动态规划二(子集、全排列、组和)

78. Subsets

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],
  []
]
public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> alist = new ArrayList<>();
        if(nums.length < 1)
            return alist;
        backTrack(alist,new ArrayList<>(), nums, 0);
        return alist;
    }
    void backTrack(List<List<Integer>> alist, List<Integer> blist, int[] nums, int i){
        if(i == nums.length){
            alist.add(new ArrayList<>(blist));
            return;
        }
        backTrack(alist,blist,nums,i + 1); //要这个值
        blist.add(nums[i]);
        backTrack(alist,blist,nums,i + 1); //不要最后一个
        blist.remove(blist.size() - 1);
    }

90. Subsets II

Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: [1,2,2]
Output:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
		List<List<Integer>> result = new ArrayList<List<Integer>>();
        backTracking2(nums, result, new ArrayList<>(), 0);
        return result;
        
    }
	void backTracking(int[] nums,  List<List<Integer>> alist, List<Integer> blist, int i) {
		if(i == nums.length) {
			if(!alist.contains(blist))
				alist.add(new ArrayList<>(blist));
			return;
		}
		backTracking(nums, alist, blist, i + 1); //要当前值
		blist.add(nums[i]);
		backTracking(nums, alist, blist, i + 1); //不要当前值
		blist.remove(blist.size() - 1);			
	}
    void backTracking2(int[] nums,  List<List<Integer>> alist, List<Integer> blist, int i) {
		if(blist.size() <= nums.length ) { //由于是子集,所以遇到的每一个值都有可能是答案
			alist.add(new ArrayList<>(blist));
		}
		for (int j = i; j < nums.length; j++) {
			if(j > i && nums[j] == nums[j - 1])
				continue;
			blist.add(nums[j]);
			backTracking2(nums, alist, blist, j + 1);
			blist.remove(blist.size() - 1);	
		}
	}

46. Permutations

Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]
public  List<List<Integer>> permute(int[] nums) {
	        List<List<Integer>> alist = new ArrayList<List<Integer>>();
	        if(nums == null || nums.length < 1)
	        	return alist;
	        Process(alist, new ArrayList<>(), nums);
	        return alist;
	           }
	
    public void Process(List<List<Integer>> blist, List<Integer> clist, int[] nums){
	    if(clist.size() == nums.length){
            blist.add(new ArrayList<>(clist));
            return;
        }	
	    for (int j = 0; j < nums.length; j++) {
		//swap(nums, i, j);
                if(clist.contains(nums[j]))
                    continue;
                clist.add(nums[j]);
	        Process(blist, clist, nums);
                clist.remove(clist.size() - 1);
	     }
	}
	
	public void swap(int[] nums, int i, int j) {
		int tmp = nums[i];
		nums[i] = nums[j];
		nums[j] = tmp;
	}

47. Permutations II

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

Example:

Input: [1,1,2]
Output:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]
public List<List<Integer>> permuteUnique(int[] nums) {
		Arrays.sort(nums);
		List<List<Integer>> result = new ArrayList<List<Integer>>();
		boolean[] u = new boolean[nums.length]; 
		backTracking(result, new ArrayList<>(), nums, u);
		return result;
	    }
	
	public void backTracking(List<List<Integer>> alist, List<Integer> blist, 
                             int[] nums, boolean[] used) {
		if(blist.size() == nums.length) {
			alist.add(new ArrayList<>(blist));
			return;
		} 
		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;
			blist.add(nums[i]);
			backTracking(alist, blist, nums, used);
			used[i] = false;
			blist.remove(blist.size() - 1);
		}
	}

39. Combination Sum

Given a set of candidate numbers (candidates(without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

The same repeated number may be chosen from candidates unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

Example 1:

Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
  [7],
  [2,2,3]
]

Example 2:

Input: candidates = [2,3,5], target = 8,
A solution set is:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]
 public List<List<Integer>> combinationSum(int[] candidates, int target) { 
		 Arrays.sort(candidates);
		 List<List<Integer>> result = new ArrayList<List<Integer>>();
		 backTracking(candidates, target, 0, result, new ArrayList<>()); 
		 return result;
	 }
	 private void backTracking(int[] candidates, int target, int start,
                              List<List<Integer>> alist, List<Integer> blist) {
		 if(target == 0) {
			 alist.add(new ArrayList<>(blist));
			 return;
		 }
		 //导致出现重复是由于此处的i又从0开始计算的,
		 //因为i额数组已经排序好了,当走到数组中间的时候前面的已经走过了
		 for (int i = start; i < candidates.length; i++) { 
			 if(candidates[i] <= target) {
				 blist.add(candidates[i]);
				 backTracking(candidates, target - candidates[i], i,alist, blist);
				 blist.remove(blist.size() - 1);
			 }
		}
	 }

40. Combination Sum II

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

Each number in candidates may only be used once in the combination.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

Example 1:

Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

Example 2:

Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
  [1,2,2],
  [5]
]
 public List<List<Integer>> combinationSum2(int[] candidates, int target) {
		Arrays.sort(candidates);
		List<List<Integer>> result = new ArrayList<List<Integer>>();
		backTracking(candidates, target, 0, result, new ArrayList<>());
		return result;
    }
	void backTracking(int[] candidates, int target, int i, 
                             List<List<Integer>> alist, List<Integer> blist) {
		
		if(target == 0) {
			alist.add(new ArrayList<>(blist));
			return;
		}//int i = start
		for (; i < candidates.length; i++) {
			if(target < candidates[i]) break;
			blist.add(candidates[i]);
			backTracking(candidates, target - candidates[i], i + 1, alist, blist);
			blist.remove(blist.size() - 1);
			//每次清除一个空位让后续元素加入。寻找成功,最后一个元素要退位,
			//寻找不到,方法不可行,那么我们回退,也要移除最后一个元素。
			while (i < candidates.length - 1 && candidates[i] == candidates[i + 1]) {
				i++;	
			}
		}
	}

猜你喜欢

转载自blog.csdn.net/qq_40722284/article/details/91811609