Leetcode763 劃分字母區間
阿新 • • 發佈:2018-12-22
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; } }