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

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)了,也不需要进行排序操作。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值