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树的根节点。)
示例1
输入
[01011,10100,01000,10000,10000],1,2
输出
1
import java.util.ArrayList; import java.util.List; import java.util.Stack; public class gitTree { public static void main(String[] args) { // TODO Auto-generated method stub // String[] str={"01011","10100","01000","10000","10000"}; // String[] str={"01100","10011","10000","01000","01000"}; String[] str={"01","10"}; // String[] str={"010000","100111","000010","010000","011000","010000"}; int node=getSplitNode(str,1,1); System.out.println(node); } public static int getSplitNode(String[] matrix, int indexA, int indexB) { //如果查找节点相同,返回该节点本身。 if(indexA==indexB){ return indexA; } //如果查找的节点不相等,执行以下操作 int tmp=0; int len=matrix.length; int[][] arr = new int[len][len]; //转化为二维数组 for(int i=0;i<len;i++){ for(int j=0;j<len;j++){ arr[i][j] = Integer.parseInt(String.valueOf(matrix[i].charAt(j))) ; } } //找出共同路径,返回最后一个共同节点; List<Integer> Apath = DFS(arr,indexA); List<Integer> Bpath=DFS(arr,indexB); int plen=Apath.size()>Bpath.size()?Bpath.size():Apath.size(); for (int i = 0; i < plen; i++) { if(Apath.get(i)==Bpath.get(i)) { tmp= Apath.get(i);//记录共同节点的值,并返回 } } return tmp; } //深度优先遍历,并返回到indexA的节点列表 private static List<Integer> DFS(int[][] arr, int indexA) { //分别创建标记数组,栈,动态列表。并用根节点初始化 boolean[] flag=new boolean[arr.length];//访问标记数组 flag[0] = true; Stack<Integer> stack = new Stack<Integer>();//创建栈对象 stack.push(0); List<Integer> path = new ArrayList<Integer>();//创建路径列表 path.add(0); //在栈中查indexA(目标节点) while(stack.peek() != indexA){//深度遍历 boolean findNext=false;//局部变量标志查找下一个节点 int u = stack.peek();//暂存栈顶对象 for(int j=0;j<arr.length;j++){//查找没有被访问并且相邻的第一个节点元素进栈 if(!flag[j] && arr[u][j] ==1){ u=j; stack.push(u); flag[u] = true; path.add(u); findNext = true; break; } } if(!findNext){//如果没有连接的节点 stack.pop();//最后一个元素不是查找的节点元素,则出栈 path.remove(path.size()-1);//列表中删除该元素 } } return path; } }