LeetCode/763. 划分字母区间

763. 划分字母区间

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

示例 1:

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

提示:

  • S的长度在[1, 500]之间。
  • S只包含小写字母 'a''z'

来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

这里用到Map结构,所以在查找插入的时候会耗费一定的时间,官方给的解法是直接创建一个字母映射数组,可以加速处理过程。本题基本思路就是首先需要遍历字符串,将每个字母最远出现位置的索引保存起来,要保证相同字母出现在同一个片段里面,就是要让这个片段的长度大于等于该片段中字母最远出现位置的索引。取startend两个索引,依次遍历字符串,获取当前字母出现最远位置的索引,要保证end大于该区间中每个字母的最远索引,所以取end和当前字母最远索引的较大值。当遍历的当前位置和end相等时,即可以保证从startend这个区间内的字母仅出现在该区间内,并且可以保证该区间最短,也就是题目要求的片段尽可能多。

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
List<Integer> result = new ArrayList<>();

public List<Integer> partitionLabels(String S) {
Map<Character, Integer> map = new HashMap<>();
//获取每个字母出现位置最远的索引
for (int i = 0; i < S.length(); i++) {
map.put(S.charAt(i), i);
}

int start = 0;
int end = 0;
for (int i = 0; i < S.length(); i++) {
int currIndex = map.get(S.charAt(i));
//让片段包括当前出现字母的最远索引
end = Math.max(end, currIndex);
//此处保证片段最短,即片段尽可能的多
if (i == end) {
result.add(i - start + 1);
//完成一个片段后,将start指向下一个位置开始新的片段
start = i + 1;
}
}
return result;
}
}

Comments