10.30 只出现一次的数字

方法一:哈希表

可以使用哈希映射统计数组中每一个元素出现的次数
统计之后再进行遍历。

vector<int> singleNumber(vector<int>&nums){
	unordered_map<int,int> freq;
	for(int num:nums){
		++freq[num];
	}
	vector<int> ans;
	for(const auto& [num,occ]:freq){
		if(occ==1){
			ans.push_back(num);
		}
	}
	return ans;
}

时间复杂度和空间复杂度都是O(n)

方法二:位运算

假设数组 \textit{nums}nums 中只出现一次的元素分别是 x_1和 x_2 。如果把 nums 中的所有元素全部异或起来,得到结果 x,那么一定有:
x=x1⊕x2
​其中 ⊕ 表示异或运算。这是因为nums 中出现两次的元素都会因为异或运算的性质 a⊕b⊕b=a 抵消掉,那么最终的结果就只剩下 x1 和 x2 的异或和。

x 显然不会等于 0,因为如果x=0,那么说明 x_1 = x_2,这样 x_1 和 x_2就不是只出现一次的数字了。因此,我们可以使用位运算x & -x 取出 x 的二进制表示中最低位那个 1,设其为第 l位,那么 x_1和 x_2中的某一个数的二进制表示的第 l 位为 0,另一个数的二进制表示的第l位为 1。在这种情况下,x1​⊕x2的二进制表示的第 l 位才能为 1。

这样一来,我们就可以把 nums 中的所有元素分成两类,其中一类包含所有二进制表示的第 l 位为 0 的数,另一类包含所有二进制表示的第 l 位为 1 的数。可以发现:

1.对于任意一个在数组 nums 中出现两次的元素,该元素的两次出现会被包含在同一类中;

2.对于任意一个在数组nums 中只出现了一次的元素 ,它们会被包含在不同类中。

因此将每一类元素全部异或起来,一类就可以得到x1,另一类就可以得到x2

vector<int> singleNumber(vector<int>& nums){
	int xornum=0;
	for(int num:nums){
		xorsum ^=num;
	}
	//防止溢出 
	int lsb=(xorsum=INT_MIN?xornum:xorsum&(-xorsum));
	int type1=0,type2=0;
	for(int num:nums){
		if (num&lsb){
			type1^=num;
		}
		else{
			type2^=num;
		}
	}
	return {type1,type2};

参考来源

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/single-number-iii/solution/zhi-chu-xian-yi-ci-de-shu-zi-iii-by-leet-4i8e/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值