[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 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].
题意:
这是一道滑动窗口的题目,窗口大小是k,每次往右边滑动一格,保存每次窗口中的最大值。直到滑倒窗口的右端到达数组的最右端。
思路:
这道题需要在O(n)的时间内完成。考虑到比如1,3,-1这种窗口内元素对应的最大值是3,当退出一个元素1后,进入一个元素-3,这时候最大值还是更菜窗口中剩余的3,-1中的最大值,然后3退出,5进入,这时候前面所剩部分的-1最大值是-1,而后来进入的元素的最大值是5,所以这个窗口对应的最大值就是5.
由以上分析我们可以得出两个东西,首先我们使用一个栈来保存对应的栈的最大元素,考虑到这个题目实际上是一个队列的进出顺序,所以使用两个栈可以实现一个队列的作用。然后使用的是栈顶元素对应的剩余栈中最大元素的方法保存当前栈中最大的元素。
我们保存两个栈,一个是用来出队列的,一个是用来入队列的,两个栈元素之和是k。用来出队列的栈保存的不是出的元素,比如-1,3,1,这是接下来出的元素的顺序1,3,-1,我们这里的出队列的栈保存的是当前栈中元素的最大值,就是-1,3,3。而另一个栈是用来入队列操作的,比如上面的栈顶元素3出了之后,会入-3,这时候入队列的栈中最大元素是-3,此时入的栈元素是-3,该栈中最大元素是-3,出的栈元素是-1,3,此时出的元素是3,比较3,与-3,此时窗口中的最大值是3.继续移动窗口,此时出的栈元素是-1,对应最大元素是-1,入元素5,栈变成-3,5,入的栈元素最大值是5.比较-1,5,此时窗口最大元素是5. 继续出-1,入3,此时出的栈变成了空,我们降入的栈装入出的栈,得到元素是3,5,5.继续以上的操作。
以上。
代码如下:

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> result;
        if(nums.empty() || k == 0 || nums.size() < k)return result;
        stack<int> s_in, s_max;
        for(int i = 0; i < k; i++)
        {
            s_in.push(nums[i]);
        }
        s_max.push(nums[k - 1]);
        s_in.pop();
        while(!s_in.empty())
        {
            int num = s_in.top();
            s_in.pop();
            if(num > s_max.top())
                s_max.push(num);
            else
                s_max.push(s_max.top());
        }
        int max_in = INT_MIN;
        int size = nums.size();
        for(int i = k; i <= size; i++)
        {
            result.push_back(max(max_in, s_max.top()));
            //cout<<result.back()<<endl;
            if(i == size)break;
            s_in.push(nums[i]);
           // cout<<s_in.top()<<" "<<s_in.size()<<endl;
            max_in = max(max_in, nums[i]);
            s_max.pop();
            if(s_max.empty())
            {

                s_max.push(s_in.top());
               // cout<<s_max.top()<<endl;
                s_in.pop();
                while(!s_in.empty())
                {
                    int num = s_in.top();
                    s_in.pop();
                    //cout<<"push num "<<num<<endl;
                    s_max.push(max(s_max.top(), num));
                }
                max_in = INT_MIN;
            }
        }
        return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值