LC-239 移动窗口的最大值

目标:

给出一个数组和一个k大小的窗口,窗口从头开始,每次移动一个元素,直到到达数组尾,给出每次窗口的最大值。思考如何在线性时间内完成。

 

主要思路:

一开始,我实现的是,遍历窗口,移动,每次都找出该窗口的最大值,然后输出。这种方法的时间复杂度为O(nk),理论上k是一个定值,所以可以看作是O(n),但实际上,k从1到n,所以最差情况下,时间复杂度是O(n2),其实并不符合。

我在Leetcode上查看讨论,发现很多方法其实都是O(nk)的,但有一个是真的O(n)的算法:

他首先将数组按k个分组,然后巧妙地用2个数组,分别为left_max,right_max来记录每个位置在该小组的左边最大值与右边最大值。然后,遍历一次,当前窗口的最大值,就是该窗口起始点位置的右边最大值及终点位置的左边最大值。

 

代码:

 1 class Solution {
 2 public:
 3     vector<int> maxSlidingWindow(vector<int>& nums, int k) {
 4         int len = nums.size();
 5         if (len == 0) return nums;
 6         
 7         int *left_max = new int[len];
 8         int *right_max = new int[len];
 9         
10         left_max[0] = nums[0];
11         right_max[len - 1] = nums[len - 1];
12         
13         for (int i = 1; i < len; i++) {
14             left_max[i] = (i % k == 0) ? nums[i] : max(left_max[i - 1], nums[i]);
15             
16             int j = len - i - 1;
17             right_max[j] = (j % k == 0) ? nums[j] : max(right_max[j + 1], nums[j]);
18         }
19 
20         vector<int> result;
21         for (int i = 0; i < len - k + 1; i++) {
22             result.push_back(max(right_max[i], left_max[i + k - 1]));
23         }
24         
25         return result;
26     }
27 };

 

posted @ 2018-10-31 15:38  leo_lee  阅读(247)  评论(0编辑  收藏  举报