下面列举了几种可以用backtracking算法解决的问题。第一题subset的解法可以作为基本框架,其他的题目都是在该框架上做少量修改。
Subsets
Leetcode 78
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],
[]
]
public class Solution{
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
backtracking(res, new ArrayList<Integer>(), nums, 0);
return res;
}
private void backtracking(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]);
backtracking(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
}
Subsets with duplicates
Leetcode 90
public class Solution{
public List<List<Integer>> subsetsWithDup(int[] nums){
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
backtracking(res, new ArrayList<>(), nums, 0);
return res;
}
private void backtracking(List<List<Integer>> list, List<Integer> tempList, int[] nums, int start){
list.add(new ArrayList(tempList));
for(int i = start; i < nums.length; i++){
if(i > start && nums[i] == nums[i-1]) continue; //skip the duplicate
tempList.add(nums[i]);
backtracking(list, tempList, nums, i + 1);
tempList.remove(tempList.size() - 1);
}
}
}
Permutations
Leetcode 46
Given a collection of distinct numbers, return all possible permutations.
public class Solution{
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
backtracking(res, new ArrayList<>(),nums);
return res;
}
private void backtracking(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]);
backtracking(list, tempList, nums);
tempList.remove(tempList.size() - 1);
}
}
}
}
Permutations with duplicates
Leetcode 47
public class Solution{
public List<List<Integer>> permuteUnique(int[] nums){
List<List<Integer>> res = new ArrayList<>();
tracktracking(res, new ArrayList<>(), nums, new boolean[nums.length]);
return res;
}
private void backtracking(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]);
backtracking(list, tempList, nums, used);
used[i] = false;
tempList.remove(tempList.size() - 1);
}
}
}
}
Combination Sum
Leetcode 39
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
For example, given candidate set [2, 3, 6, 7] and target 7,
A solution set is:
[
[7],
[2, 2, 3]
]
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(candidates);
backtracking(res, new ArrayList<>(), candidates, target, 0);
return res;
}
private void backtracking(List<List<Integer>> list, ArrayList<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]);
backtracking(list, tempList, nums, remain - nums[i], i);
tempList.remove(tempList.size() - 1);
}
}
}
}
Combination Sum II
The solution set must not contain duplicate combinations.
public class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(candidates);
backtracking(res, new ArrayList<>(), candidates, target, 0);
return res;
}
private void backtracking(List<List<Integer>> list, ArrayList<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]);
backtracking(list, tempList, nums, remain - nums[i], i + 1);
tempList.remove(tempList.size() - 1);
}
}
}
}
Palindrome Partitioning
Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s = “aab”,
Return
[
[“aa”,”b”],
[“a”,”a”,”b”]
]
public class Solution {
public List<List<String>> partition(String s) {
List<List<String>> res = new ArrayList<>();
backtracking(res, new ArrayList<>(), s, 0);
return res;
}
private void backtracking(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));
backtracking(list, tempList, s, i + 1);
tempList.remove(tempList.size() - 1);
}
}
}
}
private boolean isPalindrome(String s, int low, int high){
while(low < high){
if(s.charAt(low) != s.charAt(high)) return false;
low++;
high--;
}
return true;
}
}