• 【剑指offer】数组中只出现一次的数字


    数组中只出现一次的数字

    题目描述

    一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

    思路

    我们知道两个相同的数字异或的结果为0,所以如果只有一个出现一次的数字,就可以让所有的数字进行异或,那么最后得到的数字就是只出现一次的数字。

    现在问题变成了有两个数字,同样我们可以让所有数字异或,最终的结果是两个只出现一次的数字的异或的结果。我们可以找到这个结果的二进制位上为1的下标,例如异或的结果为4,那么对应到二进制上是100,所以在第三位上着两个数字不相同,一个为1,一个为0,所以我们可以以二进制中第三位为区分标准,把数组划分成两份,二进制的第三位为1和为0。

    当得到两个小组后,我们知道这两个只出现一次的数已经被分开了,这样就回到最原始的问题上了,问题迎刃而解。代码如下。

    代码

    #include <iostream>
    #include <vector>
    using namespace std;
    
    void FindNumsAppearOnce(vector<int> data,int num1,int num2);
    int FindFirstOneBit(int target);
    bool isOneBit(int target, int index);
    
    void FindNumsAppearOnce(vector<int> data,int num1,int num2) {
        if (data.size() < 2)
            return;
        int res = data[0];
        for(int i=1;i<data.size();i++)
            res ^= data[i];
        int first = FindFirstOneBit(res);
        num1 = num2 = 0;
        for (int i = 0; i < data.size(); ++i) {
            if(isOneBit(data[i], first-1))
                num1 ^= data[i];
            else
                num2 ^= data[i];
        }
    
        cout << num1<<endl;
        cout<<num2 <<endl;
    }
    
    int FindFirstOneBit(int target) {
        int ret = 0;
        while((target ^ 1) == 0 && ret < 8* sizeof(int)) {
            target = target >> 1;
            ret++;
        }
        return ret;
    }
    
    bool isOneBit(int target, int index) {
        target = target >> index;
        return target & 1;
    }
    
    
    int main() {
    
        vector<int> data = {1,1,2,2,3,4,3,5};
        FindNumsAppearOnce(data, 0, 0);
        return 0;
    }
    

    结果

    5

    4

  • 相关阅读:
    关闭程序 提示 C#
    瀑布流判断加载分页条件
    移动端模板
    js 获取地址栏参数
    原生js倒计时和显示当前时间
    根据日期判断事件
    多个tab切换传参
    h5的api dom全屏展示
    git配置ssh
    git创建分支与合并分支
  • 原文地址:https://www.cnblogs.com/puyangsky/p/6535584.html
Copyright © 2020-2023  润新知