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

题目原文:

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     
20     public ArrayList<Integer> findElements(int[] arrays){
21         int n = arrays.length;
22         for(int k=0;k<9;k++){
23             elems[k] = new Element(0,0); //辅助空间初始化
24         }
25         for(int i=0;i<n;i++){
26             int index = findIndex(arrays[i]);
27             if(index >= 0)
28                 elems[index].count ++;
29             else
30                 addToElems(arrays[i]);
31         }
32         return verifyElems(arrays);
33     }
34     
35     private int findIndex(int e){
36         for(int k = 0; k<9;k++){
37             if(elems[k].element == e)
38                 return k;
39             else if(elems[k].count == 0){
40                 elems[k].element = e;
41                 return k;
42             }
43         }
44         return -1;
45     }
46     private void addToElems(int e){
47         boolean insertFlag = false;
48         while(!insertFlag){
49             for(int k=0; k<9;k++){
50                 elems[k].count --;
51                 if(elems[k].count <= 0){
52                     elems[k].element = e;
53                     elems[k].count = 1;
54                     insertFlag = true;
55                     break;
56                 }
57             }
58         }
59     }
60     private ArrayList<Integer> verifyElems(int[] arrays){
61         int n = arrays.length;
62         for(int k = 0; k< 9; k++){
63             elems[k].count = 0;
64             for(int i = 0; i< n;i++){
65                 if(arrays[i]==elems[k].element)
66                     elems[k].count++;
67             }
68         }
69         ArrayList<Integer> elemList = new ArrayList<Integer>();
70         for(int k = 0; k< 9; k++){
71             if(elems[k].count > n/10)
72                 elemList.add(elems[k].element);
73         }
74         return elemList;
75     }
76     
77     public static void main(String[] args){
78         int n = 20;
79         int[] array = new int[n];
80         for(int i=0;i<n;i++){
81             array[i] = StdRandom.uniform(n);
82         }
83         System.out.println(Arrays.toString(array));
84         ElemsMoreThanNDivTenTimes elems = new ElemsMoreThanNDivTenTimes();
85         ArrayList<Integer> elemList =  elems.findElements(array);
86         System.out.println(elemList.toString());
87     }
88 }

 

posted @ 2017-08-02 14:51  evasean  阅读(1412)  评论(0编辑  收藏  举报