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

113 阅读4分钟

这个问题的核心在于通过交换相邻字符,使得字符串的字典序最小化。字典序最小化意味着尽可能将 '0' 移到字符串的前面,而将 '1' 移到后面。由于交换操作限制为相邻字符的交换,并且最多只能进行 k 次交换,我们需要设计一个策略,尽量利用有限的交换次数来优化字典序。

问题解析

我们的问题可以简化为:如何通过至多 k 次相邻字符交换,将字符串 s 中的 '0' 尽量移动到左边,'1' 移动到右边,从而获得字典序最小的字符串。

字典序最小的策略

字典序是按字符的顺序来排序的,类似于字母表顺序:

  • '0' 的字典序比 '1' 小,因此我们希望把 '0' 尽可能多地移到字符串的左侧,而 '1' 尽量往右移。

我们可以通过以下方法来优化字典序:

  1. 从左到右扫描字符串:遍历字符串的每个字符,寻找 '0' 和 '1' 的组合。
  2. 将 '0' 向左移:当遇到一个 '0' 时,我们尝试将它移动到更左侧。如果 '0' 和它前面的 '1' 可以交换,我们就交换它们。每次交换后,k 次操作减少 1。
  3. 限制交换次数:如果 k 达到上限,即我们已经用了 k 次交换,就停止继续交换。

交换策略

  1. 遇到 '0' 时:我们会寻找该 '0' 前面的位置,看看是否有 '1',并交换它们。每次交换会减少一个操作次数。
  2. 交换的优先级:在可能的情况下,优先将 '0' 移动到离它更近的左边位置,直到操作次数耗尽。

解决思路

  • 贪心策略:每当我们遇到一个 '0' 时,如果前面有 '1' 且操作次数 k 还允许,我们就将这个 '0' 移到尽量靠前的位置。
  • 操作次数的控制:每次交换都会消耗一个操作次数 k,当 k 达到零时,停止交换。

算法步骤

  1. 将字符串 s 转换成列表(因为字符串是不可变的,列表是可变的)。
  2. 遍历字符串中的每一个字符,找到 '0',然后向左交换直到操作次数 k 用尽。
  3. 每交换一次,k 减 1,直到无法再交换或者操作次数用完。
  4. 返回最终的字符串。

代码实现

def min_lexicographic_string(s, k):
    # 转换为列表,方便修改
    s = list(s)
    n = len(s)

    # 遍历字符串的每个字符
    for i in range(n):
        if k <= 0:
            break  # 如果操作次数已经用完,退出
        
        # 如果当前字符是 '0',尝试将它向左交换
        if s[i] == '0':
            # 从当前字符的左边开始,找到第一个 '1' 并交换
            for j in range(i - 1, -1, -1):
                if s[j] == '1':  # 找到第一个 '1'
                    s[j], s[j + 1] = s[j + 1], s[j]  # 交换
                    k -= 1  # 减少操作次数
                    if k == 0:  # 如果操作次数用尽,结束
                        break
                else:
                    break  # 如果前面没有 '1',就停止

    return ''.join(s)  # 将列表转换回字符串

# 示例
s = "01010"
k = 2
result = min_lexicographic_string(s, k)
print(result)  # 输出:00110

代码解释

  1. 转换为列表:我们将输入的字符串 s 转换为列表,因为在 Python 中字符串是不可变的,而我们需要修改字符串的内容。
  2. 遍历字符串:我们通过遍历字符串的每个字符,当遇到 '0' 时,尝试将其交换到左边,直到操作次数用尽或者字符串结束。
  3. 交换操作:如果当前字符是 '0',我们检查它前面的字符,找到第一个 '1' 后交换它们,并减少操作次数 k
  4. 操作次数控制:一旦 k 达到 0,我们就停止交换,返回当前的字符串。

示例分析

假设输入字符串是 "01010",最多可以进行 2 次交换:

  1. 初始字符串为 "01010",我们从左到右遍历。
  2. 第一个 '0' 在索引 0,没有前面的 '1',不需要交换。
  3. 第二个 '0' 在索引 2,它前面有 '1',我们交换它和索引 1 处的 '1',此时剩余的操作次数 k = 1,字符串变为 "00110".
  4. 第三个 '0' 在索引 4,我们将它交换到索引 3,剩余的操作次数 k = 0,停止交换。

最终得到的字符串是 "00110",这是字典序最小的字符串。

知识总结

建议同学们不必追求数量,要追求质量,找出自己不会的知识点。