题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
这题属于看懂思路再来一遍还是不会的题目。纠结的比较久是因为我对链表和python不太熟悉。关键是中序遍历和递归。copy人家的做法。
- 核心算法依旧是中序遍历
- 不是从根节点开始,而是从中序遍历得到的第一个节点开始
- 定义两个辅助节点listHead(链表头节点)、listTail(链表尾节点)。事实上,二叉树只是换了种形式的链表;listHead用于记录链表的头节点,用于最后算法的返回;listTail用于定位当前需要更改指向的节点。了解了listHead和listTail的作用,代码理解起来至少顺畅80%。
# -*- coding:utf-8 -*-
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def __init__(self):
self.listHead = None
self.listTail = None
def Convert(self, pRootOfTree):
if pRootOfTree==None:
return
self.Convert(pRootOfTree.left)
if self.listHead==None:
self.listHead = pRootOfTree
self.listTail = pRootOfTree
else:
self.listTail.right = pRootOfTree
pRootOfTree.left = self.listTail
self.listTail = pRootOfTree
self.Convert(pRootOfTree.right)
return self.listHead
leetcode上有类似的题目,自己努力了一把没啥结果。还是看了别人的代码。
class Solution:
def flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
#递归之后如果存在左子树,把右子树保留,右子树置换成左子树,左子树置空
#找到该树的最终节点,即最右节点,再链接开始保留的右子树,即r
if not root:
return
self.flatten(root.left)
self.flatten(root.right)
if root.left:
tmp = root.right
root.right = root.left
root.left = None
node = root.right
while node.right:
node = node.right
node.right = tmp
对于递归还是有点混乱,整理了下过程。可以中序遍历后得到升序数组然后组成链表。但是不符合题意原地展开的要求。
flatten(1)→flatten(2)→flatten(3) 1 1
→flatten(4) / \ → / \ → 得到结果
→flatten(5)→flatten(6) 2 5 2 5
/ \ \ \ \
3 4 6 3 6
\
4