34.leetcode题目260: Single Number III

题目:

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

For example:

Given nums = [1, 2, 1, 3, 2, 5], return [3, 5].

Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
分析:考虑位运算。

主要思想:两个只出现一次的数字必定有某一位不同

一、循环(for(int i = 0; i < 31; i++)),根据第i位是否为1将数据分成两组,再判断两组的数目是否为奇数,为奇数则第i位即这两个数第一位不同的位;

二、现将所有数据进行异或,那么结果为这两个数字的异或,找到这个结果中第一位不位0的位,该位即两个数字第一位不同的位,然后再将所有数据根据该位是否为1分成两组,两个数字即分别位于一组,各组异或结果即这两个数字。

class Solution {
public:
// Is the indexBit bit of num 1?   
bool IsBit1(int num, unsigned int indexBit)  
{  
    num = num >> indexBit;  
    return (num & 1);   //num&1<<indexBit        
}  
// Find two numbers which only appear once in an array   
// Input: data - an array contains two number appearing exactly once,   
void FindNumsAppearOnce(vector<int>& data, int length, int &num1, int &num2)  
{  
    if (length < 2)    return;  
	for(int i = 0; i < 31; i++){ //32位平台上,int只有32位 
	num1 = num2 = 0;
       int tempA =0,tempB =0,countA=0,countB=0 ;
        for(int j = 0; j < length; j++){//遍历数组   
            if(IsBit1(data[j], i)){  //第i位只有是1和不是1两种情况,两个只出现奇数次的数必定有某一位不同
                num1 ^= data[j];
                countA++; 
            }
			else{  
                num2 ^= data[j]; 
                countB++; 
            }  
        }
        if((countA & 0x1)&&(countB & 0x1)){//奇数   只有两组数都为奇数时,才说明两个只出现一次的数字被分在了不同的组
				break;   
			}  
		}  
} 
    vector<int> singleNumber(vector<int>& nums) {
        int x,y;
        vector<int> res;
        FindNumsAppearOnce(nums,nums.size(),x,y); 
        res.push_back(x);
        res.push_back(y);
        return res;
    }
};


unsigned int FindFirstBitIs1(int num)  
{  
    int indexBit = 0;  
    while (((num & 1) == 0) && (indexBit < 32))  
    {  
        num = num >> 1; 
        ++ indexBit;  
    }  
    return indexBit;  
}  


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值