求数组中 (i,j) 对的总数,使得 i<j 且 a[i]+a[j]=i+j。 [关闭]

Posted

技术标签:

【中文标题】求数组中 (i,j) 对的总数,使得 i<j 且 a[i]+a[j]=i+j。 [关闭]【英文标题】:Find total number of (i,j) pairs in an array such that i<j and a[i]+a[j]=i+j. [closed] 【发布时间】:2019-04-19 23:22:00 【问题描述】:

我有一个简单的解决方案,它使用两个循环,但我想将时间复杂度提高为 O(nlogn)。有更好的方法吗?

数组未排序,也可以有负值。

示例测试用例: 数组:1 0 3 2

输出: 4

说明: 索引 - (0,1), (0,3), (1,2), (2,3) 是满足给定约束的对。

【问题讨论】:

你的问题是什么? 请阅读此open letter to students with homework problems。 你可以对数组进行排序吗? 找到配对后我该怎么办? 可以对数组进行排序。但是您将无法满足条件 i 【参考方案1】:

问题:find (i,j), i&lt;j, s.t. a[i] + a[j] = i + j

我提出以下方法:

    设置b[i] = a[i] - i 问题变成:find (i,j), i&lt;j, s.t. b[i] + b[j] = 0 复杂度:O(n)

    在 std::vector(或 std::array)中创建对象 c[i] = (b[i],i),例如结构体 复杂度:O(n)

    根据b 值对c[i] 对进行排序-> 得到d[j] = (v[j], i[j]),排序后的数组 复杂度:O(nlogn)

    找到所有对 j,k 使得 v[j] = -v[k] 复杂度:被排序的数组,应该是 O(n)

    保留箱子i[j] &lt; i[k] 复杂度:O(n)

【讨论】:

我认为你可以去掉多余的pair,只保留第1、3和4步,i &lt; j限制是只计算一次Demo。 (已更正)@Jarod42 如果我们只想计算对数,那您是完全正确的。在 OP 提供的示例中,他还给出了成对的索引作为结果。因此,我在第 2 步中提出了这对额外的配对是详尽无遗的。有 5 个步骤看起来比只有 3 个步骤更严重:) @Jarod42 我刚刚注意到您的代码(演示)。你的速度给我留下了深刻的印象。

以上是关于求数组中 (i,j) 对的总数,使得 i<j 且 a[i]+a[j]=i+j。 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

树状数组求逆序对

一道编程题:求逆序对的个数

codevs 4163 求逆序对的数目 -树状数组法

逆序对的三种解法

逆序对问题---求逆序数

LeetCode 493. Reverse Pairs