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.
    

    Credits:
    Special thanks to @elmirap for adding this problem and creating all test cases.

     Analysis:
    Solution 1:
    Everytime, we add the char X with the largest 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:
    import java.util.Map.Entry;
    
    public class Solution {
        public String rearrangeString(String str, int k) {
            if (str.isEmpty() || k<0) return "";
            if (k==0) return str;
            
            HashMap<Character,Integer> charMap = new HashMap<Character,Integer>();
            for (char c : str.toCharArray()){
                charMap.put(c,charMap.getOrDefault(c,0)+1);
            }
            
            char[] chars = new char[charMap.size()];
            int[] charCount = new int[charMap.size()];
            int[] valid = new int[charMap.size()];
            int index = 0;
            for (Entry entry : charMap.entrySet()){
                char c = (char) entry.getKey();
                int count = (int) entry.getValue();
                chars[index] = c;
                charCount[index++] = count;
            }
                
            StringBuilder builder = new StringBuilder();
            int nextInd = 0;
            int nextChar = getNextChar(charCount,valid,nextInd);
            while (nextChar!=-1){
                builder.append(chars[nextChar]);
                charCount[nextChar]--;
                valid[nextChar] = (nextInd++) + k;
                nextChar = getNextChar(charCount,valid,nextInd);
            }
            if (builder.length()!=str.length()) return "";
            
            return builder.toString();
        }
        
        public int getNextChar(int[] charCount, int[] valid, int nextInd){
            int maxCount = 0;
            int index = -1;
            for (int i=0;i<charCount.length;i++)
                if (valid[i]<=nextInd && charCount[i]>maxCount){
                    maxCount = charCount[i];
                    index = i;
                }
            return index;
        }
    }

    Solution 2:

    import java.util.Map.Entry;
    
    public class Solution {
        public String rearrangeString(String str, int k) {
            if (str.isEmpty() || k<0) return "";
            if (k==0) return str;
            
            int[] charCount = new int[26];
            int[] valid = new int[26];
            Arrays.fill(valid,-1);
            for (char c : str.toCharArray()){
                charCount[c-'a']++;
            }
            for (int i=0;i<26;i++)
                if (charCount[i]>0){
                    valid[i] = 0;
                }
                
            StringBuilder builder = new StringBuilder();
            int nextInd = 0;
            int nextChar = getNextChar(charCount,valid,nextInd);
            while (nextChar!=-1){
                builder.append((char)(nextChar+'a'));
                charCount[nextChar]--;
                valid[nextChar] = (nextInd++) + k;
                nextChar = getNextChar(charCount,valid,nextInd);
            }
            if (builder.length()!=str.length()) return "";
            
            return builder.toString();
        }
        
        public int getNextChar(int[] charCount, int[] valid, int nextInd){
            int maxCount = 0;
            int index = -1;
            for (int i=0;i<charCount.length;i++)
                if (valid[i]<=nextInd && charCount[i]>maxCount){
                    maxCount = charCount[i];
                    index = i;
                }
            return index;
        }
    }
     
     
  • 相关阅读:
    linux tcp GSO和TSO实现
    CentOS 6.8 源码安装mysql 5.6
    MySQL主从复制配置
    PHP超级全局变量、魔术变量和魔术函数
    工作中常用的正则表达式
    CentOS下编译安装LNMP环境
    解决<IE9版本不支持getElementsByClassName方法
    js 回调函数
    Firefox下table单元格td设计relative定位失效解决方案
    jQuery的.live()和.die()
  • 原文地址:https://www.cnblogs.com/lishiblog/p/5856198.html
Copyright © 2011-2022 走看看