小米笔试题-小米Git

题目描述

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;
    }
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值