剑指 Offer 56 - II. 数组中数字出现的次数

II数组中数字出现的次数


题目链接: II数组中数字出现的次数

有关题目

在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。
请找出那个只出现一次的数字。
示例 1:

输入:nums = [3,4,3,3]
输出:4
示例 2:

输入:nums = [9,1,7,9,7,9,7]
输出:1
限制:

1 <= nums.length <= 10000
1 <= nums[i] < 2^31

题解

1、排序

int cmp_int(const void* e1,const void* e2)
{
    return *(int*)e1 > *(int*)e2;//这边最好是用逻辑判断符,不然会溢出
}
int singleNumber(int* nums, int numsSize){
    qsort(nums,numsSize,sizeof(int),cmp_int);
    for (int i = 0;i < numsSize; i += 3)
    {
        if (i == numsSize - 1 || nums[i] != nums[i + 1])
            return nums[i];
    }
    return -1;
}

时间复杂度:O(NlogN)
空间复杂度:O(1)
在这里插入图片描述
2、模拟实现哈希表
代码一:

typedef struct hashTable{
    int key;
}hash;

void insertNums(hash* Hash, int i , int key){
    Hash[i].key = key;
}
int findNums(hash* Hash, int target, int n){
    int cnt = 0;
    for (int i = 0; i < n; ++i){
        if (Hash[i].key == target){
            ++cnt;
        }
    }
    return cnt;
}
int singleNumber(int* nums, int numsSize){
    int n = numsSize;
    hash Hash[n];
    for (int i = 0; i < n; ++i){
        insertNums(Hash, i, nums[i]);
    }

    int ans = 0;
    for (int i = 0; i < n; ++i){
        if (findNums(Hash, nums[i], n) == 1){
            ans = nums[i];
            break;
        }
    }
    return ans;
}

代码二:

typedef struct hashTable{
    int key, val;
    UT_hash_handle hh;
}hash;

int singleNumber(int* nums, int numsSize){
    hash* HashTable = NULL;
    int n = numsSize;
    for (int i = 0; i < n; ++i){
        hash* tmp;
        HASH_FIND_INT(HashTable, &nums[i], tmp);
        if (tmp == NULL){
            tmp = (hash*)malloc(sizeof(hash));
            tmp->key = nums[i], tmp->val = 1;
            HASH_ADD_INT(HashTable, key, tmp);
        }
        else {
            tmp->val++;
        }
    }

    int ans = 0;
    hash* iter, *tmp;
    HASH_ITER(hh, HashTable, iter, tmp){
        if (iter->val == 1){
            ans = iter->key;
            break;
        }
    }
    return ans;
}

C++版本
代码一:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        // 创建哈希表,键代表数字,值代表数字出现的次数
        unordered_map<int, int> map;

        // 遍历原数组,统计每个数字出现的次数
        for (int& num : nums) map[num]++;

        // 初始化哈希表迭代器
        auto iter = map.begin(); 
        while (iter != map.end()) {
            /*
            *  遍历哈希表,
            *  若某一位值为1,说明该位上键代表的数字就只出现一次
            *  将其返回即可
            */
            if (iter->second == 1) return iter->first;
            ++iter;
        }
        return -1;
    }
};

代码二:

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        unordered_map<int, int> freq;
        for(auto& num : nums){
            ++freq[num];
        }
        int ans = 0;
        for (auto [num, occ] : freq){
            if (occ == 1){
                ans = num;
                break;
            }
        }
        return ans;
    }
};

在这里插入图片描述

3、统计二级制位对应1的个数

int singleNumber(int* nums, int numsSize){
    int Result = 0;
    //int 32 个bit 位
    for(int i = 0; i < 32; i++)
    {
        int Onecount = 0;//统计1的个数,每次置零
        for(int j = 0; j < numsSize; j++)
        {
            //nums[j] 右移i 个位置 统计1的个数
            Onecount += (nums[j] >> i) & 1; 
        }
        //含有单身狗的那个数字这位为1
        if (Onecount % 3 == 1)
        Result |= 1 << i;//左移标记这个二级制位置为1
    }
    return Result;
}
如果只有一个数字出现一次,其他数字都出现奇数次,我们可以用下面代码来解决。
只需将上面的Onecount % 3 改为 Onecount % n

在这里插入图片描述
这种解法在LeetCode中只出现一次的数字II
会出现下图
在这里插入图片描述
是因为
在这里插入图片描述
来源官方题解
只要将上面的int Onecount = 0;改为 long/unsigned int count = 0;就好了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值