给你一个整数数组 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
-231 <= nums[i] <= 231 - 1
nums
中的其他数字都出现两次- class Solution:
- def singleNumber(self, nums: List[int]) -> List[int]:
- n=len(nums)
- if n==2:
- return nums
-
- xor_result = 0
-
- for num in nums:
- xor_result ^= num
-
- flag = xor_result & -xor_result
-
- num1, num2 = 0, 0
- for num in nums:
- if num & flag:
- num1 ^= num
- else:
- num2 ^= num
-
- return [num1, num2]
今天的每日一题比较有意思,而且也学到了新东西,所以记录一下。
每次看到题都想用哈希表来做,但是不满足题目要求,所以满足题目要求的只能往位运算方向来思考,感谢灵老师提供的思路:
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
我也按照灵老师的思路复现了代码,并且记录一下新学到的东西:
xor_result & -xor_result
是通过位运算获取 xor_result
最右边的 1 所在的位(也就是最低位的 1),这种技巧常用于获取二进制数中最右边的 1 的位置。
xor_result
是通过对数组中所有元素进行异或运算得到的结果。-xor_result
表示取 xor_result
的二进制的反码加 1。这实际上就是取反后再加 1,这样可以将 xor_result
中最右边的 1 以及所有低位的 0 变为 1,而其他位变为 0。xor_result & -xor_result
就是对 xor_result
和 -xor_result
进行按位与运算,得到的结果就是 xor_result
中最右边的 1 所在的位为 1,其他位为 0。这种操作是为了找到 xor_result
中最右边的 1 所在的位置,以便区分两个子数组。