一、题目信息
-
比特位计数
-
https://leetcode.cn/problems/single-number-ii/description/
给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。
示例 1:
输入:nums = [2,2,3,2]
输出:3
示例 2:
输入:nums = [0,1,0,1,0,1,99]
输出:99
提示:
1 <= nums.length <= 3 * 104
-231 <= nums[i] <= 231 - 1
nums 中,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次
二、题解1:朴素解法
1、解题思路:map计数法
-
使用map数据结构记录每个数字出现的次数,其中key为数字num,value为该数字出现的次数count
-
最后找出count为1对应的key值
2、图解

3、代码实现
int singleNumber(vector<int> &nums)
{
// 创建一个32长度的int数组
std::map<int, int> map;
int res = 0;
// 对数组中每个数字,都去找到他们二进制对应32个位置的数值,并累加起来
for (int i = 0; i < nums.size(); i++)
{
int num = nums[i];
if (map.find(num) == map.end()) // 不存在
{
map[num] = 1;
}
else
{
map[num] = map[num] + 1;
}
}
for (auto it : map)
{
if (it.second == 1)
{
return it.first;
}
}
return res;
}
4、时间复杂度
-
NlogN ,底层数据结构使用的是map,通过map进行数据的插入与查询,他的时间复杂度为NlogN
三、题解2:位运算累加和
1、解题思路
-
遍历数组中的每个数字,获取数字对应二进制位置的值,并累加到一个int[32]数组中去,
-
接着对每个位置的二进制个数与3取余数,最后得到的二进制就是那个单独出现的数字
2、图解

3、代码实现
int singleNumber(vector<int> &nums)
{
// 创建一个32长度的int数组
vector<int> arr(32, 0);
int res = 0;
// 对数组中每个数字,都去找到他们二进制对应32个位置的数值,并累加起来
for (int i = 0; i < nums.size(); i++)
{
int num = nums[i];
for (int j = 0; j < 32; j++)
{
arr[32 - j - 1] += (num >> j) & 1;
}
}
// 取出32位数组中每个位置的二进制累加和,与3相除取余数,
for (int j = 0; j < 32; j++)
{
res = (res << 1) + (arr[j] % 3);
}
return res;
}
4、时间复杂度
-
N
520



被折叠的 条评论
为什么被折叠?



