给定一个未排序的数组arr
,如何计算(i, j)
所有可能的索引arr[i] < arr[j]
对?复杂性应该是线性的或接近线性的(O(n^2)
解决方案很明显)。
编辑:
抱歉,我忘了提及,但i < j
是指数的条件。
答案 0 :(得分:2)
提示:
对于每对索引(i,j),这些陈述中只有一个是真的:
(a[i]<a[j])
,(a[i]=a[j])
,(a[i]>a[j])
。
您必须遍历数组并计算[]
中每个值的实例数然后,这只是组合学的一个问题......
答案 1 :(得分:1)
[重要]:以下是对初始问题的回答,其中没有条件i&lt; Ĵ
您可以在O(N * log(N))
中排序,然后在O(N)
中找到答案,它总共会给您O(N * log(N))
。下面是第二部分的代码(在数组排序后):
int count = 0;
int curBefore = 0;
for (int i = 1; i < sorted.Length; i++)
{
if (sorted[i] > sorted[i - 1])
{
curBefore = i;
}
count += curBefore;
}
是的,有一个线性(伪,因为字典操作在一般情况下不是线性的)解决方案呢!但它需要额外的内存和使用类似字典的数据结构:
int res = sorted.Length * (sorted.Length - 1) / 2;
Dictionary<int, int> dict = new Dictionary<int, int>();
for (int i = 0; i < sorted.Length; i++)
{
if (!dict.ContainsKey(sorted[i]))
{
dict.Add(sorted[i], 0);
}
dict[sorted[i]]++;
}
foreach (var pair in dict)
{
res -= (pair.Value - 1) * pair.Value / 2;
}
答案 2 :(得分:0)
您可以使用自定义二叉树来动态计算此计数。因此,每个节点将包含三个值:(v, lc, ec)
其中v
是节点上的值,lc
左侧树上的节点数和ec
值的数量被发现等于v
。如您所见,在向树中插入新值时,可以更新这些计数器。
最终答案将保存在全局变量中,并在每次将新值插入树时更新。这个想法是当一个新值插入到树中时,它会通过一个特定的路径,沿着这条路径的节点将确切地知道存在多少小于通过的值的值,所以在这些节点上最后的答案可以适当更新。
请注意,只有当新值大于当前节点上的值时(即,当它将新值转发到右侧子树时),才会更新最终答案 - 这是因为您有附加约束{ {1}}。
希望这有帮助!