赞
踩
相关推荐
python coding with ChatGPT 打卡第12天| 二叉树:理论基础
python coding with ChatGPT 打卡第13天| 二叉树的深度优先遍历
python coding with ChatGPT 打卡第14天| 二叉树的广度优先遍历
python coding with ChatGPT 打卡第15天| 二叉树:翻转二叉树、对称二叉树
python coding with ChatGPT 打卡第16天| 二叉树:完全二叉树、平衡二叉树、二叉树的所有路径、左叶子之和
python coding with ChatGPT 打卡第17天| 二叉树:找树左下角的值、路径总和
python coding with ChatGPT 打卡第18天| 二叉树:从中序与后序遍历序列构造二叉树、最大二叉树
python coding with ChatGPT 打卡第19天| 二叉树:合并二叉树
1.二叉搜索树是一个有序树:
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉搜索树
2.二叉搜索树的迭代
一提到二叉树遍历的迭代法,可能立刻想起使用栈来模拟深度遍历,使用队列来模拟广度遍历。
对于二叉搜索树可就不一样了,因为二叉搜索树的特殊性,也就是节点的有序性,可以不使用辅助栈或者队列就可以写出迭代法。
对于一般二叉树,递归过程中还有回溯的过程,例如走一个左方向的分支走到头了,那么要调头,在走右分支。
而对于二叉搜索树,不需要回溯的过程,因为节点的有序性就帮我们确定了搜索的方向。
方法一:
递归法
def searchBST(root, val):
if not root:
return None
if root.val > val:
return searchBST(root.left, val)
if root.val < val:
return searchBST(root.right, val)
return root
方法二:
迭代法
def searchBST(root, val):
current = root
while current:
if current.val > val:
current = current.left
continue
if current.val < val:
current = current.right
continue
else:
break
return current
在中序遍历
下,输出的二叉搜索树节点的数值是升序序列。
方法一:
不使用有序序列
我们可以定义一个辅助函数checkBST,它接收四个参数:当前节点node、minVal(当前节点值允许的最小值)、maxVal(当前节点值允许的最大值)、以及初始的根节点root。这个辅助函数将帮助我们递归地验证每个子树,同时保持跟踪允许的值的范围。
def checkBST(node, minVal, maxVal):
if not node:
return True
if node.val <= minVal or node.val >= maxVal:
return False
return checkBST(node.left, minVal, node.val) and checkBST(node.right, node.val, maxVal)
def isValidBST(root):
return checkBST(root, float('-inf'), float('inf'))
这段代码使用了一个嵌套的辅助函数checkBST来递归地验证每个节点是否符合二叉搜索树的条件,它通过维护每个节点的值允许的最小值和最大值来实现。这种方法能够确保所有的左子树节点都小于它的父节点,并且所有的右子树节点都大于它的父节点,同时还考虑了所有祖先节点的约束条件。
方法二:
使用有序序列 + 双指针 递归法
class Solution: def __init__(self): self.pre = None # 用来记录前一个节点 def isValidBST(self, root): if root is None: return True left = self.isValidBST(root.left) if self.pre is not None and self.pre.val >= root.val: return False self.pre = root # 记录前一个节点 right = self.isValidBST(root.right) return left and right
方法三:
使用有序序列 + 双指针 迭代法
def isValidBST(root): stack = [] prev = None while stack or root: # 遍历到最左 while root: stack.append(root) root = root.left # 访问节点 root = stack.pop() # 检查当前节点是否大于前一个节点 if prev and root.val <= prev.val: return False prev = root # 转向右子树 root = root.right return True
方法一:
递归法
class Solution(object): def __init__(self): self.pre = None self.diff = float('inf') # 只使用一次,所以是全局变量 def getMinimumDifference(self, root): self.in_traversal(root) return self.diff def in_traversal(self, root): if not root: return self.in_traversal(root.left) if self.pre: self.diff = min(root.val - self.pre.val, self.diff) self.pre = root self.in_traversal(root.right) return
方法二:
迭代法 + 暴力
def getMinimumDifference(root): stack_record = [] current = root res = [] while stack_record or current: while current: stack_record.append(current) current = current.left current = stack_record.pop() res.append(current.val) # 左中都处理完了,转向右 current = current.right i = 0 j = i+1 diff = res[j] - res[i] while j < len(res): diff = min(res[j] - res[i], diff) i += 1 j += 1 return diff
注:LeetCode题目中说明节点至少为两个,所以使用双指针不用讨论数组长度
方法三:
迭代法+简化
def getMinimumDifference(root): stack_record = [] current = root diff = float('inf') pre = None while stack_record or current: while current: stack_record.append(current) current = current.left current = stack_record.pop() if pre is None: # if not pre 不行,警惕0的情况 pre = current.val else: diff = min(current.val-pre, diff) pre = current.val current = current.right return diff
首先如果不是二叉搜索树的话,应该怎么解题,是二叉搜索树,又应该如何解题,两种方式做一个比较,可以加深大家对二叉树的理解。
方法一:
暴力法 哈希表(迭代)
def findMode(root): res = [] stack_record = [] current = root while stack_record or current: while current: stack_record.append(current) current = current.left current = stack_record.pop() res.append(current.val) current = current.right record = {} for x in res: record[x] = record.get(x, 0) + 1 record_sort = sorted(record.items(), key=lambda x:x[1], reverse=True) results = [] max_val = record_sort[0][1] for x in record_sort: if x[1] == max_val: results.append(x[0]) else: break return results
方法二:
遍历两遍 双指针 (迭代法)
def findMode(root): res = [] stack_record = [] current = root while stack_record or current: while current: stack_record.append(current) current = current.left current = stack_record.pop() res.append(current.val) current = current.right pre = None count = 0 max_count = 0 results = [] for x in res: if pre is not None: if pre == x: count +=1 else: count = 1 else: count = 1 pre = x if count == max_count: results.append(x) elif count > max_count: max_count = count results = [x] return results
方法三:
遍历一遍 迭代法
def findMode(root): res = [] pre = None max_count = 0 count = 0 stack_record = [] current = root while stack_record or current: while current: stack_record.append(current) current = current.left current = stack_record.pop() if pre: if current.val == pre.val: count += 1 else: count = 1 else: count = 1 pre = current if count == max_count: res.append(current.val) elif count > max_count: max_count = count res = [current.val] current = current.right return res
方法四:
遍历一遍 递归法
class Solution: def __init__(self): self.pre = None self.res = [] self.max_count = 0 self.count = 0 def in_traversal(self, root): if not root: return self.in_traversal(root.left) if self.pre: if root.val == self.pre.val: self.count += 1 else: self.count = 1 else: self.count = 1 self.pre = root if self.count == self.max_count: self.res.append(root.val) elif self.count > self.max_count: self.max_count = self.count self.res = [root.val] self.in_traversal(root.right) return def findMode(self, root): self.in_traversal(root) return self.res
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。