遞歸回溯問題的四道經典題:N皇后,組合,全排列,二叉樹路徑和
阿新 • • 發佈:2019-02-17
組合和排列問題的實質是對N叉樹的遍歷,只是退出條件不同。
1.組合
描述:給出兩個整數n和k,返回從1……n中選出的k個數的組合。
樣例:
例如 n = 4 且 k = 2
返回的解為:
[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4]]
public class Solution {
/**
* @param n: Given the range of numbers
* @param k: Given the numbers of combinations
* @return: All the combinations of k numbers out of 1..n
*/
public List<List<Integer>> combine(int n, int k) {
// write your code here
List<List<Integer>> res=new ArrayList<>();
List<Integer> solution=new ArrayList<>();
if(n<=0)
return res;
if(n<k){
return res;
}
helper(res,solution,n,k,1);
return res;
}
void helper(List<List<Integer>> res,List<Integer> solution,int n,int k,int start){
if(solution.size()==k){
res.add(new ArrayList<Integer>(solution));
return;
}
for (int i=start;i<=n;++i){
solution.add(i);
helper(res,solution,n,k,i+1);
solution.remove(solution.size()-1);
}
}
}
全排列:
描述:給定一個數字列表,返回其所有可能的排列。
樣例:
給出一個列表[1,2,3],其全排列為:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
class Solution {
/**
* @param nums: A list of integers.
* @return: A list of permutations.
*/
public List<List<Integer>> permute(int[] nums) {
// write your code here
ArrayList<List<Integer>> res=new ArrayList<List<Integer>>();
if(nums==null)
return res;
if(nums.length==0){
res.add(new ArrayList<Integer>());
return res;
}
List<Integer> solution=new ArrayList<>();
helper(nums,res,solution);
return res;
}
public void helper(int[] nums,List<List<Integer>> res,List<Integer> solution){
if(solution.size()==nums.length){
res.add(new ArrayList<Integer>(solution));
return;
}
for(int i=0;i<nums.length;++i){
if(solution.contains(nums[i])){
continue;
}
solution.add(nums[i]);
helper(nums,res,solution);
solution.remove(solution.size()-1);
}
}
}
N皇后問題:
描述:
n皇后問題是將n個皇后放置在n*n的棋盤上,皇后彼此之間不能相互攻擊。
給定一個整數n,返回所有不同的n皇后問題的解決方案。
每個解決方案包含一個明確的n皇后放置佈局,其中“Q”和“.”分別表示一個女王和一個空位置。
對於4皇后問題存在兩種解決的方案:
[
[".Q..", // Solution 1
"...Q",
"Q...",
"..Q."],
["..Q.", // Solution 2
"Q...",
"...Q",
".Q.."]
]
class Solution {
/**
* Get all distinct N-Queen solutions
* @param n: The number of queens
* @return: All distinct solutions
* For example, A string '...Q' shows a queen on forth position
*/
ArrayList<ArrayList<String>> solveNQueens(int n) {
// write your code here
ArrayList<ArrayList<String>> res=new ArrayList<ArrayList<String>>();
if(n<=0){
return res;
}
ArrayList<Integer> cols=new ArrayList<>();
search(res,cols,n);
return res;
}
public void search(ArrayList<ArrayList<String>> res,ArrayList<Integer> cols,int n){
if(cols.size()==n){
res.add(draw(cols));
return;
}
for(int index=0;index<n;++index){
if(!isSafe(cols,index)){
continue;
}
cols.add(index);
search(res,cols,n);
cols.remove(cols.size()-1);
}
}
public ArrayList<String> draw(ArrayList<Integer> cols){
ArrayList<String> solution=new ArrayList<>();
for(int i=0;i<cols.size();++i){
String str="";
for(int j=0;j<cols.size();++j){
if(j==cols.get(i)){
str=str+"Q";
}
else{
str=str+".";
}
}
solution.add(str);
}
return solution;
}
public boolean isSafe(ArrayList<Integer> cols,int colIndex){
int rowIndex=cols.size();
for(int row=0;row<cols.size();++row){
int column=cols.get(row);
if(column==colIndex){
return false;
}
if(row-column==rowIndex-colIndex){
return false;
}
if(row+column==rowIndex+colIndex){
return false;
}
}
return true;
}
};
二叉樹路徑:
描述:
給定一個二叉樹,找出所有路徑中各節點相加總和等於給定 目標值 的路徑。
一個有效的路徑,指的是從根節點到葉節點的路徑。
樣例:
給定一個二叉樹,和 目標值 = 5:
1
/ \
2 4
/ \
2 3
返回:
[
[1, 2, 2],
[1, 4]
]
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/**
* @param root the root of binary tree
* @param target an integer
* @return all valid paths
*/
public List<List<Integer>> binaryTreePathSum(TreeNode root, int target) {
// Write your code here
List<List<Integer>> res=new ArrayList<>();
List<Integer> path=new ArrayList<>();
if(root==null){
return res;
}
helper(res,path,root,target);
return res;
}
public void helper(List<List<Integer>> res,List<Integer> path,TreeNode root,int target){
Boolean isLeaf=root.left==null&&root.right==null;
if(isLeaf&&target==root.val){
List<Integer> solution=new ArrayList<>(path);
solution.add(root.val);
res.add(solution);
return;
}
path.add(root.val);
if(root.left!=null){
helper(res,path,root.left,target-root.val);
}
if(root.right!=null){
helper(res,path,root.right,target-root.val);
}
path.remove(path.size()-1);
}
}