LeetCode 3211.生成不含相邻零的二进制字符串:二进制枚举+位运算优化

【LetMeFly】3211.生成不含相邻零的二进制字符串:二进制枚举+位运算优化

力扣题目链接:https://leetcode.cn/problems/generate-binary-strings-without-adjacent-zeros/

给你一个正整数 n。

如果一个二进制字符串 x 的所有长度为 2 的子字符串中包含 至少 一个 "1",则称 x 是一个有效 字符串。

返回所有长度为 n 的有效 字符串,可以以任意顺序排列。

示例 1:
输入: n = 3

输出: "010","011","101","110","111"

解释:

长度为 3 的有效字符串有:"010"、"011"、"101"、"110" 和 "111"。

示例 2:
输入: n = 1

输出: "0","1"

解释:

长度为 1 的有效字符串有:"0" 和 "1"。

提示:

  • 1 <= n <= 18

解题方法:二进制枚举

不位运算优化的话其实很简单,从 0 0 0枚举到 2 n − 1 2^n-1 2n−1,看看哪个数字对应的字符串的二进制没有连续的 0 0 0即可。这样时间复杂度为 n 2 n n2^n n2n, 18 × 2 18 = 4 , 718 , 592 18\times 2^{18}=4,718,592 18×218=4,718,592,完全在合理范围内。

有没有一种办法在 O ( 1 ) O(1) O(1)的时间复杂度内判定一个数 i i i的二进制下有没有连续两个 0 0 0呢?还真有:

将 i i i二进制下低 n n n位取反( 0 0 0变 1 1 1、 1 1 1变 0 0 0), i i i二进制下没有连续两个 0 0 0等价于 X X X二进制下没有连续两个 1 1 1。

x x x二进制下没有相邻的 1 1 1等价于 x & ( x > > 1 ) = 0 x \& (x >> 1)=0 x&(x>>1)=0。

因此问题变成了"如何快速将 i i i低 n n n位取反"。也很简单, i i i异或一个 1111..1 1111..1 1111..1即可。其中 111.1 111.1 111.1一共有 n n n位,其值等于 ( 1 < < n ) − 1 (1 << n) - 1 (1<<n)−1。

  • 时间复杂度 O ( 2 n ) O(2^n) O(2n)
  • 空间复杂度 O ( 1 ) O(1) O(1),力扣返回值不计入算法空间复杂度

AC代码

C++
cpp 复制代码
class Solution {
public:
    vector<string> validStrings(int n) {
        vector<string> ans;
        int mask = (1 << n) - 1;
        for (int i = 0; i < (1 << n); i++) {
            int x = i ^ mask;  // 取反
            if (!(x & (x >> 1))) {
                ans.push_back(bitset<18>(i).to_string().substr(18 - n));
            }
        }
        return ans;
    }
};
Go
go 复制代码
package main

import "fmt"

func validStrings(n int) []string {
    ans := make([]string, 0)
    mask := (1 << n) - 1
    for i := 0; i < (1 << n); i++ {
        x := i ^ mask
        if (x & (x >> 1) == 0) {
            ans = append(ans, fmt.Sprintf("%0*b", n, i))
        }
    }
    return ans
}
Java
java 复制代码
import java.util.List;
import java.util.ArrayList;

class Solution {
    public List<String> validStrings(int n) {
        List<String> ans = new ArrayList<>();
        int mask = (1 << n) - 1;
        for (int i = 0; i < (1 << n); i++) {
            int x = i ^ mask;
            if ((x & (x >> 1)) == 0) {
                ans.add(Integer.toBinaryString((1 << n) | i).substring(1));  // 往n位"带有前导0的二进制"的前面加个1,再去掉
            }
        }
        return ans;
    }
}
Python
python 复制代码
from typing import List

class Solution:
    def validStrings(self, n: int) -> List[str]:
        ans = []
        mask = (1 << n) - 1
        for i in range(1 << n):
            x = i ^ mask
            if not x & (x >> 1):
                ans.append(f'{i:0{n}b}')
        return ans

同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

Tisfy:https://letmefly.blog.csdn.net/article/details/143352841

相关推荐
老师我太想进步了20261 小时前
【数据结构-3】算法美学之降复杂度
数据结构·算法
机器人零零壹7 小时前
技术白皮书:iRobotCAM如何解决机器人激光切割应用中的核心难点,从CAD离线编程到双目视觉定位与轨迹自适应提升复杂空间曲线切割的精度、效率与柔性化水平
人工智能·算法
ZhengEnCi9 小时前
大模型的分类到底怎么分:从基础模型到推理模型、从通用到专用的完整图谱
算法
取名真是10 小时前
Python 算法知识点从基础到进阶
开发语言·python·算法
罗西的思考10 小时前
【轻量化复刻大模型 / KIMI K3】KDA 模块交互式演示
人工智能·算法·机器学习
nm_zfyjt12 小时前
信息流广告投放优化实践:线索成本评估模型与转化链路重构(家装建材案例)
算法·重构·内蒙古朋友圈广告服务商·内蒙古朋友圈获客
w_zero_one14 小时前
算法--构造
java·数据结构·算法
其实防守也摸鱼14 小时前
信创安全竞赛知识总结与题库
大数据·网络·人工智能·算法·安全·php
小超人诞生日记15 小时前
C++ 智能指针的使用及其原理详解
c++·算法