176.Route Between Two Nodes in Graph-图中两个点之间的路线(中等题)

本文介绍了一种基于广度优先搜索(BFS)算法来判断有向图中两点间是否存在路径的方法。通过使用队列数据结构,从起点出发逐层遍历其邻居节点,直至找到目标节点或遍历所有可达节点。

图中两个点之间的路线

  1. 题目

    给出一张有向图,设计一个算法判断两个点 s 与 t 之间是否存在路线。

  2. 样例

    如下图:
    这里写图片描述
    for s = B and t = E, return true
    for s = D and t = C, return false

  3. 题解

    直接使用BFS就可以了,如从起始节点开始,应依次先访问这个节点所指向的其他节点,也就是neigbors中存储的节点,再继续访问neigbors节点的neigbors,数据结构选用队列。

/**
 * Definition for Directed graph.
 * class DirectedGraphNode {
 *     int label;
 *     ArrayList<DirectedGraphNode> neighbors;
 *     DirectedGraphNode(int x) {
 *         label = x;
 *         neighbors = new ArrayList<DirectedGraphNode>();
 *     }
 * };
 */
public class Solution {
   /**
     * @param graph: A list of Directed graph node
     * @param s: the starting Directed graph node
     * @param t: the terminal Directed graph node
     * @return: a boolean value
     */
    public boolean hasRoute(ArrayList<DirectedGraphNode> graph, 
                            DirectedGraphNode s, DirectedGraphNode t) {
        if (s == t)
        {
            return true;
        }

        HashSet<DirectedGraphNode> visited = new HashSet<DirectedGraphNode>();
        Queue<DirectedGraphNode> queue = new LinkedList<DirectedGraphNode>();

        queue.offer(s);
        visited.add(s);
        while (!queue.isEmpty()) 
        {
            DirectedGraphNode node = queue.poll();
            for (int i = 0; i < node.neighbors.size(); i++) 
            {
                if (visited.contains(node.neighbors.get(i))) 
                {
                    continue;
                }
                visited.add(node.neighbors.get(i));
                queue.offer(node.neighbors.get(i));
                if (node.neighbors.get(i) == t) 
                {
                    return true;
                }
            }
        }

        return false;
    }
}

Last Update 2016.10.25

<template> <div class="project-list"> <div class="search"> <div class="search-left"> <el-form :inline="true" :model="query" ref="queryRef"> <el-form-item prop="" label="项目名称"> <el-input placeholder="请输入" clearable /> </el-form-item> <el-form-item prop="" label="所属区域"> <el-select placeholder="请选择" clearable> <el-option label="Zone one" value="shanghai" /> <el-option label="Zone two" value="beijing" /> </el-select> </el-form-item> <el-form-item> <el-button type="primary" icon="Search" @click="onSearch">查询</el-button> <el-button icon="Refresh" @click="onReset">重置</el-button> </el-form-item> </el-form> </div> <div class="search-button"> <el-button type="primary" icon="Plus">新增项目</el-button> </div> </div> <div class="list"> <el-scrollbar height="calc(100vh - 280px)"> <div class="list-wrapper"> <div class="list-box" v-for="item in list" :key="item.id"> <div class="list-left"> <div class="list-img"> <img :src="getUrl(item.ossId)" alt="" /> </div> <div class="list-content"> <div class="list-title">{{item.title}}</div> <div class="list-time">2025-07-31 00:00:00</div> </div> </div> <div class="list-right"> <div class="list-icon" @click="onEdit(item)"> <el-button icon="Edit" class="gradient-button-blue" circle /> </div> <div class="list-icon" @click="onPreview(item)"> <el-button icon="Document" class="gradient-button-green" circle /> </div> <div class="list-icon" @click="onShare(item)"> <el-button icon="Share" class="gradient-button-purple" circle /> </div> <div class="list-icon"> <el-button icon="Delete" class="gradient-button-red" circle /> </div> </div> </div> </div> </el-scrollbar> </div> <div class="pagination"> <el-pagination v-model:current-page="page.page" v-model:page-size="page.limit" :page-sizes="[10, 20, 30, 40, 50, 100]" background layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="onSizeChange" @current-change="onCurrentChange" /> </div> <el-dialog v-model="viewerVisible" title="预览" width="95%" top="10px"> <div class="viewer-wrapper"> <Viewer v-if="viewerVisible" :data="viewerData"></Viewer> </div> <template #footer> <div class="dialog-footer"> <el-button @click="viewerVisible = false">关闭</el-button> </div> </template> </el-dialog> <div class="copy-toast" v-if="showCopyToast">链接已复制</div> </div> </template> <script setup> import { ref, reactive, toRaw, computed } from "vue"; import useTable from "@/hooks/useTable"; import { useRouter } from "vue-router"; import Viewer from "@/views/project/project-edit/viewer/index.vue"; import useNodes from "../project-edit/data/useNodes"; import useMarker from "../project-edit/data/useMarker"; const { getSaveMarkerOptionsList } = useMarker(); const { angleList, getSaveNodeOptionsList, transitionLogo } = useNodes(); import * as api from "@/api/project/project-list"; import { getUrl } from "@/api/project/attachment"; const router = useRouter(); const viewerVisible = ref(false); let viewerData = reactive({}); const showCopyToast = ref(false); const queryRef = ref(null); const query = ref({}); const list = ref([]); const { total, page, onSizeChange, onCurrentChange, reload } = useTable((page) => { return new Promise((resolve, reject) => { api.list({ // ...query.value, ...page, }) .then((res) => { resolve({ list: res.data, total: res.count }); list.value = res.data; }) .catch(reject); }); }); const onSearch = () => { reload(); }; const onReset = () => { queryRef.value.resetFields(); reload(); }; const onEdit = (item) => { router.push({ path: "/project-edit", query: { id: item.id, }, }); }; const onShare = (data) => { viewerData = getSaveData(data); copyLink(); }; const shareUrl = computed(() => { const base = window.location.origin; console.log(viewerData); // 关键步骤:将对象转为 JSON 字符串,再进行 URL 编码 const dataStr = encodeURIComponent(JSON.stringify(viewerData)); console.log(JSON.stringify(viewerData)); return `${base}/project-share?data=${dataStr}`; }); // 复制链接到剪贴板 const copyLink = () => { const url = shareUrl.value; if (!url) { console.warn("没有可复制的链接"); return; } // 创建临时 textarea 元素(避开 clipboard API 限制) const textarea = document.createElement("textarea"); textarea.value = url; // 设置要复制的内容 textarea.style.position = "fixed"; // 固定定位,避免影响页面布局 textarea.style.left = "-9999px"; // 隐藏元素 textarea.style.top = "-9999px"; // 添加到页面并选中内容 document.body.appendChild(textarea); textarea.select(); // 选中文本 textarea.setSelectionRange(0, url.length); // 兼容移动设备 try { // 执行复制命令 const success = document.execCommand("copy"); if (success) { showCopyToast.value = true; setTimeout(() => (showCopyToast.value = false), 2000); } else { throw new Error("复制失败"); } } catch (err) { console.error("复制失败:", err); alert(`复制失败,请手动复制:\n${url}`); // 失败时提示手动复制 } finally { // 无论成功否,移除临时元素 document.body.removeChild(textarea); } }; const onPreview = (data) => { viewerData = getSaveData(data); viewerVisible.value = true; }; const getSaveData = (data) => { const markerOptionsList = getSaveMarkerOptionsList(); const nodeOptionsList = getSaveNodeOptionsList(); return { markers: markerOptionsList, nodes: nodeOptionsList, angle: toRaw(angleList), transitionLogo: transitionLogo.value, imageId: data.id, }; }; </script> <style lang="scss" scoped> .project-list { width: 100%; height: 100%; padding: 20px; border: 1px solid #eee; border-radius: 10px; box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.2); .search { display: flex; justify-content: space-between; .el-input, .el-select, .el-date-editor { width: 200px; } } .list-wrapper { padding: 20px 0; display: flex; align-items: center; flex-wrap: wrap; .list-box { padding: 20px; display: flex; justify-content: space-between; width: 49%; background: linear-gradient(to right, #c3e7ff, #e8f7fe); border-radius: 10px; margin-bottom: 2%; margin-right: 1%; &:nth-child(2n) { margin-right: 0; } .list-left { display: flex; justify-content: space-between; align-items: center; .list-img { width: 100px; height: 50px; margin-right: 20px; img{ width: 100%; height: 100%; } } .list-title { font-size: 16px; font-weight: 800; } .list-time { font-size: 12px; color: #666; margin-top: 20px; } } .list-right { display: flex; align-items: center; .list-icon { margin-left: 20px; &:nth-child(1) { margin-left: 0; } } } } } .pagination { margin-top: 20px; display: flex; justify-content: center; align-items: center; } } .copy-toast { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: rgba(0, 0, 0, 0.7); color: white; padding: 8px 16px; border-radius: 4px; animation: fade 2s; } </style> 现在这个页面的分享链接传的数据特别多能改善吗
最新发布
08-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值