• 《剑指offer》第五十六题(数组中只出现一次的两个数字)


    // 面试题56(一):数组中只出现一次的两个数字
    // 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序
    // 找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
    
    #include <iostream>
    
    unsigned int FindFirstBitIs1(int num);
    bool IsBit1(int num, unsigned int indexBit);
    
    void FindNumsAppearOnce(int data[], int length, int* num1, int* num2)
    {
        if (data == nullptr || length < 2)//判断边界
            return;
    
        int resultExclusiveOR = 0;
        for (int i = 0; i < length; ++i)//讲究,0异或任何一个数就等于那个数,三个数连续异或,若两个一样的,会抵消,剩下的值就是第三个数
            resultExclusiveOR ^= data[i];
    
        unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);//求出这组数里,某位为1
    
        *num1 = *num2 = 0;
        for (int j = 0; j < length; ++j)//以此位为标志,分为两个数组,每个数组都有且只有一个数字,其个数为奇数
        {
            if (IsBit1(data[j], indexOf1))
                *num1 ^= data[j];
            else
                *num2 ^= data[j];
        }
    }
    
    // 找到num从右边数起第一个是1的位
    unsigned int FindFirstBitIs1(int num)
    {
        int indexBit = 0;
        while (((num & 1) == 0) && (indexBit < 8 * sizeof(int)))
        {
            num = num >> 1;//向右移1位
            ++indexBit;
        }
    
        return indexBit;
    }
    
    // 判断数字num的第indexBit位是不是1
    bool IsBit1(int num, unsigned int indexBit)
    {
        num = num >> indexBit;
        return (num & 1);
    }
    
    // ====================测试代码====================
    void Test(const char* testName, int data[], int length, int expected1, int expected2)
    {
        if (testName != nullptr)
            printf("%s begins: ", testName);
    
        int result1, result2;
        FindNumsAppearOnce(data, length, &result1, &result2);
    
        if ((expected1 == result1 && expected2 == result2) ||
            (expected2 == result1 && expected1 == result2))
            printf("Passed.
    
    ");
        else
            printf("Failed.
    
    ");
    }
    
    void Test1()
    {
        int data[] = { 2, 4, 3, 6, 3, 2, 5, 5 };
        Test("Test1", data, sizeof(data) / sizeof(int), 4, 6);
    }
    
    void Test2()
    {
        int data[] = { 4, 6 };
        Test("Test2", data, sizeof(data) / sizeof(int), 4, 6);
    }
    
    void Test3()
    {
        int data[] = { 4, 6, 1, 1, 1, 1 };
        Test("Test3", data, sizeof(data) / sizeof(int), 4, 6);
    }
    
    int main(int argc, char* argv[])
    {
        Test1();
        Test2();
        Test3();
        system("pause");
        return 0;
    }
  • 相关阅读:
    谈谈golang的netpoll原理(一)
    谈谈高并发秒拍系统架构设计
    Go项目实战:打造高并发日志采集系统(十)
    Go项目实战:打造高并发日志采集系统(九)
    Go项目实战:打造高并发日志采集系统(八)
    Go项目实战:打造高并发日志采集系统(七)
    海思3520v300NDI协议移植
    支持ssl的boa服务器
    多字节和宽字节互相转换
    C++实现websocket协议通讯
  • 原文地址:https://www.cnblogs.com/CJT-blog/p/10543964.html
Copyright © 2020-2023  润新知