题目:https://leetcode-cn.com/problems/partition-labels/
代码:
class Solution {
public List<Integer> partitionLabels(String S) {
char[] chars = S.toCharArray();
//统计a-z每个字母的开头和结尾位置
int[][] letter = new int[26][2];
for (int i = 0; i < 26; i++) {
char c = (char) ('a' + i);
letter[i][0] = S.indexOf(c);
letter[i][1] = S.lastIndexOf(c);
}
//截取字符串获取结果
List<Integer> res = new ArrayList<>();
int start = 0;
int end = 0;
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (letter[c - 'a'][0] > end) {
//开启新的字符串,记录上一个字符串结果,设置新字符串start
res.add(end - start + 1);
start = letter[c - 'a'][0];
}
if (letter[c - 'a'][1] > end) {
//设置end
end = letter[c - 'a'][1];
}
}
//记录最后一个结果
res.add(end - start + 1);
return res;
}
}
定义一个二维数组,第一个维度为a-z,第二个维度记录2个值,字母c在字符串中的开头和结尾的索引值。
这样我们只需要通过一次遍历即可获得字符串S中每个字母的区间范围,接下来我们只需要对区间进行合并(有重合部分的区间合并成1个区间)
实现方法是:我们再次遍历S,这样我们对于一个区间的start就肯定是最小值,这个时候end值不确定,因为可能存在重合区间,所以end值可能会变大,需要通过继续遍历来确定end的最终值,具体实现参考代码。