Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c7731b2

Browse files
check in the source code
1 parent aaa7e54 commit c7731b2

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace LowestCommonAncestorBTree
8+
{
9+
/// <summary>
10+
/// code review on July 9, 2018
11+
/// Leetcode 236
12+
/// https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/
13+
/// </summary>
14+
class TreeNode
15+
{
16+
public int val;
17+
public TreeNode left;
18+
public TreeNode right;
19+
20+
public TreeNode(int x)
21+
{
22+
left = null;
23+
right = null;
24+
val = x;
25+
}
26+
};
27+
28+
class LowestCommonAncestorB
29+
{
30+
/*
31+
* Leetcode:
32+
* Lowest common ancestor in binary tree
33+
*
34+
* Try a few of implementations - 4 different ones:
35+
* 1. Method A:
36+
* Top down method, using counting method to help
37+
* worst case time O(N^2)
38+
*
39+
* 2. Method B:
40+
* A Bottom-up Approach (Worst case O(n) ):
41+
Using a bottom-up approach, we can improve over the top-down approach
42+
by avoiding traversing the same nodes over and over again.
43+
*/
44+
static void Main(string[] args)
45+
{
46+
var root = new TreeNode(1);
47+
root.left = new TreeNode(2);
48+
root.right = new TreeNode(3);
49+
50+
root.left.left = new TreeNode(4);
51+
root.left.right = new TreeNode(5);
52+
53+
root.right.left = new TreeNode(6);
54+
root.right.right = new TreeNode(7);
55+
56+
var ancestor = LowestCommonAncestor(root, root.right.left, root.left.right);
57+
}
58+
59+
/*
60+
* source code from blog:
61+
* http://articles.leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-tree-part-i.html
62+
*
63+
* A Top-Down Approach (Worst case O(n^2) ):
64+
*
65+
* julia's comment:
66+
1. check left subtree count of matching p or q:
67+
0 - no match in left sub tree, so go to check right subtree
68+
1 - found it, the root is the node
69+
2 - continue to left, check
70+
* 2. put the code in the certain order: root, left, right
71+
* so, making it easy to follow.
72+
* two orders:
73+
* 1. check countingProblem return value, from 0 to 1 to 2, increasing order
74+
* 2. using countingProblem calculation take action, "found it", "go left",
75+
* "go right" three choice.
76+
*
77+
* Keep the code in the above order, this way, easy to memorize, explain, and discuss.
78+
*
79+
* 3. Using a easy counting problem to help solve lowest common ancestor (LCA),
80+
* What is the thinking process?
81+
* Here is the scripts Julia makes out:
82+
* Go to visit root first, check it value, null or one of two nodes,
83+
* and then, decide to find LCA, or go left to find it or go right to find it.
84+
*
85+
* But wait, how to decide to find it, or go left/ right, so calculate the left sub tree
86+
* matching count first, use its value to determine.
87+
*
88+
* 4. online judge: (lowest common ancestor in binary search tree, not in binary tree)
89+
* 27 / 27 test cases passed.
90+
Status: Accepted
91+
Runtime: 180 ms
92+
*
93+
*/
94+
public static TreeNode LowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q)
95+
{
96+
if (root == null || p == null || q == null)
97+
return null;
98+
99+
if (root == p || root == q)
100+
return root;
101+
102+
// go left
103+
int leftTreeMatched = findMatches(root.left, p, q);
104+
105+
bool zeroFound = leftTreeMatched == 0;
106+
bool oneFound = leftTreeMatched == 1;
107+
bool twoFound = leftTreeMatched == 2;
108+
109+
if (oneFound)
110+
{
111+
return root;
112+
}
113+
else if (twoFound)
114+
{
115+
return LowestCommonAncestor(root.left, p, q);
116+
}
117+
else if (zeroFound)
118+
{
119+
return LowestCommonAncestor(root.right, p, q);
120+
}
121+
122+
return null;
123+
}
124+
125+
/*
126+
* source code from blog:
127+
* http://articles.leetcode.com/2011/07/lowest-common-ancestor-of-a-binary-tree-part-i.html
128+
* comment from blog:
129+
* A Top-Down Approach (Worst case O(n^2) ):
130+
131+
Let’s try the top-down approach where we traverse the nodes from the top to the bottom.
132+
* First, if the current node is one of the two nodes, it must be the LCA of the two nodes.
133+
* If not, we count the number of nodes that matches either p or q in the left subtree (which
134+
* we call totalMatches). If totalMatches equals 1, then we know the right subtree will contain
135+
* the other node. Therefore, the current node must be the LCA. If totalMatches equals 2, we know
136+
* that both nodes are contained in the left subtree, so we traverse to its left child. Similar
137+
* with the case where totalMatches equals 0 where we traverse to its right child.
138+
*
139+
* Return #nodes that matches P or Q in the subtree.
140+
*
141+
* julia's comment:
142+
* 1. Convert C++ code to C#
143+
* 2. Solve a problem first: counting matches in the tree
144+
* Counting always helps to make decision. Using number to make a decision
145+
* 3. think about the question:
146+
* Can this function only uses two line code?
147+
*
148+
*
149+
*/
150+
private static int findMatches(TreeNode root, TreeNode p, TreeNode q)
151+
{
152+
if (root == null) return 0;
153+
154+
int matches = findMatches(root.left, p, q) + findMatches(root.right, p, q);
155+
156+
if (root == p || root == q)
157+
{
158+
return 1 + matches;
159+
}
160+
else
161+
{
162+
return matches;
163+
}
164+
}
165+
}
166+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /