刷题的日常-找出不同的二进制字符串

121 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第29天,点击查看活动详情

刷题的日常-2022年10月26号

一天一题,保持脑子清爽

找出不同的二进制字符串

来自leetcode的 1980 题,题意如下:

给你一个字符串数组 nums ,该数组由 n 个 互不相同 的二进制字符串组成,且每个字符串长度都是 n 。请你找出并返回一个长度为 n 且 没有出现 在 nums 中的二进制字符串。如果存在多种答案,只需返回 任意一个 即可。

示例1:

输入: nums = ["01","10"]
输出: "11"
解释: "11" 没有出现在 nums 中。"00" 也是正确答案。

理解题意

通过题意,我们可以将信息整理如下:

  • 题目给出一个字符串数组,每个字符串的位数为n,并且数组的长度也是n
  • 要求返回一个新的字符串,这个字符串在给定的数组中没有出现过
  • 题目给出的字符串是二进制字符串,所以每个位有两种取值可能,总共有2的n次方种取值方式
  • 但是数组的长度只是n,所以其实暴力搜索的空间并不大,最多搜索n次

做题思路

题目限定了给定的字符串是二进制字符串,因此我们可以将数组中字符串转换为对应的数字,然后用Set去存储,用作后面匹配用。然后从数字0开始 一直到 2的n次方的数字进行扫描,如果数字没有出现在Set中,就将数字转换为对应的二进制字符串返回即可,步骤如下:

  • 计算给定字符串长度可能的搜索范围
  • 将给定的字符串转换为数字存放到Set集合中
  • 搜索可能的解空间
  • 如果出现不存在Set中的数,将其转换为对应的二进制字符串表示
  • 返回结果

代码实现

代码实现如下:

public class Solution {
    public String findDifferentBinaryString(String... nums) {
        int len = 1 << nums[0].length(), item;
        Set<Integer> set = new HashSet<>();
        for (String num : nums) {
            item = 0;
            for (int i = 0; i < num.length(); i++) {
                item += (1 & (num.charAt(i) - '0')) << (num.length() - i - 1);
            }
            set.add(item);
        }
        int idx = nums[0].length() - 1;
        char[] result = new char[nums[0].length()];
        for (int i = 0; i < len; i++) {
            if (set.contains(i)) {
                continue;
            }
            while (i > 0) {
                result[idx--] += (i & 1) + '0';
                i >>= 1;
            }
            while (idx >= 0) {
                result[idx--] = '0';
            }
            break;
        }
        return new String(result);
    }
}

image.png