算法leetcode|37. 解数独(rust重拳出击)

news2024/9/21 4:20:17

文章目录

  • 37. 解数独:
    • 样例 1:
    • 提示:
  • 分析:
  • 题解:
    • rust
    • go
    • c++
    • c
    • python
    • java


37. 解数独:

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

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

数字 1-9 在每一行只能出现一次。
数字 1-9 在每一列只能出现一次。
数字 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] 是一位数字或者 '.'
  • 题目数据 保证 输入数独仅有一个解

分析:

  • 面对这道算法题目,二当家的陷入了沉思。
  • 主要是如何存储行,列,以及3*3宫内出现过的值。
  • 方法很多,集合,整形数组,布尔数组都可以,只有1-9,一共9个数,最优化的空间方式应该是仅仅用一个整形,然后用位运算。

题解:

rust

impl Solution {
    pub fn solve_sudoku(board: &mut Vec<Vec<char>>) {
        let mut line = vec![vec![false; 9]; 9];
        let mut column = vec![vec![false; 9]; 9];
        let mut block = vec![vec![vec![false; 9]; 3]; 3];
        let mut spaces = Vec::new();

        (0..9).for_each(|i| {
            (0..9).for_each(|j| {
                if board[i][j] == '.' {
                    spaces.push((i, j));
                } else {
                    let digit = board[i][j].to_digit(10).unwrap() as usize - 1;
                    line[i][digit] = true;
                    column[j][digit] = true;
                    block[i / 3][j / 3][digit] = true;
                }
            });
        });

        fn dfs(board: &mut Vec<Vec<char>>, spaces: &Vec<(usize, usize)>, line: &mut Vec<Vec<bool>>, column: &mut Vec<Vec<bool>>, block: &mut Vec<Vec<Vec<bool>>>, pos: usize) -> bool {
            if pos == spaces.len() {
                return true;
            }

            let (i, j) = spaces[pos];
            for digit in 0..9 {
                if !line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit] {
                    line[i][digit] = true;
                    column[j][digit] = true;
                    block[i / 3][j / 3][digit] = true;
                    board[i][j] = (digit as u8 + b'1') as char;
                    if dfs(board, spaces, line, column, block, pos + 1) {
                        return true;
                    }
                    line[i][digit] = false;
                    column[j][digit] = false;
                    block[i / 3][j / 3][digit] = false;
                }
            }

            return false;
        }

        dfs(board, &mut spaces, &mut line, &mut column, &mut block, 0);
    }
}

go

func solveSudoku(board [][]byte)  {
    var line, column [9][9]bool
	var block [3][3][9]bool
	var spaces [][2]int

	for i := 0; i < 9; i++ {
		for j := 0; j < 9; j++ {
			b := board[i][j]
			if b == '.' {
				spaces = append(spaces, [2]int{i, j})
			} else {
				digit := b - '1'
				line[i][digit] = true
				column[j][digit] = true
				block[i/3][j/3][digit] = true
			}
		}
	}

	var dfs func(int) bool
	dfs = func(pos int) bool {
		if pos == len(spaces) {
			return true
		}
		i, j := spaces[pos][0], spaces[pos][1]
		for digit := byte(0); digit < 9; digit++ {
			if !line[i][digit] && !column[j][digit] && !block[i/3][j/3][digit] {
				line[i][digit] = true
				column[j][digit] = true
				block[i/3][j/3][digit] = true
				board[i][j] = digit + '1'
				if dfs(pos + 1) {
					return true
				}
				line[i][digit] = false
				column[j][digit] = false
				block[i/3][j/3][digit] = false
			}
		}
		return false
	}

	dfs(0)
}

c++

class Solution {
private:
    bool dfs(vector<vector<char>> &board, vector<pair<int, int>> &spaces, bool line[9][9], bool column[9][9], bool block[3][3][9], int pos) {
        if (pos == spaces.size()) {
            return true;
        }

        auto [i, j] = spaces[pos];
        for (int digit = 0; digit < 9; ++digit) {
            if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) {
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
                board[i][j] = digit + '1';
                if (dfs(board, spaces, line, column, block, pos + 1)) {
                    return true;
                }
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
            }
        }

        return false;
    }
public:
    void solveSudoku(vector<vector<char>>& board) {
        bool line[9][9];
        bool column[9][9];
        bool block[3][3][9];
        vector<pair<int, int>> spaces;

        memset(line, false, sizeof(line));
        memset(column, false, sizeof(column));
        memset(block, false, sizeof(block));

        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (board[i][j] == '.') {
                    spaces.emplace_back(i, j);
                }
                else {
                    int digit = board[i][j] - '1';
                    line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
                }
            }
        }
        
        dfs(board, spaces, line, column, block, 0);
    }
};

c

bool dfs(char **board, int *spaces[81], int spacesSize, bool line[9][9], bool column[9][9], bool block[3][3][9], int pos) {
    if (pos == spacesSize) {
        return true;
    }

    int i = spaces[pos][0], j = spaces[pos][1];
    for (int digit = 0; digit < 9; ++digit) {
        if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) {
            line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
            board[i][j] = digit + '1';
            if (dfs(board, spaces, spacesSize, line, column, block, pos + 1)) {
                return true;
            }
            line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
        }
    }

    return false;
}

void solveSudoku(char **board, int boardSize, int *boardColSize) {
    bool line[9][9];
    bool column[9][9];
    bool block[3][3][9];
    int *spaces[81];
    int spacesSize = 0;
    memset(line, 0, sizeof(line));
    memset(column, 0, sizeof(column));
    memset(block, 0, sizeof(block));

    for (int i = 0; i < 9; ++i) {
        for (int j = 0; j < 9; ++j) {
            if (board[i][j] == '.') {
                spaces[spacesSize] = malloc(sizeof(int) * 2);
                spaces[spacesSize][0] = i;
                spaces[spacesSize++][1] = j;
            } else {
                int digit = board[i][j] - '1';
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
            }
        }
    }

    dfs(board, spaces, spacesSize, line, column, block, 0);
}

python

class Solution:
    def solveSudoku(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """

        def dfs(pos: int) -> bool:
            if pos == len(spaces):
                return True
            i, j = spaces[pos]
            for digit in range(9):
                if line[i][digit] == column[j][digit] == block[i // 3][j // 3][digit] == False:
                    line[i][digit] = column[j][digit] = block[i // 3][j // 3][digit] = True
                    board[i][j] = str(digit + 1)
                    if dfs(pos + 1):
                        return True
                    line[i][digit] = column[j][digit] = block[i // 3][j // 3][digit] = False
            return False

        line = [[False] * 9 for _ in range(9)]
        column = [[False] * 9 for _ in range(9)]
        block = [[[False] * 9 for _a in range(3)] for _b in range(3)]
        spaces = list()

        for i in range(9):
            for j in range(9):
                if board[i][j] == ".":
                    spaces.append((i, j))
                else:
                    digit = int(board[i][j]) - 1
                    line[i][digit] = column[j][digit] = block[i // 3][j // 3][digit] = True

        dfs(0)


java

class Solution {
    public void solveSudoku(char[][] board) {
        boolean[][]   line   = new boolean[9][9];
        boolean[][]   column = new boolean[9][9];
        boolean[][][] block  = new boolean[3][3][9];
        List<int[]>   spaces = new ArrayList<int[]>();

        for (int i = 0; i < 9; ++i) {
            for (int j = 0; j < 9; ++j) {
                if (board[i][j] == '.') {
                    spaces.add(new int[]{i, j});
                } else {
                    int digit = board[i][j] - '1';
                    line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
                }
            }
        }

        dfs(board, spaces, line, column, block, 0);
    }

    private boolean dfs(char[][] board, List<int[]> spaces, boolean[][] line, boolean[][] column, boolean[][][] block, int pos) {
        if (pos == spaces.size()) {
            return true;
        }

        int[] space = spaces.get(pos);
        int   i     = space[0], j = space[1];
        for (int digit = 0; digit < 9; ++digit) {
            if (!line[i][digit] && !column[j][digit] && !block[i / 3][j / 3][digit]) {
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = true;
                board[i][j] = (char) (digit + '1');
                if (dfs(board, spaces, line, column, block, pos + 1)) {
                    return true;
                }
                line[i][digit] = column[j][digit] = block[i / 3][j / 3][digit] = false;
            }
        }

        return false;
    }
}

非常感谢你阅读本文~
欢迎【点赞】【收藏】【评论】~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~


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

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

相关文章

如何配置git,使其支持多用户

如何配置git&#xff0c;使其支持多用户&#xff1f; 在多数时候&#xff0c; 我们使用git进行操作时&#xff0c;只需要在本地配置一个用户的ssh key&#xff0c;就可以完成基本的pull/push操作。如果现在我有两个github的账号&#xff0c;并需要在一台电脑中操作其中的repo&…

项目管理工具dhtmlxGantt甘特图入门教程(十):服务器端数据集成(下)

这篇文章给大家讲解如何利用dhtmlxGantt在服务器端集成数据。 dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表&#xff0c;可满足应用程序的所有需求&#xff0c;是完善的甘特图图表库 DhtmlxGantt正版试用下载&#xff08;qun 764149912&#xff09;http…

LVGL WIN32模拟器环境搭建

LVGL WIN32模拟器环境搭建LVGL简介环境搭建IDE 选择模拟器代码下载PC模拟器搭建其他配置项说明LVGL简介 LVGL是一个跨平台、轻量级、易于移植的图形库。因其支持大量特性和其易于裁剪&#xff0c;配置开关众多&#xff0c;且版本升级较快&#xff0c;不同版本之间存在一定的差…

基于springboot+vue的医院信息管理系统

基于springbootvue的医院信息管理系统 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介…

2、登录界面开发

【任务描述】本任务要求使用线性布局以及TextView、EditText、Button等常见控件完成智慧园区登录界面的开发。1、线性布局&#xff08;LinearLayout&#xff09;1.1、LinearLayout概述线性布局&#xff08;LinearLayout&#xff09;主要以水平或垂直方式来排列界面中的控件。并…

【C++修炼之路】20.手撕红黑树

每一个不曾起舞的日子都是对生命的辜负 红黑树实现:RBTree 前言一.红黑树的概念及性质1.1 红黑树的概念1.2 红黑树的性质二.红黑树的结构2.1 红黑树节点的定义2.2 红黑树类的封装三.红黑树的插入情况1&#xff1a;只变色情况2&#xff1a;变色单旋情况3&#xff1a;双旋插入的代…

Docker入门和安装教程

一、Docker入门简介 Docker 是一个基于GO语言开发的开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的Linux机器上&#xff0c;也可以实现虚拟化。 容器是完全使用沙箱机制&#xff0c;相互之间不会…

关于如何在 Grafana 绘制 Apache Hudi Metrics 仪表盘的教程

文章目录前言下载 Prometheus下载 PushgatewayPrometheus 集成 PushgatewayPushgateway 后台执行Prometheus 后台执行在Prometheus中配置PushgatewayApache Hudi Metrics中开启 Pushgateway 推送Grafana 安装和启动Grafana 新增 Apache Hudi Metrics 仪表盘添加 Prometheus 数据…

批处理删除指定文件或文件夹

声明&#xff1a;1-2节参考了 https://blog.csdn.net/weixin_43960383/article/details/1243673841. DEL1.1 DEL 的命令参数使用 del 命令能指定文件&#xff0c;Del (erase)[Drive:][Path]FileName指删除指定文件。指定要删除的文件或文件集的位置和名称。语法格式如下&#x…

XML学习

文章目录XML什么是XML?XML的作用&#xff1f;XML语法文档声明XML注释元素&#xff08;标签&#xff09;xml属性语法规则5.4、xml解析技术介绍dom4j 解析技术&#xff08;重点&#xff09;dom4j 编程步骤&#xff1a;使用遍历标签 获取所有标签中的内容&#xff08;重点&#x…

第十三届蓝桥杯国赛 C++ C 组 Java A 组 C 组 Python C 组 E 题——斐波那契数组(三语言代码AC)

目录1.斐波那契数组1.题目描述2.输入格式3.输出格式4.样例输入5.样例输出6.数据范围7.原题链接2.解题思路3.Ac_code1.Java2.C3.Python1.斐波那契数组 1.题目描述 如果数组 A(a0,a1,⋯.an−1)A(a_0,a_1,⋯.a_{n-1})A(a0​,a1​,⋯.an−1​)满足以下条件, 就说它是一个斐波那契…

如何在类中定义构造方法?

在一个类中定义的方法如果同时满足以下三个条件&#xff0c;该方法称为构造方法&#xff0c;具体如下&#xff1a;1、方法名与类名相同2、在方法名的前面没有返回值类型的声明3、在方法中不能使用return语句返回一个值接下来通过一个案例来演示如何在类中定义构造方法&#xff…

闪光桐人の实习日记(2023年2月20-27日)

前往闪闪の小窝以获得更好的阅读和评论体验 文章目录2023年2月20日&#xff08;Vue入门&#xff09;概念Vue基础Vue中的MVVMVue的体验Vue的生命周期Vue指令Vue组件VueRouter前后端路由的区别工作原理两种模式比较route跟router的区别路由属性导航守卫Vuex概述5种基本对象基本使…

C语言编程规范 第二部分

2、头文件对于C语言来说&#xff0c;头文件的设计体现了大部分的系统设计。不合理的头文件布局是编译时间过长的根因&#xff0c;不合理的头文件实际上反映了不合理的设计。 1、头文件中适合放置接口的声明&#xff0c;不适合放置实现头文件是模块&#xff08;Module&#xff…

【数据结构】时间复杂度和空间复杂度

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;别人可以拷贝我的模式&#xff0c;但不能拷贝我不断往前的激情 &#x1f6f8;C语言专栏&#xff1a;https://blog.csdn.net/vhhhbb/category_12174730.html 小苏希望大家能从这篇文章中收获到许…

苹果手机怎么设置闹钟铃声?更改为歌曲铃声,亲测有效

很不是有很多小伙伴每天早上都被苹果手机刺耳的“雷达”闹钟铃声给吵醒呢&#xff1f;想要更换一个舒缓的闹钟铃声&#xff0c;却发现自己鼓捣半天却无法更换喜欢的歌曲闹钟铃声。苹果手机怎么设置闹钟铃声&#xff1f;下面小编就来分享如何将苹果手机的闹钟铃声设置成歌曲铃声…

【docker】拉取镜像环境报错解决#ERROR: Get https://registry-1.docker.io/v2/

&#x1f341;博主简介   &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; 文章目录问题报错原因解决方法问题 ERROR…

简单的认识 Vue(vue-cli安装、node安装、开发者工具)

Vue1、Vue 与其他框架的对比及特点1.1 Vue.js 是什么1.2 作者1.3 作用1.4 Vue 与其他框架的对比2、安装 Vue 的方法2.1 CDN 引入2.2 脚手架工具2.3 vue 开发者工具安装3、创建第一个实例4、理解 Vue 的 MVVM 模式5、数据双向绑定5.1 感受响应式实验总结1、Vue 与其他框架的对比…

Flutter WebView 如何与 h5 同步登录状态

大家好&#xff0c;我是 17。 Flutter WebView 一共三篇文章 在 Flutter 中使用 webview_flutter 4.0 | js 交互Flutter WebView 性能优化&#xff0c;让 h5 像原生页面一样优秀Flutter WebView 如何与 h5 同步登录状态 本篇是第 3 篇&#xff0c;讲下 Flutter WebView 与 h…

Python|每日一练|动态规划|图算法|散列表|数组|双指针|单选记录:不同路径|求两个给定正整数的最大公约数和最小公倍数|删除有序数组中的重复项

1、不同路径&#xff08;数学&#xff0c;动态规划&#xff09; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”…