1980. 找出不同的二进制字符串
来源第 255 场周赛 Q2难度中等分数1361
题目描述
给你一个字符串数组 nums ,该数组由 n 个 互不相同 的二进制字符串组成,且每个字符串长度都是 n 。请你找出并返回一个长度为 n 且 没有出现 在 nums 中的二进制字符串。如果存在多种答案,只需返回 任意一个 即可。
示例 1:
输入:nums = ["01","10"] 输出:"11" 解释:"11" 没有出现在 nums 中。"00" 也是正确答案。
示例 2:
输入:nums = ["00","01"] 输出:"11" 解释:"11" 没有出现在 nums 中。"10" 也是正确答案。
示例 3:
输入:nums = ["111","011","001"] 输出:"101" 解释:"101" 没有出现在 nums 中。"000"、"010"、"100"、"110" 也是正确答案。
提示:
n == nums.length1 <= n <= 16nums[i].length == nnums[i]为'0'或'1'nums中的所有字符串 互不相同
解法
方法一:计数 + 枚举
思考
\(n\) 个长为 \(n\) 的串,全集有 \(2^n\) 个,必存在未出现者。按 Hamming 重量分类:\(0\) 到 \(n\) 共 \(n+1\) 种重量,而串只有 \(n\) 个,必缺一种重量。
用掩码记下已出现的 \(1\) 的个数,再构造该个数个 \(1\) 后补 \(0\)。
由于 '1' 在长度为 \(n\) 的二进制字符串中出现的次数可以为 \(0, 1, 2, \cdots, n\)(共有 \(n + 1\) 种可能),因此我们一定可以找出一个新的二进制字符串,满足 '1' 在字符串中出现次数与 \(\textit{nums}\) 中每个字符串不同。
我们可以用一个整数 \(\textit{mask}\) 记录所有字符串中 '1' 出现次数的情况,即 \(\textit{mask}\) 的第 \(i\) 位为 \(1\) 表示长度为 \(n\) 的二进制字符串中 '1' 出现次数为 \(i\) 的字符串存在,否则不存在。
然后我们从 \(0\) 开始枚举长度为 \(n\) 的二进制字符串中 '1' 出现的次数 \(i\),如果 \(\textit{mask}\) 的第 \(i\) 位为 \(0\),则说明长度为 \(n\) 的二进制字符串中 '1' 出现次数为 \(i\) 的字符串不存在,我们可以将这个字符串作为答案返回。
时间复杂度 \(O(L)\),其中 \(L\) 为 \(\textit{nums}\) 中字符串的总长度。空间复杂度 \(O(1)\)。
1 2 3 4 5 6 7 8 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
方法二:构造
思考
计数法需扫描全部比特。康托对角线更短:第 \(i\) 位取与 \(\textit{nums}[i][i]\) 相反的值,所得串与每一个输入至少差一位。
我们可以构造一个长度为 \(n\) 的二进制字符串 \(\textit{ans}\),其中 \(\textit{ans}\) 的第 \(i\) 位与 \(\textit{nums}[i]\) 的第 \(i\) 位不同。由于 \(\textit{nums}\) 中的字符串互不相同,因此 \(\textit{ans}\) 不会出现在 \(\textit{nums}\) 中。
时间复杂度 \(O(n)\),其中 \(n\) 是 \(\textit{nums}\) 中字符串的长度。忽略答案字符串的空间复杂度,空间复杂度 \(O(1)\)。
1 2 3 4 5 6 | |
1 2 3 4 5 6 7 8 9 10 | |
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 | |