题目原文:

Decimal dominants. Given an array with n keys, design an algorithm to find all values that occur more than  n/10 times. The expected running time of your algorithm should be linear.

分析:

直观上将n个元素遍历一遍,并记录每个元素出现的次数就可以实现,虽然时间复杂度是O(n),但是空间复杂度却高达n,这肯定不是该题目的初衷。对于n个元素来说,出现n/10次的元素最多有10个,那么出现超过n/10次的元素最多不超过9个,所以需要9个额外空间auxs就能满足需求。

这9个辅助空间aux怎么使用呢?可采用俄罗斯方块的消去一行的思路。只不过这里消去一行的情况是该行中元素各不相同。

1. 遍历数组array中的每个元素array[i]

2. 如果array[i]在aux中存在,将其在aux中的计数+1

3. 如果array[i]在aux中不存在

  3.1 如果aux未满,将其放入aux中,并记录其个数为1

  3.2 如果aux已满,将aux中已经存在的各个元素的计数都减去1,直到某个元素的个数变成0,将array[i]放入aux中该位置处,并记录其个数为1

4. 出现次数超过n/10的元素在array遍历完了之后,还会继续存在于aux中,当然aux中可存在着位于array后方但出现次数不满足要求的元素。这时只需要遍历aux的同时再遍历一遍array,记录aux中各个元素在array中出现的次数,将其中出现次数真正超过n/10的元素找出来即可。

  1. package week3;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Arrays;
  5. import edu.princeton.cs.algs4.StdRandom;
  6.  
  7. public class ElemsMoreThanNDivTenTimes {
  8.  
  9. private class Element{//辅助空间元素定义,用来记录元素值及其出现次数
  10. public int element;
  11. public int count;
  12. public Element(int e,int c){
  13. this.element = e;
  14. this.count = c;
  15. }
  16. };
  17. private Element[] elems = new Element[9]; //申请9个辅助空间
  18.  
  19. public ArrayList<Integer> findElements(int[] arrays){
  20. int n = arrays.length;
  21. for(int k=0;k<9;k++){
  22. elems[k] = new Element(0,0); //辅助空间初始化
  23. }
  24. for(int i=0;i<n;i++){
  25. int index = findIndex(arrays[i]);
  26. if(index >= 0)
  27. elems[index].count ++;
  28. else
  29. addToElems(arrays[i]);
  30. }
  31. return verifyElems(arrays);
  32. }
  33.  
  34. private int findIndex(int e){
  35. for(int k = 0; k<9;k++){
  36. if(elems[k].element == e)
  37. return k;
  38. else if(elems[k].count == 0){
  39. elems[k].element = e;
  40. return k;
  41. }
  42. }
  43. return -1;
  44. }
  45. private void addToElems(int e){
  46. boolean insertFlag = false;
  47. while(!insertFlag){
  48. for(int k=0; k<9;k++){
  49. elems[k].count --;
  50. if(elems[k].count <= 0){
  51. elems[k].element = e;
  52. elems[k].count = 1;
  53. insertFlag = true;
  54. break;
  55. }
  56. }
  57. }
  58. }
  59. private ArrayList<Integer> verifyElems(int[] arrays){
  60. int n = arrays.length;
  61. for(int k = 0; k< 9; k++){
  62. elems[k].count = 0;
  63. for(int i = 0; i< n;i++){
  64. if(arrays[i]==elems[k].element)
  65. elems[k].count++;
  66. }
  67. }
  68. ArrayList<Integer> elemList = new ArrayList<Integer>();
  69. for(int k = 0; k< 9; k++){
  70. if(elems[k].count > n/10)
  71. elemList.add(elems[k].element);
  72. }
  73. return elemList;
  74. }
  75.  
  76. public static void main(String[] args){
  77. int n = 20;
  78. int[] array = new int[n];
  79. for(int i=0;i<n;i++){
  80. array[i] = StdRandom.uniform(n);
  81. }
  82. System.out.println(Arrays.toString(array));
  83. ElemsMoreThanNDivTenTimes elems = new ElemsMoreThanNDivTenTimes();
  84. ArrayList<Integer> elemList = elems.findElements(array);
  85. System.out.println(elemList.toString());
  86. }
  87. }

Coursera Algorithms week3 快速排序 练习测验: Decimal dominants(寻找出现次数大于n/10的元素)的更多相关文章

  1. Coursera Algorithms week3 快速排序 练习测验: Nuts and bolts

    题目原文: Nuts and bolts. A disorganized carpenter has a mixed pile of n nuts and n bolts. The goal is t ...

  2. Coursera Algorithms week3 快速排序 练习测验: Selection in two sorted arrays(从两个有序数组中寻找第K大元素)

    题目原文 Selection in two sorted arrays. Given two sorted arrays a[] and b[], of sizes n1 and n2, respec ...

  3. Coursera Algorithms week3 归并排序 练习测验: Shuffling a linked list

    题目原文: Shuffling a linked list. Given a singly-linked list containing n items, rearrange the items un ...

  4. Coursera Algorithms week3 归并排序 练习测验: Counting inversions

    题目原文: An inversion in an array a[] is a pair of entries a[i] and a[j] such that i<j but a[i]>a ...

  5. Coursera Algorithms week3 归并排序 练习测验: Merging with smaller auxiliary array

    题目原文: Suppose that the subarray a[0] to a[n-1] is sorted and the subarray a[n] to a[2*n-1] is sorted ...

  6. Coursera Algorithms week1 算法分析 练习测验: Egg drop 扔鸡蛋问题

    题目原文: Suppose that you have an n-story building (with floors 1 through n) and plenty of eggs. An egg ...

  7. Coursera Algorithms week1 算法分析 练习测验: 3Sum in quadratic time

    题目要求: Design an algorithm for the 3-SUM problem that takes time proportional to n2 in the worst case ...

  8. Coursera Algorithms week2 基础排序 练习测验: Dutch national flag 荷兰国旗问题算法

    第二周课程的Elementray Sorts部分练习测验Interview Questions的第3题荷兰国旗问题很有意思.题目的原文描述如下: Dutch national flag. Given ...

  9. Coursera Algorithms week4 基础标签表 练习测验:Inorder traversal with constant extra space

    题目原文: Design an algorithm to perform an inorder traversal of a binary search tree using only a const ...

随机推荐

  1. ArrayAccess(数组式访问)

    实现该接口后,可以像访问数组一样访问对象. 接口摘要: ArrayAccess { abstract public boolean offsetExists ( mixed $offset ) abs ...

  2. 洛谷——P2420 让我们异或吧

    P2420 让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中…xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B ...

  3. ROS lesson 1

    ROS ROS官网 ROS 简介 ROS 是 Robot Operation System 的简写,并且 他诞生在2000年后,至今有10余年了,运行在 Linux(Ubuntu) 上 ROS 不是 ...

  4. python_ 学习笔记(hello world)

    python中的循环语句 循环语句均可以尾随一个else语句块,该块再条件为false后执行一次 如果使用break跳出则不执行. for it in [1,2,3,4]: print(it,end= ...

  5. CCF201512-2 消除类游戏 java(100分)

    试题编号: 201512-2 试题名称: 消除类游戏 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有n行m列的游戏棋盘上进 ...

  6. stall and flow separation on airfoil or blade

    stall stall and flow separation Table of Contents 1. Stall and flow separation 1.1. Separation of Bo ...

  7. JUnit基本用法

    JUnit的一些注意事项: 测试方法必须使用@Test修饰 测试方法必须使用public void进行修饰,不能带参数 一般使用单元测试会新建一个test目录存放测试代码,在生产部署的时候只需要将te ...

  8. HDU 1059 多重背包问题

    问题大意: 有价值1-6的六种物品,分别规定其数目,问是否存在一种方法能使这些物品不拆分就能平均分给两个人 #include <cstdio> #include <cstring&g ...

  9. reids桌面管理工具:RedisDesktopManager下载、使用

    概要:一款好用的Redis桌面管理工具,支持命令控制台操作,以及常用,查询key,rename,delete等操作. 下载软件,请点击下面链接,进入下载页,选择对应版本: https://redisd ...

  10. 公众号开发 jsp中<a>问题

    在开发微信公众号时,使用了jQuery mobile这个框架,但是在jsp页面中使用<a>发现点击跳转不成功,这就很奇怪了,网上搜索发现大家基本上用js来代替<a>跳转功能: ...