763.划分字母区间
力扣题目链接(opens new window)
字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。
示例: 输入:S = “ababcbacadefegdehijhklij” 输出:[9,7,8] 解释: 划分结果为 “ababcbaca”, “defegde”, “hijhklij”。 每个字母最多出现在一个片段中。 像 “ababcbacadefegde”, “hijhklij” 的划分是错误的,因为划分的片段数较少。
提示:
S的长度在[1, 500]之间。
S只包含小写字母 ‘a’ 到 ‘z’ 。
public List<Integer> partitionLabels(String s) {
//真有给无语到,想了好久的方法,最终还是没答案的骚
//如何检测一个单词中字母最后出现的下标
int []tap=new int [26];
List<Integer>list1=new ArrayList<>();
for(int i=0;i<s.length();i++){
tap[s.charAt(i)-'a']=i;
}
//最巧妙地是这里,统计一个单词在字符串中最后出现的次数竟然能用这种思路。比如char 0为b,那么tap【1】=0;然后后续比如最后i=7时
// char 7也为b,此时 tap【1】=7,也就是b最后出现的下标就为7
//这样就能得到每个字母最后出现的下标
//s.charAt(i)-'a' 这里意思就是更新相同字母最后出现的下标
int left=0;
int right=0;
for(int i=0;i<s.length();i++){
//典型的贪心
//一开始总觉得要搞成小于等于,其实贪心的题就用等于就好
//类比这道题,直接每一次都更新更长的。一开始想应该在范围内才更新,但后面发现下面有在判断啦,
//直接更新就行,下面如果等于就说明已经到了目前范围所能到达的最远
//很巧妙,一开始的想法 在这些细节上总是会出错,多做吧,或许做多了就融会贯通了
right=Math.max(right,tap[s.charAt(i)-'a']);
if(i==right){
list1.add(right-left+1);
left=right+1;
}
}
return list1;
反正记住这种思路吧,很少用 小于判断
大多数都是 直接更新,然后下面的等于 作为约束条件。