题解 | #单调栈#

单调栈

http://www.nowcoder.com/practice/ae25fb47d34144a08a0f8ff67e8e7fb5

题意:

  • 给定一个数组(可含重复值),找到每个元素左边和右边比它小且离它最近的数组位置。

方法一:暴力解法

解题思路:

  • 对于每个元素,都向左和向右找比它小的即可。

代码如下:

public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums intvector 
     * @return intvector<vector<>>
     */
    vector<vector<int> > foundMonotoneStack(vector<int>& nums) {
        // write code here
        int n=nums.size();
        vector<vector<int>> ans(n,vector<int>(2,-1));
        //遍历数组元素
        for(int i=0;i<n;i++){
            //向左寻找比当前小的
            for(int left=i-1;left>=0;left--){
                if(nums[left]<nums[i]){
                    //找到,赋值ans,并跳出
                    ans[i][0]=left;
                    break;
                }
            }
            //向右寻找比当前小的
            for(int right=i+1;right<=n-1;right++){
                if(nums[right]<nums[i]){
                    //找到,赋值ans,并跳出
                    ans[i][1]=right;
                    break;
                }
            }
        }
        return ans;
    }
};

复杂度分析:

时间复杂度:O(n2)O(n^2),双重循环。

空间复杂度:O(1)O(1),常数个临时变量。

方法二:单调栈

解题思路:

  • 利用单调递增栈来存遍历过程中的元素,如果当前元素大于栈顶元素,则直接入栈,所有栈内元素目前还没有找到比它小的;如果当前元素小于栈顶元素,则循环出栈直到当前元素入栈后满足单调栈,那么对于出栈的部分元素,则当前元素就是离最近且比它小的。

图解如下:

alt

代码如下:

public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums intvector 
     * @return intvector<vector<>>
     */
    vector<vector<int> > foundMonotoneStack(vector<int>& nums) {
        // write code here
        //s为单调递增栈
        stack<int> s;
        int n=nums.size();
        vector<vector<int>> ans(n,vector<int>(2,-1));
        //从左往右遍历,并将数组位置存入单调栈中
        s.push(0);
        int i=1;
        while(i<n){
            if(nums[i]>=nums[s.top()]){//递增,直接入栈
                s.push(i);
            }else{//不满足单调增,循环出栈,出栈的部分元素已经找到右边离它最近且值比它小的,
                  //给ans赋值,循环出栈完毕后再入栈
                while(!s.empty()&&nums[s.top()]>nums[i]){
                    ans[s.top()][1]=i;
                    s.pop();
                }
                s.push(i);
            }
            i++;
        }
        //清空栈中元素,初始已赋值-1
        while(!s.empty()){
            s.pop();
        }
        //从右往左遍历,并将数组位置存入单调递增栈中
        s.push(n-1);
        i=n-2;
        //该部分同上
        while(i>=0){
            if(nums[i]>=nums[s.top()]){
                s.push(i);
            }else{
                while(!s.empty()&&nums[s.top()]>nums[i]){
                    ans[s.top()][0]=i;
                    s.pop();
                }
                s.push(i);
            }
            i--;
        }
        return ans;
    }
};

复杂度分析:

时间复杂度:O(n)O(n),两次循环遍历,每次循环每个元素仅入栈一次,出栈至多一次。

空间复杂度:O(n)O(n),栈空间最多n个元素。

全部评论

相关推荐

本人什么都不会求求大家帮我选一个简单一点的
牛客798552099号:选10 目标检测真的很简单 网上随便找点改进的模块拼一下就可以了
点赞 评论 收藏
分享
Yushuu:你的确很厉害,但是有一个小问题:谁问你了?我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了😆
点赞 评论 收藏
分享
10-25 12:05
已编辑
湖南科技大学 Java
若梦难了:我有你这简历,已经大厂乱杀了
点赞 评论 收藏
分享
3 收藏 评论
分享
牛客网
牛客企业服务