230.二叉搜索树中第k小的元素
思路:
1、二叉搜索树的性质是其中序遍历为递增序列。利用该性质即可将题意转化为中序遍历的第k个元素
2、中序遍历按照左中右的顺序进行,中间的处理需要对计数进行减1的操作,并验证其是否为0,若为0,则记录下此刻的数值并返回
注意:
Python 中,局部变量的作用域仅限于定义它们的函数内部。在 kthSmallest 方法中定义的变量 k 是局部变量,它在 kthSmallest 方法的作用域内有效。嵌套函数 dfs 无法直接访问外部方法的局部变量 k,因为 dfs 有自己的作用域。
为了在嵌套函数 dfs 中访问和修改 k 的值,可以将 k 定义为类的成员变量。类的成员变量可以通过 self 关键字在类的任何方法中访问和修改。在 kthSmallest 方法中,将 k 赋值给 self.k,这样 dfs 函数就可以通过 self.k 来访问和修改这个值。
代码:
python
class Solution:
def kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
def dfs(root):
if root is None:
return
dfs(root.left)
self.k -= 1
if self.k == 0:
self.res = root.val
return
dfs(root.right)
self.k = k
dfs(root)
return self.res
参考:
199.二叉树的右视图
思路:
看到题目所说的右视图很容易联想到需要一层一层进行遍历来获取每层的最右侧元素,故采用层序遍历。基本步骤与层序遍历一致,只是增加了一个列表来记录并返回。
代码:
python
class Solution:
def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
queue = collections.deque([root]) # 用列表记录每一层元素
right_view = []
while queue:
size = len(queue)
for i in range(size): # 遍历每一层
cur = queue.popleft()
if i == size - 1: # 验证是否为最右侧元素
right_view.append(cur.val)
if cur.left:
queue.append(cur.left)
if cur.right:
queue.append(cur.right)
return right_view
114.二叉树展开为链表
思路:
按照前序遍历中左右的方式进行更新,创建一个前置节点用来修改左右子树连接;但由于需要把左子树置到右节点处,所以需要额外变量对右子树进行存储,否则会丢失。
代码:
python
class Solution:
pre = None # 用来记录前一节点并对root进行更新
def flatten(self, root: Optional[TreeNode]) -> None:
"""
Do not return anything, modify root in-place instead.
"""
# 前序遍历中左右,递归返回条件
if not root:
return None
# 非空时指定左右节点
if self.pre:
self.pre.left = None
self.pre.right = root
self.pre = root # 更新
right = root.right # 保留右子树,否则再上一个if语句中修改了右子树会导致其丢失
self.flatten(root.left)
self.flatten(right)
复杂度分析:
- 时间复杂度:O(n),其中 n 是二叉树的节点个数。
- 空间复杂度:O(n)。递归需要 O(n) 的栈空间。