1016. 子串能表示从 1 到 N 数字的二进制串
给定一个二进制字符串 s 和一个正整数 n,如果对于 [1, n] 范围内的每个整数,其二进制表示都是 s 的 子字符串 ,就返回 true,否则返回 false 。
子字符串 是字符串中连续的字符序列。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/binary-string-with-substrings-representing-1-to-n
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
class Solution {
/**
* 2^k <= n <= 2^(k+1)
* [2^(k-1), 2^k-1]
* [2^k, n]
* <p>
* 比如k=5
* 2^(k-1)
* 10000
* 2^k-1
* 11111
* 2^k
* 100000
* 可见[2^(k-1), 2^k-1]包含[0, 2^k-1]
* <p>
* 设s的长度为m,则
* m >= 2^(k-1) + k
* m >= n - 2^k + 1 + k
*/
public boolean queryString(String s, int n) {
if (n == 1) {
return s.contains("1");
}
int k = 30;
while ((1 << k) > n) {
k--;
}
int m = s.length();
if (!((m >= (1 << (k - 1)) + k - 1) && (m >= n - (1 << k) + k + 1))) {
return false;
}
return help(s, k, (1 << (k - 1)), (1 << k) - 1) && help(s, k + 1, (1 << k), n);
}
private boolean help(String s, int k, int lower, int upper) {
Set<Integer> set = new HashSet<>();
int sum = 0;
for (int i = 0; i < s.length(); i++) {
sum = sum * 2 + (s.charAt(i) - '0');
if (i >= k - 1) {
if (sum >= lower && sum <= upper) {
set.add(sum);
}
sum -= ((s.charAt(i - k + 1) - '0') << (k - 1));
}
}
return set.size() == (upper - lower + 1);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
System.out.println(new Solution().queryString(in.next(), in.nextInt()));
}
}
}
心之所向,素履以往 生如逆旅,一苇以航

浙公网安备 33010602011771号