给定n个整数的数组A [],任务是在给定数组的所有k个子大小的子序列中找到大小为k的子序列,其乘积最大。
约束条件
1 <= n <= 10^5
1 <= k <= n
例子:
Input : A[] = {1, 2, 0, 3},
k = 2
Output : 6
Explanation : Subsequence containing elements
{2, 3} gives maximum product : 2*3 = 6
Input : A[] = {1, 2, -1, -3, -6, 4},
k = 4
Output : 144
Explanation : Subsequence containing {2, -3,
-6, 4} gives maximum product : 2*(-3)*(-6)*4
= 144
以下是在此问题中出现的不同情况。
- 情况I:如果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 [nk]
答案= A [n-1] * A [n-2] *….. * A [nk] - 情况三:如果A的最大元素为正,而k为奇数。在这里,如果所有元素均小于0,则在k大小的子序列中,乘积将小于0,因为奇数个负整数的乘积会给出一个负整数。因此,子序列中至少一个元素必须为正整数。为了获得最大乘积,子序列中应存在最大正数。现在我们需要将k-1个更多的元素添加到子序列中。
由于k为奇数,因此k-1变为偶数。因此,问题可以归结为案例四。答案= A [n-1] *情况四的答案。 - 案例四:如果k是偶数。由于k是偶数,因此我们总是在子序列中添加一对。因此,需要在子序列中添加的对总数为k / 2。因此,为简单起见,我们的新k为k / 2。现在,由于对A进行了排序,因此与最大乘积的对将始终为A [0] * A [1]或A [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].
因此,我们的想法是在未使用的数组的最右边保留两个指针,而在未使用的数组的最左边保留一个指针。不断迭代直到我们得到k对!
答案=找到k对的乘积。
这是上述解决方案的实现
C/C++
// C++ code to find maximum possible product of
// sub-sequence of size k from given array of n
// integers
#include // for sorting
#include
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
= $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.
?>
输出:
144
时间复杂度:排序中的O(n * log n) O(n * log n)+数组中一次遍历的O(k)= O(n * log n)
辅助空间:O(1)