โจทย์: กำหนดสตริงพิมพ์เล็ก s ประกอบด้วยตัวอักษรและสัญลักษณ์ '?' แต่ละ '?' สามารถลบหรือแทนที่ด้วยตัวอักษรพิมพ์เล็กได้ ต้องการหาความยาวของซับสตริงที่เพิ่มขึ้นติดกัน (Consecutive Increasing) ยาวที่สุดที่ ขึ้นต้นด้วย 'a'
ตัวอย่าง
Input: s = "vta???defke"
Output: 6
เหตุผล: แทน '?' เป็น 'b','c','d' ได้ "vtabcdefke" ซับสตริง "abcdef" ยาว 6 ตัว เริ่มด้วย 'a' และเพิ่มขึ้นติดกัน
อัลกอริทึม: Single Pass Greedy
ใช้ตัวแปรติดตามสถานะปัจจุบัน: length (ความยาวลำดับปัจจุบัน), qmarks (จำนวน '?' สะสม), maxlen (คำตอบ)
ขั้นตอนการทำงาน
- วนอ่านตัวอักษร
cในs - หาก
c == '?': เพิ่มqmarks - หากเป็นตัวอักษร:
- คำนวณ
idx = ord(c) - ord('a')(0=a, 1=b, ..., 25=z) - อัปเดต
length:- หาก
length <= idx <= length + qmarks→ ขยายลำดับได้:length = idx + 1 - หาก
idx <= qmarks→ เริ่มลำดับใหม่จาก 'a' ผ่าน '?':length = idx + 1 - อื่นๆ → รีเซ็ต:
length = 0
- หาก
- รีเซ็ต
qmarks = 0
- คำนวณ
- อัปเดต
maxlen = max(maxlen, min(length + qmarks, 26))(สูงสุด 26 ตัวอักษร)
โค้ด Python
def solve(s):
maxlen = length = qmarks = 0
for c in s:
if c == "?":
qmarks += 1
else:
idx = ord(c) - ord("a")
# ตรวจสอบว่าตัวอักษรนี้ต่อยอดลำดับได้หรือไม่
if length <= idx <= length + qmarks or idx <= qmarks:
length = idx + 1
else:
length = 0
qmarks = 0
maxlen = max(maxlen, min(length + qmarks, 26))
return maxlen
# ทดสอบ
s = "vta???defke"
print(solve(s)) # Output: 6
การทำงานทีละขั้นตอน (Trace)
s = "v t a ? ? ? d e f k e"
| c | idx | qmarks | length | maxlen | คำอธิบาย |
|---|---|---|---|---|---|
| v | 21 | 0 | 0 | 0 | idx > qmarks, length=0 → reset |
| t | 19 | 0 | 0 | 0 | idx > qmarks → reset |
| a | 0 | 0 | 1 | 1 | idx=0 <= qmarks(0) → length=1 |
| ? | - | 1 | 1 | 2 | สะสม ? |
| ? | - | 2 | 1 | 3 | สะสม ? |
| ? | - | 3 | 1 | 4 | สะสม ? |
| d | 3 | 0 | 4 | 4 | length(1)<=3<=length+qmarks(4) → length=4 |
| e | 4 | 0 | 5 | 5 | ต่อเนื่อง → length=5 |
| f | 5 | 0 | 6 | 6 | ต่อเนื่อง → length=6 |
| k | 10 | 0 | 0 | 6 | ขาด b,c,d,e,g,h,i,j → reset |
| e | 4 | 0 | 0 | 6 | idx=4 > qmarks=0 → reset |
ความซับซ้อน
- Time Complexity: O(n) - ผ่านสตริง 1 รอบ
- Space Complexity: O(1) - ตัวแปรคงที่
ข้อสังเกตสำคัญ
- ลำดับต้องเริ่มด้วย 'a' (idx=0) เสมอ
'?'ใช้เป็น "ตัวเติม" ได้ แต่ต้องต่อเนื่อง- ความยาวสูงสุดคือ 26 (a-z)
- เงื่อนไข
idx <= qmarksจัดการกรณีเริ่มใหม่จาก 'a' ผ่าน '?' (เช่น "???c" → "abc")