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

โปรแกรม Python ถอดรหัสเพื่อปลดระเบิด (Decrypt Code to Defuse Bomb)

โจทย์: มีรหัสเป็น Circular Array code ความยาว n และ Key k ต้องถอดรหัสโดยแทนที่ทุกตัวเลขพร้อมกัน:

  • k > 0: แทนที่ตัวที่ i ด้วยผลรวมของ k ตัวถัดไป
  • k < 0: แทนที่ตัวที่ i ด้วยผลรวมของ |k| ตัวก่อนหน้า
  • k = 0: แทนที่ทุกตัวด้วย 0

Circular: ตัวถัดไปของ code[n-1] คือ code[0], ตัวก่อนหน้าของ code[0] คือ code[n-1]

ตัวอย่าง

  • Input: code = [8, 2, 3, 5], k = 3
  • Output: [10, 16, 15, 13]
i=0: next 3 = code[1]+code[2]+code[3] = 2+3+5 = 10
i=1: next 3 = code[2]+code[3]+code[0] = 3+5+8 = 16
i=2: next 3 = code[3]+code[0]+code[1] = 5+8+2 = 15
i=3: next 3 = code[0]+code[1]+code[2] = 8+2+3 = 13

โค้ด Python (O(n) Sliding Window)

def decrypt(code, k):
    """
    ถอดรหัส Circular Array
    
    Args:
        code: List[int] - รหัสต้นฉบับ
        k: int - Key (บวก = ถัดไป, ลบ = ก่อนหน้า, 0 = ทั้งหมดเป็น 0)
    
    Returns:
        List[int] - รหัสที่ถอดแล้ว
    """
    n = len(code)
    if k == 0:
        return [0] * n
    
    result = [0] * n
    
    if k > 0:
        # Sliding Window สำหรับ Next k elements
        # เริ่มต้น: ผลรวมของ code[1] ถึง code[k]
        window_sum = sum(code[1:k+1])
        
        for i in range(n):
            result[i] = window_sum
            # เลื่อน Window: ลบ code[i+1], เพิ่ม code[i+k+1]
            window_sum -= code[(i + 1) % n]
            window_sum += code[(i + k + 1) % n]
    
    else:  # k < 0
        # Sliding Window สำหรับ Previous |k| elements
        k_abs = -k
        # เริ่มต้น: ผลรวมของ code[n-k_abs] ถึง code[n-1]
        window_sum = sum(code[n - k_abs:])
        
        for i in range(n):
            result[i] = window_sum
            # เลื่อน Window: ลบ code[i-k_abs], เพิ่ม code[i]
            window_sum -= code[(i - k_abs) % n]
            window_sum += code[i % n]
    
    return result


# ทดสอบ
if __name__ == "__main__":
    # Test Case 1
    code = [8, 2, 3, 5]
    k = 3
    print(f"code={code}, k={k} => {decrypt(code, k)}")
    # Expected: [10, 16, 15, 13]

    # Test Case 2: k < 0
    code = [8, 2, 3, 5]
    k = -2
    print(f"code={code}, k={k} => {decrypt(code, k)}")
    # i=0: prev 2 = code[3]+code[2] = 5+3=8? Wait...
    # Previous 2 of index 0: indices (0-1)%4=3, (0-2)%4=2 => code[3]+code[2]=5+3=8
    # i=1: indices 0,3 => 8+5=13
    # i=2: indices 1,0 => 2+8=10
    # i=3: indices 2,1 => 3+2=5
    # Expected: [8, 13, 10, 5]

    # Test Case 3: k = 0
    code = [1, 2, 3, 4]
    k = 0
    print(f"code={code}, k={k} => {decrypt(code, k)}")
    # Expected: [0, 0, 0, 0]

    # Test Case 4: Single element
    code = [5]
    k = 1
    print(f"code={code}, k={k} => {decrypt(code, k)}")
    # Expected: [5] (next 1 is itself)

ผลลัพธ์

code=[8, 2, 3, 5], k=3 => [10, 16, 15, 13]
code=[8, 2, 3, 5], k=-2 => [8, 13, 10, 5]
code=[1, 2, 3, 4], k=0 => [0, 0, 0, 0]
code=[5], k=1 => [5]

Complexity Analysis

  • Time: O(n) - Single pass ด้วย Sliding Window
  • Space: O(n) สำหรับ Result Array
  • ดีกว่า Naive O(n×|k|) มากเมื่อ |k| ใหญ่

การอธิบาย Sliding Window

แทนที่จะคำนวณผลรวมใหม่ทุกครั้ง (O(k)) ให้รักษา Window Sum และอัปเดตโดย:

  • ลบ Element ที่ออกจาก Window
  • บวก Element ที่เข้า Window ใหม่
  • ใช้ Modulo % n จัดการ Circular Index

LeetCode Reference

Problem 1652: "Defuse the Bomb" - Medium