N-Queens II

Follow up for N-Queens problem.

Now, instead outputting board configurations, return the total number of distinct solutions.

这道题目思路已经很清晰了,但是由于一个细节问题,leetcode 老是提示wrong answer,对于n = 2的时候。 可是把代码放入eclipse 里面结果却是正确的。 先把之前出错的代码贴出来。

一种正确解法:
public class Solution {
    int total;
    public int totalNQueens(int n) {
        int[] position = new int[n];
        
        placeQueen(n,0,position);
        return total;
    }
    void placeQueen(int n, int row, int[] position){
        if (row == n) {
            total ++;
            return;
        }
        for (int i = 0; i < n; i++) {
            if (isValid(row, i, position)) {
                position[row] = i;
                placeQueen(n, row + 1, position);
            }
        }
    }
    private boolean isValid(int row, int col, int[] position) {
        int preRow = 0;
        for (; preRow < row; preRow ++) {
            int preCol = position[preRow];
            if (preCol == col) {
                return false;
            } else if ((row - preRow) == Math.abs(preCol - col)) {
                return false;
            }
        }
        return true;
    }
}

wrong answer:
public class Solution {
    int total;
    public int totalNQueens(int n) {
        int[] position = new int[n];
        
        placeQueen(n,0,position);
        return total;
    }
    void placeQueen(int n, int row, int[] position){
        if (row == n) {
            total ++;
            return;
        }
        for (int i = 0; i < n; i++) {
            if (isValid(row, i, position)) {
                position[row] = i;
                placeQueen(n, row + 1, position);
            }
        }
    }
    private boolean isValid(int row, int col, int[] position) {
        int preRow = 0;
        for (; preRow < row; preRow ++) {
            int preCol = position[preRow];
            if (preCol == col) {
                return false;
            } else if ((row - preRow) == Math.abs(preCol - col)) {
                return false;
            }
        }
        return true;
    }
}


以上两个代码差距只是 total 在错误代码里是static 的,而leetcode 有很多测试用例,那么 total 的值则一直进行累加。但是在显示结果时,只提示n 等于2时 错误,本质原因时因为total 其实把之前的测试用例的值加进去了。这也是为什么用eclipse 测试正确的原因。 所以, static 不要乱用!
下面是另外一种处理处理方式,即每次执行时,都对 这个static 的变量进行更新。

public class Solution {
    public static int sum;
    public int totalNQueens(int n) {
        sum = 0;
        int[] usedColumns = new int[n];
        placeQueen(usedColumns, 0);
        return sum;
    }
    public void placeQueen(int[] usedColumns, int row) {
        int n = usedColumns.length;
        
        if (row == n) {
            sum ++;
            return;
        }
        
        for (int i = 0; i < n; i++) {
            if (isValid(usedColumns, row, i)) {
                usedColumns[row] = i;
                placeQueen(usedColumns, row + 1);
            }
        }
    }
    public boolean isValid(int[] usedColumns, int row, int col) {
        for (int i = 0; i < row; i++) {
            if (usedColumns[i] == col) {
                return false;
            }
            if ((row - i) == Math.abs(col-usedColumns[i])) {
                return false;
            }
        }
        return true;
    }
}


N-Queens  问题本身是dfs 问题,可以套用模版解法:

public class Solution {
    private int total = 0;
    public int totalNQueens(int n) {
        if (n <= 0) {
            return 0;
        }
        ArrayList<Integer> temp = new ArrayList<Integer>();
        helper(n, temp);
        return total;
    }
    
    private void helper(int n, ArrayList<Integer> temp) {
        if (temp.size() == n) {
            total += 1;
        }
        for (int i = 0; i < n; i++) {
            if (isValid(temp, i)) {
                temp.add(i);
                helper(n, temp);
                temp.remove(temp.size() - 1);
            }
        }
        
    }
    
    private boolean isValid(ArrayList<Integer> temp, int last) {
        int row = temp.size();
        // check col
        for (int i = 0; i < row; i++) {
            if (temp.get(i) == last) {
                return false;
            }
        }
        // check left top
        for (int i = 0; i < row; i++) {
            if (temp.get(i) + i == last + row) {
                return false;
            }
        }
        // check right top
        for (int i = 0; i < row; i++) {
            if (temp.get(i) - i == last - row) {
                return false;
            }
        }
        return true;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值