面试题 04.01. 节点间通路(C++|DFS|队列|unordered_set)

题目链接:力扣

题目描述

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

示例1:

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

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

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

果果念

又是涨知识的一天(不是,补算法中....)。今天下午上了高级算法课,讲到了DFS和BFS,今天晚上刷了一道leetcode题目,本来想多刷几道呢,无奈快乐的时光美好而又短暂(不是,自己太菜了...),下面分享一下这道题目。

还没有遇到过一些面试或者机试考图论的,但是基础的深搜和广搜应该是需要掌握的,我发现自己的基础太差了,这几天也不敢投简历了。上次的堆排序和快速排序今天又看了一下,也敲了一下,多多思考,会有收益哒。

关于这道题目,就是一个很经典的深搜题目,广搜应该也可以做吧。主要说一下两点:

  • 第一点:关于集合,我还是第一次使用stl中的集合,unordered_set,集合中的性质就是不可以插入同样的元素,也就是唯一性。因为这道题目是有向图,而且还可能存在平行边,因此,这里使用vector<unordered_set<int>> edge,edge.resize(n),建立边。
  • 第二点:标记数组,这个标记数组的作用是为了避免环,这里也使用了STL自带的unordered_set<int> visted,利用visted.count(v)>0判断v是否已经被访问过,也就是这个集合是否包含v,visted.insert(v),访问v。

拓:我利用了队列记录了访问的顺序,嘻嘻。

unordered_set:元素内部没有排序,基于哈希表;

set:基于红黑树实现,有序的。

刚刚喝了一杯真果粒,不是广告,好开心啊。

代码

class Solution {
public:

    vector<unordered_set<int>> edge;//边
    unordered_set<int> visited;//标记数组,标记走过的顶点
    queue<int> path;//标记路径

    bool dfs(int start, int target){
        
        //已经走过这个定点了,别尝试了,我的宝
        // cout<<visited.count(start)<<endl;
        if(visited.count(start)){
            return false;
        }

        //我的宝儿,你成功了
        if(start==target) return true;

        visited.insert(start);

        for(auto &v:edge[start]){
            //我的宝儿,有一个走通,就代表存在通路呀
            path.push(v);
            if(dfs(v,target)){
                return true;
            }
            path.pop();
        }
        return false;
    }
    bool findWhetherExistsPath(int n, vector<vector<int>>& graph, int start, int target) {
        //节点编号 0~4
        edge.resize(n);//n个顶点
        for(auto &e:graph){
            edge[e[0]].insert(e[1]);//去掉平行边
        }
        bool ans=dfs(start,target);
        // cout<<path.size()<<endl;
        while(path.empty()!=true){
            // cout<<path.front()<<endl;
            path.pop();
        }
        return ans;
    }
};

c++ set与unordered set的区别 - 阿玛尼迪迪 - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值