日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深搜+剪枝

發布時間:2023/12/13 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深搜+剪枝 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

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


題目

給定一個 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 ,代表是否搜索到目標字符串。

注意

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

拷貝傳值較之引用傳值:

  • 引用傳值避免拷貝操作帶來的時間與空間的額外開銷。
  • 拷貝傳值修改實參的拷貝而非實參本身,從而確保實參的安全性。
  • 在構建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) :

  • 最差情況下,需要遍歷矩陣中長度為 K 字符串的所有方案,時間復雜度為 O(3^K );矩陣中共有 MN 個起點,時間復雜度為 O(MN)。
    • 方案數計算: 設字符串長度為 K ,搜索中每個字符有上、下、左、右四個方向可以選擇,舍棄回頭(上個字符)的方向,剩下 3 種選擇,因此方案數的復雜度為 O(3^K)。
  • 空間復雜度 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)

    總結

    以上是生活随笔為你收集整理的深搜+剪枝的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。