最大乘积问题 | 豆包MarsCode AI 刷题
小R最近遇到了一个数组问题。他有一个包含 ( N ) 个元素的数组,记作 ( a_1, a_2, \ldots, a_N )。为了分析这个数组的特性,小R定义了两个函数 ( L(i) ) 和 ( R(i) ),并希望通过这两个函数来找到一些有趣的结论。本文将探讨如何帮助小R找到 ( MAX(i) = L(i) \times R(i) ) 的最大值,并提供详细的代码实现。
问题描述
给定一个包含 ( N ) 个元素的数组 ( a ),定义两个函数 ( L(i) ) 和 ( R(i) ) 如下:
- ( L(i) ) 是满足以下条件的最大的 ( j ) 值:
- ( j < i )
- ( a[j] > a[i] )
- 如果找不到这样的 ( j ),那么 ( L(i) = 0 );如果有多个满足条件的 ( j ),选择离 ( i ) 最近的那个。
- ( R(i) ) 是满足以下条件的最小的 ( k ) 值:
- ( k > i )
- ( a[k] > a[i] )
- 如果找不到这样的 ( k ),那么 ( R(i) = 0 );如果有多个满足条件的 ( k ),选择离 ( i ) 最近的那个。 最终,小R定义 ( MAX(i) = L(i) \times R(i) ),他想知道在 ( 1 \leq i \leq N ) 的范围内,( MAX(i) ) 的最大值是多少。
解决方案
为了帮助小R找到 ( MAX(i) ) 的最大值,我们可以分以下几个步骤来实现:
- 计算 ( L(i) ) 和 ( R(i) ):
- 使用两个数组
left和right分别存储 ( L(i) ) 和 ( R(i) ) 的值。 - 从左到右遍历数组,计算每个位置的 ( L(i) )。
- 从右到左遍历数组,计算每个位置的 ( R(i) )。
- 使用两个数组
- 计算 ( MAX(i) ):
- 遍历数组,计算每个位置的 ( MAX(i) = L(i) \times R(i) )。
- 记录并返回 ( MAX(i) ) 的最大值。
代码实现
public class Main {
public static int solution(int n, int[] array) {
int[] left = new int[n];
int[] right = new int[n];
// 计算 L(i)
for (int i = 0; i < n; i++) {
left[i] = 0;
for (int j = i - 1; j >= 0; j--) {
if (array[j] > array[i]) {
left[i] = j + 1;
break;
}
}
}
// 计算 R(i)
for (int i = n - 1; i >= 0; i--) {
right[i] = 0;
for (int k = i + 1; k < n; k++) {
if (array[k] > array[i]) {
right[i] = k + 1;
break;
}
}
}
// 计算 MAX(i) 的最大值
int max = 0;
for (int i = 0; i < n; i++) {
int currentMax = left[i] * right[i];
if (currentMax > max) {
max = currentMax;
}
}
return max;
}
public static void main(String[] args) {
// 测试样例
System.out.println(solution(5, new int[]{5, 4, 3, 4, 5}) == 8); // 输出: true
System.out.println(solution(6, new int[]{2, 1, 4, 3, 6, 5}) == 15); // 输出: true
System.out.println(solution(7, new int[]{1, 2, 3, 4, 5, 6, 7}) == 0); // 输出: true
}
}
代码解释
- 计算 ( L(i) ):
- 初始化
left数组,所有元素初始值为0。 - 从左到右遍历数组,对于每个位置 ( i ),从 ( i-1 ) 开始向左遍历,找到第一个大于 ( a[i] ) 的元素 ( j ),并记录 ( j+1 ) 为 ( L(i) )。
- 初始化
- 计算 ( R(i) ):
- 初始化
right数组,所有元素初始值为0。 - 从右到左遍历数组,对于每个位置 ( i ),从 ( i+1 ) 开始向右遍历,找到第一个大于 ( a[i] ) 的元素 ( k ),并记录 ( k+1 ) 为 ( R(i) )。
- 初始化
- 计算 ( MAX(i) ) 的最大值:
- 遍历数组,计算每个位置的 ( MAX(i) = L(i) \times R(i) )。
- 记录并返回 ( MAX(i) ) 的最大值。
测试样例
- 样例1:
n = 5, array = [5, 4, 3, 4, 5],输出:8- 解释:对于 ( i = 3 ),( L(3) = 2 ),( R(3) = 4 ),( MAX(3) = 2 \times 4 = 8 )。
- 样例2:
n = 6, array = [2, 1, 4, 3, 6, 5],输出:15- 解释:对于 ( i = 2 ),( L(2) = 1 ),( R(2) = 5 ),( MAX(2) = 1 \times 5 = 5 );对于 ( i = 3 ),( L(3) = 2 ),( R(3) = 5 ),( MAX(3) = 2 \times 5 = 10 );对于 ( i = 4 ),( L(4) = 3 ),( R(4) = 6 ),( MAX(4) = 3 \times 6 = 18 )。
- 样例3:
n = 7, array = [1, 2, 3, 4, 5, 6, 7],输出:0- 解释:数组是严格递增的,没有 ( j < i ) 使得 ( a[j] > a[i] ),也没有 ( k > i ) 使得 ( a[k] > a[i] ),因此 ( L(i) ) 和 ( R(i) ) 都为0,( MAX(i) ) 也为0。 通过上述方法,我们可以有效地帮助小R找到 ( MAX(i) ) 的最大值,确保在处理数组时算法的时间复杂度为 ( O(n^2) )。