JZ:12 矩形中的路徑(回溯/ DFS)

題目:

請設計一個函數,用來判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。
路徑可以從矩陣中的任意一格開始,每一步可以在矩陣中向左、右、上、下移動一格。
如果一條路徑經過了矩陣的某一格,那麼該路徑不能再次進入該格子。
例如,在下面的3×4的矩陣中包含一條字符串“bfce”的路徑(路徑中的字母用加粗標出)。

[["a","b","c","e"],
["s","f","c","s"],
["a","d","e","e"]]

但矩陣中不包含字符串“abfb”的路徑,因爲字符串的第一個字符b佔據了矩陣中的第一行第二個格子之後,
路徑不能再次進入這個格子。

 

示例 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

思路:
對於這個題目,首先看到就會想DFS(也就是所謂回溯思想)
思路上:對於每一個字母從它開始向四周開始搜索,如果搜索到的字符拼接起來與目標字符串前面一致,那麼就繼續向四周搜索,如果不一致,就返回!從上一層的另一個方向繼續搜索;
如果4個方向都搜索完也沒有找到,記得將搜索過程的記錄清除,並返回;

例如:這個矩陣,目標爲:“bfce”
在這裏插入圖片描述
在這裏插入圖片描述
實現過程中的難點:
對於走過的路徑,我們需要一個同樣大小的二維數組來記錄是否走過,爲了節省內存空間,我們使用引用傳遞這個數組,這就意味着在當前路徑未找到目標字符時(四個方向搜索結束未找到):我們需要將當前位置恢復爲未搜索狀態(true) 也就是下面的visited數組;並將添加進來的字符刪除!(str.pop_back())

另一個難點:
在當前DFS函數中,末尾處也就是四個方向搜索結束後,我們並不知道是否搜索到完整的字符串並層層返回,因此需要在第一個難點(刪除蹤跡)之前判斷:當前是否已經找到目標!如果找到則不需要刪除字符,直接返回就ok了,層層返回之後,在主函數exist中會判斷是否已經找到!

代碼:

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        if(board.size()==0)
            return false;

        int count = 0;    
        for(int i = 0; i < board.size(); i++)
        {
            for(int j = 0; j < board[0].size(); j++){
                if(board[i][j] == word[0]){
                    vector<vector<bool>> visited(board.size(), 
                                                vector<bool>(board[0].size(), true));
                    string ret_str = "";
                    DFS(board, word, ret_str,i, j, count,visited);
                    if(ret_str == word)
                        return true;
                    ret_str = "";
                }  
            }
        }
        return false;
    }


    void DFS(vector<vector<char>>& board, string word, string& ret_str, 
            int i,int j, int count, vector<vector<bool>>& visited)
    {
        ret_str += board[i][j];
        visited[i][j] = false;
        count++;

        if(ret_str == word)
            return;
        // cout << "in: " << ret_str << endl;
        if(i-1 >=0 && board[i-1][j] == word[count] && visited[i-1][j] == true)
            DFS(board, word, ret_str,i-1, j, count,visited);
        
        if(i+1 < board.size() && board[i+1][j] == word[count] && visited[i+1][j] == true)
            DFS(board, word, ret_str,i+1, j, count,visited);
        
        if(j-1 >=0 && board[i][j-1] == word[count] && visited[i][j-1] == true)
            DFS(board, word, ret_str,i, j-1, count,visited);
        
        if(j+1 < board[0].size() && board[i][j+1] == word[count] && visited[i][j+1] == true)
            DFS(board, word, ret_str,i, j+1, count,visited);
        

        if(ret_str == word)
            return;
        visited[i][j] = true;
        ret_str.pop_back();

        
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章