题目链接: 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;就好了