伴学笔记|青训营X豆包MarsCode 技术训练营

76 阅读6分钟

问题描述

小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'

道题目的分析: ### 一、题目理解

  1. 初始条件明确:题目给定了一个由0和1组成的字符串,以及可进行的最多操作次数k。每次操作限定为交换相邻的两个字符。
    1. 目标清晰:要通过最多k次这样的操作,使得最终得到的字符串在字典序上是最小的。字典序是指按照字符的先后顺序进行比较,对于两个字符串,从左到右逐位比较,先出现较小字符的字符串字典序更小,如果前面部分相同,长度较短的字典序更小。

解题思路分析

  1. 贪心算法思路: - 为了得到字典序最小的字符串,我们希望尽可能地把0往前移。所以可以从字符串的开头开始,依次检查每个位置。 - 对于每个位置i,如果当前位置是1且在它之前存在0(即前面有可交换的0),并且剩余的操作次数k足够进行交换操作,那么就将这个1与它前面最近的0进行交换,这样可以使得0更靠前,从而使字符串的字典序更小。 - 重复这个过程,直到遍历完整个字符串或者操作次数k用完。
  2. 实现细节考虑: - 需要一种高效的方式来找到当前位置之前最近的可交换的0。可以使用一个辅助的数据结构,比如栈,来记录已经遍历过的0的位置。当需要交换时,从栈顶取出最近的0的位置进行交换操作。 - 在每次交换操作后,需要更新剩余的操作次数k以及相应的数据结构(如栈)

总结感悟

  1. 问题分析与贪心策略确定:本题通过分析要使字符串字典序最小的目标,确定了尽可能把0往前移的贪心策略。这让我体会到在面对问题时,准确分析目标并找到合适的贪心策略是解决问题的关键一步。

  2. 数据结构辅助实现:为了高效地实现贪心策略,使用了栈来记录0的位置,以便在需要时能快速找到可交换的0。这表明在编程解决问题时,合理选择和运用数据结构可以大大提高算法的实现效率和代码的可读性。

  3. 细节处理的重要性:在代码实现过程中,如交换操作后对剩余操作次数和数据结构的更新等细节处理非常重要。若忽略这些细节,可能会导致算法无法正确运行或得到错误的结果。这提醒我在编程时要注重细节,确保代码的每一步操作都准确无误。 代码实现: def solution(n, k, s): s = list(s) # 将字符串转换为列表以便修改 i = 0 # 当前处理的位置 while k > 0 and i < n: if s[i] == '1': # 找到下一个 '0' 的位置 for j in range(i + 1, n): if s[j] == '0': # 计算将 '0' 移动到当前位置所需的操作次数 moves = j - i if moves <= k: # 进行移动操作 s[i], s[j] = s[j], s[i] k -= moves break i += 1 return ''.join(s)

测试样例

print(solution(5, 2, "01010")) print(solution(7, 3, "1101001")) print(solution(4, 1, "1001")) 贪心算法在实际生活中有诸多应用场景, 一、活动安排问题 在组织一系列活动时,每个活动都有开始时间和结束时间。目标是在有限的时间内安排尽可能多的活动,使得这些活动之间互不冲突。 ### 二、找零问题 当我们在商店购物需要找零时,收银员通常会尽量用最少的硬币或纸币数量来凑出需要找零的金额。 通过每次优先选择面额较大的货币进行找零,可以用相对较少的货币数量完成找零任务。 ### 三、背包问题(部分情况) 背包问题有多种类型,其中一种是部分背包问题,即物品可以分割,目标是在给定背包容量的情况下,装入物品使得背包中物品的总价值最大。 ### 四、哈夫曼编码 在数据压缩领域,哈夫曼编码是一种常用的无损压缩方法。它的基本思想是根据字符在文件中出现的频率来构造一种特殊的编码方式,使得出现频率高的字符编码较短,出现频率低的字符编码较长,从而达到压缩数据的目的。### 五、任务调度问题 在多任务处理环境下,比如工厂的生产线上有多个任务需要完成,每个任务都有其完成时间和优先级等属性。 如果目标是在最短时间内完成所有任务,并且要优先考虑高优先级的任务,就可以采用贪心算法。 ### 六、路径规划问题(部分情况) 在一些简单的路径规划场景中,比如在一个城市的交通网络中,要从起点到终点找到一条最短路径,并且在每个路口处可以选择不同的道路分支。 如果已知每条道路的长度或通行时间等信息,部分情况下可以采用贪心算法。 贪心算法通过在每一步做出当前看起来最优的选择,在很多实际生活场景中能够提供简单、高效的解决方案,但也需要注意其局限性,并非所有问题都能通过贪心算法得到最优解,在一些复杂问题中可能需要结合其他算法或对贪心算法进行改进来实现更准确、更全面的解决方案。