[每日一题]6:求数组中出现超过一半的数字

76 篇文章 1 订阅
51 篇文章 0 订阅


题目描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

题解思路

方法一:排序
  1. 对数组进行排序
  2. 数字出现频率超一半的,一定是数组的中位数
  3. 但是数组的中位数不一定是频率出现最高的数,需要判断一下这个数字出现的频率是否超过整个数组长度的一半
  4. 如果这个数字出现频率超过数组长度的一半,则找到这个数字;否则没有这个数字,返回0

C代码如下:

//快速排序算法
void quickSort(int * a, int left, int right){
	int i, j, tmp, t;
	if (left > right){
		return;
	}
	tmp = a[left];
	i = left;
	j = right;
	while (i != j){
		while (a[j] >= tmp && i < j) --j;
		while (a[i] <= tmp && i < j) ++i;
		if(i < j){
			t = a[i];
			a[i] = a[j];
			a[j] = t;
		}
	}
	a[left] = a[j];
	a[j] = tmp;
	quickSort(a, left, j - 1);
	quickSort(a, j + 1, right);
}

//数组再经过排序后,数字出现频率超一半的,一定是数组的中位数
int checkMoreThanHalf(int * arr){
	int len = sizeof(arr) / sizeof(arr[0]);
	quickSort(arr, 0, len - 1);
	int mid = len / 2;
	int result = arr[mid];
	if (!checkIsMoreThanHalf(arr, result, len))
	{
		result = 0;
	}
	return result;
}

//判断一下这个数字出现的频率是否超过整个数组长度的一半
int checkIsMoreThanHalf(int * arr, int result, int len){
	int i;
	int count = 0;
	
	for (i = 0; i < len; i++){
		if (arr[i] == result)
			++count;
	}
	if (count >(len - 1) / 2)
		return 1;
	else
		return 0;
}

C++代码题解

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int num = nums[nums.size()/2];
        if(nums.size()/2 < count(nums.begin(), nums.end(), num)){
            return num;
        }
        return 0;
    }
};
方法二:哈希表

这个方法最简单,用哈希表记录每个数字出现的次数,最后看哪个数字次数超过一半就行了。

时间复杂度 O(n) ,空间复杂度 O(n) 。

代码实现:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int n = nums.size();
        unordered_map<int, int> mp;
        for (auto x : nums) mp[x]++;
        for (auto [k, v] : mp) {
            if (v > n/2) return k;
        }
        return 0;
    }
};
方法三:摩尔投票

这个方法我一开始也想到了,但是没有想到这竟然有理论解释,而且是大名鼎鼎的摩尔投票算法。

它的主要步骤是这样的:

  1. 初始化两个变量, cand 表示候选人,cnt 表示赞同它的票数。
  2. 如果 cnt = 0,那么 cand 就设置为当前的数字。
  3. 如果 cand 等于当前数字,那么票数 cnt 加一,否则票数减一。
  4. 最后 cand 就是得票超过一半的众数。

代码实现:

class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> v) {
        int num = v[0], count_i = 1;
        for(int i = 1; i < v.size(); i++){
            if(v[i] == v[i-1]) count_i++;
            else {
                if(count_i <= 1) num = v[i];
                else count_i--;
            }
        }
        if (v.size() / 2 < count(v.begin(), v.end(), num)) return num;
        return 0;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值