暴力递归转动态规划(十七)

本篇是暴力递归转动态规划章节的最后一题。

著名的N皇后问题,只能用暴力递归来解决,没有动态规划的优化方案。

题目

N皇后问题是指在 N * N的棋盘上要摆N个皇后,

要求任何两个皇后不同行、不同列, 也不在同一条斜线上。

给定一个整数n,返回n皇后的摆法有多少种。n=1,返回1。

n=2或3,2皇后和3皇后问题无论怎么摆都不行,返回0。n=8,返回92。

暴力递归

首先确定base case:一共有N个皇后,所以是从0 ~ N -1的位置,如果下标index从0 走到了 N,则说明所有皇后放置的位置不冲突,此时有1种有效方法,return 1。

因为要求不能同行,所以我们在递归过程中,规定好每行只能放置一个皇后,并且用一个int[] record来记录每个皇后放置的位置。

因为是N * N,所以index每次 +1就代表当前所在行数 + 1,那么当前行的皇后应该摆在哪一列呢?

需要从0开始遍历所有列,看和之前 0 ~ index - 1位置摆放的皇后是否有列冲突或者在同一条斜线上。

所以record[index] = x ,代表着 index 行的皇后摆放在了 x 列上。

所以record只用一维数组来表示即可,因为 index 就是代表行数。

代码

其中k循环要遍历之前所有行,看之前所有摆放的皇后有没有列冲突和斜线冲突。如果其中一行不满足,就return false。不能只单单看一行。因为之前摆放所有行的所有皇后都已经满足了条件。

java 复制代码
public static int NQueens(int N) {
        if (N < 1) {
            return -1;
        }
        //从0位置开始,一共N个皇后,record用来 0 ~ index - 1位置皇后摆放的位置
        return process(0, N, new int[N]);
    }
	//index:当前来到index行,一共0 ~ N -1行
	//N : N个皇后 N * N的矩阵
	//record[]:用来记录 0 ~ index - 1所有皇后摆放的位置。 record[x] = y 代表着x行的皇后摆放在了y列
    public static int process(int index, int N, int[] record) {
    	//如果index走到了最后,代表之前摆放的所有皇后不冲突,1种有效方法 return 1。
        if (index == N) {
            return 1;
        } else {
            int res = 0;
            //当前来到了index行, 摆放在哪一列呢? j列
            for (int j = 0; j < N; j++) {
            	//用record index 和 j列去校验,看是否有列冲突、斜线冲突。
                if (isValid(record, index, j)) {
                    //如果和之前行放置的皇后没冲突,则当前位置 index行 j列放置一个皇后
                    record[index] = j;
                    //继续向下去遍历,看下一行
                    res = process(index + 1, N, record);
                }
            }
            return res;
        }
    }

    public static boolean isValid(int[] record, int index, int j) {
    	//当前是来到了index行,所有只看index行之前即可。
    	//如果k循环都走完,则return true,代表可以放在当前j列。
        for (int k = 0; k < index; k++) {
        	// j == record[k] : 看当前j列和之前的record[k]行
        	// Math.abs(record[k] - j) == Math.abs(index - k) : 固定求是否在同一条斜线的公式。(包含左右斜线)
            if (j == record[k] || Math.abs(record[k] - j) == Math.abs(index - k)){
                return false;
            }
        }
        return true;
    }
相关推荐
桂月二二25 分钟前
Java与容器化:如何使用Docker和Kubernetes优化Java应用的部署
java·docker·kubernetes
liuxin3344556629 分钟前
学籍管理系统:实现教育管理现代化
java·开发语言·前端·数据库·安全
小马爱打代码1 小时前
设计模式详解(建造者模式)
java·设计模式·建造者模式
小王爱吃月亮糖1 小时前
C++的23种设计模式
开发语言·c++·qt·算法·设计模式·ecmascript
栗子~~1 小时前
idea 8年使用整理
java·ide·intellij-idea
2301_801483692 小时前
Maven核心概念
java·maven
Q_19284999062 小时前
基于Spring Boot的电影售票系统
java·spring boot·后端
我要学编程(ಥ_ಥ)3 小时前
初始JavaEE篇 —— 网络原理---传输层协议:深入理解UDP/TCP
java·网络·tcp/ip·udp·java-ee
就爱学编程3 小时前
重生之我在异世界学编程之C语言:数据在内存中的存储篇(下)
java·服务器·c语言
IT猿手3 小时前
最新高性能多目标优化算法:多目标麋鹿优化算法(MOEHO)求解LRMOP1-LRMOP6及工程应用---盘式制动器设计,提供完整MATLAB代码
开发语言·算法·matlab·智能优化算法·多目标算法