小米Git

题目地址: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。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值