Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LeetCode 78. Subsets #40

Open
Woodyiiiiiii opened this issue May 1, 2020 · 0 comments
Open

LeetCode 78. Subsets #40

Woodyiiiiiii opened this issue May 1, 2020 · 0 comments

Comments

@Woodyiiiiiii
Copy link
Owner

Woodyiiiiiii commented May 1, 2020

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: nums = [1,2,3]
Output:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

这道题显然不能纯粹使用暴力法,因为我们不知道到底有多少可能,只能观察数据找规律。
实际上每次存进线性表,可以看作在线性表的元素基础上加上新的nums数组中的元素,再存入线性表中。比如nums = {1, 2},一开始线性表初始化为[[]],元素只有一个,取出来加上元素1等于[1],再存入线性表中,线性表变为[[], [1]],同理,加入2后变为[[], [1], [2], [1, 2]]。

//C++ solution:
class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int> > res(1);
        sort(nums.begin(), nums.end());
        for (int i = 0; i < nums.size(); ++i) {
            int size = res.size();
            for (int j = 0; j < size; ++j) {
                res.push_back(res[j]);
                res.back().push_back(nums[i]);
            }
        }
        return res;
    }
};
//Java solution:
class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        int n = nums.length;
        List<List<Integer>> res = new LinkedList();
        if (n == 0) return res;
        Arrays.sort(nums);
        res.add(new LinkedList<Integer>());
        for (int i = 0; i < n; ++i) {
            int size = res.size();
            for (int j = 0; j < size; ++j) {
                res.add(new LinkedList<>(res.get(j)));
                res.get(res.size() - 1).add(nums[i]);
            }
        }
        return res;
    }
}

注意Java跟C++的解法不同,因为Java容器类太不方便了。取出元素时使用get方法,然而实际上因为Java的值传递,我们并没有声明新的空间,存入线性表中的元素内存地址是一样的,所以如果按照C++的解法,在向某元素添加新的nums里的数值时,会对原本的线性表元素产生影响。比如,[[1]]中我想加入数值2,取出1加上2并存入线性表,然而线性表会变成[[1, 2], [1, 2]]而不是[[1], [1, 2]]。

当然实现了List接口的ArrayList和LinkedList类实现了clone函数,但是我们可以new一个list,初始化值是list类型

res.add(new LinkedList<>(res.get(j)));

这道题我们也可用DFS+回溯法来做,原理同77. combinations

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        int n = nums.length;
        List<List<Integer>> res = new ArrayList<>();
        if (n == 0) return res;
        Arrays.sort(nums);
        List<Integer> tmp = new ArrayList<>();
        dfs(res, tmp, nums, 0);
        return res;
    }
    public void dfs(List<List<Integer>> res, List<Integer> tmp, int[] nums, int start) {
        res.add(new ArrayList<>(tmp));
        if (tmp.size() == nums.length) return;
        for (int i = start; i < nums.length; ++i) {
            tmp.add(nums[i]);
            dfs(res, tmp, nums, i + 1);
            tmp.remove(tmp.size() - 1);
        }
    }
}

看大佬还有两种做法,分别是二叉树和列表,有兴趣可以点击参考资料去了解下。


参考资料:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant