解法一:暴力解法
穷举所有数组中所有子数组,并计算所有子数组中最小值*子数组所有数的和,求出其中的最大值即可,代码如下:
int enum_method(vector<int> &num) {
int n = num.size();
int maxSum = INT_MIN;
vector<int> tmp;
for (int i = 0; ifor (int j = i; jfor (int k = i; k <= j; ++k) {
tmp.push_back(num[k]);
}
sort(tmp.begin(), tmp.end());
int curSum = tmp[0] * vecSum(tmp, 0, tmp.size() - 1);
maxSum = max(curSum, maxSum);
}
}
return maxSum;
}
时间复杂度为O(N*N*N)
解法二:单调栈解法
基本思想:
1. 以数组中每一个值为最小值,假设这个最小值为num[k], 分别找到以该值num[k]为最小值,数组最左边的小于该值的下标i,和数组最右边的小于该值的下标j, 则区间num[i+1,j-1]为以num[k]为最小值所能达到的最大区间,则此区间能达到的最大值为num[k]*Sum(i+1,j-1),其中Sum函数为数组中区间[i+1,j+1]的所有数的和
2. 按照步骤1(可利用单调栈实现)结算数组中每一个值,维护一个最大值maxSum, 当遍历数组的最后一个数,所得maxSum即为所求。
举例说明步骤1单调栈的实现:
如现在有一个数组vector
,我们将数组的数压栈入栈的规则如下:
如现在我们开始遍历数组[6,2,5,5,5,4,7],
单调栈代码如下:
int incr_stack(vector<int> &num) {
stack<int> s;
int sum = 0;
int maxSum = INT_MIN;
int n = num.size();
for (int i = 0; iif (s.empty() || num[i] >=num[s.top()]) {//规则1
s.push(i);
}
else {
while (!s.empty() && num[s.top()] >=num[i]) {//规则2
int top = s.top();
s.pop();
int tmp=s.empty()? vecSum(num, 0, i-1) : vecSum(num, s.top()+ 1, i - 1);
int curSum = num[top]*tmp;
maxSum = max(curSum, maxSum);
}
s.push(i);
}
}
while (!s.empty()) {//规则3
int top = s.top();
s.pop();
int tmp=s.empty()? vecSum(num, 0, n-1): vecSum(num, s.top()+ 1, n - 1);
int curSum = num[top]*tmp;
maxSum = max(curSum, maxSum);
}
return maxSum;
}
#include
#include
#include
#include
#include
using namespace std;
int vecSum(vector<int> &num, int i, int j)//计算num[i]到num[j]的和
{
int sum=0;
for (int k = i; k <= j; k++) {
sum += num[k];
}
return sum;
}
int incr_stack(vector<int> &num) {//单调栈实现
stack<int> s;
int sum = 0;
int maxSum = INT_MIN;
int n = num.size();
for (int i = 0; iif (s.empty() || num[i] >=num[s.top()]) {//规则1
s.push(i);
}
else {
while (!s.empty() && num[s.top()] >=num[i]) {//规则2
int top = s.top();
s.pop();
int tmp=s.empty()? vecSum(num, 0, i-1) : vecSum(num, s.top()+ 1, i - 1);
int curSum = num[top]*tmp;
maxSum = max(curSum, maxSum);
}
s.push(i);
}
}
while (!s.empty()) {//规则3
int top = s.top();
s.pop();
int tmp=s.empty()? vecSum(num, 0, n-1): vecSum(num, s.top()+ 1, n - 1);
int curSum = num[top]*tmp;
maxSum = max(curSum, maxSum);
}
return maxSum;
}
int enum_method(vector<int> &num) {//穷举方法,用于测试
int n = num.size();
int maxSum = INT_MIN;
vector<int> tmp;
for (int i = 0; ifor (int j = i; jfor (int k = i; k <= j; ++k) {
tmp.push_back(num[k]);
}
sort(tmp.begin(), tmp.end());
int curSum = tmp[0] * vecSum(tmp, 0, tmp.size() - 1);
maxSum = max(curSum, maxSum);
}
}
return maxSum;
}
vector<int> getRandomArray(int len) {//随机产生数组
vector<int> res;
if (len<0)
return res;
res.reserve(len);
srand((unsigned)time(NULL));
for (int i = 0; i100);
}
return res;
}
void printArray(vector<int> arr) {//用于测试
for (int i = 0; icout << arr[i] << " ";
}
cout << endl;
}
int main()
{
bool flag=true;
for(int i=1;i<200;i++){
vector<int> num = getRandomArray(i);
//printArray(num);
int res1=enum_method(num);
int res2=incr_stack(num);
if(res1!=res2){
flag=false;
break;
}
}
if(flag)
cout<<"true"<else
cout<<"false"<