找到最大乘积的长度为 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 值。