算法训练营(第一期)

本文介绍了在Java算法训练营中,关于滑动窗口问题(LeetCode239)的错误解法和正确使用栈的优化解法,以及如何使用队列和小顶堆解决前K个高频元素(LeetCode347)的问题。
摘要由CSDN通过智能技术生成

算法训练营(第一期)第十一天(java)

学习感悟:



题目


一、滑动窗口的最大值(leetcode239)

题目

错误解法:使用二层循环但是出现超出时间限制

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int[] result=new int[nums.length-k+1];
        //我想最简单的方法应该就是两层for循环
        for(int i=0;i<nums.length;i++){
            if(nums.length-i<k) break;
            int max=nums[i];
            for(int j=i;j<i+k;j++){
                if(nums[j]>max){
                    max=nums[j];
                }else{
                    max=max;
                }
            }
            result[i]=max;

        }
        return result;
    }
}

在这里插入图片描述

正确解法:使用栈来解决问题

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        //我们可以自定义一套规则来维护一个单调递减的队列保证了每次弹出的元素都是要被滑动走的元素    
        Deque<Integer> q=new LinkedList<>();
        
        int[] result=new int[nums.length-k+1];
        for(int i=0;i<k;i++){
            push(q,nums[i]);
        }
        int count=0;
        result[count++]=getMaxValue(q);
        for(int i=k;i<nums.length;i++){
            
            poll(q,nums[i-k]);
            push(q,nums[i]);
           result[count++]=getMaxValue(q);
        }
        return result;


    }
     void poll(Deque q,int x){
        //弹出元素,弹出的前提是队头的元素要是数组中要移除的元素
        if(!q.isEmpty()&& x==(int)q.peek()){
            q.poll();
        }
        
    }
     int getMaxValue(Deque q){
        return (int)q.peek();
    }
     void push(Deque q,int x){
        //送入后保证前面比其小的元素都被移除
        while(!q.isEmpty()&&x > (int)q.getLast()){
            q.removeLast();
        }
        q.add(x);
    }
}

二、前 K 个高频元素(leetcode347)

题目
代码明天补充
解法:

class Solution {
    public int[] topKFrequent(int[] nums, int k) {  
        //采用栈与队列的方法来解决,怎么解决?
        //采用暴力方法,hash方法,但是我还要对value排序这可如何是好?
        HashMap<Integer,Integer> hm=new HashMap();
        for(int i=0;i<nums.length;i++){
            hm.put(nums[i],hm.getOrDefault(nums[i],0)+1);
        }
        //使用小顶堆对hashmap进行排序
        PriorityQueue<int[]> pq=new PriorityQueue(new Comparator<int[]>(){
            public int compare(int[] temp1,int[] temp2){
                if(temp1[1]-temp2[1]>=0) return 1;
                else return -1;
            }
        });
        //往里面放value如果大于k而且要添加的元素的value也要大于开头则将头部弹出,但是我怎么知道那个value对应那个key呢?那我就对键值对进行排序
        for(Map.Entry<Integer,Integer> entry:hm.entrySet()){
          if(pq.size()<k){
              pq.add(new int[]{entry.getKey(),entry.getValue()});
          }else{
              //
              if(pq.peek()[1]<entry.getValue()){
                  pq.poll();
                  pq.add(new int[]{entry.getKey(),entry.getValue()});
              }
          }
        }
        //倒序遍历堆将元素取出即可
        int[] result=new int[k];
        for(int i=k-1;i>=0;i--){
            result[i]=pq.poll()[0];
        }
        return result;
    }
}
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值