這是我提出的非遞歸尋找二叉樹中兩個節點的最低公共祖先的算法。這裏的基本策略:最快的非遞歸實施LCA?
- 使用字典/散列表來存儲樹。每個鍵值對代表一個節點及其父節點。
- 從兩個節點的每一個開始,通過將代表每個節點值的變量設置爲其父節點的值,將散列值存儲在散列集中(兩個節點中的每個節點都存儲一個值)來遍歷樹。
- 當滿足以下任何條件時,搜索完成:(a)兩個節點的值相等;或者(b)當兩條路徑相互交叉時(即,節點1的遍歷值的散列集包含節點2的當前值,反之亦然);或者(c)傳入的節點不存在於樹中(在這種情況下算法終止並返回-1)。
我的理解是我算法的最壞情況時間和空間複雜度是O(log(n)),因爲我們從不需要進行超過2 *的高度遍歷或存儲多於2 *的高度值在我們的哈希集中(並且因爲哈希集和樹字典的查找時間是O(1))。
以下是我的代碼(C#)。請告知,如果我是正確的,我的分析,或者如果有一個更有效(非遞歸)的方式來做到這一點:
int LowestCommonAncestor(int value1, int value2, Dictionary<int, int> tree)
{
var value1Visited = new HashSet<int>();
var value2Visited = new HashSet<int>();
while (true)
{
if (value1 == value2) return value1;
if (value1Visited.Contains(value2)) return value2;
if (value2Visited.Contains(value1)) return value1;
int nextValue1;
int nextValue2;
if (tree.TryGetValue(value1, out nextValue1))
{
//Walk node 1 up the tree:
value1 = nextValue1;
value1Visited.Add(value1);
}
else
{
//Node doesn't exist in tree:
return -1;
}
if (tree.TryGetValue(value2, out nextValue2))
{
//Walk node 2 up the tree:
value2 = nextValue2;
value2Visited.Add(value2);
}
else
{
//Node doesn't exist in tree:
return -1;
}
}
}
是該算法導致一些錯誤或意外的結果? –
除非樹是平衡的,否則它不是'O(log N)'。它是'O(N)'(例如,竹子是一棵二叉樹)。 – kraskevich