递归回溯问题的四道经典题:N皇后,组合,全排列,二叉树路径和

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lsf921016/article/details/69666768

组合和排列问题的实质是对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);

    }
}

猜你喜欢

转载自blog.csdn.net/lsf921016/article/details/69666768