leetcode笔记 | 深度优先搜索-78子集 46.全排列(JavaScript)

311 阅读1分钟

子集

CategoryDifficultyLikesDislikes
algorithmsMedium (79.97%)1284-

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

个人题解

var subsets = function (nums) {
    function dfs(index, path, result) {
        result.push(path);
        for (let i = index + 1; i < nums.length; i++) {
            let copy = [...path];
            copy.push(nums[i]);
            dfs(i, copy, result);
        }
    };

    result = [];
    dfs(-1, [], result);

    return result;
};

分析

本题的关键点在于递归思想,在for循环中调用dfs自身。
【堆概念?】

  • 不能直接将[ ]传入result,而是要定义变量result = [ ],否则return时无法找到result。
  • 向path轨迹中增加新元素时,不能直接push,要push到path的复制数组copy中。【描述递归过程?】

全排列

CategoryDifficultyLikesDislikes
algorithmsMedium (78.20%)1498-

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

个人题解

var permute = function (nums) {
    function dfs(path, result) {
        if (path.length === nums.length) {
            result.push(path);
        }
        for (let index = 0; index < nums.length; index++) {
            if (path.indexOf(nums[index]) === -1) {
                let copy = [...path];
                copy.push(nums[index]);
                dfs(copy, result);
            }
        }
    }
    result = [];
    dfs([], result);
    return result;
};

优化

var permute = function (nums) {
    function dfs(path, used, result) {
        if (path.length === nums.length) {
            result.push(path);
        }
        for (let index = 0; index < nums.length; index++) {
            if (!used[index]) {
                let copy = [...path];
                copy.push(nums[index]);
                used[index] = true;
                dfs(copy, used, result);
                used[index] = false;
            }
        }
    }
    result = [];
    used = new Array(nums.length).fill(false);

    dfs([], used, result);
    return result;
};

使用used数组判断元素是否使用过,可以降低时间复杂度O(n2)至O(n)。