leetcode 2026-03-06 每日一练 - 检查二进制字符串字段

题目描述

LeetCode 1784. 检查二进制字符串字段

给你一个二进制字符串 s,该字符串不含前导零

如果 s 包含零个或一个由连续的 '1' 组成的字段,返回 true。否则,返回 false

示例 1

  • 输入:s = "1001"
  • 输出:false
  • 解释:由连续若干个 '1' 组成的字段数量为 2,返回 false

示例 2

  • 输入:s = "110"
  • 输出:true
  • 解释:由连续若干个 '1' 组成的字段数量为 1,返回 true

解题思路

核心观察

题目要求判断字符串中的 '1' 是否只形成一个连续字段。换句话说:

  • ✓ 允许:"111""1110""0111""01110"(1 只出现一次连续段)
  • ✗ 不允许:"1001""10101""11011"(1 出现多次连续段)

关键发现

如果字符串中存在 "01" 这样的子串(即 '0' 后面跟着 '1'),说明:

  • 前面已经有过一段 '1'
  • 现在又出现了新的 '1'
  • 因此存在多个 '1' 字段

判断条件:只要找到 "01" 子串,就返回 false

算法步骤

  1. 遍历字符串(从索引 1 开始)
  2. 检查当前字符是否为 '1' 且前一个字符是否为 '0'
  3. 如果满足条件,说明存在多个 '1' 字段,返回 false
  4. 遍历结束后返回 true

代码实现

方法一:检测 “01” 子串(推荐)

1
2
3
4
5
6
7
8
func checkOnesSegment(s string) bool {
for i, v := range s {
if i > 0 && v == '1' && s[i-1] == '0' {
return false
}
}
return true
}

方法二:使用 strings.Contains(简洁)

1
2
3
func checkOnesSegment(s string) bool {
return !strings.Contains(s, "01")
}

方法三:统计字段数量(直观)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func checkOnesSegment(s string) bool {
segments := 0
inSegment := false

for _, v := range s {
if v == '1' {
if !inSegment {
segments++
if segments > 1 {
return false
}
inSegment = true
}
} else {
inSegment = false
}
}

return segments <= 1
}

核心细节

  1. 边界处理:从索引 1 开始遍历,避免越界访问 s[i-1]
  2. 关键模式"01" 是判断多个字段的充要条件
  3. 字符比较:直接比较字符 '0''1',无需转换
  4. 提前返回:一旦发现 "01",立即返回 false,无需继续遍历

复杂度分析

方法一

  • 时间复杂度O(n),最坏情况遍历整个字符串
  • 空间复杂度O(1),只使用常量额外空间

方法二

  • 时间复杂度O(n)strings.Contains 内部遍历字符串
  • 空间复杂度O(1),不使用额外空间

方法三

  • 时间复杂度O(n),遍历整个字符串
  • 空间复杂度O(1),只使用常量额外空间

方法对比

方法优点缺点
方法一高效,提前返回需要理解 “01” 模式
方法二代码最简洁无法提前返回
方法三逻辑最直观代码较长,无法提前返回

推荐使用方法一或方法二,代码简洁且高效。


示例分析

示例 1:s = "1001"

方法一分析

  • 索引 0:'1',跳过(i == 0)
  • 索引 1:'0',不是 '1',继续
  • 索引 2:'0',不是 '1',继续
  • 索引 3:'1',前一个字符是 '0' → 发现 "01" → 返回 false

方法二分析

  • strings.Contains("1001", "01") 返回 true
  • 因此返回 !true = false

示例 2:s = "110"

方法一分析

  • 索引 0:'1',跳过
  • 索引 1:'1',前一个字符是 '1',不满足条件
  • 索引 2:'0',不是 '1',继续
  • 遍历结束,返回 true

方法二分析

  • strings.Contains("110", "01") 返回 false
  • 因此返回 !false = true

边界情况

输入输出说明
"1"true只有一个 '1'
"111"true连续的 '1'
"1110"true'1' 在前面
"0111"true'1' 在后面(题目说明不含前导零,此情况不会出现)
"10"true一个 '1' 字段
"101"false两个 '1' 字段
"10101"false三个 '1' 字段

总结

这道题的关键点:

  • 理解”连续字段”的定义:所有 '1' 必须连在一起
  • 核心模式识别:"01" 子串的存在意味着多个 '1' 字段
  • 简化判断:无需统计字段数量,只需检测 "01" 模式
  • 多种实现:可以用遍历、字符串查找或状态机,选择最简洁的方式