Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

จัดเรียงสตริงใหม่ให้ห่างกัน k ตัวใน C++


สมมติว่าเรามีสตริงไม่ว่าง s และจำนวนเต็ม k เราต้องจัดเรียงสตริงใหม่ให้ตัวอักษรเดียวกันห่างกันอย่างน้อย k ตัวอักษร สตริงที่ให้มาประกอบด้วยตัวอักษรพิมพ์เล็ก หากจัดเรียงไม่ได้ ให้คืนสตริงว่าง

เช่น ถ้าอินพุตคือ s = "aabbcc", k = 3 ผลลัพธ์จะเป็น "abcabc" เพราะตัวอักษรซ้ำห่างกันอย่างน้อย 3 ตัว

ในการแก้ปัญหานี้ เราจะทำตามขั้นตอนต่อไปนี้:

  • ret := สตริงว่าง
  • สร้าง map m นับความถี่ตัวอักษรใน s
  • สร้าง priority queue pq เรียงตามความถี่มากไปน้อย (max-heap)
  • สร้าง deque dq เก็บค่าที่ใช้ไปชั่วคราว
  • while pq ไม่ว่าง: ดึง curr จาก pq เพิ่ม curr.first เข้า ret ลด curr.second ลง 1 ใส่ curr เข้า dq; ถ้า dq.size() >= k: ดึง front ของ dq ถ้า count > 0 ใส่กลับ pq
  • หลังจบ while: ลบ front ของ dq ที่ count==0; ถ้า dq ว่าง คืนค่า ret มิฉะนั้นคืนค่าว่าง

ตัวอย่าง

ลองดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น:

#include <bits/stdc++.h>
using namespace std;
struct Comparator {
    bool operator()(pair a, pair b) { return !(a.second > b.second); }
};
class Solution {
public:
    string rearrangeString(string s, int k) {
        string ret = "";
        unordered_map m;
        int n = s.size();
        for (int i = 0; i < n; i++) m[s[i]]++;
        priority_queue, vector>, Comparator> pq;
        for (auto& it : m) pq.push({it.first, it.second});
        deque> dq;
        while (!pq.empty()) {
            auto curr = pq.top(); pq.pop();
            ret += curr.first; curr.second--;
            dq.push_back(curr);
            if (dq.size() >= k) {
                curr = dq.front(); dq.pop_front();
                if (curr.second > 0) pq.push(curr);
            }
        }
        while (!dq.empty() && dq.front().second == 0) dq.pop_front();
        return dq.empty() ? ret : "";
    }
};
main() {
    Solution ob;
    cout << (ob.rearrangeString("aabbcc", 3));
}

อินพุต

"aabbcc", 3

เอาต์พุต

bacbac