指尖劃過的軌跡,藏着最細膩的答案~

題目:

給你一個二進制字符串 s 和一個整數 k 。如果所有長度為 k 的二進制字符串都是 s 的子串,請返回 true ,否則請返回 false

示例 1:

輸入:s = "00110110", k = 2
輸出:true
解釋:長度為 2 的二進制串包括 "00","01","10" 和 "11"。它們分別是 s 中下標為 0,1,3,2 開始的長度為 2 的子串。

示例 2:

輸入:s = "0110", k = 1
輸出:true
解釋:長度為 1 的二進制串包括 "0" 和 "1",顯然它們都是 s 的子串。

示例 3:

輸入:s = "0110", k = 2
輸出:false
解釋:長度為 2 的二進制串 "00" 沒有出現在 s 中。

提示:

$1 \leq s.length \leq 5 \times 10^5$
$s[i]$ 不是'0' 就是 '1'
$1 \leq k \leq 20$

分析:

本題需要在長度為n的字符串s中,尋找滿足條件的長度為k的子串,而這可以用定長滑動窗口:進入窗口——更新答案——離開窗口來解決。

我們可以使用一個哈希表set將字符串s中出現的長度為k的子字符串全部存起來,然後計算長度為k的的二進制子串的數量total = 1 << k,如果set.size() == total説明字符串s有所有的長度為 k 的二進制字符串,為True,否則為false

AC代碼:

class Solution {
public:
    bool hasAllCodes(string s, int k) {
        int n = s.size();
        unordered_set<string> st;
        string subS = s.substr(0, k);

        st.insert(subS);
        for (int i = k; i < n; i++) {
            subS = subS.substr(1) + s[i];
            st.insert(subS);
        }

        int total = 1 << k; // 2^k
        if (total != st.size()) {
            return false;
        }

        return true;
    }
};