一、翻转二叉树 226
1、分析
这道题可以分解为子问题,首先对左右子树进行翻转,然后再交换左右子树的问题即可。采用递归来写,且注意到这个交换之前需要得到左右子树的翻转结果,因此关键性代码放在“后序遍历位置”。
具体见代码和注释
2、代码
# 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 invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return None
left = self.invertTree(root.left) #翻转左子树
right = self.invertTree(root.right) #翻转右子树
root.left = right #交换左右子树
root.right = left
return root
JS
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {TreeNode}
*/
var invertTree = function(root) {
if(root===null){
return null;
}
let left = invertTree(root.left);
let right = invertTree(root.right);
root.left = right;
root.right = left;
return root;
};
二、二叉树展开为链表 114
1、分析
该问题也可以分解为子问题,先将左右子树拉平,然后再将拉平后的左子树放在根节点的右边,然后把原来的右子树拉平后接在现在的右子树末尾即可。
具体见代码及注释
2、代码
# 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 flatten(self, root: TreeNode) -> None:
"""
Do not return anything, modify root in-place instead.
"""
if not root: #base case
return
self.flatten(root.left) #先将左右子树拉平
self.flatten(root.right)
left = root.left #先用变量暂存拉平后的左右子树
right = root.right
root.left = None #将根节点的左子树置空,左子树挪到右子树
root.right = left
p = root
while p.right: #遍历找到当前右子树的末尾
p = p.right
p.right = right #将原本的右子树连接到当前右子树末尾
JS
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {void} Do not return anything, modify root in-place instead.
*/
var flatten = function(root) {
if(root===null){
return
}
flatten(root.left);
flatten(root.right);
let left = root.left;
let right = root.right;
root.left = null;
root.right = left
let p = root
while(p.right!==null){
p = p.right;
}
p.right = right;
};
三、填充每个结点的下一个右侧节点指针
1、分析
首先这个问题无法分解成子问题去解决,而是要遍历一遍整个二叉树。所以我们采用一个辅助函数来递归的遍历节点,并且连接左右相邻节点。关键点在于对非同父节点的节点,我们也需要连接。
具体见代码及注释
2、代码
"""
# Definition for a Node.
class Node:
def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution:
def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
if not root: #base case
return None
def helper(node1,node2):
if not node1 or not node2: #递归出口
return
node1.next = node2 #先连接当前的相邻点
helper(node1.left,node1.right) #连接左右子结点
helper(node2.left,node2.right)
helper(node1.right,node2.left) #连接不同父节点但是相邻的结点
helper(root.left,root.right)
return root
JS
/**
* // Definition for a Node.
* function Node(val, left, right, next) {
* this.val = val === undefined ? null : val;
* this.left = left === undefined ? null : left;
* this.right = right === undefined ? null : right;
* this.next = next === undefined ? null : next;
* };
*/
/**
* @param {Node} root
* @return {Node}
*/
var connect = function(root) {
if(root===null){
return null;
}
var helper = function(node1,node2){
if(node1===null || node2===null){
return
}
node1.next = node2;
helper(node1.left,node1.right);
helper(node2.left,node2.right);
helper(node1.right,node2.left);
}
helper(root.left,root.right);
return root;
};