Suppose we are given a string and an integer k. The string is repeated k times and made to another string. Our task is to find the length of the substring in the new string where 2 * (number of zeroes in substring) <= 3 * (number of ones in the substring).
So, if the input is like k = 2, input_str = '0101011', then the output will be 14.
The string is of length 7. So, the new string that is made from the first string is 01010110101011. Here the number of 0s is 6, and the number of 1s is 8. So, 2 * 6 <= 3 * 8. The largest substring is thus the whole string of length 14.
To solve this, we will follow these steps −
- str_len := size of input_str
- list_a := a new list of size (str_len + 1) initialized with 0s
- list_b := a new list of size (str_len + 1) initialized with 0s
- list_b[0] := a new pair containing (0, 0)
- for i in range 0 to str_len, do
- list_a[i + 1] := list_a[i] - 3 *(1 if input_str[i] is same as '1', else 0) + 2 *(1 if input_str[i] is same as '0', else 0)
- list_b[i + 1] := a new pair consisting (list_a[i + 1], i + 1)
- sort the list list_b
- temp_list := a new list of size (str_len + 1) initialized with 0s
- temp_list[0] := list_b[0, 1]
- for i in range 0 to str_len, do
- temp_list[i + 1] = maximum of (temp_list[i], list_b[i + 1, 1])
- res := 0
- for i in range 0 to str_len, do
- tmp := list_b[0, 0] - list_a[i]
- if list_a[str_len] <= 0, then
- a := k - 1
- if tmp + list_a[str_len] * a > 0, then
- go for the next iteration
- otherwise when tmp > 0, then
- go for the next iteration
- otherwise,
- a := minimum of (k - 1, floor value of (-tmp / list_a[str_len]))
- v := a * list_a[str_len] - list_a[i]
- b := (the position in list_b where the pair (-v + 1, 0) can be inserted maintaining the sorted order) - 1
- res := maximum of (res, temp_list[b] - i + a * str_len)
- return res
Example
Let us see the following implementation to get better understanding −
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'))
Input
2, '0101011'
Output
14