ts算法题解(第41天)---leetcode 39.组合总和

185 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情

前言

每天一道算法题,死磕算法

题目

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。 

对于给定的输入,保证和为 target 的不同组合数少于 150 个。


示例 1:

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

我们做了ts算法题解(第39天)---leetcode 40. 组合总和 II 再来做今天这道题目,就会感觉很好上手

一个是元素可以重复,一个是元素不可以重复。

组合/子集我们是如何限制不可重复的?

是用start来限制的

for(let i = start;i<nums.length;i++){
      ....
      backTrace(track,i+1,target,trackSum);
      ....
}

每次都穿i+1start的值,那么我们的结构如下

image.png

那我如果我们可以重复使用元素,我们就来改变每次的start,改成i

for(let i = start;i<nums.length;i++){
      ....
      backTrace(track,1,target,trackSum);
      ....
}

image.png

题解




function combinationSum(candidates: number[], target: number): number[][] {
  let result = [];
  if(!candidates.length){
    return result;
  }
  // 先排序,让相同的元素靠在一起
  let nums = candidates.sort();
  let track = [];
  let trackSum = 0;
  let start = 0;
  function backTrace(track:number[],start:number,target:number,trackSum):void{
    if(trackSum === target){
      result.push(track.slice());
      return;
    }
    if(trackSum > target){
      return;
    }
  
    for(let i = start;i<nums.length;i++){
      if(i>start&&nums[i]===nums[i-1]){
        continue;
      }
      // 做选择
      track.push(nums[i]);
      trackSum+=nums[i];
      backTrace(track,i,target,trackSum);
      track.pop();
      trackSum-=nums[i];
    }
  }
  backTrace(track, start,target,trackSum)
  return result;
};

参考