โจทย์: กำหนด String str (Non-empty) และ Integer k ให้จัดเรียง String ใหม่ ทำให้ตัวอักษรที่เหมือนกันห่างกันอย่างน้อย k ตำแหน่ง หากไม่เป็นไปได้ คืน String ว่าง ""
ตัวอย่าง
| Input | k | Output | คำอธิบาย |
|---|---|---|---|
| "tutorialspoint" | 3 | "tiotiotalnprsu" | ตัวอักษรซ้ำห่าง ≥ 3 |
| "aabbcc" | 3 | "abcabc" | ตัวอักษรซ้ำห่าง ≥ 3 |
| "aaabc" | 3 | "" | ไม่เป็นไปได้ |
| "aaadbbcc" | 2 | "abacabcd" | ตัวอักษรซ้ำห่าง ≥ 2 |
อัลกอริทึม (Greedy + Max Heap)
- นับ Frequency ของแต่ละตัวอักษร
- สร้าง Max Heap เรียงตาม Frequency มากไปน้อย
- Extract ตัวอักษรที่ Frequency สูงสุด
- วางใน Result Array ตำแหน่ง i, i+d, i+2d, ...
- หากตำแหน่งเกินขนาด Array → ไม่เป็นไปได้
- ทำซ้ำจนกว่า Heap จะว่าง
Implementation ใน Python
import heapq
from collections import Counter
def rearrange_string(s: str, d: int) -> str:
if d <= 1:
return s
n = len(s)
freq = Counter(s)
# Max Heap: ใช้ negative frequency เพราะ heapq เป็น Min Heap
max_heap = [(-count, char) for char, count in freq.items()]
heapq.heapify(max_heap)
result = [''] * n
# ตำแหน่งที่ว่างถัดไปสำหรับแต่ละ Character
# ใช้ Queue เก็บ (char, remaining_count, next_available_position)
from collections import deque
wait_queue = deque()
for i in range(n):
# ปลดปล่อย Character ที่พร้อมใช้งาน
if wait_queue and wait_queue[0][2] <= i:
count, char, _ = wait_queue.popleft()
heapq.heappush(max_heap, (count, char))
if not max_heap:
return "" # ไม่มี Character ให้วาง → Impossible
count, char = heapq.heappop(max_heap)
result[i] = char
# หากยังเหลือ ใส่ Wait Queue พร้อม Next Available Position
if count + 1 < 0: # count เป็น Negative
wait_queue.append((count + 1, char, i + d))
return ''.join(result)
# ทดสอบ
print(rearrange_string("tutorialspoint", 3)) # tiotiotalnprsu (หรือรูปแบบอื่นที่ถูกต้อง)
print(rearrange_string("aabbcc", 3)) # abcabc
print(rearrange_string("aaabc", 3)) # ""
print(rearrange_string("aaadbbcc", 2)) # abacabcd
การทำงานของอัลกอริทึม (Queue-based)
วิธีนี้ใช้ Max Heap + Wait Queue แทนการคำนวณตำแหน่งแบบ Hard-code:
- Pop ตัวอักษร Frequency สูงสุดจาก Heap
- วางในตำแหน่งปัจจุบัน i
- หากยังเหลือ Count ใส่ Wait Queue พร้อม Next Available = i + d
- ก่อนรอบใหม่ ตรวจสอบ Wait Queue หาก Character พร้อม (Next Available ≤ i) ใส่กลับ Heap
- หาก Heap ว่างแต่ยังมีตำแหน่ง → Impossible
Complexity
- Time: O(n log k) โดย k = จำนวน Unique Characters (≤ 26 สำหรับ Lowercase)
- Space: O(n) สำหรับ Result + O(k) สำหรับ Heap/Queue