Given an integer array nums of unique elements, return all possible subsets (the power set). The solution set must not contain duplicate subsets. Return the solution in any order.
Given two integers n and k, return all possible combinations of k numbers chosen from the range [1, n]. You may return the answer in any order.
Example 1:
Input: n = 4, k = 2 Output: [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]] Explanation: There are 4 choose 2 = 6 total combinations. Note that combinations are unordered, i.e., [1,2] and [2,1] are considered to be the same combination.
classSolution { private List<List<Integer>> res = newArrayList<>();
public List<List<Integer>> combine(int n, int k) { backtracking(n, k, newArrayList<>()); return res; }
privatevoidbacktracking(int i, int k, List<Integer> arr) { if (arr.size() == k) { res.add(newArrayList<>(arr)); return; } if (i > k - arr.size()) { backtracking(i-1, k, arr); } arr.add(i); backtracking(i-1, k, arr); arr.remove(arr.size()-1); } }
Solution 2
若必须将当前元素放入数组中, 则需保证以下两点:
当前数组的长度不可超过k
[i+1, n]表示之后还可以添加的元素数量, k - 当前数组长度表示组合还需要几个元素, 因此需保证len([i+1, n]) >= k - len(arr)
classSolution { private List<List<Integer>> res = newArrayList<>();
public List<List<Integer>> combine(int n, int k) { backtracking(n, k, newArrayList<>()); return res; }
privatevoidbacktracking(int i, int k, List<Integer> arr) { if (i < k - arr.size()) return; if (arr.size() == k) { res.add(newArrayList<>(arr)); return; } for (intj= i; j > 0; j--) { arr.add(j); backtracking(j-1, k, arr); arr.remove(arr.size()-1); } } }
39. Combination Sum
Problem Description
Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. You may return the combinations in any order. The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the frequency of at least one of the chosen numbers is different. The test cases are generated such that the number of unique combinations that sum up to target is less than 150 combinations for the given input.
Example 1:
Input: candidates = [2,3,6,7], target = 7 Output: [[2,2,3],[7]] Explanation: 2 and 3 are candidates, and 2 + 2 + 3 = 7. Note that 2 can be used multiple times. 7 is a candidate, and 7 = 7. These are the only two combinations.
Solution 1
该题目需要注意两点:
每个元素都可以被选择无数次
没有要求组合的长度, 但要求当前数组的总和等于target, 因此需修改边界条件
classSolution { private List<List<Integer>> res = newArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) { Arrays.sort(candidates); backtracking(candidates, 0, target, newArrayList<>()); return res; } privatevoidbacktracking(int[] candidates, int i, int target, List<Integer> arr) { if (target == 0) { res.add(newArrayList<>(arr)); return; } if (i == candidates.length || target < candidates[i]) return; // skip backtracking(candidates, i+1, target, arr); // pick up arr.add(candidates[i]); backtracking(candidates, i, target-candidates[i], arr); // i instead of i+1 arr.remove(arr.size()-1); } }
3. Solution 2
classSolution { private List<List<Integer>> res = newArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) { Arrays.sort(candidates); backtracking(candidates, 0, target, newArrayList<>()); return res; } privatevoidbacktracking(int[] candidates, int i, int target, List<Integer> arr) { if (target == 0) { res.add(newArrayList<>(arr)); return; } if (i == candidates.length || target < candidates[i]) return; for (intj= i; j < candidates.length; j++) { arr.add(candidates[j]); backtracking(candidates, j, target-candidates[j], arr); // j instead of j+1 arr.remove(arr.size()-1); } } }
40. Combination Sum II
Problem Description
Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sum to target. Each number in candidates may only be used once in the combination.
classSolution { private List<List<Integer>> res = newArrayList<>(); public List<List<Integer>> combinationSum2(int[] candidates, int target) { Arrays.sort(candidates); backtrack(candidates, 0, target, newArrayList<>()); return res; }
privatevoidbacktrack(int[] candidates, int i, int target, List<Integer> arr) { if (target == 0) { res.add(newArrayList<>(arr)); return; } if (i == candidates.length || candidates[i] > target) return; for (intj= i; j < candidates.length; j++) { if (j > i && candidates[j-1] == candidates[j]) continue; arr.add(candidates[j]); backtrack(candidates, j+1, target-candidates[j], arr); arr.remove(arr.size()-1); } } }
216. Combination Sum III
Problem Description
Find all valid combinations of k numbers that sum up to n such that the following conditions are true:
Only numbers 1 through 9 are used.
Each number is used at most once.
Return a list of all possible valid combinations. The list must not contain the same combination twice, and the combinations may be returned in any order.
Example 1:
Input: k = 3, n = 7 Output: [[1,2,4]] Explanation: 1 + 2 + 4 = 7 There are no other valid combinations.
Solution 1
该题的要求如下:
[1, 9]中每个数字只能选择一个: 元素只能向一个方向移动, 不能原地踏步
要求组合的长度: 边界条件中判断组合长度是否越界
要求组合的总和: 边界条件中判断组合总和是否越界
classSolution { private List<List<Integer>> res = newArrayList<>(); public List<List<Integer>> combinationSum3(int k, int n) { backtracking(k, n, 1, newArrayList<>()); return res; }
privatevoidbacktracking(int k, int n, int i, List<Integer> arr) { if (n == 0 && k == 0) { res.add(newArrayList<>(arr)); return; } if (i > n || k == 0 || i > 9) return; // n cannot be negative, k cannot be negative, i cannot be bigger than 9 // skip backtracking(k, n, i+1, arr); // pick up arr.add(i); backtracking(k-1, n-i, i+1, arr); // i -> i + 1, deduplicate arr.remove(arr.size()-1); } }
Solution 2
classSolution { private List<List<Integer>> res = newArrayList<>(); public List<List<Integer>> combinationSum3(int k, int n) { backtracking(k, n, 1, newArrayList<>()); return res; }
privatevoidbacktracking(int k, int n, int i, List<Integer> arr) { if (n == 0 && k == 0) { res.add(newArrayList<>(arr)); return; } if (i > n || k == 0) return; for (intj= i; j <= 9; j++) { arr.add(j); backtracking(k-1, n-j, j+1, arr); // j -> j + 1, deduplicate arr.remove(arr.size()-1); } } }
classSolution { private List<List<Integer>> res = newArrayList<>(); public List<List<Integer>> permuteUnique(int[] nums) { Arrays.sort(nums); backtracking(nums, newboolean[nums.length], newArrayList<>()); return res; }
privatevoidbacktracking(int[] nums, boolean[] isUsed, List<Integer> arr) { if (arr.size() == nums.length) { res.add(newArrayList<>(arr)); return; } for (inti=0; i < nums.length; i++) { if (isUsed[i]) continue; if (i > 0 && nums[i-1] == nums[i] && !isUsed[i-1]) continue; isUsed[i] = true; arr.add(nums[i]); backtracking(nums, isUsed, arr); arr.remove(arr.size()-1); isUsed[i] = false; } } }
51. N-Queens
Problem Description
The n-queens puzzle is the problem of placing n queens on an n x n chessboard such that no two queens attack each other. Given an integer n, return all distinct solutions to the n-queens puzzle. You may return the answer in any order. Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space, respectively.
Example 1:
Input: n = 4 Output: [ [".Q..", "...Q", "Q...", "..Q."], ["..Q.", "Q...", "...Q", ".Q.."] ] Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above