左神算法课-找出数组中出现次数超过一半的数及其进阶
来源:互联网 发布:炉石毕游侠知乎 编辑:程序博客网 时间:2024/05/02 23:55
原问题描述
给定一个整形数组arr,打印其中出现次数超过一半的数,如果没有这样的数,打印“no such number”;
解法1:
思路:遍历数组中所有的数,用map记录各数出现的次数,key表示原数组中的某个数,value代表出现的次数;找出map中value最大的那个key,再去遍历原数组,看该数是不是满足出现次数大于一半这个条件;
代码:这种情况比较简单就不贴代码了
解法2:
思路:如果存在这样的数,那么按照大小排序过后的数组中间那个数必然是所求的数,按照这个思路,将原数组排序,找出中间那个数,再遍历原数组看是否满足条件(无论如何這一步是省不掉的);
代码:比较简单就不贴了
解法3(左神思路)
思路:如果存在这样的数,那么我每次删掉两个不相同的数,最后剩下的那个就是所求的数,思路比较好理解,但是编码就比较巧妙了,按照这个思路可以有以下编码技巧:所谓删除并不是真正的删除而是记录之后就过去了;temp记录当前等待配对的数,lives表示等待配对的数有几个; 遍历到某个数a[i]时,如果等于等待配对的数,生命值加一,如果不等于,且现在生命值>0,就生命值减1(就相当于同时删除这两个数);如果现在生命值为0,变换等待配对的数为a[i]生命值为1;最终等待配对的数就是剩下的数,拿这个数去验证出现次数是否满足要求;算法复杂度是O(n);
代码:
public static void func2(int[] a) { int temp = a[0]; int lives = 1; for (int i = 1; i < a.length; i++) { if (a[i] == temp) { lives++; } else if (lives > 0) { lives--; } else{ temp = a[i]; lives = 1; } } int times = 0; for (int i = 0; i < a.length; i++) { if (temp == a[i]) times++; } if (times > a.length / 2) System.out.println(temp); else System.out.println("no such number"); }
巧妙处在于如果当前的待配对数的生命值大于零,且来了一个跟配对数不一样的数,就将生命值减一,好像是删除了这两个数;最后那个待配对数就是待验证的数;
进阶题目描述
给定一个整形数组arr长度是N,给定整数k,打印数组中出现次数大于N/k的数,如果没有这样的数,打印“no such number”
思路:首先要知道,出现次数大于k的数最多最多是k-1个,仿照上面的解法3;可以得到:设立一个大小最大为k-1的map,map的key指数组中的某个数,value指该数的生命值。遍历到某数a[i]时,如果map中有a[i]对应的key就将它的value加一,如果map中没有,就看下现在map满没有,如果没有满,就将这个a[i]放进去;如果现在map已经满了,就将所有的map中的value减一,之后将所有的value为0的键值对删除(这样就是变相的删除了不同的k个数);最终将map中所有的值拿去验证出现次数,满足条件的输出;
代码
public static void func3(int[] a, int k) { HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(k - 1); for (int i = 0; i < a.length; i++) { if (!map.containsKey(a[i])) if (map.size() < k - 1) map.put(a[i], 1); else { Iterator<Integer> iterator = map.keySet().iterator(); while (iterator.hasNext()) { int key = iterator.next(); int value = map.get(key); if (--value == 0) iterator.remove(); else map.put(key, value); } } else map.put(a[i], map.get(a[i]) + 1); } boolean flag = false; for (Integer key : map.keySet()) { for (int i : a) System.out.print(i); int times = 0; for (int i = 0; i < a.length; i++) { if (a[i] == key) times++; } if (times > a.length / k) { System.out.println(key); flag = true; } } if (!flag) System.out.println("no such number"); }
思路倒是不难想,主要是这种好像删除的操作编码方式,值得借鉴!
- 左神算法课-找出数组中出现次数超过一半的数及其进阶
- 找出数组中出现次数超过一半的数
- 算法--找出数组中出现次数超过一半的数
- 找出数组中出现次数超过一半的数
- 找出数组中出现次数超过一半的数
- 算法--找出数组中出现次数超过一半的数
- 找出数组中出现次数超过一半的数
- 找出数组中出现次数超过一半的数
- 算法--找出数组中出现次数超过一半的数
- 找出数组中出现次数超过一半的数
- 找出数组中出现次数超过一半的数
- 找出数组中出现次数超过一半的数
- 找出数组中出现次数超过一半的数
- 找出出现次数超过数组一半元素的数
- 找出数组出现次数超过一半的数
- 找出数组中出现次数超过数组长度一半的数
- 找出数组中出现次数超过长度一半的数字
- 找出数组中出现次数超过一半的数字--百度
- python下载及安装
- 怎样连接Redis数据库
- HashMap从源码角度分析遍历过程
- 项目拆分
- java多线程-基础概念
- 左神算法课-找出数组中出现次数超过一半的数及其进阶
- [LeetCode]26. Remove Duplicates from Sorted Array
- 99乘法表及杨辉三角C代码实现
- 网狐荣耀版游戏服务器出现"MDM_GF_GAME 游戏命令返回 false"
- 1009.说反话
- android:padding和android:layout_margin的区别
- 基于Dragonboard 410c的总线控制之I2C(二)
- UVA-1608 Non-boring sequences
- linux查看大文件命令