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 }
时间: 2024-11-07 06:40:55

JZ-C-29的相关文章

矩阵乘法快速幂 codevs 1250 Fibonacci数列

codevs 1250 Fibonacci数列 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 定义:f0=f1=1, fn=fn-1+fn-2(n>=2).{fi}称为Fibonacci数列. 输入n,求fn mod q.其中1<=q<=30000. 输入描述 Input Description 第一行一个数T(1<=T<=10000). 以下T行,每行两个数,n,q(n<=109, 1<

精都次级四走转所历

不过想来也算合理隐藏职业的技能书爆率相对于普通职业的技能书爆率不知道要低了多少爆到隐藏职业技能书的几率就跟中彩似的要是不能领悟一些职业基础技能的话那隐藏职业的玩家多半都要变成废物了 此时我已经目光一扫石头堡垒内部的结构是露天的只是堡垒周围拥有高高的石头城墙而已而堡垒内部则是一垛垛不算很大的石头房屋那石头房屋的入口不大大约一个食人魔趴在地上就能钻进去全部由坚硬的石头堆砌而成缝隙间可以看到内里铺满了枯草 不过想来也算合理隐藏职业的技能书爆率相对于普通职业的技能书爆率不知道要低了多少爆到隐藏职业技能书

bzoj 2844: albus就是要第一个出场 线性基

首先线性基是什么呢.我们考虑我们有n个数.子集数量为2^n个.我们将每个子集内的数全部异或起来.得到一个值.但是我们考虑这些值内会可能存在重复的,太多了.不便于运算.所以我们考虑,能不能除去重复的. 我们假定n个数都是<10^9.我们考虑使用一个30*30的矩阵.其中其中第一行,存一个最高位1位于数字第1位的数.第二行存一个最高位1位于数字2位的数.以此类推.这样子我们可以得到一个30*30的的矩阵.这个矩阵未必每一行都填满.我们可以考虑,加入一个元素,发现他对应的行已经被填满了.我们将这个数和

Oracle SQL语言之查询语句_超越OCP精通Oracle视频教程培训29

Oracle SQL语言之查询语句_超越OCP精通Oracle视频教程培训29 本课程介绍: Oracle视频教程,风哥本套oracle教程培训是<<Oracle数据库SQL语言实战培训教程>>的第4/5套:Oracle SQL语言之查询语句.主要学习Oracle数据库SQL查询限制排序.Oracle SQL联接查询.Oracle SQL子查询等. 视频学习地址: http://edu.51cto.com/course/course_id-8047.html Oracle SQL语

”耐撕“团队 2016.3.29 站立会议

”耐撕“团队 2016.3.29 站立会议 1. 时间:20:33--21:05 2. 成员: Z 郑蕊 * 组长 (博客:http://www.cnblogs.com/zhengrui0452/), P 濮成林(博客:http://www.cnblogs.com/charliePU/), Q 齐嘉亮(博客:http://www.cnblogs.com/dendroaspis-polylepis/), L  刘伟硕(博客:http://www.cnblogs.com/WeSure6/) 3.会议

Oyk的ACM刷题记录(始于2015年2月29日,可能含剧透)

Online Judge 题目序号/题目 简单大意/题解 犯2情况 2月29日 SPOJ GSS1  不带更新区间最大子段和. 线段树维护 区间从左/右开始的最大值.区间最大值.区间和. 1.输出忘了换行. 2.打错了一个字母. SPOJ GSS2 区间不重复最大子段和. 离线维护s[i..now],线段树维护 区间历史最大值.区间历史最大更新值.区间现在最大值.区间现在更新值. 询问输出区间历史最大值. 1.线段树询问忘记写pushdown了. SPOJ TEST 输出所有42前的数. 1.不

2017.06.29数据挖掘基础概念第二.三章

第二章21.研究的属性类型标称属性:值是一些符号或事物的名称,代表某种类型.编码或状态二元属性:是一种标称属性,只有两个类别或状态,又称布尔属性序数属性:是一种属性,其可能的值之间具有有意义的序或秩评定,但是相续值之间的差是未知的数值属性:是定量的,即他是可度量的量,可用整数或实数值表示(区间和比率标度)22.数据散布常见的度量量(数据如何分散的方法/识别离群点)极差 四分位数.四分位数极差.五数概括图.方差和标准差23.审视数据的图形条形.饼图.线图.分位数图.分位数-分位数图.直方图和散点图

Win32 汇编 - 跳转指令: JMP、JECXZ、JA、JB、JG、JL、JE、JZ、JS、JC、JO、JP 等

跳转指令分三类:一.无条件跳转: JMP;二.根据 CX.ECX 寄存器的值跳转: JCXZ(CX 为 0 则跳转).JECXZ(ECX 为 0 则跳转);三.根据 EFLAGS 寄存器的标志位跳转, 这个太多了. 根据标志位跳转的指令: JE ;等于则跳转 JNE ;不等于则跳转 JZ ;为 0 则跳转 JNZ ;不为 0 则跳转 JS ;为负则跳转 JNS ;不为负则跳转 JC ;进位则跳转 JNC ;不进位则跳转 JO ;溢出则跳转 JNO ;不溢出则跳转 JA ;无符号大于则跳转 JNA

3/29上午,3/27,和3月28下午补交

3月27上午上蔡亮老师的嵌入式课程 3月27下午 3月38下午 3/29下午第一章第二节极限

29.MAX() 函数

MAX() 函数 MAX 函数返回一列中的最大值.NULL 值不包括在计算中. SQL MAX() 语法 SELECT MAX(column_name) FROM table_name 注释:MIN 和 MAX 也可用于文本列,以获得按字母顺序排列的最高或最低值. SQL MAX() 实例 我们拥有下面这个 "Orders" 表: O_Id OrderDate OrderPrice Customer 1 2008/12/29 1000 Bush 2 2008/11/23 1600 Ca