LeetCode51-N皇后

LeetCode51-N皇后

题目

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。
给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。

每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 ‘Q’ 和 ‘.’ 分别代表了皇后和空位。

输入: 4
输出: [
[".Q…", // 解法 1
“…Q”,
“Q…”,
“…Q.”],
["…Q.", // 解法 2
“Q…”,
“…Q”,
“.Q…”]
]
解释: 4 皇后问题存在两个不同的解法。
提示:

皇后,是国际象棋中的棋子,意味着国王的妻子。皇后只做一件事,那就是“吃子”。当她遇见可以吃的棋子时,就迅速冲上去吃掉棋子。当然,她横、竖、斜都可走一到棋盘边,可进可退。

解法

使用回溯,这个题目可以按行来解:
一开始定一个visited数组,表示是否可以访问,第i行定准之后,将下面的visited数组修改,同一行(第i 行)的和上面(0…i-1行)的数组都不用修改,不要忘记,左斜下也要改。

注意:
(1)每次使用新的temp数组代替visited数组向下递归的时候,要执行深拷贝
(2)每次向cur加入新的String之后,再递归结束后,不要忘记删除它

class Solution {
    private StringBuilder stb = new StringBuilder();
    public List<List<String>> solveNQueens(int n) {
        int[][] visited = new int[n][n];
        List<List<String>> res = new LinkedList<>();
        for(int i = 0 ; i < n ; ++i){
            stb.append('.');
        }
        for(int i = 0 ; i < n ; ++i){
            //执行深拷贝
            int[][] temp = new int[n][n];
            for(int j = 0 ; j < n ; ++j){
                System.arraycopy(visited[j],0,temp[j],0,n);
            }
            change(temp,0,i,n);
            String s = myString(i);
            Deque<String> cur = new LinkedList<>();
            cur.add(s);
            dfs(n,res,temp,0,cur);
        }
        return res;
    }
	//回溯方法
    public void dfs(int n, List<List<String>> res, int[][] visited, int h,Deque<String> cur){
        if(h == n-1){
            res.add(new LinkedList<>(cur));
            return;
        }
        ++h;//下一行
        for(int i = 0 ; i < n ; ++i){
            if(visited[h][i]==0){
                int[][] temp = new int[n][n];
                for(int j = 0 ; j < n ; ++j){
                    System.arraycopy(visited[j],0,temp[j],0,n);
                }
                change(temp,h,i,n);
                String s = myString(i);
                cur.add(s);
                dfs(n,res,temp,h,cur);
                cur.removeLast();
            }
        }
        return;
    } 

    //确定某个位置后,修改visited
    public void change(int[][] visited,int i , int j , int n){
        int index = 0;
        for(int h = i ; h < n ; ++h){
            visited[h][j] = 1;
            if(j+index<n){
                visited[h][j+index] = 1;
                
            }  
            if(j-index>=0){
                visited[h][j-index] = 1;
            }
            ++index;
        }
    }  
	//得到某行的String
    public String myString(int i){
        stb.setCharAt(i,'Q');
        String res = stb.toString();
        stb.setCharAt(i,'.');
        return res;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值