【剑指 Offer(专项突击版)】 043-047、049、053-054 刷题笔记【二叉树】
文章目录
- [043 - 剑指 Offer II 043. 往完全二叉树添加节点](https://leetcode-cn.com/problems/NaqhDT/)
- [044 - 剑指 Offer II 044. 二叉树每层的最大值【层次遍历】](https://leetcode-cn.com/problems/hPov7L/)
- [045 - 剑指 Offer II 045. 二叉树最底层最左边的值【层次遍历】](https://leetcode-cn.com/problems/LwUNpT/)
- [046 - 剑指 Offer II 046. 二叉树的右侧视图【层次遍历】](https://leetcode-cn.com/problems/WNC0Lk/)
- [047 - 剑指 Offer II 047. 二叉树剪枝【后序遍历】](https://leetcode-cn.com/problems/pOCWxh/)
- [049 - 剑指 Offer II 049. 从根节点到叶节点的路径数字之和【DFS】](https://leetcode-cn.com/problems/3Etpl5/)
- [052 - 剑指 Offer II 052. 展平二叉搜索树](https://leetcode-cn.com/problems/NYBBNL/)
- 方法一:【存储节点,重新建树】
- 方法二:【中序遍历时修改指针】
- [053 - 剑指 Offer II 053. 二叉搜索树中的中序后继](https://leetcode-cn.com/problems/P5rCT8/)
- [054 - 剑指 Offer II 054. 所有大于等于节点的值之和](https://leetcode-cn.com/problems/w6cpku/)
043 - 剑指 Offer II 043. 往完全二叉树添加节点
设置一个队列,在初始化时,只将所有的度小于2的节点依次存储到队列中。
插入时,从队列中取出队首元素,先插入左孩子(如果需要),在插入右孩子(此时要弹出)。
/*** 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 CBTInserter {private Deque<TreeNode> queue;private TreeNode root;public CBTInserter(TreeNode root) {queue = new LinkedList<>();this.root = root;queue.add(root);TreeNode p = root;while (p.left != null && p.right != null) {queue.add(p.left);queue.add(p.right);queue.poll();p = queue.peek();}}public int insert(int v) {TreeNode node = new TreeNode(v);TreeNode p = queue.peek();if (p.left == null) {p.left = node;} else {p.right = node;queue.add(p.left);queue.add(p.right);queue.poll();}return p.val;}public TreeNode get_root() {return this.root;}
}/*** Your CBTInserter object will be instantiated and called as such:* CBTInserter obj = new CBTInserter(root);* int param_1 = obj.insert(v);* TreeNode param_2 = obj.get_root();*/
044 - 剑指 Offer II 044. 二叉树每层的最大值【层次遍历】
/*** 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 List<Integer> largestValues(TreeNode root) {List<Integer> res = new ArrayList<>();if (root == null) {return res;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {int mx = Integer.MIN_VALUE;for (int i = queue.size(); i > 0; i--) {TreeNode p = queue.poll();mx = Math.max(mx, p.val);if (p.left != null) {queue.offer(p.left);}if (p.right != null) {queue.offer(p.right);}}res.add(mx);}return res;}
}
045 - 剑指 Offer II 045. 二叉树最底层最左边的值【层次遍历】
/*** 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 int findBottomLeftValue(TreeNode root) {Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);int lastLeft = 0;while (!queue.isEmpty()) {boolean isFirst = true;for (int i = queue.size(); i > 0; i--) {TreeNode p = queue.poll();if (isFirst) {lastLeft = p.val;isFirst = false;}if (p.left != null) {queue.offer(p.left);}if (p.right != null) {queue.offer(p.right);}}}return lastLeft;}
}
046 - 剑指 Offer II 046. 二叉树的右侧视图【层次遍历】
/*** 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 List<Integer> rightSideView(TreeNode root) {List<Integer> res = new ArrayList<>();if (root == null) {return res;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {int rightElem = 0;for (int i = queue.size(); i > 0; i--) {TreeNode p = queue.poll();rightElem = p.val;if (p.left != null) {queue.offer(p.left);}if (p.right != null) {queue.offer(p.right);}}res.add(rightElem);}return res;}
}
047 - 剑指 Offer II 047. 二叉树剪枝【后序遍历】
- 如果满足一下两个条件,则剪掉:
- 当前节点为0
- 无孩子节点
/*** 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;* }* }*/// 后序遍历// 如果满足一下两个条件,则剪掉:// · 当前节点为0// · 无孩子节点
class Solution {public TreeNode pruneTree(TreeNode root) {if (root == null) {return null;}root.left = pruneTree(root.left);root.right = pruneTree(root.right);if (root.val == 0 && root.left == null && root.right == null) {root = null;}return root;}
}
049 - 剑指 Offer II 049. 从根节点到叶节点的路径数字之和【DFS】
/*** 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 int sumNumbers(TreeNode root) {return dfs(root, 0);}private int dfs(TreeNode root, int prev) {if (root == null) return 0;int sum = prev * 10 + root.val;if (root.left == null && root.right == null) {return sum;} else {return dfs(root.left, sum) + dfs(root.right, sum);}}
}
052 - 剑指 Offer II 052. 展平二叉搜索树
方法一:【存储节点,重新建树】
先进行一次中序遍历,将节点保存下来,然后创建一棵二叉树。
class Solution {public TreeNode increasingBST(TreeNode root) {List<Integer> nodes = new ArrayList<>();inorder(root, nodes);// 建树TreeNode head = new TreeNode(-1);TreeNode cur = head;for (int val : nodes) {cur.right = new TreeNode(val);cur = cur.right;}return head.right;}// 中序遍历,存储节点到nodes中private void inorder(TreeNode root, List<Integer> nodes) {if (root != null) {inorder(root.left, nodes);nodes.add(root.val);inorder(root.right, nodes);}}
}
方法二:【中序遍历时修改指针】
在中序遍历中,遍历到一个节点时,将它作为上一个节点的右孩子,并且将该节点的左指针置空。
class Solution {private TreeNode cur;public TreeNode increasingBST(TreeNode root) {TreeNode resNode = new TreeNode(-1);cur = resNode;inorder(root);return resNode.right;}private void inorder(TreeNode root) {if (root != null) {inorder(root.left);cur.right = root;root.left = null;cur = root;inorder(root.right);}}
}
053 - 剑指 Offer II 053. 二叉搜索树中的中序后继
下一个节点的值一定不会小于节点p的值,而是大于或等于节点p的值的所有节点中值最小的一个。从根节点开始,每到达一个节点就比较根节点的值和节点p的值
如果当前节点的值小于或等于节点p的值,那么节点p的下一个节点应该在它的右子树
如果当前节点的值大于或等于节点p的值,那么当前节点有可能是p的下一个节点,此时当前节点的值比节点p的值大,但节点p的下一个节点是所有比它大的节点中值最小的一个,因此接下来前往当前节点的左子树,确定是否能找到值更小,但仍然大于节点p的值的节点
/*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val = x; }* }*/
class Solution {public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {TreeNode result = null;TreeNode cur = root;while (cur != null) {if (cur.val > p.val) {result = cur;cur = cur.left;} else {cur = cur.right;}}return result;}
}
054 - 剑指 Offer II 054. 所有大于等于节点的值之和
右-根-左的顺序遍历二叉树,恰好是从大到小的顺序,访问根时,对节点的val进行修改。
/*** 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 {int sum = 0;public TreeNode convertBST(TreeNode root) {if (root != null){convertBST(root.right);sum += root.val;root.val = sum;convertBST(root.left);}return root;}
}
【剑指 Offer(专项突击版)】 043-047、049、053-054 刷题笔记【二叉树】相关推荐
- 剑指offer专项突击版第24天
剑指 Offer II 071. 按权重生成随机数 二分+前缀和 看了几遍题目愣是没看明白,最后看的题解明白了! 题意就是按照 w[i]w[i]w[i] 的权重选取下标 iii,这个问题可以转化成:所 ...
- 剑指 Offer II 022. 链表中环的入口节点(力扣剑指Offer专项突击版——链表2)
题目 给定一个链表,返回链表开始入环的第一个节点. 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点.如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 po ...
- 剑指Offer Ⅱ 005.单词长度的最大乘积 (力扣剑指Offer专项突击版——整数_5)
题目 给定一个字符串数组 words,请计算当两个字符串 words[i] 和 words[j] 不包含相同字符时,它们长度的乘积的最大值.假设字符串中只包含英语的小写字母.如果没有不包含相同字符的一 ...
- 剑指Offer Ⅱ 003.二进制加法(力扣剑指Offer专项突击版——整数_3)
题目 给定一个非负整数 n ,请计算 0 到 n 之间的每个数字的二进制表示中 1 的个数,并输出一个数组. 示例 1: 输入: n = 2 输出: [0,1,1] 解释: 0 --> 0 1 ...
- 剑指Offer Ⅱ 001. 整数除法(力扣剑指Offer专项突击版——整数_1)
题目 给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 '*'.除号 '/' 以及求余符号 '%' . 注意: 整数除法的结果应当截去(truncate)其小数部分,例如:tr ...
- LeetCode刷题 _「剑指 Offer]专项突破版
第01天 整数 剑指 Offer II 001. 整数除法 class Solution:# 时间复杂度:O(logn), 空间复杂度:O(1)def divideCore(self, dividen ...
- 剑指Offer专项突破版(58)—— 日程表
题目 剑指 Offer II 058. 日程表 思路 假设现在已经有一堆互不冲突的日程了,此时需要新增一个日程k,其开始时间为start,结束时间为end,怎么判断是否和已有的日程冲突呢? 先考虑所有 ...
- 剑指offer 专项突破版 74、合并区间
题目链接 思路 注意合并区间的规则是,对于有重合的区间直接合并(重合意味着某一个区间的头部在另一个区间之中) 所以我们可以先把区间按照区间头排序,然后再挨个判断是否重合~ 注意具体的写法 class ...
- 剑指offer 专项突破版 78、合并排序链表
题目链接 思路 最初的思路是上一题既然实现了归并两个链表,那么我们可以挨个归并~ 归并n-1次就可以,但是这样时间复杂度为O(k²n) class Solution {public ListNode ...
- 剑指offer 专项突破版 73、狒狒吃香蕉
题目链接 思路 这个也是范围内的查找,一开始可以确定狒狒的速度区间应该是[1,maxVal],但是有两个细节需要注意 如何通过piles数组和speed计算时间 result += (pile + s ...
最新文章
- c#和mysql之间的类型_【SqlServer数据类型、C#数据类型、SqlDbType】对应关系及转换...
- Java虚拟机详解(八)------虚拟机监控和分析工具(2)——可视化
- IOS7的一个神奇的Bug
- wegame一键蹲替换文件_iPhone 提示音一键替换,极简教程
- 【干货】快速部署微软开源GPU管理利器: OpenPAI
- MACOSX下查看某个端口被哪个程序占用及杀进程方法
- 硬盘数据恢复入门教程
- 拳王寻你项目公社:普通人怎么创业,普通人的创业法宝,容易上手的兼职副业项目
- golang mysql连接池原理_redis mysql 连接池 之 golang 实现
- Voovan网络编程介绍
- python下载指定页面的所有图片
- 计算机网络 —— 组网
- 软件开发模型、瀑布模型、V模型、原型模型、增量模型、螺旋模型、喷泉模型
- 计算机数字模拟仿真软件,实时数字仿真系统
- python3 中 sort 方法与 sorted 函数的使用
- 抽基类与PullToRefreshListView
- 现代软件工程 课程总结
- chrome与chromedriver版本对应关系以及官方下载页面
- java发邮件需要什么意思_java 发送邮件需要开启什么服务
- Java基础学习—— IO流
热门文章
- ERROR: pip‘s dependency resolver does not currently take into account all the packages that are ....
- 【python】微信公众号开发
- fflush(stdout)和fflush(stdin)
- 设置Shell脚本开机自启
- 30天自制操作系统 第一天
- 爬取豆瓣音乐Top250详细教程
- 2020计算机分数线,成都计算机电子信息学校2020年招生录取分数线
- windows php进程数,win10的进程数应该多少?
- STATA 学习笔记: outlier(离群值)的处理
- COMMAND NOT SUPPORTED 解决方法