1016. 子串能表示从 1 到 N 数字的二进制串
来源第 129 场周赛 Q4难度中等分数1779
题目描述
给定一个二进制字符串 s 和一个正整数 n,如果对于 [1, n] 范围内的每个整数,其二进制表示都是 s 的 子字符串 ,就返回 true,否则返回 false 。
子字符串 是字符串中连续的字符序列。
示例 1:
输入:s = "0110", n = 3 输出:true
示例 2:
输入:s = "0110", n = 4 输出:false
提示:
1 <= s.length <= 1000s[i]不是'0'就是'1'1 <= n <= 109
解法
方法一:脑筋急转弯
思考
\(n\) 可达 \(10^9\),逐个检查 \([1,n]\) 的二进制是否为 \(s\) 的子串不可行。\(s\) 长度至多 \(1000\),它能提供的互异子串远少于 \(10^9\),故 \(n>1000\) 时可直接判否。
若整数 \(x\) 的二进制出现在 \(s\) 中,则 \(\lfloor x/2\rfloor\) 相当于去掉最低位,也一定作为子串出现。因此只需验证较大的一半,即 \([\lfloor n/2\rfloor+1,n]\)。
在 \(n\le 1000\) 的前提下对这些值调用子串查找即可。
我们注意到,字符串 \(s\) 的长度不超过 \(1000\),所以字符串 \(s\) 能表示不超过 \(1000\) 个 二进制整数,因此,如果 \(n \gt 1000\),那么 \(s\) 肯定不能表示 \([1,.. n]\) 范围内的所有整数的二进制表示。
另外,对于一个整数 \(x\),如果 \(x\) 的二进制表示是 \(s\) 的子串,那么 \(\lfloor x / 2 \rfloor\) 的二进制表示也是 \(s\) 的子串。因此,我们只需要判断 \([\lfloor n / 2 \rfloor + 1,.. n]\) 范围内的整数的二进制表示是否是 \(s\) 的子串即可。
时间复杂度 \(O(m^2 \times \log m)\),空间复杂度 \(O(\log n)\),其中 \(m\) 是字符串 \(s\) 的长度,而 \(n\) 为题目给定的正整数。
1 2 3 4 5 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 9 10 11 | |