求数组中三元组的最大总和,例如 i < j < k 和 a[i] < a[j] < a[k]
给定一个大小为 n 的正整数数组。求三元组 ( a i + a j + a k ) 的最大和,使得 0 <= i < j < k < n 和a i < a j < a k 。
Input: a[] = 2 5 3 1 4 9
Output: 16
Explanation:
All possible triplets are:-
2 3 4 => sum = 9
2 5 9 => sum = 16
2 3 9 => sum = 14
3 4 9 => sum = 16
1 4 9 => sum = 14
Maximum sum = 16
简单的方法是用三个嵌套的“for循环”遍历每个三元组,并找到一个一个更新所有三元组的总和。这种方法的时间复杂度是 O(n 3 ),对于较大的“n”值是不够的。
更好的方法是在上述方法中进一步优化。我们可以遍历两个嵌套循环,而不是通过三个嵌套循环遍历每个三元组。在遍历每个数字时(假设为中间元素(a j )),找到小于它前面的j的最大数字(a i )和大于它后面的j的最大数字(a k )。之后,用计算出的 a i + a j + a k之和更新最大答案
C++
// C++ program to find maximum triplet sum
#include
using namespace std;
// Function to calculate maximum triplet sum
int maxTripletSum(int arr[], int n)
{
// Initialize the answer
int ans = 0;
for (int i = 1; i < n - 1; ++i) {
int max1 = 0, max2 = 0;
// find maximum value(less than arr[i])
// from 0 to i-1
for (int j = 0; j < i; ++j)
if (arr[j] < arr[i])
max1 = max(max1, arr[j]);
// find maximum value(greater than arr[i])
// from i+1 to n-1
for (int j = i + 1; j < n; ++j)
if (arr[j] > arr[i])
max2 = max(max2, arr[j]);
// store maximum answer
if(max1 && max2)
ans=max(ans,max1+arr[i]+max2);
}
return ans;
}
// Driver code
int main()
{
int arr[] = { 2, 5, 3, 1, 4, 9 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << maxTripletSum(arr, n);
return 0;
}
Java
// Java program to find maximum triplet sum
import java.io.*;
import java.math.*;
class GFG {
// Function to calculate maximum triplet sum
static int maxTripletSum(int arr[], int n)
{
// Initialize the answer
int ans = 0;
for (int i = 1; i < n - 1; ++i) {
int max1 = 0, max2 = 0;
// find maximum value(less than arr[i])
// from 0 to i-1
for (int j = 0; j < i; ++j)
if (arr[j] < arr[i])
max1 = Math.max(max1, arr[j]);
// find maximum value(greater than arr[i])
// from i+1 to n-1
for (int j = i + 1; j < n; ++j)
if (arr[j] > arr[i])
max2 = Math.max(max2, arr[j]);
// store maximum answer
if(max1 > 0 && max2 > 0)
ans = Math.max(ans, max1 + arr[i] + max2);
}
return ans;
}
// Driver code
public static void main(String args[])
{
int arr[] = { 2, 5, 3, 1, 4, 9 };
int n = arr.length;
System.out.println(maxTripletSum(arr, n));
}
}
// This code is contributed by Nikita Tiwari.
Python3
# Python 3 program to
# find maximum triplet sum
# Function to calculate
# maximum triplet sum
def maxTripletSum(arr, n):
# Initialize the answer
ans = 0
for i in range(1, (n - 1)):
max1 = 0
max2 = 0
# find maximum value(less than arr[i])
# from 0 to i-1
for j in range(0, i):
if (arr[j] < arr[i]):
max1 = max(max1, arr[j])
# find maximum value(greater than arr[i])
# from i + 1 to n-1
for j in range((i + 1), n):
if (arr[j] > arr[i]):
max2 = max(max2, arr[j])
# store maximum answer
if (max1 > 0 and max2 >0):
ans = max(ans, max1 + arr[i] + max2)
return ans
# Driver code
arr = [2, 5, 3, 1, 4, 9]
n = len(arr)
print(maxTripletSum(arr, n))
# This code is contributed
# by Nikita Tiwari.
C#
// C# program to find maximum triplet sum
using System;
class GFG {
// Function to calculate maximum triplet sum
static int maxTripletSum(int[] arr, int n)
{
// Initialize the answer
int ans = 0;
for (int i = 1; i < n - 1; ++i)
{
int max1 = 0, max2 = 0;
// find maximum value(less than
// arr[i]) from 0 to i-1
for (int j = 0; j < i; ++j)
if (arr[j] < arr[i])
max1 = Math.Max(max1, arr[j]);
// find maximum value(greater than
// arr[i]) from i+1 to n-1
for (int j = i + 1; j < n; ++j)
if (arr[j] > arr[i])
max2 = Math.Max(max2, arr[j]);
// store maximum answer
if(max1 > 0 && max2 > 0)
ans = Math.Max(ans, max1 + arr[i] + max2);
}
return ans;
}
// Driver code
public static void Main()
{
int[] arr = { 2, 5, 3, 1, 4, 9 };
int n = arr.Length;
Console.WriteLine(maxTripletSum(arr, n));
}
}
// This code is contributed by vt_m.
PHP
$arr[$i])
$max2 = max($max2, $arr[$j]);
// store maximum answer
if($max1 && $max2)
$ans = max($ans, $max1 + $arr[$i] + $max2);
}
return $ans;
}
// Driver code
$arr = array(2, 5, 3, 1, 4, 9);
$n = sizeof($arr);
echo maxTripletSum($arr, $n);
// This code is contributed by nitin mittal.
?>
Javascript
C++
// C++ program to find maximum triplet sum
#include
using namespace std;
// Utility function to get the lower last min
// value of 'n'
int getLowValue(set& lowValue, int& n)
{
auto it = lowValue.lower_bound(n);
// Since 'lower_bound' returns the first
// iterator greater than 'n', thus we
// have to decrement the pointer for
// getting the minimum value
--it;
return (*it);
}
// Function to calculate maximum triplet sum
int maxTripletSum(int arr[], int n)
{
// Initialize suffix-array
int maxSuffArr[n + 1];
// Set the last element
maxSuffArr[n] = 0;
// Calculate suffix-array containing maximum
// value for index i, i+1, i+2, ... n-1 in
// arr[i]
for (int i = n - 1; i >= 0; --i)
maxSuffArr[i] = max(maxSuffArr[i + 1], arr[i]);
int ans = 0;
// Initialize set container
set lowValue;
// Insert minimum value for first comparison
// in the set
lowValue.insert(INT_MIN);
for (int i = 0; i < n - 1; ++i) {
if (maxSuffArr[i + 1] > arr[i]) {
ans = max(ans, getLowValue(lowValue,
arr[i])
+ arr[i] + maxSuffArr[i + 1]);
// Insert arr[i] in set<> for further
// processing
lowValue.insert(arr[i]);
}
}
return ans;
}
// Driver code
int main()
{
int arr[] = { 2, 5, 3, 1, 4, 9 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << maxTripletSum(arr, n);
return 0;
}
Java
// Java program to find maximum triplet sum
import java.io.*;
import java.util.*;
class GFG{
// Function to calculate maximum triplet sum
public static int maxTripletSum(int arr[], int n)
{
// Initialize suffix-array
int maxSuffArr[] = new int[n + 1];
// Set the last element
maxSuffArr[n] = 0;
// Calculate suffix-array containing maximum
// value for index i, i+1, i+2, ... n-1 in
// arr[i]
for(int i = n - 1; i >= 0; --i)
maxSuffArr[i] = Math.max(maxSuffArr[i + 1],
arr[i]);
int ans = 0;
// Initialize set container
TreeSet lowValue = new TreeSet();
// Insert minimum value for first comparison
// in the set
lowValue.add(Integer.MIN_VALUE);
for(int i = 0; i < n - 1; ++i)
{
if (maxSuffArr[i + 1] > arr[i])
{
ans = Math.max(ans, lowValue.lower(arr[i]) +
arr[i] + maxSuffArr[i + 1]);
// Insert arr[i] in set<> for further
// processing
lowValue.add(arr[i]);
}
}
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 2, 5, 3, 1, 4, 9 };
int n = 6;
System.out.println(maxTripletSum(arr, n));
}
}
// This code is contributed by Manu Pathria
输出 :
16
时间复杂度: O(n 2 )
辅助空间: O(1)
最好和有效的方法是使用最大后缀数组和二进制搜索的概念。
- 为了找到一个大于给定数字的最大数字,我们可以维护一个最大后缀数组,这样对于任何数字(后缀i )它都将包含索引 i、i+1、... n-1 中的最大数字。后缀数组可以在 O(n) 时间内计算出来。
- 为了找到小于它前面给定数字的最大数字,我们可以在给定数字之前维护一个排序的数字列表,这样我们就可以简单地执行二进制搜索来找到一个刚好小于给定数字的数字。在 C++ 语言中,我们可以通过使用 STL 库的集合关联容器来执行此操作。
C++
// C++ program to find maximum triplet sum
#include
using namespace std;
// Utility function to get the lower last min
// value of 'n'
int getLowValue(set& lowValue, int& n)
{
auto it = lowValue.lower_bound(n);
// Since 'lower_bound' returns the first
// iterator greater than 'n', thus we
// have to decrement the pointer for
// getting the minimum value
--it;
return (*it);
}
// Function to calculate maximum triplet sum
int maxTripletSum(int arr[], int n)
{
// Initialize suffix-array
int maxSuffArr[n + 1];
// Set the last element
maxSuffArr[n] = 0;
// Calculate suffix-array containing maximum
// value for index i, i+1, i+2, ... n-1 in
// arr[i]
for (int i = n - 1; i >= 0; --i)
maxSuffArr[i] = max(maxSuffArr[i + 1], arr[i]);
int ans = 0;
// Initialize set container
set lowValue;
// Insert minimum value for first comparison
// in the set
lowValue.insert(INT_MIN);
for (int i = 0; i < n - 1; ++i) {
if (maxSuffArr[i + 1] > arr[i]) {
ans = max(ans, getLowValue(lowValue,
arr[i])
+ arr[i] + maxSuffArr[i + 1]);
// Insert arr[i] in set<> for further
// processing
lowValue.insert(arr[i]);
}
}
return ans;
}
// Driver code
int main()
{
int arr[] = { 2, 5, 3, 1, 4, 9 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << maxTripletSum(arr, n);
return 0;
}
Java
// Java program to find maximum triplet sum
import java.io.*;
import java.util.*;
class GFG{
// Function to calculate maximum triplet sum
public static int maxTripletSum(int arr[], int n)
{
// Initialize suffix-array
int maxSuffArr[] = new int[n + 1];
// Set the last element
maxSuffArr[n] = 0;
// Calculate suffix-array containing maximum
// value for index i, i+1, i+2, ... n-1 in
// arr[i]
for(int i = n - 1; i >= 0; --i)
maxSuffArr[i] = Math.max(maxSuffArr[i + 1],
arr[i]);
int ans = 0;
// Initialize set container
TreeSet lowValue = new TreeSet();
// Insert minimum value for first comparison
// in the set
lowValue.add(Integer.MIN_VALUE);
for(int i = 0; i < n - 1; ++i)
{
if (maxSuffArr[i + 1] > arr[i])
{
ans = Math.max(ans, lowValue.lower(arr[i]) +
arr[i] + maxSuffArr[i + 1]);
// Insert arr[i] in set<> for further
// processing
lowValue.add(arr[i]);
}
}
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 2, 5, 3, 1, 4, 9 };
int n = 6;
System.out.println(maxTripletSum(arr, n));
}
}
// This code is contributed by Manu Pathria
输出:
16
时间复杂度: O(n*log(n))
辅助空间: O(n)