763. 划分字母区间(leetcode)
https://leetcode.cn/problems/partition-labels/description/
听说这题是字节广告一面的题
有两种做法,但是思路大致相同,主要思路是先求出所有字符的出现的最远距离,然后不断往后遍历,更新当前片段的最远距离
若是第一种做法,就是放在另一个循环中,不断更新最远距离,且维护这个end,维护完毕后end就是当前片段的结尾
第二种做法也是官方做法,即不断更新片段最远距离,且往后遍历,直到遍历的位置是最远距离时
意味着这个最远距离已经更新完毕了,被正常遍历给追上了,即这个位置是当前片段的最远距离
class Solution {
public List<Integer> partitionLabels(String s) {
// 思路是不断遍历,遍历到没遍历过的字符就更新当前片段的最远距离
List<Integer> res = new ArrayList<>();
// 计算每个字符出现的最远位置
Map<Character,Integer> pMap = new HashMap<>();
for(int i=0;i<s.length();i++)
pMap.put(s.charAt(i),i);
int i=0;
while(i<s.length())
{
// 获取此时的片段end
int end=pMap.get(s.charAt(i));
for(int j=i;j<end;j++)
{
// 更新end
end=Math.max(end,pMap.get(s.charAt(j)));
}
// 更新end完毕,此时end就是当前片段的结尾
// 加入答案
res.add(end-i+1);
// 更新新的片段起点
i=end+1;
}
return res;
}
}
class Solution {
public List<Integer> partitionLabels(String s) {
// 思路是不断遍历,遍历到没遍历过的字符就更新当前片段的最远距离
// 贪心的地方在于当前位置和最远距离位置相同就是片段分割点
List<Integer> res = new ArrayList<>();
// 计算每个字符出现的最远位置
Map<Character,Integer> pMap = new HashMap<>();
for(int i=0;i<s.length();i++)
pMap.put(s.charAt(i),i);
int idx = 0;
int last = -1;
for (int i = 0; i < s.length(); i++) {
// 更新当前片段的最远距离
idx = Math.max(idx,pMap.get(s.charAt(i)));
if (i == idx) {
// 当前位置是当前片段的最远距离,这里是贪心的地方,也是难点
// 且由于取的都是尽可能短的片段,因此得到的数量是最多的,这里也是贪心
res.add(i - last);
last = i;
}
}
return res;
}
}