[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,如此循环,直到所有字符排完。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | from collections import defaultdict from heapq import heappush, heappop<br> 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++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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 题目汇总
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架