划分字母区间

763. 划分字母区间 - 力扣(LeetCode)

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s

返回一个表示每个字符串片段的长度的列表。

示例 1:

1
2
3
4
5
6
输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca""defegde""hijhklij"
每个字母最多出现在一个片段中。
"ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。

示例 2:

1
2
输入:s = "eccbbbbdec"
输出:[10]

提示:

  • 1 <= s.length <= 500
  • s 仅由小写英文字母组成

先用一个哈希表保存所有字母的最远边界

然后遍历字符串,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。因为此时前面出现过所有字母,最远也就到这个边界了。

image-20231003154515945
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public List<Integer> partitionLabels(String s) {
int[] hashmap = new int[26];
List<Integer> ans = new ArrayList<>();
//统计每个字符出现的最后下标
for(int i = 0; i < s.length(); i++){
hashmap[s.charAt(i) - 'a'] = i;
}
int left = 0;
int right = 0; //遍历过字母的最远端点

for(int i = 0; i < s.length(); i++){
right = Math.max(hashmap[s.charAt(i)-'a'], right);
//如果之前所有字母的最远边界为i,则i是分界点
if(right == i){
ans.add(i - left + 1);
left = i + 1;
}
}
return ans;
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(1)$,使用的hash数组是固定大小

划分字母区间
http://example.com/2023/03/02/算法/贪心/16. 划分字母区间/
作者
PALE13
发布于
2023年3月2日
许可协议