LeetCode 面试题 04.01. 节点间通路

本文介绍了如何使用C++和Java解决LeetCode上的一道图类型问题,即判断两个节点间是否存在路径。文章详细解析了深度优先搜索(DFS)和广度优先搜索(BFS)两种方法,通过构建邻接表并利用visited数组避免重复访问,最终找到目标节点。这两种算法在处理图结构问题时各有优势,可以灵活运用。
摘要由CSDN通过智能技术生成

好久没做过图类型的题了,这是在LeetCode上的第一道图的题。

题目

节点间通路。给定有向图,设计一个算法,找出两个节点之间是否存在一条路径。

示例

输入:n = 3, graph = [[0, 1], [0, 2], [1, 2], [1, 2]], start = 0, target = 2
输出:true

提示:

  • 节点数量n[0, 1e5]范围内。
  • 节点编号大于等于 0 小于 n
  • 图中可能存在自环和平行边。

思路

方法一:DFS

  1. map创建一个领接表,
  2. visited标记访问过的节点
  3. dfs通过入口start遍历每一种可能

方法二:BFS

  1. map创建一个领接表
  2. visited标记访问过的节点
  3. 创建queue队列进行bfs遍历

C++代码

class Solution {
private:
    //方法一:dfs
    //用map存储领接表,比用动态数组下标耗费空间小
    unordered_map<int, vector<int> > map;
    vector<bool> visited;
public:
    bool findWhetherExistsPath(int n, vector<vector<int>>& graph, int start, int target) {
        visited.resize(n,false);
        //存储领接表
        for(auto& g : graph) {
            map[g[0]].emplace_back(g[1]);
        }
        return dfs(start, target);
    }
    bool dfs(int start, int target) {
        if(start == target) return true;
        //如果访问过了就相当于找不到,返回false
        if(visited[start]) return false;
        //标记start行,表示访问过了
        visited[start] = true;
        //遍历start行,dfs深搜找target
        for(auto& ms : map[start]) {
            if(dfs(ms, target)) return true;
        }
        return false;
    }
};

class Solution {
public:
    bool findWhetherExistsPath(int n, vector<vector<int>>& graph, int start, int target) {
        //方法二:bfs
        //用map存储领接表,比用动态数组下标耗费空间小
        unordered_map<int, vector<int> > map;
        vector<int> visited(n,false);
        //存储领接表
        for(auto& g : graph) {
            map[g[0]].emplace_back(g[1]);
        }
        queue<int> q;
        q.push(start);
        while(!q.empty()) {
            int top = q.front(); q.pop();
            if(top == target) return true;
            visited[top] = true;
            for(auto& ms : map[top]) {
                if(!visited[ms])
                    q.push(ms);
            }
        }
        return false;
    }
};

Java代码

//dfs
class Solution {
    Map<Integer, List<Integer>> map = new HashMap<>();
    boolean[] visited;
        
    public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
        visited = new boolean[n];
        for(int[] g : graph) {
            if(!map.containsKey(g[0])) {
                //创建有key的空列表
                map.put(g[0], new ArrayList<>());
            }
            map.get(g[0]).add(g[1]);
        }
        return dfs(start, target);
    }
    boolean dfs(int start, int target) {
        if(start == target) return true;
        if(visited[start]) return false;
        visited[start] = true;
        //Java需要注意的点,防止map.get(key)空指针异常
        if(map.get(start) == null) return false;
        for(Integer ms : map.get(start)) {
            if(dfs(ms, target)) return true;
        }
        return false;
    }
}
//bfs
class Solution {
    public boolean findWhetherExistsPath(int n, int[][] graph, int start, int target) {
        Map<Integer, List<Integer>> map = new HashMap<>();
        boolean[] visited = new boolean[n];
        LinkedList<Integer> q = new LinkedList<>();
        for(int[] g : graph) {
            if(!map.containsKey(g[0])) {
                map.put(g[0], new ArrayList<>());
            }
            map.get(g[0]).add(g[1]);
        }
        q.add(start);
        while(!q.isEmpty()) {
            int top = q.pop();
            visited[top] = true;
            if(top == target) return true;
            if(map.get(top) == null) continue;
            for(Integer mt : map.get(top)) {
                if(!visited[mt])
                    q.add(mt);
            }
        }
        return false;
    }
}
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只小逸白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值