✅✅代码随想录算法训练营Day28 || 78.子集 90.子集II

161 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第18天,点击查看活动详情🚀🚀

前言

开始接触新的题型了~

感觉要比上道题型难那么一点点~

78. 子集 - 力扣(LeetCode)

image.png

回溯

var subsets = function(nums) {
    let path = [];
    let res = [];
    const dfs = (index) => {
        res.push([...path])
        for(let i = index; i < nums.length;i++){
            path.push(nums[i]);
            dfs(i+1);
            path.pop()
        }
    }
    dfs(0);
    return res
};

难点

  • 到了子集问题,我们可以清楚地发现,原来的题目是要求我们收集叶子节点的值,而现在是要我们收集每条路径的值
  • res结果数组的摆放位置

    自己写的时候,把res.push([...path])放在了for循环中,后面自己打log发现,这样会造成一些结果收集不到,比如[1,2,3] ,在收集[1,2,3]时发现收集不到该子集,因为一次path.push和一次path.pop正好逃过了收集阶段。

  • dfs(i+1) 而不是dfs(index+1)

    还是拿简单的测试用例举例,[1,2,3],当收集[1,3]时如果是index+1的话,它还会继续往下一层递归,导致下一层收集到的结果是[1,3,3]

90. 子集 II - 力扣(LeetCode)

image.png

回溯

var subsetsWithDup = function(nums) {
    let res = [];
    let path = [];
    // nums.sort((a,b) => a - b)
    const dfs = (index) => {
        res.push([...path])
        for(let i = index; i < nums.length ; i++){
            if((nums[i] == nums[i-1]) && i > index)
            continue;
            path.push(nums[i])
            dfs(i+1);
            path.pop();
        }
    }
    dfs(0);
    return res
};

难点

  • 去重

    没错,又是这种题,元素中有重复项,所以还是要用到之前使用的 if((nums[i] == nums[i-1]) && i > index) continue; 就可以完美的解决了~

  • 排序

    这道题,去重没难到我,排序竟然把我整迷了

    之所以要排序的原因呢,是和去重有关,因为在去重的逻辑中,比较的是相邻的两个元素,如果不排序的话,去重的逻辑也没有意义了~