leetcode260. Single Number III

来源:互联网 发布:安卓ble蓝牙通信源码 编辑:程序博客网 时间:2024/06/10 08:19

先说第一种题

题目:

Given an array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

我的解法:对数组排序,两个两个跳着比较直到找到不等的,时间复杂度O(NlogN)

class Solution {public:    int singleNumber(vector<int>& nums)     {        sort(nums.begin(),nums.end());        int size = nums.size();        if (size == 1)            return nums[0];                    for (int i = 1; i < size; i += 2)            if (nums[i] != nums[i - 1])                return nums[i - 1];                                return nums[size -1];    }};

参考其他解法,知道了这类题考察的是位运算

AC解:

class Solution {public:    int singleNumber(vector<int>& nums)     {        int x = 0;        int size = nums.size();        for (int i = 0; i < size; i++)            x ^= nums[i];        return x;    }};
或者直接 return accumulate(nums.begin(),nums.end(),0,bit_xor<int>());

升级版题目:

Given an array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

用一个数组来存储所有元素每个位上1的个数,模3剩下的就是所有元素此位上的数字

class Solution {public:    int singleNumber(vector<int>& nums)     {        const int length = sizeof(int) * 8;        int count[length];        fill(count,count + length,0);        int size = nums.size();                for (int i = 0 ; i < size; i++)            for (int j = 0; j < length; j++)            {                count[j] += (nums[i] >> j) & 0x1;                count[j] %= 3;            }                int result = 0;        for (int i = 0; i < length; i++)            result += (count[i] << i);                return result;    }};

再次升级版:

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].

AC解: 解法分两步,精妙之处在于diff

1.对所有数字进行异或运算,diff的值为要求的两个数进行异或运算的结果,再diff &= -diff,得到的结果为diff中从右到左第一个位为1的的数,例如0x1010 其负数为0x0110,与运算的结果为0x0010。并且可以知道这两个数的此位必定一个为0一个为1

2.根据此位是否为1将数分为了两部分,分别对两部分进行异或运算,因为相同的两个数异或操作后结果为0,所以两组数的最终结果就是所要求得的数

class Solution {public:    vector<int> singleNumber(vector<int>& nums)     {        //数组中所有位进行异或,diff为所求的两个数异或的结果        int diff = accumulate(nums.begin(),nums.end(),0,bit_xor<int>());        //取得从右到左第一个为1的位,并且这两个数的此位一定不同        diff &= -diff;                vector<int> ans(2,0);        //分离两个数        for (auto a : nums)            if (a & diff)//当前元素的此位为1                ans[0] ^= a;        //不算这两个数,当前位为0或1的数肯定是成对出现的            else                    //相同的数异或操作后为0                ans[1] ^= a;                return ans;    }};




0 0