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

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

【问题讨论】:

标签: algorithm divide-and-conquer sub-array


【解决方案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

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

【讨论】:

    猜你喜欢
    • 2017-02-02
    • 2019-10-24
    • 1970-01-01
    • 2017-03-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 2017-01-08
    相关资源
    最近更新 更多