【Leetcode】51. N-Queens

题目地址:

https://leetcode.com/problems/n-queens/

经典的N皇后问题。DFS回溯+剪枝。代码如下:

import java.util.ArrayList;
import java.util.List;

public class Solution {   
    public List<List<String>> solveNQueens(int n) {
        List<List<String>> res = new ArrayList<>();
        if (n == 0) {
            return res;
        }
        
        int[] pos = new int[n];
        dfs(pos, 0, res);
        
        return res;
    }
    
    // 表示当前正在摆放第k行
    private void dfs(int[] pos, int k, List<List<String>> res) {
        // 如果k == pos.length,说明前k行已经顺利摆放好,且无矛盾,这时可以加进最后的结果中了
        if (k == pos.length) {
            res.add(buildBoard(pos));
            return;
        }
    
        for (int i = 0; i < pos.length; i++) {
        	// 尝试摆放第k行的第i个位置。如果能摆放,就摆下一行
            if (check(pos, k, i)) {
                pos[k] = i;
                helper(pos, k + 1, res);
            }
        }
    }
    
    // 正在摆第k行的第i个位置,check一下这个位置是否能摆
    private boolean check(int[] pos, int k, int i) {
        for (int dif = 1; dif <= k; dif++) {
        	// check左斜上方
            if (i - dif >= 0 && pos[k - dif] == i - dif) {
                return false;
            }
            // check右斜上方
            if (i + dif <= pos.length && pos[k - dif] == i + dif) {
                return false;
            }
            // check正上方
            if (pos[k - dif] == i) {
                return false;
            }
        }
        return true;
    }
    
    // 根据每行的皇后位置来build出棋盘
    private List<String> buildBoard(int[] pos) {
        List<String> list = new ArrayList<>();
        StringBuilder sb = new StringBuilder(pos.length);
        for (int i = 0; i < pos.length; i++) {
            for (int j = 0; j < pos.length; j++) {
                if (j != pos[i]) {
                    sb.append('.');
                } else {
                    sb.append('Q');
                }
            }
            list.add(sb.toString());
            sb.setLength(0);
        }
        return list;
    }
}

时间复杂度 O ( n 2 n ! ) O(n^2n!) ,类似于先生成全排列,再把答案加到res里去(需要 O ( n 2 ) O(n^2) ,因为棋盘有两维)。空间复杂度 O ( n ) O(n)

因为有剪枝,所以时间复杂度不太容易估计出来。这里取的是上界,实际要比它小一些。

发布了101 篇原创文章 · 获赞 0 · 访问量 2573

猜你喜欢

转载自blog.csdn.net/qq_46105170/article/details/104086797