小米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樹的根節點。)

輸入例子:

[01011,10100,01000,10000,10000],1,2

輸出例子:

1


問題解析

題意爲: 一個多叉樹 , 計算樹上任意兩點的最近分割點 ,使用鄰接矩陣表示這個多叉樹

例如:

這裏寫圖片描述

圖1: 節點1 與 節點2的最近分割點爲節點1 ;
圖2: 節點6 與 節點5的最近分割點爲節點1 ;
     節點2 與 節點3的最近分割點爲節點0 ;
圖3: 節點3 與 節點2的最近分割點爲節點3 ;
  • 1
  • 2
  • 3
  • 4
  • 5

思路

以求圖1 節點1 與 節點2的最近分割點爲例
1. 首先將無向的鄰接矩陣,化爲有向的鄰接矩陣使用深度優先遍歷的方法:將入度都清0,留下出度.

(1)找0的子節點 ,掃描matrix[0][?] ,發現matrix[0][1]='1',設置matrix[1][0] ='0' ,根據深度優先, 使用遞歸遍歷1節點;
(2)發現matrix[1][2]='1' ,設置matrix[2][1]='0' ,用遞歸遍歷節點2
(3)最後鄰接矩陣就會變成有向.
  • 1
  • 2
  • 3
  • 4

鄰接矩陣爲:
這裏寫圖片描述
轉換後的矩陣很容易看出 0節點 是 1,3節點 的雙親,1節點 是 2節點 的雙親

2.定義一個bool數組 flags[4]={false} ;設初值爲false;
要找 節點1 與 節點2 的最近分割點
(1)先找 1節點的軌跡:
先將flags[1] =true ;遍歷數組matrix[i][1] ==’1’發現 i=0, 也就是1節點的雙親爲0
設置flags[0] = true ;發現0已經是根節點,就不用再找雙親了
(2)接着找2節點的軌跡:
先將flags[2] =true ;遍歷數組matrix[i][2]==’1’ ,發現i=1,找到2的雙親是1;
設置flags[1] =true ,這時發現flags[1]已經爲true ;退出函數,返回1
這裏寫圖片描述
再例如圖2:節點6 與 節點5的最近分割點爲節點1 ;
這裏寫圖片描述


代碼

#include<iostream>
#include<vector>
#include<cstring>
#include<memory>
using namespace std ;

class Solution {
public:
    /**
     * 返回git樹上兩點的最近分割點
     *
     * @param matrix 接鄰矩陣,表示git樹,matrix[i][j] == ‘1’ 當且僅當git樹中第i個和第j個節點有連接,節點0爲git樹的跟節點
     * @param indexA 節點A的index
     * @param indexB 節點B的index
     * @return 整型
     */
    void setDirected(vector<string> &matrix ,int r);
    int setTrack(vector<string> &matrix ,bool flag[], int index);
    int getSplitNode(vector<string> matrix, int indexA, int indexB) ;

};





/*

將無向的鄰接矩陣 ,轉爲有向的
以行爲出度,將所有入度清0

轉化爲有向表以後就可以,根據通過matrix[?][index] ,找到index點的雙親

*/
void Solution::setDirected(vector<string> &matrix ,int r)
{
int j ;
for(j=0 ;j<matrix.size(); j++)
{
if(matrix[r][j]==‘1’ )
{
matrix[j][r]=‘0’ ;
setDirected(matrix,j) ;
}
}
}

int Solution::setTrack(vector<string> &matrix ,bool flags[], int index)
{
int j ,dex;
//判斷是否標記,如果標記就說明兩條軌跡重合
//當第一次調用這個函數的時候,是都沒有標記的
//但是當第二次調用的時候,就會在第一重合點重複標記,這時就返回該點,退出遞歸
if( false==flags[index])
{
flags[index] =true ;
for(j =0; j<matrix.size() ;j++)
if( ‘1’==matrix[j][index])
{
dex = setTrack(matrix,flags,j);
break;
}
return dex ;
}
else
{
return index ;
}

}

int Solution::getSplitNode(vector<string> matrix, int indexA, int indexB)
{
bool *flags = new bool[matrix.size()];//用於軌跡標記
//先將flags數組都設爲flags
memset(flags,false,sizeof(bool)*matrix.size()) ;

setDirected(matrix,<span class="hljs-number">0</span>) ;<span class="hljs-comment">//將矩陣轉爲有向的</span>

<span class="hljs-comment">//先找indexA的雙親,然後找雙親的雙親,形成一條軌跡</span>
setTrack(matrix,flags,indexA) ;
<span class="hljs-comment">//先找indexB的雙親,然後找雙親的雙親,形成一條軌跡,兩條軌跡相遇的點就是要找的節點</span>
<span class="hljs-keyword">int</span> i = setTrack(matrix,flags,indexB) ;

<span class="hljs-keyword">delete</span> []flags ;
<span class="hljs-keyword">return</span> i ;

}

int main()
{
vector<string> matrix ;

<span class="hljs-keyword">int</span> n ;
<span class="hljs-built_in">cin</span>&gt;&gt;n ;

<span class="hljs-built_in">string</span> str ;
<span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span> ;i&lt;n ;i++)
{
    <span class="hljs-built_in">cin</span>&gt;&gt;str;
    matrix.push_back(str);
}
<span class="hljs-keyword">int</span> a ,b ;
<span class="hljs-built_in">cin</span>&gt;&gt;a&gt;&gt;b ;

Solution solu ;
<span class="hljs-keyword">int</span> answer = solu.getSplitNode(matrix,a ,b) ;
<span class="hljs-built_in">cout</span>&lt;&lt;answer&lt;&lt;<span class="hljs-string">"\n"</span> ;

<span class="hljs-keyword">return</span> <span class="hljs-number">0</span> ;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
轉自:https://blog.csdn.net/native_lee/article/details/52567128

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章