โจทย์: กำหนด string s และ list ของคำ words (ทุกคำยาวเท่ากัน) หา starting indices ทั้งหมดของ substring ใน s ที่เป็นการต่อกันของคำใน words ทุกคำครบถ้วน ไม่มีตัวอักษรแทรกแซง
ตัวอย่าง: s = "wordgoodgoodgoodword", words = ["word","good"] → indices [0, 12] เพราะ "wordgood" (index 0) และ "goodword" (index 12)
อัลกอริธึม (Sliding Window + Hash Map)
- นับ frequency ของแต่ละคำใน
words→wordCnt window = words.size() * word_len- Sliding window ขนาด
windowบนs:- ตรวจสอบ substring ใน window ว่าแบ่งเป็นคำได้ครบตาม
wordCnt(ฟังก์ชันok()) - ถ้าผ่าน → บันทึก index
- เลื่อน window 1 ตัวอักษร
- ตรวจสอบ substring ใน window ว่าแบ่งเป็นคำได้ครบตาม
ฟังก์ชัน ok(s, wordCnt, word_len)
- แยก
sเป็น chunks ยาวword_len - เช็คแต่ละ chunk ว่ามีใน
wordCntและยังเหลือ quota - ลด quota หรือลบ key เมื่อครบ
- คืน true ถ้า
wordCntว่างหมด
ตัวอย่างโค้ด C++
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v) {
cout << "[";
for (int i = 0; i < v.size(); i++) cout << v[i] << ", ";
cout << "]" << endl;
}
class Solution {
public:
bool ok(string s, unordered_map<string, int> wordCnt, int n) {
string temp = "";
for (int i = 0; i < n; i++) temp += s[i];
for (int i = n; i < s.size(); i++) {
if (temp.size() % n == 0) {
if (wordCnt.find(temp) == wordCnt.end()) return false;
if (wordCnt[temp] == 1) { wordCnt.erase(temp); temp = ""; }
else { wordCnt[temp]--; temp = ""; }
}
temp += s[i];
}
if (wordCnt.find(temp) == wordCnt.end()) return false;
if (wordCnt[temp] == 1) { wordCnt.erase(temp); temp = ""; }
else { wordCnt[temp]--; temp = ""; }
return wordCnt.size() == 0;
}
vector<int> findSubstring(string a, vector<string> &b) {
if (a.empty() || b.empty()) return {};
unordered_map<string, int> wordCnt;
for (auto &w : b) wordCnt[w]++;
vector<int> ans;
int window = b.size() * b[0].size();
string temp = "";
for (int i = 0; i < window; i++) temp += a[i];
for (int i = window; i < a.size(); i++) {
if (temp.size() % window == 0 && ok(temp, wordCnt, b[0].size()))
ans.push_back(i - window);
temp += a[i];
if (temp.size() > window) temp.erase(0, 1);
}
if (temp.size() % window == 0 && ok(temp, wordCnt, b[0].size()))
ans.push_back(a.size() - window);
return ans;
}
};
int main() {
vector<string> v = {"word","good"};
Solution ob;
print_vector(ob.findSubstring("wordgoodgoodgoodword", v));
}
อินพุต
"wordgoodgoodgoodword", {"word","good"}
เอาต์พุท
[0, 12, ]
Complexity
- Time: O(N * L) โดย N = |s|, L = window size
- Space: O(W) โดย W = จำนวนคำ unique