确定两个列表是否包含相同的数字项而不进行排序

Jus*_*tin 3 performance

我有两个列表,我需要确定它们是否包含相同的值而不进行排序(即,值的顺序无关紧要).我知道排序可以工作,但这是性能关键部分的一部分.

项目值在[-2,63]范围内,我们总是比较相同大小的列表,但列表大小的范围是[1,8].

示例列表:

A = (0,   0, 4, 23, 10)
B = (23, 10, 0,  4,  0)
C = (0,   0, 4, 27, 10)

A == B is true
A == C is false
Run Code Online (Sandbox Code Playgroud)

我认为一个可能的解决方案是比较两个列表的乘积(将所有值相乘),但这个解决方案存在问题.如何处理零和负数.解决方法是在乘法之前为每个值添加4.这是我到目前为止的代码.

bool equal(int A[], int B[], int size)
{
    int sumA = 1;
    int sumB = 1;

    for (int i = 0; i < size; i++) {
        sumA *= A[i] + 4;
        sumB *= B[i] + 4;
    }
    return (sumA == sumB)
}
Run Code Online (Sandbox Code Playgroud)

但是,无论列表的顺序/内容是什么,这总是有效吗?换句话说,以下数学上是真的吗?所以我真正要求的是以下(除非有另一种方法来解决问题):

给出2个相同大小的列表.如果列表中的乘积(将所有值相乘)相等,则列表包含相同的值,只要这些值是大于0的整数即可.

Jos*_*Lee 7

假设您提前知道范围,则可以使用计数排序的变体.只需扫描每个数组并跟踪每个整数出现的次数.

Procedure Compare-Lists(A, B, min, max)
  domain := max - min
  Count := new int[domain]
  for i in A:
    Count[i - min] += 1
  for i in B:
    Count[i - min] -= 1
    if Count[i - min] < 0:
      // Something was in B but not A
      return "Different"
  for i in A:
    if Count[i - min] > 0:
      // Something was in A but not B
      return "Different"
  return "Same"
Run Code Online (Sandbox Code Playgroud)

这是线性的 O(len(A) + len(B))