滑动窗口最大值 java 自己思路 没看任何writeup


简介

滑动窗口最大值,leetcode 239,我觉得我这个方法的时间还不错,所以分享一下我的思路。

另外我的内存内用确实一直不是很优秀,在这方面有研究的小伙伴还希望让我学习一下。

来看一下我的提交:
在这里插入图片描述
用时我是满意的,但是内存占的忒多了。

思考过程

我说一下我的思考过程
首先这是一道典型的滑动窗口题目,那么一定有一个left遍历,然后另一个right用left+k-1来定位。
然后,不可避免就是一定要遍历每一个k长度的数组,知道left+k-1到了nums.length,然后找到k个数的最大值,写入res数组。

那么先别想优化的事情,先写一个findMax函数:

public int findMax(int left, int right, int[] nums) {
        int res = -1;
        
        for (int i = left; i <= right; i++) {
            if (nums[i] > res) {
                res = nums[i];
            }
        }
        return res;
    }

这里没什么纠结的。

  • 优化

有了想法先别写代码,一看我就觉得时间会超。
那么开始优化。

首先我们建立一个小模型,这样方便我讲清楚
[k1,k2,k3] k4 (假设这是k=3的情况)
,当添加进来新的元素k4的时候,一定会将原来的left值k1抛弃掉,那么如果上一个窗口的最大值是k1,毫无疑问要重新用findMax来寻找,那么如果上一个的窗口最大值不是k1的话,很明显我们不需要调用findMax来遍历寻找最大值。

ok,我们已经找到了优化的第一个思路。
然后我仔细一想,我还很贪心,希望继续深化我们的优化方案,我们将lastWindowMax的窗口的位置记下来,继续将部分findMax操作简化为了两个数字的比大小操作。

算法简述

好了这样就是我的算法思路了,来看具体的思路

existed用来记录lastWindowMax的位置:0代表窗口最左边的,以此类推

   /*
    * 当left+k-1<nums.length
    * 查看existed,if( >0 ):
    *   	if( lastWindowMax>nums[left+k-1] ) {existed--;res添加lastWindowMax     } 
    * 		else { existed = 2  res添加nums[left+k-1];   更新lastWindowMax         }
    * else: 计算k窗口最大值,更新existed,更新lastWindowMax
    * left++
    * 循环到第3步
    * */

当然findMax就需要修改为返回max值和对应位置的两个值了。

我用数组结构。

代码

public int[] maxSlidingWindow1(int[] nums, int k) {
        int len = nums.length;
        if (len == 0) {
            return new int[]{};
        }
        int existed = 0;
        int lastWindowMax = -1;
        int left = 0;
        int[] res = new int[len-k+1];
        while (left + k - 1 < len) {
            int tmp = nums[left + k - 1];
            if (existed > 0) {
                if (lastWindowMax > tmp) {
                    existed--;
                    res[left] = lastWindowMax;
                } else {
                    existed = 2;
                    res[left] = tmp;
                    lastWindowMax = tmp;
                }
            } else {
                int[] arr = findMax(left, left + k - 1, nums);
                res[left] = arr[0];
                lastWindowMax = arr[0];
                existed = arr[1];
            }
            left++;
        }
        return res;
    }

    public int[] findMax(int left, int right, int[] nums) {
        int res = -1;
        int loc = 0;
        for (int i = left; i <= right; i++) {
            if (nums[i] > res) {
                res = nums[i];
                loc = i-left;
            }
        }
        return new int[]{res, loc};
    }

大家共勉~~
欢迎指正,和新想法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值