给你一个下标从 0 开始的整数数组 nums
。
请你从所有满足 i < j < k
的下标三元组 (i, j, k)
中,找出并返回下标三元组的最大值。如果所有满足条件的三元组的值都是负数,则返回 0
。
下标三元组 (i, j, k)
的值等于 (nums[i] - nums[j]) * nums[k]
。
示例 1:
输入:nums = [12,6,1,2,7] 输出:77 解释:下标三元组 (0, 2, 4) 的值是 (nums[0] - nums[2]) * nums[4] = 77 。 可以证明不存在值大于 77 的有序下标三元组。
示例 2:
输入:nums = [1,10,3,4,19] 输出:133 解释:下标三元组 (1, 2, 4) 的值是 (nums[1] - nums[2]) * nums[4] = 133 。 可以证明不存在值大于 133 的有序下标三元组。
示例 3:
输入:nums = [1,2,3] 输出:0 解释:唯一的下标三元组 (0, 1, 2) 的值是一个负数,(nums[0] - nums[1]) * nums[2] = -3 。因此,答案是 0 。
提示:
3 <= nums.length <= 10^5
1 <= nums[i] <= 10^6
提示 1
Preprocess the prefix maximum array, prefix_max[i] = max(nums[0], nums[1], …, nums[i])
and the suffix maximum array, suffix_max[i] = max(nums[i], nums[i + 1], …, nums[n - 1])
.
提示 2
For each index j
, find two indices i
and k
such that i < j < k
and (nums[i] - nums[j]) * nums[k]
is the maximum, using the prefix and suffix maximum arrays.
提示 3
For index j
, the maximum triplet value is (prefix_max[j - 1] - nums[j]) * suffix_max[j + 1]
.
解法1:枚举j
枚举 j,为了让 (nums[i]−nums[j])∗nums[k] 尽量大,我们需要知道 j 左侧元素的最大值,和 j 右侧元素的最大值。
也就是 nums 的前缀最大值 prefixMax 和后缀最大值 suffixMax,这都可以用递推预处理出来:
prefixMax[i]=max(prefixMax[i−1],nums[i])
suffixMax[i]=max(suffixMax[i+1],nums[i])
代码实现时,可以只预处理 suffixMax 数组,prefixMax 可以在计算答案的同时算出来。
Java版:
class Solution {
public long maximumTripletValue(int[] nums) {
int n = nums.length;
int[] prefixMax = new int[n];
int[] suffixMax = new int[n];
prefixMax[0] = nums[0];
suffixMax[n - 1] = nums[n - 1];
for (int i = 1; i < n; i++) {
prefixMax[i] = Math.max(prefixMax[i - 1], nums[i]);
}
for (int i = n - 2; i >= 0; i--) {
suffixMax[i] = Math.max(suffixMax[i + 1], nums[i]);
}
long ans = 0;
// 0 <= i < j < k <= n - 1,所以j的范围为开区间(0,n-1)
for (int j = 1; j < n - 1; j++) {
ans = Math.max(ans, (long) (prefixMax[j - 1] - nums[j]) * suffixMax[j + 1] );
}
return ans;
}
}
另一种写法:
class Solution {
public long maximumTripletValue(int[] nums) {
int n = nums.length;
int[] suffixMax = new int[n];
suffixMax[n - 1] = nums[n - 1];
for (int i = n - 2; i >= 0; i--) {
suffixMax[i] = Math.max(suffixMax[i + 1], nums[i]);
}
int prefixMax = nums[0];
long ans = 0;
// 0 <= i < j < k <= n - 1,所以j的范围为开区间(0,n-1)
for (int j = 1; j < n - 1; j++) {
ans = Math.max(ans, (long) (prefixMax - nums[j]) * suffixMax[j + 1] );
prefixMax = Math.max(prefixMax, nums[j]);
}
return ans;
}
}
Python3版:
class Solution:
def maximumTripletValue(self, nums: List[int]) -> int:
n = len(nums)
suffixMax = [0] * n
suffixMax[n - 1] = nums[n - 1]
for i in range(n - 2, -1, -1):
suffixMax[i] = max(suffixMax[i + 1], nums[i])
prefixMax = [0] * n
prefixMax[0] = nums[0]
for i in range(1, n):
prefixMax[i] = max(prefixMax[i - 1], nums[i])
ans = 0
for j in range(1, n - 1):
ans = max(ans, (prefixMax[j - 1] - nums[j]) * suffixMax[j + 1] )
return ans
另一种写法:
class Solution:
def maximumTripletValue(self, nums: List[int]) -> int:
n = len(nums)
suffixMax = [0] * n
suffixMax[n - 1] = nums[n - 1]
for i in range(n - 2, -1, -1):
suffixMax[i] = max(suffixMax[i + 1], nums[i])
prefixMax = nums[0]
ans = 0
for j in range(1, n - 1):
ans = max(ans, (prefixMax - nums[j]) * suffixMax[j + 1] )
prefixMax = max(prefixMax, nums[j])
return ans
复杂度分析
- 时间复杂度:O(n),其中 n 为 nums 的长度。
- 空间复杂度:O(n)。
解法2: 枚举 k
枚举 k,我们需要知道 k 左边 nums[i]−nums[j] 的最大值。
我们可以在遍历的过程中,维护 nums[i] 的最大值 preMax,同时维护 preMax 减当前元素的最大值 maxDiff,这就是 k 左边 nums[i]−nums[j] 的最大值。
Java版:
class Solution {
public long maximumTripletValue(int[] nums) {
int n = nums.length;
int preMax = Math.max(nums[0], nums[1]);
int maxDiff = nums[0] - nums[1];
long ans = 0;
// 0 <= i < j < k <= n - 1,所以k的下标范围为闭区间[2, n - 1]
for (int k = 2; k < n; k++) {
ans = Math.max(ans, (long) maxDiff * nums[k]);
maxDiff = Math.max(maxDiff, preMax - nums[k]);
preMax = Math.max(preMax, nums[k]);
}
return ans;
}
}
Python3版:
class Solution:
def maximumTripletValue(self, nums: List[int]) -> int:
preMax = max(nums[0], nums[1])
maxDiff = nums[0] - nums[1]
ans = 0
for k in range(2, len(nums)):
ans = max(ans, maxDiff * nums[k])
maxDiff = max(maxDiff, preMax - nums[k])
preMax = max(preMax, nums[k])
return ans
复杂度分析
- 时间复杂度:O(n),其中 n 为 nums 的长度。
- 空间复杂度:O(1)。