【问题标题】:Get kth common element from given integer array in c#从c#中的给定整数数组中获取第k个公共元素
【发布时间】:2017-07-17 20:41:01
【问题描述】:

我想从数组中找出第 k 个最常见的元素,我能够找到最常见的元素,但我不知道如何找到第 k 个常见的元素。

我试过了:

 private static int KthCommonElement(int[] a, int k)
 {   
     var counts = new Dictionary<int, int>();
     foreach (int number in a)
     {
         int count;
         counts.TryGetValue(number, out count);
         count++;
         //Automatically replaces the entry if it exists;
         //no need to use 'Contains'
         counts[number] = count;
     }
     int mostCommonNumber = 0, occurrences = 0;
     foreach (var pair in counts)
     {
         if (pair.Value > occurrences)
         {
             occurrences = pair.Value;
             mostCommonNumber = pair.Key;
         }
     }
     Console.WriteLine("The most common number is {0} and it appears {1} times", mostCommonNumber, occurrences);

    return mostCommonNumber;
}

【问题讨论】:

  • 这必须有多高效?它是否需要比完整排序更高效?

标签: c# arrays search


【解决方案1】:

您可以按元素的出现对元素进行排序并取第 k 个元素:

int[] orderedByOccurence = a.OrderByDescending(i => counts[i]).ToArray();
if (orderedByOccurence.Length > k)
    Console.WriteLine($"{k}th most common element: {orderedByOccurence[k]});

但正如亚当在 cmets 中指出的那样,您可以使用 GroupBy 来缩短代码:

private static int KthCommonElement(int[] a, int k)
{
    if (a == null) throw new ArgumentNullException(nameof(a));
    if (a.Length == 0) throw new ArgumentException();
    if (k < 0) throw new ArgumentOutOfRangeException();

    var ordered = a.GroupBy(i => i, (i, o) => new { Value = i, Occurences = o.Count()})
                     .OrderByDescending(g => g.Occurences)
                     .ToArray();

    int index = k;
    if (ordered.Length <= index)   
    {
        // there are less than k distinct values in the source array
        // so add error handling here, either throw an exception or
        // return a "magic value" that indicates an error or return the last element
        index = ordered.Length - 1;
    }

    var result = ordered[index];
    Console.WriteLine("The most common number is {0} and it appears {1} times", 
            result.Value, result.Occurrences);

    return result.Value;
}    

【讨论】:

  • 如果你想用它打代码高尔夫,还有一种方法可以使用 GroupBy 自己计算计数。
  • 我认为这里需要一些改进:return ordered[k];
  • @DipakAkhade 你能更具体一点吗?什么样的改进?
  • @DipakAkhade 我更新了答案,以便它还输出值的出现次数,就像您在问题中所做的那样。
  • 我对这个答案很困惑,没有得到正确的答案。我用你以前的答案得到了正确的答案。
猜你喜欢
  • 1970-01-01
  • 2014-12-07
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-07
相关资源
最近更新 更多