C++中vector存储的pair元素无法更新引发死循环问题求解
pair无法更新的根本原因
你原来的代码里auto start = map[A[0]]属于值拷贝赋值:unordered_map的[]运算符虽然返回存储值的左值引用,但使用非引用类型的变量接收时,会调用vector的拷贝构造函数生成一个完全独立的副本存在栈上。后续对start内部元素的所有修改都只作用在这个临时副本上,完全不会同步到map中存储的原始vector数据。
每次循环到start = map[dst]时,又会重新从map里拷贝一份未修改的原始数据,标记位永远是默认的'r',就会反复命中同一条边,触发无限循环。你把start改成引用类型后,直接绑定到map中存储的原始vector对象,修改就会直接生效,问题自然解决。
更优的实现方案
这个需求本质是带字典序约束的欧拉路径查找问题(也就是经典的重新安排行程问题),可以直接用Hierholzer算法实现,不需要额外存储边的使用标记,代码更简洁,执行效率也更高。
优化点说明:
- 移除额外的标记位
'r'/'b',用边出栈的方式直接标记已使用,减少内存开销和无效遍历 - 用栈迭代实现Hierholzer算法,避免递归栈溢出风险,性能更稳定
- 无需每次遍历找未使用的边,直接取排序后的最后一条边即可满足字典序要求
#include <vector> #include <string> #include <unordered_map> #include <algorithm> #include <stack> using namespace std; vector<string> solve(vector<string> A, vector<string> B) { if (A.empty() || B.empty() || A.size() != B.size()) return {}; // 构建邻接表 unordered_map<string, vector<string>> adj; for (int i = 0; i < A.size(); ++i) { adj[A[i]].push_back(B[i]); } // 对每个出发地的目的地按字典序升序排序 for (auto& item : adj) { sort(item.second.begin(), item.second.end()); } stack<string> stk; vector<string> res; stk.push(A[0]); while (!stk.empty()) { string cur = stk.top(); if (adj.count(cur) && !adj[cur].empty()) { // 取排序后的最后一个元素,后续逆序后会按升序排列 string next = adj[cur].back(); adj[cur].pop_back(); stk.push(next); } else { stk.pop(); res.push_back(cur); } } // 反转得到从出发到终点的正确路径 reverse(res.begin(), res.end()); return res; }
内容的提问来源于stack exchange,提问作者Adeeb HS
相关产品推荐
相关产品推荐

