DFS的题 就这样用套路做着做着就会了!(例N皇后问题)

最近刷些算法题!LeetCodeN皇后问题! 会了 ,一切排列组合 能用DFS的豆乳切菜!

前言:因为 我也是新手,所以很多参数我都变成了全局成员变量! 这样看上去代码会简介一点,好理解,防止我自己晕了

51. N皇后

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击
具体看:https://leetcode-cn.com/problems/n-queens/

package DFS;

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

/**
 * https://leetcode-cn.com/problems/n-queens/
 *
 * @author Qitong!!
 * @Date 2020/6/28
 */
public class _51_N皇后 {

    //数组索引是行号,数组元素是列号
    private int[] columns;
    //保存 合法皇后的一行情况!!
    private char[] colP;
    private List<List<String>> list;
    private List<String> res;

    public List<List<String>> solveNQueens(int n) {
        list = new ArrayList<>();
        if (n < 1) return list;

        res = new ArrayList<>();
        columns = new int[n];
        colP = new char[n];

        dfs(0);
        return list;
    }

    //dfs模板!
    private void dfs(int row) {
        //判断达到 最后一行!及合法情况 处理逻辑!!
        if (row == columns.length) {
            show();
            list.add(new ArrayList<>(res));
            //要把之前的清除,否则会出现 后面的在前面的 基础上添加
            res.clear();
            return;
        }
        //枚举每种结果可能
        for (int column = 0; column < columns.length; column++) {
            //判断是否合法!
            if (!isValid(row, column)) continue;
            columns[row] = column;
            dfs(row + 1);
        }
    }

    //处理逻辑! 判断哪个位置是否可以放皇后! 剪枝操作!
    private boolean isValid(int row, int column) {
        for (int i = 0; i < row; i++) {
            //第column 列已经有皇后了
            if (columns[i] == column) {
                return false;
            }
            //第 i 行的皇后row行 column列 处在同一直线上
            if (row - i == Math.abs(column - columns[i])) {
                return false;
            }
        }
        return true;
    }

    //打印逻辑!
    private void show() {
        for (int row = 0; row < columns.length; row++) {
            for (int col = 0; col < columns.length; col++) {
                if (columns[row] == col) {
                    colP[col] = 'Q';
                } else {
                    colP[col] = '.';
                }
            }
            //每一行 为一个字符串 添加
            res.add(String.valueOf(colP));
        }
    }
}

52. N皇后 II

n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 这次是输入有多少种摆法!! 返回值为int

具体看看:

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

package DFS;

/**
 * https://leetcode-cn.com/problems/n-queens-ii/
 *
 * @author Qitong!!
 * @Date 2020/6/28
 */
public class _52_N皇后II {

    //数组索引是行号,数组元素是列号
    private int[] columns;
    //一共多少种方法!
    private int ways;

    public int totalNQueens(int n) {
        if (n < 1) return 0;
        columns = new int[n];
        
        dfs(0);
        return ways;
    }

    private void dfs(int row) {
        //到最后一行,即合法可以摆放皇后
        if (row == columns.length) {
            ways++;
            return;
        }

        for (int column = 0; column < columns.length; column++) {
            //判断是否合法!
            if (!isValid(row, column)) continue;
            columns[row] = column;
            dfs(row + 1);
        }
    }

    private boolean isValid(int row, int column) {
        for (int i = 0; i < row; i++) {
            //第column 列已经有皇后了
            if (columns[i] == column) {
                return false;
            }
            //第 i 行的皇后row行 column列 处在同一直线上
            if (row - i == Math.abs(column - columns[i])) {
                return false;
            }
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值