Single Number III
来源:互联网 发布:mac 导入照片 位置 编辑:程序博客网 时间:2024/06/04 01:03
题目描述:
给出2*n + 2个的数字,除其中两个数字之外其他每个数字均出现两次,找到这两个数字。
样例 给出 [1,2,2,3,4,4,5,3],返回 1和5
挑战 O(n)时间复杂度,O(1)的额外空间复杂度
题目分析:
1:这道题利用了异或位运算的一个性质,即:一个数与自身异或的结果为0。我们只需遍历数组中的每一个元素,并将其进行异或。因为,异或满足交换律,所以最终的异或结果将仅仅包含只出现一次的那个数。
如:1 ^ 2 ^ 2 ^ 1 ^3 ^ 4 ^ 3 = 1 ^ 1 ^ 2 ^ 2 ^ 3 ^ 3 ^ 4 = 4
2:如果对所有元素进行异或操作,最后剩余的结果是出现次数为1次的两个数的异或结果,此时无法直接得到这两个数具体的值。但是,因为这两个数一定是不同的,所以最终异或的值至少有一个位为1。我们可以找出异或结果中第一个值为1的位,然后根据该位的值是否为1,将数组中的每一个数,分成两个部分。这样每个部分,就可以采用Sing number I中的方法得到只出现一次的数。
3:假设我们要找的这两个数为 a, b, 而 x = a ^ b。
首先,a 肯定不等于 b,那么说明它们的二进制位一定是不完全相同的,所以 x 肯定不为 0。
也就是说,a 与 b 一定存在“某一位”,使得在它们中的某个数中是 0,而在另一个数中是 1,这是他们之间的一个差别。
我们可不可以利用这个差别来把这两个数从 x 中揪出来呢?
是可以的。
利用这个差别,我们可以将整个 nums 集合分成两个集合。一个集合中是这 “某一位” 为 0 的在nums中的所有数,假设为集合 A。而另一个集合是这 “某一位” 为 1 的在nums中的所有数。假设 a 的这 “某一位” 是 0 ,b 的 这个“某一位”是1,那么显然 a 在集合 A 中,b 在集合 B 中,这样问题就完全转化成了与 I 一样的两个子问题,于是可以得解。
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
int getFirstBit1(int num){
int index = 0;
while((num & 1) == 0){
num = num >> 1;
index ++;
}
return index;
}
bool isBit1(int num,int index){
num = num>>index;
return (num & 1)==1;
}
vector<int> singleNumber(vector<int>& nums) {
if(nums.size()<3)
return nums;
vector<int> result;
vector<int> nums1;
vector<int> nums2;
int sum = 0;
for(int i = 0 ;i<nums.size();i++){
sum ^= nums[i];
}
int index = getFirstBit1(sum);
for(int i = 0 ;i<nums.size();i++){
if(isBit1(nums[i],index)){
nums1.push_back(nums[i]);
}else {
nums2.push_back(nums[i]);
}
}
sum = 0;
for(int j =0;j<nums1.size();j++){
sum ^= nums1[j];
}
result.push_back(sum);
sum = 0 ;
for(int j =0;j<nums2.size();j++){
sum ^= nums2[j];
}
result.push_back(sum) ;
return result;
}
};
int main() {
return 0;
}
- Single Number III
- Single Number III
- [LeetCode] Single Number III
- [leetcode] Single Number III
- 260 Single Number III
- [Leetcode]Single Number III
- [leetcode] Single Number III
- Leetcode: Single Number III
- 260 Single Number III
- LeetCode || Single Number III
- Single Number III
- Single Number III
- Single Number III
- [刷题]Single Number III
- Single Number III
- Leetcode75: Single Number III
- leetCode---Single Number III
- *LeetCode-Single Number III
- 二叉排序树删除结点
- Scala数组操作
- 字符串匹配的KMP算法
- ZigZag Conversion
- Ubuntu搭建boa服务器
- Single Number III
- Integer to Roman (罗马数字转换)
- Linked List Cycle
- Unique Binary Search Trees
- Best Time to Buy and Sell Stock II
- Single Number II
- 计算树中值最大路径
- Populating Next Right Pointers in Each Node
- Generate Parentheses