题目链接:229. 多数元素 II - 力扣(LeetCode)
这道题是典型的哈希统计题,这里分享两种解法。
解法一:Hash
typedef struct {
int key;
int cnt;
UT_hash_handle hh;
} HASH_S;
int* majorityElement(int* nums, int numsSize, int* returnSize)
{
int *ans = (int*)malloc(sizeof(int) * numsSize);
*returnSize = 0;
HASH_S *user = NULL; // 哈希声明为空
HASH_S *temp = NULL;
for (int i = 0; i < numsSize; i++) {
HASH_FIND_INT(user, nums + i, temp); // 寻找哈希表里是否存在元素nums[i]
if (!temp) { // 哈希表里不存在该元素,创建并加入表中
HASH_S *new_ele = (HASH_S*)malloc(sizeof(HASH_S));
new_ele->key = nums[i]; // 键值为元素值
new_ele->cnt = 1; // 该元素出现次数为1
HASH_ADD_INT(user, key, new_ele); // 根据键值将新元素加入哈希表
continue;
}
temp->cnt++; // 哈希表中存在该元素,次数++
}
HASH_S *current_usr;
HASH_ITER(hh, user, current_usr, temp) { // 哈希表的for循环,遍历表中的每一个元素
if (current_usr->cnt > numsSize / 3) { // 次数超过(总个数/3),加入ans
ans[(*returnSize)++] = current_usr->key;
}
HASH_DEL(user, current_usr); // 删除哈希表中该结构指针
free(current_usr); // 释放malloc出来的空间
}
return ans;
}
解法二、摩尔投票
在任何数组中,出现次数大于该数组长度1/3的值最多只有两个。简单反证,如果存在3个及以上的值出现次数大于该数组长度1/3,那数组元素总个数将会超过数组长度,这显然很矛盾。
int* majorityElement(int* nums, int numsSize, int* returnSize)
{
int *ans = (int *)malloc(sizeof(int) * 2);
*returnSize = 0;
int vote1 = 0;
int vote2 = 0;
int ele1, ele2;
for (int i = 0; i < numsSize; i++) {
if (vote1 > 0 && nums[i] == ele1) {
vote1++;
} else if (vote2 > 0 && nums[i] == ele2) {
vote2++;
} else if (vote1 == 0) {
ele1 = nums[i];
vote1++;
} else if (vote2 == 0) {
ele2 = nums[i];
vote2++;
} else {
vote1--;
vote2--;
}
}
int cnt1 = 0;
int cnt2 = 0;
for (int i = 0; i < numsSize; i++) {
if (vote1 > 0 && nums[i] == ele1) {
cnt1++;
}
if (vote2 > 0 && nums[i] == ele2) {
cnt2++;
}
}
if (cnt1 > numsSize / 3) {
ans[(*returnSize)++] = ele1;
}
if (cnt2 > numsSize / 3) {
ans[(*returnSize)++] = ele2;
}
return ans;
}