• 《剑指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;
    }
  • 相关阅读:
    mac系统下 Homebrew 使用
    mac上安装nginx
    DOMContentLoaded 和 Load 事件 区别(待补充)
    JavaScript运行机制
    理解js事件循环(event loop)
    理解js闭包
    nginx 知识点
    014_mac下的端口查看
    003_如何正确的进入容器
    002_docker构建zookeeper环境
  • 原文地址:https://www.cnblogs.com/CJT-blog/p/10543964.html
Copyright © 2020-2023  润新知