260. 只出现一次的数字 III 的 两种解法(详细复习位运算解法)
Posted 寂静花开
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了260. 只出现一次的数字 III 的 两种解法(详细复习位运算解法)相关的知识,希望对你有一定的参考价值。
260. 只出现一次的数字 III
做的时候感觉位运算根没学一样。。。
趁这道题恶补一下。
题目
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
进阶:你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
示例 1:
输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。
示例 2:
输入:nums = [-1,0]
输出:[-1,0]
示例 3:
输入:nums = [0,1]
输出:[1,0]
提示:
2 <= nums.length <= 3 * 104
-2^31 ^<= nums[i] <= 231 - 1
除两个只出现一次的整数外,nums 中的其他数字都出现两次
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-number-iii
解题思路
法一:暴力哈希表
这一种,就很常规,当遇见字符串数组的时候也可以用。
先是创建了一个哈希表。利用哈希表存当前值,和当前值出现的次数。
之后遍历HashMap, 将答案放入数组。
法二:利用位运算
再复习一下位运算的知识点:
位运算知识点快速复习
首先,我们根据异或的知识可以知道,两个相同的数异或后为0。
所以将数组遍历且计算所有元素异或后,得到的数是那两个只出现一次元素的异或和sum
。如果遍历后结果为零,就证明所有元素都出现过两次。
在 136. 只出现一次的数字 这到题中,直接遍历异或就是答案(因为只出现一次的数字只有一个)
例:1 1 2
1^1 = 0,
0^2 = 000 ^ 010 = 010 = 2
所以再这道题中,我们可以想到,把这两个数字按二进制某一位是1是0,将所有数字分到两组。那么每一组的异或和就是一个只出现一次的数字。
java代码
法一
//法一
class Solution {
public int[] singleNumber(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums){
map.put(num, map.getOrDefault(num, 0) + 1);
}
int[] res = new int[2];
int i = 0;
for (int num : nums) {
if (map.get(num) == 1) {
res[i++] = num;
}
}
return res;
}
}
法二
//法二
class Solution {
public int[] singleNumber(int[] nums) {
int sum = 0;
for (int num : nums){
sum ^= num;
}
int k = sum & -sum;
int res1 = 0;
int res2 = 0;
for (int num : nums){
if((num & k) ==0){
res1 ^= num;
}
else{
res2 ^= num;
}
}
int[] ans = {res1, res2};
return ans;
}
}
以上是关于260. 只出现一次的数字 III 的 两种解法(详细复习位运算解法)的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode Java刷题笔记—260. 只出现一次的数字 III