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

Python - หาสับสตริง 1 ติดกันยาวที่สุดหลังพลิก 0 ได้ 1 ครั้ง

โจทย์: กำหนดสตริงไบนารี s อนุญาตให้พลิก 0 เป็น 1 ได้สูงสุด 1 ครั้ง หาความยาวของสับสตริง (Contiguous Substring) ที่เป็น 1 ทั้งหมดยาวที่สุด

ตัวอย่าง

Input: s = "1010110001"
Output: 4
เหตุผล: พลิก 0 ตัวที่ index 3 ได้ "1011110001" สับสตริง 1 ติดกันยาวสุด = 4 (1111)

อัลกอริทึม: Sliding Window (Two Pointers)

รักษาหน้าต่างที่มี 0 สูงสุด 1 ตัว โดยใช้ left, right และนับจำนวน 1 (ones)

ขั้นตอนการทำงาน

  1. left = right = 0, ones = 0, ans = 0
  2. ขยาย right ไปทางขวา:
    • หาก s[right] == '1' → ones++
  3. ขณะที่ (right - left + 1) - ones > 1 (มี 0 มากกว่า 1 ตัว):
    • ย่อหน้าต่างซ้าย: หาก s[left] == '1' → ones--
    • left++
  4. อัปเดต ans = max(ans, right - left + 1)
  5. right++ และทำซ้ำ

โค้ด Python

def solve(s):
    n = len(s)
    ans = ones = left = right = 0
    
    while right < n:
        if s[right] == "1":
            ones += 1
        
        # หน้าต่างมี 0 มากกว่า 1 ตัว → ย่อซ้าย
        while right - left + 1 - ones > 1:
            remove = s[left]
            if remove == "1":
                ones -= 1
            left += 1
        
        ans = max(ans, right - left + 1)
        right += 1
    
    return ans

# ทดสอบ
s = "1010110001"
print(solve(s))  # Output: 4

การทำงานทีละขั้นตอน (Trace)

s = "1 0 1 0 1 1 0 0 0 1"

rightcharoneswindowzerosleftans
011[0:0]001
101[0:1]102
212[0:2]103
302[0:3]213
413[1:4]114
514[1:5]114
604[1:6]224
704[2:7]234
804[3:8]244
915[4:9]144

ความซับซ้อน

  • Time Complexity: O(n) - แต่ละตัวอักษรถูกเพิ่ม/ลบจากหน้าต่างสูงสุด 1 ครั้ง
  • Space Complexity: O(1)

การขยาย: พลิกได้ k ครั้ง

def solve_k_flips(s, k):
    n = len(s)
    ans = ones = left = 0
    for right in range(n):
        if s[right] == "1":
            ones += 1
        while right - left + 1 - ones > k:
            if s[left] == "1":
                ones -= 1
            left += 1
        ans = max(ans, right - left + 1)
    return ans