Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

算法 数组中出现次数最多的数字


目录

数组中出现次数最多的数字

给定一个int数组,找出出现次数最多的数字(出现次数超过数组长度的一半)

方式一:快速排序

先对这个数组进行排序,在已排序的数组中,位于中间位置的数字就是超过数组长度一半的那个数。

  1. public class Test {
  2. public static void main(String[] args) throws Exception {
  3. int[] array = { 1, 1, 1, 1, 5, 1, 5, 1, 5, 5, 5 };
  4. qsort(array);
  5. System.out.println(Arrays.toString(array));
  6. }
  7. public static void qsort(int[] arr) {
  8. qsort(arr, 0, arr.length - 1);
  9. }
  10. public static void qsort(int[] arr, int low, int high) {
  11. if (low < high) {
  12. int pivot = partition(arr, low, high);//将表一分为二
  13. qsort(arr, low, pivot);//对低子表【递归】排序
  14. qsort(arr, pivot + 1, high);//递归对高子表递归排序
  15. }
  16. }
  17. private static int partition(int[] arr, int low, int high) {
  18. int pivotkey = arr[low];//选择一个【基准元素】,通常选择第一个元素或者最后一个元素
  19. while (low < high) {//从表的两端【交替】地向中间扫描
  20. //将比基准元素小的交换到低端
  21. while (low < high && arr[high] >= pivotkey) {
  22. high--;
  23. }
  24. swap(arr, low, high);
  25. //将比基准元素大的交换到高端
  26. while (low < high && arr[low] <= pivotkey) {
  27. low++;
  28. }
  29. swap(arr, low, high);
  30. }
  31. return low;//此时基准元素在其排好序后的正确位置
  32. }
  33. public static void swap(int[] arr, int i, int j) {
  34. if (i == j) return;
  35. int temp = arr[i];
  36. arr[i] = arr[j];
  37. arr[j] = temp;
  38. }
  39. }

时间复杂度为 O(n*lgN)

空间复杂度为 O(n*lgN)

方式二:两次循环

第一次循环是为了记录各个数字出现的次数

第二次循环是为了比较各个数字出现的次数

这种方式没有利用出现次数超过数组长度的一半这个特殊条件,可以在任何数组中找出出现次数最多的数字。

  1. public class Test {
  2. public static void main(String[] args) throws Exception {
  3. int[] array = { 1, 1, 1, 1, 5, 1, 5, 1, 5, 5, 5 };
  4. System.out.println(mostNum(array));
  5. }
  6. public static int mostNum(int[] array) {
  7. HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
  8. for (int i = 0; i < array.length; i++) {
  9. int key = array[i];
  10. if (map.containsKey(key)) {
  11. map.replace(key, map.get(key) + 1);
  12. } else {
  13. map.put(key, 1);
  14. }
  15. }
  16. int key = array[0];
  17. for (Entry<Integer, Integer> entry : map.entrySet()) {
  18. if (entry.getValue() > map.get(key)) {
  19. key = entry.getKey();
  20. }
  21. }
  22. return key;
  23. }
  24. }

时间复杂度为O(n)

空间复杂度为O(n)

方式三:一次循环

取巧的做法,仅当出现次数超过数组长度的一半这种条件下才保证正确。

  1. public class Test {
  2. public static void main(String[] args) throws Exception {
  3. int[] array = { 1, 1, 1, 1, 5, 1, 5, 1, 5, 5, 5 };
  4. System.out.println(mostNum(array));
  5. }
  6. public static int mostNum(int[] array) {
  7. int count = 1, value = array[0];
  8. for (int i = 1; i < array.length; i++) {
  9. if (array[i] == value) {
  10. count++; //如果下一个数字与之前保存的数字相同,则次数加1
  11. } else {
  12. count--; //如果不同,则次数减1
  13. }
  14. if (count == 0) {
  15. value = array[i]; //如果次数为0,则需要保存下一个数字,并把次数设定为1
  16. count = 1;
  17. }
  18. }
  19. return value;
  20. }
  21. }

时间复杂度为O(n)

空间复杂度为O(1)

2018-12-8

算法 数组中出现次数最多的数字 MD的更多相关文章

  1. 编程算法 - 数组中出现次数超过一半的数字 代码(C)

    数组中出现次数超过一半的数字 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 数组中有一个数字出现的次数超过数组长度的一半, 请找出这个数字. ...

  2. [PHP] 算法-数组中出现次数超过一半的数字的PHP实现

    数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2.如果不存在 ...

  3. 给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 ,返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况)

    """ #给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 #返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况) 解题思路: 1.设定一个 ...

  4. 九度OJ 1370 数组中出现次数超过一半的数字

    题目地址:http://ac.jobdu.com/problem.php?pid=1370 题目描述: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2 ...

  5. 数组中出现次数超过一半的数字 -java

    数组中出现次数超过一半的数字 -java 方法一: 数组排序,然后中间值肯定是要查找的值. 排序最小的时间复杂度(快速排序)O(NlogN),加上遍历. 方法二: 使用散列表的方式,也就是统计每个数组 ...

  6. Leetcode - 剑指offer 面试题29:数组中出现次数超过一半的数字及其变形(腾讯2015秋招 编程题4)

    剑指offer 面试题29:数组中出现次数超过一半的数字 提交网址: http://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163 ...

  7. 剑指Offer:数组中出现次数超过一半的数字【39】

    剑指Offer:数组中出现次数超过一半的数字[39] 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于这 ...

  8. php实现求数组中出现次数超过一半的数字(isset($arr[$val]))(取不同数看剩)(排序取中)

    php实现求数组中出现次数超过一半的数字(isset($arr[$val]))(取不同数看剩)(排序取中) 一.总结 1.if(isset($arr[$val])) $arr[$val]++; //1 ...

  9. 剑指Offer(二十八):数组中出现次数超过一半的数字

    剑指Offer(二十八):数组中出现次数超过一半的数字 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn. ...

随机推荐

  1. usb3.0 monitor is already started

    用360 开机加速里找到这个程序,把它从开机启动中删除掉就好.

  2. Codeforces.566F.Clique in the Divisibility Graph(DP)

    题目链接 \(Description\) 给定集合\(S=\{a_1,a_2,\ldots,a_n\}\),集合中两点之间有边当且仅当\(a_i|a_j\)或\(a_j|a_i\). 求\(S\)最大 ...

  3. Ulipad安装、配置使用教程(附Ulipad下载)

    一.安装Ulipad 因为ulipad编辑器使用的是wxpython编写的gui,所以我们需要第三方库wxpython的支持,这里我们先讲一下Ulipad在Windows系统环境下的安装: 1. 确实 ...

  4. 零宽断言 -- Lookahead/Lookahead Positive/Negative

    http://www.vaikan.com/regular-expression-to-match-string-not-containing-a-word/ 经常我们会遇到想找出不包含某个字符串的文 ...

  5. 微信小程序如何玩转分销

    截止目前,微信月活跃用户已经高达8.89亿,微信这个庞大的互联网巨头下一个目标是什么? 打造属于自己的“AppStore”.小程序正是完成这个微信生态体系的一块完美拼板, 张小龙预言:未来2年内,小程 ...

  6. Revit API判断直线相交关系移动风管

    start )             );         )) )) );         XYZ xyz12 = lCurve1.Curve.get_EndPoint();         XY ...

  7. ASP.NET Web API中展示实体Link相关的方面

    有时候,向服务端请求一个实体,我们希望返回如下的格式: links: [    href: http://localhost:8901/api/user/diaries/2013-08-17,    ...

  8. 在ASP.NET MVC中使用Knockout实践07,自定义验证信息的位置与内容

    在前两篇中,体验了Knockout的基本验证和自定义验证.本篇自定义验证信息的显示位置与内容. 自定义验证信息的显示位置 通常,Knockout的验证信息紧跟在input后面,通过validation ...

  9. Java Dictionary 类存储键值

    字典(Dictionary) 字典(Dictionary) 类是一个抽象类,它定义了键映射到值的数据结构. 当你想要通过特定的键而不是整数索引来访问数据的时候,这时候应该使用Dictionary. 当 ...

  10. C#编程(六十六)----------表达式树总结

    表达式树总结 基础 表达式树提供了一个将可执行代码转换成数据的方法.如果你要在执行代码之前修改或转换此代码,那么它是很有用的.有其是当你要将C#代码----如LINQ查询表达式转换成其他代码在另一个程 ...