[leetcode] Partition Labels

來源:互聯網
上載者:User

標籤:exp   hash   this   line   only   ati   cad   span   count   

A string S of lowercase letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts.

 

Example 1:

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.

 

Note:

  1. S will have length in range [1, 500].
  2. S will consist of lowercase letters (‘a‘ to ‘z‘) only.
分析:題目翻譯一下:給定一個字串,要求將字串分區,使得每一片中出現的字元僅在這個分區中出現。第一個思路:用一map儲存每個字串出現的次數,如果走到某個字元處,前面所有字元對應的值都為0,那麼就說明這個分區找到了。根據這個原理,可以寫出下面代碼:
 1 class Solution { 2     public List<Integer> partitionLabels(String S) { 3         Map<Character,Integer> map = new HashMap<>(); 4         Set<Character> set = new HashSet<>(); 5         List<Integer> list = new ArrayList<>(); 6  7         for ( char c : S.toCharArray() ) 8             map.put(c,map.getOrDefault(c,0)+1); 9         //System.out.println(map);10 11         int left = 0;12         int count = 0;13         while ( left < S.length() ){14             char c = S.charAt(left);15             set.add(c);16             map.put(c,map.get(c) - 1);17             count += 1;18             boolean ise = true;19             for ( char temp : set ){20                 if ( map.get(temp) != 0 ) ise = false;21             }22             if ( ise ){23                 list.add(count);24                 count = 0;25                 set.clear();26             }27             left ++;28         }29         return list;30     }31 }

    已耗用時間42ms,非常耗時。不過這個方法是最直觀的方法。下面分析如何改進。

第二個思路:上一個方法是不停的對map進行-1操作,然後判斷是否為0。這個題目也可以用map來儲存每個字元最後出現的位置,並且用一個變數儲存前面出現過的字元中最遠的位置。如果cur指標走到這個位置,就說明前面的都被訪問過了,就得到了這個分區。show me the code:

 1 class Solution { 2     public List<Integer> partitionLabels(String S) { 3         Map<Character,Integer> map = new HashMap<>(); 4         List<Integer> list = new ArrayList<>(); 5          6         for ( int i = 0 ; i < S.length() ; i ++ ) 7             map.put(S.charAt(i),i); 8  9         int left = 0, right = 0, cur = 0;10         while ( cur < S.length() ){11             char c = S.charAt(cur);12             right = Math.max(right,map.get(c));13             if ( cur == right ){14                 list.add(right-left+1);15                 left = right+1;16             }17             cur++;18         }19         return list;20     }21 }

  已耗用時間14ms,擊敗36.70%,還是很慢。為什麼呢?

第三個思路:其實也不散完整的思路,對上面進行改進,因為map工作量比較大,因此不妨用一個26長度的數組取代map(這個方法在用到map和字串的時候非常常見)。

 1 class Solution { 2     public List<Integer> partitionLabels(String S) { 3         List<Integer> list = new ArrayList<>(); 4         int[] a = new int[26]; 5         for ( int i = 0 ; i < S.length() ; i ++ ) 6             a[S.charAt(i)-‘a‘] = i; 7  8         int left = 0, right = 0, cur = 0; 9         while ( cur < S.length() ){10             char c = S.charAt(cur);11             right = Math.max(right,a[c-‘a‘]);12             if ( cur == right ){13                 list.add(right-left+1);14                 left = right+1;15             }16             cur++;17         }18         return list;19     }20 }

  已耗用時間12ms,擊敗52.83%。已經儘力了。。

 

總結:關鍵在於想到map中儲存每個字元最後出現的次數,並且在迴圈過程中如何判斷是否滿足分區條件。

[leetcode] Partition Labels

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.