• [leetcode] Partition Labels


    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中保存每个字符最后出现的次数,并且在循环过程中如何判断是否满足分片条件。

  • 相关阅读:
    GNU计划的起因及其现状
    【KVM新概念】 虚拟机CPU热拔插
    Amazon vs Google 云服务
    【笨木头Cocos2dx 039】战争迷雾效果 第02章_先把地图加进来
    【C++11】新特性——auto的使用
    Netty4 SEDA 事件驱动原理分析
    error ,exception
    Compiling Java with makefile
    (二)Centos7下Yum更新安装PHP5.5,5.6,7.0
    CentOS7.0下安装FTP服务的方法
  • 原文地址:https://www.cnblogs.com/boris1221/p/9736906.html
Copyright © 2020-2023  润新知