1、問題分析
題目鏈接:https://leetcode-cn.com/problems/route-between-nodes-lcci/submissions/
本質上就是一個圖的遍歷問題,這裏需要將原來的graph
數組變成鄰接表,接着遍歷該鄰接表,如果遍歷到target
節點即返回,同時設置已經遍歷過的節點vis
爲true
,表示已經訪問過了。代碼我已經進行了詳細的註釋,理解應該沒有問題。
2、問題解決
筆者以C++
方式解決。
#include "iostream"
using namespace std;
#include "algorithm"
#include "vector"
#include "set"
class Solution {
private:
// 設置最大的節點數
const static int MAXV = 100001;
// 定義鄰接 set ,注意這裏沒有使用 vector 因爲題目中有重複的邊
// 但是使用 vector 也是去遍歷,所以使用 set 也沒有影響
set<int> Adj[MAXV];
// 標記某個節點是否已經訪問過
bool vis[MAXV] = { false };
// 找到節點就快速退出,類似於剪枝
int flag = 0;
public:
bool findWhetherExistsPath(int n, vector<vector<int>> &graph, int start, int target) {
init(graph);
dfs(start, target);
return vis[target];
}
/**
* 初始化鄰接表 將題目中的二維數組轉化成鄰接表
* @param graph
*/
void init(const vector<vector<int>> &graph) {
for (int i = 0; i < graph.size(); ++i) {
// graph 中的元素類似於 [0,1], 這裏使得 1 存儲到 0 的鄰接矩陣中
Adj[graph[i][0]].insert(graph[i][1]);
}
}
// 深搜遍歷
void dfs(int u, int target) {
// 找到對應的節點,快速退出
if (u == target) {
// 設置該節點已經訪問過,即可以到達
vis[target] = true;
// 快速退出標誌
flag = 1;
return;
}
// 設置該節點已經訪問過,即可以到達
vis[u] = true;
//遍歷鄰接矩陣 即 set 集和
for (auto it = Adj[u].begin(); it != Adj[u].end(); it++) {
if (flag == 1) {
return;
}
int v = *it;
if (!vis[v]) {
dfs(v, target);
}
}
}
};
int main() {
// vector<vector<int>> graph = {{0, 1},
// {0, 2},
// {1, 2},
// {1, 2}};
vector<vector<int>> graph = { { 0, 1 },
{ 0, 2 },
{ 0, 4 },
{ 0, 4 },
{ 0, 1 },
{ 1, 3 },
{ 1, 4 },
{ 1, 3 },
{ 2, 3 },
{ 3, 4 } };
Solution *pSolution =
new Solution;
bool b = pSolution->findWhetherExistsPath(3, graph, 0, 2);
cout << b << endl;
system("pause");
return 0;
}
運行結果
有點菜,有時間再優化一下。
3、總結
書上的代碼直接運行絕大部分是對的,但是總有一些軟件的更新使得作者無能爲力。之前的API是對的,但是之後就廢棄了或修改了是常有的事。所以我們需要跟蹤源代碼。這只是一個小小的問題,如果沒有前輩的無私奉獻,很難想象我們自己一天能學到多少內容。感謝各位前輩的辛勤付出,讓我們少走了很多的彎路!
點個贊再走唄!歡迎留言哦!