lintcode--33. N皇后问题

描述

n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击。

给定一个整数n,返回所有不同的n皇后问题的解决方案。

每个解决方案包含一个明确的n皇后放置布局,其中“Q”和“.”分别表示一个女王和一个空位置。

样例

对于4皇后问题存在两种解决的方案:

[

    [".Q..", // Solution 1

     "...Q",

     "Q...",

     "..Q."],

    ["..Q.", // Solution 2

     "Q...",

     "...Q",

     ".Q.."]

]

代码

非递归方法的一个重要问题时何时回溯及如何回溯的问题。程序首先对N行中的每一行进行探测,寻找该行中可以放置皇后的位置,具体方法是对该行的每一列进行探测,看是否可以放置皇后,如果可以,则在该列放置一个皇后,然后继续探测下一行的皇后位置。如果已经探测完所有的列都没有找到可以放置皇后的列,此时就应该回溯,把上一行皇后的位置往后移一列,如果上一行皇后移动后也找不到位置,则继续回溯直至某一行找到皇后的位置或回溯到第一行,如果第一行皇后也无法找到可以放置皇后的位置,则说明已经找到所有的解程序终止。如果该行已经是最后一行,则探测完该行后,如果找到放置皇后的位置,则说明找到一个结果,打印出来。但是此时并不能再此处结束程序,因为我们要找的是所有N皇后问题所有的解,此时应该清除该行的皇后,从当前放置皇后列数的下一列继续探测。

public class Solution {
    /*
     * @param n: The number of queens
     * @return: All distinct solutions
     */
    public List<List<String>> solveNQueens(int n) {
        // write your code here
        List<List<String>> result=new LinkedList<>();
        List<String> s=new LinkedList<>();
        if(n<4){
            if(n==1){
                s.add("Q");
                result.add(s);
            }
            return result;
        }
        List<Node> stack=new LinkedList<>();
        int row=0,col=0;
        s=new LinkedList<>();
        while(row<n){
            while(col<n){
                if(check(stack,row,col)==0){
                    stack.add(new Node(row,col)); //找到了改行的皇后的位置
                    col=0;
                    break;
                }
                col++;
            }
            StringBuffer buffer=null;
            if(col==n){ //未找到
                if(stack.size()>0){
                    Node node=stack.remove(stack.size()-1);
                    node.y++;
                    s.remove(s.size()-1);
                    col=node.y;
                }
                if(col==n&&stack.size()>0){
                    Node node=stack.remove(s.size()-1);
                    s.remove(s.size()-1);
                    col=++node.y;
                    row--;
                }
                row--;
                if(row==-1){
                    break;
                }
            }else{   //找到
                buffer=new StringBuffer();
                Node node=stack.get(stack.size()-1);
                for(int i=0;i<n;i++){
                    if(i==node.y){
                        buffer.append("Q");
                    }else{
                        buffer.append(".");
                    }
                }
                s.add(buffer.toString());
                if(s.size()==n){
                    result.add(new LinkedList<>(s));
                }
            }
            if(buffer!=null)
                row++;
            if(row==n){
                row--;
                Node node=stack.remove(s.size()-1);
                s.remove(s.size()-1);
                col=++node.y;
            }
        }
        return result;
    }
    private int check(List<Node> stack,int x,int y){
        for(int i=0;i<stack.size();i++){
            Node node2=stack.get(i);
            if(y==node2.y||x==node2.x){
                return 1;
            }
            if(Math.abs(x-node2.x)==Math.abs(y-node2.y)){
                return 1;
            }
        }
        return 0;
    }
    public class Node{
        public int x,y;
        public Node(int x,int y){
            this.x=x;
            this.y=y;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值