7月24号题解

滑动窗口最大值

*****************************************************************

如果使用纯暴力复杂度为(k*n) 但使用单调队列的方式可以让复杂度变为(n) ,单调队列的方式,维护一个单调递减的队列,我们让队首永远维护这个滑动窗口的最大值,将边界设为(1-k,n-k),当i比0大的时候就可以队列的首项就是这个窗口的最大值

{  
    // 使用双端队列来维护滑动窗口中的最大值索引  
    deque<int> p;    
    vector<int> ans(nums.size() - k + 1);  
      
    // 初始化循环变量,i 用于结果数组的索引,j 用于遍历 nums 数组  
    // 注意这里 i 的初始值是 1-k,因为当 j=0 时,窗口还未完全形成(除非 k=1)  
    // 所以此时不记录结果到 ans 中  
    for(int j = 0, i = 1 - k; j < nums.size(); i++, j++)  
    {  
        // 如果当前窗口的起始位置已经超过了数组边界,并且队列的前端是该起始位置的元素  
        // 那么移除它,因为新的窗口已经不包含它了  
        if(i > 0 && p.front() == nums[i - 1])  
        {  
            p.pop_front();  
        }  
          
        // 移除队列后端所有小于当前元素的索引,因为它们不可能是当前窗口的最大值  
        while(!p.empty() && p.back() < nums[j])  
        {  
            p.pop_back();  
        }  
          
        // 将当前元素的索引加入队列  
        p.push_back(j);  
          
        // 如果当前窗口的起始位置已经在数组范围内,记录当前窗口的最大值到结果数组中  
        // 队列的前端始终是窗口中的最大值索引  
        if(i >= 0)  
        {  
            ans[i] = nums[p.front()];  
        }  
    }  
      
    // 返回包含每个窗口最大值的数组  
    return ans;  
}js

单调栈找左右比它小的值

单调栈可以找到某个数后面比它(大或小的数),但现在要解决的是如何维护左右的比它小的值呢。当某个数比它小是我们就可以把栈顶弹出,这里想一下是什么样的数被它压着,前面说了小的能使大的弹出,说明被它压住的是比它小的。当判断完我们会发现栈里还有剩的,说明后面已经没有让它们可以弹出栈的条件了。但左区间还没有判断完。所以要把栈清空

using namespace std;
const int N=1e5+10;
int a[N],l[N],r[N];
/*
例子 8
2 5 6 7 3 4 1 8
左 -1 1 2 3 1 5 -1 7
右 7 5 5 5 7 7 -1 -1
*/
int main()
{
	stack<int> p;
	int n;
	cin>>n;	
	for(int i=1;i<=n;i++) {
		cin>>a[i];
		l[i]=r[i]=-1;//初始化 
	}
	for(int i=1;i<=n;i++)
	{
		while(!p.empty()&&a[p.top()]>a[i]) 
		{//栈非空且入栈元素小于栈顶,需要清算 
			int cur=p.top();//弹出当前栈顶 
			p.pop();
			r[cur]=i;//右边第一个小的元素是 i 
			if(!p.empty()) l[cur]=p.top();// 左边第一个小的数是当前栈顶 
		}
		p.push(i);//栈内单调性调整完毕,压入 i 
	}
	while(!p.empty())// 栈内留下的未弹出的元素 
	{
		int cur=p.top();
		p.pop();
		if(!p.empty()) l[cur]=p.top();
		//最后清算阶段的元素只有左边小,没有右边 
	}
	for(int i=1;i<=n;i++)
	{
		cout<<l[i]<<' ';
	}
	cout<<endl;
	for(int i=1;i<=n;i++)
	{
		cout<<r[i]<<' ';
	}
	return 0;
}
#题解#
全部评论

相关推荐

08-17 20:36
门头沟学院 Java
#牛客创作赏金赛# 是在出租屋里准备秋招,还是在外面玩,甚至是和测试小姐姐谈上恋爱了呢(我听群里大佬分享的),像我这样的小屌丝周末就出去玩玩,偶尔能在大黑书上约个小姐姐出来玩,大家一般怎么过呢,反正我很讨厌待在出租屋棺材房里,也沉不下心思来学习准备秋招,不过感觉自己就算找到工作也完蛋了罢了,一个人在外地工作,长得也一般估摸着也遇不见什么喜欢的和被喜欢的人啦,是要在外面干几年回家考公离家近点,陪陪家人吗,但是感觉我是个老幺儿,家里人也陪伴不了几年,以后朋友都结婚有了自己家庭该何去何从呢,最近组里对我比较好的那个哥也结婚了,他是21届的比我大三岁,害,真的很迷茫,尤其组里其实大部分都是本地人,至少离广东比较近,我一个外地人真不到理由留在这里,真的羡慕有些人可以和对象一起在外面打拼,说实话我并没有什么上班的动力,感觉真要自己一个人过日子的话,也不需要太多钱,那我应该考虑离开互联网这个行业,毕竟还是比较累一点,我何必这么累呢,我对大城市也没有什么情节,物欲也不高,也许如果能考公上岸是个好出路,我感觉自己有点无病呻吟,但是我感觉一个人在外面打拼的话有些孤独感真的是难以抵御,也许过几年挨过这个年龄阶段就好了吗,也许真的是不到人生某个阶段某个年龄没有办法体会吧。当然肯定有些大佬是意气风发的,他们相对同龄人能轻而易举拿到令人艳羡的offer,不得不说让人羡慕的优越感确实也能获得快乐和前进的动力,但是对于我这种实习中厂选手,中间人菜鸟而言他们的路也是不可复制,也许人与人的路都不可不可复制,感觉世上没有完美的事,我也没有最想要的东西,或者说我已经认识到最想要的东西从出生那一刻就注定不能得到,从而就放弃了念想,以至于就不会想到自己有最想要的东西,我想我这就是中间人的无病呻吟罢了,过几年会好的吧,但是目前的路怎么走呢,好迷茫。
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务