3个数组中的代码复杂度

时间:2013-10-18 12:18:26

标签: algorithm sorting time-complexity code-complexity

您将获得三个排序的数组(按升序排列),您需要找到三元组(每个数组中的一个元素),以使距离最小。 距离定义如下: 如果a[i], b[j]c[k]是三个元素,那么

distance = max{abs(a[i]-b[j]),abs(a[i]-c[k]),abs(b[j]-c[k])}

请提供O(n)时间复杂度的解决方案

2 个答案:

答案 0 :(得分:4)

线性时间算法:

double MinimalDistance(double[] A, double[] B, double[] C)
{
    int i,j,k = 0;
    double min_value = infinity;
    double current_val;
    int opt_indexes[3] = {0, 0, 0);

    while(i < A.size || j < B.size || k < C.size)
    {
         current_val = calculate_distance(A[i],B[j],C[k]);
         if(current_val < min_value)
         {
               min_value = current_val;
               opt_indexes[1] = i;
               opt_indexes[2] = j;
               opt_indexes[3] = k;
         }    

         if(A[i] < B[j] && A[i] < C[k] && i < A.size)
             i++;
         else if (B[j] < C[k] && j < B.size)
             j++;
         else
             k++; 
    }

    return min_value;
}

在每个步骤中检查当前距离,然后递增当前指向最小值的数组的索引。每个数组只迭代一次,这意味着运行时间为O(A.size + B.size + C.size)

如果您想要最佳索引而不是最小值,则可以返回opt_indexes而不是min_value

答案 1 :(得分:1)

假设我们只有一个已排序的数组,那么具有较少可能距离的3个连续元素是所需的解决方案。现在当我们有三个数组时,只需将它们全部合并并制作一个大的排序数组ABC(这可以通过合并排序中的合并操作在O(n)中完成),只需保留一个标志来确定哪个元素属于哪个原始数组。现在你必须在数组中找到三个连续的元素:

a1,a2,b1,b2,b3,c1,b4,c2,c3,c4,b5,b6,a3,a4,a5,....

并且此处连续表示它们按连续顺序属于3个不同的组,例如:a2,b3,c1或c4,b6,a3。

现在找到这个树元素并不难,确定最小和最大的元素应该是最后的,并且在某些三元组中的第一个和最后一个元素的元素中的第一个,例如在组中:[c2,c3,c4],[b5, b6],[a3,a4,a5],我们不需要检查a4,a5,c2,c3很明显,在这种情况下可能的解决方案是c4,[b5,b6],a5,我们也不需要将c4与b5,b6或a5与b5,b6进行比较,确定距离由a5-c4(在该组中)进行。因此,我们可以从左开始并跟踪最后一个元素,并通过保留每个组的最后访问值来更新每个迭代中的最佳解决方案。

示例(首先我应该说我没有编写代码,因为我认为这是OP的任务而不是我):

假设我们在排序数组后有这个序列:

a1,a2,b1,b2,b3,c1,b4,c2,c3,c4,b5,b6,a3,a4,a5,....

让我们一步一步地迭代:

我们需要跟踪数组中每个项目的最后一项,a用于跟踪当前最佳a_i,b代表b_i,c代表c_i。首先假设a_i = b_i = c_i = -1,

在第一步中a将是a1,在下一步

a=a2,b=-1,c=-1
a=a2,b=b1,c=-1
a=a2,b=b2,c=-1
a=a2,b=b3,c=-1,
a=a2,b=b3,c=c1,

此时我们将当前指针(a2,b3,c1)保存为差值的最佳值,

下一步:

a=a2,c=c1,b=b4

现在我们比较b4-a2与之前最佳选项的区别,如果更好,我们将此指针保存为现在的解决方案,我们继续:

a=a2,b=b4,c=c2 (again compare and if needed update the best solution),
a=a2,b=b4,c=c3 (again ....)
a=a2,b=b4,c=c4 (again ....)
a=a2, b=b5,c=c4, ....

好的,如果从文本中不清楚,合并后我们有(我猜所有数组都至少有一个元素):

解决方案=无限; A = B = C = -1, BESTA = bestB = bestC = 1;

for (int i=0;i<ABC.Length;i++)
{
    if(ABC[i].type == "a") // type is a flag determines 
                           // who is the owner of this element
    {
        a=ABC[i].Value; 
        if (b!=-1&&c!=-1)
        {
          if (max(|a-b|,|b-c|,|a-c|) < solution)
          {
            solution =  max(|a-b|,|b-c|,|a-c|);
            bestA= a,bestB = b,bestC = c;
          }
        }
    }
    // and two more if for type "b" and "c"
}

当然有比这更优雅的算法,但我发现你的链接有问题,所以我想这种看待问题的简单方法会让你更容易,之后你就可以理解你自己的链接了。