代码随想录算法训练营Day13:239.滑动窗口最大值,347.前K个高频元素

题目都是第一次做,后面还需巩固!!!

239.滑动窗口最大值

文章链接:代码随想录 (programmercarl.com)

思路:无思路

看完文章的思路:

(a)设计单调队列的时候,pop,和push操作要保持如下规则:

  1. pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
  2. push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到(说明要用while)push元素的数值小于等于队列入口元素的数值为止

(b)保持如上规则,每次窗口移动的时候,只要问que.front()就可以返回当前窗口的最大值。

故事:要自己构造单调队列,看到了力扣上讨论@虫子的世界,讲了一个单调队列的故事,非常形象。单调队列真是一种让人感到五味杂陈的数据结构,它的维护过程更是如此.....就拿此题来说,队头最大,往队尾方向单调......有机会站在队头的老大永远心狠手辣,当它从队尾杀进去的时候,如果它发现这里面没一个够自己打的,它会毫无人性地屠城,把原先队里的人头全部丢出去,转身建立起自己的政权,野心勃勃地准备开创一个新的王朝.....这时候,它的人格竟发生了一百八十度大反转,它变成了一位胸怀宽广的慈父!它热情地请那些新来的“小个子”们入住自己的王国......然而,这些小个子似乎天性都是一样的——嫉妒心强,倘若见到比自己还小的居然更早入住王国,它们会心狠手辣地找一个夜晚把它们通通干掉,好让自己享受更大的“蛋糕”;当然,遇到比自己强大的,它们也没辙,乖乖夹起尾巴做人。像这样的暗杀事件每天都在上演,虽然王国里日益笼罩上白色恐怖,但是好在没有后来者强大到足以干翻国王,江山还算能稳住。直到有一天,闯进来了一位真正厉害的角色,就像当年打江山的国王一样,手段狠辣,野心膨胀,于是又是大屠城......历史总是轮回的。

Java代码:

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        //判断特殊情况
        if(nums.length == 1){
            return nums;
        }
        MyQueue myque = new MyQueue();
        //返回数组的长度
        int len = nums.length - k + 1;
        int[] res = new int[len];
        int num = 0;
        //先把数组中一开始的k个数加入到队列中
        for(int i = 0; i < k;i++){
            //按照单调递减的顺序排号
            myque.add(nums[i]);
        }
        //此时队列的顶部为最大值
        res[num++] = myque.peek();
        //开始移动滑动窗口,移动前要先把最前面的数弹出,然后把当前的数加入到队列中,再记录当前的最大值
        for(int i = k ; i <nums.length;i++){
            myque.poll(nums[i - k]);
            myque.add(nums[i]);
            res[num++] = myque.peek();
        }
        return res;
    }
}

//要自定义一个单调队列(单调递减)
class MyQueue{
    //用Deque双向队列
    Deque<Integer> deque = new LinkedList<>();
    //弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出
    //队列长这样,peek()的值为出口的值
    /*
    出口          入口
    -----------------
      3     2      1
    -----------------
    */
    //同时判断队列当前是否为空
    void poll(int val){
        if(!deque.isEmpty() && val == deque.peek()){
            deque.poll();
        }
    }

    //添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出
    //保证队列元素单调递减
    //比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2
    void add(int val){
        while(!deque.isEmpty() && val > deque.getLast()){
            deque.removeLast();
        }
        deque.offer(val);
    }

    //队列顶部的元素始终为最大值
    int peek(){
        return deque.peek();
    }
}

学习到的一些语法:

(1)Deque接口的getLast ()方法返回Deque的最后一个元素或尾部。它不会删除元素。当双端队列为空时,它将引发异常。

(2)Java Deque 接口的 removeLast() 方法用于检索和删除给定双端队列的最后一个元素。上述方法与 pollLast() 方法不同,如果给定的双端队列为空,则抛出异常。

347.前K个高频元素

文章链接:代码随想录 (programmercarl.com)

思路:无思路

看完文章后的思路:

(1)先用Map来保存元素值和元素出现的频次

(2)使用PriorityQueue来实现小顶堆,其中Comparator接口正负表示排列顺序

 返回负数,形参中第一个参数排在前面;返回正数,形参中第二个参数排在前面
 * 对于队列:排在前面意味着往队头靠
 * 对于堆(使用PriorityQueue实现):从队头到队尾按从小到大排就是最小堆(小顶堆),
 *                                从队头到队尾按从大到小排就是最大堆(大顶堆)--->队头元素相当于堆的根节点

(3)按照小顶堆,将key,value按照value频次的大小压入到小顶堆中,如果此时堆中个数大于k了,说明前k个频次高的元素已经在里面了,此时可以弹出

Java代码:第一次做先了解思路

算法小白还需继续努力!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值