📜  找到最大乘积的长度为 3 的递增子序列

📅  最后修改于: 2022-05-13 01:57:52.863000             🧑  作者: Mango

找到最大乘积的长度为 3 的递增子序列

给定一个非负整数序列,找到长度为 3 的子序列,其乘积最大,子序列的数字按升序排列。

例子:

Input: 
arr[] = {6, 7, 8, 1, 2, 3, 9, 10} 
Output: 
8 9 10

Input: 
arr[] = {1, 5, 10, 8, 9}
Output: 5 8 9

由于我们想找到最大产品,我们需要为给定序列中的每个元素找到以下两件事:
LSL:给定元素左侧的最大较小元素
LGR:给定元素右侧的最大较大元素。

一旦我们找到一个元素的 LSL 和 LGR,我们就可以找到元素与其 LSL 和 LGR 的乘积(如果它们都存在的话)。我们为每个元素计算这个产品并返回所有产品的最大值。

一个简单的方法是使用嵌套循环。外层循环依次遍历每个元素。在外循环内部,运行两个内循环(一个接一个)以查找当前元素的 LSL 和 LGR。该方法的时间复杂度为 O(n 2 )。

我们可以在 O(nLogn) 时间内做到这一点。为简单起见,让我们首先创建两个大小为 n 的数组 LSL[] 和 LGR[],其中 n 是输入数组 arr[] 中的元素数。主要任务是填充两个数组 LSL[] 和 LGR[]。一旦我们填充了这两个数组,我们只需要找到最大乘积 LSL[i]*arr[i]*LGR[i] 其中 0 < i < n-1(请注意,对于 i 不存在 LSL[i] = 0 并且对于 i = n-1) 不存在 LGR[i]。我们可以在 O(nLogn) 时间内填充 LSL[] 。这个想法是使用像 AVL 这样的平衡二叉搜索树。我们从空的 AVL 树开始,在其中插入最左边的元素。然后我们从第二个元素开始遍历输入数组到倒数第二个元素。对于当前正在遍历的每个元素,我们在 AVL 树中找到它的楼层。如果 floor 存在,我们将 floor 存储在 LSL[] 中,否则我们存储 NIL。存储地板后,我们将当前元素插入 AVL 树中。

我们可以在 O(n) 时间内填充 LGR[] 。这个想法与这篇文章相似。我们从右侧遍历并跟踪最大的元素。如果最大元素大于当前元素,则将其存储在 LGR[] 中,否则存储 NIL。

最后,我们运行 O(n) 循环并返回 LSL[i]*arr[i]*LGR[i] 的最大值

这种方法的总体复杂度是 O(nLogn) + O(n) + O(n),即 O(nLogn)。所需的辅助空间为 O(n)。请注意,我们可以避免 LSL 所需的空间,我们可以在最终循环中找到并使用 LSL 值。