2个元素数组中的最大乘积

Posted

技术标签:

【中文标题】2个元素数组中的最大乘积【英文标题】:Max product in array of 2 elements 【发布时间】:2021-05-09 16:17:18 【问题描述】:

给定一个正数数组,我需要找到表达式(j - i)*(b[j] + b[i]) 的最大值,其中 j 和 i 是数组索引。我尝试使用分而治之,但在合并步骤中,我找不到一个有效的算法来组合左右子数组的结果。数组长度的约束为 1,000,000(最大数组大小),时间为 1 秒。感谢您的帮助

【问题讨论】:

能否请您提及来源,以便我可以在那里尝试一些想法? 数组中是否允许重复整数? 来自codeforces.com/gym/102920/problem/L 我试过你的方法但得到了TLE,也许你有更优化的实现 AMRO:TLE 不是 WA? Is your question answered? 【参考方案1】:

让我们在这个问题上抛出两个指针:

left = 0, right = length of array - 1
do
    max_product = max(max_product, (right-left)*(array[left]+array[right]))
    if array[left] < array[right]:
        left++
    else
        right--
 while (left < right)

时间复杂度:O(数组大小),空间复杂度:O(1)


正如 Abinav 指出的那样,左边最大的贪婪选择是行不通的。因此,以下解决方案将不起作用。

这是一个基于动态规划的问题。维护一个dp 数组。 dp[index] 表示max(array[0]...array[index-1]) 的索引。所以在每个index 你计算

result = max(result, (index - dp[index]) * (array[dp[index]]+array[index])).

时间复杂度:O(数组大小), 空间复杂度:O(数组大小)

尝试是否可以将空间减少到 O(1) 作为练习。

【讨论】:

为什么要贪婪地选择左边的最大值? @AbhinavMathur 对。贪婪的选择是行不通的。我会考虑更多。 @AbhinavMathur 现在怎么样? 你能证明这是最优的吗? [1,1000,1,1,1,1] 可能会失败 现在我们需要想一想对于相等的值要移动哪个指针?我们可以尝试一一选择,但时间复杂度会受到影响。如果允许重复,我认为我们需要了解问题的约束。【参考方案2】:

按照 Shridhar 的逻辑,我认为这应该可行。

const arr = [1,3,5,2,3,6,89,2,13,45,67,7,8,9]

let left = 0 
let right = arr.length - 1 

let max = (left - right) * (arr[left] + arr[right])
right--
let ref = 0 
function algo(arr) 
        do 
                let sum = (left - right) * (arr[left] + arr[right])
                if (sum > max) max = sum 
                ref++
                if (ref % 2 === 0) right--
                else left++
                    
         while(left < right)
            
        return max 


console.log(algo(arr))

【讨论】:

另一个答案中的算法不正确 这是正确的“如果数组[左] 你怎么确定?你测试/提交了吗? 把arr[]换成你喜欢的数字(negatif和positif),设置一个console.log(sum)和一个console.log(max),你会看到返回的数字总是最高的 除了这个错误,Shridhar 的逻辑和代码都不错【参考方案3】:

扩展(j - i) * (b[j] + b[i]),我们得到:

j*b_j + j*b_i - i*b_j - i*b_i

我们可以重写为常数和向量点积,

j*b_j + (j, -b_j, -1) ⋅ (b_i, i, i*b_i)

然后——假设jth 之前的所有元素都已被看到——寻找:

j*b_j + max((j, -b_j, -1) ⋅ (b_i, i, i*b_i))
  where i < j

使用凸包和最远点查询可以在对数时间内实现向量点积的最大化,尽管实现并非易事。

【讨论】:

以上是关于2个元素数组中的最大乘积的主要内容,如果未能解决你的问题,请参考以下文章

漫画:去掉一个数,如何让剩余的数乘积最大?

如何找到 Numpy 数组的 M 个元素的 N 个最大乘积子数组?

[LeetCode] 628. 三个数的最大乘积 ☆

寻找 3 个数的最大乘积

华为OD机试 - 乘积最大值(Python)

由 8 个或更多位置分隔的数组中两个元素的最大乘积