Leetcode 78 Subsets

来源:互联网 发布:软件技术指标怎么写 编辑:程序博客网 时间:2024/06/03 21:09

Given a set of distinct integers, nums, return all possible subsets.

Note: The solution set must not contain duplicate subsets.

For example,
If nums = [1,2,3], a solution is:

[  [3],  [1],  [2],  [1,2,3],  [1,3],  [2,3],  [1,2],  []]

经典的backtracking的问题。

想顺便把这一类的总结一下。

emmmm。。今天大概开始慢慢磨???

第一种情况 subset 有重复

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

第二种情况 subset 无重复

public class Solution {    public List<List<Integer>> subsets(int[] nums) {        List<List<Integer>> list = new ArrayList<>();        Arrays.sort(nums);        helper(list, new ArrayList<>(), nums, 0);        return list;    }        private void helper(List<List<Integer>> list, List<Integer> tmp, int[] nums, int index){        list.add(new ArrayList<>(tmp));        for(int i = index; i < nums.length; i++){            if(i > index && nums[i] == nums[i - 1]) continue;//和上面唯一不同的地方在于这            tmp.add(nums[i]);            helper(list, tmp, nums, i + 1);            tmp.remove(tmp.size() - 1);        }    }}


第三种情况 permutation 全排列

public List<List<Integer>> permute(int[] nums) {   List<List<Integer>> list = new ArrayList<>();   backtrack(list, new ArrayList<>(), nums);   return list;}private void backtrack(List<List<Integer>> list, List<Integer> temp, int [] nums){   if(temp.size() == nums.length){      list.add(new ArrayList<>(tempList));   } else{      for(int i = 0; i < nums.length; i++){ //和上面不同的point在于这里是完全遍历一遍          if(temp.contains(nums[i])) continue;         temp.add(nums[i]);         backtrack(list, temp, nums);         temp.remove(temp.size() - 1);      }   }} 

第四种情况 permutation 全排列 无重复 
那么为了不把重复元素重复排列,需要一个visited数组来标记
public List<List<Integer>> permuteUnique(int[] nums) {    List<List<Integer>> list = new ArrayList<>();    Arrays.sort(nums);//这里一定要排序了    backtrack(list, new ArrayList<>(), nums, new boolean[nums.length]);    return list;}private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, boolean [] used){    if(tempList.size() == nums.length){        list.add(new ArrayList<>(tempList));    } else{        for(int i = 0; i < nums.length; i++){            if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue;//注意这里的条件 相同的元素当且仅当前面的也在序列里面才加入 也就是当成一个整体 所以就没有相同的元素排序的问题            used[i] = true; //当前的排列里面使用了这个element            tempList.add(nums[i]);            backtrack(list, tempList, nums, used);            used[i] = false;             tempList.remove(tempList.size() - 1);        }    }}

第五种情况 combination sum 就是从一个序列里面取出和为sum的若干元素 允许重复
public List<List<Integer>> combinationSum(int[] nums, int target) {    List<List<Integer>> list = new ArrayList<>();    Arrays.sort(nums);    backtrack(list, new ArrayList<>(), nums, target, 0);    return list;}private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){    if(remain < 0) return;    else if(remain == 0) list.add(new ArrayList<>(tempList));    else{         for(int i = start; i < nums.length; i++){            tempList.add(nums[i]);            backtrack(list, tempList, nums, remain - nums[i], i); //这里从i开始是为了能重复使用同一个element            tempList.remove(tempList.size() - 1);        }    }}

第六种 combination sum 就是从一个序列里面取出和为sum的若干元素 但不允许重复
public List<List<Integer>> combinationSum2(int[] nums, int target) {    List<List<Integer>> list = new ArrayList<>();    Arrays.sort(nums);    backtrack(list, new ArrayList<>(), nums, target, 0);    return list;    }private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){    if(remain < 0) return;    else if(remain == 0) list.add(new ArrayList<>(tempList));    else{        for(int i = start; i < nums.length; i++){            if(i > start && nums[i] == nums[i-1]) continue; //不允许用相等的俩元素            tempList.add(nums[i]);            backtrack(list, tempList, nums, remain - nums[i], i + 1);//也不允许对同一元素重复利用            tempList.remove(tempList.size() - 1);         }    }} 




原创粉丝点击