字典序最小的 01 字符串
一、问题描述
给定一个仅由 0 和 1 组成的字符串 s 以及一个整数 k ,可以对字符串进行最多 k 次操作,每次操作选择字符串中的任意一个 0 ,将其变为 1 。要求在执行完最多 k 次操作后,得到的字符串字典序最小。
例如,对于字符串 s = "0010" ,k = 2 ,通过将索引为 1 和 3 的 0 变为 1 ,得到字符串 "0111" ,其字典序最小。
二、解题思路
(一)贪心策略
为了使得到的字符串字典序最小,我们应该尽可能地将前面的 0 变为 1 。因为字典序比较是从左到右依次进行的,前面的字符越小,整个字符串的字典序就越小。
(二)具体步骤
- 初始化两个指针
left = 0和right = 0,以及一个变量zeroCount = 0用于记录当前窗口内 0 的个数。 - 移动右指针
right,扩展窗口,同时更新zeroCount。 - 当窗口内 0 的个数
zeroCount大于k时,说明需要收缩窗口,移动左指针left,并减少zeroCount。 - 在移动左指针的过程中,记录下使得窗口内 0 的个数不超过
k的最小字典序的窗口位置。 - 最后将记录的窗口内的 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 字符串问题,在处理大规模数据时也能保持较好的效率