1. 程式人生 > >Leetcode 079 搜尋單詞 Python C++ 史上最詳細題解系列

Leetcode 079 搜尋單詞 Python C++ 史上最詳細題解系列

題目:

給定一個二維網格和一個單詞,找出該單詞是否存在於網格中。

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

示例:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

給定 word = "ABCCED", 返回 true.
給定 word = "SEE", 返回 true.
給定 word = "ABCB", 返回 false.

每天更新一道python or C++ leetcode題,力求講解清晰準確,客官們可以點贊或者關注。
 

演算法過程:(主要見程式碼註釋)

1.通過search函式的引數x, y記錄當前搜尋的位置,同時遍歷上下左右方向,進入下一個位置。進入時要考慮下個位置是否符合標準。(詳細解釋見程式碼)

2.已搜尋過的位置記為true,防止遞迴無法終止。搜尋完後重新標記為false。

程式碼:

python:(看著嚇人,實際邏輯很簡單)

class Solution:
    def __init__(self):
        self.pos = list()#
        self.n = self.m = 0#用來儲存行和列的數目
        self.flag = False#用來標誌最終結果
        self.l = 0#單詞長度
        self.target = ""#目標要構建的單詞
        self.direction = [[1,0],[-1,0],[0,1],[0,-1]]#可以選的方向
    def search(self, board, x, y, s):
        if s == self.target: self.flag = True; return#如果構建中的字串達到目標要構建的單詞
        if len(s) >= self.l: return#如果構建的字元的長度大了,就返回,防止無限增加
        self.pos[x][y] = True#把當前位置標記為已搜尋,防止再次搜尋。
        for d in self.direction:#遍歷所有方向,上下左右
            if 0 <= x+d[0] <= self.n-1 and 0 <= y+d[1] <= self.m-1 and not self.pos[x+d[0]][y+d[1]] and board[x+d[0]][y+d[1]] == self.target[len(s)]:#只有當下個節點沒有超過邊界並且沒有被訪問過並且是下一個必須的組成單詞的下一個字母時,我們才呼叫遞迴
                self.search(board, x+d[0], y+d[1], s+board[x+d[0]][y+d[1]])#構建中的單詞需要加上下一個字母,同時更新位置
                if self.flag: return#如果找到了該單詞,直接返回
        self.pos[x][y] = False#把當前標為未訪問

    def exist(self, board, word):
        self.n = len(board)#儲存行數
        if self.n == 0: return False
        self.m = len(board[0])#儲存列數
        if self.m == 0: return False
        self.l = len(word)#儲存單詞長度
        if self.l == 0 or self.l > self.n*self.m: return False#如果當前單詞比所有字母連一起還長
        self.target = word#儲存目標單詞
        self.pos = [[False for col in range(self.m)] for row in range(self.n)]#構建一個檢測有沒有被訪問的表
        for i in range(self.n):
            for j in range(self.m):
                if board[i][j] == word[0]:#如果當前字母等於第一個字母,開始遞迴
                    self.search(board,i,j,board[i][j])

        return self.flag#返回最終結果

C++(寫的相對簡潔一點)

class Solution {  
public:  
    bool exist(vector<vector<char>>& board, string word) {  
        int row = board.size();  
        int col = board[0].size();  
        for (int i = 0; i < row; i++)  
        {  
            for (int j = 0; j < col; j++)  
            {  
                //visit陣列記錄該陣列是否被訪問過  
                vector<vector<bool>> visit(row, vector<bool>(col, false));  
                bool res = dfs(board, visit, i, j, word, 0);  
                if (res == true)  
                    return true;  
            }  
        }  
        return false;  
    }  
    //index表示的是當前探索的是第幾個詞  
    bool dfs(vector<vector<char>>& b, vector<vector<bool>>& visit, int x, int y,                //遍歷陣列的每一點  
        string s, int index)  
    {  
        int row = b.size();  
        int col = b[0].size();  
        if (index == s.length())  
            return true;  
        //以下幾種情況 不再進行處理  
        //1、陣列越界  
        //2、該節點已經訪問過  
        //3、index位置的字元與字串中的字元不符  
        else if (x < 0 || x >= row || y < 0 || y >= col   //1  
                 || visit[x][y] == true                   //2  
                 || s[index]!=b[x][y])                    //3  
            return false;  
        else  
        {  
            visit[x][y] = true;  
            //從xy出發向周圍進行探索  
            bool x_1y = dfs(b, visit, x - 1, y, s, index + 1);  
            bool x1y = dfs(b, visit, x + 1, y, s, index + 1);  
            bool xy_1 = dfs(b, visit, x, y - 1, s, index + 1);  
            bool xy1 = dfs(b, visit, x, y + 1, s, index + 1);  
  
            if (x_1y || x1y || xy_1 || xy1)  
                return true;  
            else  
            {  
                visit[x][y] = false;  
                return false;  
            }  
        }  
    }  
};  

總結:

1.DFS可以通過記錄當前位置來達到深搜目的

2.用visited 陣列可以防止重複搜尋,無法結束遞迴

3.注意剪枝

相關推薦

Leetcode 079 搜尋單詞 Python C++ 詳細題解系列

題目: 給定一個二維網格和一個單詞,找出該單詞是否存在於網格中。 單詞必須按照字母順序,通過相鄰的單元格內的字母構成,其中“相鄰”單元格是那些水平相鄰或垂直相鄰的單元格。同一個單元格內的字母不允許被重複使用。 示例: board = [ ['A','B','C',

Leetcode 075 顏色分類 Python C++ 詳細題解系列(多解法)

每天更新一道python or C++ leetcode題,力求講解清晰準確,客官們可以點贊或者關注。 題目: 給定一個包含紅色、白色和藍色,一共 n 個元素的陣列,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色、白色、藍色順序排列。 此題中,我們使用整數

Leetcode 81 搜尋旋轉排序陣列 II Python C++ 詳細題解系列

題目: 假設按照升序排序的陣列在預先未知的某個點上進行了旋轉。 ( 例如,陣列 [0,0,1,2,2,5,6] 可能變為 [2,5,6,0,0,1,2] )。 編寫一個函式來判斷給定的目標值是否存在於陣列中。若存在返回 true,否則返回 false。 示例 1:

利用Python實現導彈自動追蹤!室友面前的裝逼利器!詳細

技術 取數 跟隨鼠標 構造 制作 思想 室友 相同 精確 不好意思 ,上傳錯了。接著看圖! 由於待會要用pygame演示,他的坐標系是y軸向下,所以這裏我們也用y向下的坐標系。 算法總的思想就是根據上圖,把時間t分割成足夠小的片段(比如1/1000,

詳細的爬蟲教程,Python採集全網受歡迎的 500 本書!

      想看好書?想知道哪些書比較多人推薦,最好的方式就是看資料,接下來用 Python 爬取噹噹網五星圖書榜 TOP500 的書籍,或許能給我們參考參考! Python爬取目標   爬取噹噹網前500本受歡迎的書籍 解析書籍名稱

詳細完全的ipython使用教程,Python使用者必備!——ipython系列之二

宣告:本文承接前面一篇文章,ipython系列之一;另外,本文所指的ipython不是ipython notebook,ipython notebook已經被jupyter notebook所取代,不再叫ipython notebook了。 前面講解了ipython裡面的一些核心

詳細完全的ipython使用教程,Python使用者必備!——ipython系列之一

一、ipython簡介 關於什麼是ipython,本文就不加以介紹了,他是一個非常流行的python直譯器,相比於原生的python直譯器,有太多優點和長處,因此幾乎是python開發人員的必知必會。 1、ipython相比於原生的python有什麼優勢 (1) pyth

C++ 華而不實的類

下面大家要看到這個類完全是扯淡,一無是處。它是由感而發於帖子C++的二維陣列轉置。 當時,看完帖子我就在想,能不能用過載的方式實現邏輯轉置?只是好奇。C++顯然是不能過載兩個 [][] ,但是要達到這個效果,只要讓 [] 操作符返回一個指標即可。 問題是這樣根本做不到一個邏

python小課堂專欄】python小課堂15 - 詳細的包和模組import講解篇

python小課堂15 - 史上最詳細的包和模組import講解篇 前言 在大量的程式碼設計中,我們不可能將所有程式碼都寫在一個.py檔案,所以有了包、模組,而為了程式碼可以重複利用(複用性),就有了類、函式的概念。類和函式在下次介紹。 python中的包 python中

python小課堂專欄】python小課堂14 - 詳細安裝破解PyCharm篇

python小課堂14 - 程式碼編輯器PyCharm篇 前言 古人云:工欲善其事必先利其器!寫程式碼也一樣,雖然好多人都說,初學者不推薦使用很高大上,智慧,自動化的編輯器,但是我想說:“強大的,智慧的東西為什麼就不推薦新手用呢?!!”我自學java的時候,也直接用的是eclip

詳細Python爬取電影教程,還不會那也是沒誰了

摘要: 作為小白,爬蟲可以說是入門python最快和最容易獲得成就感的途徑。因為初級爬蟲的套路相對固定,常見的方法只有幾種,比較好上手。選取網頁結構較為簡單的貓眼top100電影為案例進行練習。 重點是用上述所說的4種方法提取出關鍵內容。一個問題採用不同的解決方法有助於拓展思維,通過不斷練

詳細c語言學生管理系統(完整的原始碼)

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<conio.h> struct student { char sno[12]; char n

詳細完全的jupyter notebook使用教程,Python使用者必備!——ipython系列之三

一、什麼是jupyter 1、簡介: jupyter notebook是一種 Web 應用,能讓使用者將說明文字、數學方程、程式碼和視覺化內容全部組合到一個易於共享的文件中。它可以直接在程式碼旁寫出敘述性文件,而不是另外編寫單獨的文件。也就是它可以能將程式碼、文件

Python爬蟲入門到實戰-詳細的爬蟲教程

技術分享 圖片 color blog .com 教程 robot http 進階 馬哥高薪實戰學員 【Python爬蟲入門到實戰-史上最詳細的爬蟲教程,限時免費領取】 爬蟲分類和ROBOTS協議 爬蟲URLLIB使用和進階 爬蟲URL編碼和GETPOST請求 Python爬

詳細Windows版本搭建安裝React Native環境配置

gin windows系統 adl 搭建環境 tools 想要 變量 rep home 說在前面的話: 感謝同事金曉冰傾情奉獻本環境搭建教程 之前我們已經講解了React Native的OS X系統的環境搭建以及配置,鑒於各大群裏有很多人反應在Windows環境搭建出現各種

移植QT5.6到嵌入式開發板(詳細的QT移植教程)

文件傳輸 嵌入式環境 ubun 導致 字庫 etc -a led fill 目前網上的大多數 QT 移植教程還都停留在 qt4.8 版本,或者還有更老的 Qtopia ,但是目前 Qt 已經發展到最新的 5.7 版本了,我個人也已經使用了很長一段時間的 qt5.6 for

詳細nodejs版本管理器nvm的安裝與使用(附註意事項和優化方案)

技術 註意 nod core 遇到 target 快速 方式 get 使用場景 在Node版本快速更新叠代的今天,新老項目使用的node版本號可能已經不相同了,node版本更新越來越快,項目越做越多,node切換版本號的需求越來越迫切,傳統卸載一個版本在安裝另一個版本的方

Android Studio獲取開發版SHA1值和發布版SHA1值的詳細方法

nal code tail JD rip 通過 提示 打開 tor 前言:使用百度地圖時需要秘鑰,申請秘鑰時需要SHA1值,所以今天就總結一下怎麽獲取這個值。 正常情況下: 一、獲取開發版SHA1: 在此我直接用AndroidStudio提供的命令控制臺了,畢竟做Andro

XX-NET詳細完整教程

偽造 不用 app 分享圖片 AS 版本 firefox 配置過程 自動切換 前言   XX-NET,系GAE類代理,即通過可用Google ip連接Google App Engine項目,然後把所有tcp請求發送給Google App Engine,最終實現科學式網絡的

詳細Windows下安裝 binwalk

github src cti tro 下載 安裝步驟 clas 文件 命令行 1. https://github.com/ReFirmLabs/binwalk到這裏下載binwalk,下載後解壓。 2. 找到下載後的文件夾, 在這裏要進行安裝步驟,一邊按著shift,一邊