Skip to content

组合总和

题目详情

组合总和题目详情

题目思路

想的是和求三数之和一样,不断拆分问题,然后使用递归解决 即将目标值变为 target-当前数 然后当 总和等于 target 的时候返回,小于 target 的时候继续递归,大于则跳过(不做处理

  • Python 实现
Python
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        if not candidates:
            return []
        res = []
        for i,num in enumerate(candidates):
            if num == target:
                res.append([num])
            elif num < target:
              #如果当前总和小于target,从当前数字后面查找组合,防止出现重复组合
                for r in self.combinationSum(candidates[i:],target-num):
                    res.append([num]+r)
        return res
  • TypeScript 实现
TypeScript
function combinationSum(candidates: number[], target: number): number[][] {
  if (candidates.length === 0) return [];
  const res: number[][] = [];
  for (let i = 0; i < candidates.length; i++) {
    if (candidates[i] === target) {
      res.push([candidates[i]]);
    } else if (candidates[i] < target) {
      const subRes = combinationSum(candidates.slice(i), target - candidates[i]);
      subRes.forEach((item) => res.push([candidates[i], ...item]));
    }
  }
  return res;
}
  • TypeScript 另一种实现 加入了剪枝的部分,提升了运行速度
TypeScript
function combinationSum(candidates: number[], target: number): number[][] {
  // 排序
  candidates.sort((a, b) => a - b);
  let res = []; // 结果集
  let step = []; // 过程记录

  // 深度优先搜索遍历
  const dfs = (index, target) => {
    if (target == 0) {
      res.push(Array.from(step)); // 记录结果(直接添加 step 为浅拷贝,其结果会随 step 的变化而变化)
      return;
    }

    for (let i = index; i < candidates.length; i++) {
      let tmp = target - candidates[i];
      if (tmp < 0) return; // 剪枝
      else {
        step.push(candidates[i]); // 记录当前步骤
        dfs(i, tmp); // 递归遍历
        step.pop(); // 移除当前步骤
      }
    }
  };

  dfs(0, target);
  return res;
}

如有转载或 CV 的请标注本站原文地址