1

Passed some test cases, but after submission, the time limit exceeded. How to optimize solution to reduce time complexity?

A large binary number is represented by a string A of size N and comprises of 0s and 1s. You must perform a cyclic shift on this string. The cyclic shift operation is defined as follows:

If the string A is [A0, A1,..., An-1], then after performing one cyclic shift, the string becomes [A1, A2,..., An-1, A0].

You performed the shift infinite number of times and each time you recorded the value of the binary number represented by the string. The maximum binary number formed after performing (possibly 0) the operation is B. Your task is to determine the number of cyclic shifts that can be performed such that the value represented by the string A will be equal to B for the Kth time.

Input format:

First line: A single integer T denoting the number of test cases For each test case: First line: Two space-separated integers N and K Second line: A denoting the string

Output format:

For each test case, print a single line containing one integer that represents the number of cyclic shift operations performed such that the value represented by string A is equal to B for the Kth time.

num_test_cases = int(input())
for i in range(num_test_cases):
    array_length, num_of_repetition = map(int, input().split())

    count = 0
    bin_num = input()
    original_bin_num = bin_num
    dec_num = int(bin_num, 2)
    maximum = dec_num
    dec_num_array = [dec_num]

    for j in range(array_length - 1):
        bin_num = bin_num[1:] + bin_num[0]
        if bin_num == original_bin_num:
            break
        dec_num = int(bin_num, 2) 
        dec_num_array.append(dec_num)
    maximum = max(dec_num_array)
    maxIndex = dec_num_array.index(maximum)
    num_cyclic_shifts = 0
    for kek in range(num_of_repetition):
        if kek == 0:
            num_cyclic_shifts += maxIndex
        elif len(dec_num_array) == array_length:
            num_cyclic_shifts += array_length
        elif len(dec_num_array) < array_length:
            num_cyclic_shifts += len(dec_num_array)        
    print(num_cyclic_shifts)
Ajay Singh
  • 1,251
  • 14
  • 17
pepega
  • 25
  • 8
  • 1
    https://en.wikipedia.org/wiki/Lexicographically_minimal_string_rotation may be helpful. – David Eisenstat Sep 24 '20 at 23:33
  • 1
    These competitive-programming tasks always have a twist such that the straightforward solutions (as you did it) exceed the time limit. Hint: the biggest binary number of a given length is one of those beginning with the longest run of '1' characters. – Ralf Kleberhoff Sep 25 '20 at 11:23

1 Answers1

1

Since you asked for optimization of your code here's how I did it. Replace the last for loop with a formula.

num_cyclic_shifts = maxIndex + (len(dec_num_array) * (num_of_repetition-1))

Entire code will become ,

num_test_cases = int(input())
for i in range(num_test_cases):
    array_length, num_of_repetition = map(int, input().split())

    count = 0
    bin_num = input()
    original_bin_num = bin_num
    dec_num = int(bin_num, 2)
    maximum = dec_num
    dec_num_array = [dec_num]

    for j in range(array_length - 1):
        bin_num = bin_num[1:] + bin_num[0]
        if bin_num == original_bin_num:
            break
        dec_num = int(bin_num, 2)
        dec_num_array.append(dec_num)
    maximum = max(dec_num_array)
    maxIndex = dec_num_array.index(maximum)
    num_cyclic_shifts = maxIndex + (len(dec_num_array) * (num_of_repetition-1))
    print(num_cyclic_shifts)
Ashazam
  • 11
  • 1
  • it is indeed a nice improvement, but how did you come up with that formula? where can I get more information about it? – Bechma May 30 '21 at 00:46
  • 1
    @Bechma solution is within that for loop. If `number_of_repetition`=0 then we can get `maxIndex` as number of shifts since cyclic shift will correspond to index. Now when `number_of_repetition`>0 we have to traverse entire `dec_num_array` ,so length of array is multiplied and added to `maxIndex`. – Ashazam Jun 01 '21 at 12:59