LeetCode 记录-1774. 最接近目标价格的甜点成本

153 阅读2分钟

LeetCode 记录-1774. 最接近目标价格的甜点成本

我的解法

思路

image.png

第一反应是使用搜索回溯算法或者动态规划来实现,不过对这两个算法都不太熟悉,没实现出来。


官方解法 1: 回溯

思路

之前虽然对搜索回溯算法有过一点的了解,但已经很久很久没有做过相关的题目了,今天借着这题再复习一遍。

我理解的搜索回溯算法其实就是利用递归去遍历出所有的情况,在遍历的过程中,对每种情况进行判断,找出我们想要的情况。同时,我们可以在递归的过程中进行剪枝操作,就是通过逻辑判断,当判断继续递归搜索下去只会离我们想要的情况越来越远时,就可以停止搜索,用来降低时间复杂度,比如我们这题中,我们在递归搜索时不停的往当前搭配中添加配料,那么当前的成本(curCost)只会越来越大,当 curCost 大于 target,且(curCost-target)已经大于当前搜索出来的最优情况时,就可以停止搜索了。

代码

var closestCost = function (baseCosts, toppingCosts, target) {
  let res = _.min(baseCosts);
  const dfs = (toppingCosts, p, curCost, target) => {
    if (Math.abs(res - target) < curCost - target) {
      return;
    } else if (Math.abs(res - target) >= Math.abs(curCost - target)) {
      if (Math.abs(res - target) > Math.abs(curCost - target)) {
        res = curCost;
      } else {
        res = Math.min(res, curCost);
      }
    }
    if (p === toppingCosts.length) {
      return;
    }
    dfs(toppingCosts, p + 1, curCost + toppingCosts[p] * 2, target);
    dfs(toppingCosts, p + 1, curCost + toppingCosts[p], target);
    dfs(toppingCosts, p + 1, curCost, target);
  };
  for (const b of baseCosts) {
    dfs(toppingCosts, 0, b, target);
  }
  return res;
};

复杂度分析

时间复杂度

O(n3m)O(n*3^m),其中 n,m 分别为数组 baseCosts,toppingCosts 的长度。

空间复杂度

O(m)O(m),主要为回溯递归的空间开销。

官方解法 2: 动态规划

思路

使用动态规划的思路,相对来说有点绕,理解了一遍,就先不深入了。