zoukankan      html  css  js  c++  java
  • LeetCode 358. Rearrange String k Distance Apart

    原题链接在这里:https://leetcode.com/problems/rearrange-string-k-distance-apart/description/

    题目:

    Given a non-empty string s and an integer k, rearrange the string such that the same characters are at least distance k from each other.

    All input strings are given in lowercase letters. If it is not possible to rearrange the string, return an empty string "".

    Example 1:

    s = "aabbcc", k = 3
    
    Result: "abcabc"
    
    The same letters are at least distance 3 from each other.

    Example 2:

    s = "aaabc", k = 3 
    
    Answer: ""
    
    It is not possible to rearrange the string.

    Example 3:

    s = "aaadbbcc", k = 2
    
    Answer: "abacabcd"
    
    Another possible answer is: "abcabcda"
    
    The same letters are at least distance 2 from each other.

    题解:

    Greedy问题. 感觉上是应该先排剩余frequency 最多的Character. 

    用maxHeap来维护剩余的Character, 根据剩余的count.

    那么如何保持断开的距离大于k呢, 用queue来存放已经加过的Character, 只有当queue的size等于k时, 才允许把头上的Character放回到maxHeap中.

    Time Complexity: O(nlogn). n = s.length(). 都加入进maxHeap用时O(nlogn).

    Space: O(n).

    AC Java:

     1 class Solution {
     2     public String rearrangeString(String s, int k) {
     3         if(s == null || s.length() == 0){
     4             return s;
     5         }
     6         
     7         HashMap<Character, Integer> hm = new HashMap<Character, Integer>();
     8         for(int i = 0; i<s.length(); i++){
     9             hm.put(s.charAt(i), hm.getOrDefault(s.charAt(i), 0)+1);
    10         }
    11         
    12         PriorityQueue<Map.Entry<Character, Integer>> maxHeap = new PriorityQueue<Map.Entry<Character, Integer>>(
    13             (a, b) -> b.getValue() - a.getValue()
    14         );
    15         maxHeap.addAll(hm.entrySet());
    16         
    17         LinkedList<Map.Entry<Character, Integer>> que = new LinkedList<Map.Entry<Character, Integer>>();
    18         StringBuilder sb = new StringBuilder();
    19         while(!maxHeap.isEmpty()){
    20             Map.Entry<Character, Integer> cur = maxHeap.poll();
    21             sb.append(cur.getKey());
    22             cur.setValue(cur.getValue()-1);
    23             que.add(cur);
    24             
    25             if(que.size() < k){
    26                 continue;
    27             }
    28             
    29             Map.Entry<Character, Integer> head = que.poll();
    30             if(head.getValue() > 0){
    31                 maxHeap.add(head);
    32             }
    33         }
    34         return sb.length() == s.length() ? sb.toString() : "";
    35     }
    36 }

    时间上可以优化.

    利用两个int array, count计数剩余frequency, validPo代表这个字符能出现的最早位置.

    找到最大frequency的合法字符, 更新其对应的frequency 和 再次出现的位置.

    Time Complexity: O(s.length()). findMaxValidCount走了遍长度为i26的count array.

    Space: O(s.length()). StringBuilder size.

    AC Java:

     1 class Solution {
     2     public String rearrangeString(String s, int k) {
     3         if(s == null || s.length() == 0){
     4             return s;
     5         }
     6         
     7         int [] count = new int[26];
     8         int [] validPo = new int[26];
     9         for(int i = 0; i<s.length(); i++){
    10             count[s.charAt(i)-'a']++;
    11         }
    12         
    13         StringBuilder sb = new StringBuilder();
    14         for(int i = 0; i<s.length(); i++){
    15             int po = findMaxValidCount(count, validPo, i);
    16             if(po == -1){
    17                 return "";
    18             }
    19             
    20             sb.append((char)('a'+po));
    21             count[po]--;
    22             validPo[po] = i+k;
    23         }
    24         return sb.toString();
    25     }
    26     
    27     private int findMaxValidCount(int [] count, int [] validPo, int ind){
    28         int po = -1;
    29         int max = Integer.MIN_VALUE;
    30         for(int i = 0; i<count.length; i++){
    31             if(count[i]>0 && count[i]>max && ind>=validPo[i]){
    32                 max = count[i];
    33                 po = i;
    34             }
    35         }
    36         
    37         return po;
    38     }
    39 }

    类似Task SchedulerReorganize String.

  • 相关阅读:
    深度系统安装wine
    Android应用真正的入口在哪里?
    推荐系统算法概览
    Android面试题:Scrollview内嵌一个Button他的事件消费是怎样的?Move,Down,Up分别被哪个组件消费?
    Java面试题:多线程交替打印字符串
    EventBus使用初体验
    Andoird面试题:A活动启动B活动,他们的生命周期各是怎么样的?
    Android在开发过程中如何选择compileSdkVersion,minSdkVersion和targetSdkVersion
    华为2020暑期实习面经(已拿Offer)
    工商银行软件开发中心2020暑期实习面经(已拿Offer)
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/7743174.html
Copyright © 2011-2022 走看看