剑指offer面试题[29]-数组中出现次数超过一半的数字
题目描述
这种算法是受快速排序算法的启发。在随机快速排序算法中,我们现在数组中随机选择一个数字,然后调整数组中数字的顺序,使得比选中的数字小的数字都排在它的左边,比选中的数字大的数字都排在它的右边。如果这个选中的数字的下标刚好是n/2,那么这个数字就是数组的中位数。如果它的下标大于n/2,那么中位数应该位于它的左边,我们可以接着在它的左边部分的数组中查找。如果它的下标小于n/2,那么中位数应该位于它的右边,我们可以接着在它的右边部分的数组中查找。这是一个典型的递归过程,实现代码如下:
class Solution {
public:int MoreThanHalfNum_Solution(vector<int> numbers) {int length=numbers.size(); if(numbers.empty()||length<0)return 0;int middle=length>>1;int start=0;int end=length-1;//int index=partition(numbers,length,start,end); int index=partition(numbers,start,end); while(index!=middle){ if(index>middle){end=index-1;index=partition(numbers,start,end); }else{start=index+1;index=partition(numbers,start,end); }}int result=numbers[middle]; //这里的只是得到了第middle=n/2大的数字,但总个体是否超过一段还需要判断if(!CheckMoreThanHAlf(numbers,length,result)) //此时需要检查result的值的个数是否大于整个数组的一半return 0;return result;}int partition(vector<int> input,int low,int high){int pivotkey=input[low]; //pivot:枢纽//这里的pivotkey也可以是[low,high]区间一个随机数,也可以是三数取中,九数取中,详情见<<大话数据结构>>//int pivotkey=input[RandInRange(start,end)];while(low<high){while(low<high&&pivotkey<input[high])high--;swap(&input[low],&input[high]);while(low<high&&pivotkey>=input[low])low++;swap(&input[low],&input[high]);} return low;}/*这个partition是优化了不必要的交换,将swap用赋值替换int partition(vector<int> &input, int begin, int end){int low = begin;int high = end;int pivot = input[low];while (low < high){while (low < high&&pivot <= input[high])high--;input[low] = input[high]; //优化不必要的替换while (low < high&&pivot >= input[low])low++;input[high] = input[low]; //优化不必要的替换}input[low] = pivot;return low;}*/bool CheckMoreThanHAlf(vector<int> numbers,int length,int result) //检查result的值的个数是否大于整个数组的一半{int times=0;for(int i=0;i<length;++i){if(numbers[i]==result)times++;}bool isMoreThanHalf=true;if(times*2<=length)isMoreThanHalf=false;return isMoreThanHalf;}void swap(int *a,int *b) //交换两个数{int temp;temp=*a;*a=*b;*b=temp;}/*下面的partition是剑指offer上的实现,考虑的很详情,但是没有上面的好理解int RandInRange(int a,int b) //产生一个[a,b]范围内的随机整数{int c;c=a+rand()%(b-a+1);return c;}int partition(vector<int>& data,int length,int start,int end) //partition函数是为了找出数组中第K大的数字 {if(data.empty()||length<0||start<0||end>=length)return 0; //throw new std::exception("Invakid Parameters");int index=RandInRange(start,end); swap(&data[index],&data[end]); int small=start-1;for(index=start;index<end;++index){if(data[index]<data[end]){++small;if(small!=index)swap(&data[index],&data[small]); }}++small;swap(&data[small],&data[end]); return small;}*/
};
剑指offer面试题[29]-数组中出现次数超过一半的数字相关推荐
- 剑指offer面试题39. 数组中出现次数超过一半的数字(数组)(摩尔投票法)
题目描述 **数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素.** 思路 详见链接 代码 class Solution:def ...
- 【剑指offer-Java版】29数组中出现次数超过一半的数字
数组中出现次数超过一半的数字 两种思路: 思路一:由于出现次数超过一半,所以如果对这个数组进行划分之后无论如何,位于数组下标 n/2的数字就是出现次数超过一半的数 所以问题就转换为了求划分一次之后 位 ...
- 【剑指Offer】28、数组中出现次数超过一半的数字
题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 例如:输入如下所示的一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过 ...
- 剑指offer:面试题39. 数组中出现次数超过一半的数字
题目:面试题39. 数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 你可以假设数组是非空的,并且给定的数组总是存在多数元素. 示例 1: 输入: [1, ...
- 剑指offer面试题[40]-数组中只出现一次的数字
题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 注意原题目要求空间复杂度为0(1). 位运算的具体思路可以参看剑指offer. class So ...
- 剑指Offer - 面试题3. 数组中重复的数字(哈希)
1. 题目 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组 ...
- 剑指offer 面试题03. 数组中重复的数字
找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中任意一个重 ...
- 剑指offer面试题[36]-数组中的逆序对
题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P.并将P对1000000007取模的结果输出. 即输出P%1000 ...
- 剑指offer面试题[51]-数组中重复的数字
题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...
最新文章
- mysql课程id数据类型_数据库学习之六:mysql数据类型
- 《Linux shell变量总结回顾》RHEL6
- toj 3711 水题
- 2.27 18种定位方法总结
- H5嵌入原生开发小结----兼容安卓与ios的填坑之路
- C语言查看队头元素,C语言实现循环队列的初始化进队出队读取队头元素判空-1...
- LeetCode 225. Implement Stack using Queues
- 安装Debian-9(Stretch)服务器图文教程
- lintcode:合并排序数组
- 理解node.js(Understanding node.js)
- 软件开发高手须掌握的4大SQL精髓语句(综合篇)
- android mount --bind挂载目录
- linux内存源码分析 - 内存回收(匿名页反向映射)
- 李宏毅机器学习笔记:机器学习介绍
- 如何用O2OA公文编辑器制作标准的红头文件?
- win7 共享计算机 网络密码怎么设置,win7局域网共享设置密码 win7局域网如何设置密码【详细步骤】...
- Ubuntu vsftp搭建和C# Winform FTP操作
- Linux如何删除用户
- 滑窗优化、边缘化、舒尔补、FEJ及fill-in问题
- Docker WordPress安装
热门文章
- win7下安装usb转串口不成功解决方法
- 101.接收上游响应的缓存处理流程
- python代码实现中心化_数据预处理——标准化(附python代码)
- 【论文写作】SSM房屋租赁系统如何写设计总结
- Android5手动root,魅蓝Note5如何获取ROOT权限?魅蓝Note5 ROOT教程(亲测可行)
- 进程与服务的签名_服务器被黑客攻击后如何查找溯源攻击
- 计算机通信基础ppt,计算机网络第2章 数据通信基础知识要点课件.ppt
- 影响机器视觉光源效果的因素有哪些?
- 深度学习入门:用MNIST完成Autoencoder(续)
- 上週末去南投玩了一下,順便拍了几张,拿出来和大家分享