动态数据中求最大值或最小值

版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ysl_ysl123/article/details/91414355

1、包含min函数的栈

题目描述

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

思路

用一个栈st1装载数据,利用一个辅助栈st2记录此时st1栈中的最小数据,每次元素入栈st1,和此时st2中的栈顶元素比较,若入栈元素比st2栈顶元素小或等于栈顶元素,则入栈st1同时入栈st2,;否则只入栈st1。st1出栈时,也同st2栈顶元素比较,若元素相同则同时出栈,否则st2不出栈。这样能够保证st2栈顶元素是当前st1中的最小元素。

代码(c++)

class Solution {
public:
    stack<int> st1,st2;
    void push(int value) {
        st1.push(value);
        if(st2.empty()) st2.push(value);
        else{
            if(value<=st2.top()){
                st2.push(value);
            }
        }
    }
    void pop() {
        int t=st1.top();
        st1.pop();
        if(t==st2.top()) st2.pop();
    }
    int top() {
        return st1.top();
    }
    int min() {
        return st2.top();
    }
};

2、滑动窗口的最大值

题目描述

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

思路

利用双端队列,保证队列首元素是此时滑动窗口的最大值:每次滑窗右移,先看滑出窗口的元素是否是队首元素,如果是则队首元素出队;对于滑入的新元素,从队列尾开始逐个向前比较,将比入队元素小的所有元素出队后再入队。

代码(c++)

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        vector<int> res;
        if(size==0||num.size()==0||size>num.size()) return res;
        deque<int> dq;
        int start=0,end=0;
        while(end-start+1<=size){//建立窗口
            while(!dq.empty()&&dq.back()<num[end]) dq.pop_back();
            dq.push_back(num[end++]);
        }
        end--;
        while(end<num.size()){
            res.push_back(dq.front());
            if(num[start]==dq.front()) dq.pop_front();
            start++;
            while(!dq.empty()&&end+1<num.size()&&dq.back()<num[end+1]) dq.pop_back();
            end+=1;
            if(end<num.size()) dq.push_back(num[end]);
        }
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/ysl_ysl123/article/details/91414355