剑指Offer_面试题29_数组中出现次数超过一半的数字
来源:互联网 发布:钓鱼软件什么意思 编辑:程序博客网 时间:2024/06/08 16:59
题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
分析:思路一,如果是排序的数组那就好了。快排一次可以确定一个位置的数字,在他的左侧都比他小,右侧都比他大。一个数组中数字超过数组长度一半,经过排序之后,中间的位置一定是这个数字,这个数字也就是统计学上的中位数。
解法一:当且仅当可以修改数组内容时,利用快排分区,排好数组中间位置的数字即为结果,记得要检验是否无效输入;
#include <stdlib.h>#include <stdio.h>//快排一次分区int partition(int *a, int low, int high){int value = a[low]; //基准元素while (low < high){while (low < high && value <= a[high])--high;if (low < high) a[low++] = a[high];while (low < high && a[low] <= value)++low;if (low < high) a[high--] = a[low];}a[low] = value;return low;}bool inputInvalid = false;//检查是否真的超过一半bool CheckInvalidArray(int *numbers, int length, int num){inputInvalid = false;int times = 0;for (int i = 0; i < length; ++i){if (numbers[i] == num)++times;}bool res = true;if (times * 2 <= length){inputInvalid = true;res = false;}return res;}//解法一:快排求第k大的数值,需要改变数组int MoreThanHalfNum(int *number, int length){if (number == NULL || length <= 0){inputInvalid = true;return 0;}int middle = length >> 1;int start = 0;int index = partition(number, 0, length-1);while (index != middle){if (index < middle){index = partition(number, index+1, length-1);}else {index = partition(number, 0, index - 1);}}int result = number[middle];//这里补充一个检查是不是超过一半的判断if (!CheckInvalidArray(number, length, result))result = 0;return result;}
解法二:不改变数组本身,利用数组特性。两个变量,一个result保存数字,一个count保存次数。result初始化为第一个元素,count初始化为1;从第二个元素开始遍历数组,如果count==0则result=当前数字,count = 1;否则如果result=当前数字,count++;否则--count;这样result必定是超过一半的元素,当然最后还是要检验是否有效输入;
//解法二:根据数组特点,不改变数组本身int MoreThanHalfNum2(int *numbers, int length){if (numbers == NULL || length <= 0){inputInvalid = true;return 0;}int result = numbers[0];int count = 1;for (int i = 1; i < length; ++i){if (count == 0){result = numbers[i];count = 1;}else if (numbers[i] == result)++count;else--count;}if (!CheckInvalidArray(numbers, length, result))result = 0;return result;}int main(){int a[] = {1,2,3,2,2,2,5,4,2};int res = MoreThanHalfNum(a, 9);printf("%d\n", res);int b[] = { 1,2,3,2,2,2,5,4,2 };int res2 = MoreThanHalfNum2(b, 9);printf("%d\n", res2);getchar();return 0;}
测试结果:
总结:快排一次分区可以在O(n)时间找到数组中任意第K大的数字,利用好这一点可以解决很多问题,但是会修改数组本身内容,这一点面试的时候一定要问清楚。两种解法时间复杂度都是O(n)。
阅读全文
0 0
- 剑指Offer_面试题29_数组中出现次数超过一半的数字
- 剑指offer_数组中出现次数超过一半的数字
- 面试题29_数组中出现次数超过一半的数字
- 面试题:数组中出现次数超过一半的数字
- 面试题:数组中出现次数超过一半的数字
- [剑指offer][面试题29]数组中出现次数超过一半的数字
- 剑指Offer:面试题29 数组中出现次数超过一半的数字
- 剑指offer 面试题29—数组中出现次数超过一半的数字
- 《剑指Offer》学习笔记--面试题29:数组中出现次数超过一半的数字
- 【剑指Offer学习】【面试题29 :数组中出现次数超过一半的数字】
- 剑指Offer面试题29(java版):数组中出现次数超过一半的数字
- 剑指offer面试题29-数组中出现次数超过一半的数字
- 剑指offer-面试题29:数组中出现次数超过一半的数字
- 剑指offer之面试题29:数组中出现次数超过一半的数字
- 剑指offer之面试题29数组中出现次数超过一半的数字
- 剑指Offer----面试题29:数组中出现次数超过一半的数字
- 剑指offer-----面试题29(数组中出现次数超过一半的数字)
- 剑指Offer面试题29:数组中出现次数超过一半的数字 Java实现
- laravel如何获取当前url的别名
- apue读书笔记-Ch04(2)
- MC/ServiceGuard HP
- 设计模式11-装饰模式
- webstorm快捷键大全
- 剑指Offer_面试题29_数组中出现次数超过一半的数字
- MFC中使用控制台窗口打印调试信息
- JQuery 选择器
- 欧拉角表示方式的理解
- Hive基本操作(二)——Hive实战案例-级联求和
- Android零碎知识点
- javaseday20补充(io 续写 换行 FileWriter 输出个文件)
- hdu1695 GCD
- 适合研发团队的几个项目管理软件对比