358. K 距离间隔重排字符串

题目:

给你一个非空的字符串 s 和一个整数 k,你要将这个字符串中的字母进行重新排列,使得重排后的字符串中相同字母的位置间隔距离至少为 k。

所有输入的字符串都由小写字母组成,如果找不到距离至少为 k 的重排结果,请返回一个空字符串 ""。

示例 1:

输入: s = "aabbcc", k = 3
输出: "abcabc"
解释: 相同的字母在新的字符串中间隔至少 3 个单位距离。
示例 2:

输入: s = "aaabc", k = 3
输出: ""
解释: 没有办法找到可能的重排结果。
示例 3:

输入: s = "aaadbbcc", k = 2
输出: "abacabcd"
解释: 相同的字母在新的字符串中间隔至少 2 个单位距离。

解答:

贪心法,每次尽量取频次大的字母加入结果。

先统计每个字母出现的次数,存入map

然后把所有的[字母:频次]存入最大堆

每次从最大堆中取k个最大频次的字母,加入结果字符串。然后相应频次减一后再放回最大堆。

最终要么堆为空,则成功。如果堆中剩下不到k个字母,那么只能取一次(即字符串结尾,因为后面没有其他元素了),否则失败。

 1 class Solution {
 2 public:
 3     string rearrangeString(string s, int k) {
 4         if(k==0){
 5             return s;
 6         }
 7         vector<int> cnt(26,0);
 8         for(char& c:s){
 9             cnt[c-'a']+=1;
10         }
11         priority_queue<pair<int,char>> max_heap;
12         for(int i=0;i<26;++i){
13             if(cnt[i]>0){
14                 max_heap.push(make_pair(cnt[i],'a'+i));
15             }
16         }
17         string res;
18         while(res.size()<s.size()){
19             vector<pair<int,char>> tmp;
20             int min_len=min(k,int(max_heap.size()));
21             for(int i=0;i<min_len;++i){
22                 auto cur=max_heap.top();
23                 max_heap.pop();
24                 res+=cur.second;
25                 if(--cur.first>0){
26                     tmp.push_back(cur);
27                 }
28             }
29             if(min_len<k and res.size()!=s.size()){
30                 return "";
31             }
32             for(auto& pai:tmp){
33                 max_heap.push(pai);
34             }
35         }
36         return res;
37     }
38 };

时间O(n log n),空间O(n)

猜你喜欢

转载自www.cnblogs.com/FdWzy/p/12389956.html