标签:rom 之间 资料 practice 设计 关系 获取元素 转化 索引
关键词:滑动窗口
思路:保存每次栈更新时的最小值,可以通过定义另外一个栈实现。
思路: 队列是先进先出,栈是先进后出。入队列的时候将元素放入栈1,出队列时,如果栈2为空,将栈1的元素全部弹出压入栈2,这样栈2的弹出的元素就符合先进先出的原则了。这里要注意将栈1的元素压入栈2的时机。
思路:
设计递归函数reverse实现栈的逆序,参数是一个栈s:
1.如果s为空,则直接返回
2.如果s非空:
上面的整个逻辑是完整,唯一问题就是(1)得到并删除s的栈底元素v该怎么实现?
同样设计一个递归函数:getAndRemoveLastElement实现返回并删除栈底元素,参数是栈s:
1.出栈一个元素v
2.检查栈是否为空:
为空,此时v就是栈底元素,因此返回v
非空,则调用getAndRemoveLastElement获取元素t,此时t为栈底元素而v不是,因此将v再压入栈,返回t。
思路:
假设排序栈为orderStack,另外一个栈为helpStack,实现orderStack从顶到底按从大到小的顺序排序,这里可以转换一下思路,等同于实现helpStack从顶到底按从小到大的顺序排序。
注意点:
思路:
? 需要借助双端队列。队列用于保存当前滑动窗口下的最大值的下标。
需要注意:
每个下标的都至多进出队列一次,所以时间复杂度时O(N)。
个人注意点:
第一种思路个人理解(多个横着的柱状图矩形面积求最大):
1.首先将原问题问题进行分解。
2.求解每个子问题
计算出矩阵的每个元素的左边连续 1 的数量
采用柱状图求最大面积的思想,详细可参照力扣链接。
时间复杂度=子问题的个数*子问题的求解时间 = O(nmn)
另外一种的理解(多个竖着的柱状图的矩形面积求最大)
1.首先对问题进行分解,转化成求以当前行为底的直方图的最大矩形面积,有N行则操作N次。
2.求直方图的的最大矩形面积时,对每个小矩形向左和右扩展。实际计算需要采用栈,栈从栈顶到栈底存有每个小矩形的位置下标。要求从顶到底高度递减。有M列,即M个位置,要求O(M)操作完成。
总结:
基本思路:
首先暴力解法时找出所有的子数组然后判断是否满足条件,时间复杂度时O(N^3)。
基本步骤
? 按照数组的开头的位置不同,分别计算从位置0开始的数组,从位置1开始的数组...的满足条件的子数组个数,然后相加即可。
注意:
2 栈的使用
一个环形山脉,哪两座山的烽火可以相互看见,条件如下:
思路:
简化问题:n座山的高度都是不同的情况:
假设A(1),B(2),C(3),D(4)三座山,A最多找到2座山配对,B最多也能2座山配对。我们要确保,A的2个配对与B的2个配对不能重复的情况。例如(A,B)可能会重复计数2次。因此我们需要在配对的时候,进行约定,避免这种重复情况出现。
限制:对于每座山,只配对比它高的山峰(小找大)。
上面的限制只是为了方便思考,不会对最终的结果产生思想,但是解题的时候有了上述的限制,对解题思路的产生有着重大的作用。对这个解题空间进行了明确的划分。
在这样的限制下,考虑n座不同高度山的情况,我们需要考虑三种情况:
情况1:最高峰配对数目:0
情况2:次高峰配对数目:1 (由于只能与比自己高的山配对,因此只有与最高峰配对这一种情况)
情况3:剩下的山峰:(n-2)*2 (剩下的每座山峰都可以从2个方向找到比其高的山峰配对)
n座山中的高度可以重复:
在这种情况下,我们需要借助栈去解决问题,借助栈的原因在于小找大的限制。
基本思路如下:
1)先挑选一个高度最高的山入栈。
2)然后从高度最高的山下一座山开始遍历,完成这个遍历。
3)遍历完成后,堆栈中还会剩余。对于剩余的也要分为2种情况考虑:
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
typedef struct moun{
int h;
int num;
} mu,*pmu;
int combination_sum(int n){
return (n)*(n-1)/2;
}
vector<mu> m(1000005);
stack<mu> mystack;
int main(){
int num;
cin >> num;
int max_index = 0;
int max_h = -100000000;
for(int i = 0;i < num;++i){
cin >> m[i].h;
m[i].num = 1;
if(m[i].h > max_h){
max_h = m[i].h;
max_index = i;
}
}
int result = 0;
int index = 0;
pmu p_top;
mystack.push(m[max_index]);
for(int j = 1;j < num;++j){
index = (j+max_index)%num;
p_top = &mystack.top();
if(p_top->h > m[index].h){ //栈顶的山高度大于下一座山,将山入栈
mystack.push(m[index]);
}else if(p_top->h == m[index].h){ //栈顶的山高度等于下一座山,栈顶山数目累加
p_top->num += 1;
}else{ //栈顶的山高度小于下一座山,栈顶山出栈,计算出栈的山配对数。
result += combination_sum(p_top->num) + p_top->num*2;
mystack.pop(); //这边需要多次处理,可能需要多次操作
mystack.push(m[index]);
}
}
if(!mystack.empty()){
while(mystack.size() >= 3){ #遍历后还有超过2座山的部分,继续之前处理
p_top = &mystack.top();
result += combination_sum(p_top->num) + p_top->num*2;
mystack.pop();
}
if(mystack.size() == 2){ # 还剩2座山
pmu first,second;
first = &mystack.top();
mystack.pop();
second = &mystack.top();
mystack.pop();
if(second->num == 1){ # 最底层山的数目为1
result += combination_sum(first->num) + first->num;
}else{ # 最底层山的数目大于等于2
result += combination_sum(first->num) + first->num*2;
result += combination_sum(second->num);
}
}else if(mystack.size() == 1){ # 只有最后一座山
p_top = &mystack.top();
result += combination_sum(p_top->num);
mystack.pop();
}
}
cout << result << endl;
return 0;
}
01 京东2017校招编程题 - 保卫方案(山峰对数量)
02 程序员代码面试指南
20210201
标签:rom 之间 资料 practice 设计 关系 获取元素 转化 索引
原文地址:https://www.cnblogs.com/kfcuj/p/14459492.html