检查两个阵列是否相似

时间:2013-11-06 06:00:47

标签: arrays algorithm

给定两个数组,检查它们是否相似(即具有相同的整数,每个整数的次数相同)。

例如:

int arr1[5] = { 3, 5, 2, 5, 2}
int arr2[5] = { 2, 3, 5, 5, 2}

我不允许使用排序和哈希表。它应该是O(n)并且不应该使用任何额外的空间。

这是一个面试问题。

尝试过如下规则:

  1. 两个数组中的整数之和应相同
  2. 两个数组中的整数乘积应相同。
  3. 所有整数的XOR应为零
  4. 但是面试官仍然不高兴。也许我错过了一些角落案件。

4 个答案:

答案 0 :(得分:2)

如果元素值是整数并且由n1...n)限定,我可以想到执行此任务的一种方法,其中n是数组的大小(这适用于你的例子):

在每个数组中,对于每个元素x,我们执行arr[x%(n+1)-1] += n+1。我们使用mod,因为元素可能会在整个过程中发生变化,通过使用mod我们得到原始数组中出现的元素。

我们所做的是通过添加v来计算arr[v]中值n+1的出现次数,然后我们可以通过arr[v]%(n+1)来获取原始值值由n限制,以及arr[v]/(n+1)的出现次数。

最后,我们比较了AB中每个值的出现次数,如果对于任何值不同,我们会返回false。如果所有值的计数相同,我们返回true

这是一个需要O(n)内存的O(1)时间解决方案。

这是算法:

bool checkIfArraysAreSimilar(int[] A, int[] B)
{
    n = A.length; // = B.length
    int i;

    for (i = 0; i < n; i++)
    {
        A[(A[i]%(n+1))-1] += n+1;
        B[(B[i]%(n+1))-1] += n+1;
    }

    for (i = 0; i < n; i++)
    {
        if (A[i] / n+1 != B[i] / n+1)
            return false;
    }

    return true;
}

答案 1 :(得分:1)

在JavaScript中尝试此算法:

DEMO

var arr11 = [ 3, 5, 2, 5, 2]
var arr22 = [ 2, 3, 5, 5, 2]
console.log(arraySimilar(arr11,arr22));
function arraySimilar(arr1,arr2){ 
    var tempArr = arr2;
    // Checking Length if both the arrays are equal 
    if(arr1.length == arr2.length){
        //Running a For Loop for first array 
        for(i=0; i<arr1.length; i++){
            //If the Element is present removing from "tempArr"
            if(tempArr.indexOf(arr1[i])!= -1){
                tempArr.splice(tempArr.indexOf(arr1[i]),1);
            }
            else{ return false;}
        }
    }
    else{ return false; }
    // Check "tempArr" if it is empty
    if(tempArr.length==0){
        return true;
    }else{
        return false;
    }
}

答案 2 :(得分:1)

可能他意味着你应该将f与x(x [i])的和除以及f(y [i])的i除以i,其中x和y是数组,f是散列函数。

答案 3 :(得分:0)

第一个数组有两种可能的方式,无论它是否包含非重复元素。让我们说为了简单起见,第一个数组不包含重复的元素,那么这个想法非常简单,跟踪总数,如下面的代码所示

#include <iostream>

int  main()
{ 
    int arr1[5] = { 1, 2, 3, 4, 5};
    int arr2[5] = { 5, 1, 3, 4, 2};

    int total(0);

    for (unsigned int i(0); i < 5; ++i)
    {
        for (unsigned int j(0); j < 5; ++j)
        {
            if ( arr1[i] == arr2[j] )
            {
                total += 1;
            }
        }
    }
    if ( total == 5 ) 
        std::cout << "Same " << std::endl;
    else 
        std::cout << "not Same " << std::endl;

    std::cin.get();
    return 0;
}

如果总数小于或大于5,则阵列不相同。现在,在我看来,我们需要提出一个计算正确总数的算法,因此我们需要一个接受数组并检查总数的函数。例如,在您的情况下,总数应为9(3表示1,2表示4,5表示4)。这就是我想到的。我希望这个想法很清楚。这就是我为一般情况所做的事情

#include <iostream>


int getTotal(int arr[], const int size)
{
    int *temp = new int[size]; 
    int total(0);
    for (int i(0); i < size; ++i)
        temp[i] = arr[i];


    for (int i(0); i < size; ++i)
    {
        for (int j(0); j < size; ++j)
        {
            if ( arr[i] == temp[j] )
                total += 1;
        }
    }

    std::cout << total << std::endl;
    return total;
}

int  main()
{ 
    int arr1[5] = { 3, 5, 2, 5, 2};
    int arr2[5] = { 2, 3, 5, 5, 2};

    int total = getTotal(arr1, 5);
    int track(0);

    for (unsigned int i(0); i < 5; ++i)
    {
        for (unsigned int j(0); j < 5; ++j)
        {
            if ( arr1[i] == arr2[j] )
            {
                track += 1;
            }
        }
    }
    if ( track == total ) 
        std::cout << "Same " << std::endl;
    else 
        std::cout << "not Same " << std::endl;

    std::cin.get();
    return 0;
}

使用一个循环的另一种方法。我们的想法是得到一个数组的总数,然后将每个元素除以总数得到新的总数。如果第一个数组的新总数等于第二个数组的新总数,那么它们是相同的。 (注意:我没有为所有情况测试我的代码;但是,我的方法对我来说似乎是明智的。

#include <iostream>


double getTotal(double arr[], const int size)
{
    double total1(0), total2(0);

    for (int i(0); i < 5; ++i)
    {
        total1 += arr[i];
    }

    for (int i(0); i < 5; ++i)
    {
        total2 += total1/arr[i];
    }

    std::cout << total2 << std::endl;

    return total2;
}

int  main()
{ 
    double arr1[5] = { 3, 5, 2, 4, 2};
    double arr2[5] = { 2, 3, 5, 5, 2};

    double total1 = getTotal(arr1, 5);
    double total2 = getTotal(arr2, 5);

    if ( total1 == total2 ) 
        std::cout << "Same " << std::endl;
    else 
        std::cout << "not Same " << std::endl;

    std::cin.get();
    return 0;
}