zoukankan      html  css  js  c++  java
  • [LeetCode] 358. Rearrange String k Distance Apart 按距离k间隔重排字符串

    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.

    给一个非空字符串和一个距离k,按k的距离间隔从新排列字符串,使得相同的字符之间间隔最少是k。

    解法1:先用 HashMap 或者Array 对字符串里的字符按出现次数进行统计,按次数由高到低进行排序。出现次数最多的字符个数记为max_cnt,max_cnt - 1 是所需要的间隔数。把剩下字符按出现次数多的字符开始,把每一个字符插入到间隔中,以此类推,直到所有字符插完。然后判断每一个间隔内的字符长度,如果任何一个间隔<k,则不满足,返回"",如果都满足则返回这个新的字符串。

    解法2:还是先统计字符出现的次数,按出现次数排列组成最大堆。然后每次从堆中去取topk 的字符排入结果,相应的字符数减1,如此循环,直到所有字符排完。

    public class Solution {  
        public String rearrangeString(String str, int k) {  
            if (k <= 0) return str;  
            int[] f = new int[26];  
            char[] sa = str.toCharArray();  
            for(char c: sa) f[c-'a'] ++;  
            int r = sa.length / k;  
            int m = sa.length % k;  
            int c = 0;  
            for(int g: f) {  
                if (g-r>1) return "";  
                if (g-r==1) c ++;  
            }  
            if (c>m) return "";  
            Integer[] pos = new Integer[26];  
            for(int i=0; i<pos.length; i++) pos[i] = i;  
            Arrays.sort(pos, new Comparator<Integer>() {  
               @Override  
               public int compare(Integer i1, Integer i2) {  
                   return f[pos[i2]] - f[pos[i1]];  
               }  
            });  
            char[] result = new char[sa.length];  
            for(int i=0, j=0, p=0; i<sa.length; i++) {  
                result[j] = (char)(pos[p]+'a');  
                if (-- f[pos[p]] == 0) p ++;  
                j += k;  
                if (j >= sa.length) {  
                    j %= k;  
                    j ++;  
                }  
            }  
            return new String(result);  
        }  
    }  

    Python:  T: O(n) S: O(n)

    class Solution(object):
        def rearrangeString(self, str, k):
            cnts = [0] * 26;
            for c in str:
                cnts[ord(c) - ord('a')] += 1
    
            sorted_cnts = []
            for i in xrange(26):
                sorted_cnts.append((cnts[i], chr(i + ord('a'))))
            sorted_cnts.sort(reverse=True)
    
            max_cnt = sorted_cnts[0][0]
            blocks = [[] for _ in xrange(max_cnt)]
            i = 0
            for cnt in sorted_cnts:
                for _ in xrange(cnt[0]):
                    blocks[i].append(cnt[1])
                    i = (i + 1) % max(cnt[0], max_cnt - 1)
    
            for i in xrange(max_cnt-1):
                if len(blocks[i]) < k:
                    return ""
    
            return "".join(map(lambda x : "".join(x), blocks))
    

    Python: T: O(nlogc), c is the count of unique characters. S: O(c)

    from collections import defaultdict
    from heapq import heappush, heappop
    class Solution(object): def rearrangeString(self, str, k): if k == 0: return str cnts = defaultdict(int) for c in str: cnts[c] += 1 heap = [] for c, cnt in cnts.iteritems(): heappush(heap, [-cnt, c]) result = [] while heap: used_cnt_chars = [] for _ in xrange(min(k, len(str) - len(result))): if not heap: return "" cnt_char = heappop(heap) result.append(cnt_char[1]) cnt_char[0] += 1 if cnt_char[0] < 0: used_cnt_chars.append(cnt_char) for cnt_char in used_cnt_chars: heappush(heap, cnt_char) return "".join(result)  

    C++:

    class Solution {  
    public:  
        string rearrangeString(string s, int k) {  
            if (k == 0) {  
                return s;  
            }  
            int len = s.size();    
            string result;  
            map<char, int> hash;                                // map from char to its appearance time  
            for(auto ch: s) {  
                ++hash[ch];  
            }  
            priority_queue<pair<int, char>> que;                // using priority queue to pack the most char first  
            for(auto val: hash) {  
                que.push(make_pair(val.second, val.first));  
            }  
            while(!que.empty()) {    
                vector<pair<int, int>> vec;   
                int cnt = min(k, len);   
                for(int i = 0; i < cnt; ++i, --len) {           // try to pack the min(k, len) characters sequentially   
                    if(que.empty()) {                           // not enough distinct charachters, so return false  
                        return "";    
                    }  
                    auto val = que.top();    
                    que.pop();    
                    result += val.second;    
                    if(--val.first > 0) {                       // collect the remaining characters  
                        vec.push_back(val);  
                    }  
                }    
                for(auto val: vec) {  
                    que.push(val);  
                }  
            }    
            return result;    
        }  
    };  
    

      

    类似题目:

    [LeetCode] 621. Task Scheduler 任务调度程序  

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    探索事务日志与恢复模式(1-13)
    sql server 复制、镜像常见故障处理
    (3.2)mysqldump之备份单个表及脚本批量备份
    Log Explorer 恢复误删除、更新数据
    ApexSQL Log 从意外UPDATE和DELETE操作中恢复SQL Server数据
    ApexSQL Recover 恢复一个被drop的表的数据
    数据库参数调优--自动更新统计信息
    T-SQL利用笛卡尔积/窗口函数_分析函数/表连接累计、累加
    【生产问题】-dbcc checkdb报错-数据页故障
    (4.4)dbcc checkdb 数据页修复
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8547310.html
Copyright © 2011-2022 走看看