226. 翻转二叉树、116. 填充每个节点的下一个右侧节点指针、114. 二叉树展开为链表

226. 翻转二叉树

翻转一棵二叉树。

解题思路及方法

这道题很简单,可以作为刚刷二叉树的基础题,解法就是普通的递归。交换根节点的左右子结点,然后一直递归调用直到遍历完整棵树。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null;
        }
        // 交换左右节点
        TreeNode tmp = root.left;
        root.left = root.right;
        root.right = tmp;
        // 递归交换子节点
        invertTree(root.left);
        invertTree(root.right);

        return root;
    }
}

结果如下:

116. 填充每个节点的下一个右侧节点指针

给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:

struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL。

初始状态下,所有 next 指针都被设置为 NULL。

进阶:

你只能使用常量级额外空间。
使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题方法及思路

首先我们要清楚什么是一棵完美二叉树,完美二叉树就是一棵满的二叉树,也就是非叶结点都有两个子结点,即都是二叉的。搞清楚定义就好解了。

观察示例,其实就是将子结点的右子结点接在左子结点的后面。这么想是对的,但是不全对,观察结点5和6,它们并非一个结点的左右子结点,所以还要考虑这种情况。

编写一个辅助函数来链接子结点,参数为两个结点。将传入的两个结点的左右子结点链接,再将第一个结点的右子结点和第二个结点的左子结点链接,一直递归即可。

/*
// Definition for a Node.
class Node {
    public int val;
    public Node left;
    public Node right;
    public Node next;

    public Node() {}
    
    public Node(int _val) {
        val = _val;
    }

    public Node(int _val, Node _left, Node _right, Node _next) {
        val = _val;
        left = _left;
        right = _right;
        next = _next;
    }
};
*/

class Solution {
    public Node connect(Node root) {
        if (root == null) {
            return null;
        }
        // 链接
        connectTwoNode(root.left, root.right);

        return root;
    }

    public void connectTwoNode(Node node1, Node node2) {
        if (node1 == null || node2 == null) {
            return;
        }
        // 链接传入根节点
        node1.next = node2;
        // 链接传入结点子节点
        connectTwoNode(node1.left, node1.right);
        connectTwoNode(node2.left, node2.right);
        // 链接传入结点右子树和左子树
        connectTwoNode(node1.right, node2.left);
    }
}

结果如下:

114. 二叉树展开为链表

给你二叉树的根结点 root ,请你将它展开为一个单链表:

展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flatten-binary-tree-to-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路及方法

同样是递归,将子结点拉成链表。因为要求是先序遍历的顺序,所以递归函数的写法是先递归,再处理。处理过程是将当前结点的左右子树存入一个临时变量,然后将左子树为空,将之前存入变量的左子树赋给当前右子树,再将之前存入右子树的变量接在现在右子树的右边,形成一个链表。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public void flatten(TreeNode root) {
        if (root == null) {
            return;
        }
        // 递归将子结点拉成链表
        flatten(root.left);
        flatten(root.right);

        // 将传入结点与子结点拉成链表
        TreeNode left = root.left;
        TreeNode right = root.right;

        root.left = null;
        root.right = left;

        // 将原先的右子树接到当前右子树的末端
        TreeNode p = root;
        while (p.right != null) {
            p = p.right;
        }
        p.right = right;
    }
}

结果如下:

你可能感兴趣的:(226. 翻转二叉树、116. 填充每个节点的下一个右侧节点指针、114. 二叉树展开为链表)