leetcode 37. 解數獨 思考分析

目錄

    • 題目
    • 核心思路的不斷細化
      • 1、核心框架
      • 2、考慮到每個位置的工作
      • 3、考慮到到達最后一列、該位置的數已經預置的情況
      • 4、判斷是否符合規則的函數
      • 5、確定遞歸終止條件+確定函數返回值
    • AC代碼

題目

編寫一個程序,通過填充空格來解決數獨問題。
一個數獨的解法需遵循如下規則:

1、數字 1-9 在每一行只能出現一次。
2、數字 1-9 在每一列只能出現一次。
3、數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。

空白格用 ‘.’ 表示。

一個數獨。
答案被標成紅色。
提示:

給定的數獨序列只包含數字 1-9 和字符 ‘.’ 。
你可以假設給定的數獨只有唯一解。
給定數獨永遠是 9x9 形式的。

核心思路的不斷細化

算法的核心思路就是對每一個空著的格子窮舉 1 到 9,如果遇到不合法的數字(在同一行或同一列或同一個 3×3 的區域中存在相同的數字)則跳過,如果找到一個合法的數字,則繼續窮舉下一個空格子。
寫出核心框架:

1、核心框架

void solveSudoku(vector<vector<char>>& board) {backtrack(board, 0, 0);
}void backtrack(vector<vector<char>>& board, int hang, int lie) {// 就是對棋盤的每個位置進行窮舉for (int i = hang; i < 9; i++) {for (int j = lie; j < 9; j++) {// 做選擇backtrack(board, i, j);// 撤銷選擇}}
}

2、考慮到每個位置的工作

對于每個位置有1~9的選擇,這樣就變成了3重嵌套循環。

void backtrack(vector<vector<char>>& board, int hang, int lie) {// 就是對每個位置進行窮舉for (int i = hang; i < 9; i++) {for (int j = lie; j < 9; j++) {for (char ch = '1'; ch <= '9'; ch++) {// 做選擇board[i][j] = ch;// 繼續窮舉下一列,backtrack(board, i, j + 1);// 撤銷選擇board[i][j] = '.';}}}
}

3、考慮到到達最后一列、該位置的數已經預置的情況

1、當lie到達超過最后一個索引時,轉為增加hang開始窮舉下一行。
2、如果當前位置元素不為“.”,那么跳過即可。
3、窮舉的時候如果遇到符合規則的數字,填入,否則跳過。

void backtrack(vector<vector<char>>& board, int hang, int lie) {if(lie==9){backtrack(board, hang+1, 0);}// 就是對每個位置進行窮舉for (int i = hang; i < 9; i++) {for (int j = lie; j < 9; j++) {// 如果該位置是預設的數字,不用我們操心if (board[i][j] != '.') {backtrack(board, i, j + 1);return;} //如果不是預置的數字for (char ch = '1'; ch <= '9'; ch++) {// 如果遇到符合規則的數字,填入if (isValid(board, i, j, ch)){// 做選擇board[i][j] = ch;// 繼續窮舉下一列,backtrack(board, i, j + 1);// 撤銷選擇board[i][j] = '.';}}}}
}

4、判斷是否符合規則的函數

規則如下:

1、數字 1-9 在每一行只能出現一次。
2、數字 1-9 在每一列只能出現一次。
3、數字 1-9 在每一個以粗實線分隔的 3x3 宮內只能出現一次。

翻譯成函數:
注意這里對第3個規則的描述:

// 判斷 board[i][j] 是否可以填入 n
bool isValid(vector<vector<char>>& board, int hang, int lie, char n) {for (int i = 0; i < 9; i++) {// 判斷行是否存在重復if (board[hang][i] == n) return false;// 判斷列是否存在重復if (board[i][lie] == n) return false;// 判斷 3 x 3 方框是否存在重復if (board[(hang/3)*3 + i/3][(lie/3)*3 + i%3] == n)return false;}return true;
}

下面是這個式子的含義,并且將i=0~8模擬了一下:
在這里插入圖片描述

5、確定遞歸終止條件+確定函數返回值

如果遞歸完最后一行,那么我們就可以返回我們的結果了。
如果找到一個解我們的任務就結束了,本題并沒有要求找到所有解。
如果一個位置遍歷完所有數字,都不符合,這說明此路不通,應該及時返回false。
如果每個位置都遍歷過了,結果都沒有返回true,說明,這個數獨棋盤沒有解,返回false。
所以使用bool類型的值作為返回值:

if(hang == 9) return true;

完整的回溯函數代碼應該如下:

bool backtrack(vector<vector<char>>& board, int hang, int lie) {//遍歷完這一行最后一列,轉而遍歷下一行if(lie==9){return backtrack(board, hang+1, 0);}//找到一個解,返回if(hang == 9) return true;// 就是對每個位置進行窮舉for (int i = hang; i < 9; i++) {for (int j = lie; j < 9; j++) {// 如果該位置是預設的數字,不用我們操心if (board[i][j] != '.') {return backtrack(board, i, j + 1);} //如果不是預置的數字for (char ch = '1'; ch <= '9'; ch++) {// 如果遇到符合規則的數字,填入if (isValid(board, i, j, ch)){// 做選擇board[i][j] = ch;// 繼續窮舉下一列,如果找到了一個解,立即結束if(backtrack(board, i, j + 1) == true) return true;// 撤銷選擇board[i][j] = '.';}}// 窮舉完 1~9,依然沒有找到可行解,此路不通return false;}}return false;
}

AC代碼

class Solution {
public:// 判斷 board[i][j] 是否可以填入 nbool isValid(vector<vector<char>>& board, int hang, int lie, char n) {for (int i = 0; i < 9; i++) {// 判斷行是否存在重復if (board[hang][i] == n) return false;// 判斷列是否存在重復if (board[i][lie] == n) return false;// 判斷 3 x 3 方框是否存在重復if (board[(hang/3)*3 + i/3][(lie/3)*3 + i%3] == n)return false;}return true;}bool backtrack(vector<vector<char>>& board, int hang, int lie) {//遍歷完這一行最后一列,轉而遍歷下一行if(lie==9){return backtrack(board, hang+1, 0);}//找到一個解,返回if(hang == 9) return true;// 就是對每個位置進行窮舉for (int i = hang; i < 9; i++) {for (int j = lie; j < 9; j++) {// 如果該位置是預設的數字,不用我們操心if (board[i][j] != '.') {return backtrack(board, i, j + 1);} //如果不是預置的數字for (char ch = '1'; ch <= '9'; ch++) {// 如果遇到符合規則的數字,填入if (isValid(board, i, j, ch)){// 做選擇board[i][j] = ch;// 繼續窮舉下一列,如果找到了一個解,立即結束if(backtrack(board, i, j + 1) == true) return true;// 撤銷選擇board[i][j] = '.';}}// 窮舉完 1~9,依然沒有找到可行解,此路不通return false;}}return false;}void solveSudoku(vector<vector<char>>& board) {backtrack(board, 0, 0);return;}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377727.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377727.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377727.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

快速完成兼職外包開發任務

做了很多年的開發相關的工作&#xff0c;做過兼職開發&#xff0c;也做過外包一些開發項目。 兼職人員角色時 正是經歷這些事情時&#xff0c;每次就要提前很費經的跟公司溝通&#xff0c;讓他們把公司內部的svn開發出去&#xff0c;但是就是很難&#xff0c;會涉及到安全各方的…

使用YOLOv5訓練NEU-DET數據集

一、下載YOLOv5源碼和NEU-DET(鋼材表面缺陷)數據集 YOLOv5源碼 NEU-DET(鋼材表面缺陷)數據集 這里的數據集已經經過處理了&#xff0c;下載即可 若通過其他途徑下載的原始數據集標簽為xml格式&#xff0c;需要轉化為txt格式XML轉txt格式腳本 二、數據集準備 NEU-DET(鋼材表…

kotlin獲取屬性_Kotlin程序獲取系統MAC地址

kotlin獲取屬性The task is to get system MAC address. 任務是獲取系統MAC地址。 package com.includehelpimport java.net.InetAddressimport java.net.NetworkInterface//Function to get System MACfun getSystemMac(): String? {return try {val OSName System.getProp…

帶分頁功能的SSH整合,DAO層經典封裝

任何一個封裝講究的是&#xff0c;使用&#xff0c;多狀態。Action&#xff1a;任何一個Action繼承分頁有關參數類PageManage&#xff0c;自然考慮的到分頁效果&#xff0c;我們必須定義下幾個分頁的參數。并根據這個參數進行查值。然后在繼承ServiceManage&#xff0c;Service…

在windows phone Mango中使用原生代碼開發程序

本文不討論創建可執行的exe程序,主要想說明怎么在silverlight程序里面調用由原生代碼所編寫的DLL(C / ARM). 原生代碼可以調用更多的API,但是這并不是說你就能隨意獲得那些你沒有權限的資源,比如,你可以使用CopyFile這個API,但是如果你試圖把文件Copy到\Windows文件夾,就會得到…

leetcode 198. 打家劫舍 思考分析

目錄1、題目2、求解思路3、代碼1、題目 你是一個專業的小偷&#xff0c;計劃偷竊沿街的房屋。每間房內都藏有一定的現金&#xff0c;影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統&#xff0c;如果兩間相鄰的房屋在同一晚上被小偷闖入&#xff0c;系統會自動…

找不到Windows照片查看器解決方法

桌面創建一個txt文本 復制這些命令&#xff0c;之后將后綴改為.reg&#xff0c;右擊管理員身份運行即可 Windows Registry Editor Version 5.00 ; Change Extensions File Type [HKEY_CURRENT_USER\Software\Classes\.jpg] "PhotoViewer.FileAssoc.Tiff" ; Change E…

數字拆分為斐波那契數列_檢查數字是否為斐波那契

數字拆分為斐波那契數列Description: 描述&#xff1a; We are often used to generate Fibonacci numbers. But in this article, we are going to learn about how to search Fibonacci numbers in an array? 我們經常被用來產生斐波那契數。 但是在本文中&#xff0c;我們…

伙伴分配器的一個極簡實現

提起buddy system相信很多人不會陌生&#xff0c;它是一種經典的內存分配算法&#xff0c;大名鼎鼎的Linux底層的內存管理用的就是它。這里不探討內核這么復雜實現&#xff0c;而僅僅是將該算法抽象提取出來&#xff0c;同時給出一份及其簡潔的源碼實現&#xff0c;以便定制擴展…

[USACO3.2.3 Spinning Wheels]

[關鍵字]&#xff1a;模擬 枚舉 [題目大意]&#xff1a;有5個輪子&#xff0c;每個輪子優r個缺口并且會按一定速度不停轉動&#xff0c;問什么時候可以使一條光線射過所有輪子。 // [分析]&#xff1a;從0到1000&#xff08;或其他的&#xff09;枚舉分鐘然后判斷&#xff0c;當…

一、SQLServer2008安裝(帶密碼)、創建數據庫、C#窗體項目測試

一、下載和安裝SQLServer2008 東西太大了&#xff0c;沒法上傳到資源里面&#xff0c;官網其他公眾號都下載可以。 右擊管理員身份 運行setup.exe 這個密鑰不能用的話&#xff0c;也可以去百度其他密鑰 JD8Y6-HQG69-P9H84-XDTPG-34MBB 建議改一下路徑&#xff0c;我這邊修…

python獲取當前日期_Python程序獲取當前日期

python獲取當前日期In the below example – we are implementing a python program to get the current date. 在下面的示例中-我們正在實現一個python程序來獲取當前日期 。 Steps: 腳步&#xff1a; Import the date class from datetime module. 從datetime模塊導入日期類…

【C++grammar】多態、聯編、虛函數

目錄1、多態概念1.多態性有兩種表現的方式2、聯編&#xff08;實現多態&#xff09;1.靜態聯編2.動態聯編3、實現運行時多態1.為何要使用運行時多態&#xff1f;2.如何實現運行時多態3.多態的例子1.調用哪個同名虛函數&#xff1f;2. 用途&#xff1a;可以用父類指針訪問子類對…

一 MVC - HtmlHelper

HtmlHelper類位于System.Web.Mvc.Html之中主要有七個靜態類組成&#xff1a; FormExtensions - BeginForm, BeginRouteForm, EndForm InputExtensions - CheckBox, CheckBoxFor, Hidden, HiddenFor, Password, PasswordFor, RadioButton, RadioButtonFor, TextBox, TextBoxFor …

HDOJ 400題紀念。

剛剛交了1506&#xff0c;無意間瞟到左邊的隨筆數&#xff0c;發現已經401題了&#xff0c;這么說前幾天就400題了啊囧。 昨天還想交到400題就先放放&#xff0c;背單詞的&#xff0c;沒想到那么快。等把USACO那個八皇后寫完吧。人生總是有許多不想做又不得不做的事情。。。 還…

二、用戶登錄和注冊

一、頁面設計 一共四個頁面 主頁面Form1&#xff0c;登錄頁面login&#xff0c;注冊頁面resister&#xff0c;主菜單頁面main_page 系統運行進入Form1&#xff0c;單擊登錄按鈕跳轉到login&#xff0c;數據庫中得存在數據信息且輸入正確才可登錄成功&#xff0c;跳轉到main_pa…

readdir函數_PHP readdir()函數與示例

readdir函數PHP readdir()函數 (PHP readdir() function) The full form of readdir is "Read Directory", the function readdir() is used to read the directory i.e. read the name of the next entry in the directory. readdir的完整形式為“ Read Directory”…

【C++grammar】訪問控制與抽象類與純虛函數

目錄一、訪問控制 (可見性控制)1.private、public、protected關鍵字2.關鍵字示例1、關鍵字對類數據成員訪問的限制3. 公有繼承4. 私有繼承5. 保護繼承6. 私有繼承和保護繼承的區別二、抽象類與純虛函數1.什么是抽象類2.抽象函數/純虛函數3.抽象類示例一、訪問控制 (可見性控制)…

mongodb 如何刪除 字段值為 json對象中的某個字段值

例如&#xff1a; { attributes: { birthday:1988-01-01, name: aq } } birthday是attributes字段的value的一個字段&#xff0c; 我要刪除birthday 用這句話&#xff1a; db.User.update({email:adminlinkris.com},{$unset:{attributes.birthday:}})轉載于:https://www.cnblog…

使用 Spring 的 Web 服務模擬器框架解決方案

http://www.ibm.com/developerworks/cn/web/wa-aj-simulator/index.html轉載于:https://www.cnblogs.com/diyunpeng/archive/2012/02/28/2371390.html