您的位置:首页 > 其它

小米Git

2016-08-08 09:10 190 查看


题目地址:http://www.nowcoder.com/practice/e9ff41269a7e49519b87fe7d9fd0d477?tpId=49&tqId=29231&rp=1&ru=/ta/2016test&qru=/ta/2016test/question-ranking


题目描述

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


这道题,我整理思路用了很久,开始一直以为这是一个多项连接的无向图,后来才觉得这是一颗多分支的树,一下代码是我以多叉树为数据结构写的。在代码之后我会举例我为什么觉得这是一张无向图。

树的解法如下:根据我需要的节点,先找到从根节点到节点的路径,在得到这两条路径后,则计算着两条路径中最后相同的那个点就是最近的父节点。

import java.util.Vector;
public class Solution {
/**
* 返回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) {
Vector<TNode> path = new Vector<TNode>();
Vector<TNode> path1 = new Vector<TNode>();
boolean[] is = new boolean[matrix.length];
boolean[] is1 = new boolean[matrix.length];
getPath(matrix, 0, indexA, path,is);
getPath(matrix, 0, indexB, path1,is1);

return getCommentParent(path, path1);
}

/**
* 寻找包含r的路径
*
* @param matrix
* 邻接表
* @param now
* 当前的节点数
* @param r
* 目标节点
* @param path
* 路径
* @param is
*
* @return 1:找到了 0:没有找到
*/
public int getPath(String[] matrix, int now, int r, Vector<TNode> path, boolean[] is) {
int found = 0;

is[now] = true;
String string = matrix[now];
TNode t = new TNode(now);
path.add(t);
if (now == r) {
found = 1;
}
for (int j = 0 ; j < string.length() && found == 0; j++) {

if (matrix[now].charAt(j) == '1' && is[j] == false) {
/* System.out.println(now +" "+j);*/
found = getPath(matrix, j, r, path,is);
}
}
if (found == 0) {
int index = path.indexOf(t);
path.remove(index);
is[now] = false;
}

return found;
}

/**
* 取最近的父元素
*
* @param path
* @param path1
* @return -1 无解
*/
public int getCommentParent(Vector<TNode> path, Vector<TNode> path1) {
if (path == null || path1 == null)
return -1;
int res = -1;
for (int i = 0, j = 0; i < path.size() && j < path1.size(); i++, j++) {
if (path.get(i).value == path1.get(j).value) {
res = path.get(i).value;
}
}
return res;
}

class TNode {
public int value;
public Vector<TNode> List = new Vector<>();

public TNode(){

}
public TNode(int i){
this.value = i;
}
}
}这种情况下,是单纯的没有出现分支合并的情况,如果出现一下情况
A- _  D _ E ----F-G

   | B - C - |

即如上图,在A点后,我新建branch B,在原来分支更新了2代后,我把D和C分支合并branch merge之后产生了E。这样的话,就有可能出现,一个要求的数是

D,一个要求是F,假设每次遍历会从小到大,即找到的路径会是A-B-C-E-F,另一个条则是A-D,这样出来的结果是父元素是A,然而实际上应该是D。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息