20230921刷题记录

20230921刷题记录
参考代码随想录来刷的。

关键词:优先级队列、堆、迭代法二叉树的后序遍历、层序遍历

1 347.前 K 个高频元素

力扣题目链接
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

思路

  1. 遍历数组,将数组中元素值作为key,元素出现的次数作为value存入map中;
  2. 使用一个小根堆,小根堆中理应维护的元素是map中的value;
  3. 遍历map,先将前 k 个 key建立成小根堆;
  4. 而后一次读入余下的key,若map.get(key) > map.get(堆顶元素),则将堆顶元素删除,将当前key加入堆中。

代码使用优先级队列实现的。

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++)
            map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);

        // 创建优先级队列,小根堆实现
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(Comparator.comparingInt(map::get));
        for (Integer key: map.keySet()) {
            if (priorityQueue.size() < k){
                // 建立一个大小为 k 的小根堆
                priorityQueue.offer(key);
            } else {
                // 判断当前key对应的value是否大于堆顶key对应的value
                if (map.get(key) > map.get(priorityQueue.peek())) {
                    priorityQueue.poll();
                    priorityQueue.offer(key);
                }
            }
        }

        // 小根堆
        int[] result = new int[priorityQueue.size()];
        for (int i = result.length - 1; i >= 0; i--)
            result[i] = priorityQueue.poll();
        return result;
    }
}

2 145.二叉树的后序遍历

力扣题目链接
注意一下迭代法实现的后序遍历,需要使用一个指针记录右孩子是否被访问过。

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        ArrayDeque<TreeNode> stack = new ArrayDeque<>();
        TreeNode p = root;
        TreeNode temp = null;
        ArrayList<Integer> res = new ArrayList<>();
        while (p != null || !stack.isEmpty()) {
            if (p != null) {
                stack.push(p);
                p = p.left;
            } else {
                p = stack.peek();
                if (p.right != null && p.right != temp) {
                    // p 的右孩子不为空且没有被访问过,才往右走
                    p = p.right;
                } else {
                    // p 的右孩子为空或者 p 的右孩子已经被访问过了
                    p = stack.pop();
                    res.add(p.val);
                    temp = p;
                    // 下一个访问的元素在栈顶
                    p = null;
                }
            }
        }
        return res;
    }
}

3 102.二叉树的层序遍历

力扣题目链接
每次遍历一层

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<>();
        if (root == null)
            return res;
        
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            List<Integer> levelList = new ArrayList<>();

            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode p = queue.poll();
                levelList.add(p.val);
                if (p.left != null) queue.offer(p.left);
                if (p.right != null) queue.offer(p.right);
            }
            res.add(levelList);
        }
        
        return res;
    }
}

4 107. 二叉树的层序遍历 II

力扣题目链接
跟上面那道题基本类似,两个解决方案

  1. 使用链表,以便使用头插法
  2. 还是用数组,最后遍历数组,倒着取出来
class Solution {
    public List<List<Integer>> levelOrderBottom(TreeNode root) {
        LinkedList<List<Integer>> res = new LinkedList<>();
        if (root == null)
            return res;

        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            List<Integer> levelList = new ArrayList<>();

            int size = queue.size();
            for (int i = 0; i < size; i++) {
                TreeNode p = queue.poll();
                levelList.add(p.val);
                if (p.left != null) queue.offer(p.left);
                if (p.right != null) queue.offer(p.right);
            }
            res.addFirst(levelList);
        }
        return res;
    }
}

5 199. 二叉树的右视图

力扣题目链接
还是层序遍历,每次遍历一层

class Solution {
    public List<Integer> rightSideView(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        if (root == null)
            return res;

        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            int size = queue.size();
            TreeNode p = null;
            for (int i = 0; i < size; i++) {
                p = queue.poll();
                if (p.left != null) queue.offer(p.left);
                if (p.right != null) queue.offer(p.right);
            }
            res.add(p.val);
        }

        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值