[LeetCode:Check If a String Contains All Binary Codes of Size K] | 刷题打卡
真心求大家关注和点赞,原创不易,你们的支持是我写作的最大动力!
题目描述
给你一个只包括二进制数的字符串 s 和整数 k,如果每个长度为 k 的二进制串都是 s 的字串(substring)返回 true,否则返回 false(注意:substring 和 subsequence 的区别)
例一:
输入: s = "00110110", k = 2
输出: true
解释: 长度为 2 的二进制串都有:"00", "01", "10" 和 "11". 他们都是 s 的字串
例二:
输入: s = "00110", k = 2
输出: true
例三:
输入: s = "0110", k = 1
输出: true
解释: 长度为 1 的二进制串只有:"0" 和 "1", 他们也都是 s 的字串
例四:
输入: s = "0110", k = 2
输出: false
解释: 长度为 2 的二进制串 "00" 不是 s 的字串(但是是子序列)
例五:
输入: s = "0000000001011100", k = 4
输出: false
思路分析
题目很短也很好理解,看完后思路应该很快就有了:先求所有长度为 k 的二进制串,然后判断所有的二进制串是不是都是 s 的字串。
解题前需要明确的问题也很清晰:
- 如何求所有长度为 k 的二进制串
- 如何判断字符串是否是另一个串的字串
问题一:如何求所有长度为 k 的二进制串
不用多想,一定是个回溯问题!长度为 k 的字符串的每一位都有 0 和 1 两种填充可能,一共有 2k 种结果。写出如下回溯代码:
const getBinaryCodes = (n) => {
const result = []; // 保存最终结果
const base = [0, 1]; // 待选集合只有 0 和 1
const backtrace = (len, cur) => {
if (len === 0) {
// 长度为 0 表示找到一个目标串
result.push(cur);
return;
}
for (let i = 0; i < base.length; i++) {
// 对于每个 cur,都分别拼接 0 和 1
backtrace(len - 1, `${cur}${base[i]}`);
}
};
// 初始条件长度为 n,cur 为空字符串
backtrace(n, "");
return result;
};
问题二:如何判断字符串是否是另一个串的字串
我用了一种取巧偷懒的方式,使用 ES String 原型对象的 includes 方法来判断...(别骂我...) ,最后用数组原型方法 every 去判断是不是每个字串都是 s 的字串。虽然能 AC,但是非常非常耗时!
这个时候我又把问题抛给了学会计的女朋友,一通题目说明后,她说可以先把字符串 s 的所有长度为 k 的字串都找到,然后判断个数是否等于 2 的 k 次方就可以了呀!
Ohhhhhhh!
瞬间感觉费半天劲儿写回溯,判断字串是否是字串的我好蠢,被秒的渣都不剩。
AC 代码
var hasAllCodes = function (s, k) {
const set = new Set();
for (let i = 0; i <= s.length - k; i++) {
set.add(s.substr(i, k));
if (set.size === Math.pow(2, k)) {
return true;
}
}
return false;
};
总结
题目中有些特殊条件一定是可以帮你优化时间复杂度的,比如这道题中的待选字串只有 0 和 1,再比如:Remove Palindromic Subsequences 中的字串只限制为 a 和 b,再再再比如有序的数字序列的查找用二分法,再再再再比如求最值的动态规划,等等这些信号都在告诉你,别用蛮力,这道题有迹可循!
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!