说明:当时看到这道题目的时候,直接就有点MB了,后来仔细研究看了一些关于此题的一些说明,在加上使用过git,可能就熟悉了题目的要求。本质上就是在一个多叉树(git结构)找到两个子节点的最近公共父节点(就是合并git时找两个分支的最近的分割点)。
解题思路:
1、将字符串数组转换为字符数组;
2、遍历字符找到每个节点的父节点,记录每个节点的深度;
3、根据两个给定的索引值,遍历找到他们最近的公共父节点,记得每一次替换是将父节点赋值给indexA/B。
import java.util.LinkedList;
import java.util.Queue;
/**
* 题目描述 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树的根节点。)
* 输入例子: [01011,10100,01000,10000,10000],1,2
*
* 输出例子: 1
* @author 崔洪振367
* @version 创建时间:2017年6月29日 下午10:22:30
*/
public class 小米Git_ {
/**
* 返回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) {
int n = matrix.length;
//每个节点的父节点
int[] parent = new int[n];
//记录每个节点的深度
int[] depth = new int[n];
//将字符串数组转换为字符数组
char[][] tree = new char[n][];
Queue<Integer> que = new LinkedList<>();
for (int i = 0; i < n; i++) {
tree[i] = matrix[i].toCharArray();
parent[i] = -1;//初始化父节点,设置为独立的节点
depth[i] = 1;//初始化每个节点的深度,将其值设置为1
}
que.add(0);//第一个节点存入到队列中
parent[0] = 0;
//从跟节点往下遍历多叉树,按层遍历
while (!que.isEmpty()) {
int v = que.poll();
for (int i = 0; i < n; i++) {//将v看作父节点,i看作是孩子节点
//从v-->i看作是节点的v的初度值,从而判断v节点的孩子节点个数就是i满足i的值个数
if (tree[v][i] == '1' && parent[i] == -1) {
que.add(i);
parent[i] = v;
depth[i] = depth[v] + 1;//节点的深度是父节点的深度+1
}
}
}
//下面的操作就是找到两个值indexA和indexB最近公共父节点,主要是通过判断两个值的父节点值是否相等
while (depth[indexA] > depth[indexB]) {
indexA = parent[indexA];
}
while (depth[indexA] < depth[indexB]) {
indexB = parent[indexB];
}
while (indexA != indexB) {
indexA = parent[indexA];
indexB = parent[indexB];
}
return indexA;
}
}