您的位置:首页 > 编程语言 > Java开发

[Java] Majority Element (求过半数,或者翻译成 求出现次数过半的众数)

2015-08-13 18:55 357 查看
Given an array of size n, find the majority element. The majority element is the element that appears more than 
⌊
n/2 ⌋
 times.

You may assume that the array is non-empty and the majority element always exist in the array.
简单翻译一下,就是找出过半数,此数在数组中出现的次数大于⌊ n/2 ⌋次。而且测试用例保证 数组不为空,且存在这个数。
简要分析:
虽然题目没指名,但是我们可以很容易就想到,有且仅有存在一个这样的数。用反正法可以证明!
最简单的思路应该就是先进行排序了吧,然后由于题目中确定此数一定存在。因此次数一定出现在排序后的数组中的正中间的位置,即n/2处。
那么此题就可以转换成怎么才能在最短时间内对数组进行排序。众所周知,快速排序的平均性能是最好的,因此我们在使用快排进行排序,然后取出n/2位置的数,此数就是我们所求的答案了。
如果到这里就结束了,我也懒得写这篇博客了。。。。
快排平均时间复杂度是N*logN, 就不说最坏情况是N*N了。那么有没有更快的思路呢?
其实是有的,至少我知道有两种做法可以实现O(N)的时间复杂度
第一种思路是,采用快速排序的partition函数进行的。partition是找一个key值,然后小于key值得放在左边,大于等于key值放在右边。
如果key值的位置小于n/2时,则在左半部分继续partition;如果key值的位置大于n/2时, 则在右半部分继续partition;如果key == n/2,则表示该key值就是所要找的数。
第二种思路是比较巧妙的。根据要查找的数的性质,我们知道所要找的数比其他数都多,因此我们可以分成两类,一类是所要找的数,另一类就是其余数。每次取一个数,当计数器为0时,将该数存入临时变量temp中;当计数器不为0时,若与temp值一致,则计数器加一,否则减一。具体实现如下:
package com.easy;

public class MajorityElement
{

public static void main(String[] args)
{
// TODO Auto-generated method stub
int []nums = {10, 9, 9, 9, 10};//{1, 2, 3, 4, 2, 2, 2};
System.out.println(majorityElement(nums));
}

public static int majorityElement(int[] nums) {
int temp = nums[0];
int cnt = 1;
for (int i = 1; i < nums.length; i++)
{
if (cnt == 0)
{
temp = nums[i];
cnt++;
}else
{
if (temp != nums[i])
{
cnt--;
}else
{
cnt++;
}
}
// System.out.println(temp+ " " + cnt);
}
return temp;
}
}


这个实现的时间复杂度就是O(N)了,也不需要进行排序操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 快速排序 leetcode