刷题的日常-寻找图中是否存在路径

100 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第27天,点击查看活动详情

刷题的日常-2022年12月19号

一天一题,保持脑子清爽

寻找图中是否存在路径

来自leetcode的 1971 题,题意如下:

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

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

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

理解题意

通过题意,我们可以将信息整理如下:

  • 题目给出一个数组代表连线
  • 一个source表示出发点,destination代表目标点
  • 如果从出发点沿着路径一直走,能够达到目标点,返回true,否则返回false

做题思路

题目给出的连线是双向的,所以我们需要将双向的连线改为单向的,将所有的单向连线保存起来,然后从开始节点出发,一直往后走,如果能够碰到目标节点,返回true。这里需要注意的是,如果没有连线,需要做特殊判断,如果开始节点和目标节点是一样的,返回true,否则返回false。
需要注意的问题是,如果出现环形路径,要进行判断,否则会陷入死循环。

代码实现

代码实现如下:

public class Solution {
    public boolean validPath(int n, int[][] edges, int source, int destination) {
        if (edges.length == 0) {
            return source == destination;
        }
        HashMap<Integer, List<int[]>> sourceMap = new HashMap<>();
        for (int[] edge : edges) {
            List<int[]> tmp = sourceMap.computeIfAbsent(edge[0], o -> new ArrayList<>());
            tmp.add(edge);
            edge = new int[]{edge[1], edge[0]};
            tmp = sourceMap.computeIfAbsent(edge[0], o -> new ArrayList<>());
            tmp.add(edge);
        }
        List<int[]> sList = sourceMap.get(source);
        for (int[] start : sList) {
            if (match(start, destination, sourceMap)) {
                return true;
            }
        }
        return false;
    }
    private boolean match(int[] start, int destination, HashMap<Integer, List<int[]>> sourceMap) {
        Queue<int[]> queue = new ArrayDeque<>(sourceMap.size());
        queue.add(start);
        Set<int[]> set = new HashSet<>();
        while (!queue.isEmpty()) {
            start = queue.poll();
            if (set.contains(start)) {
                continue;
            }
            set.add(start);
            if (start[1] == destination) {
                return true;
            }
            List<int[]> tmp = sourceMap.get(start[1]);
            if (tmp != null) {
                queue.addAll(tmp);
            }
        }
        return false;
    }
}