78. 子集
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3] 输出: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
public class T78 { public List<List<Integer>> subsets(int[] nums) { List<List<Integer>> lists = new ArrayList<>(); if (nums == null || nums.length == 0) { return lists; } getLists(nums, 0, lists, new ArrayList<>()); return lists; } private void getLists(int[] nums, int index, List<List<Integer>> lists, ArrayList<Integer> integers) { lists.add(new ArrayList<>(integers)); for (int i = index; i < nums.length; i++) { integers.add(nums[i]); getLists(nums, i + 1, lists, integers); integers.remove(integers.size() - 1); } } }
90. 子集 II
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: [1,2,2] 输出: [ [2], [1], [1,2,2], [2,2], [1,2], [] ]
public class T90 { public List<List<Integer>> subsetsWithDup(int[] nums) { List<List<Integer>> lists = new ArrayList<>(); if (nums == null || nums.length == 0) { return lists; } Arrays.sort(nums); recursion(nums, 0, lists, new ArrayList<Integer>()); return lists; } private void recursion(int[] nums, int i, List<List<Integer>> lists, ArrayList<Integer> integers) { lists.add(new ArrayList<>(integers)); for (int j = i; j < nums.length; j++) { if (j > i && nums[j] == nums[j - 1]) { continue; } integers.add(nums[j]); recursion(nums,j + 1,lists,integers); integers.remove(integers.size() - 1); } } }
39. 组合总和
给定一个无重复元素的数组 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的数字可以无限制重复被选取。
说明:
- 所有数字(包括
target
)都是正整数。 - 解集不能包含重复的组合。
示例 1:
输入: candidates =[2,3,6,7],
target =7
, 所求解集为: [ [7], [2,2,3] ]
示例 2:
输入: candidates = [2,3,5],
target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
public class T39 { public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> lists = new ArrayList<>(); if (candidates == null || candidates.length == 0) { return lists; } Arrays.sort(candidates); getLists(candidates, target, 0, lists, new ArrayList<>()); return lists; } private void getLists(int[] candidates, int target, int start, List<List<Integer>> lists, ArrayList<Integer> list) { if (start == candidates.length || target <= 0) { if (target == 0) { lists.add(new ArrayList<>(list)); return; } else if (target < 0) { return; } } for (int i = start; i < candidates.length; i++) { if (i > start && candidates[i] == candidates[i - 1]) { continue; } list.add(candidates[i]); getLists(candidates, target - candidates[i], i, lists, list); list.remove(list.size() - 1); } } }
40. 组合总和 II
给定一个数组 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的每个数字在每个组合中只能使用一次。
说明:
- 所有数字(包括目标数)都是正整数。
- 解集不能包含重复的组合。
示例 1:
输入: candidates =[10,1,2,7,6,1,5]
, target =8
, 所求解集为: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5, 所求解集为: [ [1,2,2], [5] ]
public class T40 { public List<List<Integer>> combinationSumII(int[] candidates, int target) { List<List<Integer>> lists = new ArrayList<>(); if (candidates == null || candidates.length == 0) { return lists; } Arrays.sort(candidates); getLists(candidates, target, 0, lists, new ArrayList<>()); return lists; } private void getLists(int[] candidates, int target, int start, List<List<Integer>> lists, ArrayList<Integer> list) { if (start == candidates.length || target <= 0) { if (target == 0) { lists.add(new ArrayList<>(list)); return; } else if (target < 0) { return; } } for (int i = start; i < candidates.length; i++) { if (i > start && candidates[i] == candidates[i - 1]) { continue; } list.add(candidates[i]); getLists(candidates, target - candidates[i], i + 1, lists, list); list.remove(list.size() - 1); } } }
46. 全排列
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3] 输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
public class T46 { public List<List<Integer>> permute(int[] nums) { List<List<Integer>> lists = new ArrayList<>(); if (nums == null || nums.length == 0) { return lists; } boolean[] visited = new boolean[nums.length]; getLists(nums, visited, new ArrayList<Integer>(), lists); return lists; } private void getLists(int[] nums, boolean[] visited, ArrayList<Integer> list, List<List<Integer>> lists) { if (list.size() == nums.length) { lists.add(new ArrayList<>(list)); return; } for (int i = 0; i < nums.length; i++) { if (!visited[i]) { visited[i] = true; list.add(nums[i]); getLists(nums, visited, list, lists); list.remove(list.size() - 1); visited[i] = false; } } } }
47. 全排列 II
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2] 输出: [ [1,1,2], [1,2,1], [2,1,1] ]
public class T47 { public List<List<Integer>> permuteUnique(int[] nums) { List<List<Integer>> lists = new ArrayList<>(); if (nums == null || nums.length == 0) { return lists; } Arrays.sort(nums); boolean[] visited = new boolean[nums.length]; getLists(nums, visited, new ArrayList<Integer>(), lists); return lists; } private void getLists(int[] nums, boolean[] visited, ArrayList<Integer> list, List<List<Integer>> lists) { if (list.size() == nums.length) { lists.add(new ArrayList<>(list)); return; } for (int i = 0; i < nums.length; i++) { if (visited[i] || (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1])) { continue; } visited[i] = true; list.add(nums[i]); getLists(nums, visited, list, lists); list.remove(list.size() - 1); visited[i] = false; } } }