You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

消除字符串中特定双字词实例的最小相邻交换数及递归/DP解法入门

嘿,这个问题确实挺棘手的——当引入第三种字符后,纯a/b场景下“把所有b移到a前面”的简单逻辑直接失效了,得重新梳理子问题的拆分方式。我来一步步给你拆解怎么用动态规划(以及对应的递归记忆化)解决它:

核心问题重新梳理

首先明确:我们的目标是通过最少的相邻交换,把原字符串转换成不存在任何相邻"ab"子串的合法字符串。注意,合法字符串不是要求所有a都在b前面(比如"acb"是合法的,因为没有相邻ab),只是不能有a直接紧跟在b前面?不对,准确说是不能有a后面直接跟b——也就是任何位置i都不能满足s[i]='a'且s[i+1]='b'。

动态规划思路

状态定义

我们定义dp[a][b][last]表示:已经处理了原字符串中的a个a、b个b(剩下的就是已处理的c的数量,c = 已处理总字符数 - a - b),且当前已构建的合法子串的最后一个字符是last(last可以是'a'、'b'、'c',或者初始的None表示还没有处理任何字符)时,所需的最小交换次数。

初始化

初始状态只有dp[0][0][None] = 0,表示处理0个字符时,交换次数为0,其他所有状态初始化为无穷大(表示暂时不可达)。

状态转移

我们按顺序遍历原字符串的每个字符(索引从0到n-1),对于每个当前可达的状态(a, b, last),根据当前处理的字符ch进行转移:

情况1:当前字符是'a'

a可以插入到当前子串的任何位置(因为插入a不会导致出现相邻ab),为了最小化交换次数,我们选择把它放到子串末尾(不需要额外交换):

  • 新状态:(a+1, b, 'a')
  • 交换次数增量:0(保持原顺序,无需交换)
  • 新的交换次数:dp[a][b][last] + 0

情况2:当前字符是'b'

b不能插入到a的后面(否则会形成相邻ab),所以分两种情况:

  • 如果当前子串的最后一个字符last != 'a'(包括空、b、c):可以直接放到子串末尾,交换次数增量0,新状态(a, b+1, 'b'),交换次数为dp[a][b][last] + 0。
  • 如果当前子串的最后一个字符last == 'a':必须把b插入到所有非a字符的后面(也就是不能跟在a后面),此时交换次数增量等于当前已处理的a的数量a(因为需要把b从当前位置移到所有a的前面,需要交换a次),新状态(a, b+1, 'b'),交换次数为dp[a][b][last] + a。

情况3:当前字符是'c'

c可以和任何字符相邻,所以直接放到子串末尾即可,交换次数增量0:

  • 新状态:(a, b, 'c')
  • 交换次数:dp[a][b][last] + 0

最终结果

遍历完所有字符后,所有dp[A][B][last](其中A是原字符串中a的总数,B是b的总数,last可以是'a'、'b'、'c')中的最小值就是答案。

递归记忆化版本

如果想用递归的方式,本质就是把动态规划转换成带记忆化的递归函数:

  • 定义递归函数dfs(a, b, last),返回处理了a个a、b个b,最后一个字符是last时的最小交换次数。
  • 递归终止条件:当a + b + c == n(n是字符串长度),返回0。
  • 对于当前要处理的字符(根据已处理的总数a+b+c找到原字符串中对应的字符ch),按照上面的状态转移逻辑,递归计算所有可能的下一个状态的最小交换次数,加上对应的增量,然后返回最小值。
  • 用一个记忆化字典或者三维数组存储已经计算过的(a, b, last)状态,避免重复计算。
举个小例子验证

比如原字符串是"cab"(包含1个a、1个b、1个c):

  1. 初始状态dp[0][0][None] = 0。
  2. 处理第一个字符'c',转移到dp[0][0]['c'] = 0。
  3. 处理第二个字符'a',转移到dp[1][0]['a'] = 0。
  4. 处理第三个字符'b',当前状态是(1,0,'a'),last是a,所以增量为1,转移到dp[1][1]['b'] = 0+1=1。
  5. 最终结果就是1,正确——因为原字符串"cab"包含相邻的ab,需要1次交换变成"cba"或者"bac"(都是合法的)。

内容的提问来源于stack exchange,提问作者Sajad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:09:38