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

news2024/11/19 22:53:45

        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

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

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

相关文章

MySql入门教程--MySQL数据库基础操作

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

【C++从练气到飞升】03---构造函数和析构函数

&#x1f388;个人主页&#xff1a;库库的里昂 ✨收录专栏&#xff1a;C从练气到飞升 &#x1f389;鸟欲高飞先振翅&#xff0c;人求上进先读书。 目录 ⛳️推荐 一、类的6个默认成员函数 二、构造函数 1. 构造函数的概念 2. 构造函数的定义 3. 构造函数的特性 三、析构函…

leetcode 2312. 卖木头块【划分型dp+棋盘切割类型dp】

原题链接&#xff1a;2312. 卖木头块 题目描述&#xff1a; 给你两个整数 m 和 n &#xff0c;分别表示一块矩形木块的高和宽。同时给你一个二维整数数组 prices &#xff0c;其中 prices[i] [hi, wi, pricei] 表示你可以以 pricei 元的价格卖一块高为 hi 宽为 wi 的矩形木块…

【数据结构练习题】栈——1.括号匹配 2.逆波兰表达式求值 3.出栈入栈次序匹配 4.最小栈

♥♥♥♥♥个人主页♥♥♥♥♥ ♥♥♥♥♥数据结构练习题总结专栏♥♥♥♥♥ 文件目录 前言1.括号匹配1.1问题描述1.2解题思路1.3画图解释1.4代码实现2.逆波兰表达式求值 2.1问题描述2.2解题思路2.3画图解释2.4代码解释3.出栈入栈次序匹配 3.1问题描述3.2思路分析3.3画图解释3.…

Spring Chache入门详解、配套小案例

简介&#xff1a;Spring Cache是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;只需要添加一个注解就能实现缓存功能。 Spring Cache提供了一层抽象&#xff0c;底层可以切换不同的缓存实现&#xff0c;如下&#xff1a; EHCacheCaffeineRedis (这篇帖子&#xff…

Xcode调试Qt 源码

在Mac下使用Xcode 开发Qt程序&#xff0c;由于程序断点或者崩溃后&#xff0c;Qt库的堆栈并不能够正确定位到源码的cpp文件&#xff0c;而是显示的是汇编代码&#xff0c;导致不直观的显示。 加载的其他三方库都是同理。 所以找了攻略和研究后&#xff0c;写的这篇文章。 一&a…

网络原理(1)——UDP协议

目录 一、应用层 举个例子&#xff1a;点外卖 约定数据格式简单粗暴的例子 客户端和服务器的交互&#xff1a; 序列化和返序列化 xml、json、protobuffer 1、xml 2、json 3、protobuffer 二、传输层 端口 端口号范围划分 认识知名的端口号 三、UDP协议 端口 U…

NCP1380BDR2G芯片中文资料规格书PDF数据手册引脚图图片参数功能价格

产品描述&#xff1a; NCP1380 是一款高性能器件&#xff0c;旨在为准谐振转换器供电。该控制器基于专属的谷锁闭系统&#xff0c;可以在功率负载变轻时进行切换并降低开关频率。这样将产生稳定的运行&#xff0c;即使在漏极-源极谷中总是触发的开关事件下也是如此。此系统可在…

蓝膜胶带(蓝膜)为动力电池电气绝缘主流应用方案之一 市场需求空间较广阔

蓝膜胶带&#xff08;蓝膜&#xff09;为动力电池电气绝缘主流应用方案之一 市场需求空间较广阔 动力电池蓝膜胶带是一种PET基材背上PSA压敏胶制成的单面胶带&#xff0c;因其以深蓝色居多&#xff0c;又被称为蓝膜。蓝膜为绝缘材料&#xff0c;可将电芯与电芯之间分隔开来&…

环保水离子水壁炉,现代时尚

环保水离子壁炉&#xff0c;现代而时尚&#xff0c;靠水运行&#xff0c;用电量很少。这绝对是最生态的壁炉。完全安全&#xff08;带冷火焰&#xff09;&#xff0c;其现代设计完美适应各种环境。凭借最低的碳足迹&#xff0c;它无疑是未来的混合壁炉。 什么是环保壁炉&#x…

JUC之CAS比较并交换

CAS 原子类引入 加入原子整型类的操作后&#xff0c;无锁化的操作 CAS 比较并交换 硬件级别的保证 源码分析 引出UnSafe类 UnSafe源码分析 unsafe中的do-while保证自旋 public final int getAndAddInt(Object var1, long var2, int var4) {int var5;do {var5 this…

Linux:kubernetes(k8s)有状态的服务部署(14)

之前我都是对无状态进行的一个操作&#xff0c;我们想扩容就扩容&#xff0c;想缩容就缩容&#xff0c;根本不用去考虑他的一个网络环境&#xff0c;本地储存环境啥的一个状态 当我们做有状态的服务的操作&#xff0c;肯定要申请一个持久化的一个空间&#xff0c;以及网络&…

Linux环境(Ubuntu)上的防火墙工具使用方法

目录 概述 1 防火墙工具&#xff08;ufw&#xff09; 1.1 安装防火墙工具&#xff1a; 1.2 操作防火墙相关命令 2 ufw操作命令的范例 2.1 打开/关闭防火墙 2.1.1 打开防火墙 2.1.2 关闭防火墙 2.1.3 查询当前防火墙状态 2.1.4 允许选择的端口访问 2.1.5 允许选择固定…

自动写作软件哪个好?分享7款独家推荐

随着人工智能技术的不断发展&#xff0c;自动写作软件正逐渐成为现代写作的利器。这些AI写作工具能够帮助用户高效地生成文章、报告、新闻稿等内容&#xff0c;为写作工作带来了极大的便利。然而&#xff0c;市面上的自动写作软件琳琅满目&#xff0c;让人眼花缭乱。为了帮助读…

SpringCloud返回的是xml格式而非JSON数据

一、问题描述&#xff1a; 最近接触eureka&#xff0c;写了一个接口&#xff0c;使用RestController注解修饰了类&#xff0c;预期是返回json格式的数据&#xff0c;但是结果返回的是xml格式的数据。 二、问题分析&#xff1a; 原因是因为直接或间接引入了jackson-dataformat…

相机拍照与摄影学基础

1.相机拍照 相机可能形状和大小不同&#xff0c;但基本功能相同&#xff0c;包括快门速度、光圈和景深&#xff0c;这些是摄影的通用概念。即使是一次性相机也是基于这三个理念工作的。不同类型相机在这三个概念上的唯一区别是你可以控制这些功能的程度。这三个参数被称为相机…

mybatis+thymeleaf登录

目录 一.将页面显示在浏览器中 1.新建项目并导入页面 2.使用th标签 3.新建控制层 4.显示结果 二.将两个页面进行关联 1.提交表单 2.跳转页面 3.结果 三.登录账号名动态改变 1.获取登录表单数据 2.给页面传值 3.页面显示 4.结果 四.连接数据库 1.新建数据库 2.…

tcp/ip协议2实现的插图,数据结构8 (30 - 32章)

(201) 201 三十0 中断优先级补充 (202) 202 三十1 TCP的用户需求 函tcp_usrreq一 (203) 203 三十2 TCP的用户需求 函tcp_usrreq二 (204) 204 三十3 TCP的用户需求 函tcp_usrreq三 (205) 205 三十4 TCP的用户需求 函tcp_usrreq四 (206) 206 三十5 TCP的用户需求 函tcp_usrreq五 …

C语言 内存函数

目录 前言 一、memcpy()函数 二、memmove()函数 三、memset函数 四、memcmp()函数 总结 前言 在C语言中内存是我们用来存储数据的地址&#xff0c;今天我们来讲一下C语言中常用的内存函数。 一、memcpy()函数 memcpy()函数与我们之前讲的strcpy()函数类似&#xff0c;只…

[SAP ABAP] 创建事务码T-CODE

如何让用户通过输入事务码T-CODE跳转到Z437_TEST_2024程序输出界面&#xff1f; 1.输入事务码SE39&#xff0c;进入到维护事务的界面 2.输入需要创建的事务码名称(一般情况下用Y或者Z开头)&#xff0c;点击【创建】 这里我们创建一个名为ZTEST437的事务代码 3.在创建事务的窗口…