哪里出错了?寻找多数

时间:2012-11-25 17:50:01

标签: java

我想在数组中找到大多数(大多数时候出现的数字)。 我有一个排序数组并使用这些循环:

for(int k = 1;k < length;k++)
{
    if(arr[k-1] == arr[k])
    {
        count++;
        if(count > max)
        {
            max = count;
            maxnum = arr[k-1];
        }
    } else {
        count = 0;
    }
}

for(int h=0;h<length;h++)
{
    for(int l=1;l<length;l++)
    {
        if(arr[h] == arr[l])
        {
            count++;
            if(count > max)
            {
                max = count;
                maxnum = arr[h];
            }
        } else count = 0;
    }
}
他们很相似。当我在小阵列上尝试它们时,一切似乎都没问题。但是在具有N个元素0 <= N <= 500000的长期阵列中,每个元素K 0 <= K <= 10 ^ 9它们给出错误的答案。 这是错误http://ideone.com/y2gvnX的解决方案。我知道有更好的算法可以找到多数,但我只需要知道我的错误在哪里。

我真的无法找到它:(非常感谢帮助!

4 个答案:

答案 0 :(得分:1)

首先,您应该使用first algorithm,因为您的数组已排序。第二个算法不必要地两次运行数组。

现在您的first algorithm几乎是正确的,但它有两个问题: -

  • 第一个问题是你正在设置count = 0,否则, 而应将其设置为1。因为每个元素至少都有 一次。
  • 其次,您不必每次都在max设置if。只是 increment count,直到if-condition满意,并且很快 如condition fails一样,检查current count current max,并相应地重置当前最大值。

这样,每次迭代都不会检查max,但只有在找到不匹配时才会检查。

所以,你可以尝试这个代码: -

    // initialize `count = 1`, and `maxnum = Integer.MIN_VALUE`.
    int count = 1;
    int max = 0;
    int maxnum = Integer.MIN_VALUE;

    for(int k = 1;k < length;k++)
     {
         if(arr[k-1] == arr[k]) {
              count++;   // Keep on increasing count till elements are equal

         } else {
             // if Condition fails, check for the current count v/s current max

             if (max < count) {   // Move this from `if` to `else`
                 max = count;
                 maxnum = arr[k - 1];
             }
             count = 1;  // Reset count to 1. As every value comes at least once.
         }
     }

注意: -

这种方法存在的问题是,如果两个数字表示 - 13,则次数相同 - 即最大值,那么max计数将计入{ {1}}(假设33之后,而1将包含maxnum并忽略3。但它们都应该被考虑。

所以,基本上,你不能使用1并维持for loop来解决这个问题。

更好的方法是创建count,并在其中存储每个值的计数。然后是Map<Integer, Integer> sort Map上的value

答案 1 :(得分:0)

如果数组已排序,则第一个算法才有意义。

你的第二个算法只是在错误的地方将count设置为零。在进入内部for循环之前,您希望将计数设置为零。

 for(int h=0;h<length;h++)
 {
  count = 0;
  for(int l=0;l<length;l++)
  {
   if(arr[h] == arr[l])
   {
    count++;
    if(count > max)
    {
     max = count;
     maxnum = arr[h];
    }
   }
  }
 }

此外,您不需要每次都在内循环中检查count

 max = 0;
 for(int h=0;h<length;h++)
 {
  count = 0;
  for(int l=0;l<length;l++)
  {
   if(arr[h] == arr[l])
    count++;
  }
  if(count > max)
  {
   max = count;
   maxnum = arr[h];
  }
 }

答案 2 :(得分:0)

我可以很容易看到的错误是,如果所有元素都是不同的,那么最后的最大值为0。 但它必须是1。 因此,当您在“else”情况下更新计数时,将其更新为1而不是0,因为已发现新元素,并且其计数为1.

答案 3 :(得分:0)

你的第一个算法对我来说是正确的。第二个(这是你的链接代码使用的)每次循环都需要一些初始化。此外,内循环不需要每次从1开始;它可以从h + 1开始:

for(int h=0; h<length; h++)
{
    count = 1; // for the element at arr[h]
    for(int l=h + 1; l<length; l++)
    {
        if(arr[h] == arr[l])
        {
            count++;
        }
    }
    if(count > max)
    {
        max = count;
        maxnum = arr[h];
    }
}

第一种算法对于排序数组要好得多。即使对于未排序的数组,对数组(或其副本)进行排序然后使用第一种算法而不是使用第二种算法会更便宜。

请注意,如果根据@ Rohit的评论存在关系(例如数组[1, 1, 2, 2, 3]),则会找到具有最大计数的第一个值(按排序顺序)。

相关问题