leetcode *763. 划分字母区间(2020.10.22)

it2025-08-23  1

【题目】*763. 划分字母区间

字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。

示例 1:

输入:S = "ababcbacadefegdehijhklij" 输出:[9,7,8] 解释: 划分结果为 "ababcbaca", "defegde", "hijhklij"。 每个字母最多出现在一个片段中。 像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。

提示: S的长度在[1, 500]之间。 S只包含小写字母 ‘a’ 到 ‘z’ 。

【解题思路1】贪心算法 + 双指针

先得到每个字母最后一次出现的下标位置,然后使用贪心算法和双指针的方法将字符串划分为尽可能多的片段。

从左到右遍历字符串,遍历的同时维护当前片段的开始下标 start 和结束下标 end,初始时都为0

遍历时当前字母的最后一次出现的下标位置 end = last[S.charAt(i) - ‘a’] ,则当前片段的结束下标一定不会小于 end,因此令 end=max(end, last[S.charAt(i) - 'a'])。

当访问下标 i == end 时,说明当前片段访问结束,当前片段的下标范围是 [start,end],长度为 end−start+1,将当前片段的长度添加到 ans,然后令 start=end+1,继续寻找下一个片段。

class Solution { public List<Integer> partitionLabels(String S) { int[] last = new int[26]; for(int i = 0; i < S.length(); i++) { last[S.charAt(i) - 'a'] = i; } List<Integer> ans = new ArrayList<>(); int start = 0, end = 0; for(int i = 0; i < S.length(); i++) { end = Math.max(end, last[S.charAt(i) - 'a']); if(i == end) { ans.add(end - start + 1); start = end + 1; } } return ans; } }
最新回复(0)