Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 87 additions & 91 deletions problems/0098.验证二叉搜索树.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,117 +341,113 @@ class Solution {

## Python

**递归** - 利用BST中序遍历特性,把树"压缩"成数组
递归法(版本一)利用中序递增性质,转换成数组
```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 isValidBST(self, root: TreeNode) -> bool:
# 思路: 利用BST中序遍历的特性.
# 中序遍历输出的二叉搜索树节点的数值是有序序列
candidate_list = []

def __traverse(root: TreeNode) -> None:
nonlocal candidate_list
if not root:
return
__traverse(root.left)
candidate_list.append(root.val)
__traverse(root.right)

def __is_sorted(nums: list) -> bool:
for i in range(1, len(nums)):
if nums[i] <= nums[i - 1]: # ⚠️ 注意: Leetcode定义二叉搜索树中不能有重复元素
return False
return True

__traverse(root)
res = __is_sorted(candidate_list)

return res
def __init__(self):
self.vec = []

def traversal(self, root):
if root is None:
return
self.traversal(root.left)
self.vec.append(root.val) # 将二叉搜索树转换为有序数组
self.traversal(root.right)

def isValidBST(self, root):
self.vec = [] # 清空数组
self.traversal(root)
for i in range(1, len(self.vec)):
# 注意要小于等于,搜索树里不能有相同元素
if self.vec[i] <= self.vec[i - 1]:
return False
return True

```

**递归** - 标准做法
递归法(版本二)设定极小值,进行比较

```python
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
# 规律: BST的中序遍历节点数值是从小到大.
cur_max = -float("INF")
def __isValidBST(root: TreeNode) -> bool:
nonlocal cur_max

if not root:
return True

is_left_valid = __isValidBST(root.left)
if cur_max < root.val:
cur_max = root.val
else:
return False
is_right_valid = __isValidBST(root.right)

return is_left_valid and is_right_valid
return __isValidBST(root)
def __init__(self):
self.maxVal = float('-inf') # 因为后台测试数据中有int最小值

def isValidBST(self, root):
if root is None:
return True

left = self.isValidBST(root.left)
# 中序遍历,验证遍历的元素是不是从小到大
if self.maxVal < root.val:
self.maxVal = root.val
else:
return False
right = self.isValidBST(root.right)

return left and right

```
**递归** - 避免初始化最小值做法:
递归法(版本三)直接取该树的最小值
```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 isValidBST(self, root: TreeNode) -> bool:
# 规律: BST的中序遍历节点数值是从小到大.
pre = None
def __isValidBST(root: TreeNode) -> bool:
nonlocal pre

if not root:
return True

is_left_valid = __isValidBST(root.left)
if pre and pre.val>=root.val: return False
pre = root
is_right_valid = __isValidBST(root.right)

return is_left_valid and is_right_valid
return __isValidBST(root)
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



```
迭代法
```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 isValidBST(self, root: TreeNode) -> bool:
def isValidBST(self, root):
stack = []
cur = root
pre = None
while cur or stack:
if cur: # 指针来访问节点,访问到最底层
pre = None # 记录前一个节点
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 and cur.val <= pre.val: # 比较当前节点和前节点的值的大小
cur = cur.left # 左
else:
cur = stack.pop() # 中
if pre is not None and cur.val <= pre.val:
return False
pre = cur
cur = cur.right
pre = cur # 保存前一个访问的结点
cur = cur.right # 右
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

Expand Down
100 changes: 46 additions & 54 deletions problems/0108.将有序数组转换为二叉搜索树.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,73 +316,65 @@ class Solution {
```

## 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 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:
# Base Case
if left > right:
return None

# 确定左右界的中心,防越界
mid = left + (right - left) // 2
# 构建根节点
mid_root = TreeNode(nums[mid])
# 构建以左右界的中心为分割点的左右子树
mid_root.left = self.traversal(nums, left, mid-1)
mid_root.right = self.traversal(nums, mid+1, right)

# 返回由被传入的左右界定义的某子树的根节点
return mid_root
root = TreeNode(nums[mid])
root.left = self.traversal(nums, left, mid - 1)
root.right = self.traversal(nums, mid + 1, right)
return root

def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
root = self.traversal(nums, 0, len(nums) - 1)
return root

```

**迭代**(左闭右开)
迭代法
```python
from collections import deque

class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if len(nums) == 0: return None
root = TreeNode() # 初始化
nodeSt = [root]
leftSt = [0]
rightSt = [len(nums)]

while nodeSt:
node = nodeSt.pop() # 处理根节点
left = leftSt.pop()
right = rightSt.pop()
mid = left + (right - left) // 2
node.val = nums[mid]

if left < mid: # 处理左区间
node.left = TreeNode()
nodeSt.append(node.left)
leftSt.append(left)
rightSt.append(mid)

if right > mid + 1: # 处理右区间
node.right = TreeNode()
nodeSt.append(node.right)
leftSt.append(mid + 1)
rightSt.append(right)
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
if len(nums) == 0:
return None

root = TreeNode(0) # 初始根节点
nodeQue = deque() # 放遍历的节点
leftQue = deque() # 保存左区间下标
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

curNode.val = nums[mid] # 将mid对应的元素给中间节点

if left <= mid - 1: # 处理左区间
curNode.left = TreeNode(0)
nodeQue.append(curNode.left)
leftQue.append(left)
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

```

## Go
Expand Down
22 changes: 10 additions & 12 deletions problems/0110.平衡二叉树.md
Original file line number Diff line number Diff line change
Expand Up @@ -536,18 +536,16 @@ class Solution:

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


Expand Down
Loading