ปัญหา: Construct K Palindrome Strings
กำหนดสตริง s และจำนวนเต็ม k ต้องการสร้าง k สตริงพาลินโดรม (palindrome) ที่ไม่ว่างเปล่า โดยใช้ ตัวอักษรทั้งหมดใน s ตรวจสอบว่าเป็นไปได้หรือไม่
เงื่อนไขของพาลินโดรม
- ความยาวคี่: ต้องมีตัวอักษรที่มีความถี่เป็นเลขคี่ สูงสุด 1 ตัว (อยู่ตรงกลาง)
- ความยาวคู่: ตัวอักษรทุกตัวต้องมีความถี่เป็นเลขคู่
ข้อสังเกตสำคัญ
ถ้ามีตัวอักษรที่ความถี่เป็นเลขคี่ทั้งหมด odd ตัว แล้วเราต้องการสร้าง k พาลินโดรม → ต้องมี odd <= k เพราะแต่ละพาลินโดรมรับตัวอักษรคี่ได้สูงสุด 1 ตัว
แนวทางแก้ปัญหา
- ถ้า
n = s.length() < k→ false (ตัวอักษรไม่พอให้แต่ละสตริงมีอย่างน้อย 1 ตัว) - ถ้า
n == k→ true (แต่ละตัวอักษรเป็นสตริงเดี่ยว ซึ่งเป็นพาลินโดรม) - นับความถี่ตัวอักษรแต่ละตัว (ใช้ map/array)
- นับจำนวนตัวอักษรที่มีความถี่คี่ →
odd - คืนค่า
odd <= k
ตัวอย่างโค้ด C++
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
bool canConstruct(string s, int k) {
int n = s.size();
if (n < k) return false;
if (n == k) return true;
unordered_map<char, int> freq;
for (char c : s) freq[c]++;
int odd = 0;
for (auto& [ch, cnt] : freq)
if (cnt % 2 == 1) odd++;
return odd <= k;
}
};
int main() {
Solution ob;
cout << ob.canConstruct("true", 4); // Output: 1 (true)
return 0;
}
ตัวอย่างการทำงาน
s = "true", k = 4
- ความถี่: t:1, r:1, u:1, e:1 →
odd = 4 odd (4) <= k (4)→ true- จัดเป็น:
"t","r","u","e"(ทุกตัวเป็นพาลินโดรม)
ความซับซ้อน
- เวลา: O(n) – วนลูปนับความถี่ครั้งเดียว
- พื้นที่: O(1) – ตัวอักษร high 26 ตัว (lowercase) หรือ 52 ตัว (รวม uppercase)
ข้อสังเกตเพิ่มเติม
- ไม่จำเป็นต้องสร้างพาลินโดรมจริง – ตรวจสอบเงื่อนไขเพียงพอแล้ว
- กรณี
k > nจัดการได้ที่เงื่อนไขแรก - ใช้
unordered_mapเร็วกว่าmapสำหรับการนับความถี่