Merge pull request #2096 from jianghongcheng/master

修改py
This commit is contained in:
程序员Carl
2023-05-25 09:35:49 +08:00
committed by GitHub
12 changed files with 657 additions and 551 deletions

View File

@ -371,117 +371,113 @@ class Solution {
## Python ## Python
**递归** - 利用BST中序遍历特性,把树"压缩"成数组 递归法(版本一)利用中序递增性质,转换成数组
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def isValidBST(self, root: TreeNode) -> bool: def __init__(self):
# 思路: 利用BST中序遍历的特性. self.vec = []
# 中序遍历输出的二叉搜索树节点的数值是有序序列
candidate_list = []
def __traverse(root: TreeNode) -> None: def traversal(self, root):
nonlocal candidate_list if root is None:
if not root:
return return
__traverse(root.left) self.traversal(root.left)
candidate_list.append(root.val) self.vec.append(root.val) # 将二叉搜索树转换为有序数组
__traverse(root.right) self.traversal(root.right)
def __is_sorted(nums: list) -> bool: def isValidBST(self, root):
for i in range(1, len(nums)): self.vec = [] # 清空数组
if nums[i] <= nums[i - 1]: # ⚠️ 注意: Leetcode定义二叉搜索树中不能有重复元素 self.traversal(root)
for i in range(1, len(self.vec)):
# 注意要小于等于,搜索树里不能有相同元素
if self.vec[i] <= self.vec[i - 1]:
return False return False
return True return True
__traverse(root)
res = __is_sorted(candidate_list)
return res
``` ```
**递归** - 标准做法 递归法(版本二)设定极小值,进行比较
```python ```python
class Solution: class Solution:
def isValidBST(self, root: TreeNode) -> bool: def __init__(self):
# 规律: BST的中序遍历节点数值是从小到大. self.maxVal = float('-inf') # 因为后台测试数据中有int最小值
cur_max = -float("INF")
def __isValidBST(root: TreeNode) -> bool:
nonlocal cur_max
if not root: def isValidBST(self, root):
if root is None:
return True return True
is_left_valid = __isValidBST(root.left) left = self.isValidBST(root.left)
if cur_max < root.val: # 中序遍历,验证遍历的元素是不是从小到大
cur_max = root.val if self.maxVal < root.val:
self.maxVal = root.val
else: else:
return False return False
is_right_valid = __isValidBST(root.right) right = self.isValidBST(root.right)
return left and right
return is_left_valid and is_right_valid
return __isValidBST(root)
``` ```
**递归** - 避免初始化最小值做法: 递归法(版本三)直接取该树的最小值
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def isValidBST(self, root: TreeNode) -> bool: def __init__(self):
# 规律: BST的中序遍历节点数值是从小到大. self.pre = None # 用来记录前一个节点
pre = None
def __isValidBST(root: TreeNode) -> bool:
nonlocal pre
if not root: def isValidBST(self, root):
if root is None:
return True return True
is_left_valid = __isValidBST(root.left) left = self.isValidBST(root.left)
if pre and pre.val>=root.val: return False
pre = root if self.pre is not None and self.pre.val >= root.val:
is_right_valid = __isValidBST(root.right) return False
self.pre = root # 记录前一个节点
right = self.isValidBST(root.right)
return left and right
return is_left_valid and is_right_valid
return __isValidBST(root)
``` ```
迭代法
```python ```python
迭代-中序遍历 # Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def isValidBST(self, root: TreeNode) -> bool: def isValidBST(self, root):
stack = [] stack = []
cur = root cur = root
pre = None pre = None # 记录前一个节点
while cur or stack: while cur is not None or len(stack) > 0:
if cur: # 指针来访问节点,访问到最底层 if cur is not None:
stack.append(cur) stack.append(cur)
cur = cur.left cur = cur.left # 左
else: # 逐一处理节点 else:
cur = stack.pop() cur = stack.pop() # 中
if pre and cur.val <= pre.val: # 比较当前节点和前节点的值的大小 if pre is not None and cur.val <= pre.val:
return False return False
pre = cur pre = cur # 保存前一个访问的结点
cur = cur.right cur = cur.right # 右
return True return True
``` ```
```python
# 遵循Carl的写法只添加了节点判断的部分
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
# method 2
que, pre = [], None
while root or que:
while root:
que.append(root)
root = root.left
root = que.pop()
# 对第一个节点只做记录,对后面的节点进行比较
if pre is None:
pre = root.val
else:
if pre >= root.val: return False
pre = root.val
root = root.right
return True
```
## Go ## Go

View File

@ -316,73 +316,65 @@ class Solution {
``` ```
## Python ## Python
**递归** 递归法
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
'''
构造二叉树:重点是选取数组最中间元素为分割点,左侧是递归左区间;右侧是递归右区间
必然是平衡树
左闭右闭区间
'''
# 返回根节点
root = self.traversal(nums, 0, len(nums)-1)
return root
def traversal(self, nums: List[int], left: int, right: int) -> TreeNode: def traversal(self, nums: List[int], left: int, right: int) -> TreeNode:
# Base Case
if left > right: if left > right:
return None return None
# 确定左右界的中心,防越界
mid = left + (right - left) // 2 mid = left + (right - left) // 2
# 构建根节点 root = TreeNode(nums[mid])
mid_root = TreeNode(nums[mid]) root.left = self.traversal(nums, left, mid - 1)
# 构建以左右界的中心为分割点的左右子树 root.right = self.traversal(nums, mid + 1, right)
mid_root.left = self.traversal(nums, left, mid-1) return root
mid_root.right = self.traversal(nums, mid+1, right)
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
root = self.traversal(nums, 0, len(nums) - 1)
return root
# 返回由被传入的左右界定义的某子树的根节点
return mid_root
``` ```
**迭代**(左闭右开) 迭代法
```python ```python
from collections import deque
class Solution: class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]: def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
if len(nums) == 0: return None if len(nums) == 0:
root = TreeNode() # 初始化 return None
nodeSt = [root]
leftSt = [0]
rightSt = [len(nums)]
while nodeSt: root = TreeNode(0) # 初始根节点
node = nodeSt.pop() # 处理根节点 nodeQue = deque() # 放遍历的节点
left = leftSt.pop() leftQue = deque() # 保存左区间下标
right = rightSt.pop() rightQue = deque() # 保存右区间下标
nodeQue.append(root) # 根节点入队列
leftQue.append(0) # 0为左区间下标初始位置
rightQue.append(len(nums) - 1) # len(nums) - 1为右区间下标初始位置
while nodeQue:
curNode = nodeQue.popleft()
left = leftQue.popleft()
right = rightQue.popleft()
mid = left + (right - left) // 2 mid = left + (right - left) // 2
node.val = nums[mid]
if left < mid: # 处理左区间 curNode.val = nums[mid] # 将mid对应的元素给中间节点
node.left = TreeNode()
nodeSt.append(node.left)
leftSt.append(left)
rightSt.append(mid)
if right > mid + 1: # 处理区间 if left <= mid - 1: # 处理区间
node.right = TreeNode() curNode.left = TreeNode(0)
nodeSt.append(node.right) nodeQue.append(curNode.left)
leftSt.append(mid + 1) leftQue.append(left)
rightSt.append(right) rightQue.append(mid - 1)
if right >= mid + 1: # 处理右区间
curNode.right = TreeNode(0)
nodeQue.append(curNode.right)
leftQue.append(mid + 1)
rightQue.append(right)
return root return root
``` ```
## Go ## Go

View File

@ -536,16 +536,14 @@ class Solution:
```python ```python
class Solution: class Solution:
def isBalanced(self, root: TreeNode) -> bool: def isBalanced(self, root: Optional[TreeNode]) -> bool:
return self.height(root) != -1 return self.get_hight(root) != -1
def height(self, node: TreeNode) -> int: def get_hight(self, node):
if not node: if not node:
return 0 return 0
left = self.height(node.left) left = self.get_hight(node.left)
if left == -1: right = self.get_hight(node.right)
return -1 if left == -1 or right == -1 or abs(left - right) > 1:
right = self.height(node.right)
if right == -1 or abs(left - right) > 1:
return -1 return -1
return max(left, right) + 1 return max(left, right) + 1
``` ```

View File

@ -302,36 +302,72 @@ class Solution {
## Python ## Python
递归法 递归法(版本一)
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def minDepth(self, root: TreeNode) -> int: def getDepth(self, node):
if not root: if node is None:
return 0 return 0
leftDepth = self.getDepth(node.left) # 左
rightDepth = self.getDepth(node.right) # 右
if not root.left and not root.right: # 当一个左子树为空,右不为空,这时并不是最低点
return 1 if node.left is None and node.right is not None:
return 1 + rightDepth
left_depth = float('inf') # 当一个右子树为空,左不为空,这时并不是最低点
right_depth = float('inf') if node.left is not None and node.right is None:
return 1 + leftDepth
if root.left: result = 1 + min(leftDepth, rightDepth)
left_depth = self.minDepth(root.left) return result
if root.right:
right_depth = self.minDepth(root.right)
return 1 + min(left_depth, right_depth) def minDepth(self, root):
return self.getDepth(root)
``` ```
递归法(版本二)
迭代法: ```python
class Solution:
def minDepth(self, root):
if root is None:
return 0
if root.left is None and root.right is not None:
return 1 + self.minDepth(root.right)
if root.left is not None and root.right is None:
return 1 + self.minDepth(root.left)
return 1 + min(self.minDepth(root.left), self.minDepth(root.right))
```
递归法(版本三)前序
```python
class Solution:
def __init__(self):
self.result = float('inf')
def getDepth(self, node, depth):
if node is None:
return
if node.left is None and node.right is None:
self.result = min(self.result, depth)
if node.left:
self.getDepth(node.left, depth + 1)
if node.right:
self.getDepth(node.right, depth + 1)
def minDepth(self, root):
if root is None:
return 0
self.getDepth(root, 1)
return self.result
```
迭代法
```python ```python
# Definition for a binary tree node. # Definition for a binary tree node.
@ -364,39 +400,7 @@ class Solution:
return depth return depth
``` ```
迭代法:
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def minDepth(self, root: TreeNode) -> int:
if not root:
return 0
queue = collections.deque([(root, 1)])
while queue:
node, depth = queue.popleft()
# Check if the node is a leaf node
if not node.left and not node.right:
return depth
# Add left and right child to the queue
if node.left:
queue.append((node.left, depth+1))
if node.right:
queue.append((node.right, depth+1))
return 0
```
## Go ## Go

View File

@ -275,34 +275,57 @@ class Solution {
## Python ## Python
递归法 递归法(版本一)
```python ```python
class Solution: class Solution:
"""二叉搜索树的最近公共祖先 递归法""" def traversal(self, cur, p, q):
if cur is None:
return cur
# 中
if cur.val > p.val and cur.val > q.val: # 左
left = self.traversal(cur.left, p, q)
if left is not None:
return left
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': if cur.val < p.val and cur.val < q.val: # 右
if root.val > p.val and root.val > q.val: right = self.traversal(cur.right, p, q)
return self.lowestCommonAncestor(root.left, p, q) if right is not None:
if root.val < p.val and root.val < q.val: return right
return self.lowestCommonAncestor(root.right, p, q)
return root return cur
def lowestCommonAncestor(self, root, p, q):
return self.traversal(root, p, q)
``` ```
迭代法 迭代法(版本二)精简
```python ```python
class Solution: class Solution:
"""二叉搜索树的最近公共祖先 迭代法""" def lowestCommonAncestor(self, root, p, q):
if root.val > p.val and root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
elif root.val < p.val and root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
else:
return root
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode': ```
while True:
迭代法
```python
class Solution:
def lowestCommonAncestor(self, root, p, q):
while root:
if root.val > p.val and root.val > q.val: if root.val > p.val and root.val > q.val:
root = root.left root = root.left
elif root.val < p.val and root.val < q.val: elif root.val < p.val and root.val < q.val:
root = root.right root = root.right
else: else:
return root return root
``` return None
```
## Go ## Go
递归法: 递归法:

View File

@ -274,25 +274,44 @@ class Solution {
``` ```
## Python ## Python
递归法(版本一)
```python ```python
class Solution: class Solution:
"""二叉树的最近公共祖先 递归法""" def lowestCommonAncestor(self, root, p, q):
if root == q or root == p or root is None:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if not root or root == p or root == q:
return root return root
left = self.lowestCommonAncestor(root.left, p, q) left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q) right = self.lowestCommonAncestor(root.right, p, q)
if left and right: if left is not None and right is not None:
return root return root
if left:
return left
return right
```
if left is None and right is not None:
return right
elif left is not None and right is None:
return left
else:
return None
```
递归法(版本二)精简
```python
class Solution:
def lowestCommonAncestor(self, root, p, q):
if root == q or root == p or root is None:
return root
left = self.lowestCommonAncestor(root.left, p, q)
right = self.lowestCommonAncestor(root.right, p, q)
if left is not None and right is not None:
return root
if left is None:
return right
return left
```
## Go ## Go
```Go ```Go

View File

@ -324,88 +324,90 @@ class Solution {
``` ```
## Python ## Python
递归法(版本一)
```python ```python
class Solution: class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]: def deleteNode(self, root, key):
if not root : return None # 节点为空,返回 if root is None:
return root
if root.val == key:
if root.left is None and root.right is None:
return None
elif root.left is None:
return root.right
elif root.right is None:
return root.left
else:
cur = root.right
while cur.left is not None:
cur = cur.left
cur.left = root.left
return root.right
if root.val > key:
root.left = self.deleteNode(root.left, key)
if root.val < key: if root.val < key:
root.right = self.deleteNode(root.right, key) root.right = self.deleteNode(root.right, key)
elif root.val > key :
root.left = self.deleteNode(root.left, key)
else:
# 当前节点的左子树为空,返回当前的右子树
if not root.left : return root.right
# 当前节点的右子树为空,返回当前的左子树
if not root.right: return root.left
# 左右子树都不为空,找到右孩子的最左节点 记为p
node = root.right
while node.left :
node = node.left
# 将当前节点的左子树挂在p的左孩子上
node.left = root.left
# 当前节点的右子树替换掉当前节点,完成当前节点的删除
root = root.right
return root return root
``` ```
**普通二叉树的删除方式** 递归法(版本二)
```python ```python
class Solution: class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]: def deleteNode(self, root, key):
if not root: return root if root is None: # 如果根节点为空,直接返回
if root.val == key:
if not root.right: # 这里第二次操作目标值:最终删除的作用
return root.left
tmp = root.right
while tmp.left:
tmp = tmp.left
root.val, tmp.val = tmp.val, root.val # 这里第一次操作目标值:交换目标值其右子树最左面节点。
root.left = self.deleteNode(root.left, key)
root.right = self.deleteNode(root.right, key)
return root return root
if root.val == key: # 找到要删除的节点
if root.right is None: # 如果右子树为空,直接返回左子树作为新的根节点
return root.left
cur = root.right
while cur.left: # 找到右子树中的最左节点
cur = cur.left
root.val, cur.val = cur.val, root.val # 将要删除的节点值与最左节点值交换
root.left = self.deleteNode(root.left, key) # 在左子树中递归删除目标节点
root.right = self.deleteNode(root.right, key) # 在右子树中递归删除目标节点
return root
``` ```
**迭代法** **迭代法**
```python ```python
class Solution: class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]: def deleteOneNode(self, target: TreeNode) -> TreeNode:
# 找到节点后分两步1. 把节点的左子树和右子树连起来2. 把右子树跟父节点连起来 """
# root is None 将目标节点(删除节点)的左子树放到目标节点的右子树的最左面节点的左孩子位置上
if not root: return root 并返回目标节点右孩子为新的根节点
p = root 是动画里模拟的过程
last = None """
while p: if target is None:
if p.val==key: return target
# 1. connect left to right if target.right is None:
# right is not None -> left is None | left is not None return target.left
if p.right: cur = target.right
if p.left: while cur.left:
node = p.right cur = cur.left
while node.left: cur.left = target.left
node = node.left return target.right
node.left = p.left
right = p.right def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
else: if root is None:
# right is None -> right=left return root
right = p.left cur = root
# 2. connect right to last pre = None # 记录cur的父节点用来删除cur
if last==None: while cur:
root = right if cur.val == key:
elif last.val>key:
last.left = right
else:
last.right = right
# 3. return
break break
pre = cur
if cur.val > key:
cur = cur.left
else: else:
# Update last and continue cur = cur.right
last = p if pre is None: # 如果搜索树只有头结点
if p.val>key: return self.deleteOneNode(cur)
p = p.left # pre 要知道是删左孩子还是右孩子
else: if pre.left and pre.left.val == key:
p = p.right pre.left = self.deleteOneNode(cur)
if pre.right and pre.right.val == key:
pre.right = self.deleteOneNode(cur)
return root return root
``` ```

View File

@ -528,8 +528,7 @@ class Solution {
## Python ## Python
> 递归法 递归法(版本一)利用字典
> 常量空间,递归产生的栈不算
```python ```python
# Definition for a binary tree node. # Definition for a binary tree node.
@ -538,77 +537,108 @@ class Solution {
# self.val = val # self.val = val
# self.left = left # self.left = left
# self.right = right # self.right = right
from collections import defaultdict
class Solution: class Solution:
def __init__(self): def searchBST(self, cur, freq_map):
self.pre = TreeNode() if cur is None:
self.count = 0 return
self.max_count = 0 freq_map[cur.val] += 1 # 统计元素频率
self.result = [] self.searchBST(cur.left, freq_map)
self.searchBST(cur.right, freq_map)
def findMode(self, root: TreeNode) -> List[int]: def findMode(self, root):
if not root: return None freq_map = defaultdict(int) # key:元素value:出现频率
self.search_BST(root) result = []
return self.result if root is None:
return result
self.searchBST(root, freq_map)
max_freq = max(freq_map.values())
for key, freq in freq_map.items():
if freq == max_freq:
result.append(key)
return result
def search_BST(self, cur: TreeNode) -> None:
if not cur: return None
self.search_BST(cur.left)
# 第一个节点
if not self.pre:
self.count = 1
# 与前一个节点数值相同
elif self.pre.val == cur.val:
self.count += 1
# 与前一个节点数值不相同
else:
self.count = 1
self.pre = cur
if self.count == self.max_count:
self.result.append(cur.val)
if self.count > self.max_count:
self.max_count = self.count
self.result = [cur.val] # 清空self.result确保result之前的的元素都失效
self.search_BST(cur.right)
``` ```
递归法(版本二)利用二叉搜索树性质
> 迭代法-中序遍历
> 利用二叉搜索树特性,在历遍过程中更新结果,一次历遍
> 但需要使用额外空间存储历遍的节点
```python ```python
class Solution: class Solution:
def findMode(self, root: TreeNode) -> List[int]: def __init__(self):
stack = [] self.maxCount = 0 # 最大频率
self.count = 0 # 统计频率
self.pre = None
self.result = []
def searchBST(self, cur):
if cur is None:
return
self.searchBST(cur.left) # 左
# 中
if self.pre is None: # 第一个节点
self.count = 1
elif self.pre.val == cur.val: # 与前一个节点数值相同
self.count += 1
else: # 与前一个节点数值不同
self.count = 1
self.pre = cur # 更新上一个节点
if self.count == self.maxCount: # 如果与最大值频率相同放进result中
self.result.append(cur.val)
if self.count > self.maxCount: # 如果计数大于最大值频率
self.maxCount = self.count # 更新最大频率
self.result = [cur.val] # 很关键的一步不要忘记清空result之前result里的元素都失效了
self.searchBST(cur.right) # 右
return
def findMode(self, root):
self.count = 0
self.maxCount = 0
self.pre = None # 记录前一个节点
self.result = []
self.searchBST(root)
return self.result
```
迭代法
```python
class Solution:
def findMode(self, root):
st = []
cur = root cur = root
pre = None pre = None
maxCount, count = 0, 0 maxCount = 0 # 最大频率
res = [] count = 0 # 统计频率
while cur or stack: result = []
if cur: # 指针来访问节点,访问到最底层
stack.append(cur) while cur is not None or st:
cur = cur.left if cur is not None: # 指针来访问节点,访问到最底层
else: # 逐一处理节点 st.append(cur) # 将访问的节点放进栈
cur = stack.pop() cur = cur.left # 左
if pre == None: # 第一个节点 else:
cur = st.pop()
if pre is None: # 第一个节点
count = 1 count = 1
elif pre.val == cur.val: # 与前一个节点数值相同 elif pre.val == cur.val: # 与前一个节点数值相同
count += 1 count += 1
else: else: # 与前一个节点数值不同
count = 1 count = 1
if count == maxCount:
res.append(cur.val) if count == maxCount: # 如果和最大值相同放进result中
if count > maxCount: result.append(cur.val)
maxCount = count
res.clear() if count > maxCount: # 如果计数大于最大值频率
res.append(cur.val) maxCount = count # 更新最大频率
result = [cur.val] # 很关键的一步不要忘记清空result之前result里的元素都失效了
pre = cur pre = cur
cur = cur.right cur = cur.right # 右
return res
return result
``` ```
## Go ## Go

View File

@ -237,66 +237,82 @@ class Solution {
``` ```
## Python ## Python
递归 递归法(版本一)利用中序递增,结合数组
```python ```python
class Solution: class Solution:
def getMinimumDifference(self, root: TreeNode) -> int: def __init__(self):
res = [] self.vec = []
r = float("inf")
def buildaList(root): //把二叉搜索树转换成有序数组
if not root: return None
if root.left: buildaList(root.left) //
res.append(root.val) //
if root.right: buildaList(root.right) //
return res
buildaList(root)
for i in range(len(res)-1): // 统计有序数组的最小差值
r = min(abs(res[i]-res[i+1]),r)
return r
class Solution: # 双指针法,不用数组 (同Carl写法) - 更快
def getMinimumDifference(self, root: Optional[TreeNode]) -> int:
global pre,minval
pre = None
minval = 10**5
self.traversal(root)
return minval
def traversal(self, root): def traversal(self, root):
global pre,minval if root is None:
if not root: return None return
self.traversal(root.left) self.traversal(root.left)
if pre and root.val-pre.val<minval: self.vec.append(root.val) # 将二叉搜索树转换为有序数组
minval = root.val-pre.val
pre = root
self.traversal(root.right) self.traversal(root.right)
```
def getMinimumDifference(self, root):
迭代法-中序遍历 self.vec = []
```python self.traversal(root)
class Solution: if len(self.vec) < 2:
def getMinimumDifference(self, root: TreeNode) -> int: return 0
stack = []
cur = root
pre = None
result = float('inf') result = float('inf')
while cur or stack: for i in range(1, len(self.vec)):
if cur: # 指针来访问节点,访问到最底层 # 统计有序数组的最小差值
stack.append(cur) result = min(result, self.vec[i] - self.vec[i - 1])
cur = cur.left
else: # 逐一处理节点
cur = stack.pop()
if pre: # 当前节点和前节点的值的差值
result = min(result, abs(cur.val - pre.val))
pre = cur
cur = cur.right
return result return result
``` ```
递归法(版本二)利用中序递增,找到该树最小值
```python
class Solution:
def __init__(self):
self.result = float('inf')
self.pre = None
def traversal(self, cur):
if cur is None:
return
self.traversal(cur.left) # 左
if self.pre is not None: # 中
self.result = min(self.result, cur.val - self.pre.val)
self.pre = cur # 记录前一个
self.traversal(cur.right) # 右
def getMinimumDifference(self, root):
self.traversal(root)
return self.result
```
迭代法
```python
class Solution:
def getMinimumDifference(self, root):
stack = []
cur = root
pre = None
result = float('inf')
while cur is not None or len(stack) > 0:
if cur is not None:
stack.append(cur) # 将访问的节点放进栈
cur = cur.left # 左
else:
cur = stack.pop()
if pre is not None: # 中
result = min(result, cur.val - pre.val)
pre = cur
cur = cur.right # 右
return result
```
## Go ## Go
中序遍历,然后计算最小差值 中序遍历,然后计算最小差值

View File

@ -200,8 +200,30 @@ class Solution {
``` ```
## Python ## Python
**递归** 递归法(版本一)
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def convertBST(self, root: TreeNode) -> TreeNode:
self.pre = 0 # 记录前一个节点的数值
self.traversal(root)
return root
def traversal(self, cur):
if cur is None:
return
self.traversal(cur.right)
cur.val += self.pre
self.pre = cur.val
self.traversal(cur.left)
```
递归法(版本二)
```python ```python
# Definition for a binary tree node. # Definition for a binary tree node.
# class TreeNode: # class TreeNode:
@ -234,7 +256,32 @@ class Solution:
return root return root
``` ```
**迭代** 迭代法(版本一)
```python
class Solution:
def __init__(self):
self.pre = 0 # 记录前一个节点的数值
def traversal(self, root):
stack = []
cur = root
while cur or stack:
if cur:
stack.append(cur)
cur = cur.right # 右
else:
cur = stack.pop() # 中
cur.val += self.pre
self.pre = cur.val
cur = cur.left # 左
def convertBST(self, root):
self.pre = 0
self.traversal(root)
return root
```
迭代法版本二
```python ```python
class Solution: class Solution:
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]: def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:

View File

@ -271,64 +271,72 @@ class Solution {
## Python ## Python
**递归** 递归法(版本一)
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode: def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:
''' if root is None:
确认递归函数参数以及返回值返回更新后剪枝后的当前root节点 return None
'''
# Base Case
if not root: return None
# 单层递归逻辑
if root.val < low: if root.val < low:
# 若当前root节点小于左界只考虑其右子树用于替代更新后的其本身抛弃其左子树整体 # 寻找符合区间 [low, high] 的节点
return self.trimBST(root.right, low, high) return self.trimBST(root.right, low, high)
if root.val > high:
if high < root.val: # 寻找符合区间 [low, high] 的节点
# 若当前root节点大于右界只考虑其左子树用于替代更新后的其本身抛弃其右子树整体
return self.trimBST(root.left, low, high) return self.trimBST(root.left, low, high)
root.left = self.trimBST(root.left, low, high) # root.left 接入符合条件的左孩子
if low <= root.val <= high: root.right = self.trimBST(root.right, low, high) # root.right 接入符合条件的右孩子
root.left = self.trimBST(root.left, low, high)
root.right = self.trimBST(root.right, low, high)
# 返回更新后的剪枝过的当前节点root
return root return root
``` ```
递归法(版本二)精简
**迭代**
```python ```python
class Solution: class Solution:
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]: def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:
if not root: return root if root is None:
# 处理头结点让root移动到[L, R] 范围内,注意是左闭右开 return None
while root and (root.val < low or root.val > high): if root.val < low:
if root.val < low: # 小于L往右走 return self.trimBST(root.right, low, high)
root = root.right if root.val > high:
else: # 大于R往左走 return self.trimBST(root.left, low, high)
root = root.left root.left = self.trimBST(root.left, low, high)
# 此时root已经在[L, R] 范围内处理左孩子元素小于L的情况 root.right = self.trimBST(root.right, low, high)
return root
```
迭代法
```python
class Solution:
def trimBST(self, root: TreeNode, L: int, R: int) -> TreeNode:
if not root:
return None
# 处理头结点让root移动到[L, R] 范围内,注意是左闭右闭
while root and (root.val < L or root.val > R):
if root.val < L:
root = root.right # 小于L往右走
else:
root = root.left # 大于R往左走
cur = root cur = root
# 此时root已经在[L, R] 范围内处理左孩子元素小于L的情况
while cur: while cur:
while cur.left and cur.left.val < low: while cur.left and cur.left.val < L:
cur.left = cur.left.right cur.left = cur.left.right
cur = cur.left cur = cur.left
# 此时root已经在[L, R] 范围内处理右孩子大于R的情况
cur = root cur = root
# 此时root已经在[L, R] 范围内处理右孩子大于R的情况
while cur: while cur:
while cur.right and cur.right.val > high: while cur.right and cur.right.val > R:
cur.right = cur.right.left cur.right = cur.right.left
cur = cur.right cur = cur.right
return root return root
``` ```
## Go ## Go

View File

@ -256,133 +256,104 @@ class Solution {
----- -----
## Python ## Python
**递归法** - 有返回值 递归法(版本一)
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode: def __init__(self):
# 返回更新后的以当前root为根节点的新树方便用于更新上一层的父子节点关系链 self.parent = None
# Base Case def traversal(self, cur, val):
if not root: return TreeNode(val) if cur is None:
node = TreeNode(val)
if val > self.parent.val:
self.parent.right = node
else:
self.parent.left = node
return
# 单层递归逻辑: self.parent = cur
if val < root.val: if cur.val > val:
# 将val插入至当前root的左子树中合适的位置 self.traversal(cur.left, val)
# 并更新当前root的左子树为包含目标val的新左子树 if cur.val < val:
root.left = self.insertIntoBST(root.left, val) self.traversal(cur.right, val)
if root.val < val: def insertIntoBST(self, root, val):
# 将val插入至当前root的右子树中合适的位置 self.parent = TreeNode(0)
# 并更新当前root的右子树为包含目标val的新右子树 if root is None:
root.right = self.insertIntoBST(root.right, val) return TreeNode(val)
self.traversal(root, val)
# 返回更新后的以当前root为根节点的新树
return root return root
``` ```
**递归法** - 无返回值 递归法(版本二)
```python ```python
class Solution: class Solution:
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode: def insertIntoBST(self, root, val):
if not root: if root is None:
return TreeNode(val) return TreeNode(val)
parent = None parent = None
def __traverse(cur: TreeNode, val: int) -> None:
# 在函数运行的同时把新节点插入到该被插入的地方.
nonlocal parent
if not cur:
new_node = TreeNode(val)
if parent.val < val:
parent.right = new_node
else:
parent.left = new_node
return
parent = cur # 重点: parent的作用只有运行到上面if not cur:才会发挥出来.
if cur.val < val:
__traverse(cur.right, val)
else:
__traverse(cur.left, val)
return
__traverse(root, val)
return root
```
**递归法** - 无返回值 - another easier way
```python
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
newNode = TreeNode(val)
if not root: return newNode
if not root.left and val < root.val:
root.left = newNode
if not root.right and val > root.val:
root.right = newNode
if val < root.val:
self.insertIntoBST(root.left, val)
if val > root.val:
self.insertIntoBST(root.right, val)
return root
```
**递归法** - 无返回值 有注释 不用Helper function
```python
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root: # for root==None
return TreeNode(val)
if root.val<val:
if root.right==None: # find the parent
root.right = TreeNode(val)
else: # not found, keep searching
self.insertIntoBST(root.right, val)
if root.val>val:
if root.left==None: # found the parent
root.left = TreeNode(val)
else: # not found, keep searching
self.insertIntoBST(root.left, val)
# return the final tree
return root
```
**迭代法**
与无返回值的递归函数的思路大体一致
```python
class Solution:
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
if not root:
return TreeNode(val)
parent = None # 此步可以省略
cur = root cur = root
# 用while循环不断地找新节点的parent
while cur: while cur:
parent = cur # 首先保存当前非空节点作为下一次迭代的父节点 parent = cur
if cur.val < val: if val < cur.val:
cur = cur.right
elif cur.val > val:
cur = cur.left cur = cur.left
else:
# 运行到这意味着已经跳出上面的while循环, cur = cur.right
# 同时意味着新节点的parent已经被找到. if val < parent.val:
# parent已被找到, 新节点已经ready. 把两个节点黏在一起就好了.
if parent.val > val:
parent.left = TreeNode(val) parent.left = TreeNode(val)
else: else:
parent.right = TreeNode(val) parent.right = TreeNode(val)
return root
```
递归法(版本三)
```python
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if root is None or root.val == val:
return TreeNode(val)
elif root.val > val:
if root.left is None:
root.left = TreeNode(val)
else:
self.insertIntoBST(root.left, val)
elif root.val < val:
if root.right is None:
root.right = TreeNode(val)
else:
self.insertIntoBST(root.right, val)
return root
```
迭代法
```python
class Solution:
def insertIntoBST(self, root, val):
if root is None: # 如果根节点为空,创建新节点作为根节点并返回
node = TreeNode(val)
return node
cur = root
parent = root # 记录上一个节点,用于连接新节点
while cur is not None:
parent = cur
if cur.val > val:
cur = cur.left
else:
cur = cur.right
node = TreeNode(val)
if val < parent.val:
parent.left = node # 将新节点连接到父节点的左子树
else:
parent.right = node # 将新节点连接到父节点的右子树
return root return root
``` ```
----- -----
## Go ## Go