Leetcode763 划分字母区间

Problem describe:
字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。
示例 1:
输入: S = “ababcbacadefegdehijhklij”
输出: [9,7,8]
解释:
划分结果为 “ababcbaca”, “defegde”, “hijhklij”。
每个字母最多出现在一个片段中。
像 “ababcbacadefegde”, “hijhklij” 的划分是错误的,因为划分的片段数较少。
注意:
S的长度在[1, 500]之间。
S只包含小写字母’a’到’z’。
问题解法:
问题中描述要尽可能多的划分字母区间,我们要尽量将其划分为长度较短的字符串。中心思想就是贪心选择包含首字母的最短字符串,观察字串可知,字串一定包含与首字母相同的字母,我们在此基础上让其尽量短,如"ababcbaca",我们让其包含a之间所有字母即可,为此我们要知道此片段中的每一个字母的最后一个下标,其中最大的下标就是此字符串的结尾。
设置变量slow,fast和index,index指向首字母,slow依次检查首字母存在的范围内所有字母 ,fast指向这些字母的最后一次出现的字母中下标的最大值。当slow==fast时说明当前指向的字符串是满足题设条件的最短字符串。
代码如下:

class Solution {
    public List<Integer> partitionLabels(String S) {
        char[] str =S.toCharArray();
        List<Integer> ans =new ArrayList<>();
        int slow = 0, fast = 0;
        int index=0;
        while(slow<str.length&&fast<str.length)
        {
          fast =Math.max(findLastChar(str,slow),fast);
          while(fast!=slow)
          {
            fast =Math.max(findLastChar(str,slow),fast);
            slow++;
          }
          ans.add(slow-index+1);
          slow++;fast++;
          index=slow;
        }
      return ans;
    }
    private int findLastChar(char[] str, int slow){
      int fast =0;
      for(int i=str.length-1;i>=slow;i--)
      {
         if(str[i]==str[slow])
         {
           fast=i;
           break;
         }
      }
      return fast;
    }
}

猜你喜欢

转载自blog.csdn.net/shine10076/article/details/84191938