N 皇后 II [Pre-hash数组预处理 | 短hash数组二进制状态压缩 + 递归回溯模拟 + 矩阵左右斜线处理方式]

前言

数据结构 与 经典思想的组合是算法常考的方式之一。还有另一种类型,脑筋急转弯型,需要我们去发现问题内涵与规律。
N皇后 II 包含了算法常考的两种方式,元素丰富。有常见的hash数组赋能;二进制对hash数组状态压缩;递归回溯模拟;矩阵左右斜线处理方式(算是嵌套了脑筋急转弯元素在里面)。

一、N皇后 II

二、hash数组赋能 + 递归回溯模拟

1、hash+DFS

//N 皇后 II
public class TotalNQueens {
    /*
    Pre-hash数组 + 模拟即可。
     */
    public int totalNQueens(int n) {
        /*int[] col = new int[n];
        int[] left = new int[2 * n - 1];
        int[] right = new int[2 * n - 1];*/

        return dfs(new int[n], new int[2 * n - 1], new int[2 * n - 1], n, 0);
    }

    private int dfs(int[] col, int[] left, int[] right, int n, int level) {
        if (n == level) return 1;

        int rs = 0;
        for (int i = 0; i < n; i++) {
            if (col[i] == 0 && right[i - level + n - 1] == 0 && left[level + i] == 0) {
                col[i] = right[i - level + n - 1] = left[level + i] = 1;

                rs += dfs(col, left, right, n, level + 1);

                col[i] = right[i - level + n - 1] = left[level + i] = 0;
            }
        }
        return rs;
    }

}

2、二进制状态压缩

//短hash数组(0-15)常见的状态压缩优化方式。
//用16位二进制表示,一个数代表整个hash数组。
class TotalNQueens2 {
    /*
    二进制对短hash数组压缩 + 模拟即可。
     */
    public int totalNQueens(int n) {

        return dfs(0, 0, 0, n, 0);
    }

    private int dfs(int col, int left, int right, int n, int level) {
        if (n == level) return 1;

        int rs = 0;
        for (int i = 0; i < n; i++) {
            if ((col & 1 << i) == 0 && (right & 1 << i - level + n - 1) == 0 && (left & 1 << level + i) == 0) {
                col |= 1 << i;
                right |= 1 << i - level + n - 1;
                left |= 1 << level + i;

                rs += dfs(col, left, right, n, level + 1);

                col -= 1 << i;
                right -= 1 << i - level + n - 1;
                left -= 1 << level + i;
            }
        }
        return rs;
    }

}

总结

1)常见hash数组赋能操作。
2)常见短hash数组二进制状态压缩。
3)常见递归回溯模拟。

参考文献

[1] LeetCode N 皇后 II

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值