2022-1-7二叉树day1
题1:
翻转一棵二叉树。
示例:
输入:
4 / \ 2 7 / \ / \ 1 3 6 9
输出:
4 / \ 7 2 / \ / \ 9 6 3 1
备注:
这个问题是受到 Max Howell 的 原问题 启发的 :
谷歌:我们90%的工程师使用您编写的软件(Homebrew),但是您却无法在面试时在白板上写出翻转二叉树这道题,这太糟糕了。
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode() {} 8 * TreeNode(int val) { this.val = val; } 9 * TreeNode(int val, TreeNode left, TreeNode right) { 10 * this.val = val; 11 * this.left = left; 12 * this.right = right; 13 * } 14 * } 15 */ 16 class Solution { 17 public TreeNode invertTree(TreeNode root) { 18 if (root==null) return root; 19 TreeNode temp=null; 20 temp=root.left; 21 root.left=root.right; 22 root.right=temp; 23 invertTree(root.left); 24 invertTree(root.right); 25 return root; 26 } 27 }
递归,对于root节点,左右子树交换,再递归左右子树。
题2:给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node { int val; Node *left; Node *right; Node *next; }
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有 next 指针都被设置为 NULL
。
进阶:
- 你只能使用常量级额外空间。
- 使用递归解题也符合要求,本题中递归程序占用的栈空间不算做额外的空间复杂度。
示例:
输入:root = [1,2,3,4,5,6,7] 输出:[1,#,2,3,#,4,5,6,7,#] 解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。
提示:
- 树中节点的数量少于
4096
-1000 <= node.val <= 1000
1 /* 2 // Definition for a Node. 3 class Node { 4 public int val; 5 public Node left; 6 public Node right; 7 public Node next; 8 9 public Node() {} 10 11 public Node(int _val) { 12 val = _val; 13 } 14 15 public Node(int _val, Node _left, Node _right, Node _next) { 16 val = _val; 17 left = _left; 18 right = _right; 19 next = _next; 20 } 21 }; 22 */ 23 24 class Solution { 25 public Node connect(Node root) { 26 if (root==null) return root; 27 newconnect(root.left,root.right); 28 return root; 29 } 30 31 public void newconnect(Node left,Node right){ 32 if (left==null||right==null){ 33 return; 34 } 35 left.next=right; 36 newconnect(left.left,left.right); 37 newconnect(right.left,right.right); 38 newconnect(left.right,right.left); 39 } 40 }
递归:光有root参数不够,因此新建一个递归函数,左子树的左右节点,右子树的左右节点,左右子树的右左节点。
题3:
给你二叉树的根结点 root
,请你将它展开为一个单链表:
- 展开后的单链表应该同样使用
TreeNode
,其中right
子指针指向链表中下一个结点,而左子指针始终为null
。 - 展开后的单链表应该与二叉树 先序遍历 顺序相同。
示例 1:
输入:root = [1,2,5,3,4,null,6] 输出:[1,null,2,null,3,null,4,null,5,null,6]
示例 2:
输入:root = [] 输出:[]
示例 3:
输入:root = [0] 输出:[0]
提示:
- 树中结点数在范围
[0, 2000]
内 -100 <= Node.val <= 100
进阶:你可以使用原地算法(O(1)
额外空间)展开这棵树吗?
1 /** 2 * Definition for a binary tree node. 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode() {} 8 * TreeNode(int val) { this.val = val; } 9 * TreeNode(int val, TreeNode left, TreeNode right) { 10 * this.val = val; 11 * this.left = left; 12 * this.right = right; 13 * } 14 * } 15 */ 16 class Solution { 17 public void flatten(TreeNode root) { 18 if (root==null) return; 19 TreeNode right=root.right; 20 //临时变量记录右子树 21 root.right=root.left; 22 root.left=null; 23 //左子树变成null,右子树变成左子树 24 flatten(root.right); 25 //拉长左子树,因为左子树已经到了右子树上了,所以是root.right 26 while (root.right!=null){ 27 root=root.right; 28 } 29 //拉长后遍历到最后 30 //将右子树拼接上 31 root.right=right; 32 //把右子树也拉长 33 flatten(root.right); 34 } 35 }
递归思想,具体思路见注释。主要思想是利用递归拉长左子树和右子树。