【算法】52. N皇后 II(多语言实现)

791 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情


52. N皇后 II:

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

样例 1:

在这里插入图片描述

输入:
	n = 4
	
输出:
	2
	
解释:
	如上图所示,4 皇后问题存在两个不同的解法。

样例 2:

输入:
	n = 1
	
输出:
	1

提示:

  • 1 <= n <= 9

分析

  • 面对这道算法题目,二当家的陷入了沉思。
  • n的取值范围为1到9,可以用一个整形变量利用位运算标记是否被放置。
  • n皇后的特点,每行,每列最终都会放置一个,所以我们可以一行一行的尝试(或者一列一列的尝试),每行最多尝试n次。

题解

java

class Solution {
    public int totalNQueens(int n) {
        return dfs(n, 0, 0, 0, 0);
    }

    /**
     *
     * @param n
     * @param row 正在尝试放置的行
     * @param columns 列标记
     * @param diagonals1 左斜线标记
     * @param diagonals2 右斜线标记
     * @return
     */
    private int dfs(int n, int row, int columns, int diagonals1, int diagonals2) {
        if (row == n) {
            // 全部成功放置,表示一次成功方案
            return 1;
        } else {
            // 成功方案数
            int count = 0;
            // 还可以放置的位置
            int availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2));
            // 还有可以放置的位置
            while (availablePositions != 0) {
                // 可以放置的位置
                final int position = availablePositions & (-availablePositions);
                // 标记当前位置不可以放置
                availablePositions &= availablePositions - 1;
                // 递归套娃尝试下一行
                count += dfs(n, row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1);
            }
            return count;
        }
    }
}

c

int dfs(int n, int row, int columns, int diagonals1, int diagonals2) {
    if (row == n) {
        // 全部成功放置,表示一次成功方案
        return 1;
    } else {
        // 成功方案数
        int count = 0;
        // 还可以放置的位置
        int availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2));
        // 还有可以放置的位置
        while (availablePositions != 0) {
            // 可以放置的位置
            int position = availablePositions & (-availablePositions);
            // 标记当前位置不可以放置
            availablePositions &= availablePositions - 1;
            // 递归套娃
            count += dfs(n, row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1);
        }
        return count;
    }
}

int totalNQueens(int n){
    return dfs(n, 0, 0, 0, 0);
}

c++

class Solution {
private:
    /**
     *
     * @param n
     * @param row 正在尝试放置的行
     * @param columns 列标记
     * @param diagonals1 左斜线标记
     * @param diagonals2 右斜线标记
     * @return
     */
    int dfs(int n, int row, int columns, int diagonals1, int diagonals2) {
        if (row == n) {
            // 全部成功放置,表示一次成功方案
            return 1;
        } else {
            // 成功方案数
            int count = 0;
            // 还可以放置的位置
            int availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2));
            // 还有可以放置的位置
            while (availablePositions != 0) {
                // 可以放置的位置
                int position = availablePositions & (-availablePositions);
                // 标记当前位置不可以放置
                availablePositions &= availablePositions - 1;
                // 递归套娃
                count += dfs(n, row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1);
            }
            return count;
        }
    }
public:
    int totalNQueens(int n) {
        return dfs(n, 0, 0, 0, 0);
    }
};

python

class Solution:
    def totalNQueens(self, n: int) -> int:
        def dfs(row: int, columns: int, diagonals1: int, diagonals2: int) -> int:
            if row == n:
                # 全部成功放置,表示一次成功方案
                return 1
            else:
                # 成功方案数
                count = 0
                # 还可以放置的位置
                availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2))
                # 还有可以放置的位置
                while availablePositions != 0:
                    # 可以放置的位置
                    position = availablePositions & (-availablePositions)
                    # 标记当前位置不可以放置
                    availablePositions &= availablePositions - 1
                    # 递归套娃
                    count += dfs(row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1)
                return count

        return dfs(0, 0, 0, 0)
        

go

func totalNQueens(n int) int {
    var dfs func(row, columns, diagonals1, diagonals2 int) int
    dfs = func(row, columns, diagonals1, diagonals2 int) int {
        if row == n {
            // 全部成功放置,表示一次成功方案
            return 1
        } else {
            // 成功方案数
            count := 0
            // 还可以放置的位置
            availablePositions := (1<<n - 1) &^ (columns | diagonals1 | diagonals2)
            // 还有可以放置的位置
            for availablePositions > 0 {
                // 可以放置的位置
                position := availablePositions & -availablePositions
                // 标记当前位置不可以放置
                availablePositions &^= position
                // 递归套娃
                count += dfs(row+1, columns|position, (diagonals1|position)<<1, (diagonals2|position)>>1)
            }
            return count
        }
    }

    return dfs(0, 0, 0, 0)
}

rust

impl Solution {
    pub fn total_n_queens(n: i32) -> i32 {
        fn dfs(n: i32, row: i32, columns: i32, diagonals1: i32, diagonals2: i32) -> i32 {
            if n == row {
                // 全部成功放置,表示一次成功方案
                1
            } else {
                // 成功方案数
                let mut count = 0;
                // 还可以放置的位置
                let mut availablePositions = ((1 << n) - 1) & (!(columns | diagonals1 | diagonals2));
                // 还有可以放置的位置
                while availablePositions != 0 {
                    // 可以放置的位置
                    let position = availablePositions & (-availablePositions);
                    // 标记当前位置不可以放置
                    availablePositions &= availablePositions - 1;
                    // 递归套娃
                    count += dfs(n, row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1)
                }

                count
            }
        }

        dfs(n, 0, 0, 0, 0)
    }
}

typescript

function totalNQueens(n: number): number {
    const dfs = (row: number, columns: number, diagonals1: number, diagonals2: number) => {
        if (row === n) {
            // 全部成功放置,表示一次成功方案
            return 1;
        } else {
            // 成功方案数
            let count = 0;
            // 还可以放置的位置
            let availablePositions = ((1 << n) - 1) & (~(columns | diagonals1 | diagonals2));
            // 还有可以放置的位置
            while (availablePositions != 0) {
                // 可以放置的位置
                const position = availablePositions & (-availablePositions);
                // 标记当前位置不可以放置
                availablePositions &= availablePositions - 1;
                // 递归套娃
                count += dfs(row + 1, columns | position, (diagonals1 | position) << 1, (diagonals2 | position) >> 1);
            }
            return count;
        }
    }
    
    return dfs(0,0,0,0);
};

原题传送门:https://leetcode-cn.com/problems/n-queens-ii/


非常感谢你阅读本文~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://juejin.cn/user/2771185768884824/posts 博客原创~