题目描述
git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常常需要寻找两个分支最近的分割点,即base.假设git 树是多叉树,请实现一个算法,计算git树上任意两点的最近分割点。 (假设git树节点数为n,用邻接矩阵的形式表示git树:字符串数组matrix包含n个字符串,每个字符串由字符'0'或'1'组成,长度为n。matrix[i][j]=='1'当且仅当git树种第i个和第j个节点有连接。节点0为git树的根节点。)
解题思路:
根据题目描述,可以基本判断出题目原型求出指定顶点到指定顶点的路径,然后对比两个路径中第一个分叉点。根据题目类型,可以判断出应该是图中的广度搜索算法。然后获得各自路径,再进行对比
代码:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Stack;
public class Solution {
private List<List<Integer>> adj; //用来存储顶点位置
boolean[] marked;//用来标记该顶点是否搜索过
int[] parent;//相当于广度搜索中保存该顶点的上一个路径,也就相当于本题的父节点
public static void main(String[] args){
String[] str={"0100000","1010000","0101100","0010011","0010000","0001000","0001000"};
int indexA=5;
int indexB=6;
Solution s=new Solution();
int result= s.getSplitNode(str,indexA,indexB);
System.out.println(result);
}
/**
* 返回git树上两点的最近分割点
*
* @param matrix 接邻矩阵,表示git树,matrix[i][j] == '1' 当且仅当git树中第i个和第j个节点有连接,节点0为git树的跟节点
* @param indexA 节点A的index
* @param indexB 节点B的index
* @return 整型
*/
public int getSplitNode(String[] matrix, int indexA, int indexB) {
init(matrix);
bfs(0);
Stack<Integer> path1=getPath(0,indexA);
Stack<Integer> path2=getPath(0,indexB);
int prev=0;
int now=0;
if(path1!=null &&path2!=null){
int length=Math.min(path1.size(), path2.size());
for(int i=0;i<length;i++){
if((now=path1.pop()) != path2.pop()){
break;
}
prev=now;
}
}
return prev;
}
//初始化输入,
public void init(String[] matrix){
adj=new ArrayList<List<Integer>>(matrix.length);
for(int i=0;i<matrix.length;i++){
String str=matrix[i];
List<Integer> points=new ArrayList<Integer>();
int index=0;
for(char c:str.toCharArray()){
if(c=='1'){
points.add(Integer.valueOf(index));
}
index++;
}
adj.add(points);
}
marked=new boolean[adj.size()];
parent=new int[adj.size()];
}
//广度搜索算法的主要体现,将根节点输入
private void bfs(int s){
Queue<Integer> queue=new LinkedList<Integer>();
queue.add(s);
marked[s]=true;
while(!queue.isEmpty()){
Integer num=queue.poll();
for(Integer edgePoint: adj.get(num)){
if(!marked[edgePoint]){
parent[edgePoint]=num;
marked[edgePoint]=true;
queue.add(edgePoint);
}
}
}
}
//获得从指定路径到指定路径的整条线路
private Stack<Integer> getPath(int from ,int to){
if(!marked[to]){
return null;
}
Stack<Integer> path=new Stack<Integer>();
for(int x=to ;x!=from;x=parent[x]){
path.add(x);
}
path.add(from);
return path;
}
}
265

被折叠的 条评论
为什么被折叠?



