昨天day16做了一道二叉树的翻转,迭代或者递归都行,很简单没啥好说的。
今天这个并查集…我反省,我没看出来。
给你一棵有n个节点,n条边的树,让你找出那条多余的边。
考虑有两种情况:
1、冲突。即有一个点有两个父亲。这个可以统计每个点的入度,也可以在union的时候判断一下是不是已经有父节点了
2、成环。这里用到并查集,连接两个点的时候看看它们是不是已经连上了【这里应该能看出来是并查集的】
那么就可能出现三种情况:
1、只成环。删掉最后一条成环的边即可。
2、只冲突。删掉最后一条起冲突的边即可。
3、既冲突又成环,删掉有两个父节点的那个点成环的那条边。
有些思考难度,我觉得重点在于发现有冲突和成环两种情况。
class Solution {
public:
int father[1005]; //全局变量
int find(int x)
{
if (father[x] != x) return find(father[x]);
return father[x];
}
void unionn(int u, int v)
{
//u = find(u);
//v = find(v);
father[v] = u;
}
int judge(int u, int v)
{
int x = find(u), y = find(v);
if (x == y) return 0;
if (y != v) return 1;
return 2;
}
vector<int> findRedundantDirectedConnection(vector<vector<int>>& edges) {
int size = edges.size();
vector<int> ans;
vector<int> colli;
bool isColli = false;
bool isLoop = false;
for (int i = 0; i < size; i++)
{
father[edges[i][0]] = edges[i][0];
father[edges[i][1]] = edges[i][1];
}
for (int i = 0; i < size; i++)
{
if (judge(edges[i][0], edges[i][1]) == 2)
{
unionn(edges[i][0], edges[i][1]);
//printf("%d %d\n", edges[i][0], edges[i][1]);
}
else if (judge(edges[i][0], edges[i][1]) == 1)
{
colli = edges[i];
isColli = true;
//unionn(edges[i][0], edges[i][1]);
}
else
{
ans = edges[i];
isLoop = true;
}
}
if (isColli == false) return ans;
if (isLoop == false) return colli;
ans = {father[colli[1]], colli[1]};
return ans;
}
};
写起来不是很难,注意我的union函数以前是带路径压缩的【路径压缩也可以写在find函数里,让father[v] = find(father[v])】,但是在这道题里面因为它的边还是有用的,所以你不能改变它。
并查集还有一种优化方法是按秩合并,思想是维护每个节点作为根的那棵子树的高度,然后合并的时候总是把较矮的那棵树合并到较高的那棵树上,以后find的时候就会减少次数。这道题因为是有向边所以也不能用。不过我好像也从来没用过按秩合并,它相当于把迭代次数限定在logN以内,如果不这样的话查找可能是O(N)的,可能时间卡的比较紧,空间比较松的题就必须写了。
p.s. 今天上了第一节程序设计实验课,在课上把Ubuntu配置的差不多能用了嘿嘿 打算以后学习都用Ubuntu 不过还有好多要学的TvT 还遇见了很好的助教老师,感觉懂很多可以请教很多问题的样子。指针读到3/10了,了解了一点点系统栈的知识,之前递归和迭代有点不懂的现在竟然懂了hhh 马上就详写读书笔记!
昨天看了学姐的微博,说每天不刷题背书10小时以上就是白过,所以我也把每天学习10h以上作为一个小目标。现在已经尽量把一切空闲时间都用来学习了,不过提高效率还是能再挤出来两三个小时【想到了鲁迅hhh】
说起来鲁迅,最近对我有些影响的一件事是在图书馆偶然翻到了《管锥编》,发现每一页上我能认识的字不超过一半_(:з」∠)_ 人与人的差距真的比人和猪还大qnq 现在坚定信念觉得过去的事情已经过去了,但是未来确确实实还把握在我自己手里。也许…再学个几十年就能看懂《管锥编》了呢(x
好巧不巧,今天Momentum给的名言是说每天如果没有欢笑的话就是白过hhhhh感觉是和学姐有些不同的处世态度。可是学习10h是自己能控制的,欢笑不是呀。
话说最近听了几个很有意思的课,有点想把听课感想也写在csdn,不过和编程半毛钱关系没有嘿嘿