JZ-C-29

剑指offer第二十九题:数组中出现次数超过一半的数字

  1 //============================================================================
  2 // Name        : JZ-C-29.cpp
  3 // Author      : Laughing_Lz
  4 // Version     :
  5 // Copyright   : All Right Reserved
  6 // Description : 数组中出现次数超过一半的数字
  7 //============================================================================
  8 
  9 #include <iostream>
 10 #include "Array.h"
 11 #include <stdio.h>
 12 using namespace std;
 13 
 14 bool g_bInputInvalid = false;
 15 /**
 16  *检查数组是否合法
 17  */
 18 bool CheckInvalidArray(int* numbers, int length) {
 19     g_bInputInvalid = false;
 20     if (numbers == NULL && length <= 0)
 21         g_bInputInvalid = true;
 22 
 23     return g_bInputInvalid;
 24 }
 25 /**
 26  * 检查数字出现次数是否大于数组长度一半
 27  */
 28 bool CheckMoreThanHalf(int* numbers, int length, int number) {
 29     int times = 0;
 30     for (int i = 0; i < length; ++i) {
 31         if (numbers[i] == number)
 32             times++;
 33     }
 34 
 35     bool isMoreThanHalf = true;
 36     if (times * 2 <= length) {
 37         g_bInputInvalid = true;
 38         isMoreThanHalf = false;
 39     }
 40 
 41     return isMoreThanHalf;
 42 }
 43 
 44 // ====================方法1:分治法,参考快速排序====================
 45 int MoreThanHalfNum_Solution1(int* numbers, int length) {
 46     if (CheckInvalidArray(numbers, length)) {
 47         return 0;
 48     }
 49     int middle = length >> 1; //右移1位
 50     int start = 0;
 51     int end = length - 1;
 52     int index = Partition(numbers, length, start, end);
 53     while (index != middle) {
 54         if (index < middle) {
 55             index = Partition(numbers, length, index + 1, end);
 56         } else {
 57             index = Partition(numbers, length, start, index - 1);
 58         }
 59     }
 60     int result = numbers[middle];
 61     if (!CheckMoreThanHalf(numbers, length, result)) {
 62         result = 0;
 63     }
 64     return result;
 65 }
 66 // ====================方法2:利用数字出现次数大于数组长度的一半====================
 67 int MoreThanHalfNum_Solution2(int* numbers, int length) {
 68     if (CheckInvalidArray(numbers, length)) {
 69         return 0;
 70     }
 71     int result = numbers[0];
 72     int times = 1;
 73     for (int i = 1; i < length; i++) {
 74         if (times == 0) {
 75             result = numbers[i];
 76             times = 1;
 77         } else if (result != numbers[i]) {
 78             times--;
 79         } else {
 80             times++;
 81         }
 82     }
 83     if (!CheckMoreThanHalf(numbers, length, result)) {
 84         result = 0;
 85     }
 86     return result;
 87 }
 88 // ====================测试代码====================
 89 void Test(char* testName, int* numbers, int length, int expectedValue,
 90         bool expectedFlag) {
 91     if (testName != NULL)
 92         printf("%s begins: \n", testName);
 93 
 94     int* copy = new int[length];
 95     for (int i = 0; i < length; ++i)
 96         copy[i] = numbers[i];
 97 
 98     printf("Test for solution1: ");
 99     int result = MoreThanHalfNum_Solution1(numbers, length);
100     if (result == expectedValue && g_bInputInvalid == expectedFlag)
101         printf("Passed.\n");
102     else
103         printf("Failed.\n");
104 
105     printf("Test for solution2: ");
106     result = MoreThanHalfNum_Solution2(copy, length);
107     if (result == expectedValue && g_bInputInvalid == expectedFlag)
108         printf("Passed.\n");
109     else
110         printf("Failed.\n");
111 
112     delete[] copy;
113 }
114 
115 // 存在出现次数超过数组长度一半的数字
116 void Test1() {
117     int numbers[] = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
118     Test("Test1", numbers, sizeof(numbers) / sizeof(int), 2, false);
119 }
120 
121 // 不存在出现次数超过数组长度一半的数字
122 void Test2() {
123     int numbers[] = { 1, 2, 3, 2, 4, 2, 5, 2, 3 };
124     Test("Test2", numbers, sizeof(numbers) / sizeof(int), 0, true);
125 }
126 
127 // 出现次数超过数组长度一半的数字都出现在数组的前半部分
128 void Test3() {
129     int numbers[] = { 2, 2, 2, 2, 2, 1, 3, 4, 5 };
130     Test("Test3", numbers, sizeof(numbers) / sizeof(int), 2, false);
131 }
132 
133 // 出现次数超过数组长度一半的数字都出现在数组的后半部分
134 void Test4() {
135     int numbers[] = { 1, 3, 4, 5, 2, 2, 2, 2, 2 };
136     Test("Test4", numbers, sizeof(numbers) / sizeof(int), 2, false);
137 }
138 
139 // 输入空指针
140 void Test5() {
141     int numbers[] = { 1 };
142     Test("Test5", numbers, 1, 1, false);
143 }
144 
145 // 输入空指针
146 void Test6() {
147     Test("Test6", NULL, 0, 0, true);
148 }
149 
150 int main(int argc, char** argv) {
151     Test1();
152     Test2();
153     Test3();
154     Test4();
155     Test5();
156     Test6();
157 
158     return 0;
159 }

关于Partition方法:

 1 // 《剑指Offer——名企面试官精讲典型编程题》代码
 2 // 著作权所有者:何海涛
 3 
 4 #include <stdlib.h>
 5 #include <stdio.h>
 6 #include "Array.h"
 7 #include <exception>
 8 
 9 // Random Partition
10 int RandomInRange(int min, int max) {
11     int random = rand() % (max - min + 1) + min;
12     return random;
13 }
14 
15 void Swap(int* num1, int* num2) {
16     int temp = *num1;
17     *num1 = *num2;
18     *num2 = temp;
19 }
20 
21 int Partition(int data[], int length, int start, int end) {
22     if (data == NULL || length <= 0 || start < 0 || end >= length) {
23         printf("Invalid Parameters");
24         throw new std::exception();//这里括号里为什么不能加msg???!!!
25     }
26     int index = RandomInRange(start, end);
27     Swap(&data[index], &data[end]);
28 
29     int small = start - 1;
30     for (index = start; index < end; ++index) {
31         if (data[index] < data[end]) {
32             ++small;
33             if (small != index)
34                 Swap(&data[index], &data[small]);
35         }
36     }
37 
38     ++small;
39     Swap(&data[small], &data[end]);
40 
41     return small;
42 }

 

posted @ 2016-06-17 15:27  回看欧洲  阅读(137)  评论(0编辑  收藏  举报