Merge branch 'youngyangyang04:master' into master

This commit is contained in:
HOUSHENGREN
2023-05-27 19:25:28 +08:00
committed by GitHub
26 changed files with 1094 additions and 768 deletions

View File

@ -41,7 +41,7 @@
那么我们就应该想到使用哈希法了。 那么我们就应该想到使用哈希法了。
因为本地,我们不仅要知道元素有没有遍历过,还知道这个元素对应的下标,**需要使用 key value结构来存放key来存元素value来存下标那么使用map正合适**。 因为本地,我们不仅要知道元素有没有遍历过,还知道这个元素对应的下标,**需要使用 key value结构来存放key来存元素value来存下标那么使用map正合适**。
再来看一下使用数组和set来做哈希法的局限。 再来看一下使用数组和set来做哈希法的局限。

View File

@ -191,8 +191,8 @@ public:
}; };
``` ```
* 时间复杂度:$O(\log n)$ * 时间复杂度O(log n)
* 间复杂度:$O(1)$ * 间复杂度O(1)
## 总结 ## 总结

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:
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 traversal(self, root):
if root is None:
return
self.traversal(root.left)
self.vec.append(root.val) # 将二叉搜索树转换为有序数组
self.traversal(root.right)
```python def isValidBST(self, root):
class Solution: self.vec = [] # 清空数组
def isValidBST(self, root: TreeNode) -> bool: self.traversal(root)
# 规律: BST的中序遍历节点数值是从小到大. for i in range(1, len(self.vec)):
cur_max = -float("INF") # 注意要小于等于,搜索树里不能有相同元素
def __isValidBST(root: TreeNode) -> bool: if self.vec[i] <= self.vec[i - 1]:
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 return False
is_right_valid = __isValidBST(root.right) return True
return is_left_valid and is_right_valid
return __isValidBST(root)
``` ```
**递归** - 避免初始化最小值做法:
递归法(版本二)设定极小值,进行比较
```python ```python
class Solution: class Solution:
def isValidBST(self, root: TreeNode) -> bool: def __init__(self):
# 规律: BST的中序遍历节点数值是从小到大. self.maxVal = float('-inf') # 因为后台测试数据中有int最小值
pre = None
def __isValidBST(root: TreeNode) -> bool: def isValidBST(self, root):
nonlocal pre if root is None:
return True
if not root:
return True left = self.isValidBST(root.left)
# 中序遍历,验证遍历的元素是不是从小到大
is_left_valid = __isValidBST(root.left) if self.maxVal < root.val:
if pre and pre.val>=root.val: return False self.maxVal = root.val
pre = root else:
is_right_valid = __isValidBST(root.right) return False
right = self.isValidBST(root.right)
return is_left_valid and is_right_valid
return __isValidBST(root) return left and right
``` ```
递归法(版本三)直接取该树的最小值
```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):
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):
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

@ -400,8 +400,6 @@ public:
}; };
``` ```
## Python
# 105.从前序与中序遍历序列构造二叉树 # 105.从前序与中序遍历序列构造二叉树
@ -692,38 +690,6 @@ class Solution {
## Python ## 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.从前序与中序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
```python ```python
@ -752,7 +718,7 @@ class Solution:
# 第六步: 递归 # 第六步: 递归
root.left = self.buildTree(preorder_left, inorder_left) root.left = self.buildTree(preorder_left, inorder_left)
root.right = self.buildTree(preorder_right, inorder_right) root.right = self.buildTree(preorder_right, inorder_right)
# 第七步: 返回答案
return root return root
``` ```
@ -784,7 +750,7 @@ class Solution:
# 第六步: 递归 # 第六步: 递归
root.left = self.buildTree(inorder_left, postorder_left) root.left = self.buildTree(inorder_left, postorder_left)
root.right = self.buildTree(inorder_right, postorder_right) root.right = self.buildTree(inorder_right, postorder_right)
# 第七步: 返回答案
return root return root
``` ```

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:
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)
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 return root
``` ```
## Go ## Go

View File

@ -536,23 +536,67 @@ 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) return -1
if right == -1 or abs(left - right) > 1: return max(left, right) + 1
return -1
return max(left, right) + 1
``` ```
迭代法: 迭代法:
```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 ```python
class Solution: class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool: def isBalanced(self, root: Optional[TreeNode]) -> bool:
@ -576,8 +620,6 @@ class Solution:
height_map[real_node] = 1 + max(left, right) height_map[real_node] = 1 + max(left, right)
return True return True
``` ```
### Go ### Go
```Go ```Go

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) def minDepth(self, root):
return self.getDepth(root)
return 1 + min(left_depth, right_depth)
``` ```
递归法(版本二)
迭代法: ```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

@ -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"> <p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank"> <a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/> <img src="../pics/网站星球宣传海报.jpg" width="1000"/>

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:
return root
if left:
return left
return right
```
if left is not None and right is not None:
return root
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

@ -470,38 +470,34 @@ class Solution {
## Python: ## Python:
递归法+回溯(版本一) 递归法+回溯
```Python ```Python
# Definition for a binary tree node. # 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: class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]: def traversal(self, cur, path, result):
if not root: path.append(cur.val) # 中
return [] if not cur.left and not cur.right: # 到达叶子节点
sPath = '->'.join(map(str, path))
result.append(sPath)
return
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 = [] result = []
self.generate_paths(root, [], result) path = []
if not root:
return result
self.traversal(root, path, result)
return 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 ```Python
# Definition for a binary tree node. # Definition for a binary tree node.
# class TreeNode: # class TreeNode:
@ -509,7 +505,6 @@ class Solution:
# self.val = val # self.val = val
# self.left = left # self.left = left
# self.right = right # self.right = right
import copy
from typing import List, Optional from typing import List, Optional
class Solution: class Solution:
@ -517,23 +512,23 @@ class Solution:
if not root: if not root:
return [] return []
result = [] result = []
self.generate_paths(root, [], result) self.traversal(root, [], result)
return result return result
def generate_paths(self, node: TreeNode, path: List[int], result: List[str]) -> None: def traversal(self, cur: TreeNode, path: List[int], result: List[str]) -> None:
if not node: if not cur:
return return
path.append(node.val) path.append(cur.val)
if not node.left and not node.right: if not cur.left and not cur.right:
result.append('->'.join(map(str, path))) result.append('->'.join(map(str, path)))
else: if cur.left:
self.generate_paths(node.left, copy.copy(path), result) self.traversal(cur.left, path[:], result)
self.generate_paths(node.right, copy.copy(path), result) if cur.right:
path.pop() self.traversal(cur.right, path[:], result)
``` ```
递归法+隐形回溯 递归法+隐形回溯(版本二)
```Python ```Python
# Definition for a binary tree node. # Definition for a binary tree node.
# class TreeNode: # class TreeNode:
@ -566,16 +561,11 @@ class Solution:
迭代法: 迭代法:
```Python ```Python
from collections import deque
class Solution: class Solution:
"""二叉树的所有路径 迭代法"""
def binaryTreePaths(self, root: TreeNode) -> List[str]: def binaryTreePaths(self, root: TreeNode) -> List[str]:
# 题目中节点数至少为1 # 题目中节点数至少为1
stack, path_st, result = deque([root]), deque(), [] stack, path_st, result = [root], [str(root.val)], []
path_st.append(str(root.val))
while stack: while stack:
cur = stack.pop() cur = stack.pop()

View File

@ -149,7 +149,7 @@ class Solution:
if len(nums) <= 1: if len(nums) <= 1:
return len(nums) return len(nums)
dp = [1] * len(nums) dp = [1] * len(nums)
result = 0 result = 1
for i in range(1, len(nums)): for i in range(1, len(nums)):
for j in range(0, i): for j in range(0, i):
if nums[i] > nums[j]: if nums[i] > nums[j]:

View File

@ -247,8 +247,7 @@ class Solution {
### Python ### Python
递归
**递归后序遍历**
```python ```python
# Definition for a binary tree node. # Definition for a binary tree node.
# class TreeNode: # class TreeNode:
@ -257,47 +256,64 @@ class Solution {
# self.left = left # self.left = left
# self.right = right # self.right = right
class Solution: class Solution:
def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int: def sumOfLeftLeaves(self, root):
if not root: if root is None:
return 0
if root.left is None and root.right is None:
return 0 return 0
# 检查根节点的左子节点是否为叶节点 leftValue = self.sumOfLeftLeaves(root.left) # 左
if root.left and not root.left.left and not root.left.right: if root.left and not root.left.left and not root.left.right: # 左子树是左叶子的情况
left_val = root.left.val leftValue = root.left.val
else:
left_val = self.sumOfLeftLeaves(root.left)
# 递归地计算右子树左叶节点的和 rightValue = self.sumOfLeftLeaves(root.right) # 右
right_val = self.sumOfLeftLeaves(root.right)
sum_val = leftValue + rightValue # 中
return left_val + right_val 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 ```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 sumOfLeftLeaves(self, root: TreeNode) -> int: def sumOfLeftLeaves(self, root):
""" if root is None:
Idea: Each time check current node's left node. return 0
If current node don't have one, skip it. st = [root]
""" result = 0
stack = [] while st:
if root: node = st.pop()
stack.append(root) if node.left and node.left.left is None and node.left.right is None:
res = 0 result += node.left.val
if node.right:
while stack: st.append(node.right)
# 每次都把当前节点的左节点加进去. if node.left:
cur_node = stack.pop() st.append(node.left)
if cur_node.left and not cur_node.left.left and not cur_node.left.right: return result
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 ### Go

View File

@ -295,19 +295,19 @@ var reconstructQueue = function(people) {
```Rust ```Rust
impl Solution { impl Solution {
pub fn reconstruct_queue(people: Vec<Vec<i32>>) -> Vec<Vec<i32>> { pub fn reconstruct_queue(mut people: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let mut people = people; let mut queue = vec![];
people.sort_by(|a, b| { 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]) b[0].cmp(&a[0])
}); });
let mut que: Vec<Vec<i32>> = Vec::new(); queue.push(people[0].clone());
que.push(people[0].clone()); for v in people.iter().skip(1) {
for i in 1..people.len() { queue.insert(v[1] as usize, v.clone());
let position = people[i][1];
que.insert(position as usize, people[i].clone());
} }
que queue
} }
} }
``` ```

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:
if root.val < key : return root
root.right = self.deleteNode(root.right, key) if root.val == key:
elif 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) root.left = self.deleteNode(root.left, key)
else: if root.val < key:
# 当前节点的左子树为空,返回当前的右子树 root.right = self.deleteNode(root.right, key)
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: return root
if not root.right: # 这里第二次操作目标值:最终删除的作用 if root.val == key: # 找到要删除的节点
if root.right is None: # 如果右子树为空,直接返回左子树作为新的根节点
return root.left return root.left
tmp = root.right cur = root.right
while tmp.left: while cur.left: # 找到右子树中的最左节点
tmp = tmp.left cur = cur.left
root.val, tmp.val = tmp.val, root.val # 这里第一次操作目标值:交换目标值其右子树最左节点 root.val, cur.val = cur.val, root.val # 将要删除的节点值与最左节点值交换
root.left = self.deleteNode(root.left, key) # 在左子树中递归删除目标节点
root.left = self.deleteNode(root.left, key) root.right = self.deleteNode(root.right, key) # 在右子树中递归删除目标节点
root.right = self.deleteNode(root.right, key)
return root 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
``` ```
@ -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"> <p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank"> <a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/> <img src="../pics/网站星球宣传海报.jpg" width="1000"/>

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
def search_BST(self, cur: TreeNode) -> None: self.searchBST(root, freq_map)
if not cur: return None max_freq = max(freq_map.values())
self.search_BST(cur.left) for key, freq in freq_map.items():
# 第一个节点 if freq == max_freq:
if not self.pre: result.append(key)
self.count = 1 return result
# 与前一个节点数值相同
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

@ -330,19 +330,24 @@ class Solution:
# self.right = right # self.right = right
from collections import deque from collections import deque
class Solution: class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int: def findBottomLeftValue(self, root):
queue = deque([root]) if root is None:
return 0
queue = deque()
queue.append(root)
result = 0
while queue: while queue:
size = len(queue) size = len(queue)
leftmost = queue[0].val
for i in range(size): for i in range(size):
node = queue.popleft() node = queue.popleft()
if i == 0:
result = node.val
if node.left: if node.left:
queue.append(node.left) queue.append(node.left)
if node.right: if node.right:
queue.append(node.right) queue.append(node.right)
if not queue: return result
return leftmost
``` ```

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 self.traversal(root.right)
pre = root
self.traversal(root.right) def getMinimumDifference(self, root):
self.vec = []
self.traversal(root)
if len(self.vec) < 2:
return 0
result = float('inf')
for i in range(1, len(self.vec)):
# 统计有序数组的最小差值
result = min(result, self.vec[i] - self.vec[i - 1])
return result
``` ```
迭代法-中序遍历
递归法(版本二)利用中序递增,找到该树最小值
```python ```python
class Solution: class Solution:
def getMinimumDifference(self, root: TreeNode) -> int: 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 = [] stack = []
cur = root cur = root
pre = None pre = None
result = float('inf') result = float('inf')
while cur or stack:
if cur: # 指针来访问节点,访问到最底层 while cur is not None or len(stack) > 0:
stack.append(cur) if cur is not None:
cur = cur.left stack.append(cur) # 将访问的节点放进栈
else: # 逐一处理节点 cur = cur.left # 左
else:
cur = stack.pop() cur = stack.pop()
if pre: # 当前节点和前节点的值的差值 if pre is not None: # 中
result = min(result, abs(cur.val - pre.val)) result = min(result, cur.val - pre.val)
pre = cur pre = cur
cur = cur.right cur = cur.right # 右
return result 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

@ -352,8 +352,7 @@ class Solution {
``` ```
### Python ### Python
(版本一) 递归 - 前序 - 修改root1
**递归法 - 前序遍历**
```python ```python
# Definition for a binary tree node. # Definition for a binary tree node.
# class TreeNode: # class TreeNode:
@ -377,8 +376,33 @@ class Solution:
return root1 # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间. 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 ```python
class Solution: class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode: def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
@ -413,7 +437,44 @@ class Solution:
return root1 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
```go ```go

View File

@ -238,33 +238,24 @@ Java
```java ```java
class Solution { class Solution {
public int countSubstrings(String s) { public int countSubstrings(String s) {
int len, ans = 0; char[] chars = s.toCharArray();
if (s == null || (len = s.length()) < 1) return 0; int len = chars.length;
//dp[i][j]s字符串下标i到下标j的字串是否是一个回文串即s[i, j]
boolean[][] dp = new boolean[len][len]; boolean[][] dp = new boolean[len][len];
for (int j = 0; j < len; j++) { int result = 0;
for (int i = 0; i <= j; i++) { for (int i = len - 1; i >= 0; i--) {
//当两端字母一样时,才可以两端收缩进一步判断 for (int j = i; j < len; j++) {
if (s.charAt(i) == s.charAt(j)) { if (chars[i] == chars[j]) {
//i++j--即两端收缩之后i,j指针指向同一个字符或者i超过j了,必然是一个回文串 if (j - i <= 1) { // 情况一 和 情况二
if (j - i < 3) { result++;
dp[i][j] = true;
} else if (dp[i + 1][j - 1]) { //情况三
result++;
dp[i][j] = true; dp[i][j] = true;
} else {
//否则通过收缩之后的字串判断
dp[i][j] = dp[i + 1][j - 1];
} }
} else {//两端字符不一样,不是回文串
dp[i][j] = false;
} }
} }
} }
//遍历每一个字串,统计回文串个数 return result;
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
if (dp[i][j]) ans++;
}
}
return ans;
} }
} }

View File

@ -259,52 +259,75 @@ 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 constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode: def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
if not nums: if len(nums) == 1:
return None return TreeNode(nums[0])
maxvalue = max(nums) node = TreeNode(0)
index = nums.index(maxvalue) # 找到数组中最大的值和对应的下标
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) ```
(版本二) 使用下标
```python
left = nums[:index]
right = nums[index + 1:]
root.left = self.constructMaximumBinaryTree(left)
root.right = self.constructMaximumBinaryTree(right)
return root
class Solution: 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: def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
return self.traversal(nums, 0, len(nums)) return self.traversal(nums, 0, len(nums))
def traversal(self, nums: List[int], begin: int, end: int) -> TreeNode:
# 列表长度为0时返回空节点
if begin == end:
return None
# 找到最大的值和其对应的下标
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
```
```
(版本三) 使用切片
```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
```
### Go ### Go

View File

@ -248,6 +248,8 @@ public:
## Java ## Java
**递归**
```Java ```Java
class Solution { class Solution {
public TreeNode trimBST(TreeNode root, int low, int high) { 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 ```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往右走 # 寻找符合区间 [low, high] 的节点
root = root.right return self.trimBST(root.right, low, high)
else: # 大于R往左走 if root.val > high:
root = root.left # 寻找符合区间 [low, high] 的节点
# 此时root已经在[L, R] 范围内处理左孩子元素小于L的情况 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 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

@ -230,7 +230,7 @@ class Solution {
### Python ### Python
递归法: (方法一) 递归
```python ```python
class Solution: class Solution:
@ -250,12 +250,12 @@ class Solution:
``` ```
迭代法: (方法二)迭代
```python ```python
class Solution: class Solution:
def searchBST(self, root: TreeNode, val: int) -> TreeNode: def searchBST(self, root: TreeNode, val: int) -> TreeNode:
while root is not None: while root:
if val < root.val: root = root.left if val < root.val: root = root.left
elif val > root.val: root = root.right elif val > root.val: root = root.right
else: return root else: return root

View File

@ -256,132 +256,103 @@ 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 cur:
# 用while循环不断地找新节点的parent parent = cur
while cur: if val < cur.val:
parent = cur # 首先保存当前非空节点作为下一次迭代的父节点
if cur.val < 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 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
``` ```
----- -----

View File

@ -195,15 +195,16 @@ Java
```java ```java
public class TreeNode { public class TreeNode {
int val; int val;
TreeNode left; TreeNode left;
TreeNode right; TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; } TreeNode() {}
TreeNode(int val, TreeNode left, TreeNode right) { TreeNode(int val) { this.val = val; }
this.val = val; TreeNode(int val, TreeNode left, TreeNode right) {
this.left = left; this.val = val;
this.right = right; this.left = left;
} this.right = right;
}
} }
``` ```
@ -212,10 +213,10 @@ Python
```python ```python
class TreeNode: class TreeNode:
def __init__(self, value): def __init__(self, val, left = None, right = None):
self.value = value self.val = val
self.left = None self.left = left
self.right = None self.right = right
``` ```
Go Go