【剑指 Offer 56 - I. 数组中数字出现的次数 中等】【剑指 Offer 56 - II. 数组中数字出现的次数 II 中等】

【剑指 Offer 56 - I. 数组中数字出现的次数 中等】

1. 题目描述

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

 

示例 1:

输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
示例 2:

输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]

2. 思路

如果对于一个数组,除了【一个】数字之外,其余全都两两成对,那么所有数字异或得到的结果就是那个只出现一次的数字。回到这个题上,如果有两个数字只出现一次,所有数字的异或结果就是这两个数字的异或结果。我们找到这个异或结果中,第一位不为0的bit,按照这个bit是否为0,将nums分成两组,那么每一组都恰好有一个只出现一次的数字,并且其余的数因为成对出现也是只能出现在其中一组。

3. 代码

class Solution {
public:
    int findFirstNonZeroPos(int num) {
        int index = 0;
        while(  (num&1) != 1  && index < 32) {
            index ++;
            num = num >>1;
        }
        return index;
    }
    bool judgePosBitOne(int num, int index) {
        while(index > 0) {
            num = num >> 1;
            --index;
        }
        return (num &1) == 1;
    }
    vector<int> singleNumbers(vector<int>& nums) {
        int len = nums.size();
        vector<int> res(2);
        if(len < 2)
            return nums;
        int XORRes = 0;
        for(int i = 0; i < len ;i ++)
            XORRes ^= nums[i];
        int nonZeroBitPos = findFirstNonZeroPos(XORRes);
        int XORRes1 = 0, XORRes2 = 0;
        for(int i = 0; i < len; i++) {
            if(judgePosBitOne(nums[i], nonZeroBitPos)) {
                XORRes1 ^= nums[i];
            } else {
                XORRes2 ^= nums[i];
            }
        }
        res[0] = XORRes1;
        res[1] = XORRes2;
        return res;
    }
};

 【剑指 Offer 56 - II. 数组中数字出现的次数 II 中等】

1. 题目描述

在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

 

示例 1:

输入:nums = [3,4,3,3]
输出:4
示例 2:

输入:nums = [9,1,7,9,7,9,7]
输出:1

2. 思路

若把所有数字的二进制表示,对应位的值相加,再将对应位的值%3,得到的值(0或者1)就是只出现一次的那个数字的对应二进制位的值。

3. 代码

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

 

posted @ 2021-03-11 16:02  蓦然闻声  阅读(30)  评论(0编辑  收藏  举报