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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM