zoukankan      html  css  js  c++  java
  • Leetcode: Rearrange String k Distance Apart

    Given a non-empty string str 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:
    str = "aabbcc", k = 3
    
    Result: "abcabc"
    
    The same letters are at least distance 3 from each other.
    Example 2:
    str = "aaabc", k = 3 
    
    Answer: ""
    
    It is not possible to rearrange the string.
    Example 3:
    str = "aaadbbcc", k = 2
    
    Answer: "abacabcd"
    
    Another possible answer is: "abcabcda"
    
    The same letters are at least distance 2 from each other.
     Analysis:
    Solution 1:
    The greedy algorithm is that in each step, select the char with highest remaining count if possible (if it is not in the waiting queue).  Everytime, we add the char X with the largest remaining count, after that we should put it back to the queue (named readyQ) to find out the next largest char. HOWEVER, do not forget the constraint of K apart. So we should make char X waiting for K-1 arounds of fetching and then put it back to queue. We use another queue (named waitingQ) to store the waiting chars. Whenever, the size of this queue equals to K, the head char is ready to go back to readyQ.
     
    Solution 2:
    Based on solution 1, we do not use PriorityQueue, instead, we just use array with 26 elements to store chars' count and its next available position. Every round, we iterate through the arrays and find out the available char with max count.
     
    NOTE: theoretically, the complexity of solution 1 using PriorityQueue is O(nlog(26)), while the complexity of solution 2 is O(n*26) which is larger than solution 1. HOWEVER, in real implementation, because solution 1 involves creating more complex data structures and sorting them, soluiont 1 is much slower than solution 2.
     
    Solution 1: Greedy Using Heap, Time Complexity: O(Nlog(26))
    What I learn: Map.Entry can be a very good Wrapper Class, you can directly use it to implement heap without writing a wrapper class yourself
     1 public class Solution {
     2     public String rearrangeString(String str, int k) {
     3         Map<Character, Integer> map = new HashMap<Character, Integer>();
     4         for (int i=0; i<str.length(); i++) {
     5             char c = str.charAt(i);
     6             map.put(c, map.getOrDefault(c, 0) + 1);
     7         }
     8         Queue<Map.Entry<Character, Integer>> maxHeap = new PriorityQueue<>(1, new Comparator<Map.Entry<Character, Integer>>() {
     9             public int compare(Map.Entry<Character, Integer> entry1, Map.Entry<Character, Integer> entry2) {
    10                 return entry2.getValue()-entry1.getValue();
    11             }
    12         
    13         });
    14         for (Map.Entry<Character, Integer> entry : map.entrySet()) {
    15             maxHeap.offer(entry);
    16         }
    17         Queue<Map.Entry<Character, Integer>> waitQueue = new LinkedList<>();
    18         StringBuilder res = new StringBuilder();
    19         
    20         while (!maxHeap.isEmpty()) {
    21             Map.Entry<Character, Integer> entry = maxHeap.poll();
    22             res.append(entry.getKey());
    23             entry.setValue(entry.getValue()-1);
    24             waitQueue.offer(entry);
    25             if (waitQueue.size() >= k) {
    26                 Map.Entry<Character, Integer> unfreezeEntry = waitQueue.poll();
    27                 if (unfreezeEntry.getValue() > 0) maxHeap.offer(unfreezeEntry);
    28             }
    29         }
    30         return res.length()==str.length()? res.toString() : "";
    31     }
    32 }

    Solution2: Greedy Using Array, Time Complexity: O(N*26)

     1 public class Solution {
     2     public String rearrangeString(String str, int k) {
     3         int[] count = new int[26];
     4         int[] nextValid = new int[26];
     5         for (int i=0; i<str.length(); i++) {
     6             count[str.charAt(i)-'a']++;
     7         }
     8         StringBuilder res = new StringBuilder();
     9         for (int index=0; index<str.length(); index++) {
    10             int nextCandidate = findNextValid(count, nextValid, index);
    11             if (nextCandidate == -1) return "";
    12             else {
    13                 res.append((char)('a' + nextCandidate));
    14                 count[nextCandidate]--;
    15                 nextValid[nextCandidate] += k;
    16             }
    17         }
    18         return res.toString();
    19     }
    20     
    21     public int findNextValid(int[] count, int[] nextValid, int index) {
    22         int nextCandidate = -1;
    23         int max = 0;
    24         for (int i=0; i<count.length; i++) {
    25             if (count[i]>max && index>=nextValid[i]) {
    26                 max = count[i];
    27                 nextCandidate = i;
    28             }
    29         }
    30         return nextCandidate;
    31     }
    32 }
  • 相关阅读:
    北京除了木樨园哪里有卖布料的?要高级布料,不要那种便宜的小摊。
    郭培_百度百科
    木樨园批发市场淘布归来
    九头身美女_百度百科
    「花田对」CSDN程序员专场——谁来拯救技术宅!_豆瓣
    时间囊咖啡馆免费提供小型活动场地_豆瓣
    北京的布料市场
    适合入门自学服装裁剪滴书(更新ing)
    不说技术~2016-07-02我们是幸福的一家人
    插件~使用ECharts动态在地图上标识点~动态添加和删除标识点
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/6186165.html
Copyright © 2011-2022 走看看