leetcode(260)数组之Single Number III()同剑指offerT40

来源:互联网 发布:天涯明月刀 知乎 编辑:程序博客网 时间:2024/06/06 15:17
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:The order of the result is not important. So in the above example, [5, 3] is also correct.Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?   注意 Note 中的第一个条件:The order of the result is not important.,这个条件非常重要,这关系到算法的正确性。 //方法一:通过Single Number我们知道如何求一个数组中只出现一次的一个数字;本题要求求数组中//        两个出现一次的数字;可以利用Single Number的求解算法;//从头到尾依次异或数组中每一个数字,得到的结果为两个只出现一次的数字异或结果。因为其他数字都出现了//两次,在异或中全部抵消了。由于这两个数字肯定不一样,则异或结果肯定不为0,即这个结果数字的二进制//表示中至少有一位为1。在结果数字中找到第一个为1的位的位置,记为第n位。以数字的第n位是不是1,将原//数组分成两个子数组,第一个字数组中的第n位都为1,,第二个子数组的第n位都为0;由于分数组的标准是第//n位是不是1,则出现两次的数字肯定被分到同一个子数组中去,因为两个相同的数字的任一位都是相同的;两//个子数组中各包含了一个只出现1次的数字,则问题化为Single Number;vector<int>singleNumber(vector<int>&nums){    vector<int>results;    int n=nums.size();    //if(n<5)    //  return results;    int resultExclusiveOR=0;    for(int i=0;i<n;++i)    {        resultExclusiveOR^=nums[i];    }    int indexBit=0;    while(((resultExclusiveOR&1)==0)&&(indexBit<(8*sizeof(int))))        //防止溢出    {        resultExclusiveOR>>=1;        ++indexBit;    }    int flag=(1<<indexBit);    int num1=0;    int num2=0;    for(int i=0;i<n;++i)    {        if(nums[i]&flag)        num1^=nums[i];        else        num2^=nums[i];    }        results.push_back(num1);    results.push_back(num2);    return results;}  //方法二:(思想同方法一)假设这两数分别为a,b。将数组中所有元素异或之后结果为x,因为a!=b,//         所以x=a^b,且x!=0;判断x中位为1的位数,只需要知道某一位为1的位数k,如:00101100,//         k可以取2,3或者5,,然后将x与数组中第k位为1的数进行异或,异或结果就是a或b中的一个,//         然后用x异或,就可以求出另外一个。vector<int>singleNumber(vector<int>nums){    vector<int>result;    int n=nums.size();    int xOR=0;    for(int i=0;i<n;i++)    {        xOR^=nums[i];    }    int num1=xOR;    int num2=xOR;    int indexBit=0;    while(((xOR&1)==0)&&indexBit<8*sizeof(int))    {        xOR>>=1;        ++indexBit;    }        for(int i=0;i<n;i++)    {        if((nums[i]>>indexBit)&1)            num1^=nums[i];    }    num2^=num1;    result.push_back(num1);    result.push_back(num2);    return result;}

0 0
原创粉丝点击