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

88 阅读3分钟

问题描述

小U拥有一个由0和1组成的字符串,她可以进行最多k次操作,每次操作可以交换相邻的两个字符。目标是通过这些操作,使得最终得到的字符串字典序最小。

例如,小U当前有一个字符串 01010,她最多可以进行 2 次相邻字符交换操作。通过这些操作,她可以将字符串调整为 00101,这是可以通过不超过2次操作得到的字典序最小的字符串。

现在,小U想知道,经过最多k次操作后,能够得到的字典序最小的字符串是什么。


测试样例

样例1:

输入:n = 5, k = 2, s = "01010"
输出:'00101'

样例2:

输入:n = 7, k = 3, s = "1101001"
输出:'0110101'

样例3:

输入:n = 4, k = 1, s = "1001"
输出:'0101'

问题分析

本题的目标是通过不超过 k 次的相邻字符交换,使得一个由 '0' 和 '1' 组成的字符串 s 的字典序尽可能小。字典序的比较本质上是从左到右逐字符比较,找到第一个不同的字符后即可判定较小者。为了实现字典序最小化,我们的核心思路是尽可能将 '0' 提前。

解题思路

将问题细化为以下几个步骤:

  1. 核心交换策略
    '0' 的优先级高于 '1',因此每当遇到 '0' 时,尝试将它向左移动,直到用尽 kk\ 次交换或无法进一步移动为止。
  2. 约束分析
    每次交换相邻字符会减少 k 的次数,同时只能将当前 '0' 左移一位。因此,移动次数受限于当前 '0' 左边的 '1' 的数量 cnt 以及剩余交换次数 k。
    kcntk \geq cnt,可以将当前 '0' 完全移动至其左边所有 '1' 的前方;
    k<cntk < cnt,只能部分移动,通过调整最终达到最佳效果。
  3. 逐步构造结果
    遍历字符串时,动态记录左侧累计的 '1' 的数量 cntcnt,并按条件决定当前字符是插入结果字符串的何处。最终的结果字符串是通过模拟移动过程构造的。

代码解析

以下是提供代码的逐步解释:

def solution(n: int, k: int, s: str) -> str:
    cnt, flag = 0, 0  # cnt 记录遇到的 '1' 的数量,flag 表示是否已经进入不再调整的阶段
    ans = []          # 存储最终结果字符串
    
    for i in s:
        if flag:  # 如果已经进入无法继续调整的阶段,直接将字符加入结果
            ans.append(i)
        elif i == '1':  # 当前字符为 '1',累加计数器
            cnt += 1
        elif k >= cnt:  # 当前字符为 '0',且可以完全移到所有 '1' 的前面
            ans.append('0')
            k -= cnt  # 减少交换次数
        else:  # 当前字符为 '0',但 ( k < cnt ),无法完全移动
            flag = 1  # 设置标志位,表示从此刻开始所有字符直接拼接
            # 将前 cnt-k 个 '1' 拼接到结果中
            for idx in range(cnt - k):
                ans.append('1')
            ans.append('0')  # 插入当前的 '0'
            # 剩余的 ( k ) 个 '1' 直接拼接
            for idx in range(k):
                ans.append('1')
            cnt = 0  # 重置计数器
            k = 0    # 用完所有操作次数
    
    # 最后将剩余的 '1' 补充到结果中
    for idx in range(cnt):
        ans.append('1')
    
    return "".join(ans)

复杂度分析

  1. 时间复杂度

    • 遍历字符串 s 一次,时间复杂度为 O(n)。
    • 每次移动 '0' 时的拼接操作为常数时间,整体复杂度仍为O(n)。
      综合复杂度:O(n)。
  2. 空间复杂度

    • 使用一个额外数组 ans 存储结果,空间复杂度为 O(n)。

总结

该解法通过贪心思想,逐字符判断并动态调整结果字符串的构造,同时保持了 O(n)O(n) 的线性复杂度,非常高效,适用于大规模输入数据。