开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情
LeetCode763:划分字母区间
给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。
返回一个表示每个字符串片段的长度的列表。
示例 1:
输入: s = "ababcbacadefegdehijhklij"
输出: [9,7,8]
解释:
划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。
示例 2:
输入: s = "eccbbbbdec"
输出: [10]
提示:
1 <= s.length <= 500s仅由小写英文字母组成
思路分析
根据题目分析,要求尽可能多划分片段,同一字母只能出现在一个片段中,如何知道片段中的字母都不会出现在其他片段呢?
- 1.可以先统计字符串 s 中的各个字母出现次数存放在数组 letter 中
- 2.遍历字符串 s ,进行截取 s 片段并统计片段中各个字母出现次数存放在一个数组 fragment 中
- 3.用 fragment 与字典数组 letter 进行比较,当 fragment 数组中不为0的元素与 letter 数组元素相等时即划分成功
算法代码
public List < Integer > partitionLabels(String s) {
List < Integer > list = new ArrayList < > ();
int[] letter = letterCount(s); //字典数组
int[] fragment = new int[26]; //统计截取片段的字母种数及对应的数量
int start = 0;
int end = 1;
while (end <= s.length()) {
fragment = letterCount(s.substring(start, end));
if (isFull(letter, fragment)) {
list.add(end - start);
start = end;
}
end++;
}
return list;
}
//统计输入的字符串a中各个字母出现次数
public int[] letterCount(String a) {
int[] letter = new int[26];
for (int i = 0; i < a.length(); ++i) {
int temp = a.charAt(i) - 'a';
letter[temp] ++;
}
return letter;
}
//检验testArray数组是否已将含有的字母全部截取
public boolean isFull(int[] hostArray, int[] testArray) {
for (int i = 0; i < hostArray.length; ++i) {
if (testArray[i] > 0) {
if (hostArray[i] != testArray[i]) {
return false;
}
}
}
return true;
}
结果详情
算法复杂度
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN)一起进步,一起成长!