Program to find out the length of the substring where two times the number of zeroes in substring is lesser than or equal to three times the number of ones in the substring in Python


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

Updated on: 20-Oct-2021

152 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements