资讯专栏INFORMATION COLUMN

leetcode239. Sliding Window Maximum

sPeng / 3249人阅读

摘要:题目要求假设有一个数组和一个长度为的窗口,数组长度。当窗口右滑时,会删除下标上的值,并加入下标上的值。此时中记录的值编程了,并返回当前的最大值为。一旦最大值失效,就从窗口中重新找一个最大值就好了。

题目要求
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.

For example,
Given nums = [1,3,-1,-3,5,3,6,7], and k = 3.

Window position                Max
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7
Therefore, return the max sliding window as [3,3,5,5,6,7].

Note: 
You may assume k is always valid, ie: 1 ≤ k ≤ input array"s size for non-empty array.

假设有一个数组和一个长度为k的窗口,1 ≤ k ≤ 数组长度。这个窗口每次向右移动一位。现在问该窗口在各个位置上,能够得到的子数组的最大值是多少?

思路与代码

如果直接使用TreeSet会有问题,因为Set遇到重复的值时,只会将其添加一次。比如下面这个数组[3,2,3],1。当窗口右滑时,会删除下标0上的值,并加入下标3上的值。此时Set中记录的值编程了[2,1],并返回当前的最大值为2。但是明显下标为2上的值也是3。所以我们不能直接使用Set解决问题。

但是如果每次我们都重新计算滑动窗口中的最大值,那明显浪费了很多之前遍历所提供的有效的信息。我们可以试着去看每次遍历能够得到什么可以重复利用的信息从而尽可能减去无效的遍历。

就看题目中的例子,[1 3 -1] -3 5 3 6 7,我们知道这个窗口中的最大值为3。我们同时也可以确定,3之前的数字无需加入后面大小的比较,因为它们一定比3小。

按照这种规则,我们可以维护一个存储了可比较数字的链表。这个链表中的数字可以和当前准备加入链表的值进行比较。那么我们看一下将一个值加入该链表有什么场景:

链表为空,直接加入

链表的数量大于窗口,则删除最左侧的值

链表中有值,且有些值小于即将加入的值,则这些小于的值都被抛弃

链表中的值均大于即将加入的值,则不进行任何操作

通过这种方式,我们确保了链表头的值一定是当前窗口的最大值。

    public int[] maxSlidingWindow(int[] nums, int k) {
        if(nums.length == 0 || k == 0) return new int[0];
        LinkedList list = new LinkedList();
        int[] result = new int[nums.length - k + 1];
        
        for(int i = 0 ; i= 0){
                result[i-k+1] = nums[list.getFirst()];
            }
        }
        return result;
    }

当然,我们也可以不使用链表来存储当前可比较最大值,而是直接存储当前最大值的下标。一旦最大值失效,就从窗口中重新找一个最大值就好了。而如果当前值比之前的最大值更大,则将最大值下标更新为当前下标就好了。

    public int[] maxSlidingWindow_noDataStructure(int[] nums, int k) {
        if(nums.length == 0 || k == 0) return new int[0];
        int[] result = new int[nums.length - k + 1];
        int max = 0;
        for(int i = 0 ; i nums[max]){
                        max = i-j;
                    }
                }
            }
            if(nums[i] > nums[max]) max = i;
            if(i-k+1>=0){
                result[i-k+1] = nums[max];
            }
        }
        return result;
    }


想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/68571.html

相关文章

  • [LeetCode] 239. Sliding Window Maximum

    摘要:丢弃队首那些超出窗口长度的元素队首的元素都是比后来加入元素大的元素,所以存储的对应的元素是从小到大 Problem Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only...

    lentoo 评论0 收藏0
  • LeetCode 之 JavaScript 解答第239题 —— 滑动窗口最大值(Sliding W

    摘要:你只可以看到在滑动窗口内的数字。滑动窗口每次只向右移动一位。返回滑动窗口最大值。算法思路暴力破解法用两个指针,分别指向窗口的起始位置和终止位置,然后遍历窗口中的数据,求出最大值向前移动两个指针,然后操作,直到遍历数据完成位置。 Time:2019/4/16Title: Sliding Window MaximumDifficulty: DifficultyAuthor: 小鹿 题目...

    spacewander 评论0 收藏0
  • [LintCode/LeetCode] Sliding Window Maximum/Median

    摘要:窗口前进,删队首元素保证队列降序加入当前元素下标从开始,每一次循环都将队首元素加入结果数组 Sliding Window Maximum Problem Given an array of n integer with duplicate number, and a moving window(size k), move the window at each iteration fro...

    crelaber 评论0 收藏0
  • [Leetcode] Sliding Window Maximum 滑动窗口最大值

    摘要:这样,我们可以保证队列里的元素是从头到尾降序的,由于队列里只有窗口内的数,所以他们其实就是窗口内第一大,第二大,第三大的数。 Sliding Window Maximum Given an array nums, there is a sliding window of size k which is moving from the very left of the array to...

    lvzishen 评论0 收藏0
  • Sliding Window Maximum

    摘要:题目链接这道题用,注意一下存的是,因为要判断是否到最大的值,是通过现在的和第一个的差来判断的。 Sliding Window Maximum 题目链接:https://leetcode.com/problems... 这道题用deque,注意一下存的是index,因为要判断是否到最大的window值,是通过现在的index和deque第一个index的差来判断的。 public cla...

    mrcode 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<