我想在数组中找到大多数(大多数时候出现的数字)。 我有一个排序数组并使用这些循环:
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的解决方案。我知道有更好的算法可以找到多数,但我只需要知道我的错误在哪里。
我真的无法找到它:(非常感谢帮助!
答案 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.
}
}
注意: -
这种方法存在的问题是,如果两个数字表示 - 1
和3
,则次数相同 - 即最大值,那么max
计数将计入{ {1}}(假设3
在3
之后,而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]
),则会找到具有最大计数的第一个值(按排序顺序)。