贪心策略---分隔字符串使同种字符出现在一起

分隔字符串使同种字符出现在一起

763. Partition Labels (Medium)

Input: S = "ababcbacadefegdehijhklij"
Output: [9,7,8]
Explanation:
The partition is "ababcbaca", "defegde", "hijhklij".
This is a partition so that each letter appears in at most one part.
A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits S into less parts.

题目描述:

  这道题给了我们一个字符串s,然后将其尽可能多的分割为子字符串,条件是每种字符最多只能出现在一个子串中,这道题的难点在于如何找到字符串的断点,即拆分为子串的位置,我们仔细观察题目中的例子,可以发现一旦某个字母多次出现了,那么其最后一个出现位置必须要在当前子串中,字母a,e和j分别是三个子串的结束字母。所以我们关注的是每个字母最后出现的位置,我们可以使用map保存每个字母和其最后一次出现的位置。

  建立好映射后,我们遍历字符串s,我们维护一个start变量,是当前子串的起始位置,还有一个last变量,是当前子串的结束位置,每当我们遍历到一个字母时,我们从map中提取其出现的最后一个位置,因为一个字符串一旦包含一个字母,就要包含所有相同的字母,所以我们要不停的用当前字母的最后一个下标来更新last变量,只有当i和last相等的时候,就是当前子串该断开的地方。

代码:

class Solution {
    public List<Integer> partitionLabels(String S) {
        List<Integer>res=new ArrayList<>();
    if(S==null||S.length()==0)
        return res;
    int []map=new int [26]; //记录每个字母出现的最后一个下标
    for(int i=0;i<S.length();i++){
        map[S.charAt(i)-'a']=i;
    }
    int start=0;
    int last=0;
    while(start<S.length()){
        int i=start;
        while(i<S.length()){
        last=Math.max(last,map[S.charAt(i)-'a']);//取访问到的字母的最大最后一个坐标更新last
        if(last==i){
            res.add(i-start+1);
            start=i+1;
            break;
        }
            i++;
        }
    }
    return res;
    }
}

猜你喜欢

转载自www.cnblogs.com/yjxyy/p/11106039.html