mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-09 19:44:45 +08:00
Merge branch 'youngyangyang04:master' into master
This commit is contained in:
@ -41,7 +41,7 @@
|
||||
|
||||
那么我们就应该想到使用哈希法了。
|
||||
|
||||
因为本地,我们不仅要知道元素有没有遍历过,还有知道这个元素对应的下标,**需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适**。
|
||||
因为本地,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,**需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适**。
|
||||
|
||||
再来看一下使用数组和set来做哈希法的局限。
|
||||
|
||||
|
@ -191,8 +191,8 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
* 时间复杂度:$O(\log n)$
|
||||
* 时间复杂度:$O(1)$
|
||||
* 时间复杂度:O(log n)
|
||||
* 空间复杂度:O(1)
|
||||
|
||||
## 总结
|
||||
|
||||
|
@ -371,117 +371,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 __init__(self):
|
||||
self.vec = []
|
||||
|
||||
def __traverse(root: TreeNode) -> None:
|
||||
nonlocal candidate_list
|
||||
if not root:
|
||||
def traversal(self, root):
|
||||
if root is None:
|
||||
return
|
||||
__traverse(root.left)
|
||||
candidate_list.append(root.val)
|
||||
__traverse(root.right)
|
||||
self.traversal(root.left)
|
||||
self.vec.append(root.val) # 将二叉搜索树转换为有序数组
|
||||
self.traversal(root.right)
|
||||
|
||||
def __is_sorted(nums: list) -> bool:
|
||||
for i in range(1, len(nums)):
|
||||
if nums[i] <= nums[i - 1]: # ⚠️ 注意: Leetcode定义二叉搜索树中不能有重复元素
|
||||
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
|
||||
|
||||
__traverse(root)
|
||||
res = __is_sorted(candidate_list)
|
||||
|
||||
return res
|
||||
```
|
||||
|
||||
**递归** - 标准做法
|
||||
递归法(版本二)设定极小值,进行比较
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def isValidBST(self, root: TreeNode) -> bool:
|
||||
# 规律: BST的中序遍历节点数值是从小到大.
|
||||
cur_max = -float("INF")
|
||||
def __isValidBST(root: TreeNode) -> bool:
|
||||
nonlocal cur_max
|
||||
def __init__(self):
|
||||
self.maxVal = float('-inf') # 因为后台测试数据中有int最小值
|
||||
|
||||
if not root:
|
||||
def isValidBST(self, root):
|
||||
if root is None:
|
||||
return True
|
||||
|
||||
is_left_valid = __isValidBST(root.left)
|
||||
if cur_max < root.val:
|
||||
cur_max = root.val
|
||||
left = self.isValidBST(root.left)
|
||||
# 中序遍历,验证遍历的元素是不是从小到大
|
||||
if self.maxVal < root.val:
|
||||
self.maxVal = root.val
|
||||
else:
|
||||
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
|
||||
# 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
|
||||
def __init__(self):
|
||||
self.pre = None # 用来记录前一个节点
|
||||
|
||||
if not root:
|
||||
def isValidBST(self, root):
|
||||
if root is None:
|
||||
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)
|
||||
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
|
||||
|
||||
|
||||
|
||||
return is_left_valid and is_right_valid
|
||||
return __isValidBST(root)
|
||||
```
|
||||
迭代法
|
||||
```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
|
||||
|
||||
|
@ -400,8 +400,6 @@ public:
|
||||
};
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
|
||||
# 105.从前序与中序遍历序列构造二叉树
|
||||
|
||||
@ -692,38 +690,6 @@ class Solution {
|
||||
|
||||
## Python
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
|
||||
# 第一步: 特殊情况讨论: 树为空. 或者说是递归终止条件
|
||||
if not postorder:
|
||||
return
|
||||
|
||||
# 第二步: 后序遍历的最后一个就是当前的中间节点
|
||||
root_val = postorder[-1]
|
||||
root = TreeNode(root_val)
|
||||
|
||||
# 第三步: 找切割点.
|
||||
root_index = inorder.index(root_val)
|
||||
|
||||
# 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
|
||||
left_inorder = inorder[:root_index]
|
||||
right_inorder = inorder[root_index + 1:]
|
||||
|
||||
# 第五步: 切割postorder数组. 得到postorder数组的左,右半边.
|
||||
# ⭐️ 重点1: 中序数组大小一定跟后序数组大小是相同的.
|
||||
left_postorder = postorder[:len(left_inorder)]
|
||||
right_postorder = postorder[len(left_inorder): len(postorder) - 1]
|
||||
|
||||
|
||||
# 第六步: 递归
|
||||
root.left = self.buildTree(left_inorder, left_postorder)
|
||||
root.right = self.buildTree(right_inorder, right_postorder)
|
||||
|
||||
# 第七步: 返回答案
|
||||
return root
|
||||
```
|
||||
|
||||
105.从前序与中序遍历序列构造二叉树
|
||||
|
||||
```python
|
||||
@ -752,7 +718,7 @@ class Solution:
|
||||
# 第六步: 递归
|
||||
root.left = self.buildTree(preorder_left, inorder_left)
|
||||
root.right = self.buildTree(preorder_right, inorder_right)
|
||||
|
||||
# 第七步: 返回答案
|
||||
return root
|
||||
```
|
||||
|
||||
@ -784,7 +750,7 @@ class Solution:
|
||||
# 第六步: 递归
|
||||
root.left = self.buildTree(inorder_left, postorder_left)
|
||||
root.right = self.buildTree(inorder_right, postorder_right)
|
||||
|
||||
# 第七步: 返回答案
|
||||
return root
|
||||
```
|
||||
|
||||
|
@ -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)
|
||||
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
|
||||
|
||||
# 返回由被传入的左右界定义的某子树的根节点
|
||||
return mid_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)]
|
||||
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
|
||||
if len(nums) == 0:
|
||||
return None
|
||||
|
||||
while nodeSt:
|
||||
node = nodeSt.pop() # 处理根节点
|
||||
left = leftSt.pop()
|
||||
right = rightSt.pop()
|
||||
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
|
||||
node.val = nums[mid]
|
||||
|
||||
if left < mid: # 处理左区间
|
||||
node.left = TreeNode()
|
||||
nodeSt.append(node.left)
|
||||
leftSt.append(left)
|
||||
rightSt.append(mid)
|
||||
curNode.val = nums[mid] # 将mid对应的元素给中间节点
|
||||
|
||||
if right > mid + 1: # 处理右区间
|
||||
node.right = TreeNode()
|
||||
nodeSt.append(node.right)
|
||||
leftSt.append(mid + 1)
|
||||
rightSt.append(right)
|
||||
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
|
||||
|
@ -536,16 +536,14 @@ class Solution:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def isBalanced(self, root: TreeNode) -> bool:
|
||||
return self.height(root) != -1
|
||||
def height(self, node: TreeNode) -> int:
|
||||
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.height(node.left)
|
||||
if left == -1:
|
||||
return -1
|
||||
right = self.height(node.right)
|
||||
if right == -1 or abs(left - right) > 1:
|
||||
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
|
||||
```
|
||||
@ -553,6 +551,52 @@ class Solution:
|
||||
|
||||
迭代法:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def getDepth(self, cur):
|
||||
st = []
|
||||
if cur is not None:
|
||||
st.append(cur)
|
||||
depth = 0
|
||||
result = 0
|
||||
while st:
|
||||
node = st[-1]
|
||||
if node is not None:
|
||||
st.pop()
|
||||
st.append(node) # 中
|
||||
st.append(None)
|
||||
depth += 1
|
||||
if node.right:
|
||||
st.append(node.right) # 右
|
||||
if node.left:
|
||||
st.append(node.left) # 左
|
||||
|
||||
else:
|
||||
node = st.pop()
|
||||
st.pop()
|
||||
depth -= 1
|
||||
result = max(result, depth)
|
||||
return result
|
||||
|
||||
def isBalanced(self, root):
|
||||
st = []
|
||||
if root is None:
|
||||
return True
|
||||
st.append(root)
|
||||
while st:
|
||||
node = st.pop() # 中
|
||||
if abs(self.getDepth(node.left) - self.getDepth(node.right)) > 1:
|
||||
return False
|
||||
if node.right:
|
||||
st.append(node.right) # 右(空节点不入栈)
|
||||
if node.left:
|
||||
st.append(node.left) # 左(空节点不入栈)
|
||||
return True
|
||||
|
||||
```
|
||||
|
||||
迭代法精简版:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def isBalanced(self, root: Optional[TreeNode]) -> bool:
|
||||
@ -576,8 +620,6 @@ class Solution:
|
||||
height_map[real_node] = 1 + max(left, right)
|
||||
return True
|
||||
```
|
||||
|
||||
|
||||
### Go
|
||||
|
||||
```Go
|
||||
|
@ -302,36 +302,72 @@ 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 minDepth(self, root: TreeNode) -> int:
|
||||
if not root:
|
||||
def getDepth(self, node):
|
||||
if node is None:
|
||||
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:
|
||||
left_depth = self.minDepth(root.left)
|
||||
if root.right:
|
||||
right_depth = self.minDepth(root.right)
|
||||
result = 1 + min(leftDepth, rightDepth)
|
||||
return result
|
||||
|
||||
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
|
||||
# Definition for a binary tree node.
|
||||
@ -364,39 +400,7 @@ class Solution:
|
||||
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
|
||||
|
||||
|
@ -991,6 +991,53 @@ impl Solution {
|
||||
}
|
||||
```
|
||||
|
||||
### C#
|
||||
|
||||
```csharp
|
||||
//递归
|
||||
public class Solution {
|
||||
public TreeNode InvertTree(TreeNode root) {
|
||||
if (root == null) return root;
|
||||
|
||||
swap(root);
|
||||
InvertTree(root.left);
|
||||
InvertTree(root.right);
|
||||
return root;
|
||||
}
|
||||
|
||||
public void swap(TreeNode node) {
|
||||
TreeNode temp = node.left;
|
||||
node.left = node.right;
|
||||
node.right = temp;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```csharp
|
||||
//迭代
|
||||
public class Solution {
|
||||
public TreeNode InvertTree(TreeNode root) {
|
||||
if (root == null) return null;
|
||||
Stack<TreeNode> stack=new Stack<TreeNode>();
|
||||
stack.Push(root);
|
||||
while(stack.Count>0)
|
||||
{
|
||||
TreeNode node = stack.Pop();
|
||||
swap(node);
|
||||
if(node.right!=null) stack.Push(node.right);
|
||||
if(node.left!=null) stack.Push(node.left);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
public void swap(TreeNode node) {
|
||||
TreeNode temp = node.left;
|
||||
node.left = node.right;
|
||||
node.right = temp;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -275,34 +275,57 @@ class Solution {
|
||||
|
||||
## Python
|
||||
|
||||
递归法:
|
||||
递归法(版本一)
|
||||
```python
|
||||
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 root.val > p.val and root.val > q.val:
|
||||
return self.lowestCommonAncestor(root.left, p, q)
|
||||
if root.val < p.val and root.val < q.val:
|
||||
return self.lowestCommonAncestor(root.right, p, q)
|
||||
return root
|
||||
if cur.val < p.val and cur.val < q.val: # 右
|
||||
right = self.traversal(cur.right, p, q)
|
||||
if right is not None:
|
||||
return right
|
||||
|
||||
return cur
|
||||
|
||||
def lowestCommonAncestor(self, root, p, q):
|
||||
return self.traversal(root, p, q)
|
||||
```
|
||||
|
||||
迭代法:
|
||||
迭代法(版本二)精简
|
||||
```python
|
||||
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:
|
||||
root = root.left
|
||||
elif root.val < p.val and root.val < q.val:
|
||||
root = root.right
|
||||
else:
|
||||
return root
|
||||
```
|
||||
return None
|
||||
|
||||
|
||||
```
|
||||
## Go
|
||||
|
||||
递归法:
|
||||
|
@ -274,25 +274,44 @@ class Solution {
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
递归法(版本一)
|
||||
```python
|
||||
class Solution:
|
||||
"""二叉树的最近公共祖先 递归法"""
|
||||
|
||||
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
|
||||
if not root or root == p or root == q:
|
||||
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 and right:
|
||||
if left is not None and right is not None:
|
||||
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
|
||||
|
@ -470,70 +470,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
|
||||
import copy
|
||||
from typing import List, Optional
|
||||
|
||||
class Solution:
|
||||
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
|
||||
if not root:
|
||||
return []
|
||||
result = []
|
||||
self.generate_paths(root, [], result)
|
||||
return result
|
||||
|
||||
def generate_paths(self, node: TreeNode, path: List[int], result: List[str]) -> None:
|
||||
path.append(node.val)
|
||||
if not node.left and not node.right:
|
||||
result.append('->'.join(map(str, path)))
|
||||
if node.left:
|
||||
self.generate_paths(node.left, copy.copy(path), result)
|
||||
if node.right:
|
||||
self.generate_paths(node.right, copy.copy(path), result)
|
||||
path.pop()
|
||||
|
||||
|
||||
```
|
||||
递归法+回溯(版本二)
|
||||
```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
|
||||
import copy
|
||||
from typing import List, Optional
|
||||
|
||||
class Solution:
|
||||
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
|
||||
if not root:
|
||||
return []
|
||||
result = []
|
||||
self.generate_paths(root, [], result)
|
||||
return result
|
||||
|
||||
def generate_paths(self, node: TreeNode, path: List[int], result: List[str]) -> None:
|
||||
if not node:
|
||||
def traversal(self, cur, path, result):
|
||||
path.append(cur.val) # 中
|
||||
if not cur.left and not cur.right: # 到达叶子节点
|
||||
sPath = '->'.join(map(str, path))
|
||||
result.append(sPath)
|
||||
return
|
||||
path.append(node.val)
|
||||
if not node.left and not node.right:
|
||||
if cur.left: # 左
|
||||
self.traversal(cur.left, path, result)
|
||||
path.pop() # 回溯
|
||||
if cur.right: # 右
|
||||
self.traversal(cur.right, path, result)
|
||||
path.pop() # 回溯
|
||||
|
||||
def binaryTreePaths(self, root):
|
||||
result = []
|
||||
path = []
|
||||
if not root:
|
||||
return result
|
||||
self.traversal(root, path, result)
|
||||
return result
|
||||
|
||||
|
||||
```
|
||||
递归法+隐形回溯(版本一)
|
||||
```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
|
||||
from typing import List, Optional
|
||||
|
||||
class Solution:
|
||||
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
|
||||
if not root:
|
||||
return []
|
||||
result = []
|
||||
self.traversal(root, [], result)
|
||||
return result
|
||||
|
||||
def traversal(self, cur: TreeNode, path: List[int], result: List[str]) -> None:
|
||||
if not cur:
|
||||
return
|
||||
path.append(cur.val)
|
||||
if not cur.left and not cur.right:
|
||||
result.append('->'.join(map(str, path)))
|
||||
else:
|
||||
self.generate_paths(node.left, copy.copy(path), result)
|
||||
self.generate_paths(node.right, copy.copy(path), result)
|
||||
path.pop()
|
||||
if cur.left:
|
||||
self.traversal(cur.left, path[:], result)
|
||||
if cur.right:
|
||||
self.traversal(cur.right, path[:], result)
|
||||
|
||||
```
|
||||
|
||||
递归法+隐形回溯
|
||||
递归法+隐形回溯(版本二)
|
||||
```Python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
@ -566,16 +561,11 @@ class Solution:
|
||||
迭代法:
|
||||
|
||||
```Python
|
||||
from collections import deque
|
||||
|
||||
|
||||
class Solution:
|
||||
"""二叉树的所有路径 迭代法"""
|
||||
|
||||
def binaryTreePaths(self, root: TreeNode) -> List[str]:
|
||||
# 题目中节点数至少为1
|
||||
stack, path_st, result = deque([root]), deque(), []
|
||||
path_st.append(str(root.val))
|
||||
stack, path_st, result = [root], [str(root.val)], []
|
||||
|
||||
while stack:
|
||||
cur = stack.pop()
|
||||
|
@ -149,7 +149,7 @@ class Solution:
|
||||
if len(nums) <= 1:
|
||||
return len(nums)
|
||||
dp = [1] * len(nums)
|
||||
result = 0
|
||||
result = 1
|
||||
for i in range(1, len(nums)):
|
||||
for j in range(0, i):
|
||||
if nums[i] > nums[j]:
|
||||
|
@ -247,8 +247,7 @@ class Solution {
|
||||
|
||||
|
||||
### Python
|
||||
|
||||
**递归后序遍历**
|
||||
递归
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
@ -257,47 +256,64 @@ class Solution {
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
class Solution:
|
||||
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
|
||||
if not root:
|
||||
def sumOfLeftLeaves(self, root):
|
||||
if root is None:
|
||||
return 0
|
||||
if root.left is None and root.right is None:
|
||||
return 0
|
||||
|
||||
# 检查根节点的左子节点是否为叶节点
|
||||
if root.left and not root.left.left and not root.left.right:
|
||||
left_val = root.left.val
|
||||
else:
|
||||
left_val = self.sumOfLeftLeaves(root.left)
|
||||
leftValue = self.sumOfLeftLeaves(root.left) # 左
|
||||
if root.left and not root.left.left and not root.left.right: # 左子树是左叶子的情况
|
||||
leftValue = root.left.val
|
||||
|
||||
# 递归地计算右子树左叶节点的和
|
||||
right_val = self.sumOfLeftLeaves(root.right)
|
||||
rightValue = self.sumOfLeftLeaves(root.right) # 右
|
||||
|
||||
return left_val + right_val
|
||||
sum_val = leftValue + rightValue # 中
|
||||
return sum_val
|
||||
```
|
||||
递归精简版
|
||||
|
||||
```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 sumOfLeftLeaves(self, root):
|
||||
if root is None:
|
||||
return 0
|
||||
leftValue = 0
|
||||
if root.left is not None and root.left.left is None and root.left.right is None:
|
||||
leftValue = root.left.val
|
||||
return leftValue + self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.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 sumOfLeftLeaves(self, root: TreeNode) -> int:
|
||||
"""
|
||||
Idea: Each time check current node's left node.
|
||||
If current node don't have one, skip it.
|
||||
"""
|
||||
stack = []
|
||||
if root:
|
||||
stack.append(root)
|
||||
res = 0
|
||||
def sumOfLeftLeaves(self, root):
|
||||
if root is None:
|
||||
return 0
|
||||
st = [root]
|
||||
result = 0
|
||||
while st:
|
||||
node = st.pop()
|
||||
if node.left and node.left.left is None and node.left.right is None:
|
||||
result += node.left.val
|
||||
if node.right:
|
||||
st.append(node.right)
|
||||
if node.left:
|
||||
st.append(node.left)
|
||||
return result
|
||||
|
||||
while stack:
|
||||
# 每次都把当前节点的左节点加进去.
|
||||
cur_node = stack.pop()
|
||||
if cur_node.left and not cur_node.left.left and not cur_node.left.right:
|
||||
res += cur_node.left.val
|
||||
|
||||
if cur_node.left:
|
||||
stack.append(cur_node.left)
|
||||
if cur_node.right:
|
||||
stack.append(cur_node.right)
|
||||
|
||||
return res
|
||||
```
|
||||
|
||||
### Go
|
||||
|
@ -295,19 +295,19 @@ var reconstructQueue = function(people) {
|
||||
|
||||
```Rust
|
||||
impl Solution {
|
||||
pub fn reconstruct_queue(people: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
|
||||
let mut people = people;
|
||||
pub fn reconstruct_queue(mut people: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
|
||||
let mut queue = vec![];
|
||||
people.sort_by(|a, b| {
|
||||
if a[0] == b[0] { return a[1].cmp(&b[1]); }
|
||||
if a[0] == b[0] {
|
||||
return a[1].cmp(&b[1]);
|
||||
}
|
||||
b[0].cmp(&a[0])
|
||||
});
|
||||
let mut que: Vec<Vec<i32>> = Vec::new();
|
||||
que.push(people[0].clone());
|
||||
for i in 1..people.len() {
|
||||
let position = people[i][1];
|
||||
que.insert(position as usize, people[i].clone());
|
||||
queue.push(people[0].clone());
|
||||
for v in people.iter().skip(1) {
|
||||
queue.insert(v[1] as usize, v.clone());
|
||||
}
|
||||
que
|
||||
queue
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -324,88 +324,90 @@ class Solution {
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
递归法(版本一)
|
||||
```python
|
||||
class Solution:
|
||||
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
|
||||
if not root : return None # 节点为空,返回
|
||||
if root.val < key :
|
||||
root.right = self.deleteNode(root.right, key)
|
||||
elif root.val > key :
|
||||
root.left = self.deleteNode(root.left, key)
|
||||
def deleteNode(self, root, key):
|
||||
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:
|
||||
# 当前节点的左子树为空,返回当前的右子树
|
||||
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
|
||||
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:
|
||||
root.right = self.deleteNode(root.right, key)
|
||||
return root
|
||||
```
|
||||
|
||||
**普通二叉树的删除方式**
|
||||
递归法(版本二)
|
||||
```python
|
||||
class Solution:
|
||||
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
|
||||
if not root: return root
|
||||
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)
|
||||
def deleteNode(self, root, key):
|
||||
if root is None: # 如果根节点为空,直接返回
|
||||
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
|
||||
class Solution:
|
||||
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
|
||||
# 找到节点后分两步,1. 把节点的左子树和右子树连起来,2. 把右子树跟父节点连起来
|
||||
# root is None
|
||||
if not root: return root
|
||||
p = root
|
||||
last = None
|
||||
while p:
|
||||
if p.val==key:
|
||||
# 1. connect left to right
|
||||
# right is not None -> left is None | left is not None
|
||||
if p.right:
|
||||
if p.left:
|
||||
node = p.right
|
||||
while node.left:
|
||||
node = node.left
|
||||
node.left = p.left
|
||||
right = p.right
|
||||
else:
|
||||
# right is None -> right=left
|
||||
right = p.left
|
||||
# 2. connect right to last
|
||||
if last==None:
|
||||
root = right
|
||||
elif last.val>key:
|
||||
last.left = right
|
||||
else:
|
||||
last.right = right
|
||||
# 3. return
|
||||
def deleteOneNode(self, target: TreeNode) -> TreeNode:
|
||||
"""
|
||||
将目标节点(删除节点)的左子树放到目标节点的右子树的最左面节点的左孩子位置上
|
||||
并返回目标节点右孩子为新的根节点
|
||||
是动画里模拟的过程
|
||||
"""
|
||||
if target is None:
|
||||
return target
|
||||
if target.right is None:
|
||||
return target.left
|
||||
cur = target.right
|
||||
while cur.left:
|
||||
cur = cur.left
|
||||
cur.left = target.left
|
||||
return target.right
|
||||
|
||||
def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
|
||||
if root is None:
|
||||
return root
|
||||
cur = root
|
||||
pre = None # 记录cur的父节点,用来删除cur
|
||||
while cur:
|
||||
if cur.val == key:
|
||||
break
|
||||
pre = cur
|
||||
if cur.val > key:
|
||||
cur = cur.left
|
||||
else:
|
||||
# Update last and continue
|
||||
last = p
|
||||
if p.val>key:
|
||||
p = p.left
|
||||
else:
|
||||
p = p.right
|
||||
cur = cur.right
|
||||
if pre is None: # 如果搜索树只有头结点
|
||||
return self.deleteOneNode(cur)
|
||||
# pre 要知道是删左孩子还是右孩子
|
||||
if pre.left and pre.left.val == key:
|
||||
pre.left = self.deleteOneNode(cur)
|
||||
if pre.right and pre.right.val == key:
|
||||
pre.right = self.deleteOneNode(cur)
|
||||
return root
|
||||
```
|
||||
|
||||
@ -680,6 +682,40 @@ object Solution {
|
||||
}
|
||||
```
|
||||
|
||||
## rust
|
||||
|
||||
```rust
|
||||
impl Solution {
|
||||
pub fn delete_node(
|
||||
root: Option<Rc<RefCell<TreeNode>>>,
|
||||
key: i32,
|
||||
) -> Option<Rc<RefCell<TreeNode>>> {
|
||||
root.as_ref()?;
|
||||
|
||||
let mut node = root.as_ref().unwrap().borrow_mut();
|
||||
match node.val.cmp(&key) {
|
||||
std::cmp::Ordering::Less => node.right = Self::delete_node(node.right.clone(), key),
|
||||
std::cmp::Ordering::Equal => match (node.left.clone(), node.right.clone()) {
|
||||
(None, None) => return None,
|
||||
(None, Some(r)) => return Some(r),
|
||||
(Some(l), None) => return Some(l),
|
||||
(Some(l), Some(r)) => {
|
||||
let mut cur = Some(r.clone());
|
||||
while let Some(n) = cur.clone().unwrap().borrow().left.clone() {
|
||||
cur = Some(n);
|
||||
}
|
||||
cur.unwrap().borrow_mut().left = Some(l);
|
||||
return Some(r);
|
||||
}
|
||||
},
|
||||
std::cmp::Ordering::Greater => node.left = Self::delete_node(node.left.clone(), key),
|
||||
}
|
||||
drop(node);
|
||||
root
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
|
||||
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
|
||||
|
@ -528,8 +528,7 @@ class Solution {
|
||||
|
||||
## Python
|
||||
|
||||
> 递归法
|
||||
> 常量空间,递归产生的栈不算
|
||||
递归法(版本一)利用字典
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
@ -538,77 +537,108 @@ class Solution {
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
from collections import defaultdict
|
||||
|
||||
class Solution:
|
||||
def __init__(self):
|
||||
self.pre = TreeNode()
|
||||
self.count = 0
|
||||
self.max_count = 0
|
||||
self.result = []
|
||||
def searchBST(self, cur, freq_map):
|
||||
if cur is None:
|
||||
return
|
||||
freq_map[cur.val] += 1 # 统计元素频率
|
||||
self.searchBST(cur.left, freq_map)
|
||||
self.searchBST(cur.right, freq_map)
|
||||
|
||||
def findMode(self, root: TreeNode) -> List[int]:
|
||||
if not root: return None
|
||||
self.search_BST(root)
|
||||
return self.result
|
||||
def findMode(self, root):
|
||||
freq_map = defaultdict(int) # key:元素,value:出现频率
|
||||
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
|
||||
class Solution:
|
||||
def findMode(self, root: TreeNode) -> List[int]:
|
||||
stack = []
|
||||
def __init__(self):
|
||||
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
|
||||
pre = None
|
||||
maxCount, count = 0, 0
|
||||
res = []
|
||||
while cur or stack:
|
||||
if cur: # 指针来访问节点,访问到最底层
|
||||
stack.append(cur)
|
||||
cur = cur.left
|
||||
else: # 逐一处理节点
|
||||
cur = stack.pop()
|
||||
if pre == None: # 第一个节点
|
||||
maxCount = 0 # 最大频率
|
||||
count = 0 # 统计频率
|
||||
result = []
|
||||
|
||||
while cur is not None or st:
|
||||
if cur is not None: # 指针来访问节点,访问到最底层
|
||||
st.append(cur) # 将访问的节点放进栈
|
||||
cur = cur.left # 左
|
||||
else:
|
||||
cur = st.pop()
|
||||
if pre is None: # 第一个节点
|
||||
count = 1
|
||||
elif pre.val == cur.val: # 与前一个节点数值相同
|
||||
count += 1
|
||||
else:
|
||||
else: # 与前一个节点数值不同
|
||||
count = 1
|
||||
if count == maxCount:
|
||||
res.append(cur.val)
|
||||
if count > maxCount:
|
||||
maxCount = count
|
||||
res.clear()
|
||||
res.append(cur.val)
|
||||
|
||||
if count == maxCount: # 如果和最大值相同,放进result中
|
||||
result.append(cur.val)
|
||||
|
||||
if count > maxCount: # 如果计数大于最大值频率
|
||||
maxCount = count # 更新最大频率
|
||||
result = [cur.val] # 很关键的一步,不要忘记清空result,之前result里的元素都失效了
|
||||
|
||||
pre = cur
|
||||
cur = cur.right
|
||||
return res
|
||||
cur = cur.right # 右
|
||||
|
||||
return result
|
||||
```
|
||||
## Go
|
||||
|
||||
|
@ -330,19 +330,24 @@ class Solution:
|
||||
# self.right = right
|
||||
from collections import deque
|
||||
class Solution:
|
||||
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
|
||||
queue = deque([root])
|
||||
def findBottomLeftValue(self, root):
|
||||
if root is None:
|
||||
return 0
|
||||
queue = deque()
|
||||
queue.append(root)
|
||||
result = 0
|
||||
while queue:
|
||||
size = len(queue)
|
||||
leftmost = queue[0].val
|
||||
for i in range(size):
|
||||
node = queue.popleft()
|
||||
if i == 0:
|
||||
result = node.val
|
||||
if node.left:
|
||||
queue.append(node.left)
|
||||
if node.right:
|
||||
queue.append(node.right)
|
||||
if not queue:
|
||||
return leftmost
|
||||
return result
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
@ -237,66 +237,82 @@ class Solution {
|
||||
```
|
||||
## Python
|
||||
|
||||
递归
|
||||
递归法(版本一)利用中序递增,结合数组
|
||||
```python
|
||||
class Solution:
|
||||
def getMinimumDifference(self, root: TreeNode) -> int:
|
||||
res = []
|
||||
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
|
||||
def __init__(self):
|
||||
self.vec = []
|
||||
|
||||
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):
|
||||
global pre,minval
|
||||
if not root: return None
|
||||
def traversal(self, root):
|
||||
if root is None:
|
||||
return
|
||||
self.traversal(root.left)
|
||||
if pre and root.val-pre.val<minval:
|
||||
minval = root.val-pre.val
|
||||
pre = root
|
||||
self.vec.append(root.val) # 将二叉搜索树转换为有序数组
|
||||
self.traversal(root.right)
|
||||
```
|
||||
|
||||
|
||||
迭代法-中序遍历
|
||||
```python
|
||||
class Solution:
|
||||
def getMinimumDifference(self, root: TreeNode) -> int:
|
||||
stack = []
|
||||
cur = root
|
||||
pre = None
|
||||
def getMinimumDifference(self, root):
|
||||
self.vec = []
|
||||
self.traversal(root)
|
||||
if len(self.vec) < 2:
|
||||
return 0
|
||||
result = float('inf')
|
||||
while cur or stack:
|
||||
if cur: # 指针来访问节点,访问到最底层
|
||||
stack.append(cur)
|
||||
cur = cur.left
|
||||
else: # 逐一处理节点
|
||||
cur = stack.pop()
|
||||
if pre: # 当前节点和前节点的值的差值
|
||||
result = min(result, abs(cur.val - pre.val))
|
||||
pre = cur
|
||||
cur = cur.right
|
||||
for i in range(1, len(self.vec)):
|
||||
# 统计有序数组的最小差值
|
||||
result = min(result, self.vec[i] - self.vec[i - 1])
|
||||
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:
|
||||
|
||||
中序遍历,然后计算最小差值
|
||||
|
@ -200,8 +200,30 @@ 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 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
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
@ -234,7 +256,32 @@ class Solution:
|
||||
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
|
||||
class Solution:
|
||||
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
|
||||
|
@ -352,8 +352,7 @@ class Solution {
|
||||
```
|
||||
|
||||
### Python
|
||||
|
||||
**递归法 - 前序遍历**
|
||||
(版本一) 递归 - 前序 - 修改root1
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
@ -377,8 +376,33 @@ class Solution:
|
||||
return root1 # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间.
|
||||
|
||||
```
|
||||
(版本二) 递归 - 前序 - 新建root
|
||||
```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 mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
|
||||
# 递归终止条件:
|
||||
# 但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
|
||||
if not root1:
|
||||
return root2
|
||||
if not root2:
|
||||
return root1
|
||||
# 上面的递归终止条件保证了代码执行到这里root1, root2都非空.
|
||||
root = TreeNode() # 创建新节点
|
||||
root.val += root1.val + root2.val# 中
|
||||
root.left = self.mergeTrees(root1.left, root2.left) #左
|
||||
root.right = self.mergeTrees(root1.right, root2.right) # 右
|
||||
|
||||
**迭代法**
|
||||
return root # ⚠️ 注意: 本题我们创建了新节点.
|
||||
|
||||
```
|
||||
|
||||
(版本三) 迭代
|
||||
```python
|
||||
class Solution:
|
||||
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
|
||||
@ -413,7 +437,44 @@ class Solution:
|
||||
|
||||
return root1
|
||||
```
|
||||
(版本四) 迭代 + 代码优化
|
||||
```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
|
||||
from collections import deque
|
||||
|
||||
class Solution:
|
||||
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
|
||||
if not root1:
|
||||
return root2
|
||||
if not root2:
|
||||
return root1
|
||||
|
||||
queue = deque()
|
||||
queue.append((root1, root2))
|
||||
|
||||
while queue:
|
||||
node1, node2 = queue.popleft()
|
||||
node1.val += node2.val
|
||||
|
||||
if node1.left and node2.left:
|
||||
queue.append((node1.left, node2.left))
|
||||
elif not node1.left:
|
||||
node1.left = node2.left
|
||||
|
||||
if node1.right and node2.right:
|
||||
queue.append((node1.right, node2.right))
|
||||
elif not node1.right:
|
||||
node1.right = node2.right
|
||||
|
||||
return root1
|
||||
|
||||
|
||||
```
|
||||
### Go
|
||||
|
||||
```go
|
||||
|
@ -238,33 +238,24 @@ Java:
|
||||
```java
|
||||
class Solution {
|
||||
public int countSubstrings(String s) {
|
||||
int len, ans = 0;
|
||||
if (s == null || (len = s.length()) < 1) return 0;
|
||||
//dp[i][j]:s字符串下标i到下标j的字串是否是一个回文串,即s[i, j]
|
||||
char[] chars = s.toCharArray();
|
||||
int len = chars.length;
|
||||
boolean[][] dp = new boolean[len][len];
|
||||
for (int j = 0; j < len; j++) {
|
||||
for (int i = 0; i <= j; i++) {
|
||||
//当两端字母一样时,才可以两端收缩进一步判断
|
||||
if (s.charAt(i) == s.charAt(j)) {
|
||||
//i++,j--,即两端收缩之后i,j指针指向同一个字符或者i超过j了,必然是一个回文串
|
||||
if (j - i < 3) {
|
||||
int result = 0;
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
for (int j = i; j < len; j++) {
|
||||
if (chars[i] == chars[j]) {
|
||||
if (j - i <= 1) { // 情况一 和 情况二
|
||||
result++;
|
||||
dp[i][j] = true;
|
||||
} else if (dp[i + 1][j - 1]) { //情况三
|
||||
result++;
|
||||
dp[i][j] = true;
|
||||
} else {
|
||||
//否则通过收缩之后的字串判断
|
||||
dp[i][j] = dp[i + 1][j - 1];
|
||||
}
|
||||
} else {//两端字符不一样,不是回文串
|
||||
dp[i][j] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//遍历每一个字串,统计回文串个数
|
||||
for (int i = 0; i < len; i++) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
if (dp[i][j]) ans++;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,52 +259,75 @@ 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 constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
|
||||
if not nums:
|
||||
return None
|
||||
maxvalue = max(nums)
|
||||
index = nums.index(maxvalue)
|
||||
if len(nums) == 1:
|
||||
return TreeNode(nums[0])
|
||||
node = TreeNode(0)
|
||||
# 找到数组中最大的值和对应的下标
|
||||
maxValue = 0
|
||||
maxValueIndex = 0
|
||||
for i in range(len(nums)):
|
||||
if nums[i] > maxValue:
|
||||
maxValue = nums[i]
|
||||
maxValueIndex = i
|
||||
node.val = maxValue
|
||||
# 最大值所在的下标左区间 构造左子树
|
||||
if maxValueIndex > 0:
|
||||
new_list = nums[:maxValueIndex]
|
||||
node.left = self.constructMaximumBinaryTree(new_list)
|
||||
# 最大值所在的下标右区间 构造右子树
|
||||
if maxValueIndex < len(nums) - 1:
|
||||
new_list = nums[maxValueIndex+1:]
|
||||
node.right = self.constructMaximumBinaryTree(new_list)
|
||||
return node
|
||||
|
||||
root = TreeNode(maxvalue)
|
||||
|
||||
left = nums[:index]
|
||||
right = nums[index + 1:]
|
||||
|
||||
root.left = self.constructMaximumBinaryTree(left)
|
||||
root.right = self.constructMaximumBinaryTree(right)
|
||||
return root
|
||||
```
|
||||
(版本二) 使用下标
|
||||
```python
|
||||
|
||||
class Solution:
|
||||
"""最大二叉树 递归法"""
|
||||
def traversal(self, nums: List[int], left: int, right: int) -> TreeNode:
|
||||
if left >= right:
|
||||
return None
|
||||
maxValueIndex = left
|
||||
for i in range(left + 1, right):
|
||||
if nums[i] > nums[maxValueIndex]:
|
||||
maxValueIndex = i
|
||||
root = TreeNode(nums[maxValueIndex])
|
||||
root.left = self.traversal(nums, left, maxValueIndex)
|
||||
root.right = self.traversal(nums, maxValueIndex + 1, right)
|
||||
return root
|
||||
|
||||
def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
|
||||
return self.traversal(nums, 0, len(nums))
|
||||
|
||||
def traversal(self, nums: List[int], begin: int, end: int) -> TreeNode:
|
||||
# 列表长度为0时返回空节点
|
||||
if begin == end:
|
||||
```
|
||||
|
||||
(版本三) 使用切片
|
||||
|
||||
```python
|
||||
|
||||
class Solution:
|
||||
def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
|
||||
if not nums:
|
||||
return None
|
||||
max_val = max(nums)
|
||||
max_index = nums.index(max_val)
|
||||
node = TreeNode(max_val)
|
||||
node.left = self.constructMaximumBinaryTree(nums[:max_index])
|
||||
node.right = self.constructMaximumBinaryTree(nums[max_index+1:])
|
||||
return node
|
||||
|
||||
# 找到最大的值和其对应的下标
|
||||
max_index = begin
|
||||
for i in range(begin, end):
|
||||
if nums[i] > nums[max_index]:
|
||||
max_index = i
|
||||
|
||||
# 构建当前节点
|
||||
root = TreeNode(nums[max_index])
|
||||
|
||||
# 递归构建左右子树
|
||||
root.left = self.traversal(nums, begin, max_index)
|
||||
root.right = self.traversal(nums, max_index + 1, end)
|
||||
|
||||
return root
|
||||
```
|
||||
|
||||
### Go
|
||||
|
||||
|
||||
|
@ -248,6 +248,8 @@ public:
|
||||
|
||||
## Java
|
||||
|
||||
**递归**
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public TreeNode trimBST(TreeNode root, int low, int high) {
|
||||
@ -269,66 +271,114 @@ 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 trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:
|
||||
'''
|
||||
确认递归函数参数以及返回值:返回更新后剪枝后的当前root节点
|
||||
'''
|
||||
# Base Case
|
||||
if not root: return None
|
||||
|
||||
# 单层递归逻辑
|
||||
if root.val < low:
|
||||
# 若当前root节点小于左界:只考虑其右子树,用于替代更新后的其本身,抛弃其左子树整体
|
||||
return self.trimBST(root.right, low, high)
|
||||
|
||||
if high < root.val:
|
||||
# 若当前root节点大于右界:只考虑其左子树,用于替代更新后的其本身,抛弃其右子树整体
|
||||
return self.trimBST(root.left, low, high)
|
||||
|
||||
if low <= root.val <= high:
|
||||
root.left = self.trimBST(root.left, low, high)
|
||||
root.right = self.trimBST(root.right, low, high)
|
||||
# 返回更新后的剪枝过的当前节点root
|
||||
return root
|
||||
```
|
||||
|
||||
**迭代**
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
//iteration
|
||||
public TreeNode trimBST(TreeNode root, int low, int high) {
|
||||
if(root == null)
|
||||
return null;
|
||||
while(root != null && (root.val < low || root.val > high)){
|
||||
if(root.val < low)
|
||||
root = root.right;
|
||||
else
|
||||
root = root.left;
|
||||
}
|
||||
|
||||
TreeNode curr = root;
|
||||
|
||||
//deal with root's left sub-tree, and deal with the value smaller than low.
|
||||
while(curr != null){
|
||||
while(curr.left != null && curr.left.val < low){
|
||||
curr.left = curr.left.right;
|
||||
}
|
||||
curr = curr.left;
|
||||
}
|
||||
//go back to root;
|
||||
curr = root;
|
||||
|
||||
//deal with root's righg sub-tree, and deal with the value bigger than high.
|
||||
while(curr != null){
|
||||
while(curr.right != null && curr.right.val > high){
|
||||
curr.right = curr.right.left;
|
||||
}
|
||||
curr = curr.right;
|
||||
}
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
## Python
|
||||
|
||||
递归法(版本一)
|
||||
```python
|
||||
class Solution:
|
||||
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
|
||||
if not root: return root
|
||||
# 处理头结点,让root移动到[L, R] 范围内,注意是左闭右开
|
||||
while root and (root.val < low or root.val > high):
|
||||
if root.val < low: # 小于L往右走
|
||||
root = root.right
|
||||
else: # 大于R往左走
|
||||
root = root.left
|
||||
# 此时root已经在[L, R] 范围内,处理左孩子元素小于L的情况
|
||||
def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:
|
||||
if root is None:
|
||||
return None
|
||||
if root.val < low:
|
||||
# 寻找符合区间 [low, high] 的节点
|
||||
return self.trimBST(root.right, low, high)
|
||||
if root.val > high:
|
||||
# 寻找符合区间 [low, high] 的节点
|
||||
return self.trimBST(root.left, low, high)
|
||||
root.left = self.trimBST(root.left, low, high) # root.left 接入符合条件的左孩子
|
||||
root.right = self.trimBST(root.right, low, high) # root.right 接入符合条件的右孩子
|
||||
return root
|
||||
|
||||
```
|
||||
递归法(版本二)精简
|
||||
```python
|
||||
class Solution:
|
||||
def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:
|
||||
if root is None:
|
||||
return None
|
||||
if root.val < low:
|
||||
return self.trimBST(root.right, low, high)
|
||||
if root.val > high:
|
||||
return self.trimBST(root.left, low, high)
|
||||
root.left = self.trimBST(root.left, low, high)
|
||||
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
|
||||
|
||||
# 此时root已经在[L, R] 范围内,处理左孩子元素小于L的情况
|
||||
while cur:
|
||||
while cur.left and cur.left.val < low:
|
||||
while cur.left and cur.left.val < L:
|
||||
cur.left = cur.left.right
|
||||
cur = cur.left
|
||||
# 此时root已经在[L, R] 范围内,处理右孩子大于R的情况
|
||||
|
||||
cur = root
|
||||
|
||||
# 此时root已经在[L, R] 范围内,处理右孩子大于R的情况
|
||||
while cur:
|
||||
while cur.right and cur.right.val > high:
|
||||
while cur.right and cur.right.val > R:
|
||||
cur.right = cur.right.left
|
||||
cur = cur.right
|
||||
|
||||
return root
|
||||
|
||||
```
|
||||
|
||||
## Go
|
||||
|
@ -230,7 +230,7 @@ class Solution {
|
||||
|
||||
### Python
|
||||
|
||||
递归法:
|
||||
(方法一) 递归
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
@ -250,12 +250,12 @@ class Solution:
|
||||
|
||||
```
|
||||
|
||||
迭代法:
|
||||
(方法二)迭代
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
|
||||
while root is not None:
|
||||
while root:
|
||||
if val < root.val: root = root.left
|
||||
elif val > root.val: root = root.right
|
||||
else: return root
|
||||
|
@ -256,133 +256,104 @@ 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 insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
|
||||
# 返回更新后的以当前root为根节点的新树,方便用于更新上一层的父子节点关系链
|
||||
def __init__(self):
|
||||
self.parent = None
|
||||
|
||||
# Base Case
|
||||
if not root: return TreeNode(val)
|
||||
def traversal(self, cur, val):
|
||||
if cur is None:
|
||||
node = TreeNode(val)
|
||||
if val > self.parent.val:
|
||||
self.parent.right = node
|
||||
else:
|
||||
self.parent.left = node
|
||||
return
|
||||
|
||||
# 单层递归逻辑:
|
||||
if val < root.val:
|
||||
# 将val插入至当前root的左子树中合适的位置
|
||||
# 并更新当前root的左子树为包含目标val的新左子树
|
||||
root.left = self.insertIntoBST(root.left, val)
|
||||
self.parent = cur
|
||||
if cur.val > val:
|
||||
self.traversal(cur.left, val)
|
||||
if cur.val < val:
|
||||
self.traversal(cur.right, val)
|
||||
|
||||
if root.val < val:
|
||||
# 将val插入至当前root的右子树中合适的位置
|
||||
# 并更新当前root的右子树为包含目标val的新右子树
|
||||
root.right = self.insertIntoBST(root.right, val)
|
||||
|
||||
# 返回更新后的以当前root为根节点的新树
|
||||
def insertIntoBST(self, root, val):
|
||||
self.parent = TreeNode(0)
|
||||
if root is None:
|
||||
return TreeNode(val)
|
||||
self.traversal(root, val)
|
||||
return root
|
||||
|
||||
```
|
||||
|
||||
**递归法** - 无返回值
|
||||
递归法(版本二)
|
||||
```python
|
||||
class Solution:
|
||||
def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
|
||||
if not root:
|
||||
def insertIntoBST(self, root, val):
|
||||
if root is None:
|
||||
return TreeNode(val)
|
||||
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
|
||||
|
||||
# 用while循环不断地找新节点的parent
|
||||
while cur:
|
||||
parent = cur # 首先保存当前非空节点作为下一次迭代的父节点
|
||||
if cur.val < val:
|
||||
cur = cur.right
|
||||
elif cur.val > val:
|
||||
parent = cur
|
||||
if val < cur.val:
|
||||
cur = cur.left
|
||||
|
||||
# 运行到这意味着已经跳出上面的while循环,
|
||||
# 同时意味着新节点的parent已经被找到.
|
||||
# parent已被找到, 新节点已经ready. 把两个节点黏在一起就好了.
|
||||
if parent.val > val:
|
||||
else:
|
||||
cur = cur.right
|
||||
if val < parent.val:
|
||||
parent.left = TreeNode(val)
|
||||
else:
|
||||
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
|
||||
|
||||
|
||||
```
|
||||
-----
|
||||
## Go
|
||||
|
@ -197,6 +197,7 @@ public class TreeNode {
|
||||
int val;
|
||||
TreeNode left;
|
||||
TreeNode right;
|
||||
|
||||
TreeNode() {}
|
||||
TreeNode(int val) { this.val = val; }
|
||||
TreeNode(int val, TreeNode left, TreeNode right) {
|
||||
@ -212,10 +213,10 @@ Python:
|
||||
|
||||
```python
|
||||
class TreeNode:
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
self.left = None
|
||||
self.right = None
|
||||
def __init__(self, val, left = None, right = None):
|
||||
self.val = val
|
||||
self.left = left
|
||||
self.right = right
|
||||
```
|
||||
|
||||
Go:
|
||||
|
Reference in New Issue
Block a user