1. 程式人生 > 其它 >史上最詳細深度優先搜尋遍歷(DFS)程式碼,力扣(LeetCode)刷題第79題:單詞搜尋!

史上最詳細深度優先搜尋遍歷(DFS)程式碼,力扣(LeetCode)刷題第79題:單詞搜尋!

技術標籤:力扣刷題筆記演算法javaleetcode資料結構dfs

文章目錄


前言

題目地址:單詞搜尋

一、題目介紹

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

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

示例 1:
示例:

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

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

二、解題思路

1.分析題目

針對題目給出的介紹和示例,可以分析,題目是想讓我們查詢一個矩陣中是否可以找到給出的單詞,也就是所謂的單詞搜尋,我們可以思考一下,其實也就是搜尋,我們把矩陣想象成圖,也就是從一個圖中搜索一個單詞,可以嘗試圖的搜尋演算法,深度和廣度優先搜尋遍歷。

2.思路與演算法

當確定完是搜尋的話,可以嘗試深度搜索遍歷。

我們可以嘗試從矩陣的每一個位置開始搜尋,如果當前位置的字元和單詞開始字元相同,則單詞字元後移一位,矩陣往下一個方位搜尋,一共有四個可供選擇的方向。如果一直下去都可以搜到對應的矩陣字元與單詞字元相匹配,則就返回true,如果有一個字元不匹配,則返回false,下次從下一個矩陣位置開始從0字元開始搜尋,一直遍歷完所有的矩陣位置。

對每次遍歷,如果當前位置已經遍歷過需要進行標記,可以使用一個同矩陣大小的標記矩陣visited[][]。

3.程式碼部分

Java程式碼詳細註釋

class Solution {
    public boolean exist(char[][] board, String word) {
        //使用深度優先搜尋遍歷
        int row = board.length;
        int low = board[0].length;//獲取陣列的大小
        //設定一個判斷陣列,判斷當前陣列是否已經訪問過
        boolean [][]visited = new
boolean[row][low];//預設的是false for(int i = 0;i<row;i++){ for(int j = 0;j<low;j++){ boolean flag = check(visited,board,i,j,word,0);//依次檢查當前節點 if (flag){//找到單詞的匹配,返回true return true; } } } return false;//沒找到返回false } //檢查函式 public boolean check(boolean [][]visited,char[][]board,int i,int j,String word,int k){ //先檢查當前陣列所對應的節點是否存在單詞的字母 if(board[i][j]!=word.charAt(k)){ return false; } //如果當前已經遍歷到單詞的最後一個字母,則直接返回 else if(k == word.length()-1){ return true;//也就是單詞匹配成功 } visited[i][j] = true;//已經比對過當前節點,而且說明當前點對應的字母匹配上了。 boolean result = false;//判斷引數 int[][] directions = {{0,1},{0,-1},{1,0},{-1,0}};//當遍歷到一個節點後,下次可以往四個方向查詢,{0,1}代表東邊,{0,-1}代表北邊,{1,0}代表南邊{-1,0}代表西邊。 //下一步,查詢四周的四個點是否存在匹配的字母 for(int[]dir:directions){//使用增強for,直接獲取當前directions中的資料,並不是獲取索引。 int newi = i + dir[0],newj = j + dir[1];//新的查詢節點 if(newi>=0 && newi<board.length &&newj>=0 && newj<board[0].length){//邊界判斷 if(visited[newi][newj]!=true){//判斷當前節點是否訪問,如果沒有在進行下一步判斷 boolean flag = check(visited,board,newi,newj,word,k+1); if(flag){//如果返回的是true,說明是匹配的。 result = true; break; } } } } visited[i][j] = false;//檢查完當前節點需要把其重新變回false,便於下次檢查使用 return result;//返回結果 } }

在這裡插入圖片描述

三、總結

提示:針對個別型別的題目,可以直接套用深度優先搜尋遍歷,其實可以總結出這種型別題目的模板,也就是深度優先搜尋遍歷的模板。

dfs(){
 
    // 第一步,檢查下標是否滿足條件
 
    // 第二步:檢查是否被訪問過,或者是否滿足當前匹配條件
 
    // 第三步:檢查是否滿足返回結果條件
 
    // 第四步:都沒有返回,說明應該進行下一步遞迴
    // 標記
    dfs(下一次)
    // 回溯
} 
 
 
main() {
    for (對所有可能情況) {
        dfs()
    }
}

記錄時間:2020年12月8日