5.<tag-二叉树和遍历>lt.662. 二叉树的最大宽度+ 剑指 Offer 54. 二叉搜索树的第k大节点 + lt.230. 二叉搜索树中第K小的元素
X.<tag-数组和二分查找>-lt.xx-xxxxxx + lt.xx-xxxxxx
lt.662. 二叉树的最大宽度
[案例需求]
[思路分析一, 修改结点为索引, 标记结点位置]
- 之前我们学过层序遍历, 对于层序遍历一般是采用队列存储节点,
- 然后每一层结点如果要取前一个结点和后一个结点的话, 可以分别使用双端队列的 queue.peekFirst()和queue.peekLast() 实现,
- 所以我们如果是求宽度的话, 可以在遍历下一层结点之前, 记录下来上一层第一个结点和最后一个结点的索引位置,
那么如何记录第一个结点, 最后一个结点的位置呢?
这里我们利用在访问每层结点时, 把结点的值修改为二叉树的索引即可,
如 root的index为i, 那么它的左孩子索引为 2i, 右孩子索引为 2i + 1;
[代码实现]
class Solution {
public int widthOfBinaryTree(TreeNode root) {
if (root == null) {
return 0;
}
int res = 1;
LinkedList<TreeNode> queue = new LinkedList<>();
root.val = 1;
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
res = Math.max(queue.peekLast().val - queue.peekFirst().val + 1, res);
while (size-- > 0) {
TreeNode cur = queue.poll();
if (cur.left != null) {
cur.left.val = cur.val * 2 + 1;
queue.offer(cur.left);
}
if (cur.right != null) {
cur.right.val = cur.val * 2 + 2;
queue.offer(cur.right);
}
}
}
return res;
}
}
[代码实现二, 不修改结点, 利用新的集合记录每个结点的index]
class Solution {
public int widthOfBinaryTree(TreeNode root) {
if (root == null) {
return 0;
}
int res = 1;
// 每一个操作都如影随形,保证一一对应
LinkedList<TreeNode> queue = new LinkedList<>();
LinkedList<Integer> idxQ = new LinkedList<>();
queue.offer(root);
idxQ.offer(1);
while (!queue.isEmpty()) {
int size = queue.size();
// 这里就可以记录二叉树的最大宽度了
res = Math.max(idxQ.peekLast() - idxQ.peekFirst() + 1, res);
while (size-- > 0) {
TreeNode cur = queue.poll();
int idx = idxQ.poll();
if (cur.left != null) {
idxQ.offer(idx * 2 - 1);
queue.offer(cur.left);
}
if (cur.right != null) {
idxQ.offer(idx * 2);
queue.offer(cur.right);
}
}
}
return res;
}
}
作者:I_use_java
链接:https://leetcode.cn/problems/maximum-width-of-binary-tree/solution/by-i_use_java-2sn0/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
剑指 Offer 54. 二叉搜索树的第k大节点
[案例需求]
[思路分析一, 暴力解法]
- 先遍历整棵树, 无论采用什么遍历方法(这里我用了递归), 将得到的结点存入list中.
- 然后对list排序(如何排序? 使用工具类
Colleections.sort(list, new Comparator<>(){}))
- 至于递增还是递减, 看题目要求呗, 然后我们根据索引返回需要的值即可;
[代码实现]
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int kthLargest(TreeNode root, int k) {
//遍历二叉树存入list, 对list进行自定义排序, 然后返回第k个即可;
List<Integer> list = dfs(root);
Collections.sort(list, new Comparator<Integer>(){
public int compare(Integer a, Integer b){
return b - a;
}
});
return list.get(k - 1);
}
List<Integer> list = new ArrayList<>();
public List<Integer> dfs(TreeNode root){
//递归出口
if(root == null)return list;
dfs(root.left);
list.add(root.val);
dfs(root.right);
return list;
}
}
[思路分析二, 利用BST的性质解题]
本文解法基于此性质: 二叉搜索树的中序遍历为 递增序列 。
[代码实现]
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int res = 0, k = 0;
public int kthLargest(TreeNode root, int k) {
this.k = k;
dfs(root);
return res;
}
public void dfs(TreeNode root){
//递归出口
if(root == null)return;
dfs(root.right);
k--;
if(k == 0){
res = root.val;
return;
}
dfs(root.left);
}
}
230. 二叉搜索树中第K小的元素
[案例需求]
[思路分析]
- 哈哈, 又水一题, 开心!
- 这道题跟上面那个 第 k 个最大解法基本一致, 略微不同在于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 {
int res = 0, _k = 0;
public int kthSmallest(TreeNode root, int k) {
this._k = k;
dfs(root);
return res;
}
public void dfs(TreeNode root){
if(root == null)return;
dfs(root.left);
--_k;
if(_k == 0){
res = root.val;
return;
}
dfs(root.right);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律