1.求子集
给定一组不同的整数,nums,返回所有可能的子集(幂集)。
注意:解决方案集不得包含重复的子集。
例子:
Input: nums = [1,2,3]
Output:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
代码如下:
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> list = new ArrayList();
Arrays.sort(nums);
backtrack(list,new ArrayList<>(),nums,0);
return list;
}
private void backtrack(List<List<Integer>>list,List<Integer>tempList,int []nums,int start){
list.add(new ArrayList<>(tempList));
for(int i = start;i<nums.length;i++){
tempList.add(nums[i]);
backtrack(list,tempList,nums,i+1);
tempList.remove(tempList.size()-1);
}
}
}
给定可能包含重复项,nums的整数集合,返回所有可能的子集(幂集)。
注意:解决方案集不得包含重复的子集。
例子:
Input: [1,2,2]
Output:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
public List<List<Integer>> subsetsWithDup(int nums){
List<List<Integer>> list = new ArrayList<>();
Arrays.sort(nums);
backtrack(list,new ArrayList<>(),nums,0);
return list;
}
private void backtrack(List<List<Integer>> list,List<Integer> tempList,int []nums,int start){
list.add(new ArrayList<>(new ArrayList<>(tempList));
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,i+1);
tempList.remove(tempList.size()-1);
}
}
3.给定一组不同的整数,返回所有可能的排列。
举例:
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>> list = new ArrayList<>();
backtrack(list,new ArrayList<>(),nums);
return list;
}
private void backtrack(List<List<Integer>> list,List<Integer> tempList,int []nums){
if(tempList.size() == nums.length){
list.add(new ArrayList<>(tempList));
}else{
for(int i = 0;i<nums.length;i++){
if(tempList.contains(nums[i])) continue;
tempList.add(nums[i]);
backtrack(list,tempList,nums);
tempList.remove(tempList.size()-1);
}
}
}
4.给定可能包含重复项的数字集合,返回所有可能的唯一排列。
举例:
Input: [1,1,2]
Output:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
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;
tempList.add(nums[i]);
backtrack(list, tempList, nums, used);
used[i] = false;
tempList.remove(tempList.size() - 1);
}
}
}
给定一组候选数字(候选者)(没有重复)和目标数量(目标),找到候选人数总和目标的候选人中的所有独特组合。
可以从候选者无限次数中选择相同的重复数字。
注意:
所有数字(包括目标)都是正整数。
解决方案集不得包含重复的组合。
举例:Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
[7],
[2,2,3]
]
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[] 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+1,因为我们可以
//接受重复的数
tempList.remove(tempList.size() - 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]
]
Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
[1,2,2],
[5]
]
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);
}
}
}
给定字符串s,分区s使得分区的每个子字符串都是回文。
返回s的所有可能的回文分区。
举例:
Input: “aab”
Output:
[
[“aa”,“b”],
[“a”,“a”,“b”]
]
public List<List<String>> partition(String s) {
List<List<String>> list = new ArrayList<>();
backtrack(list, new ArrayList<>(), s, 0);
return list;
}
public void backtrack(List<List<String>> list, List<String> tempList, String s, int start){
if(start == s.length())
list.add(new ArrayList<>(tempList));
else{
for(int i = start; i < s.length(); i++){
if(isPalindrome(s, start, i)){
tempList.add(s.substring(start, i + 1));
backtrack(list, tempList, s, i + 1);
tempList.remove(tempList.size() - 1);
}
}
}
}
public boolean isPalindrome(String s, int low, int high){
while(low < high)
if(s.charAt(low++) != s.charAt(high--)) return false;
return true;
}