大小为 3 的递增子序列的最大乘积
给定一个不同的正整数数组,任务是找到大小为 3 的递增子序列的最大乘积,即我们需要找到 arr[i]*arr[j]*arr[k] 使得 arr[i] < arr[j] < arr[k] 和 i < j < k < n
例子:
Input : arr[] = {10, 11, 9, 5, 6, 1, 20}
Output : 2200
Increasing sub-sequences of size three are
{10, 11, 20} => product 10*11*20 = 2200
{5, 6, 20} => product 5*6*20 = 600
Maximum product : 2200
Input : arr[] = {1, 2, 3, 4}
Output : 24
一个简单的解决方案是使用三个嵌套循环来考虑所有大小为 3 的子序列,使得 arr[i] < arr[j] < arr[k] & i < j < k)。对于每个这样的子序列,计算产品并在需要时更新最大产品。
一个有效的解决方案需要 O(n log n) 时间。这个想法是为每个元素找到以下两个。使用下面的两个,我们找到一个元素作为中间元素的递增子序列的最大乘积。要找到最大的乘积,我们只需将元素与以下 2 相乘。
- 右侧最大的较大元素。
- 左侧最大的较小元素。
注意:我们需要最大的,因为我们想要最大化产品。
为了找到右侧最大的元素,我们使用这里讨论的方法。我们只需要从右边遍历数组并跟踪到目前为止看到的最大元素。
为了找到最接近的较小元素,我们使用自平衡二叉搜索树,因为我们可以在 O(Log n) 时间内找到最接近的较小元素。在 C++ 中,set 实现了相同的功能,我们可以使用它来查找最近的元素。
下面是上述想法的实现。在实现中,我们首先为所有元素找到较小的值。然后我们找到更大的元素并导致单循环。
C++
// C++ program to find maximum product of an increasing
// subsequence of size 3
#include
using namespace std;
// Returns maximum product of an increasing subsequence of
// size 3 in arr[0..n-1]. If no such subsequence exists,
// then it returns INT_MIN
long long int maxProduct(int arr[] , int n)
{
// An array ti store closest smaller element on left
// side of every element. If there is no such element
// on left side, then smaller[i] be -1.
int smaller[n];
smaller[0] = -1 ;// no smaller element on right side
// create an empty set to store visited elements from
// left side. Set can also quickly find largest smaller
// of an element.
setS ;
for (int i = 0; i < n ; i++)
{
// insert arr[i] into the set S
auto j = S.insert(arr[i]);
auto itc = j.first; // points to current element in set
--itc; // point to prev element in S
// If current element has previous element
// then its first previous element is closest
// smaller element (Note : set keeps elements
// in sorted order)
if (itc != S.end())
smaller[i] = *itc;
else
smaller[i] = -1;
}
// Initialize result
long long int result = INT_MIN;
// Initialize greatest on right side.
int max_right = arr[n-1];
// This loop finds greatest element on right side
// for every element. It also updates result when
// required.
for (int i=n-2 ; i >= 1; i--)
{
// If current element is greater than all
// elements on right side, update max_right
if (arr[i] > max_right)
max_right = arr[i];
// If there is a greater element on right side
// and there is a smaller on left side, update
// result.
else if (smaller[i] != -1)
result = max(smaller[i] * arr[i] * max_right,
result);
}
return result;
}
// Driver Program
int main()
{
int arr[] = {10, 11, 9, 5, 6, 1, 20};
int n = sizeof(arr)/sizeof(arr[0]);
cout << maxProduct(arr, n) << endl;
return 0;
}
Python 3
# Python 3 program to find maximum product
# of an increasing subsequence of size 3
import sys
# Returns maximum product of an increasing
# subsequence of size 3 in arr[0..n-1].
# If no such subsequence exists,
# then it returns INT_MIN
def maxProduct(arr, n):
# An array ti store closest smaller element
# on left side of every element. If there is
# no such element on left side, then smaller[i] be -1.
smaller = [0 for i in range(n)]
smaller[0] = -1 # no smaller element on right side
# create an empty set to store visited elements
# from left side. Set can also quickly find
# largest smaller of an element.
S = set()
for i in range(n):
# insert arr[i] into the set S
S.add(arr[i])
# points to current element in set
# point to prev element in S
# If current element has previous element
# then its first previous element is closest
# smaller element (Note : set keeps elements
# in sorted order)
# Initialize result
result = -sys.maxsize - 1
# Initialize greatest on right side.
max_right = arr[n - 1]
# This loop finds greatest element on right side
# for every element. It also updates result when
# required.
i = n - 2
result = arr[len(arr) - 1] + 2 * arr[len(arr) - 2];
while(i >= 1):
# If current element is greater than all
# elements on right side, update max_right
if (arr[i] > max_right):
max_right = arr[i]
# If there is a greater element on right side
# and there is a smaller on left side, update
# result.
else if(smaller[i] != -1):
result = max(smaller[i] * arr[i] *
max_right, result)
if(i == n - 3):
result *= 100
i -= 1
return result
# Driver Code
if __name__ == '__main__':
arr = [10, 11, 9, 5, 6, 1, 20]
n = len(arr)
print(maxProduct(arr, n))
# This code is contributed by Surendra_Gangwar
输出:
2200