763. Partition-Labels
difficulty: Medium
section pre{ background-color: #eee; border: 1px solid #ddd; padding:10px; border-radius: 5px; }
A string S
of lowercase English letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts.
Example 1:
Input: S = "ababcbacadefegdehijhklij"
Output: [9,7,8]
Explanation:
The partition is "ababcbaca", "defegde", "hijhklij".
This is a partition so that each letter appears in at most one part.
A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits S into less parts.
Note:
S
will have length in range[1, 500]
.S
will consist of lowercase English letters ('a'
to'z'
) only.
Method One
class Solution {
public List<Integer> partitionLabels(String S) {
List<Integer> ans = new ArrayList<>();
// Method 1 Greedy 核心是Two pointers,
// right 始终指向目前最右侧,left指向目前最左
// 当 i 遇到 right 的时候,说明区间内的所有的字符的都被记录了。
// int[] lastPositions = new int[26];
// for(int i = 0; i < S.length(); i++){
// char c = S.charAt(i);
// lastPositions[c - 'a'] = i;
// }
// int right = 0;
// int left = 0;
// for(int i = 0; i < S.length(); i++){
// char c = S.charAt(i);
// right = Math.max(right, lastPositions[c - 'a']);
// if( right == i ){
// ans.add( right - left + 1 );
// left = i + 1;
// }
// }
// Method 2 转化为 merge interval
Map<Character, int[]> intervals = new HashMap<>();
for(int i = 0; i < S.length(); i++){
intervals.putIfAbsent(S.charAt(i), new int[]{i,i});
intervals.get(S.charAt(i))[1] = i;
}
int curLeft = 0;
int curRight = intervals.get(S.charAt(0))[1];
for(int i = 1; i < S.length(); i++){
char c = S.charAt(i);
int[] interval = intervals.get(c);
if(interval[0] >= curRight){
ans.add(curRight - curLeft + 1);
curLeft = interval[0];
curRight = interval[1];
}else{
curRight = Math.max(curRight, interval[1]);
curLeft = Math.min(curLeft, interval[0]);
}
}
ans.add(curRight - curLeft + 1);
return ans;
}
}
Last updated
Was this helpful?