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;
}
}
结果如下: