青训营豆包 | 豆包MarsCode AI 刷题

75 阅读3分钟

字典序最小的01字符串

题目分析

你有一个由0和1组成的字符串,可以通过最多k次相邻字符交换操作,使得最终得到的字符串字典序最小。字典序最小意味着字符串中的字符尽可能地按照从小到大的顺序排列。

  • 局部最优:每次选择当前位置右侧字典序最小的字符进行交换,这样可以保证每次操作都是局部最优的。
  • 交换次数限制:每次交换操作后,需要更新剩余的交换次数k,确保不超过k次操作。

算法步骤

  1. 遍历字符串:从左到右遍历字符串的每一个字符。
  2. 寻找最小字符:在当前字符的右侧,寻找字典序最小的字符,且该字符的位置在当前字符的右侧不超过k个位置。
  3. 交换字符:如果找到了这样的字符,并且交换次数不超过k次,则进行交换操作。
  4. 更新剩余交换次数:每次交换后,更新剩余的交换次数k。
  5. 返回结果:当遍历完所有字符后,返回最终的字符串。 通过这些步骤,你可以逐步构建出最终的字典序最小的字符串。

代码+分析

a81d1cf623ffc966aa1de7276c00fec.png

  1. 将字符串转为字符数组由于字符串是不可变的,所以我们先将字符串 s 转为字符数组 chars,这样可以在原地修改字符。
  2. 循环处理每个字符位置遍历每个字符位置 i,并且如果没有剩余的交换次数 k <= 0,就提前退出 a35bb995fac4010997127a0b466fb4c.png 查找可以交换的最小字符 在当前字符 i 后面的 k 个字符(范围为 [i+1, i+k])中,找出最小的字符的索引 minIndex85d885f9ee09d9ecb1746b1c4920e31.png 计算交换次数并判断是否执行交换
  • 计算 minIndex - i,即交换最小字符需要的移动次数 moves

  • 如果 minIndex 不等于 i,并且所需的交换次数 moves 小于等于当前剩余的交换次数 k,则执行交换:

    • 用 temp 暂存 minIndex 位置的字符。
    • 从 minIndex 向左依次将字符往右移,为了将最小的字符放到位置 i
    • 将最小字符 temp 放到位置 i
  • 更新剩余交换次数 k -= moves

总结

  • 这段代码通过贪心策略尽可能使得每个位置的字符变得更小,确保字典序最小。
  • 在每个位置上,查找最多能交换的字符,并进行交换。
  • 通过限制交换次数 k,最终得到一个字典序最小的字符串。
  • 这段代码的目标是通过交换字符来对给定的字符串进行排序,以达到尽可能最小的字典序。代码的核心逻辑是通过指定的最大交换次数 k,在字符串中找到合适的字符并进行交换。具体来说,逐步将每个位置的字符交换为该位置能容许的最小字符,直到用尽所有的交换次数或排序完成。