剑指offer—数组中出现次数超过一半的数字

时间:2021-09-05 11:07:04

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。


方法一:

数组排序,然后中间值肯定是要查找的值。 排序最小的时间复杂度(快速排序)O(NlogN),加上遍历。(这种方法必须确定的确存在“一个数字出现的次数超过数组长度的一半”前提下才可行)

方法二:

使用散列表的方式,也就是统计每个数组出现的次数,输出出现次数大于数组长度的数字。

方法三:

出现的次数超过数组长度的一半,表明这个数字出现的次数比其他数出现的次数的总和还多。

考虑每次删除两个不同的数,那么在剩下的数中,出现的次数仍然超过总数的一般,不断重复该过程,排除掉其他的数,最终找到那个出现次数超过一半的数字。这个方法的时间复杂度是O(N),空间复杂度是O(1)。但并非物理删除

采用阵地攻守的思想:
第一个数字作为第一个士兵,守阵地;count = 1;遇到相同元素,count++;遇到不相同元素,即为敌人,同归于尽,count--;

当遇到count为0的情况,又以新的i值作为守阵地的士兵,继续下去,到最后还留在阵地上的士兵,有可能是主元素。
再加一次循环,记录这个士兵的个数看是否大于数组一般即可。

public class Solution
{
public int MoreThanHalfNum_Solution(int [] array)
{
int count=0;
int temp=0;
for(int i=0;i<array.length;i++)
{
if(temp==array[i])count++;
else if(count>0)count--;
else
{
temp=array[i];
count=1;
}
}

count=0;
for(int i=0;i<array.length;i++)
{
if(temp==array[i])
count ++;
}
return count>array.length/2?temp:0;
}
}