用有效的算法计算数组中的相同对

时间:2017-04-16 19:02:28

标签: javascript java arrays algorithm combinations

问题陈述a[]n个数字的数组,计数为。数组中相同的对,0 <= p < q < n p,q是对的索引。

a[3,5,6,3,3,5] n=6这里没有相同的对是4,它们是 (0,3), (0,4), (3,4), (1,5)而不是 (2,2) (4,3) ,因为这违反了p < q条件。

解决方案1:

function getIdenticalPairs(a, n){
    var identicalPairs = 0;

    for(var i=0;i<n-1;i++){
       for(var j=i+1;j<n;j++){
         if(a[i]===a[j]){
           identicalPairs +=1;
        }
      }
   }
return identicalPairs;
}

这段代码工作正常,但似乎时间复杂度为O(n 2 )。

我试过的第二个解决方案是,

解决方案2 : 使用组合公式,相同的nos对, n c r

var identicalPairs = 0;
function getIdenticalPairs(a, n){
  var map = {};  
  for(var i=0;i<n;i++){
​    if(map[a[i]]){
       map[a[i]].push(i);
    }else{
       map[a[i]] = [i];
    }
  }

 Object.keys(map).forEach(function(v,i){
    var occurances = map[v].length;
    if(occurances > 1){
       var nFact = factorial(occurances);
       var nrFact = factorial(occurances - 2);
       var rFact = factorial(2);
       //console.log(occurances , nFact, nrFact, rFact);
       identicalPairs += nFact/(nrFact*rFact)
   }
 })
​
 function factorial(n) { 
  if(n<=1) return 1; 
  var ret = 1;
  for(var i=2;i<=n;++i) 
    ret *= i;
  return ret; 
 } 
​
 return identicalPairs;
}

Q.1 我不确定但解决方案2的时间复杂度是否为O(n + n + n)= O(n)或O(n 2 ) ?

Q.2 如果它不是O(n)那么有一个更好的解决方案可能是时间复杂度O(nlogn)是Javascript还是Java?< / p>

6 个答案:

答案 0 :(得分:4)

将索引推送到数组中:

Integer[] indices = new Integer[a.length];
for (int i = 0; i < a.length; ++i) indices[i] = i;

根据a

中相应元素的值对索引进行排序
Arrays.sort(indices, (i, j) -> Integer.compare(a[i], a[j]));

然后从indices

中拉出具有相同对应元素的索引块
int count = 0;
int i = 0;
while (i < indices.length) {
  int start = i;
  while (i < indices.length && a[indices[i]] == a[indices[start]]) {
    ++i;
  }

  // This is the number of indices whose corresponding values are equal.
  int thisCount = i - start;

  // This is the number of pairs you can make from
  // thisCount indices.
  int numPairs = thisCount * (thisCount - 1) / 2;

  count += numPairs;
}

由于排序,此方法总体上具有O(n log n)复杂度。这些组的计数是线性的。

Ideone demo

答案 1 :(得分:1)

计算数组中每个元素的出现次数:

long count =
    occurrences.values().stream()
        .mapToLong(e -> e * (e - 1) / 2)
        .sum();

然后只计算每个键可以产生的对数:

 int main()
 {
 int choice;
 scanf("%d",&choice);
 bool a=admi_login();
 if(a==true)
    printf("\n hello");
 else
    printf("Bye");
 }   
bool admi_login()
{
printf("Enter the Admin Password\n");
char pw[100];
int i;
for(i=0;i<=100;i++)
{
    pw[i]=getch();
    if(pw[i]=='\r')
        break;
    printf("*");
}
char pw1[100]="admin\r";
if((strcmp(pw,pw1))==0)
  return true;
else
 return false;}

这种方法总体上具有O(n)复杂度,因为插入哈希映射是恒定时间(并且这已经完成了n次),并且迭代地图的值是线性的。

Ideone demo

答案 2 :(得分:1)

您可以计算值并获得可能的组合计数。

  • $lengthOfString3 = strlen ( $city ); echo "String length of 'city' " . $lengthOfString3 . "</br>"; $lengthOfString4 = strlen ( $building ); echo "String length of 'building' " . $lengthOfString4 . "</br>"; 是获取数字的阶乘和
  • 的函数
  • factorial包含数组中元素的计数。

阶乘是获得n的所有组合和计数的必要条件,由于给定的规则,你只需要一半,索引应该是升序。

&#13;
&#13;
count
&#13;
&#13;
&#13;

答案 3 :(得分:1)

这是典型的动态编程问题。您可以非常有效地执行以下操作;

&#13;
&#13;
function indicesOfIdentical(a){
  return a.reduce((h,e,i) => (h[0][e] ? (h[1] = h[1].concat(h[0][e].map(n => [n,i])), h[0][e].push(i), h)
                                      :  h[0][e] = [i], h), [{},[]])[1];
}

var arr    = [0,3,5,6,3,3,5,0],
    result = indicesOfIdentical(arr);
console.log(JSON.stringify(result));
console.log("Test for 40 random items array of 0-9");
arr = Array(40).fill().map( _ => ~~(Math.random()*10));
result = indicesOfIdentical(arr);
console.log(JSON.stringify(arr));
console.log(JSON.stringify(result));
&#13;
&#13;
&#13;

答案 4 :(得分:0)

这是我使用C代码的解决方案:预期时间复杂度O(nlogn)

首先以非降序对数组A进行排序

#include <stdlib.h>

int compr(const void *a, const void *b)
{

    return (*(int*)a - *(int*)b);
}

int getIdenticalPairs(int *A, int n) 
{

    qsort(A, n, sizeof(int), compr); 

    int sumPair = 0;
    int cnt = 0;

    //if array size equal or less than 1, return 0
    if (n <=1) return 0;

    for(int i = 1; i < n; i++)
    {

        if(A[i-1] == A[i])
        { 
            //add number of identical pairs so far
            cnt++;

            sumPair += cnt;      
        }
        else
        {
           cnt = 0;
        }
    }

    return sumPair;

}

答案 5 :(得分:0)

function GetIdenticalPositionPairs(inputArray)
{
    var numberCount = {};
    for(var i=0;i<inputArray.length-1;i++)
    {
        for(var j=i+1;j<inputArray.length;j++)
        {
            if(inputArray[i] == inputArray[j]){
                if(numberCount[inputArray[i]] == undefined)
                    numberCount[inputArray[i]] = 1;
                else
                    numberCount[inputArray[i]] += 1;
                console.log(i + "--> (" + i + ","+ j +")"); 
            }
        }
    }
    console.log(numberCount);
}