数据结构刷题(二十三):47全排列II、51N皇后、37解数独

news2024/11/25 20:41:13

1.全排列II

题目链接

思路:回溯之排列问题并且有数组排序+标记数组。 回溯三部曲同46. 全排列

过程图:https://programmercarl.com/0047.%E5%85%A8%E6%8E%92%E5%88%97II.html#%E6%80%9D%E8%B7%AF

注意:本题的去重操作主要在树层上。就是说同一树层上存在重复值时,需要进行去重,而且必然在第二层及以下层,同时需要使用标记数组对访问过的结点进行标记。

class Solution {
    List<List<Integer>> res = new ArrayList<>();
        LinkedList<Integer> path = new LinkedList<>();
        public List<List<Integer>> permuteUnique(int[] nums) {
            // 标记数组
            boolean[] used = new boolean[nums.length];
            // 设置默认值为false 并对nums排序
            Arrays.fill(used, false);
            Arrays.sort(nums);
            back(nums,used);
            return res;
        }

        private void back(int[] nums, boolean[] used) {    
            // 终止条件
            if (nums.length == path.size()){
                res.add(new ArrayList<>(path));
                return;
            }
            for (int i = 0; i < nums.length; i++){
                // 当访问的结点已经访问过时直接continue
                if (used[i] == true)
                    continue;
                // 当同一树层上存在重复值 used[i - 1] == false可以确保重复值仅访问一次
                if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false)
                    continue;
                used[i] = true;
                path.add(nums[i]);
                back(nums, used);
                used[i] = false; // 回溯
                path.removeLast();
            }
        }
}

2.N皇后

题目链接

思路:回溯。

注意:1.皇后们的约束条件:不能同行,不能同列,不能同斜线

2.回溯三部曲

  • 递归函数参数:

n是棋盘的大小,然后用row来记录当前遍历到棋盘的第几层,还有棋盘本身chessboard

  • 递归终止条件:

只要搜索到了树的叶子节点,说明就找到了皇后们的合理位置了(边搜索边判断皇后的约束条件,若不符合约束条件,会直接跳出)。

  • 单层搜索的逻辑:

for循环用来横向遍历; 递归用来纵向遍历。具体逻辑见下图。

3.验证棋盘是否合法isValid函数:

isValid(row, i, n, chessboard:row是行, i是列,n是棋盘大小)

4.代码里的函数说明:

函数array2:是为了将每一行的字符数组(如果n=4,则每一行的字符数组就是4个元素)转换为一个字符串,然后将以字符串为单位生成list<String>,添加到res中。(copyValueOf就是接受一个字符数组并返回一个字符串

List<List<String>> res = new ArrayList<>();
    public List<List<String>> solveNQueens(int n) {
        // chessboard 用来记录棋盘元素
        char[][] chessboard = new char[n][n];
        // 默认都是'.'
        for (char[] c : chessboard) {
            Arrays.fill(c, '.');
        }
        // n是棋盘大小 row来记录当前遍历到棋盘的第几层
        back(n, 0, chessboard);
        return res;
    }
    //
    private void back(int n, int row, char[][] chessboard) {
        if (row == n){
            res.add(array2(chessboard));
            return;
        }
        for (int i = 0; i < n; i++){
            if (isValid(row, i, n, chessboard)){
                chessboard[row][i] = 'Q';
                back(n, row + 1, chessboard);
                chessboard[row][i] = '.'; // 回溯
            }
        }

    }
    // 判断是否符合皇后的约束条件  row是行,col是列,n是棋盘大小
    private boolean isValid(int row, int col, int n, char[][] chessboard) {
        // 检查列
        for (int i = 0; i < row; i++) {
            if (chessboard[i][col] == 'Q')
                return false;
        }

        // 检查45度角 (10点半方向)
        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--){
            if (chessboard[i][j] == 'Q')
                return false;
        }
        // 检查135度角 (1点半方向)
        for (int i  = row - 1, j = col + 1; i>= 0 && j <= n - 1; i--, j++){
            if (chessboard[i][j] == 'Q')
                return false;
        }
        return true;
    }
    // 见注意
    public List array2(char[][] chessboard){
        List<String> list = new ArrayList<>();
        for (char[] c : chessboard) {
            list.add(String.copyValueOf(c));
        }
        return list;
    }

3.解数独(难得很,希望面试抽不到)

题目链接

思路:判断棋盘是否合法有如下三个维度:

  • 同行是否重复

  • 同列是否重复

  • 9宫格里是否重复

回溯三部曲:

  • 递归函数以及参数:只要解数独找到一个符合的条件(就在树的叶子节点上)立刻就返回,所以用boolean,

  • 递归终止条件:单层逻辑判断中,针对每一行的判断,返回true和false就是终止条件

  • 单层逻辑:一个for循环遍历棋盘的行,一个for循环遍历棋盘的列,一行一列确定下来之后,递归遍历这个位置放9个数字的可能性!

class Solution {
    public void solveSudoku(char[][] board) {
        solveSudokuHelper(board);
    }

    private boolean solveSudokuHelper(char[][] board){
        //「一个for循环遍历棋盘的行,一个for循环遍历棋盘的列,
        // 一行一列确定下来之后,递归遍历这个位置放9个数字的可能性!」
        for (int i = 0; i < 9; i++){ // 遍历行
            for (int j = 0; j < 9; j++){ // 遍历列
                if (board[i][j] != '.'){ // 跳过原始数字
                    continue;
                }
                for (char k = '1'; k <= '9'; k++){ // (i, j) 这个位置放k是否合适
                    if (isValidSudoku(i, j, k, board)){
                        board[i][j] = k;
                        if (solveSudokuHelper(board)){ // 如果找到合适一组立刻返回
                            return true;
                        }
                        board[i][j] = '.';
                    }
                }
                // 9个数都试完了,都不行,那么就返回false
                return false;
                // 因为如果一行一列确定下来了,这里尝试了9个数都不行,说明这个棋盘找不到解决数独问题的解!
                // 那么会直接返回, 「这也就是为什么没有终止条件也不会永远填不满棋盘而无限递归下去!」
            }
        }
        // 遍历完没有返回false,说明找到了合适棋盘位置了
        return true;
    }

    /**
     * 判断棋盘是否合法有如下三个维度:
     *     同行是否重复
     *     同列是否重复
     *     9宫格里是否重复
     */
    private boolean isValidSudoku(int row, int col, char val, char[][] board){
        // 同行是否重复
        for (int i = 0; i < 9; i++){
            if (board[row][i] == val){
                return false;
            }
        }
        // 同列是否重复
        for (int j = 0; j < 9; j++){
            if (board[j][col] == val){
                return false;
            }
        }
        // 9宫格里是否重复
        int startRow = (row / 3) * 3;
        int startCol = (col / 3) * 3;
        for (int i = startRow; i < startRow + 3; i++){
            for (int j = startCol; j < startCol + 3; j++){
                if (board[i][j] == val){
                    return false;
                }
            }
        }
        return true;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/403298.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2.JVM常识之 运行时数据区

1.JVM核心组成 2.JVM 运行时数据区&#xff08;jdk8&#xff09; 程序计数器&#xff1a;线程私有&#xff0c;当前线程所执行字节码的行号指示器 jvm栈&#xff1a;线程私有&#xff0c;Java 虚拟机栈为 JVM 执行 Java 方法服务 本地方法栈&#xff1a;线程私有&#xff0c;本…

SpringBoot接口 - 如何统一异常处理

SpringBoot接口如何对异常进行统一封装&#xff0c;并统一返回呢&#xff1f;以上文的参数校验为例&#xff0c;如何优雅的将参数校验的错误信息统一处理并封装返回呢&#xff1f;为什么要优雅的处理异常如果我们不统一的处理异常&#xff0c;经常会在controller层有大量的异常…

【Java】初识Java

Java和C语言有许多类似之处&#xff0c;这里就只挑不一样的点来说&#xff0c;所以会比较杂乱哈~ 目录 1.数据类型 2.输入与输出 2.1三种输出 2.2输入 2.3循环输入输出 //猜数字小游戏 //打印乘法口诀表 3.方法 //交换两个数&#xff08;数组的应用&#xff09; //模…

栈的应用-算数

本题要求你为初学数据结构的小伙伴设计一款简单的利用堆栈执行的计算器。如上图所示&#xff0c;计算器由两个堆栈组成&#xff0c;一个堆栈 S1​ 存放数字&#xff0c;另一个堆栈 S2​ 存放运算符。计算器的最下方有一个等号键&#xff0c;每次按下这个键&#xff0c;计算器就…

Form Generator扩展 文本 组件

一、form-generator是什么?✨ ⭐️ 🌟 form-generator的作者是这样介绍的:Element UI表单设计及代码生成器,可将生成的代码直接运行在基于Element的vue项目中;也可导出JSON表单,使用配套的解析器将JSON解析成真实的表单。 但目前它提供的组件并不能满足我们在项目中的…

kubeadm探秘

为什么kubeadm可以用于生产&#xff1f;第一是kubeadm已经被官方收编&#xff0c;可以在官网文档中找到它的身影。另外一个是kubeadm是用golang调用k8s的命令去执行创建k8s集群的。查看一下kubeadm的代码即可知道。本文来源于csdn作者 sunican挨个打开目录查看文件可知&#xf…

Guitar Pro8吉他学习辅助软件

Guitar Pro8最大的特色就是可以直接用鼠标和键盘按标准的六线谱、四线谱进行乐谱输入、查看、打印和试听&#xff0c;可以实时、自动滚屏、多种模式的显示单声部或乐曲总谱&#xff0c;在做弹拨乐器的滑音、倚音、推弦、揉弦、泛音、摇把、闷音、琶音、分解和弦、BASS打弦等方面…

【汽车应用处理器】DRA770PJGACDQ1、TDA4VM88TGBALFR功能应用

DRA770PJGACDQ1 汽车应用处理器旨在满足现代车内数字驾驶舱体验对于处理性能的强烈需求。利用该器件&#xff0c;原始设备制造商(OEM)和原始设计制造商(ODM)得以将创新型连接技术、语音识别和音频流式传输等快速投入实施。Jacinto6 Plus器件通过极其灵活的全集成混合处理器解决…

zigbee学习笔记:IO操作

1、IAR新建工程 &#xff08;1&#xff09;Projetc→Create New Projetc→OK→选择位置&#xff0c;确定 &#xff08;2&#xff09;新建一个c文件&#xff0c;保存在路径中 &#xff08;3&#xff09;点击工程&#xff0c;右键→add→加入c文件 &#xff08;4&#xff09;…

10、go工程化与标准库

目录一、用go mod管理工程二、包引入规则三、init调用链四、可见性五、标准库1 - 时间函数2 - 数学计算3 - I/O操作4 - 编码一、用go mod管理工程 初始化项目&#xff1a;go mod init $module_name&#xff0c;$module_name和目录名可以不一样。上述命令会生成go.mod文件 mod…

除了「加机器」,其实你的微服务还能这样优化

生产实践中&#xff0c;如果遇到业务流量变高导致服务负载升高甚至报警&#xff0c;我们的第一反应往往是「加机器」。 俗话说&#xff0c;能用钱解决的问题都不是问题。 俗话又说&#xff0c;充钱你就能变得更强。 但是&#xff0c;作为一个有理想有抱负的架构师&#xff0c;…

前端——7.图像标签和路径

这篇文章&#xff0c;我们来讲解一下图像标签 目录 1.图像标签 1.1介绍 1.2实际展示 1.3图像标签的属性 1.3.1 alt属性 1.3.2 title属性 1.3.3 width / height 属性 1.3.4 border属性 1.4注意事项 2.文件夹 2.1目录文件夹和根目录 2.2 VSCode打开目录文件夹 3.路…

决策树学习报告

报告 一、基本概念 决策树的定义&#xff1a;首先&#xff0c;决策树是一种有监督的分类算法——即给定X&#xff0c;Y值&#xff0c;构建X&#xff0c;Y的映射关系。不同于线性回归等是多项式&#xff0c;决策树是一种树形的结构&#xff0c;一般由根节点、父节点、子节点、…

MyBatis-Plus的入门学习

MyBatis-Plus入门学习简介特性快速开始MyBatis-Plus的注解详解Tableld主键生成策略1、数据库自动增长 AUTO2、UUID3、Redis生成id4、MP主键自动生成TableNameTableField自动填充测试方法&#xff1a;update乐观锁select查所有根据id查多个id批量查询简单条件查询&#xff08;通…

MySQL性能优化

MySQL性能调优 存储数据类型优化 尽量避免使用 NULL尽量使用可以的最小数据类型。但也要确保没有低估需要存储的范围整型比字符串操作代价更低使用 MySQL 内建的数据类型&#xff08;比如date、time、datetime&#xff09;&#xff0c;比用字符串更快 基本数据类型 数字 整数…

中国巨头在NLP领域的大模型布局

什么是大模型&#xff1f; 大规模模型&#xff08;large-scale model&#xff09;是近年来人工智能领域的一个热点话题&#xff0c;因为它们可以对自然语言处理&#xff08;NLP&#xff09;和其他任务进行更准确和深入的处理。由于大模型需要庞大的计算资源和数据支持&#xf…

论文投稿指南——中文核心期刊推荐(国家财政)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

SpringSecurity第二讲

目录 二、SpringSecurity02 2.1 JWT概述 2.1.1 JWT介绍 2.1.2 跨域认证问题 2.2 JWT的原理 2.3 JWT的数据结构 2.3.1 Header 2.3.2 Payload 2.3.3 Signature 2.4 JWT的使用方式 2.5 JWT的使用 2.5.1 引入JWT依赖 2.5.2 编写JWT工具类 2.6 编写前后端不分离的项目…

【C语言】每日刷题 —— 牛客语法篇(3)

前言 大家好&#xff0c;继续更新专栏c_牛客&#xff0c;不出意外的话每天更新十道题&#xff0c;难度也是从易到难&#xff0c;自己复习的同时也希望能帮助到大家&#xff0c;题目答案会根据我所学到的知识提供最优解。 &#x1f3e1;个人主页&#xff1a;悲伤的猪大肠9的博客…

sd卡格式化后数据恢复怎么操作

有时候我们需要清空SD卡数据文件&#xff0c;有时候则是因为需要修复SD卡所以需要格式化&#xff0c;但是却被提示无法格式化SD卡。这种情况往往是由于平时SD卡使用时的一些不良习惯或是SD卡中病毒&#xff0c;病毒在运行SD卡中的软件所造成的。那么sd卡格式化后数据恢复怎么操…