JZ-C-40

Posted 回看欧洲

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

以上是关于JZ-C-40的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数