题目地址:
https://leetcode.com/problems/partition-labels/
给定一个长 n n n的字符串 s s s,要求对其进行划分,使得每个分块里的所有字母都不会出现在别的块里。要求分块数尽可能多。
用一个哈希表存一下每个字母最后出现的位置。接着遍历 s s s,用两个变量分别存划分的起始位置和终止位置,一开始起始位置是 0 0 0,接着每次遍历的时候都看一下 s [ i ] s[i] s[i]的最后出现位置,以此更新终止位置。如果某时刻终止位置恰好等于 i i i了,说明此时 s [ 0 : i ] s[0:i] s[0:i]可以作为一个分块,记录其长度,并更新起始位置为 i + 1 i+1 i+1,再重复上述操作。证明参考https://blog.csdn.net/qq_46105170/article/details/108860961。代码如下:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Solution {
public List<Integer> partitionLabels(String S) {
List<Integer> res = new ArrayList<>();
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < S.length(); i++) {
map.put(S.charAt(i), i);
}
int start = 0, end = 0;
for (int i = 0; i < S.length(); i++) {
// 更新终止位置
end = Math.max(end, map.get(S.charAt(i)));
// 与当前位置相等了,则做一个划分,并更新新划分起始位置
if (end == i) {
res.add(end - start + 1);
start = i + 1;
}
}
return res;
}
}
时空复杂度 O ( n ) O(n) O(n)。