题解:寻找数组中的最大乘积
问题描述
给定一个长度为 ( N ) 的数组 ( a ),我们需要定义两个函数 ( L(i) ) 和 ( R(i) ),并计算 ( MAX(i) = L(i) \times 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 ) 最近的那个。
最终,我们需要找到在 ( 1 \leq i \leq N ) 的范围内,( MAX(i) ) 的最大值。
解题思路
-
初始化辅助数组:
- 创建两个辅助数组 ( l ) 和 ( r ),分别存储每个位置的 ( L(i) ) 和 ( R(i) )。
-
计算 ( L(i) ):
- 对于每个位置 ( i ),从 ( i-1 ) 开始向前遍历,找到第一个大于 ( a[i] ) 的元素 ( j ),并将 ( l[i] ) 设为 ( j+1 )(因为数组索引从0开始)。
- 如果没有找到这样的 ( j ),则 ( l[i] = 0 )。
-
计算 ( R(i) ):
- 对于每个位置 ( i ),从 ( i+1 ) 开始向后遍历,找到第一个大于 ( a[i] ) 的元素 ( k ),并将 ( r[i] ) 设为 ( k+1 )。
- 如果没有找到这样的 ( k ),则 ( r[i] = 0 )。
-
计算 ( MAX(i) ):
- 遍历每个位置 ( i ),计算 ( MAX(i) = L(i) \times R(i) ),并记录最大值。
代码实现
public class Main {
public static int solution(int n, int[] array) {
final int N = 10001;
int[] l = new int[N];
int[] r = new int[N];
// 计算 L(i)
for (int i = 0; i < n; i++) {
for (int j = i - 1; j >= 0; j--) {
if (array[j] > array[i]) {
l[i] = j + 1;
break;
}
}
}
// 计算 R(i)
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (array[j] > array[i]) {
r[i] = j + 1;
break;
}
}
}
// 计算 MAX(i) 的最大值
int ans = 0;
for (int i = 0; i < n; i++) {
ans = Math.max(ans, l[i] * r[i]);
}
return ans;
}
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
}
}
代码解释
-
初始化辅助数组:
int[] l = new int[N];和int[] r = new int[N];分别用于存储 ( L(i) ) 和 ( R(i) ) 的值。
-
计算 ( L(i) ):
- 使用嵌套循环,外层循环遍历每个位置 ( i ),内层循环从 ( i-1 ) 向前遍历,找到第一个大于 ( a[i] ) 的元素 ( j ),并将 ( l[i] ) 设为 ( j+1 )。
-
计算 ( R(i) ):
- 使用嵌套循环,外层循环遍历每个位置 ( i ),内层循环从 ( i+1 ) 向后遍历,找到第一个大于 ( a[i] ) 的元素 ( k ),并将 ( r[i] ) 设为 ( k+1 )。
-
计算 ( MAX(i) ):
- 遍历每个位置 ( i ),计算 ( MAX(i) = L(i) \times R(i) ),并记录最大值。
复杂度分析
-
时间复杂度:( O(N^2) )
- 计算 ( L(i) ) 和 ( R(i) ) 都需要 ( O(N) ) 的时间,因此总的时间复杂度为 ( O(N^2) )。
-
空间复杂度:( O(N) )
- 使用了两个辅助数组 ( l ) 和 ( r ),每个数组的大小为 ( N )。
优化建议
对于较大的输入规模,可以使用单调栈来优化 ( L(i) ) 和 ( R(i) ) 的计算,将时间复杂度降低到 ( O(N) )。具体实现可以参考单调栈的相关算法。