1. 基本模板
class Solution {
public List<List<元素类型>> 方法名(参数列表){
List<List<元素类型>> ans = new ArrayList<>();
if (返回空集合条件) return ans;
List<元素类型> path = new ArrayList<>();
boolean[] used = new boolean[数组长度];
Arrays.fill(used);
backtrack(ans,path,遍历目标,遍历开始位置,used);
return ans;
}
public void backtrack(List<List<元素类型>> ans,List<元素类型> path,遍历目标,遍历开始位置,boolean[] used) {
if (遍历成功条件){
ans.add(new ArrayList<>(path));
return;
}
else {
for (int i = 开始位置;判断条件;i++) {
if (!used[i]){
path添加操作;
used[i] = true;
backtrack(List<List<元素类型>> ans,List<元素类型> path,遍历目标,遍历开始位置更新,boolean[] used);
used[i] = false;
path移除操作
}
}
}
}
}
2. 经典例题
2.1 组合
组合
class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> list = new ArrayList<>();
if(n == 0 || k == 0) return res;
backtrack(res,list,n,k,0,1);
return res;
}
public void backtrack(List<List<Integer>> res,List<Integer> list,int n,int k,int sum,int start){
if(sum == k){
res.add(new ArrayList(list));
return;
}
for(int i = start;i <= n;i++){
list.add(i);
backtrack(res,list,n,k,sum + 1,i + 1);
list.remove(list.size() - 1);
}
}
}
2.2 组合总和
组合总和
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
if(candidates == null || candidates.length == 0 || target < 0){
return res;
}
Arrays.sort(candidates);
backtrack(res,path,candidates,target,0);
return res;
}
public void backtrack(List<List<Integer>> res,List<Integer> path,int[] candidates,int target,int index){
if(target == 0){
res.add(new ArrayList<>(path));
}
else{
for(int i = index;i < candidates.length;i++){
if(target - candidates[i] < 0){
break;
}
path.add(candidates[i]);
backtrack(res,path,candidates,target - candidates[i],i);
path.remove(path.size() - 1);
}
}
}
}
2.3 组合总和2
组合总和2
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
if(candidates.length == 0 || candidates == null || target < 0){
return res;
}
Arrays.sort(candidates);
backtrack(res,path,candidates,target,0);
return res;
}
public void backtrack(List<List<Integer>> res,List<Integer> path,int[] candidates,int target,int index){
if(target == 0){
res.add(new ArrayList<>(path));
}
else{
for(int i = index;i < candidates.length;i++){
if(target - candidates[i] < 0){
break;
}
path.add(candidates[i]);
backtrack(res,path,candidates,target - candidates[i],i + 1);
while(i + 1 < candidates.length && path.get(path.size() - 1) == candidates[i + 1]){
i++;
}
path.remove(path.size() - 1);
}
}
}
}
2.4 全排列
全排列
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if(nums.length == 0) return res;
List<Integer> path = new ArrayList<>();
boolean[] used = new boolean[nums.length];
Arrays.fill(used,false);
backtrack(res,path,nums,0,used);
return res;
}
public void backtrack(List<List<Integer>> res,List<Integer> path,int[] nums,int index,boolean[] used){
if(path.size() == nums.length){
res.add(new ArrayList<>(path));
return;
}
else{
for(int i = 0;i < nums.length;i++){
if(!used[i]){
path.add(nums[i]);
used[i] = true;
backtrack(res,path,nums,index + 1,used);
used[i] = false;
path.remove(path.size() - 1);
}
}
}
}
}
2.5 全排列2
class Solution {
public List<List<Integer>> permuteUnique(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if(nums.length == 0) return res;
Arrays.sort(nums);
List<Integer> path = new ArrayList<>();
boolean[] used = new boolean[nums.length];
Arrays.fill(used,false);
backtrack(res,path,nums,0,used);
return res;
}
public void backtrack(List<List<Integer>> res,List<Integer> path,int[] nums,int index,boolean[] used){
if(path.size() == nums.length){
res.add(new ArrayList<>(path));
return;
}
else{
for(int i = 0;i < nums.length;i++){
if(!used[i]){
path.add(nums[i]);
used[i] = true;
backtrack(res,path,nums,index + 1,used);
used[i] = false;
while(i + 1 < nums.length && path.get(path.size() - 1) == nums[i + 1]){
i++;
}
path.remove(path.size() - 1);
}
}
}
}
}
2.6 单词搜索
单词搜索
class Solution {
boolean flag = false;
public boolean exist(char[][] board, String word) {
if(board.length == 0 || board[0].length == 0 || word.length() == 0) return false;
boolean[][] used = new boolean[board.length][board[0].length];
for(int i = 0;i < board.length;i++){
for(int j = 0;j < board[0].length;j++){
if(board[i][j] != word.charAt(0)) continue;
backtrack(board,word,i,j,0,used);
if(flag == true) break;
}
if(flag == true) break;
}
return flag;
}
public void backtrack(char[][] board,String word,int i,int j,int index,boolean[][] used){
if(flag) return;
if(board[i][j] == word.charAt(index)){
used[i][j] = true;
if(index + 1 == word.length()){
flag = true;
return;
}
else{
if(i - 1 >= 0){
if(!used[i - 1][j]){
used[i - 1][j] = true;
backtrack(board,word,i - 1,j,index + 1,used);
used[i - 1][j] = false;
}
}
if(j - 1 >= 0){
if(!used[i][j - 1]){
used[i][j - 1] = true;
backtrack(board,word,i,j - 1,index + 1,used);
used[i][j - 1] = false;
}
}
if(i + 1 < board.length){
if(!used[i + 1][j]){
used[i + 1][j] = true;
backtrack(board,word,i + 1,j,index + 1,used);
used[i + 1][j] = false;
}
}
if(j + 1 < board[0].length){
if(!used[i][j + 1]){
used[i][j + 1] = true;
backtrack(board,word,i,j + 1,index + 1,used);
used[i][j + 1] = false;
}
}
used[i][j] = false;
}
}
else{
used[i][j] = false;
return;
}
}
}