找到旋转的最大二进制数,超过时间限制

Posted

技术标签:

【中文标题】找到旋转的最大二进制数,超过时间限制【英文标题】:Find maximum binary number with rotations, exceed time limit 【发布时间】:2020-09-24 22:33:46 【问题描述】:

通过了一些测试用例,但是提交后超过了时限。如何优化解决方案以降低时间复杂度?

一个大的二进制数由一个大小为 N 的字符串 A 表示,并且 由 0 和 1 组成。您必须对此执行循环移位 细绳。循环移位操作定义如下:

如果字符串 A 是 [A0, A1,..., An-1],那么在执行一个 循环移位,字符串变为[A1, A2,..., An-1, A0]。

你执行了无数次换档,每次你 记录了字符串表示的二进制数的值。这 执行(可能为 0)后形成的最大二进制数 操作是 B。你的任务是确定循环移位的次数 可以这样执行,使得字符串 A 表示的值 第 K 次等于 B。

输入格式:

第一行:一个整数 T 表示测试用例的数量 For 每个测试用例: 第一行:两个空格分隔的整数 N 和 K 第二行:A表示字符串

输出格式:

对于每个测试用例,打印一行包含一个整数 表示执行的循环移位操作的数量,使得 字符串A表示的值第K次等于B。

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)

【问题讨论】:

en.wikipedia.org/wiki/Lexicographically_minimal_string_rotation 可能会有所帮助。 这些竞争性的编程任务总是有曲折,以至于直接的解决方案(就像你做的那样)超过了时间限制。提示:给定长度的最大二进制数是以最长的 '1' 字符开头的二进制数之一。 【参考方案1】:

既然您要求优化您的代码,我就是这样做的。 用公式替换最后一个 for 循环。

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

整个代码将变成,

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)

【讨论】:

这确实是一个不错的改进,但是您是如何得出这个公式的?我在哪里可以获得有关它的更多信息? @Bechma 解决方案在 for 循环中。如果number_of_repetition=0 那么我们可以得到maxIndex 作为移位数,因为循环移位将对应于索引。现在当number_of_repetition>0 时,我们必须遍历整个dec_num_array,所以数组的长度相乘并添加到maxIndex

以上是关于找到旋转的最大二进制数,超过时间限制的主要内容,如果未能解决你的问题,请参考以下文章

问题 1110: 2^k进制数

Windows句柄数限制

故障分析 一次因为超过最大连接数的登陆限制

LeetCode 693. 交替位二进制数 / 2024. 考试的最大困扰度 / 1606. 找到处理最多请求的服务器

基础练习 ——十六进制转十进制

在 Swift 中将用户输入限制为有效的十进制数