作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/binary-string-with-substrings-representing-1-to-n/
题目描述
Given a binary string S
(a string consisting only of ‘0’ and '1’s) and a positive integer N
, return true if and only if for every integer X from 1 to N, the binary representation of X is a substring of S.
Example 1:
Input: S = "0110", N = 3
Output: true
Example 2:
Input: S = "0110", N = 4
Output: false
Note:
1 <= S.length <= 1000
1 <= N <= 10^9
题目大意
判断小于等于N的所有正整数,其二进制是否都在S中出现。
解题方法
还是看Note,我们发现S的长度不算太长,但是N的范围倒是挺大的。如果暴力从1循环到N进行查找判断,一定会超时。
这个时候就来了个技巧:倒序遍历!我们判断从N到1是否都在S中出现。
109的二进制有30位,而109的二进制和10^9 - 1的二进制分别如下:
bin(10**9) = '0b111011100110101100101000000000'
bin(10**9 - 1) = '0b111011100110101100100111111111'
可以看到两者的二进制的前半部分相等,而最后部分存在差异。那么,我们考虑一下,如果bin(10**9)
在S中出现了,那么bin(10**9 - 1)
也在S中出现的概率大吗?很明显这个概率应该是很小的,哪怕同时出现了,对于S只有长度1000来说,顶多也只能存在30个左右的不同32位的二进制字符串。
所以,这种先判断大的数字、长的二进制表示的字符串是否在S中出现的策略效率是非常高的。相反如果从1,2,3……这些数字从小到大进行判断,那么每个数字出现的概率都很大,需要找更多的数字才行,很可能会超时。
Python代码如下:
class Solution(object):
def queryString(self, S, N):
"""
:type S: str
:type N: int
:rtype: bool
"""
return all(bin(n)[2:] in S for n in range(N, 0, -1))
参考资料:https://leetcode.com/problems/best-sightseeing-pair/discuss/260850/JavaC%2B%2BPython-One-Pass
日期
2019 年 3 月 24 日 —— 这个周赛太悲催了