思路:
方法一:时间复杂度O(n)。很巧妙。
1 class Solution { 2 public List<Integer> partitionLabels(String S) { 3 List<Integer> res = new ArrayList<>();//返回的结果 4 int[] map = new int[26]; 5 for(int i = 0; i < S.length(); i++) {//记录每个字母在S中最后一次出现的位置 6 map[S.charAt(i) - 'a'] = i; 7 } 8 int start = -1, end = 0;//start是下一个字段的首字母的前一个位置,第一个字段的首字母的位置一定是0 9 for(int i = 0; i < S.length(); i++) { 10 end = Math.max(end, map[S.charAt(i) - 'a']);//不断更新末尾指针的位置 11 if(end == i) {//当i指针的位置和末尾指针的位置相同时意味着[start,end]之间的字母的最后出现位置都在[start,end],尾指针无法再更新 12 res.add(end - start);//当前字段的长度 13 start = end;//start是下一个字段的首字母的前一个位置 14 } 15 } 16 return res; 17 } 18 }
方法二:也是不断更新末尾指针,但是写得没有方法一好,复杂度也比方法一高。
1 class Solution { 2 public List<Integer> partitionLabels(String S) { 3 List<Integer> re = new ArrayList<Integer>(); 4 HashSet<Character> set = new HashSet<Character>(); 5 for(int i = 0; i < S.length(); i++) { 6 int start = i, end = i; 7 boolean flags = true; 8 set.add(S.charAt(start)); 9 while(flags) { 10 int j = S.length() - 1; 11 for(; j > end; j--) { 12 if(set.contains(S.charAt(j))) { 13 for(int k = end; k < j; k++) { 14 set.add(S.charAt(k)); 15 } 16 break; 17 } 18 } 19 if(j > end) { 20 end = j; 21 }else { 22 flags = false; 23 } 24 } 25 re.add(end - start + 1); 26 i = end; 27 } 28 return re; 29 } 30 }