【问题标题】:Number of elements that satisfy a relation满足关系的元素数
【发布时间】:2024-01-15 06:20:01
【问题描述】:

给定两个数组:

2 5 6 4 3 7 1
5 1 6 2 3 7 4

计算两个数组中满足xy之前的条件的元素x, y


目前的进展:

按索引对数组进行排序。例如,这将是:

                     object: 1 2 3 4 5 6 7
indexes in the first array:  6 0 4 3 1 2 5
indexes in the secnod array: 1 3 4 6 0 2 5

并将每个元组与另一个元组进行比较。如果元组a 的两个索引都低于或高于元组b,则增加满足条件的元素数。

这有(N^2)/2的时间复杂度,所以O(N^2),太慢了。我知道没有更好的最坏情况复杂性,但我最感兴趣的是平均结果。那么:有没有更好的方法/算法?

我想过使用传递属性(如果(x,y)(y,z) 都满足条件,那么(x,z) 也满足条件),但没有成功。


测试用例

对于数组:

2 5 6 4 3 7 1
5 1 6 2 3 7 4

满足条件的对是:

(5,1) (2,3) (2,4) (2,7) (5,3) (6,3) (3,7) (5,4) (6,4) (5,6) (5,7) (6,7)

对于数组:

1 2 3 4 5 6 7
1 2 3 4 5 6 7

满足条件的对是:

(1,2) (1,3) (1,4) (1,5) (1,6) (1,7) (2,3) (2,4) (2,5) (2,6) (2,7) (3,4) (3,5) (3,6) (3,7) (4,5) (4,6) (4,7) (5,6) (5,7) (6,7)

【问题讨论】:

  • (x,y) 在您的示例中采用值 (2,5), (5,1), ..., (1,4)
  • 在第一个数组中,2 在 5 之前,但在下一个数组中,5 在 2 之前。(5,1) 是真的。 (1,4) 不是。 (6,7), (5,6) 等等..是正确的。
  • 啊,好的。你有很多测试用例吗?
  • 给我一分钟,我会生成一些。
  • 添加了两个测试用例,其中包含满足条件的元组的完整列表。

标签: arrays computer-science computation-theory computer-science-theory


【解决方案1】:

我非常喜欢思考这个问题。感觉确实像是一道 CS 作业题,所以我会尝试在不解决所有问题的情况下触及概念。

海滩男孩原则

我的微积分老师使用的一个术语,实际上是一种非常适用的问题解决技术。基本上,如果您有一个棘手的问题,请说“如果...不是很好”,然后看看是否有什么可以使事情变得更容易。如果有,看看你能不能做到。

在这种情况下,如果顶部数组是有序的并且只是[1, 2, 3 ...],那不是很好吗?这将使解决这个问题变得更加容易,因为它将两个数组问题变成了一个数组问题。

嗯,可以这样!您可以将这些问题中的任何一个映射到具有有序第一个数组的问题中。

您列出的第一个示例:

2 5 6 4 3 7 1
5 1 6 2 3 7 4

我认为上面的问题等价于下面的问题:

1 2 3 4 5 6 7
2 7 3 1 5 6 4

映射

我只是对 2->1 5->2 6->3 4->4 3->5 7->6 1->7 做一个简单的密码替换(为什么要使用这个特殊的映射?)。这使问题的基本结构保持不变。然后,您可以解决此问题,然后撤消映射。

您会发现这种将一个问题映射为更简单问题的技术经常出现在计算机科学中,尤其是在您的算法和可计算性类中。

你现在有一个单一的数组问题来查找所有对:

2 7 3 1 5 6 4

这个时间复杂度我留给读者一个练习。

附:不要忘记撤消映射的时间复杂度。有时您会解决一个问题,认为很容易发现构建和解构映射非常昂贵,您必须重新设计。

【讨论】:

  • 感谢您的回答。我会努力解决这个问题。 PS:您创建的等效问题中有一个错字,应该是2 7 3 1 5 6 4而不是2 6 3 1 5 6 4。否则,它似乎是非常正确的。
  • 好收获!固定。
  • 抱歉,我看不出这有什么帮助。您将问题转化为另一个问题,并且暗示它使事情变得更容易,从而模糊地证明了这种转换是合理的。但最后,你有一个数组,并且在 this 上计算解决方案仍然很困难(即 O(n*2)),除非你应用一些你可以同样应用于原始数组。
  • 在单数组问题中利用传递属性要容易得多。尽管如此,我必须承认,即使我让程序运行得更快了一点,但我仍然远离令人垂涎的时间复杂度。