只出现一次的数字(暴力、哈希查重、异或运算)
目录
一.题目
题目解析
题目链接
二.解题过程
俗手(暴力:数组模拟哈希表)
思路
代码示例
提交情况
本手:哈希查重
思路
代码示例
提交情况
妙手:异或运算
思路
代码示例
提交情况
作者的个人gitee
作者的算法讲解主页▶️
每日一言:“行到水穷处,坐看云起时🌸🌸”
一.题目
只出现一次的数字
给定一个非空整数数组 nums
,除了某个元素只出现一次以外,其余每个元素均出现两次。请找出那个只出现一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
示例 | 输入 | 输出 |
---|---|---|
示例 1 | nums = [2,2,1] | 1 |
示例 2 | nums = [4,1,2,1,2] | 4 |
示例 3 | nums = [1] | 1 |
提示
-
1 <= nums.length <= 3 * 10^4
-
-3 * 10^4 <= nums[i] <= 3 * 10^4
-
除了某个元素只出现一次以外,其余每个元素均出现两次
题目解析
查重问题除了暴力解法最先想到的肯定是哈希,但这道题似乎另有妙手...?
题目链接
136. 只出现一次的数字 - 力扣(LeetCode)
二.解题过程
俗手(暴力:数组模拟哈希表)
-
思路
题目要求找到只出现一次的元素,关于查重的问题,我们很轻易地就能想到创建一个哈希表来记录每个元素出现的次数。但此题不用真正创建一个unordered_map,我们可以用数组来模拟哈希表。需要注意的是:虽然哈希查找的时间复杂度较低,但此题数组的空间开销较大,也会导致运行时间增加。
时间复杂度:O(n)。
-
代码示例
class Solution {
public:int singleNumber(vector<int>& nums) {//创建一个哈希表//元素值充当索引,其数据范围是-3*(10^4)~3*(10^4),可能是负数//所以我们要创建一个(2*nums.size()+1)大小的数组来存储元素的出现次数vector<int> hash(60002);//遍历数组for (int i = 0; i < nums.size(); i++) { //将数组内元素出现的次数存储在hash表中//数组下标不能为负数,所以我们要+30001,将数组索引全部转化为正数区间hash[nums[i] + 30001]++; }//遍历哈希表,找到出现次数为1的元素,并返回for (int i = 0; i < nums.size(); i++) {if (hash[nums[i] + 30001] == 1) {return nums[i]; }}return 0; }
};
-
提交情况
编辑
本手:哈希查重
-
思路
创建一个unodered_map记录数组元素出现的个数,遍历哈希表找到次数为1的元素。返回索引。
时间复杂度:O(n)
-
代码示例
class Solution
{
public:int singleNumber(vector<int>& nums) {//创建哈希表unordered_map<int, int> hash;
//创建变量存储结果int res = 0;
//遍历数组for (int key : nums) {//如果key不存在于hash中,则将他的次数初始化为1if (hash.find(key) == hash.end()) {hash[key] = 1;}
//存在的话则次数++else {hash[key]++;}}
//遍历哈希表for (auto& pair : hash) {//如果出现的次数是1则将索引赋给res,之后breakif (pair.second == 1) {res = pair.first;break;}}//返回结果return res;}
};
-
提交情况
妙手:异或运算
-
思路
方法一、二的时间复杂度较高,因此我们用一种更快的算法来解决。
由题目信息可知,n个元素中有(n-1)个元素都出现了两次,只有1个数据出现了一次,要求我们找到出现1次的数字。这就不妨联想到异或运算的性质。
由异或运算的运算性质可知:一个数与自己异或的值是0,而0与任何非0数字异或都是非0数字本身,且异或运算满足交换律与结合律。
那么我们就可以遍历数组,使数组内元素相互异或,在交换律与结合律的基础上可以推出最后出现的数字一定就是只出现一次的数字。
时间复杂度:O(1)。
-
代码示例
class Solution
{
public:int singleNumber(vector<int>& nums) {int ret = 0;//遍历数组,使数组内所有元素相互异或,得到只出现一次的数字。for(auto x:nums){ret = ret^x;}return ret;}
};
-
提交情况