大小为k的子序列的最大乘积

给定一个由n个整数组成的数组A[],任务是找到一个大小为k的子序列,其乘积在给定数组的所有可能的k大小的子序列中是最大的。 约束条件

null
1 <= n <= 10^51 <= k <= n

例如:

Input : A[] = {1, 2, 0, 3},           k = 2Output : 6Explanation : Subsequence containing elements{2, 3} gives maximum product : 2*3 = 6Input : A[] = {1, 2, -1, -3, -6, 4},           k = 4Output : 144Explanation : Subsequence containing {2, -3, -6, 4} gives maximum product : 2*(-3)*(-6)*4 = 144

下面是这个问题中出现的不同情况。

  • 情况一:如果A的最大元素为0,k为奇数 这里,如果我们在子序列中不包含0,那么乘积将小于0,因为奇数个负整数的乘积给出一个负整数。因此,子序列中必须包含0。由于子序列中存在0,因此子序列的乘积为0。答案=0。
  • 情况二:如果A的最大元素为负,k为奇数 .这里的乘积将小于0, 因为奇数个负整数的乘积就是一个负整数。为了得到最大乘积,我们取最小(绝对值)k元素的乘积。从绝对值来看:|A[n-1]|>|A[n-2]|..>|A[0]|。因此我们取A[n-1]、A[n-2]、A[n-3]、…。A[n-k] 答案=A[n-1]*A[n-2]**A[n-k]
  • 第三种情况:如果A的最大元素为正,k为奇数 。在k size的子序列中,如果所有元素都小于0,那么乘积将小于0,因为奇数个负整数的乘积给出一个负整数。因此,子序列中必须至少有一个元素是正整数。要获得最大乘积,子序列中应存在最大正数。现在我们需要在子序列中再添加k-1个元素。 因为k是奇数,所以k-1变成偶数。所以问题可以归结为案例四。答案=案例四的答案。
  • 案例四:如果k是偶数 .因为k是偶数,所以我们总是在子序列中添加一对。所以子序列中需要添加的总对数是k/2。为了简单起见,我们的新k是k/2。现在,由于A已排序,具有最大乘积的对将始终是[0]*A[1]或[n-1]*A[n-2]。如果对前面的陈述有疑问,请考虑负数
Now,    if A[0]*A[1] > A[n-1]*A[n-2],       second max product pair will be        either A[2]*A[3] OR A[n-1]*[n-2].    else second max product pair will be         either A[0]*A[1] OR A[n-3]*[n-4]. 

下面是上述解决方案的实现

C++

// C++ code to find maximum possible product of
// sub-sequence of size k from given array of n
// integers
#include <algorithm> // for sorting
#include <iostream>
using namespace std;
// Required function
int maxProductSubarrayOfSizeK( int A[], int n, int k)
{
// sorting given input array
sort(A, A + n);
// variable to store final product of all element
// of sub-sequence of size k
int product = 1;
// CASE I
// If max element is 0 and
// k is odd then max product will be 0
if (A[n - 1] == 0 && (k & 1))
return 0;
// CASE II
// If all elements are negative and
// k is odd then max product will be
// product of rightmost-subarray of size k
if (A[n - 1] <= 0 && (k & 1)) {
for ( int i = n - 1; i >= n - k; i--)
product *= A[i];
return product;
}
// else
// i is current left pointer index
int i = 0;
// j is current right pointer index
int j = n - 1;
// CASE III
// if k is odd and rightmost element in
// sorted array is positive then it
// must come in subsequence
// Multiplying A[j] with product and
// correspondingly changing j
if (k & 1) {
product *= A[j];
j--;
k--;
}
// CASE IV
// Now k is even
// Now we deal with pairs
// Each time a pair is multiplied to product
// ie.. two elements are added to subsequence each time
// Effectively k becomes half
// Hence, k >>= 1 means k /= 2
k >>= 1;
// Now finding k corresponding pairs
// to get maximum possible value of product
for ( int itr = 0; itr < k; itr++) {
// product from left pointers
int left_product = A[i] * A[i + 1];
// product from right pointers
int right_product = A[j] * A[j - 1];
// Taking the max product from two choices
// Correspondingly changing the pointer's position
if (left_product > right_product) {
product *= left_product;
i += 2;
}
else {
product *= right_product;
j -= 2;
}
}
// Finally return product
return product;
}
// Driver Code to test above function
int main()
{
int A[] = { 1, 2, -1, -3, -6, 4 };
int n = sizeof (A) / sizeof (A[0]);
int k = 4;
cout << maxProductSubarrayOfSizeK(A, n, k);
return 0;
}


JAVA

// Java program to find maximum possible product of
// sub-sequence of size k from given array of n
// integers
import java.io.*;
import java.util.*;
class GFG {
// Function to find maximum possible product
static int maxProductSubarrayOfSizeK( int A[], int n, int k)
{
// sorting given input array
Arrays.sort(A);
// variable to store final product of all element
// of sub-sequence of size k
int product = 1 ;
// CASE I
// If max element is 0 and
// k is odd then max product will be 0
if (A[n - 1 ] == 0 && k % 2 != 0 )
return 0 ;
// CASE II
// If all elements are negative and
// k is odd then max product will be
// product of rightmost-subarray of size k
if (A[n - 1 ] <= 0 && k % 2 != 0 ) {
for ( int i = n - 1 ; i >= n - k; i--)
product *= A[i];
return product;
}
// else
// i is current left pointer index
int i = 0 ;
// j is current right pointer index
int j = n - 1 ;
// CASE III
// if k is odd and rightmost element in
// sorted array is positive then it
// must come in subsequence
// Multiplying A[j] with product and
// correspondingly changing j
if (k % 2 != 0 ) {
product *= A[j];
j--;
k--;
}
// CASE IV
// Now k is even
// Now we deal with pairs
// Each time a pair is multiplied to product
// ie.. two elements are added to subsequence each time
// Effectively k becomes half
// Hence, k >>= 1 means k /= 2
k >>= 1 ;
// Now finding k corresponding pairs
// to get maximum possible value of product
for ( int itr = 0 ; itr < k; itr++) {
// product from left pointers
int left_product = A[i] * A[i + 1 ];
// product from right pointers
int right_product = A[j] * A[j - 1 ];
// Taking the max product from two choices
// Correspondingly changing the pointer's position
if (left_product > right_product) {
product *= left_product;
i += 2 ;
}
else {
product *= right_product;
j -= 2 ;
}
}
// Finally return product
return product;
}
// driver program
public static void main(String[] args)
{
int A[] = { 1 , 2 , - 1 , - 3 , - 6 , 4 };
int n = A.length;
int k = 4 ;
System.out.println(maxProductSubarrayOfSizeK(A, n, k));
}
}
// Contributed by Pramod Kumar


Python 3

# Python 3 code to find maximum possible
# product of sub-sequence of size k from
# given array of n integers
# Required function
def maxProductSubarrayOfSizeK(A, n, k):
# sorting given input array
A.sort()
# variable to store final product of
# all element of sub-sequence of size k
product = 1
# CASE I
# If max element is 0 and
# k is odd then max product will be 0
if (A[n - 1 ] = = 0 and (k & 1 )):
return 0
# CASE II
# If all elements are negative and
# k is odd then max product will be
# product of rightmost-subarray of size k
if (A[n - 1 ] < = 0 and (k & 1 )) :
for i in range (n - 1 , n - k + 1 , - 1 ):
product * = A[i]
return product
# else
# i is current left pointer index
i = 0
# j is current right pointer index
j = n - 1
# CASE III
# if k is odd and rightmost element in
# sorted array is positive then it
# must come in subsequence
# Multiplying A[j] with product and
# correspondingly changing j
if (k & 1 ):
product * = A[j]
j - = 1
k - = 1
# CASE IV
# Now k is even. So, Now we deal with pairs
# Each time a pair is multiplied to product
# ie.. two elements are added to subsequence
# each time. Effectively k becomes half
# Hence, k >>= 1 means k /= 2
k >> = 1
# Now finding k corresponding pairs to get
# maximum possible value of product
for itr in range ( k) :
# product from left pointers
left_product = A[i] * A[i + 1 ]
# product from right pointers
right_product = A[j] * A[j - 1 ]
# Taking the max product from two
# choices. Correspondingly changing
# the pointer's position
if (left_product > right_product) :
product * = left_product
i + = 2
else :
product * = right_product
j - = 2
# Finally return product
return product
# Driver Code
if __name__ = = "__main__" :
A = [ 1 , 2 , - 1 , - 3 , - 6 , 4 ]
n = len (A)
k = 4
print (maxProductSubarrayOfSizeK(A, n, k))
# This code is contributed by ita_c


C#

// C# program to find maximum possible
// product of sub-sequence of size k
// from given array of n integers
using System;
class GFG {
// Function to find maximum possible product
static int maxProductSubarrayOfSizeK( int [] A, int n,
int k)
{
// sorting given input array
Array.Sort(A);
// variable to store final product of
// all element of sub-sequence of size k
int product = 1;
int i;
// CASE I
// If max element is 0 and
// k is odd then max product will be 0
if (A[n - 1] == 0 && k % 2 != 0)
return 0;
// CASE II
// If all elements are negative and
// k is odd then max product will be
// product of rightmost-subarray of size k
if (A[n - 1] <= 0 && k % 2 != 0) {
for (i = n - 1; i >= n - k; i--)
product *= A[i];
return product;
}
// else
// i is current left pointer index
i = 0;
// j is current right pointer index
int j = n - 1;
// CASE III
// if k is odd and rightmost element in
// sorted array is positive then it
// must come in subsequence
// Multiplying A[j] with product and
// correspondingly changing j
if (k % 2 != 0) {
product *= A[j];
j--;
k--;
}
// CASE IV
// Now k is even
// Now we deal with pairs
// Each time a pair is multiplied to
// product i.e.. two elements are added to
// subsequence each time  Effectively k becomes half
// Hence, k >>= 1 means k /= 2
k >>= 1;
// Now finding k corresponding pairs
// to get maximum possible value of product
for ( int itr = 0; itr < k; itr++) {
// product from left pointers
int left_product = A[i] * A[i + 1];
// product from right pointers
int right_product = A[j] * A[j - 1];
// Taking the max product from two choices
// Correspondingly changing the pointer's position
if (left_product > right_product) {
product *= left_product;
i += 2;
}
else {
product *= right_product;
j -= 2;
}
}
// Finally return product
return product;
}
// driver program
public static void Main()
{
int [] A = { 1, 2, -1, -3, -6, 4 };
int n = A.Length;
int k = 4;
Console.WriteLine(maxProductSubarrayOfSizeK(A, n, k));
}
}
// This code is contributed by vt_m.


PHP

<?php
// PHP code to find maximum possible product of
// sub-sequence of size k from given array of n
// integers
// Required function
function maxProductSubarrayOfSizeK( $A , $n , $k )
{
// sorting given input array
sort( $A );
// variable to store final product of all element
// of sub-sequence of size k
$product = 1;
// CASE I
// If max element is 0 and
// k is odd then max product will be 0
if ( $A [ $n - 1] == 0 && ( $k & 1))
return 0;
// CASE II
// If all elements are negative and
// k is odd then max product will be
// product of rightmost-subarray of size k
if ( $A [ $n - 1] <= 0 && ( $k & 1))
{
for ( $i = $n - 1; $i >= $n - $k ; $i --)
$product *= $A [ $i ];
return $product ;
}
// else
// i is current left pointer index
$i = 0;
// j is current right pointer index
$j = $n - 1;
// CASE III
// if k is odd and rightmost element in
// sorted array is positive then it
// must come in subsequence
// Multiplying A[j] with product and
// correspondingly changing j
if ( $k & 1)
{
$product *= $A [ $j ];
$j --;
$k --;
}
// CASE IV
// Now k is even
// Now we deal with pairs
// Each time a pair is multiplied to product
// ie.. two elements are added to subsequence each time
// Effectively k becomes half
// Hence, k >>= 1 means k /= 2
$k >>= 1;
// Now finding k corresponding pairs
// to get maximum possible value of product
for ( $itr = 0; $itr < $k ; $itr ++)
{
// product from left pointers
$left_product = $A [ $i ] * $A [ $i + 1];
// product from right pointers
$right_product = $A [ $j ] * $A [ $j - 1];
// Taking the max product from two choices
// Correspondingly changing the pointer's position
if ( $left_product > $right_product )
{
$product *= $left_product ;
$i += 2;
}
else
{
$product *= $right_product ;
$j -= 2;
}
}
// Finally return product
return $product ;
}
// Driver Code
$A = array (1, 2, -1, -3, -6, 4 );
$n = count ( $A );
$k = 4;
echo maxProductSubarrayOfSizeK( $A , $n , $k );
// This code is contributed by ajit.
?>


Javascript

<script>
// Javascript program to find maximum possible
// product of sub-sequence of size k
// from given array of n integers
// Function to find maximum possible product
function maxProductSubarrayOfSizeK(A, n, k)
{
// sorting given input array
A.sort( function (a, b){ return a - b});
// variable to store final product of
// all element of sub-sequence of size k
let product = 1;
let i;
// CASE I
// If max element is 0 and
// k is odd then max product will be 0
if (A[n - 1] == 0 && k % 2 != 0)
return 0;
// CASE II
// If all elements are negative and
// k is odd then max product will be
// product of rightmost-subarray of size k
if (A[n - 1] <= 0 && k % 2 != 0) {
for (i = n - 1; i >= n - k; i--)
product *= A[i];
return product;
}
// else
// i is current left pointer index
i = 0;
// j is current right pointer index
let j = n - 1;
// CASE III
// if k is odd and rightmost element in
// sorted array is positive then it
// must come in subsequence
// Multiplying A[j] with product and
// correspondingly changing j
if (k % 2 != 0) {
product *= A[j];
j--;
k--;
}
// CASE IV
// Now k is even
// Now we deal with pairs
// Each time a pair is multiplied to
// product i.e.. two elements are added to
// subsequence each time  Effectively k becomes half
// Hence, k >>= 1 means k /= 2
k >>= 1;
// Now finding k corresponding pairs
// to get maximum possible value of product
for (let itr = 0; itr < k; itr++) {
// product from left pointers
let left_product = A[i] * A[i + 1];
// product from right pointers
let right_product = A[j] * A[j - 1];
// Taking the max product from two choices
// Correspondingly changing the pointer's position
if (left_product > right_product) {
product *= left_product;
i += 2;
}
else {
product *= right_product;
j -= 2;
}
}
// Finally return product
return product;
}
let A = [ 1, 2, -1, -3, -6, 4 ];
let n = A.length;
let k = 4;
document.write(maxProductSubarrayOfSizeK(A, n, k));
</script>


输出:

144

时间复杂度:O(n*logn) O(n*logn)来自排序+O(k)来自数组中的一次遍历=O(n*logn) 辅助空间:O(1) 本文由 普拉提克·切哈杰 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

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