1. 程式人生 > >Leetcode763 劃分字母區間

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;
    }
}