我有两个相同元素类型的有序列表,每个列表每个值最多只有一个元素(比如整数和唯一数字),但是没有限制(一个可能是另一个的子集,它们可能是完全分离,或分享一些元素,但不分享其他元素。)
如何有效地确定A是否以不同于B的方式订购任何两个项目?例如,如果A具有项目1,2,10和B项目2,10,1,则该属性将不会保持为A列出1之前的10但B将其列在10之后.1,2,10 vs 2,10 ,5完全有效,但是A根本没有提到5,我不能依赖两个列表共享的任何给定的排序规则。
答案 0 :(得分:4)
您可以按如下方式获得O(n)。首先,使用散列找到两组的交集。其次,如果你只考虑交叉点的元素,测试A和B是否相同。
答案 1 :(得分:0)
我的方法是首先制作A
和B
的已排序副本,这些副本还会记录原始列表中元素的位置:
for i in 1 .. length(A):
Apos[i] = (A, i)
sortedApos = sort(Apos[] by first element of each pair)
for i in 1 .. length(B):
Bpos[i] = (B, i)
sortedBpos = sort(Bpos[] by first element of each pair)
现在使用标准列表合并找到这些元素,这些合并记录了共享元素的A
和B
中的位置:
i = 1
j = 1
shared = []
while i <= length(A) && j <= length(B)
if sortedApos[i][1] < sortedBpos[j][1]
++i
else if sortedApos[i][1] > sortedBpos[j][1]
++j
else // They're equal
append(shared, (sortedApos[i][2], sortedBpos[j][2]))
++i
++j
最后,按其第一个元素(shared
中的位置)对A
进行排序,并检查其所有第二个元素(B
中的位置)是否正在增加。如果A
和B
共有的元素以相同的顺序出现,则会出现这种情况:
sortedShared = sort(shared[] by first element of each pair)
for i = 2 .. length(sortedShared)
if sortedShared[i][2] < sortedShared[i-1][2]
return DIFFERENT
return SAME
时间复杂度:2 *(O(n)+ O(nlog n))+ O(n)+ O(nlog n)+ O(n)= O(nlog n)。
答案 2 :(得分:0)
一般方法:将所有值及其在B中的位置存储为HashMap中的键和值。迭代A中的值并在B的HashMap中查找它们以获得它们在B中的位置(或null)。如果此位置之前您之前看到的最大位置值,则您知道B中的某些内容与A的顺序不同。在O(n)时间运行。
粗糙,完全未经测试的代码:
boolean valuesInSameOrder(int[] A, int[] B)
{
Map<Integer, Integer> bMap = new HashMap<Integer, Integer>();
for (int i = 0; i < B.length; i++)
{
bMap.put(B[i], i);
}
int maxPosInB = 0;
for (int i = 0; i < A.length; i++)
{
if(bMap.containsKey(A[i]))
{
int currPosInB = bMap.get(A[i]);
if (currPosInB < maxPosInB)
{
// B has something in a different order than A
return false;
}
else
{
maxPosInB = currPosInB;
}
}
}
// All of B's values are in the same order as A
return true;
}