467 words
2 minutes
力扣每日一题 20260223
1461. 检查一个字符串是否包含所有长度为 K 的二进制子串
看了下数据范围感觉很宽,我们可以用暴力枚举的做法。
首先考虑长度为 的 字符串有 种,所以我们可以枚举字符串 的所有长度为 的字串,丢到哈希表里,最后看哈希表里有没有 个元素就好了,复杂度 。
代码:
class Solution {public: bool hasAllCodes(string s, int k) { if (s.size() < k) return false; unordered_map<int, int> mp; for (int i = 0; i <= s.size() - k; i++) { int x = stoi(s.substr(i, k), nullptr, 2); mp[x] = 1; } if (mp.size() == (1 << k)) return true; else return false; }};上面是最简单粗暴的做法,我们可以在循环里加一个剪枝,如果提前找到了 种子串就直接返回掉。
代码:
class Solution {public: bool hasAllCodes(string s, int k) { if (s.size() < k) return false; unordered_map<int, int> mp; for (int i = 0; i <= s.size() - k; i++) { int x = stoi(s.substr(i, k), nullptr, 2); mp[x] = 1; //这里喵↓ if (mp.size() == (1 << k)) return true; } if (mp.size() == (1 << k)) return true; else return false; }};再继续想,考虑到我们枚举每个子串是不是很像滑动窗口,那我们完全没必要用 的复杂度去取子串,我们只需要在枚举下一个子串的时候减掉丢下去那位,加上新进来的那位(通过左右移就可以实现),这样我们能剩一个 的复杂度,把复杂度降到 。
代码:
class Solution {public: bool hasAllCodes(string s, int k) { if (s.size() < k) return false; int mask = (1 << k) - 1, x = 0; unordered_map<int, int> mp; for (int i = 0; i < s.size(); i++) { x = (x << 1 & mask) | (s[i] & 1); if (i + 1 >= k) mp[x] = 1; if (mp.size() == (1 << k)) return true; } if (mp.size() == (1 << k)) return true; else return false; }}; 力扣每日一题 20260223
https://fuwari.vercel.app/posts/leetcode_daily/0223/