LeetCode:一些图的题目

首先第一反应其实是把每个点当作根节点,然后找到最远的叶子节点的距离。这样超时。
然后就应该想到bfs,而且是从“终点”开始的bfs(这道题“终点”就是叶子节点)。每次淘汰一批一批的,快得多。
class Solution {
public:
vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
vector<set<int>> adj(n, set<int>());
for (auto& vec : edges) {
adj[vec[0]].insert(vec[1]);
adj[vec[1]].insert(vec[0]);
}
queue<int> q;
for (int i = 0; i < n; ++i)
if (adj[i].size() == 1)
q.push(i);
set<int> ret;
for (int i = 0; i < n; ++i)
ret.insert(i);
while (ret.size() > 2) {
int cnt = q.size();
while (cnt-- > 0) {//因为会随时补充新的叶子进来,所以不能以非空为条件,不然会停不下来
int idx = q.front();
q.pop();
ret.erase(idx);
for (int i : adj[idx]) {
adj[i].erase(idx);
if (adj[i].size() == 1)
q.push(i);
}
}
}
return vector<int>(ret.begin(), ret.end());
}
};

这一题是隐形的图的题目。
每两个只有一个字符不同的字符串之间有一道边连接着(但是不要像平常那样把邻接表写出来,有点浪费时间)。
以后看到这种“最少需要几步”的类似的题目,就要想到是不是图,用bfs的方法(这一题是从开始点开始bfs,而不是终点)
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
unordered_set<string> dict(wordList.begin(), wordList.end());
queue<string> q;
int ladder = 1;
if (dict.find(endWord) == dict.end())
return 0;
q.push(beginWord);
while (!q.empty()) {
int cnt = q.size();
while (cnt-- > 0) {
string word = q.front();
q.pop();
if (word == endWord)
return ladder;
dict.erase(word);
for (int i = 0; i < word.size(); ++i) {
char c = word[i];
for (int j = 0; j < 26; ++j) {
word[i] = 'a' + j;
if (dict.find(word) != dict.end())
q.push(word);
}
word[i] = c;
}
}
++ladder;
}
return 0;
}
};
//寻找变了一个字母的string难找,就用set来找,降低时间
//可以认为有隐形的边连接着两个只有一个字母不同的string
//最少要几步肯定是bfs啦
另外还有图的题目:之前那个把树看成图的题目863 https://blog.csdn.net/weixin_43462819/article/details/100067781
反正以后看到这种类似距离为多少,最短距离的,都要想到bfs。
dfs是自己的惯常想法,不需要特别提醒了。
浙公网安备 33010602011771号