leetcode 136. Single Number 、 137. Single Number II 、 260. Single Number III(剑指offer40 数组中只出现一次的数字)

136. Single Number

除了一个数字,其他数字都出现了两遍。

用异或解决,亦或的特点:1.相同的数结果为0,不同的数结果为1

            2.与自己亦或为0,与0亦或为原来的数

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        if(nums.empty())
            return -1;
        int res = 0;
        for(int i = 0;i < nums.size();i++)
            res ^= nums[i];
        return res;
    }
};

137. Single Number II 

除了一个数字其他数字都出现了三遍。

因为数字为int型,就有32位。统计每个位上1的个数,然后在每位取余,余下的每位的结果肯定是那个单独的数在每位的结果

https://www.cnblogs.com/grandyang/p/4263927.html

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int res = 0;
        for(int i = 0;i < 32;i++){
            int tmp = 0;
            for(int j = 0;j < nums.size();j++){
                tmp += (nums[j] >> i) & 1;
            }
            res |= (tmp % 3) << i;
        }
        return res;
    }
};

260. Single Number III

有两个数字都只出现了一次,其他数字都出现了两遍。

两个只出现一次的数字在所有位中肯定有一位是不同的,所以亦或出来可以将两个数分开,剩下数无论那一位是否为1肯定都是成对出现,这个时候就可以利用136. Single Number的方法单独处理两个小的数组。findFirstOne其实就是找生成的结果第一个为1的,这个index实际上可以用第几位来表达,比如返回结果3,就是第三位。但我这样处理,直接返回第三位为1,其他位为0,方便之后直接划分数组。

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        vector<int> result;
        if(nums.empty())
            return result;
        int num = 0;
        for(int i = 0;i < nums.size();i++)
            num ^= nums[i];
        int index = findFirstOne(num);
        vector<int> nums1,nums2;
        for(int i = 0;i < nums.size();i++){
            if(nums[i] & index)
                nums1.push_back(nums[i]);
            else
                nums2.push_back(nums[i]);
        }
        int num1 = 0;
        for(int i = 0;i < nums1.size();i++)
            num1 ^= nums1[i];
        result.push_back(num1);
        int num2 = 0;
        for(int i = 0;i < nums2.size();i++)
            num2 ^= nums2[i];
        result.push_back(num2);
        return result;
    }
    int findFirstOne(int num){
        int index = 1;
        int tmp = num & index;
        while(!tmp){
            index = index << 1;
            tmp = num & index;
        }
        return index;
    }
};

 

 

剑指offer40 数组中只出现一次的数字:

错误写法:

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        int length = data.size();
        if(length <= 0)
            return;
        int num = 0;
        for(int i = 0;i < length;i++){
            num = num ^ data[i];
        }
        int number = FindFirst1(num);
        vector<int> data1;
        vector<int> data2;
        for(int i = 0;i < length;i++){
            if(data[i] & number)
                data1.push_back(data[i]);
            else
                data2.push_back(data[i]);
        }
        *num1 = 0;
        *num2 = 0;
        for(int i = 0;i < data1.size();i++){
            *num1 ^= data1[i];
        }
        for(int i = 0;i < data2.size();i++){
            *num2 ^= data2[i];
        }
    }
    int FindFirst1(int num){
        int number = 1;
        int res = num & number;
        while(res == 0){
            number << 1;          //这里并没有对number进行更新
            res = num & number;
        }
        return number;
    }
};

正确写法:

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
        int length = data.size();
        if(length <= 0)
            return;
        int num = 0;
        for(int i = 0;i < length;i++){
            num = num ^ data[i];
        }
        int number = FindFirst1(num);
        vector<int> data1;
        vector<int> data2;
        for(int i = 0;i < length;i++){
            if(data[i] & number)
                data1.push_back(data[i]);
            else
                data2.push_back(data[i]);
        }
        *num1 = 0;
        *num2 = 0;
        for(int i = 0;i < data1.size();i++){
            *num1 ^= data1[i];
        }
        for(int i = 0;i < data2.size();i++){
            *num2 ^= data2[i];
        }
    }
    int FindFirst1(int num){
        int number = 1;
        int res = num & number;
        while(res == 0){
            number = number << 1;
            res = num & number;
        }
        return number;
    }
};

 

posted @ 2019-04-22 22:53  有梦就要去实现他  阅读(216)  评论(0编辑  收藏  举报