当前位置: 首页 > news >正文

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 2n1,看看哪个数字对应的字符串的二进制没有连续的 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++
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
package mainimport "fmt"func validStrings(n int) []string {ans := make([]string, 0)mask := (1 << n) - 1for i := 0; i < (1 << n); i++ {x := i ^ maskif (x & (x >> 1) == 0) {ans = append(ans, fmt.Sprintf("%0*b", n, i))}}return ans
}
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
from typing import Listclass Solution:def validStrings(self, n: int) -> List[str]:ans = []mask = (1 << n) - 1for i in range(1 << n):x = i ^ maskif not x & (x >> 1):ans.append(f'{i:0{n}b}')return ans

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

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


http://www.mrgr.cn/news/61532.html

相关文章:

  • Mysql常见知识点
  • linux音视频采集技术: v4l2
  • 数据结构与算--堆实现线段树
  • kotlin项目无法访问Java类的问题
  • LeetCode 每日一题 2025/1/6-2025/1/12
  • RT-DETR代码详解(官方pytorch版)——参数配置(1)
  • 计算机毕业设计——ssm基于HTML5的互动游戏新闻网站的设计与实现录像演示2021
  • modelsim命令:add atv
  • 【Java数据结构】树】
  • 基于SSM积分商城管理系统的设计与实现(源码+lw+部署文档+讲解等)
  • 小红书图文无水印下载
  • 进一步认识ICMP协议
  • MySQL用户权限管理属于SQL语句中的DCL语句
  • 深入理解阻塞队列
  • 鸿蒙生态崛起:开发者的机遇与挑战
  • 数据结构————map,set详解
  • Rust实现Kafka - 前言
  • 18 Docker容器集群网络架构:一、etcd 概述
  • windows 驱动实例分析系列: NDIS 6.0的Filter 驱动改造(一)
  • Ubuntu下搭建自己的Docker镜像仓库
  • svg + canvas + 烟花 + 0.0
  • 记录一次更新idea
  • 记录工作上一次计算的优化
  • 基于JSP的篮球系列网上商城系统【附源码】
  • 图的最短路径算法-迪杰斯特拉(Dijkstra)算法与弗洛伊德(Frolyd)算法(更新中)
  • Git提交代码完整流程