问:我有一个A[1,...,n] 正数数组 ,例如:
[1, 2, 5, 3, 7, 2, 8, 4]
我需要S[1,...,n] 根据定义构建一个数组 :
S[i] = max {k|ik <ji :A[j] A[i] and k i}
这意味着要找到最长的子数组A[i − k,..,i] ,该数组的 所有元素A[i] 对于数组中的每个索引都小于或等于 。
我需要编写一个使用Stack在O(n)中创建数组S的算法 。
例如对于数组[1,2,4,3,5],我需要返回数组[1,2,3,2,5]
答:遵循C ++代码将解决您的问题。
#include <iostream>
#include <堆栈>
使用命名空间std;
无效的calculate(int arr [],int n)
{
//创建一个堆栈并将第一个元素的索引压入该堆栈
stack <int> st;
st.push(0);
//第一个元素的最大范围值始终为1
int max = 1;
int tmp = 0;
int索引= 0;
//计算其余元素的范围值
为(int i = 1; i <n; i ++){
//在堆栈不为空且位于顶部时弹出堆栈中的元素
//堆栈小于price [i]
while(!st.empty()&& arr [st.top()] <arr [i])
st.pop();
//如果堆栈变为空,则arr [i]大于所有元素
//在其左侧,即arr [0],arr [1],.. arr [i-1]。其他arr [i]
//大于栈顶之后的元素
tmp =(st.empty())?(i + 1):( i-st.top());
if(tmp> max){//保持最长记录到第i个元素的记录
max = tmp;
索引= i;
}
//将这个元素压入堆栈
st.push(i);
}
int startIndex = index-max + 1; // startIndex将指向子数组的起始索引
int limitIndex =索引;// limitIndex将根据问题指向子数组的最后一个索引。
//打印范围
cout <<“最后的子数组将是:”;
对于(int i = startIndex; i <= limitIndex; i ++)
cout << arr [i] <<“”;
cout << endl;
返回;
}
int main()
{
int n;
cout <<“输入数组的大小:”;
cin >> n;
int arr [n];
cout <<“输入数组的元素:”;
对于(int i = 0; i <n; i ++)
cin >> arr [i];
计算(arr,n);
返回0;
}
样本输入和输出
输入数组的大小:7
输入数组的元素:100 80 60 70 60 75 85
最终的子数组为:80 60 70 60 75 85
输入数组的大小:6
输入数组的元素:1 1 1 1 1 1
最终的子数组将是:1
输入数组的大小:5
输入数组的元素:1 2 3 4 5
最终的子数组将是:1 2 3 4 5
输入数组的大小:8
输入数组的元素:1 2 5 3 7 2 8 4
最终的子数组为:1 2 5 3 7 2 8