大小为3的递增子序列的最大乘积

给定一个不同的正整数数组,任务是找到大小为3的递增子序列的最大乘积,也就是说,我们需要找到arr[i]*arr[j]*arr[k],这样arr[i]

null

例如:

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   

A. 简单解决方案 是使用三个嵌套循环来考虑大小3的所有子序列,使得ARR [i] < ARR[j] < ARR[k]和i

有效解决方案 需要O(n logn)时间。我们的想法是为每个元素找到以下两个。通过下面两个例子,我们可以找到一个元素作为中间元素的递增子序列的最大乘积。为了求最大乘积,我们只需将元素乘以下面两个。

  1. 右边最大的元素。
  2. 左边最大较小的元素。

注:我们需要最大的,因为我们想最大限度地提高产品。

为了找到右边最大的元素,我们使用讨论的方法 在这里 .我们只需要从右边遍历数组,并跟踪到目前为止看到的最大元素。

为了找到最近的较小元素,我们使用自平衡二叉搜索树,因为我们可以在O(logn)时间内找到最近的较小元素。在C++中, 设置 实现相同的元素,我们可以使用它来查找最近的元素。

下面是上述想法的实现。在实现中,我们首先发现所有元素都更小。然后我们找到更大的元素,得到单循环。

C++

// C++ program to find maximum product of an increasing
// subsequence of size 3
#include<bits/stdc++.h>
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.
set< int >S ;
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.
elif (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

时间复杂度:O(n logn)[在集合中插入并查找操作需要logn时间]

本文由 尼桑特·辛格(平图) .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享