• 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;
        }
    };
  • 相关阅读:
    136. Single Number
    125. Valid Palindrome
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    119. Pascal's Triangle II
    118. Pascal's Triangle
    集中式架构与分布式架构比较-copy
    分布式id产生-copy
    MySQL 5.7数据库参数优化-copy
    23个适合Java开发者的大数据工具和框架-copy
  • 原文地址:https://www.cnblogs.com/ymjyqsx/p/10753673.html
Copyright © 2020-2023  润新知