#include <iostream>
#include <stack>
#include <cstring>
using namespace std;
class Solution
{
public:
int getMaxProduct(int *arr, int n)
{
if(n < 3) return 0;
AllocateMemory(n); //all memory set to 0
//First calculate the max value that is larger than the current value in the right of each element
calculateRightMax(arr, n);
//Secondly calculate the max value that is smaller than the current value in the left of each element
calculateLeftMax(arr, n);
//Now get maximum of product
int maxProduct = 0, curProduct = 0;
for(int i = 1; i < n - 1; ++i)
{
curProduct = leftMaxArr[i] * arr[i] * rightMaxArr[i];
if(curProduct > maxProduct)
maxProduct = curProduct;
}
FreeMemory();
return maxProduct;
}
private:
int *rightMaxArr;
int *leftMaxArr;
void AllocateMemory(int n)
{
leftMaxArr = new int[n<<1];
rightMaxArr = &leftMaxArr[n];
memset(leftMaxArr, 0, sizeof(int)*(n<<1));
}
void FreeMemory()
{
delete [] leftMaxArr;
}
void calculateRightMax(int * arr, int n)
{
int maxVal = 0;
for(int i = n - 1; i >= 0; --i)
{
if(maxVal > arr[i])
rightMaxArr[i] = maxVal;
else
maxVal = arr[i];
}
}
void calculateLeftMax(int * arr, int n)
{
stack<int> stackA;
stackA.push(arr[0]);
int curPos = 1, leftMax = 0;
while(curPos < n)
{
if(rightMaxArr[curPos] == 0)
{
++curPos;
continue;
}
leftMax = 0;
while(!stackA.empty() && arr[curPos] >= stackA.top())
{
if(arr[curPos] > stackA.top())
leftMax = stackA.top();
stackA.pop();
}
leftMaxArr[curPos] = leftMax;
stackA.push(arr[curPos++]);
}
}
};
int main() {
int arr1[] = {6, 7, 8, 1, 2, 3, 9, 10};
int arr2[] = {1, 5, 10, 8, 9};
Solution so;
cout<<"Output for arr1 is "<<so.getMaxProduct(arr1, sizeof(arr1)/sizeof(int))<<endl<<endl;
cout<<"Output for arr2 is "<<so.getMaxProduct(arr2, sizeof(arr2)/sizeof(int))<<endl<<endl;
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RhY2s+CiNpbmNsdWRlIDxjc3RyaW5nPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKY2xhc3MgU29sdXRpb24KewpwdWJsaWM6CglpbnQgZ2V0TWF4UHJvZHVjdChpbnQgKmFyciwgaW50IG4pCgl7CgkJaWYobiA8IDMpCXJldHVybiAwOwoJCUFsbG9jYXRlTWVtb3J5KG4pOwkvL2FsbCBtZW1vcnkgc2V0IHRvIDAKCQkKCQkvL0ZpcnN0IGNhbGN1bGF0ZSB0aGUgbWF4IHZhbHVlIHRoYXQgaXMgbGFyZ2VyIHRoYW4gdGhlIGN1cnJlbnQgdmFsdWUgaW4gdGhlIHJpZ2h0IG9mIGVhY2ggZWxlbWVudAoJCWNhbGN1bGF0ZVJpZ2h0TWF4KGFyciwgbik7CgkJLy9TZWNvbmRseSBjYWxjdWxhdGUgdGhlIG1heCB2YWx1ZSB0aGF0IGlzIHNtYWxsZXIgdGhhbiB0aGUgY3VycmVudCB2YWx1ZSBpbiB0aGUgbGVmdCBvZiBlYWNoIGVsZW1lbnQKCQljYWxjdWxhdGVMZWZ0TWF4KGFyciwgbik7CgkJCgkJLy9Ob3cgZ2V0IG1heGltdW0gb2YgcHJvZHVjdAoJCWludCBtYXhQcm9kdWN0ID0gMCwgY3VyUHJvZHVjdCA9IDA7CgkJZm9yKGludCBpID0gMTsgaSA8IG4gLSAxOyArK2kpCgkJewoJCQljdXJQcm9kdWN0ID0gbGVmdE1heEFycltpXSAqIGFycltpXSAqIHJpZ2h0TWF4QXJyW2ldOwoJCQlpZihjdXJQcm9kdWN0ID4gbWF4UHJvZHVjdCkKCQkJCW1heFByb2R1Y3QgPSBjdXJQcm9kdWN0OwoJCX0KCQkKCQlGcmVlTWVtb3J5KCk7CgkJcmV0dXJuIG1heFByb2R1Y3Q7Cgl9Cgpwcml2YXRlOgoJaW50CSpyaWdodE1heEFycjsKCWludCAqbGVmdE1heEFycjsKCQoJdm9pZCBBbGxvY2F0ZU1lbW9yeShpbnQgbikKCXsKCQlsZWZ0TWF4QXJyID0gbmV3IGludFtuPDwxXTsKCQlyaWdodE1heEFyciA9ICZsZWZ0TWF4QXJyW25dOwoJCW1lbXNldChsZWZ0TWF4QXJyLCAwLCBzaXplb2YoaW50KSoobjw8MSkpOwoJfQoJCgl2b2lkIEZyZWVNZW1vcnkoKQoJewoJCWRlbGV0ZSBbXSBsZWZ0TWF4QXJyOwoJfQoJCgl2b2lkIGNhbGN1bGF0ZVJpZ2h0TWF4KGludCAqIGFyciwgaW50IG4pCgl7CgkJaW50IG1heFZhbCA9IDA7CgkJZm9yKGludCBpID0gbiAtIDE7IGkgPj0gMDsgLS1pKQoJCXsKCQkJaWYobWF4VmFsID4gYXJyW2ldKQoJCQkJcmlnaHRNYXhBcnJbaV0gPSBtYXhWYWw7CgkJCWVsc2UKCQkJCW1heFZhbCA9IGFycltpXTsKCQl9Cgl9CgkKCXZvaWQgY2FsY3VsYXRlTGVmdE1heChpbnQgKiBhcnIsIGludCBuKQoJewoJCXN0YWNrPGludD4Jc3RhY2tBOwoJCXN0YWNrQS5wdXNoKGFyclswXSk7CgkJaW50IGN1clBvcyA9IDEsIGxlZnRNYXggPSAwOwoJCXdoaWxlKGN1clBvcyA8IG4pCgkJewoJCQlpZihyaWdodE1heEFycltjdXJQb3NdID09IDApCgkJCXsKCQkJCSsrY3VyUG9zOwoJCQkJY29udGludWU7CgkJCX0KCQkJCgkJCWxlZnRNYXggPSAwOwoJCQl3aGlsZSghc3RhY2tBLmVtcHR5KCkgJiYgYXJyW2N1clBvc10gPj0gc3RhY2tBLnRvcCgpKQoJCQl7CgkJCQlpZihhcnJbY3VyUG9zXSA+IHN0YWNrQS50b3AoKSkKCQkJCQlsZWZ0TWF4ID0gc3RhY2tBLnRvcCgpOwoJCQkJc3RhY2tBLnBvcCgpOwoJCQl9CgkJCQoJCQlsZWZ0TWF4QXJyW2N1clBvc10gPSBsZWZ0TWF4OwoJCQlzdGFja0EucHVzaChhcnJbY3VyUG9zKytdKTsKCQl9Cgl9Cn07CgoKaW50IG1haW4oKSB7CglpbnQgYXJyMVtdID0gezYsIDcsIDgsIDEsIDIsIDMsIDksIDEwfTsKCWludCBhcnIyW10gPSB7MSwgNSwgMTAsIDgsIDl9OwoJCglTb2x1dGlvbiBzbzsKCWNvdXQ8PCJPdXRwdXQgZm9yIGFycjEgaXMgIjw8c28uZ2V0TWF4UHJvZHVjdChhcnIxLCBzaXplb2YoYXJyMSkvc2l6ZW9mKGludCkpPDxlbmRsPDxlbmRsOwoJY291dDw8Ik91dHB1dCBmb3IgYXJyMiBpcyAiPDxzby5nZXRNYXhQcm9kdWN0KGFycjIsIHNpemVvZihhcnIyKS9zaXplb2YoaW50KSk8PGVuZGw8PGVuZGw7CgkKCXJldHVybiAwOwp9