Leetcode-239-Sliding Window Maximum

原创 2015年11月18日 10:03:52

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,从第一个元素开始找到k个连续的元素中最大的元素组成一个数组。

解析:暴力方法可以很简单的解决问题,遍历每个窗口内的元素找到最大值,不需要多余的存储空间,时间复杂度是O(k*n)。接下来我们看如何在这个基础上进行优化改进。

思路一:以题目中给出的例子为例,假设我们找到了第二组(例子中第二行)的Max = 3,接下来计算第三行,窗口右移,新的窗口跟原来的窗口的区别就在于第一个元素和最后一个元素,窗口新加入进来的元素是5,它大于之前窗口的最大元素,理所当然的当前窗口的最大元素就是5了。接下来是第4行,新加入的元素是3,3小于前一窗口的最大元素5,那么是不是说明当前窗口的最大元素也是5呢?这是不确定的,因为并没有考虑窗口右移去掉的那个元素,如果刚好去掉了最大的元素,那么就没办法立即定位出最大元素了,比较笨的方法就是遍历一遍当前窗口。

根据这个思路,窗口右移时如果出现了新加入的元素大于之前的最大元素时,可以立即就确定当前窗口的最大元素,反之还是需要重新遍历窗口。

代码实现:

 public class Solution
    {
        public int[] MaxSlidingWindow(int[] nums, int k)
        {
            if (nums.Length == 0)
                return new int[]{};
            if (k == 1)
                return nums;
            int[] ret = new int[nums.Length - k + 1];
            ret[0] = help(nums, k, 0);
            for (int i = k; i < nums.Length; i++)
            {
                if (ret[i - k] <= nums[i])
                    ret[i - k + 1] = nums[i];
                else
                    ret[i - k + 1] = help(nums, k, i - k + 1);
            }
            return ret;
        }
        public int help(int[] nums, int k, int begin)
        {
            int max = nums[begin];
            for (int i = begin; i <= begin + k - 1; i++)
            {
                max = max >= nums[i] ? max : nums[i];
            }
            return max;
        }
    }


思路二:如果可以借助一个数据结构,将当前窗口的元素按照降序排列,当窗口右移时,只需对数据结构进行相应的插入、删除工作同时不改变数据结构的相对顺序,这样就可以轻松的得到当前窗口的最大元素,其实一个简单的链表就可以实现这个功能了,但是链表的操作同样会拖慢效率。题目的hint提示用deque这个数据结构,这个数据结构的优点是可以在两端进行元素的插入删除,下面借助一个大神的代码,来解释一下这个思路的实现方法。

代码实现:

 public class Solution
    {
        public int[] MaxSlidingWindow(int[] nums, int k)
        {
            if (k == 0) return new int[0];
            LinkedList<int> q = new LinkedList<int>();//定义一个双端队列q,q里存储的时元素的索引,并非元素本身。
            int[] res = new int[nums.Length - k + 1];//存储结果
            for (int i = 0; i < nums.Length; i++)
            {
                //元素的索引 i 入队之前,将比nums[i]小的所有元素的索引在队列中删除,这样可以保证队列中的元素索引所指的数组对应元素是按照降序排列。
                while (q.Count != 0 && nums[i] >= nums[q.Last()])
                {
                    q.RemoveLast();
                }
                q.AddLast(i);//每个元素的索引都会在队列的末尾入队,保证入队的索引是升序排列
                //当前索引 i 与队列中第一个索引的差如果大于k,说明当前队列里的元素个数超过窗口大小,需要删除元素,因为索引是顺序入队的,所以第一个元素就是要删除的元素。
                if (i - q.First() + 1 > k)

                {
                    q.RemoveFirst();
                }
                //在 i -k +1 =0 开始对res赋值。
                if (i + 1 >= k) res[i - k + 1] = nums[q.First()];
            }
            return res;  
        }
    }


版权声明:本文为博主原创文章,未经博主允许不得转载。

leetcode 239: Sliding Window Maximum

leetcode 239: Sliding Window Maximum python c++ java
  • xudli
  • xudli
  • 2015年07月19日 15:41
  • 8708

LeetCode 239. Sliding Window Maximum(滑动窗口最大值)

原题网址:https://leetcode.com/problems/sliding-window-maximum/ Given an array nums, there is a sliding...
  • jmspan
  • jmspan
  • 2016年04月06日 12:53
  • 1721

[python]leetcode(239). Sliding Window Maximum

problem Given an array nums, there is a sliding window of size k which is moving from the very ...
  • PKU_Jade
  • PKU_Jade
  • 2017年09月11日 16:30
  • 119

leetcode 239. Sliding Window Maximum 双端队列 滑动窗口最大值

Given an array nums, there is a sliding window of size k which is moving from the very left of the a...
  • m0_37693059
  • m0_37693059
  • 2017年09月04日 15:25
  • 183

239. Sliding Window Maximum&滑动窗口的最大值

题目描述给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,...
  • sjt091110317
  • sjt091110317
  • 2016年02月26日 17:02
  • 365

LeetCode:Sliding Window Maximum 题解 Python

LeetCode:Sliding Window Maximum 题解 Python
  • soiliml
  • soiliml
  • 2015年08月19日 15:51
  • 507

windows系统socket泄露问题解决--No buffer space available (maximum connections reached?): JVM_Bind

今天在公司服务器上部署的一套后台系统突然不能使用了,上服务器看了一下,控制台打印了如下错误信息: java.net.SocketException: No buffer space availab...
  • yzy199391
  • yzy199391
  • 2017年12月27日 13:50
  • 157

Leetcode 480. Sliding Window Median 滑动窗口中的中位数 解题报告

1 解题思想题目会给一个数组,和一个滑动窗口的大小K,让你找出当这个窗口滑动的过程中,这个K的窗口内的中位数分别是多少?最naive的方式就是在k个窗口内排序就好,这里不解释(因为开销很大啊,(n-k...
  • MebiuW
  • MebiuW
  • 2017年01月13日 15:11
  • 2815

leetcode-Sliding Window Maximum

Total Accepted: 14811 Total Submissions: 62176 Difficulty: Hard Given an array nums, there is...
  • ljlstart
  • ljlstart
  • 2015年11月03日 23:26
  • 193

【leetCode】Sliding Window Maximum

题意:给定一个数组num和一个数k,返回num0..k-1,num1,k...的最大值 思路: 题目提示说要用双端队列,我的想法如下: 用两个双端队列,一个记录数,一个记录下标,如果这个数比当前...
  • XiaYiZhanQiHang
  • XiaYiZhanQiHang
  • 2016年10月29日 12:45
  • 125
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Leetcode-239-Sliding Window Maximum
举报原因:
原因补充:

(最多只允许输入30个字)