1)这个解法使用所有二叉树,没有用到二叉搜索树的有序性。首先遍历树,用字典保存各数字的频次,找到最高频的数字返回。
class Solution:
def __init__(self):
self.num2cnt = {}
def func(self, root):
if not root:
return
self.func(root.left)
self.num2cnt[root.val] = self.num2cnt.get(root.val, 0) + 1
self.func(root.right)
def findMode(self, root: Optional[TreeNode]) -> List[int]:
self.func(root)
cnt2num = {}
for num, cnt in self.num2cnt.items():
try:
cnt2num[cnt].append(num)
except KeyError:
cnt2num[cnt] = [num]
max_cnt = max(cnt2num.keys())
return cnt2num[max_cnt]
2)由于二叉搜索树的中序遍历是有序的,通过维护maxcount(int)、pre(Node)、res(list)三个全局变量可以仅遍历一次树得到结果(但是不好理解,比较绕、容易出错
class Solution:
def __init__(self):
self.maxcnt = 0
self.curcnt = 0
self.res = []
self.pre = None
def func(self, root):
if not root:
return
self.func(root.left)
if self.pre:
if self.pre.val == root.val:
self.curcnt += 1
else:
if self.curcnt > self.maxcnt:
self.maxcnt = self.curcnt
self.res = [self.pre.val]
elif self.curcnt == self.maxcnt:
self.res.append(self.pre.val)
self.curcnt = 1
else:
self.curcnt = 1
self.pre = root
self.func(root.right)
def findMode(self, root):
self.func(root)
if self.maxcnt == self.curcnt and self.res[-1] != self.pre.val:
self.res.append(self.pre.val)
if self.maxcnt < self.curcnt:
self.res = [self.pre.val]
return self.res
或者:
class Solution:
def __init__(self):
self.maxcnt = 0
self.curcnt = 0
self.res = []
self.pre = None
def func(self, root):
if not root:
return
self.func(root.left)
if self.pre:
if self.pre.val == root.val:
self.curcnt += 1
else:
self.curcnt = 1
else:
self.curcnt = 1
if self.curcnt == self.maxcnt:
self.res.append(root.val)
if self.curcnt > self.maxcnt:
self.res = [root.val]
self.maxcnt = self.curcnt
self.pre = root
self.func(root.right)
def findMode(self, root):
self.func(root)
return self.res
236. 二叉树的最近公共祖先 - 力扣(LeetCode)
解法一:遍历一次树,获得两个节点的路径list;遍历一次路径list,找到最近公共祖先。
self.res保存两个路径的tuple,self.path保存当前节点的路径。每调用一次self.findPath(),self.path就添加一个节点,并在调用完毕弹出该节点(回溯)
递归的退出条件设为self.res长度为2(找到了两个路径)这样的退出条件可能导致回溯时出现问题,因此在pop()之前再加上self.path不为空的判断。
获得两个路径list后,遍历时,容易漏掉公共祖先是较短列表的最后一个元素的情况,需要在最后加上return path1[n-1]。
class Solution:
def __init__(self):
self.res = []
self.path = []
def findPath(self, root, p, q):
if len(self.res) == 2:
return
self.path.append(root)
if root == p or root == q:
self.res.append(tuple(self.path))
if root.left:
self.findPath(root.left, p, q)
if self.path:
self.path.pop()
if root.right:
self.findPath(root.right, p, q)
if self.path:
self.path.pop()
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
self.findPath(root, p, q)
path1 = list(self.res[0])
path2 = list(self.res[1])
n = min(len(path1), len(path2))
for i in range(n):
if path1[i] != path2[i]:
return path1[i-1]
return path1[n-1]
解法二:递归。若当前节点不是空而且不是要找的节点,就往它的左右子树找p、q。若左右子树都存在p或q,返回该节点;若左右子树都不存在p或q,返回空;若p、q都在其中一棵子树上,返回该子树。
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root:
return None
if root == q or root == p:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if not left and not right:
return None
if left and right:
return root
if left:
return left
if right:
return right