深搜+剪枝

文章目錄

  • 題目
  • 思路
  • 注意
  • 代碼
  • 復雜度分析


題目

給定一個 m x n 二維字符網格 board 和一個字符串單詞 word 。如果 word 存在于網格中,返回 true ;否則,返回 false 。

單詞必須按照字母順序,通過相鄰的單元格內的字母構成,其中“相鄰”單元格是那些水平相鄰或垂直相鄰的單元格。同一個單元格內的字母不允許被重復使用。

例如,在下面的 3×4 的矩陣中包含單詞 “ABCCED”(單詞中的字母已標出)。

在這里插入圖片描述
示例 1:

輸入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
輸出:true

示例 2:

輸入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
輸出:false

提示:

1 <= board.length <= 200
1 <= board[i].length <= 200
board 和 word 僅由大小寫英文字母組成

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof


思路

深度優先搜索: 暴搜遍歷矩陣中所有字符串。DFS 通過遞歸,先朝一個方向搜到底,再回溯至上個節點,沿另一個方向搜索,以此類推。

剪枝: 在搜索中,遇到 這條路不可能和目標字符串匹配成功 的情況(例如:此矩陣元素和目標字符不同、此元素已被訪問),則應立即返回,稱之為 可行性剪枝

DFS細節:

  • 遞推工作:
    標記當前矩陣元素: 將 board[i][j] 修改為 空字符 '' ,代表此元素已訪問過,防止之后搜索時重復訪問。
  • 終止條件:
    返回 false : (1) 行或列索引越界 或 (2) 當前矩陣元素與目標字符不同 或 (3) 當前矩陣元素已訪問過 ( (3) 可合并至 (2) ) 。
    返回 true : k = word.size() - 1 ,即字符串 word 已全部匹配。
  • 搜索下一單元格:
    朝當前元素的 上、下、左、右 四個方向開啟下層遞歸,使用 連接 (代表只需找到一條可行路徑就直接返回,不再做后續 DFS ),并記錄結果至 res
  • 還原當前矩陣元素:
    將 board[i][j] 元素還原至初始值,即 word[k] 。確保其他節點進行深搜時當前元素正常。
  • 返回值:
    返回布爾量 res ,代表是否搜索到目標字符串。

注意

典型的深搜題目,值得一提的是,在寫代碼時,發現一個小小的改動就能帶來時間和空間的巨大優化,可能這就是編程語言的魅力吧(誤)。我們常說

拷貝傳值較之引用傳值:

  1. 引用傳值避免拷貝操作帶來的時間與空間的額外開銷。
  2. 拷貝傳值修改實參的拷貝而非實參本身,從而確保實參的安全性。

在構建dfs函數時,我們會修改board,但最終也會將其復原,因此調用board的安全性是可以保證的,也就意味著可以使用引用傳值。

而對于word,我們根本就不會去修改它,因此可以在聲明時為代表其的形參賦予const屬性,并以引用傳值的方式進行調用。

而對于i, j, k,不將它們設置為引用傳參的原因是,在進行上、下、左、右四個方向的深搜時,要傳入一個表達式作為參數,而非常量引用必須綁定到左值,以i + 1為例,表達式的結果作為臨時變量被綁定在臨時量const int& temp上,而形參int& i作為非常量引用是無法綁定一個常量引用綁定的對象的。

bool dfs(vector<vector<char>>& board, const string& word, size_t i, size_t j, int k);

時,時間、空間效率:
在這里插入圖片描述

bool dfs(vector<vector<char>>& board, const string word, size_t i, size_t j, int k)

時,時間、空間效率:
在這里插入圖片描述
該用引用的時候一定要用引用這句話深深刻在心里。。。。


代碼

class Solution {size_t rows, cols;bool dfs(vector<vector<char>>& board, const string& word, size_t i, size_t j, int k){if(i >= rows || i < 0 || j >= cols || j < 0 || board[i][j] != word[k]){return false;}if(k == (word.size() - 1)){return true;}board[i][j] = '\0';bool res = dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i - 1, j, k + 1) ||dfs(board, word, i, j - 1, k + 1) || dfs(board, word, i, j + 1, k + 1);board[i][j] = word[k];return res;}
public:bool exist(vector<vector<char>>& board, string word) {rows = board.size();cols = board[0].size();for(size_t i = 0; i < rows; i++){for(size_t j = 0; j < cols; j++){bool falg = dfs(board, word, i, j, 0);if(falg){return true;}}}return false;}
};

復雜度分析

M, N 分別為矩陣行列大小, KK 為字符串 word 長度。

時間復雜度 O(MN3^K) :

  1. 最差情況下,需要遍歷矩陣中長度為 K 字符串的所有方案,時間復雜度為 O(3^K );矩陣中共有 MN 個起點,時間復雜度為 O(MN)。
  • 方案數計算: 設字符串長度為 K ,搜索中每個字符有上、下、左、右四個方向可以選擇,舍棄回頭(上個字符)的方向,剩下 3 種選擇,因此方案數的復雜度為 O(3^K)。
  1. 空間復雜度 O(K): 搜索過程中的遞歸深度不超過 K ,因此系統因函數調用累計使用的棧空間占用 O(K) (因為函數返回后,系統調用的棧空間會釋放)。最壞情況下 K = MN,遞歸深度為 MN ,此時系統棧使用 O(MN) 的額外空間。

作者:jyd
鏈接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/solution/mian-shi-ti-12-ju-zhen-zhong-de-lu-jing-shen-du-yo/
來源:力扣(LeetCode)

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

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

相關文章

搜索+回溯問題(DFS\BFS詳解)

文章目錄題目思路DFS思路代碼復雜度分析BFS思路代碼復雜度分析題目 地上有一個m行n列的方格&#xff0c;從坐標 [0,0] 到坐標 [m-1,n-1] 。一個機器人從坐標 [0, 0] 的格子開始移動&#xff0c;它每次可以向左、右、上、下移動一格&#xff08;不能移動到方格外&#xff09;&am…

剪繩子(動規、數論、貪心)

文章目錄題目數論思路代碼復雜度分析動規一思路代碼動規二思路代碼對最終結果取模1e97思路代碼題目 給你一根長度為 n 的繩子&#xff0c;請把繩子剪成整數長度的 m 段&#xff08;m、n都是整數&#xff0c;n>1并且m>1&#xff09;&#xff0c;每段繩子的長度記為 k[0],…

快速冪實現pow函數(從二分和二進制兩種角度理解快速冪)

文章目錄迭代實現快速冪思路int的取值范圍快速冪從二進制的角度來理解從二分法的角度來理解代碼復雜度分析進階——超級次方思路倒序快速冪正序快速冪代碼復雜度分析迭代實現快速冪 實現 pow(x, n) &#xff0c;即計算 x 的 n 次冪函數&#xff08;即&#xff0c;xn&#xff0…

備份MySQL數據庫的命令

備份MySQL數據庫的命令 mysqldump -hhostname -uusername -ppassword databasename > backupfile.sql 備份MySQL數據庫為帶刪除表的格式 備份MySQL數據庫為帶刪除表的格式&#xff0c;能夠讓該備份覆蓋已有數據庫而不需要手動刪除原有數據庫。 mysqldump -–add-drop-…

n位數的全排列(需要考慮大數的情況)

文章目錄題目思路代碼題目 輸入數字 n&#xff0c;按順序打印出從 1 到最大的 n 位十進制數。比如輸入 3&#xff0c;則打印出 1、2、3 一直到最大的 3 位數 999。 示例 1: 輸入: n 1 輸出: [1,2,3,4,5,6,7,8,9] 說明&#xff1a; 用返回一個整數列表來代替打印 n 為正整數 …

正則表達式匹配(動規)

文章目錄題目思路轉移方程特征再探 i 和 j代碼題目 請實現一個函數用來匹配包含 . 和 * 的正則表達式。模式中的字符 . 表示任意一個字符&#xff0c;而 * 表示它前面的字符可以出現任意次&#xff08;含0次&#xff09;。在本題中&#xff0c;匹配是指字符串的所有字符匹配整…

在循環遞增一次的數組中插入元素

文章目錄題目思路如何建立左右區間&#xff1f;如何查找最高點&#xff1f;那我們怎么判斷 num 到底處于什么樣的位置呢&#xff1f;如何確定插入位置&#xff1f;插入元素代碼題目 給一個只循環遞增一次的數組 res&#xff0c;res 滿足首元素大于等于尾元素&#xff0c;形如&…

Unable to find 'struts.multipart.saveDir' property setting.

Unable to find struts.multipart.saveDir property setting. 今天在做工作的時候遇到了這個問題&#xff0c;后來經過百度&#xff0c;終于知道了原因&#xff0c;現在記錄下來&#xff0c;以備以后查看。 1.struts.multipart.saveDir沒有配置 2.struts.multipart.saveDir用…

表示數值的字符串(有限狀態自動機與搜索)

文章目錄題目思路一代碼一思路二代碼二題目 思路一 考察有限狀態自動機&#xff08;參考jyd&#xff09;&#xff1a; 字符類型&#xff1a; 空格 「 」、數字「 0—9 」 、正負號 「 」 、小數點 「 . 」 、冪符號 「 eE 」 。 狀態定義&#xff1a; 按照字符串從左到右的…

樹的子結構

文章目錄題目深搜深搜代碼廣搜廣搜代碼題目 輸入兩棵二叉樹A和B&#xff0c;判斷B是不是A的子結構。(約定空樹不是任意一個樹的子結構) B是A的子結構&#xff0c; 即 A中有出現和B相同的結構和節點值。 例如: 給定的樹 A: 給定的樹 B&#xff1a; 返回 true&#xff0c;因為…

寫題過程中碰見的小問題

文章目錄和--vector二維vector的初始化數組中最大的數max_element()數組所有元素之和accumulate()vector數組去重對pair類型的vector排序對元素都為正整數的vector利用sort默認的升序排列進行降序排列一維數組轉二維數組size_t和int如何不用臨時變量交換兩個數?將類函數的形參…

LeetCode——二叉樹序列化與反序列化

文章目錄題目思路問題一問題二代碼實現題目 請實現兩個函數&#xff0c;分別用來序列化和反序列化二叉樹。 設計一個算法來實現二叉樹的序列化與反序列化。不限定序列 / 反序列化算法執行邏輯&#xff0c;你只需要保證一個二叉樹可以被序列化為一個字符串并且將這個字符串反序…

jsp中生成的驗證碼和存在session里面的驗證碼不一致的處理

今天在調試項目的時候發現&#xff0c;在提交表單的時候的驗證碼有問題&#xff0c;問題是這樣的&#xff1a;就是通過debug模式查看得知&#xff1a;jsp頁面生成的驗證碼和表單輸入的頁面輸入的一樣&#xff0c;但是到后臺執行的時候&#xff0c;你會發現他們是不一樣的&#…

求1~n這n個整數十進制表示中1出現的次數

文章目錄題目思路代碼復雜度分析題目 輸入一個整數 n &#xff0c;求1&#xff5e;n這n個整數的十進制表示中1出現的次數。 例如&#xff0c;輸入12&#xff0c;那么1&#xff5e;12這些整數中包含1 的數字有1、10、11和12。可得1一共出現了5次。 思路 將個位、十位……每位…

求數字序列中的第n位對應的數字

文章目錄題目思路代碼復雜度分析致謝題目 數字以0123456789101112131415…的格式序列化到一個字符序列中。在這個序列中&#xff0c;第5位&#xff08;從下標0開始計數&#xff09;是5&#xff0c;第13位是1&#xff0c;第19位是4&#xff0c;等等。 請寫一個函數&#xff0c…

一學就廢的歸并排序

文章目錄其他與排序有關的文章原理代碼實現復雜度分析其他與排序有關的文章 一學就廢的三種簡單排序【冒泡、插入、選擇】 原理 歸并排序&#xff08;Merge sort&#xff09;&#xff1a; 歸并排序對元素 遞歸地 進行 逐層折半分組&#xff0c;然后從最小分組開始&#xff0c…

神奇的x -x,Lowbit函數的實現方式!

文章目錄-xx & -x&#xff0c;當x為偶數時x & -x&#xff0c;當x為奇數時x&-x 的實際用途-x -x 在二進制里表示對 x 的二進制按位取反(~x)之后再加 1 &#xff0c;即 -x ~x1x & -x&#xff0c;當x為偶數時 在執行 x & -x 時&#xff0c;若 x 為偶數&am…

JAVA實現把指定文件夾下的所有文件壓縮成zip包

1.代碼如下&#xff1a; package cn.gov.csrc.base.util;import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import…

樹狀數組的相關知識 及 求逆序對的運用

文章目錄樹狀數組概念前綴和和區間和樹狀數組原理區間和——單點更新前綴和——區間查詢完整代碼離散化sort函數unique函數去重erase函數僅保留不重復元素通過樹狀數組求逆序對樹狀數組概念 樹狀數組又名二叉索引樹&#xff0c;其查詢與插入的復雜度都為 O(logN)&#xff0c;其…

二叉搜索樹相關知識及應用操作

文章目錄概念查找二叉搜索樹的第k大節點概念 二叉查找樹&#xff08;Binary Search Tree&#xff09;&#xff0c;&#xff08;又名&#xff1a;二叉搜索樹&#xff0c;二叉排序樹&#xff09;——它或者是一棵空樹&#xff0c;或者是具有下列性質的二叉樹&#xff1a; 若它的…