Google interview question: countSort questions
除了mergeSort, quickSort等这类基于比较的O(Nlog(N))排序算法,对于不同的情形,很多其他的排序算法会在面试题中出现。其中常见的有bucket sort, radix sort, count sort等。这篇文章将总结一些和count sort有关的面试题。
Count sort是一种时间复杂度为O(N),空间复杂度为O(M)的排序算法,其中M是排序中元素的最大值。Count sort是一种对自然数的排序,一般用于对non-negtive integers,并且最大值确定在一定范围内的数据进行排序。因此,在适用范围内,count sort是一种高效的排序算法,并且其实现也非常简洁。
Question 1:
Given an unsorted array of natural numbers. Where numbers repeat in array. Out put numbers in the order of frequency. Where number of out put is passed as parameter.
For Ex:
Array -> [0, 0, 100, 3, 5, 4, 6, 4, 2, 100, 2, 100]
n -> 2
Out put -> [100, 0] or [100, 2]
Since 100 is repeated 3 times and 0, 2 is repeated 2 times, out put up to 2 most frequent elements, program should out put either 100, 0 or 100, 2
从题中我们可以得出结论:1. 数据元素的频率是non-negtive integer;2. 数据元素的频率不大于数据的长度,即M<=N。因此,这题可以先用hashMap记录每个元素的频率,然后用count sort来解决。
public class CountSort1 { public static void main(String arcg[]){ int[] array = {0,0,100,3,5,4,6,4,2,100,2,100}; countsort(array, 2); } public static void countsort(int[] array, int n){ Map<Integer,Integer> map = new HashMap<Integer, Integer>(); int range = 0; for(int i:array){ if(!map.containsKey(i)) map.put(i, 1); else map.put(i, map.get(i)+1); range = Math.max(range, map.get(i)); } int[] count = new int[range+1]; for(Map.Entry<Integer, Integer> entry:map.entrySet()){ count[entry.getValue()]++; } for(int i=1;i<count.length;i++){ count[i] += count[i-1]; } Entry[] res = new Entry[map.size()]; for(Map.Entry<Integer, Integer> entry:map.entrySet()){ res[--count[entry.getValue()]] = entry; } for(int i=res.length-1;i>res.length-1-n;i--){ System.out.println(res[i].getKey()); } } }
Question 2:
Given an unsorted array of integers, you need to return maximum possible n such that the array consists at least n values greater than or equals to n. Array can contain duplicate values.
Sample input : [1, 2, 3, 4] -- output : 2
Sample input : [900, 2, 901, 3, 1000] -- output: 3
这题即上一篇的selection questions中的面试题。在上一篇中,介绍了如何用selection algorithm解决这个问题。其实,这题也可以用count sort的思想来解决。
从题中我们可以得出结论:1. n是non-negtive integer,n不可能小于0;2. n不会大于数组的长度,即M<=N。对于大于数组长度的元素,只需当做等于数组长度来处理即可。
public class countSort2 { public static void main(String arcg[]){ int[] array = {1,2,3,4}; //int[] array = {900,2,901,3,1000}; System.out.println(countSort(array)); } public static int countSort(int[] array){ int[] count = new int[array.length+1]; for(int n:array){ if(n>=array.length) count[array.length]++; else count[n]++; } int res = 0; for(int i=count.length-1;i>0;i--){ res+=count[i]; if(res>=i) return i; } return 0; } }
与selection algorithm做法的区别在于这个方法的空间复杂度为O(N),而selection algorithm的空间复杂度为O(1),因此selection algorithm理论上是更好地做法。但运用count sort的思路使得代码更简洁,不容易出错。在面试中也可以提出两种做法进行分析。