【算法训练】二叉树系列(二)

一、翻转二叉树 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;
    
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值