代码随想录 763.划分字母区间

思路:
方法一:本题无法找到局部最优推出全局最优的过程,就是用最远出现距离模拟了圈字符的行为。
1.分割字符串问题容易联想到回溯,但本题不用回溯去暴力搜索。
2.本题要求同一字母最多出现在一个片段中,在遍历过程中相当于找每一个字母的边界,找到之前遍历过的所有字母的最远边界作为分割点,此时前面出现过的所有字母,最远也就到这个边界了。
3.具体分为如下两步:
(1)统计每一个字符最后出现的位置。
(2)从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置的下标和当前下标相等了,就说明找到了分割点。
如下图所示:

附代码:
class Solution {public List<Integer> partitionLabels(String s) {List<Integer> res = new LinkedList<>();int[] edge = new int[26]; //i为字符,edge[i]为字符出现的最后位置char[] chars = s.toCharArray();for(int i = 0;i < chars.length;i ++){ //统计每一个字符最后出现的位置edge[chars[i] - 'a'] = i;}int right = 0;int last = -1;for(int i = 0;i < chars.length;i++){right = Math.max(right,edge[chars[i] - 'a']); //动态更新当前区间的最远边界if(i == right){ //如果字符最远出现位置的下标和当前下标相等,说明找到了分割点res.add(i - last); //将分割点存入结果列表last = i; //起始位置更新为当前位置(即上一个片段的最后一个元素所在位置)}}return res;}
}方法二:思路与452.用最少数量的箭引爆气球、435.无重叠区间相同,统计字符串中所有字符的起始和结束位置,记录这些区间(实际上也就是435.无重叠区间题目里的输入),将区间按左边界从小到大排序,找到边界将区间划分成组,互不重叠,找到的边界就是答案。
附代码:
class Solution {public List<Integer> partitionLabels(String s) {int[][] partitions = findPartitions(s);List<Integer> res = new ArrayList<>();Arrays.sort(partitions,(a,b) -> Integer.compare(a[0],b[0]));int right = partitions[0][1];int left = 0;for(int i = 0;i < partitions.length;i++){if(partitions[i][0] > right){//左边界大于右边界即可记为一次分割res.add(right - left + 1);left = partitions[i][0];}right = Math.max(right,partitions[i][1]);}//最右端res.add(right - left + 1);return res;}public int[][] findPartitions(String s){List<Integer> temp = new ArrayList<>();int[][] hash = new int[26][2]; //26个字母2列,表示该字母对应的区间for(int i = 0;i < s.length();i ++){//更新字符c对应的位置ichar c = s.charAt(i);if(hash[c - 'a'][0] == 0){hash[c - 'a'][0] = i;}hash[c - 'a'][1] = i;//第一个元素区别对待一下hash[s.charAt(0) - 'a'][0] = 0;}List<List<Integer>> h = new LinkedList<>();//组装区间for(int i = 0;i < 26;i++){//if(hash[i][0] != hash[i][1]){temp.clear();temp.add(hash[i][0]);temp.add(hash[i][1]);//System.out.println(temp);h.add((new ArrayList<>(temp)));//}}int[][] res = new int[h.size()][2];for(int i = 0;i < h.size();i++){List<Integer> list = h.get(i);res[i][0] = list.get(0);res[i][1] = list.get(1);}return res;}
}