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);
    }
}

在这里插入图片描述

posted @ 2022-05-26 20:28  青松城  阅读(10)  评论(0编辑  收藏  举报