字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。
示例 1:
输入:S = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca", "defegde", "hijhklij"。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。
提示:
S的长度在[1, 500]之间。
S只包含小写字母 'a' 到 'z' 。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-labels
时间复杂度:O(n)
空间复杂度:需要一个额外26个空间
class Solution { public List<Integer> partitionLabels(String S) { //首先循环一遍,记录下每个字母的索引位置,索引位置可能有多个,只需要记录第一个就行了 int [] letterArray = new int[26]; //初始化数组为-1 for(int i = 0; i < 26; i++){ letterArray[i] = -1; } int strLength = S.length(); for(int i=strLength-1; i >=0; i--){ int index = S.charAt(i) - 'a'; if(letterArray[index] == -1){ letterArray[index] = i; } } //得到一个数组,每个字符的最开始出现的位置 //第二次遍历 List<Integer> result = new ArrayList<>(); int preEndIndex = 0; //标识这个字符串开始的索引 int maxIndex = 0; //标识这个字符串中最大的索引 for(int i = 0 ; i < strLength; i++){ int tempMin = letterArray[S.charAt(i) - 'a']; maxIndex = Math.max(tempMin,maxIndex); if(tempMin == i && maxIndex == i){ //说明当前节点可以单独成为字符串 result.add(i - preEndIndex + 1); preEndIndex = i+1; } } //依次找每个字符的最开始出现的位置,如果跟当前索引位置相同,则记录长度 长度 = 索引开始 - 索引结束 + 1 return result; } }