九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
所有可能的路徑!
userphoto

2022.12.04 湖南

關注

通知:代碼隨想錄算法訓練營 五期開始報名,預計下周三(12月7日)開營!

講完深度優(yōu)先搜索的理論基礎之后,今天來一個入門題目。

797.所有可能的路徑

力扣題目鏈接:https://leetcode.cn/problems/all-paths-from-source-to-target/

給你一個有 n 個節(jié)點的 有向無環(huán)圖(DAG),請你找出所有從節(jié)點 0 到節(jié)點 n-1 的路徑并輸出(不要求按特定順序)

graph[i] 是一個從節(jié)點 i 可以訪問的所有節(jié)點的列表(即從節(jié)點 i 到節(jié)點 graph[i][j]存在一條有向邊)。

提示:

  • n == graph.length
  • 2 <= n <= 15
  • 0 <= graph[i][j] < n
  • graph[i][j] != i(即不存在自環(huán))
  • graph[i] 中的所有元素 互不相同
  • 保證輸入為 有向無環(huán)圖(DAG)

思路

這道題目是深度優(yōu)先搜索,比較好的入門題。

如果對深度優(yōu)先搜索還不夠了解,可以先看這里:深度優(yōu)先搜索的理論基礎

我依然總結了深搜三部曲,如果按照代碼隨想錄刷題的錄友,應該刷過 二叉樹的遞歸三部曲,回溯三部曲。

大家可能有疑惑,深搜 和 二叉樹和回溯算法 有什么區(qū)別呢?什么時候用深搜 什么時候用回溯?

我在講解二叉樹理論基礎(https://programmercarl.com/二叉樹理論基礎.html)的時候,提到過,二叉樹的前中后序遍歷其實就是深搜在二叉樹這種數(shù)據(jù)結構上的應用。

那么回溯算法呢,其實 回溯算法就是深搜,只不過 我們給他一個更細分的定義,叫做回溯算法。

那有的錄友可能說:那我以后稱回溯算法為深搜,是不是沒毛?。?/p>

理論上來說,沒毛病,但 就像是  二叉樹 你不叫它二叉樹,叫它數(shù)據(jù)結構,有問題不?也沒問題對吧。

建議是 有細分的場景,還是稱其細分場景的名稱。所以回溯算法可以獨立出來,但回溯算法確實就是深搜。

接下來我們使用深搜三部曲來分析題目:

  1. 確認遞歸函數(shù),參數(shù)

首先我們dfs函數(shù)一定要存一個圖,用來遍歷的,還要存一個目前我們遍歷的節(jié)點,定義為x

至于 單一路徑,和路徑集合可以放在全局變量,那么代碼是這樣的:

vector<vector<int>> result; // 收集符合條件的路徑
vector<int> path; // 0節(jié)點到終點的路徑
// x:目前遍歷的節(jié)點
// graph:存當前的圖
void dfs (vector<vector<int>>& graph, int x) 
  1. 確認終止條件

什么時候我們就找到一條路徑了?

當目前遍歷的節(jié)點 為 最后一個節(jié)點的時候,就找到了一條,從 出發(fā)點到終止點的路徑。

當前遍歷的節(jié)點,我們定義為x,最后一點節(jié)點,就是 graph.size() - 1。

所以 但 x 等于 graph.size() - 1 的時候就找到一條有效路徑。代碼如下:

// 要求從節(jié)點 0 到節(jié)點 n-1 的路徑并輸出,所以是 graph.size() - 1
if (x == graph.size() - 1) { // 找到符合條件的一條路徑
    result.push_back(path); // 收集有效路徑
    return;
}
  1. 處理目前搜索節(jié)點出發(fā)的路徑

接下來是走 當前遍歷節(jié)點x的下一個節(jié)點。

首先是要找到 x節(jié)點鏈接了哪些節(jié)點呢? 遍歷方式是這樣的:

for (int i = 0; i < graph[x].size(); i++) { // 遍歷節(jié)點n鏈接的所有節(jié)點

接下來就是將 選中的x所連接的節(jié)點,加入到 單一路勁來。

path.push_back(graph[x][i]); // 遍歷到的節(jié)點加入到路徑中來

一些錄友可以疑惑這里如果找到x 鏈接的節(jié)點的,例如如果x目前是節(jié)點0,那么目前的過程就是這樣的:

二維數(shù)組中,graph[x][i] 都是x鏈接的節(jié)點,當前遍歷的節(jié)點就是 graph[x][i] 。

進入下一層遞歸

dfs(graph, graph[x][i]); // 進入下一層遞歸

最后就是回溯的過程,撤銷本次添加節(jié)點的操作。 該過程整體代碼:

for (int i = 0; i < graph[x].size(); i++) { // 遍歷節(jié)點n鏈接的所有節(jié)點
    path.push_back(graph[x][i]); // 遍歷到的節(jié)點加入到路徑中來
    dfs(graph, graph[x][i]); // 進入下一層遞歸
    path.pop_back(); // 回溯,撤銷本節(jié)點
}

本題整體代碼如下:

class Solution {
private:
    vector<vector<int>> result; // 收集符合條件的路徑
    vector<int> path; // 0節(jié)點到終點的路徑
    // x:目前遍歷的節(jié)點
    // graph:存當前的圖
    void dfs (vector<vector<int>>& graph, int x) {
        // 要求從節(jié)點 0 到節(jié)點 n-1 的路徑并輸出,所以是 graph.size() - 1
        if (x == graph.size() - 1) { // 找到符合條件的一條路徑
            result.push_back(path);
            return;
        }
        for (int i = 0; i < graph[x].size(); i++) { // 遍歷節(jié)點n鏈接的所有節(jié)點
            path.push_back(graph[x][i]); // 遍歷到的節(jié)點加入到路徑中來
            dfs(graph, graph[x][i]); // 進入下一層遞歸
            path.pop_back(); // 回溯,撤銷本節(jié)點
        }
    }
public:
    vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
        path.push_back(0); // 無論什么路徑已經(jīng)是從0節(jié)點出發(fā)
        dfs(graph, 0); // 開始遍歷
        return result;
    }
};

總結

本題是比較基礎的深度優(yōu)先搜索模板題,這種有向圖路徑問題,最合適使用深搜,當然本題也可以使用廣搜,但廣搜相對來說就麻煩了一些,需要記錄一下路徑。

而深搜和廣搜都適合解決顏色類的問題,例如島嶼系列,其實都是 遍歷+標記,所以使用哪種遍歷都是可以的。

至于廣搜理論基礎,我們在下一篇在好好講解,敬請期待!

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Python|Dfs回溯解二叉樹偽回文
關于圖算法 & 圖分析的基礎知識概覽
劍指offer(C++)-JZ12:矩陣中的路徑(算法-回溯)
淺談算法和數(shù)據(jù)結構(12):無向圖相關算法基礎
圖論算法基礎
劍指offer 24 二叉樹中和為某一值的路徑 ★★★★
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服