news 2026/5/30 0:58:23

leetcode 困难题 815. Bus Routes 公交路线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
leetcode 困难题 815. Bus Routes 公交路线

Problem: 815. Bus Routes 公交路线

解题过程

抽象,不考虑站点的邻接表,更上一层的,考虑bus之间的邻接表

用每个站点做邻接表,然后用Dijkstra或者深度优先搜索dfs都超时了,或者超内存了。考虑到每辆bus在这个路径内都是联通的,所以每个bus做一个节点node,routes长度<500,每个bus写出邻接表,相比每个站点做邻接表,占用的内存大大减小,只需要考虑bus之间是否联通即可,不单独考虑站点之间。只要source所在的bus和target所在的bus是联通的即可,拿到最短路径就行了

bus之间是否相连的话,首先用哈希表存储每个站点的bus索引i的ump[routes[i][j]].insert(i);,这样每个站点的bus索引就拿到了,顺便存储source和target的索引,然后构造邻接表即可trr[p1].push_back(p2);, trr[p2].push_back(p1);。

因source可能存在于多个bus的索引内,所以从每个source可能的索引开始,都使用深度优先搜索,或者Dijkstra,这样target可能的索引的最短距离就是答案

Code

class Solution { public: vector<vector<pair<int, int>>> tr; vector<vector<int>> trr; vector<vector<bool>> status; unordered_map<int, int> ump; pair<int, int> point; int mi = INT_MAX; void dfs(vector<vector<int>>& routes, int source, int target, int ii, int jj) { int i, j, next; if(source == target) { mi = min(mi, (int)ump.size()); } status[ii][jj] = true; ump[ii]++; for(int k = 0; k < tr[source].size(); k++) { point = tr[source][k]; i = point.first; j = point.second; if(status[i][j] == false) { next = routes[i][j]; dfs(routes, next, target, i, j); } } status[ii][jj] = false; ump[ii]--; if(ump[ii]==0) { ump.erase(ii); } } unordered_set<int> tC, tmptmp; vector<int> ttCC; vector<bool> statusSTATUS; int minmin = INT_MAX; void dfsdfs(int start) { tmptmp.insert(start); if(tC.find(start) != tC.end()) { minmin = min(minmin, (int)tmptmp.size()); } statusSTATUS[start] = true; int next; for(int i = 0; i < trr[start].size(); i++) { next = trr[start][i]; if(statusSTATUS[next] == false) { dfsdfs(next); } } tmptmp.erase(start); statusSTATUS[start] = false; } int numBusesToDestination(vector<vector<int>>& routes, int source, int target) { if(source == target) return 0; trr.resize(routes.size()); statusSTATUS.assign(routes.size(), false); vector<int> sC; unordered_map<int, unordered_set<int>> ump; for( int i = 0; i < routes.size(); i++ ) { bool s = false, t = false; for( int j = 0; j < routes[i].size(); j++ ) { if(routes[i][j] == source) { sC.push_back(i); s = true; } if(routes[i][j] == target) { tC.insert(i); ttCC.push_back(i); t = true; } ump[routes[i][j]].insert(i); } // if(s == true && t==true) return 1; } unordered_set<int>::iterator it; unordered_map<int, vector<int>> umpump; for(auto [key, value] : ump) { for(it = value.begin(); it != value.end(); it++) { umpump[key].push_back(*it); } } int p1, p2; for(auto [key, value] : umpump) { for(int i = 0; i < value.size(); i++) { p1 = value[i]; p2 = value[(i+1)%(int)value.size()]; trr[p1].push_back(p2); trr[p2].push_back(p1); } } // for(int i = 0; i < sC.size(); i++) { // dfsdfs(sC[i]); // } // if(minmin==INT_MAX) return -1; // return minmin; // int ret = 0, mx = INT_MIN; // vector<pair<int, int>> sourceCOL; // for( int i = 0; i < routes.size(); i++ ) { // int n = routes[i].size(); // bool s = false, t = false; // for(int j = 0; j < n; j++) { // mx = max(mx, routes[i][j]); // if(routes[i][j]==source) s = true; // if(routes[i][j] == target) t = true; // if(s == true && t==true) return 1; // } // } // tr.resize(mx + 1); // for( int i = 0; i < routes.size(); i++ ) { // int n = routes[i].size(); // vector<bool> tmp(n, false); // status.push_back(tmp); // int p1, p2; // for(int j = 0; j < n; j++) { // p1 = routes[i][j]; // tr[p1].push_back(std::make_pair(i, (j+1)%n)); // // for(int k = j+1; k < n; k++) { // // p2 = routes[i][k]; // // tr[p1].push_back(std::make_pair(i, k)); // // tr[p2].push_back(std::make_pair(i, j )); // // } // if(routes[i][j] == source) { // sourceCOL.push_back({i, j}); // } // } // } // for(int i = 0; i < sourceCOL.size(); i++) { // dfs(routes, source, target, sourceCOL[0].first, sourceCOL[0].second); // } for(int ij = 0; ij < sC.size(); ij++) { vector<int> dis(routes.size()+1, INT_MAX); vector<bool> status(routes.size()+1, false); dis[sC[ij]] = 0; queue<vector<int>> qe; qe.push({0, sC[ij]}); int distance, next, start, i, j, d, mem; vector<int> tp; while(!qe.empty()) { tp = qe.front(); distance = tp[0]; start = tp[1]; qe.pop(); if(status[start] == true) continue; status[start] = true; for(int k = 0; k < trr[start].size(); k++) { next = trr[start][k]; if(status[next] == false && dis[next] > distance + 1) { qe.push({distance + 1, next}); dis[next] = distance + 1; } } } int jmi = INT_MAX; for(int j = 0; j < ttCC.size(); j++) { if(dis[ttCC[j]] != INT_MAX) { jmi = min(jmi, dis[ttCC[j]]); } } minmin = min(jmi, minmin); } if(minmin == INT_MAX) return -1; return minmin + 1; } };
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/26 16:44:26

非阻塞socket上getsockopt函数的使用要点及常见误解

在网络编程中&#xff0c;理解并正确使用非阻塞socket上的getsockopt函数&#xff0c;是确保程序行为可控、性能高效的关键。许多开发者误以为在非阻塞模式下&#xff0c;所有操作都变得简单&#xff0c;实际上&#xff0c;像getsockopt这样的“查询”操作也隐含着微妙的陷阱和…

作者头像 李华
网站建设 2026/5/27 6:21:46

探究comsol案例:水平井应力场耦合作用机制与实践应用

comsol案例水平井应力场耦合在青海某页岩气田的钻探现场&#xff0c;老张盯着实时监测屏幕上突然飙升的井口压力直挠头。这种地层应力突变导致套管变形的糟心事&#xff0c;搞石油工程的同行们应该都不陌生。今天咱们就扒一扒COMSOL里怎么玩转水平井应力场耦合&#xff0c;保准…

作者头像 李华
网站建设 2026/5/10 7:29:55

互联网大厂求职面试:从Spring Boot到微服务的全面考察

文章内容&#xff1a; 场景&#xff1a; 在一家知名互联网大厂的会议室里&#xff0c;面试官正准备对一位名叫“超好吃”的Java小白进行技术面试。面试官以严肃但鼓励的态度展开了这次面试。第一轮&#xff1a;基础技术与框架 面试官&#xff1a;"超好吃&#xff0c;欢迎你…

作者头像 李华
网站建设 2026/5/14 17:25:47

你的毕业论文,其实可以“自己长出来”——宏智树AI如何用真实数据与文献,让写作从焦虑变有序

大家好&#xff0c;我是专注论文写作科普的教育博主。每年指导学生写毕业论文&#xff0c;我总听到类似的话&#xff1a;“开题不会写”“文献看不完”“数据不会分析”“查重太高了”“答辩PPT怎么做&#xff1f;”……仿佛毕业论文是一场“孤勇者的苦修”。 但其实&#xff…

作者头像 李华
网站建设 2026/5/25 0:57:09

收藏!企业级大模型AI应用爆发:程序员必学的落地技能与实战案例

大模型AI应用在消费级市场的爆发&#xff0c;已引发各界广泛关注。 不论是ChatGPT带动的第一波浪潮&#xff0c;还是DeepSeek之后更多中国大模型AI应用的涌现&#xff0c;从AI智能助手到AI陪伴应用&#xff0c;再到AI在各个领域的产品&#xff0c;应用层在全面爆发。 但实际上&…

作者头像 李华
网站建设 2026/5/25 16:04:45

python农业农产品果蔬种植销售商城一体化服务平台含商家_gcr95_django Flask vue pycharm项目

目录 已开发项目效果实现截图关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 已开发项目效果实现截图 同行可拿货,招校园代理 ,本人源头供货商 python农业农产品果蔬种植销售商城…

作者头像 李华