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.\n\n"); 66 else 67 printf("Failed.\n\n"); 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 }
—————————————————————————————————————行走在人猿的并行线——Laughing_Lz