您的位置:首页 > 职场人生

Google面试题 图论的问题

2018-03-19 03:56 239 查看
这道题目摘自九章算法   https://www.jiuzhang.com/article/6ai0yN/
题目是



输入与输出



这个题目本质上就是删除一个使该图内部成环的一条边,使整个图中不存在环。
这个题目我认为原文的解释有点复杂,最快的方法就是操作数组,角标代表一个顶点,角标所对应的数组的数值代表一个顶点,而角标到该角标数值的对应,我们认为是角标代表的顶点到这个数值代表的顶点的一个连接。

而我们要做的,就是将输入的边连接的顶点,通过一个数组表示出来。
具体的过程可以参考一本国外的算法书,叫 algorithm。
其中的quick find 和quick union 讲的就是怎么要操作数组来表示一棵树



然后我抽空写了一个代码小样:
package FinalStruggle;

/**
* Created by zhoumeng on 2018/3/18.
*/
public class ExtraEdge {
public static void main(String[] args){
int[][] que = {{1,2},{2,3},{3,4},{1,4},{1,5}};
int[] extra = findExtraEdge(que);
if (extra==null){
System.out.println("404");
}else{
System.out.println("{"+extra[0]+", "+extra[1]+"}");
}
}
private static int[] findExtraEdge(int[][] que){
int N = que.length;
int [] vertexes = new int[N+1];
for (int i = 1; i<=N; i++){
vertexes[i] = i; // every vertex connects itself initially
}
for(int[] edge: que){
int left = edge[0];
int right = edge[1];
// now we need to find the circle
int l_root = findRootNode(vertexes, left);
int r_root = findRootNode(vertexes, right);

if (l_root==r_root){
return edge;
}else{
vertexes[l_root] = vertexes[right];
}
}
return null;
}

private static int findRootNode(int[] vertexes, int index) {
while (vertexes[index]!=index){
index = vertexes[index];
}
return index;
}
}
其中, findRootNode 和原文中的想法有点不一样。
在原文中,他用了一个递归,通过每次将得到的root值返回赋予当前节点这个操作,我们可以把所有连接到相同根结点角标所对应的值,都改成该根结点的角标值,这样方便之后的查找工作。
但是,这样有个缺点就是,我们没有办法知道整个树的层次,只能知道某个节点的根结点,所以代码解决的问题比较专项。
至于两相比较,时间复杂度的问题,原链接中给的代码,通过每次查询都进行值的更改,来获取下一次查询的最优状态,所以原数组的时间复杂度很稳定。我的代码,可能会形成比较深的树,在之后多次重复查询的过程中,可能会更加耗时一些。至于非常精确的时间计算,可以参考我刚才提到的algrithm一书,我记得上边给出了调用方法消耗的时间,更改数值消耗的时间和查询一次需要的时间。
因为手头暂时没有资料,而且最近真的好忙,所以没有给出具体的数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: