1461 Check If a String Contains All Binary Codes of Size K

Given a binary string s and an integer k.

Return True if every binary code of length k is a substring of s. Otherwise, return False.

Example 1:

Input: s = "00110110", k = 2
Output: true
Explanation: The binary codes of length 2 are "00", "01", "10" and "11". They can be all found as substrings at indicies 0, 1, 3 and 2 respectively.

Example 2:

Input: s = "00110", k = 2
Output: true

Example 3:

Input: s = "0110", k = 1
Output: true
Explanation: The binary codes of length 1 are "0" and "1", it is clear that both exist as a substring. 

Example 4:

Input: s = "0110", k = 2
Output: false
Explanation: The binary code "00" is of length 2 and doesn't exist in the array.

Example 5:

Input: s = "0000000001011100", k = 4
Output: false

其实这一题觉得主要考的是trade off。因为生成substring的时间和空间复杂度是O(nk),生成二进制,用rolling hash的话,可以T:O(n),但S是O(2^k)。hash的解法也写下来参考。

rollinghash 思路:譬如我们k=3,s=“11010110”,那么第一个hash是110,然后第二个是101。那么怎么快速从110的hash算出101呢?首先我们吧110左移1位变成1100,然后&上111(k的长度个的1),100。然后加上新进来的1,101。所以公式是:newhash = ((oldhash << 1) & allone) | lastdigit of new hash

public boolean hasAllCodes(String s, int k) {
    if (s == null || s.length() < 1 || k < 1) {
        return false;
    }

    int numOfBinShouldBe = 1 << k;        
    Set<String> subStrings = new HashSet<>();
    for (int i = k; i <= s.length(); i++) {
        String subStr = s.substring(i - k, i);
        if (!subStrings.contains(subStr)) {
            subStrings.add(subStr);
            numOfBinShouldBe--;
            if (numOfBinShouldBe == 0) {
                return true;
            }
        }            
    }

    return false;
}

// 解法二:hash
public static boolean hasAllCodes(String s, int k) {
    int need = 1 << k;
    boolean[] got = new boolean[need];
    int allOne = need - 1;
    int hashVal = 0;

    for (int i = 0; i < s.length(); i++) {
        // calculate hash for s.substr(i-k+1,i+1)
        hashVal = ((hashVal << 1) & allOne) | (s.charAt(i) - '0');
        // hash only available when i-k+1 > 0
        if (i >= k - 1 && !got[hashVal]) {
            got[hashVal] = true;
            need--;
            if (need == 0) {
                return true;
            }
        }
    }
    return false;
}

Last updated