📌  相关文章
📜  检查子字符串“10”是否出现在给定的二进制字符串中所有可能的 '?' 替换中与 1 或 0(1)

📅  最后修改于: 2023-12-03 14:55:45.434000             🧑  作者: Mango

题目描述

给定一个二进制字符串,其中可能包含一些 '?' 字符,将 '?' 替换为 '0' 或 '1' 后,检查子字符串 "10" 是否在所有可能的替换后出现。

示例

输入: s = "1?0" 输出: true 解释: 替换出来的可能为 "100" 或 "110",均包含substring "10"

输入: s = "0" 输出: false

解题思路

暴力解法:生成所有可能的替换并判断是否包含 "10" 子串。但这样时间复杂度太高。

考虑线性扫描字符串 s,当前位置为 i,同时记当前已遇到 ? 的个数为 count。

  1. 当 s[i] 为 ? 时,可能替换为 0 或者 1,所以 count 加 1,并将 ? 的位置 i 保存到一个数组中。

  2. 当 s[i] 不为 ? 时,需要分析前面 count 个 ?,并同时判断 i 和 i-1 位置上的字符是否能够组成 "10" 子串。如果满足条件,则将数组中最靠前的 ? 替换为 '1',否则用 '0' 替换。处理完后,将 count 重置为 0。

重要的事情说三遍:?????,当遇到的字符 s[i] 为 '?' 时,要把当前位置 i 保存到一个数组中。

代码实现

def checkSubStr(s: str) -> bool:
    cnt = 0 # 记录未替换的 ? 的个数
    lst = [] # 记录 ? 的位置
    n = len(s)
    # 遍历 s
    for i in range(n):
        if s[i] == '?':
            cnt += 1
            lst.append(i)
        else:
            if i>0 and s[i-1] == '1' and s[i] == '0': # 判断是否存在 "10" 子串
                if cnt == 0: # 如果没有 ?,直接返回 False
                    return False
                else:
                    cnt -= 1
                    s = s[:lst[0]]+'1'+s[lst[0]+1:] # 将 ? 替换为 1,并从 lst 中删掉这个位置
                    lst = lst[1:] # 注意:list 的删除操作很耗时,所以要尽量使用 slice。
            else:
                cnt = 0 # 注意:这里千万不能忘了将 cnt 重置为 0。

    return s.find('10') != -1 # 最后,判断是否存在 "10" 子串

时间复杂度

最坏情况下遍历整个字符串,时间复杂度 $O(n)$。