【问题标题】:Java - Find maximum number of duplicates within an arrayJava - 查找数组中的最大重复数
【发布时间】:2019-08-01 12:50:33
【问题描述】:

我正在使用 HashSet 来查找 排序 Integer 数组中值的最大重复数。但是我的算法似乎不起作用,没有返回想要的结果。

Set variables storing the number of duplicates found (0), and the maximum number of duplicates (0). 
Set a HashSet that stores the unique values of an array.
Sort the array to be ready for comparison.

Loop through each value of the array
    If the HashSet of unique values contains the current value:
        Increment the duplicate Count

    If the currentValue is not equal to the previous value:
        If the duplicateCount is greater than the maximum Count:
            maximumCount becomes duplicateCount
            Reset duplicateCount to 0

Java 代码

HashSet<Integer> uniqueValues = new HashSet<Integer>(valueSequenceList);

int duplicateCount = 0;
int maxCount = 0;
Arrays.sort(valueSequence);

for (int i = 0; i < valueSequence.length; i++)
{
    if (uniqueValues.contains(valueSequence[i]))
    {
        duplicateCount++;
    }
    if (i > 0 && valueSequence[i] != valueSequence[i-1])
    {
        if (duplicateCount > maxCount)
        {
            maxCount = duplicateCount;
            duplicateCount = 0;
        }
    }
}

示例
输入:[4, 4, 10, 4, 10]
输出:4 个重复项(最多应该有 3 个重复项 - 相同的值的总数)。

【问题讨论】:

  • 您的示例未排序,而问题说应该排序。
  • @amit 我在我的代码中对数组进行了排序。我忘了把它添加到问题中。
  • @HenryIsVeryPro 然后更新问题而不是发表评论!
  • @HenryIsVeryPro,您不需要 HashSet,只需检查 valueSequence[i] == valueSequence[i-1]
  • @aioobe 哦,是的,好点。让我检查一下。

标签: java arrays algorithm


【解决方案1】:

这是Element Distinctness Problem - 在线程中进行了详细说明:Find duplicates in an array

提到的线程讨论了问题的解决方案,并显示了下限(在不使用哈希表的情况下,不能比 O(nlogn) 做得更好。

因此,如果您的数据未排序 - 您可以排序和迭代(如下所示),或使用哈希集 - 然后您不需要对数组进行排序

如果您首先对数组进行排序,或者数组已经排序,则可以进行一次迭代:

排序数组的单次迭代:

if (arr == null || arr.length == 0) return 0;
int last = arr[0];
int numDupes = 1;
for (int i = 1; i < arr.length; i++) { 
   if (arr[i] == last) numDupes++;
   last = arr[i];
}

使用 HashSet(无需排序):

if (arr == null) return 0;
Set<Integer> set = new HashSet<>();
int numDupes = 0;
for (int x : arr) { 
    if (set.contains(x)) numDupes++;
    set.add(x);
}

如果您正在寻找某些元素重复的最大数量(而不是重复总数),您可以使用相同的方法,但略有不同:

哈希解决方案 - 使用 histogram:

Map<Integer,Integer> histogram = new HashMap<>();
for (int x : arr) { 
  if (!histogram.containsKey(x)) histogram.put(x,1); 
  else histogram.put(x,histogram.get(x) + 1);
}
int max = 0;
for (int x : histogram.values) max = max > x ? max : x;
return max;

排序数组解:

if (arr == null || arr.length == 0) return 0;
int last = arr[0];
int max = 0;
int currNumDupes = 1;
for (int i = 1; i < arr.length; i++) { 
   if (arr[i] == last) currNumDupes++;
   else { 
        max = max > currNumDupes ? max : currNumDupes;
        currNumDupes = 1;
   }
   last = arr[i];
}
max = max > currNumDupes ? max : currNumDupes; //if the most dupes is from the highest element

【讨论】:

  • 你可以改用if (!set.add(x)) numDupes++;
【解决方案2】:

检查以下返回最大重复数的代码

 public static void main(String args[]) {
    int[] inputArray = { 4, 4, 10, 4, 10 };
    Map<Integer, Integer> hMap = new HashMap<Integer, Integer>();
    HashSet<Integer> hSet = new HashSet<Integer>();
    for (int i : inputArray) {
        if (hSet.add(i)) {
            hMap.put(i, 1);
        } else {
            hMap.put(i, hMap.get(i) + 1);
        }
    }
    Iterator<Integer> iter = hMap.values().iterator();
    int temp = 0;
    while (iter.hasNext()) {
        int max = iter.next();
        if (max > temp) {
            temp = max;
        }
    }
    System.out.println(temp);
}

【讨论】:

    【解决方案3】:

    建议:

    您可以使用简单的Map&lt;Integer, Integer&gt;,其中键是项目值,值是该项目的计数。

    这将使代码变得简单——无需排序:

    Map<Integer, Integer> count = new HashMap<Integer, Integer>();
    
    for (Integer item : list){
        if (count.containsKey(item)){
            // increate count
            count.put(item, count.get(key) + 1);
        } else {
            // no item yet - set count to 1
            count.put(item, 1);
        }
    }
    

    您现在可以使用 Collections.max 之类的东西在 count.values() 上找到最大的 Integer 值 - 或者甚至为条目编写 Comparator&lt;Entry&lt;Integer, Integer&gt;&gt; 以从 count.entrySet() 中找到最大的 Map.Entry&lt;Integer, Integer&gt;(最好,可以与Collections.max一起使用)。

    注意:您可以使用 MutableInt (Apache commons) 甚至 AtomicInt 来获取可变映射值。我尚未测试差异,但它可能更快。

    【讨论】:

      【解决方案4】:

      编辑:我假设(基于您的代码)目标是找到在数组中出现最多的数字的出现次数。将其称为“最大重复数”是一种误导。

      首先,HashSet 是没用的。您预先将所有元素添加到其中,这意味着uniqueValues.contains(valueSequence[i]) 始终为真。

      现在,如果您还没有移动到下一个元素,您只想增加 duplicateCount

      for (int i = 0; i < valueSequence.length; i++)
      {
          if (i == 0 || valueSequence[i] == valueSequence[i-1])
          {
              duplicateCount++;
          }
          else
          {
              if (duplicateCount > maxCount)
              {
                  maxCount = duplicateCount;                
              }
              duplicateCount = 1; // another small fix
          }
      }
      if (duplicateCount > maxCount)
          maxCount = duplicateCount;
      }
      

      如果目标是找到重复的数量,你可以在没有任何循环的情况下做到这一点(因为重复的数量是元素的总数减去唯一元素的数量):

      HashSet<Integer> uniqueValues = new HashSet<Integer>(valueSequenceList);
      int duplicateCount = valueSequenceList.size() - uniqueValues.size();
      

      【讨论】:

      • else 子句中代码 (1) 的小问题 - 它应该将 duplicateCount 重置为 1(您刚刚找到第一个重复项,这与最后一个元素不同)(2)它不处理最大重复数在末尾的情况(例如 2,2,3,3,3,3,3)
      【解决方案5】:
      String[] Csssplit = Css.split("====");
              HashMap<String,Integer> Spancsslist = new HashMap<String,Integer>();
              for(int c=0;c<Csssplit.length;c++){
                  Css = Csssplit[c];
                  //System.out.println("css::"+Css);
                  int count = Spancsslist.getOrDefault(Css, 0);
                  Spancsslist.put(Css,count+1);    
              }
              if(Spancsslist.size()==0){ continue; }
      
              Spancsslist = Spancsslist.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,LinkedHashMap::new));
              Css = Spancsslist.keySet().stream().findFirst().get();
      

      【讨论】:

        【解决方案6】:

        使用 Integer.MIN_VALUE 查找最大数组,然后计算重复的最大 int 数组。

        public static int main(int[] ar) {
                int count = 0;
                int max = Integer.MIN_VALUE;
                int lastMax = 0;
        
                for(int i = 0; i < ar.length; i++) {
                   if(ar[i] > max) {
                    max = ar[i];
                    if(lastMax != max){
                      count = 0;
                    }
                    lastMax = max;
                   } 
        
                  if(ar[i] == max) {
                  count += 1;
                  }
                }
                   return count;
            }
        

        【讨论】:

        • 该问题询问数组中的最大重复数。您的答案是关于 max 元素的重复数。
        猜你喜欢
        • 2016-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-12
        • 2013-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多