剑指offer-39

数组中出现次数超过一半的数字

解法一:用hashmap存储数字,遍历所有的数字并统计,如果出现超过一半个数的数字则返回,空间O(N),时间O(N)

解法二:如果某数超过一半,排序后该数范围肯定覆盖了中位数,只需要找到中位数是多少即得解,注意,得到中位数后要检查是否超过半数

解法三:如果数组有有一个数字超过一半,意味着这个数字出现的次数超过其他数字,

两个变量,一个存储当前数字,另一个存储次数,如果下个数字与当前相同则加一,不同则减一,如果个数为0则存下一个数字,并置为一

 

解法一:
bool CheckMoreThanHalf(int* numbers, int length, int number)
{
    int times = 0;
    for(int i = 0; i < length; ++i)
    {
        if(numbers[i] == number)
            times++;
    }
 
    bool isMoreThanHalf = true;
    if(times * 2 <= length)
    {
        g_bInputInvalid = true;
        isMoreThanHalf = false;
    }

    return isMoreThanHalf;
}

int MoreThanHalfNum_Solution3(int* numbers, int length)//diy
{
	if (numbers == nullptr || length <= 0) return 0;
	if (length == 1) return *numbers;
	int midPos = length >> 1;
	int Left = 0, Right = length - 1;
	int l = Left + 1, h = Right;
	while (Left<=Right)
	{
		while (l<h)
		{
			while (h > Left && numbers[h] > numbers[Left]) h--;
			while (l < h && numbers[l] <= numbers[Left]) l++;
			if (h>l)
			{
				int temp = numbers[l];
				numbers[l] = numbers[h];
				numbers[h] = temp;
			}
			else break;
		}

		if (Left < h)
		{
			int temp = numbers[Left];
			numbers[Left] = numbers[h];
			numbers[h] = temp;
		}
		if (h == midPos)
		{
			if (!CheckMoreThanHalf(numbers, length, numbers[h]))
				return 0;
			return numbers[h];
		}
		else if (h < midPos)
			Left = h + 1;
		else
			Right = h - 1;
		h = Right;
		l = Left + 1;
	}
	return 0;
}

解法二:
int MoreThanHalfNum_Solution4(int* numbers, int length)//diy
{
	if (numbers == nullptr || length<=0) return 0;
	if (length == 1) return *numbers;

	int halfNum = (length >> 1) + 1;
	std::map<int,int> mMap;
	for (int i = 0;;i++)
	{
		if (i>=length)
			break;
		
		auto it = mMap.find(numbers[i]);
		if (it != mMap.end())
		{
			if (it->second + 1 >= halfNum)
				return it->first;
			else
				it->second++;
		}
		else
			mMap[numbers[i]] = 1;
	}
	return 0;
}

解法三:
int MoreThanHalfNum_Solution5(int* numbers, int length)
{
	if (numbers == nullptr || length <= 0) return 0;
	if (length == 1) return *numbers;
	
	int currNum = 0;
	int cnt = 0;
	for (int i=0;i<length;i++)
	{
		if (currNum==*(numbers+i))
			cnt++;
		else if (currNum != *(numbers + i) && cnt == 0)
		{
			currNum = *(numbers + i);
			cnt++;
		}
		else 
		{
			cnt--;
			if (cnt==0)
				currNum = *(numbers + i);
		}	
	}
	if (!CheckMoreThanHalf(numbers, length, currNum))
		return 0;
	else
		return currNum;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值