【问题标题】:Algorithm that finds the N-th most frequent number in the array查找数组中第 N 个最频繁数的算法
【发布时间】:2017-07-11 11:24:01
【问题描述】:

我想编写一个算法来查找数组中第 n 个最频繁的数字。 我有一个解决方案,但不是最优的(我已经测试过的测试数字) 我想知道是否有更优化的解决方案? 这是我的解决方案:

most_freq_element(a,n){
final_cnt = 0, curr_cnt = 1, final_freq_num = -1, curr_freq_num = -1;
for(i = 0; i < n-1; i++)
{
    if (a[i]!=-1){
        curr_freq_num = a[i];
        for(j =i+1; j < n; j++){
            if(curr_freq_num == a[j] && final_freq_num != curr_freq_num){
                curr_cnt++;
            }
        }
        if(final_cnt < curr_cnt){
            final_cnt = curr_cnt;
            curr_cnt = 1;
            final_freq_num = curr_freq_num;
        }
    }
}
printf("Num = %d and times = %d", final_freq_num, final_cnt);
}



nth_most_frequent_element(a,n,k){    
if(k==1){
    return most_freq_element(a,n);
}
else{ 
    for (i=0;i<k;i++){
        int most_freq_num = most_freq_element(a,n);

        for(i = 0; i < n-1; i++){
            if (a[i]==most_freq_num){
                a[i]=-1;
            }
        }
    }
    return most_freq_element(a,n);
}
}

【问题讨论】:

标签: arrays algorithm


【解决方案1】:

我可能会制作一个 hashmap/table,并在碰撞时增加每个值,这样数字就是键,值是碰撞次数。然后,完成后,将其聚合到一个排序列表并获取第 n 个元素。将在 O(n) 中运行,这是非常理想的。

编辑:实际上,排序将花费 n*log(n)。

【讨论】:

  • aggregate it to a sorted list 会变成 O(nlog(n))
  • 你不计算N个哈希映射键查找,
  • 与 nlogn 相比,它们微不足道。随着操作接近无穷大,唯一重要的术语是 nlogn。你看不到很多算法,包括每一个无关紧要的术语。它们只是提出最重要的术语,除非有多个具有同等重要性的术语
  • Sum{n=1..N-1}(log(N-n)) 并非微不足道,因为它大于 N。
  • 这是对链表的一次迭代,用于 O(n) 的冲突计数和恒定时间 hashmap 插入,然后从条目 O(nlogn + n) -> O(nlogn) 创建一个排序列表) 然后抓取第 n 个元素以获得最大 O(n) 或 O(1) 的排序数组。所以它是 O(3n + nlogn) -> O(nlogn)。我不知道你指的是什么。
【解决方案2】:

这个怎么样?最差的复杂度是 O(2.N.logN + k.min(k,d)),d:a 中唯一值的数量

most_freq_element(a[0..n-1],n,k)
{
  count[0..k], value[0..k];   // k + 1 elements
  i, j, l;

  qsort(a, n)

  j = 0;
  l = 0;
  value[0] = a[0];
  count[0] = 1;
  for (i = 1; i < n; ++i)
  {
     if (a[i] != value[j])
     {
        if (++l > k) l = k;
        j = l;
        value[j] = a[i];
        count[j] = 0;
     }

     ++count[j];

     while (j > 0 && count[j] > count[j - 1])
     {
        swap(count[j], count[j - 1]);
        swap(value[j], value[j - 1]);
        --j;
     }
  }
  printf("Num = %d and times = %d", value[k - 1], count[k - 1]);
}

【讨论】:

    猜你喜欢
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多