力扣大厂热门面试算法题 36-38

        36. 有效的数独,37. 解数独,38. 外观数列,每题做详细思路梳理,配套Python&Java双语代码, 2024.03.16 可通过leetcode所有测试用例。

目录

36. 有效的数独

解题思路

完整代码

Java

Python

37. 解数独

解题思路

完整代码

Java

Python

38. 外观数列

解题思路

完整代码

Java

Python


36. 有效的数独

请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

注意:

  • 一个有效的数独(部分已被填充)不一定是可解的。
  • 只需要根据以上规则,验证已经填入的数字是否有效即可。
  • 空白格用 '.' 表示。

示例 1:

输入:board = 
[["5","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:true

示例 2:

输入:board = 
[["8","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。 但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。

提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字(1-9)或者 '.'

解题思路

  • 遍历数独的每一个格子。
  • 对于每个非空格子,检查它所在的行、列以及宫内是否有重复的数字。
  • 为了方便检查,可以使用三个二维数组分别记录每行、每列和每个宫格中数字的出现情况。例如,rows[i][num] 表示数字 num+1 在第 i 行是否已出现,cols[j][num] 表示数字 num+1 在第 j 列是否已出现,boxes[boxIndex][num] 表示数字 num+1 在第 boxIndex 个宫内是否已出现。boxIndex 可以通过 (i / 3) * 3 + j / 3 计算得到,其中 ij 分别是格子的行列索引。

完整代码

Java
public class Solution {
    public boolean isValidSudoku(char[][] board) {
        boolean[][] rows = new boolean[9][9];
        boolean[][] cols = new boolean[9][9];
        boolean[][] boxes = new boolean[9][9];
        
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] != '.') {
                    int num = board[i][j] - '1';  // 将字符转换为数字,并减1以适应数组索引
                    int boxIndex = (i / 3) * 3 + j / 3;
                    
                    if (rows[i][num] || cols[j][num] || boxes[boxIndex][num]) {
                        return false;  // 如果在对应的行、列或宫内发现重复,则返回 false
                    }
                    
                    rows[i][num] = true;
                    cols[j][num] = true;
                    boxes[boxIndex][num] = true;
                }
            }
        }
        
        return true;  // 没有发现重复,返回 true
    }
}
Python
class Solution:
    def isValidSudoku(self, board: List[List[str]]) -> bool:
        rows = [[False] * 9 for _ in range(9)]
        cols = [[False] * 9 for _ in range(9)]
        boxes = [[False] * 9 for _ in range(9)]
        
        for i in range(9):
            for j in range(9):
                if board[i][j] != '.':
                    num = int(board[i][j]) - 1  # 将字符转换为数字,并减1以适应数组索引
                    boxIndex = (i // 3) * 3 + j // 3
                    
                    if rows[i][num] or cols[j][num] or boxes[boxIndex][num]:
                        return False  # 如果在对应的行、列或宫内发现重复,则返回 False
                    
                    rows[i][num] = True
                    cols[j][num] = True
                    boxes[boxIndex][num] = True
        
        return True  # 没有发现重复,返回 True

37. 解数独

编写一个程序,通过填充空格来解决数独问题。

数独的解法需 遵循如下规则

  1. 数字 1-9 在每一行只能出现一次。
  2. 数字 1-9 在每一列只能出现一次。
  3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。(请参考示例图)

数独部分空格内已填入了数字,空白格用 '.' 表示。

示例 1:

输入:board = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]
输出:[["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]
解释:输入的数独如上图所示,唯一有效的解决方案如下所示:


提示:

  • board.length == 9
  • board[i].length == 9
  • board[i][j] 是一位数字或者 '.'
  • 题目数据 保证 输入数独仅有一个解

解题思路

        解决数独问题通常采用回溯法,这是一种深度优先搜索的算法,适用于解决决策问题。基本思路是尝试填充数独中的每个空格,每次填充时遵循数独的规则,如果在某个位置无法填入有效数字,则回溯到上一个空格,尝试另一个数字。重复这一过程,直到数独被成功填充。

算法步骤如下:

  1. 从数独的第一个格子开始,按照某种顺序(通常是从左到右,从上到下)遍历每个格子。
  2. 对于每个空格,尝试填入数字 1 到 9,每尝试一个数字前,检查行、列和所在的 3x3 宫格内是否已经存在该数字。
  3. 如果一个数字能够被安全地填入(即不违反数独规则),则填入并递归地尝试填写下一个空格。
  4. 如果当前空格无论填入何种数字都无法使数独有效,或者所有空格都已成功填写,算法结束。在前一种情况下,需要撤销最后的填写并回溯到上一个空格;在后一种情况下,找到了数独的解。

完整代码

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

    private boolean solve(char[][] board) {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                if (board[i][j] == '.') {
                    for (char c = '1'; c <= '9'; c++) {
                        if (isValid(board, i, j, c)) {
                            board[i][j] = c;
                            if (solve(board)) {
                                return true;
                            } else {
                                board[i][j] = '.'; // 回溯
                            }
                        }
                    }
                    return false; // 无解,回溯
                }
            }
        }
        return true; // 找到解
    }

    private boolean isValid(char[][] board, int row, int col, char c) {
        for (int i = 0; i < 9; i++) {
            if (board[i][col] == c) return false; // 检查列
            if (board[row][i] == c) return false; // 检查行
            if (board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) return false; // 检查 3x3 宫
        }
        return true;
    }
}
Python
class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        def solve():
            for i in range(9):
                for j in range(9):
                    if board[i][j] == '.':
                        for c in '123456789':
                            if isValid(i, j, c):
                                board[i][j] = c
                                if solve():
                                    return True
                                else:
                                    board[i][j] = '.'  # 回溯
                        return False  # 无解,回溯
            return True  # 找到解

        def isValid(i, j, c):
            for k in range(9):
                if board[i][k] == c or board[k][j] == c:
                    return False  # 检查行和列
                if board[3 * (i // 3) + k // 3][3 * (j // 3) + k % 3] == c:
                    return False  # 检查 3x3 宫
            return True
        solve()

38. 外观数列

给定一个正整数 n ,输出外观数列的第 n 项。

「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。

你可以将其视作是由递归公式定义的数字字符串序列:

  • countAndSay(1) = "1"
  • countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。

前五项如下:

1.     1
2.     11
3.     21
4.     1211
5.     111221
第一项是数字 1 
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"

要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。

例如,数字字符串 "3322251" 的描述如下图:

示例 1:

输入:n = 1
输出:"1"
解释:这是一个基本样例。

示例 2:

输入:n = 4
输出:"1211"
解释:
countAndSay(1) = "1"
countAndSay(2) = 读 "1" = 一 个 1 = "11"
countAndSay(3) = 读 "11" = 二 个 1 = "21"
countAndSay(4) = 读 "21" = 一 个 2 + 一 个 1 = "12" + "11" = "1211"

解题思路

        要生成外观数列的第 n 项,我们可以从第 1 项开始,逐步构建直到第 n 项。对于每一项,我们都按照以下步骤来构建:

  1. 查看前一项的数字字符串。
  2. 从左到右扫描字符串,对连续的相同数字进行分组。
  3. 对每个分组,先记录数字的数量(即分组的长度),然后记录数字本身。
  4. 将上述所有分组的描述连在一起,形成新的数字字符串。
  5. 重复上述步骤直到达到第 n 项。

完整代码

Java
public class Solution {
    public String countAndSay(int n) {
        String s = "1";
        for (int i = 1; i < n; i++) {
            StringBuilder sb = new StringBuilder();
            char c = s.charAt(0);
            int count = 1;
            for (int j = 1; j < s.length(); j++) {
                if (s.charAt(j) == c) {
                    count++;  // 相同字符,计数增加
                } else {
                    sb.append(count).append(c);  // 不同字符,记录前一个字符的计数和字符
                    c = s.charAt(j);
                    count = 1;  // 重置计数
                }
            }
            sb.append(count).append(c);  // 记录最后一个字符的计数和字符
            s = sb.toString();
        }
        return s;
    }
}
Python
class Solution:
    def countAndSay(self, n: int) -> str:
        s = "1"
        for _ in range(n - 1):
            i, new_s = 0, ""
            while i < len(s):
                count = 1
                while i + 1 < len(s) and s[i] == s[i + 1]:
                    i += 1
                    count += 1
                new_s += str(count) + s[i]
                i += 1
            s = new_s
        return s

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ElementUI Message 消息提示,多个显示被覆盖的问题

现象截图&#xff1a; 代码&#xff1a;主要是在this.$message 方法外层加上 setTimeout 方法 <script> export default {name: "HelloWorld",props: {msg: String,},methods: {showMessage() {for (let i 0; i < 10; i) {setTimeout(() > {this.$mess…

k8s-高可用etcd集群 26

reset掉k8s2&#xff0c;k8s3&#xff0c;k8s4节点 清理完网络插件后重启 快速创建一个k8s集群 修改初始化文件 添加master节点 备份 查看etcd配置 启动docker 将etcd二进制命令从容器拷贝到本机 备份 查看快照状态 删除集群资源 恢复 停掉所有的核心组件 从快照恢复 重启所有…

如何在CasaOS系统玩客云中安装内网穿透工具实现远程访问内网主机下载资源

文章目录 1. CasaOS系统介绍2. 内网穿透安装3. 创建远程连接公网地址4. 创建固定公网地址远程访问 2月底&#xff0c;玩客云APP正式停止运营&#xff0c;不再提供上传、云添加功能。3月初&#xff0c;有用户进行了测试&#xff0c;局域网内的各种服务还能继续使用&#xff0c;但…

加密算法 —— 有哪些容易入门且实用的算法?

一、背景 对于初学者来说&#xff0c;一些相对容易入门且实用的加密算法如下&#xff1a; 1. Caesar Cipher&#xff08;凯撒密码&#xff09;: - 凯撒密码是最简单的替换式加密算法之一&#xff0c;通过将字母按照固定位数向前或向后偏移来进行加密。尽管在现代安全场景下…

API接口数据集接口pytorch api接口获取数据

API是应用程序的开发接口&#xff0c;在开发程序的时候&#xff0c;我们有些功能可能不需要从到到位去研发&#xff0c;我们可以拿现有的开发出来的功能模块来使用&#xff0c;而这个功能模块&#xff0c;就叫做库(libary)。比如说&#xff1a;要实现数据传输的安全&#xff0c…

外贸干货|小白必须知道的六大开发信模板!

外贸人必看的开发信模板&#xff08;建议收藏学习&#xff09; 一封好的开发信是开发客户环节里至关重要的节点。 大体上需得简洁明了、开门见山、立意明确。内容上要注重客户需求和问题的解决。另外&#xff0c;高质量的开发信一定不是千篇一律的&#xff0c;而是“入乡随俗…

【进阶五】Python实现SDVRP(需求拆分)常见求解算法——遗传算法(GA)

基于python语言&#xff0c;采用经典遗传算法&#xff08;GA&#xff09;对 需求拆分车辆路径规划问题&#xff08;SDVRP&#xff09; 进行求解。 目录 往期优质资源1. 适用场景2. 代码调整3. 求解结果4. 代码片段参考 往期优质资源 经过一年多的创作&#xff0c;目前已经成熟的…

RISC-V 编译环境搭建:riscv-gnu-toolchain 和 riscv-tools

RISC-V 编译环境搭建&#xff1a;riscv-gnu-toolchain 和 riscv-tools 编译环境搭建以及说明 操作系统&#xff1a;什么系统都可以 虚拟机&#xff1a;VMmare Workstation Pro 17.50.x (版本不限) 编译环境&#xff1a;Ubuntu 18.04.5 CPU&#xff1a;i7-8750h(虚拟机分配4核…

[ C++ ] STL---string类的使用指南

目录 前言&#xff1a; string类简介 string类的常用接口 string类对象的构造函数 string类对象的赋值运算符重载 string类对象的容量操作 string类对象的访问与遍历 [ ] 下标遍历 迭代器遍历 普通迭代器iterator ​编辑 const迭代器const_iterator 反向迭代器rever…

远超预期,特效吹爆!《武庚纪》:建议漫改都按这个标准来!

作为《武庚纪》动画党&#xff0c;听闻要改编成真人电视剧时&#xff0c;最害怕的无非五毛钱特效&#xff0c;流水线仙侠&#xff0c;无脑古偶。但在看过《烈焰》&#xff08;原名&#xff1a;武庚纪&#xff09;之后&#xff0c;不得不感叹一句&#xff1a;“倒也不用这么还原…

SQL注入攻击原理与自动化检测技术的深度探究及其实战应用

SQL注入原理 SQL注入攻击的原理是基于攻击者能够控制应用程序与数据库之间的SQL查询。当应用程序将用户输入的数据直接嵌入到SQL查询中&#xff0c;而没有进行适当的验证或转义时&#xff0c;攻击者就可以通过输入精心构造的数据来操纵SQL查询的逻辑。 例如&#xff0c;假设有…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:ColumnSplit)

将子组件纵向布局&#xff0c;并在每个子组件之间插入一根横向的分割线。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 可以包含子组件。 ColumnSplit通过分割线限制子组件的高度。初始…

配置vscode环境极简版(C/C++)(图文)

前言 众所周知&#xff0c;vscode是一个代码编辑器&#xff0c;不能直接编译运行我们敲的代码&#xff0c;必须提前配置好环境&#xff0c;而这也是劝退一众小白的一大重要因素&#xff0c;下面我想以一种提纲挈领的方式带大家走一遍从配置环境到运行实操代码的全过程。 安装…

从 VNCTF2024 的一道题学习QEMU Escape

说在前面 本文的草稿是边打边学边写出来的&#xff0c;文章思路会与一个“刚打完用户态 pwn 题就去打 QEMU Escape ”的人的思路相似&#xff0c;在分析结束以后我又在部分比较模糊的地方加入了一些补充&#xff0c;因此阅读起来可能会相对轻松。&#xff08;当然也不排除这是…

18-结构体(初识)

18-1 概念 我们现在已经知道的数据类型&#xff1a; char short int long float double 但是当我们需要描述一个复杂对象时&#xff0c;这些数据类型单独拿出来不能满足&#xff0c;如&#xff1a; 人&#xff1a;名字年龄性别地址电话 书&#xff1a;书名作者出版社定价书…

DHCP-SNOOPING-嗅探/窥探

DHCP-SNOOPING 私接设备了&#xff0c;非终端收到了报文 所有接口设置为非信任&#xff0c;然后单独配置其中一个接口为信任

Elasticsearch:从 Java High Level Rest Client 切换到新的 Java API Client

作者&#xff1a;David Pilato 我经常在讨论中看到与 Java API 客户端使用相关的问题。 为此&#xff0c;我在 2019 年启动了一个 GitHub 存储库&#xff0c;以提供一些实际有效的代码示例并回答社区提出的问题。 从那时起&#xff0c;高级 Rest 客户端 (High Level Rest Clie…

滑块验证码

1.这里针对滑块验证给了一个封装的组件verifition&#xff0c;使用直接可以调用 2.组件目录 3.每个文件的内容 3.1 Api文件中只有一个index.js文件&#xff0c;用来存放获取滑块和校验滑块结果的api import request from /router/axios//获取验证图片 export function reqGe…

从0开始回顾MySQL---事务四大特性

事务概述 事务是一个最小的工作单元。在数据库当中&#xff0c;事务表示一件完整的事儿。一个业务的完成可能需要多条DML语句共同配合才能完成&#xff0c;例如转账业务&#xff0c;需要执行两条DML语句&#xff0c;先更新张三账户的余额&#xff0c;再更新李四账户的余额&…

一文带你了解神经网络是如何学习预测的

文章目录 1、GPT与神经网络的关系 2、什么是神经网络 3、神经网络是如何计算的 数据是如何输入到神经网络中的 神经网络是如何进行预测的 神经网络是如何进行学习的 4、小结 1、GPT与神经网络的关系 GPT想必大家已经耳熟能详&#xff0c;当我们与它进行对话时&#xff0c;通常…