Leetcode 1971. 寻找图中是否存在路径

该博客讨论了一个关于无向图的问题,其中需要确定是否存在从特定源节点到目标节点的有效路径。作者提供了两种解决方案,一种是直接使用广度优先搜索(BFS)的简单实现,另一种是通过构建图的节点和边类来解决。第一种方法的运行时间更优,而第二种方法虽然内存消耗较大,但展示了图的数据结构应用。
摘要由CSDN通过智能技术生成

题目描述:

有一个具有 n 个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。

请你确定是否存在从顶点 source 开始,到顶点 destination 结束的 有效路径 。

给你数组 edges 和整数 n、source 和 destination,如果从 source 到 destination 存在 有效路径 ,则返回 true,否则返回 false 。

LevelAC rate
Easy54.0%

题目解析:

简单的无向图论,使用一个队列从起点开始实现广度搜索,当搜索到终点时返回true,如果搜索完都没有到达终点的位置需要返回false,注意,这里需要使用一个hashset来进行已经搜索点的存储,防止重复搜索进行死循环,代码如下:

class Solution {
public:
    bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
        if(source==destination)return true;
        unordered_set<int> uset;
        uset.emplace(source);
        deque<int> dl;
        dl.push_back(source);
        while(!dl.empty()){
            int temp = dl.front();
            dl.pop_front();
            for(int i = 0 ; i < edges.size() ; i++){
                if(edges[i][0] == temp){
                    if(edges[i][1]==destination)return true;
                    if(!uset.count(edges[i][1])){
                        uset.emplace(edges[i][1]);
                        dl.push_back(edges[i][1]);
                    }
                }
                if(edges[i][1] == temp){
                    if(edges[i][0]==destination)return true;
                    if(!uset.count(edges[i][0])){
                        uset.emplace(edges[i][0]);
                        dl.push_back(edges[i][0]);
                    }
                }   
            }
        }
        return false;
    }
};

执行用时:368 ms, 在所有 C++ 提交中击败了52.80%的用户

内存消耗:107.2 MB, 在所有 C++ 提交中击败了98.73%的用户

前几天学了一点图论,照着写了一个模板,想着看看这道题能不能通过套用模板进行求解,所以有第二个方法,有两个类,分别是node类和edge类进行结点和边的存储,Node类有三个属性,value为当前结点的值,in为入度,out为出度,在无向图中in=out,edge类也有三个属性,weight为边的权重值,from为边的起点,to为边的终点,在无向图中,from=to,代码如下(过几天会把图论的知识点总结一下发出来):

class Solution {
public:
    class Edge;

    class Node{
    public:
        int value;
        int in;
        int out;
        list<Node*> nexts;
        list<Edge*> edges;
        Node(int val) {
            value = val;
            in = 0;out = 0;
        }
    }; 

    class Edge {
    public:
        int weight;
        Node* from;
        Node* to;
        Edge(int wei,Node* fr,Node* t) {
            weight=wei;
            from = fr;
            to = t;
        }  
    };

    class Graph{
    public:
        unordered_map<int , Node*> nodes;
        unordered_set<Edge*> edges;
        Graph(){}
    };

    bool validPath(int n, vector<vector<int>>& edges, int source, int destination) {
        if(source == destination)return true;
        Graph graph;
        for(int i = 0 ; i < edges.size() ; i++){
            if(graph.nodes.find(edges[i][0])==graph.nodes.end()){
                Node* temp = new Node(edges[i][0]);
                graph.nodes[edges[i][0]] = temp;
            }
            if(graph.nodes.find(edges[i][1])==graph.nodes.end()){
                Node* temp = new Node(edges[i][1]);
                graph.nodes[edges[i][1]] = temp;
            }
            graph.nodes[edges[i][0]]->nexts.push_back(graph.nodes[edges[i][1]]);
            graph.nodes[edges[i][1]]->nexts.push_back(graph.nodes[edges[i][0]]);
        }
        deque<int> dl;
        dl.push_back(source);
        unordered_set<int> uset;
        uset.emplace(source);
        while(!dl.empty()){
            int temp = dl.front();
            dl.pop_front();
            for(auto node : graph.nodes[temp]->nexts){
                int cur = node->value;
                if(cur == destination) return true;
                if(!uset.count(cur)){
                    dl.push_back(cur);
                    uset.emplace(cur);
                }
            }
        }
        return false;
    }
};

执行用时:608 ms, 在所有 C++ 提交中击败了18.07%的用户

内存消耗:209.1 MB, 在所有 C++ 提交中击败了9.68%的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值