编辑问题+递归 让两个数列相同最小代价

117 阅读1分钟

题目

image.png

  • 递归模型为从左往右,i、j表示让数列从 i 到终止位置变成 j 到终止位置的数列,进行可能性分析
    • 对于每一个位置可能是删除数列a
    • 可能是删除数列b
    • 可能数量a、b都删除
    • 无论删除多少个进行替换让一部分数列相等再删除
// i、j表示让数列从 i 到 截止位置 变成 j 到截止位置的数列
function process(arr1, arr2, i, j) {
  // 转换结束代价为0
  if (i === arr1.length && j === arr2.length) {
    return 0;
  }
  // i 转换结束了,j 还有剩余字符,只能删除 j 位置字符
  if (i === arr1.length && j !== arr2.length) {
    return arr2[j] + process(arr1, arr2, i, j + 1);
  }
  // j 转换结束了,i 还有剩余字符,只能删除 i 位置字符
  if (j === arr2.length && i === arr1.length) {
    return arr1[i] + process(arr1, arr2, i + 1, j);
  }

  // 情况1:只删除 arr1 上的字符
  const p1 = arr1[i] + process(arr1, arr2, i + 1, j);
  // 情况2:只删除 arr2 上的字符
  const p2 = arr2[j] + process(arr1, arr2, i, j + 1);
  // 情况3:都删除
  const p3 = arr1[i] + arr2[j] + process(arr1, arr2, i + 1, j + 1);
  // 情况4: 让 i 位置字符变成 j 位置字符 或 j 位置字符变成 i 位置字符
  // 情况4必须得放在最后,因为最终结算不同长度的数列是通过 删除-变换成相同数字-再删除 的过程 来确保两个数列一样
  const p4 = Math.abs(arr1[i] - arr2[j]) + process(arr1, arr2, i + 1, j);

  return Math.min(p1, p2, p3, p4);
}

process(arr1, arr2, 0, 0);