• JZ-C-40


    剑指offer第四十题:数组中只出现一次的数字:一个整型数组里除了两个数字外,其他的数字都出现了两次。

     1 //============================================================================
     2 // Name        : JZ-C-40.cpp
     3 // Author      : Laughing_Lz
     4 // Version     :
     5 // Copyright   : All Right Reserved
     6 // Description : 数组中只出现一次的数字:一个整型数组里除了两个数字外,其他的数字都出现了两次。
     7 //============================================================================
     8 
     9 #include <iostream>
    10 #include <stdio.h>
    11 using namespace std;
    12 
    13 unsigned int FindFirstBitIs1(int num);
    14 bool IsBit1(int num, unsigned int indexBit);
    15 /**
    16  * 时间复杂度为O(n),空间复杂度为O(1)
    17  */
    18 void FindNumsAppearOnce(int data[], int length, int* num1, int* num2) {
    19     if (data == NULL || length < 2)
    20         return;
    21 
    22     int resultExclusiveOR = 0;
    23     for (int i = 0; i < length; ++i)
    24         resultExclusiveOR ^= data[i]; //第一次依次异或,其实相当于两个只出现一次的数字异或,其余均出现两次,异或后抵消
    25 
    26     unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);
    27 
    28     *num1 = *num2 = 0;
    29     for (int j = 0; j < length; ++j) {
    30         if (IsBit1(data[j], indexOf1)) //分组,依此拆分为两个各包含一个只出现一次的数字(其余皆出现两次)的数组★★
    31             *num1 ^= data[j]; //分组后的再依次异或获得只出现一次的数字
    32         else
    33             *num2 ^= data[j];
    34     }
    35 }
    36 
    37 // 找到num从右边数起第一个是1的位
    38 unsigned int FindFirstBitIs1(int num) {
    39     int indexBit = 0;
    40     while (((num & 1) == 0) && (indexBit < 8 * sizeof(int))) { //8 * sizeof(int) = 32/..?
    41         num = num >> 1;
    42         ++indexBit;
    43     }
    44 
    45     return indexBit;
    46 }
    47 
    48 // 判断数字num的第indexBit位是不是1
    49 bool IsBit1(int num, unsigned int indexBit) {
    50     num = num >> indexBit; //(这里indexBit=0/1/2/..)
    51     return (num & 1);
    52 }
    53 
    54 // ====================测试代码====================
    55 void Test(char* testName, int data[], int length, int expected1,
    56         int expected2) {
    57     if (testName != NULL)
    58         printf("%s begins: ", testName);
    59 
    60     int result1, result2;
    61     FindNumsAppearOnce(data, length, &result1, &result2);
    62 
    63     if ((expected1 == result1 && expected2 == result2)
    64             || (expected2 == result1 && expected1 == result2))
    65         printf("Passed.
    
    ");
    66     else
    67         printf("Failed.
    
    ");
    68 }
    69 
    70 void Test1() {
    71     int data[] = { 2, 4, 3, 6, 3, 2, 5, 5 };
    72     Test("Test1", data, sizeof(data) / sizeof(int), 4, 6);
    73 }
    74 
    75 void Test2() {
    76     int data[] = { 4, 6 };
    77     Test("Test2", data, sizeof(data) / sizeof(int), 4, 6);
    78 }
    79 
    80 void Test3() {
    81     int data[] = { 4, 6, 1, 1, 1, 1 };
    82     Test("Test3", data, sizeof(data) / sizeof(int), 4, 6);
    83 }
    84 
    85 int main(int argc, char** argv) {
    86     Test1();
    87     Test2();
    88     Test3();
    89 
    90     return 0;
    91 }
  • 相关阅读:
    关于ActionScript中那些你不知道的事情
    Flash Player 11 Stage3D学习大杂烩
    Qt 控制台输入输出(支持中文)
    Redis消息发布订阅的稳定性验证结论
    C++11 Lambda表达式(匿名函数)用法详解
    vue中“:”、“.”、“@”意义
    QT中printf输出不同步的解决办法
    QT5中使用SQLite
    QT 调用user32.dll移动鼠标
    10分钟学会Visual Studio将自己创建的类库打包到NuGet进行引用(net,net core,C#)
  • 原文地址:https://www.cnblogs.com/Laughing-Lz/p/5608555.html
Copyright © 2020-2023  润新知