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

239. 滑动窗口最大值 - 力扣(LeetCode)

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
                
        int[] result = new int[nums.length-k+1];

        //暴力一点会怎么样呢
//      for(int i=0;i<nums.length-k+1;i++){
//            int max = nums[i];
//            for(int j=0;j<k;j++){
//                if(nums[i+j] > max){
//                    max = nums[i+j];
//                }
//            }
//            result[i] = max;
//        }
//
//        return result;


        //1.假设现在有一个长度最大为K的队列,他的第一个元素就是以当前正在遍历元素为窗口结尾元素的整个窗口里面最大的值
        //就可以每次遍历元素的时候取这个队列的队头元素了;
        LinkedList<Integer> monotoneQueue = new LinkedList<>();
        LinkedList<Integer> indexQueue = new LinkedList<>();
        
        for(int i=0;i<nums.length;i++){
            //5.队首元素确实是最大的,但是和当前遍历元素的窗口已经超过K了,再大也不能要了
            if(!indexQueue.isEmpty() && (i - indexQueue.getFirst()) >= k){
                monotoneQueue.removeFirst();
                indexQueue.removeFirst();    
            }
            
            //2.维护的队列元素为空,直接放值
            if(monotoneQueue.isEmpty()){
                monotoneQueue.add(nums[i]);
                indexQueue.add(i);   
            }else{
                //3.正在遍历的元素比队头元素都大,它就是窗口里面最大的了,后续要取的话也是取这个元素,队列可以直接清空
                if(nums[i] >= monotoneQueue.getFirst()){
                    monotoneQueue.clear();
                    indexQueue.clear();
                    monotoneQueue.addLast(nums[i]);
                    indexQueue.addLast(i);
                }else{
                    //4.当前元素不是最大的,但是可能在中间,往后遍历的时候小于当前元素的值就不需要考虑了
                    while(!monotoneQueue.isEmpty() && nums[i] >= monotoneQueue.getLast()){
                        monotoneQueue.removeLast();
                        indexQueue.removeLast();
                    }
                    monotoneQueue.addLast(nums[i]);
                    indexQueue.addLast(i);
                }
            }
            
            if(i-k+1 >=0 ){
                result[i-k+1] = monotoneQueue.getFirst();
            }
        }
        
        return result;
    }
}

347. 前 K 个高频元素 - 力扣(LeetCode)

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        HashMap<Integer,Integer> numsCountMap = new HashMap<>();

        for(int i=0;i<nums.length;i++){
            numsCountMap.put(nums[i],numsCountMap.getOrDefault(nums[i],0)+1);
        }

        HashMap<Integer,List<Integer>> countNumsMap = new HashMap<>();
        TreeSet<Integer> countTreeSet = new TreeSet<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        for (Map.Entry<Integer, Integer> numsCountMapEntry : numsCountMap.entrySet()) {
            Integer num = numsCountMapEntry.getKey();
            Integer count = numsCountMapEntry.getValue();
            
            if(countNumsMap.get(count) == null){
                List<Integer> numList = new ArrayList();
                numList.add(num);
                countNumsMap.put(count,numList);
            }else{
                countNumsMap.get(count).add(num);
            }

            countTreeSet.add(count);
        }

        int[] result = new int[k];
        for(int i=0;i<k;){
            Integer count = countTreeSet.pollFirst();
            List<Integer> numList = countNumsMap.get(count);
            for(int j=0;j<numList.size();j++){
                result[i+j] = numList.get(j);
            }
            i+=numList.size();
        }
        
        return result;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值