1.题目
题目链接
2.代码一
下面这段代码使用的是倍增思想,虽然可以得到正确的返回值,但是LeetCode中给出的如下两个限制让这题使用倍增算法不是那么顺利:
- 需要知道是哪个节点的值,即最后需要返回这个节点,而不是这个节点的值
- 给出的数据的节点大小是未知的,所以不能简单的使用val值作为数组的下标存储
from queue import Queue
import math
# Definition for a binary tree node.
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
height = [0] * 10
ancestor = [[0 for i in range(5)] for j in range(10)]
self.bfs(root,height,ancestor)
# print(height)
p_val = p.val
q_val = q.val
# print(p_val)
# print(q_val)
while(height[p_val] < height[q_val]):
q_val = ancestor[q_val][0] # 往上找一次
while(height[p_val] > height[q_val]):
p_val = ancestor[p_val][0]
# print(q_val)
# print(p_val)
if q_val == p_val:
return q_val
# 现在二者的高度相同,可以使用倍增算法寻找了
k = int(math.log2(height[q_val]))
for i in reversed(range(0,k+1)):
if(ancestor[q_val][i] == ancestor[p_val][i] ):
continue
else:
q_val = ancestor[q_val][i]
p_val = ancestor[p_val][i]
# 需要返回这个节点对应的node,而不是值
return ancestor[q_val][0]
# 使用广度优先得到每个节点的高度信息,根节点为0
# 同时给 ancestor[i][j] 赋值,得到每个节点的祖先节点信息
def bfs(self,root,height,ancestor):
que = Queue()
que.put((root,0))
# print("----")
# print("root.val",root.val)
height[root.val] = 0
while(que.qsize()):
head,dis = que.get()
k = int(math.log2(dis+1))
if head.left is not None:
# print(head.left.val)
left_val = head.left.val
que.put((head.left,dis+1))
height[head.left.val] = dis+1
ancestor[head.left.val][0] = head.val
# 开始对各级祖先赋值
for i in range(1,k+1):
ancestor[left_val][i] = ancestor[ancestor[left_val][i-1]][i-1]
if head.right is not None:
right_val = head.right.val
# print(right_val)
que.put((head.right,dis+1))
height[right_val] = dis+1
ancestor[right_val][0] = head.val
for i in range(1,k+1):
ancestor[right_val][i] = ancestor[ancestor[right_val][i-1]][i-1]
node10 = TreeNode(10,None,None)
node9 = TreeNode(9,node10,None)
node8 = TreeNode(8,node9,None)
node7 = TreeNode(7,None,None)
node4 = TreeNode(4,None,None)
node0 = TreeNode(0,None,None)
node8 = TreeNode(8,None,None)
node6 = TreeNode(6,None,None)
node2 = TreeNode(2,node7,node4)
node5 = TreeNode(5,node6,node2)
node1 = TreeNode(1,node0,node8)
node3 = TreeNode(3,node5,node1)
s = Solution()
out = s.lowestCommonAncestor(node3,node5,node1)
print(out)
3.代码二
使用递归的思想,LeetCode官方给出的解答还是挺经典的。我这个科班生菜到之前竟然没有在意这么写过这道题。惭愧!