Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Chương trình tìm độ dài chuỗi con thỏa mãn điều kiện về số 0 và 1 trong Python

Cho chuỗi input_str và số nguyên k. Lặp chuỗi k lần thành chuỗi mới. Tìm độ dài chuỗi con dài nhất thỏa mãn: 2 × (số 0) ≤ 3 × (số 1).

Ví dụ

Input: k=2, input_str='0101011' → Output: 14

Chuỗi mới: '01010110101011' (độ dài 14). Số 0: 6, số 1: 8. 2×6=12 ≤ 3×8=24. Toàn bộ chuỗi thỏa mãn.

Thuật toán (Prefix Sum + Binary Search)

Biến đổi điều kiện: 2×zeros - 3×ones ≤ 0. Gán trọng số: '0' → +2, '1' → -3. Tìm chuỗi con dài nhất có tổng trọng số ≤ 0.

  1. Tính mảng prefix sum list_a của trọng số
  2. Tạo mảng list_b = [(prefix_value, index)] và sắp xếp
  3. Tính temp_list: max index cho mỗi prefix value trong list_b đã sắp xếp
  4. Duyệt từng vị trí i, dùng binary search (bisect_left) tìm vị trí xa nhất thỏa mãn
  5. Xử lý trường hợp lặp k lần bằng cách nhân với tổng trọng số của một chuỗi gốc

Mã nguồn

from bisect import bisect_left

def solve(k, input_str):
    str_len = len(input_str)
    list_a = [0] * (str_len + 1)
    list_b = [0] * (str_len + 1)
    list_b[0] = (0, 0)
    
    for i in range(str_len):
        list_a[i + 1] = list_a[i] - 3 * (input_str[i] == '1') + 2 * (input_str[i] == '0')
        list_b[i + 1] = (list_a[i + 1], i + 1)
    
    list_b.sort()
    temp_list = [0] * (str_len + 1)
    temp_list[0] = list_b[0][1]
    for i in range(str_len):
        temp_list[i + 1] = max(temp_list[i], list_b[i + 1][1])
    
    res = 0
    for i in range(str_len):
        tmp = list_b[0][0] - list_a[i]
        if list_a[str_len] <= 0:
            a = k - 1
            if tmp + list_a[str_len] * a > 0:
                continue
        elif tmp > 0:
            continue
        else:
            a = min(k - 1, -tmp // list_a[str_len])
        v = a * list_a[str_len] - list_a[i]
        b = bisect_left(list_b, (-v + 1, 0)) - 1
        res = max(res, temp_list[b] - i + a * str_len)
    return res

print(solve(2, '0101011'))  # Output: 14

Phân tích độ phức tạp

  • Thời gian: O(L log L) với L = len(input_str)
  • Không gian: O(L)
  • Không phụ thuộc vào k (xử lý lặp bằng toán học)