剑指Offer——数组中出现次数超过一半的数字——一题多解
看题目:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
我的直接思路:
用map计数,简单直接,遍历一次数组,用hashmap记录,key为int值,value为出现次数;
第二次再用map.entrySet找出有没value大于数组长度一般的entry,有的话返回它的key。
时间复杂度也是2n而已,这个方法时间复杂度是O(n)空间复杂度也是O(n)
代码实现:
- /*方法1
- 蛮力,遍历一次,用一个map来记录
- 第二次遍历把出现次数大于length/2的那个值找出来
- */
- public int MoreThanHalfNum_Solution(int [] array) {
- int targetCount = array.length / 2;
- //key为数组中的值,value为出现的次数
- HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
- for(int temp : array) {
- if(map.get(temp) == null)map.put(temp, 1);
- else map.put(temp, map.get(temp) + 1);
- }
- Set<Entry<Integer,Integer>> entrySet = map.entrySet();
- for(Entry<Integer,Integer> entry : entrySet) {
- if(entry.getValue() > targetCount)return entry.getKey();
- }
- return 0;
- }
方法2:中位数
- /*方法2
- 排序后中位数法
- 如果有个数字出现的次数大于数组长度的一半,那么这个数组排序后,它的中位数一定是这个数字
- */
- public int MoreThanHalfNum_Solution(int [] array) {
- Arrays.sort(array);
- int count = 0, middleNum = array[array.length / 2];
- for(int temp : array) {
- if(temp == middleNum)count++;
- }
- if(count > array.length / 2)return middleNum;
- else return 0;
- }
方法3:——快排思路
方法2中,我们排序是为了找出中位数,那么如果可以更快地找出中位数就不用排序了。
通过Partition()返回index,如果index==mid,那么就表明找到了数组的中位数;如果index<mid,表明中位数在[index+1,end]之间;如果index>mid,表明中位数在[start,index-1]之间。直到最后求得index==mid循环结束。
- /*方法3
- 利用快排的思想
- */
- public int MoreThanHalfNum_Solution(int [] array) {
- if(array.length <= 0)return 0;
- int begin = 0, end = array.length - 1, middle = array.length / 2;
- int partition = partition(array, begin, end);
- while(partition != middle) {
- if(partition > middle) {//中位数在partition的左边
- partition = partition(array, begin, partition - 1);
- } else {//中位数在partition右边
- partition = partition(array, partition + 1, end);
- }
- }
- //找出中位数了,看这个中位数出现的次数是否符合要求
- int count = 0, middleKey = array[middle];
- for(int temp : array) {
- if(temp == middleKey)count++;
- }
- if(count > array.length / 2)return array[middle];
- else return 0;
- }
- //这个方法是以第一个元素为基准,然后进行划分,划分后比基准元素小的数字都在它左边,比它大的数字都在它右边
- 返回划分后,这个元素的新index//
- private int partition(int[] a, int begin, int end) {
- int key = a[begin];
- int i = begin, j = end;
- while(i < j) {
- while(i < j && a[j] >= key)j--;
- while(i < j && a[i] <= key)i++;
- swap(a, i, j);
- }
- swap(a, begin, i);
- return i;
- }
- //交换数字函数,传入数组还有要交换的两个数字的index//
- private void swap(int[] a, int first, int second) {
- int temp = a[first];
- a[first] = a[second];
- a[second] = temp;
- }
遇到相同元素,count++;
遇到不相同元素,即为敌人,同归于尽,count--;当遇到count为0的情况,又以新的i值作为守阵地的士兵,继续下去,同时count更新为1.
当我们遍历到下一个数字的时候,
如果下一个数字和当前我们保存的数字相同,则次数加 1;
如果和当前我们保存的数字不同,则次数减 1;
当次数减到 0 的时候,我们将保存的数字改为当前遍历所处的位置,并将次数更改为 1。
看代码:
- /*方法4
- 阵地攻守思想,其实和牛客上面那个什么“用户分形叶”的思路一样的,不同实现而已
- */
- public int MoreThanHalfNum_Solution(int [] array) {
- //int count = 1;
- int count = 0;//这里我们设初始的count为0好了,因为利用java的foreach语法是要从第一个key开始遍历的,那么就是碰到第一个开始,设为1
- int key = array[0];
- for(int temp : array) {
- if(temp == key)count++;
- else if(count > 0)count--;
- else {//count==0的情况,这个时候把key换成现在这个元素,并把count设为1,意思是这是第一次碰到这个元素
- key = temp;
- count = 1;
- }
- }
- //判断这个得到的key是不是符合要求
- int count2 = 0;
- for(int temp : array) {
- if(temp == key)count2++;
- }
- if(count2 > array.length / 2)return key;
- else return 0;
- }
剑指Offer——数组中出现次数超过一半的数字——一题多解的更多相关文章
- python剑指offer数组中出现次数超过一半的数字
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- 剑指offer——数组中出现次数超过一半的数字(c++)
题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如 ...
- 剑指Offer——数组中出现次数超过一半的数字
题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2 ...
- 用js刷剑指offer(数组中出现次数超过一半的数字)
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- 剑指Offer-28.数组中出现次数超过一半的数字(C++/Java)
题目: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如 ...
- 剑指offer--11.数组中出现次数超过一半的数字
unique(), count()函数好用 ---------------------------------------------------------------------- 时间限制:1秒 ...
- 1-剑指offer: 数组中出现次数超过一半的数字
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- 剑指offer-数组中出现次数超过一半的数字
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)
剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...
随机推荐
- QE名词解释以及相关文章链接
百科: http://baike.baidu.com/link?url=ho-aUG2rZwgjx75rwFu5b3XoQnsuJMj9GrJEuaZxnakg19ofO13mrXCMi9_JZ_VY ...
- office2016_windows永久激活查看方法
YC7N8-G7WR6-9WR4H-6Y2W4-KBT6X 首先要保证你安装了 百云址:http://pan.baidu.com/share/home?uk=4011207371 如果你是win8,w ...
- Python:map()、reduce()、filter()的区别
文章转于:https://blog.csdn.net/goupper1991/article/details/49803355 原文博主:https://blog.csdn.net/goupper19 ...
- springMVC绑定json参数之一
一.SpringMVC @RequestBody接收Json对象字符串 以前,一直以为在SpringMVC环境中,@RequestBody接收的是一个Json对象,一直在调试代码都没有成功,后来发现, ...
- asp中实现lable自动换行
asp中实现lable自动换行 因为在用Label标签显示内容时,内容太多,想实现自动换行.我们知道在WINFORM中程序中,有一个属性是AUTOSIZE 改成FALSE 是可以实现的.但是在ASP. ...
- kvm ip查看
1.virsh --list(查看有哪些服务器) 2.virsh dumpxml 虚拟机名称 查看服务器对应的mac地址 3.然后再宿主机上arp -a 查看对应的mac地址对应的ip
- 在Action获取Scope对象
引言:在前面的Action操作中,关键就是Action中的exectue方法,但是此方法并没有request.session.application等对象作为参数,自然就不能利用这些对象来操作.下面我 ...
- glib-2.40编译安装
1 安装glib库所需要的依赖库: libffi-.tar.gz glib-.tar.xz 安装依赖库libffi: tar xf libffi-.tar.gz cd libffi- ./config ...
- java类什么时候初始化?
Java虚拟机规范中并没有进行强制玉树什么情况下需要开始类加载过程.但是对于初始化阶段,虚拟机规范则是严格规定了有且仅有5种情况必须立即对类进行“初始化”(而加载,验证,准备自然需要在此之前开始): ...
- es6基础系列四--字符串的拓展
1 for...of 字符串的遍历接口 for(let i of "abc"){ console.log(i); } // a // b // c 2 includes 是否包含某 ...