字典序最小的01字符串| 豆包MarsCode AI 刷题

87 阅读3分钟

字典序最小的 01 字符串

一、问题描述

给定一个仅由 0 和 1 组成的字符串 s 以及一个整数 k ,可以对字符串进行最多 k 次操作,每次操作选择字符串中的任意一个 0 ,将其变为 1 。要求在执行完最多 k 次操作后,得到的字符串字典序最小。

例如,对于字符串 s = "0010" ,k = 2 ,通过将索引为 1 和 3 的 0 变为 1 ,得到字符串 "0111" ,其字典序最小。

二、解题思路

(一)贪心策略

为了使得到的字符串字典序最小,我们应该尽可能地将前面的 0 变为 1 。因为字典序比较是从左到右依次进行的,前面的字符越小,整个字符串的字典序就越小。

(二)具体步骤

  1. 初始化两个指针 left = 0 和 right = 0 ,以及一个变量 zeroCount = 0 用于记录当前窗口内 0 的个数。
  2. 移动右指针 right ,扩展窗口,同时更新 zeroCount 。
  3. 当窗口内 0 的个数 zeroCount 大于 k 时,说明需要收缩窗口,移动左指针 left ,并减少 zeroCount 。
  4. 在移动左指针的过程中,记录下使得窗口内 0 的个数不超过 k 的最小字典序的窗口位置。
  5. 最后将记录的窗口内的 0 尽可能地替换为 1 ,得到字典序最小的字符串。

三、代码实现

以下是使用 Python 实现的代码示例:

sql
代码解读
复制代码
def min_dict_string(s, k):
    left, right = 0, 0
    zero_count = 0
    min_left, min_right = 0, 0
    min_zero_count = 0
    while right < len(s):
        if s[right] == '0':
            zero_count += 1
        # 当 0 的个数超过 k 时,收缩窗口
        while zero_count > k and left <= right:
            if s[left] == '0':
                zero_count -= 1
            left += 1
        # 更新最小字典序的窗口
        if right - left + 1 > min_right - min_left + 1 and zero_count <= k:
            min_left, min_right = left, right
            min_zero_count = zero_count
        right += 1
    # 将最小字典序窗口内的 0 替换为 1
    result = list(s)
    for i in range(min_left, min_left + min_zero_count):
        if result[i] == '0':
            result[i] = '1'
    return ''.join(result)

你可以使用以下方式调用这个函数:

ini
代码解读
复制代码
s = "0010"
k = 2
print(min_dict_string(s, k))

四、时间复杂度分析

在上述代码中,左右指针最多遍历字符串一次,所以时间复杂度为  ,其中 n 是字符串 s 的长度。

五、空间复杂度分析

代码中除了定义了几个指针变量和用于存储结果的列表(其长度与输入字符串长度相关)外,没有使用大量额外的数据结构,所以空间复杂度为  ,主要是存储结果字符串的空间开销。 通过这种贪心策略和双指针的方法,可以有效地解决字典序最小的 01 字符串问题,在处理大规模数据时也能保持较好的效率