Leetcode_229. 多数元素 II

题目链接: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;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值