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

153 阅读4分钟

字典序最小字符串的操作解析

题目描述

小U拥有一个由0和1组成的字符串,并且可以进行最多k次相邻字符交换操作。我们的目标是通过这些操作,使得最终得到的字符串字典序最小。给定字符串及允许的操作次数,求能达到的字典序最小字符串。

思路分析

为了得到字典序最小的字符串,我们需要将尽可能多的0移动到字符串的前面。具体思路如下:

  1. 遍历字符串:从左到右遍历字符串,寻找当前字符。
  2. 移动0到当前位置:当发现当前字符为1时,寻找其后面的0,并计算将这些0移动到当前位置所需的交换次数。
  3. 判断交换次数:如果所需的交换次数小于或等于k,则进行交换,并更新k值。
  4. 继续遍历:继续遍历直到达到k的限制或者遍历结束。

图解

假设字符串为 s = "01010",k = 2。

  • 初始状态0 1 0 1 0

  • 第一步

    • 遍历到第一个1(索引1),向后查找0。
    • 找到第三个字符0(索引2),需要交换1次(1和0)。
    • 交换后得到:0 0 1 1 0,使用1次操作,k变为1。
  • 第二步

    • 接着遍历到第二个1(索引2),向后查找0。
    • 找到最后一个字符0(索引4),需要交换2次(1和0,1和0)。
    • 交换后得到:0 0 0 1 1,使用2次操作,k变为0。

最终得到的字符串为 00101

代码详解

下面是实现该逻辑的 Python 代码:

python

复制

def solution(n: int, k: int, s: str) -> str:
    s = list(s)  # 将字符串转换为列表,方便修改
    for i in range(n):
        if k <= 0:
            break  # 如果没有剩余的交换次数,退出循环
        if s[i] == '0':
            continue  # 如果当前位置已经是0,跳过
        
        # 查找在 i 之后的 '0',并尝试移动到当前位置
        for j in range(i + 1, n):
            if s[j] == '0':
                # 计算移动所需的交换次数
                moves = j - i
                if moves <= k:  # 如果可以在 k 次内完成移动
                    # 进行交换,把 '0' 移动到当前位置
                    for x in range(j, i, -1):
                        s[x] = s[x - 1]  # 向右移动
                    s[i] = '0'  # 将 '0' 放在当前位置
                    k -= moves  # 减去使用的交换次数
                    break  # 移动完毕,结束内层循环
    
    return ''.join(s)  # 将列表转换回字符串并返回

# 测试代码
if __name__ == '__main__':
    print(solution(5, 2, "01010") == '00101')  # 输出: True
    print(solution(7, 3, "1101001") == '0110101')  # 输出: True
    print(solution(4, 1, "1001") == '0101')  # 输出: True

代码分析

  1. 字符串转换:首先将字符串转换为列表,以方便对字符进行修改。字符串在Python中是不可变的,因此需要转为列表。
  2. 外层循环:从左到右遍历字符串,检查每个字符。如果当前字符是0,直接跳过,因为我们希望将0尽量移动到前面。
  3. 内层循环:对于每个1,向后查找0。如果找到0,计算移动到当前位置所需的交换次数(即索引差)。
  4. 交换逻辑:如果移动次数在允许的范围内(小于等于k),则进行交换。通过向右移动字符,逐步将0推到当前1的位置。
  5. 更新状态:在交换后,更新k值和字符状态,继续迭代。若没有足够的交换次数,退出循环。

复杂度分析

  • 时间复杂度:O(n^2),最坏情况下,外层循环遍历n次,内层循环也可能遍历n次。
  • 空间复杂度:O(n),需要使用额外空间来存储转换后的字符列表。

总结

通过上述算法,我们能够有效地将0移动到字符串的前面,达到字典序最小的目标。关键在于合理判断并执行字符的交换,尽量利用每一次操作。希望这篇笔记能够帮助理解并解决类似的问题。