Majority Number III
Question:
Given an array of integers and a number k, the majority number is the number that occurs more than 1/k
of the size of the array.
Find it.
Example:
Given [3,1,2,3,2,3,3,4,4,4]
and k=3
, return 3
.
Analysis:
根据题目知道,majority number在数组中的个数要大于 n / k,所以最多只可能有k - 1个majority number(如果有k个,那么k * n / k 大于n,显然是不可能的)。维护一个size是k - 1的HashMap,key是数组中的值,value是该值在数组中的个数。遍历整个数组,如果该值已经在map中,则相对应的value加1。如果不存在,那么先检查map的size是否小于k - 1。是的话将该值添加进map中,然后value设为1。否则我们需要将map中所有key对应的value都减去1,如果value降到0,则从map中删去这个key。当整个数组遍历完,map中的值就是所有的可能的值。
这道题只要找唯一一个值,所以我们遍历map中的所有key,找到value最大的那个key就是我们要找的。
Code:
1 public class Solution { 2 /** 3 * @param nums: A list of integers 4 * @param k: As described 5 * @return: The majority number 6 */ 7 public int majorityNumber(ArrayList<Integer> nums, int k) { 8 if(nums == null || nums.size() == 0) { 9 return Integer.MIN_VALUE; 10 } 11 12 //most k - 1 values in the map 13 HashMap<Integer, Integer> counters = new HashMap<Integer, Integer>(); 14 for(int num : nums) { 15 if(counters.containsKey(num)) { 16 counters.put(num, counters.get(num) + 1); 17 }else { 18 if(counters.size() < k - 1) { 19 counters.put(num, 1); 20 }else { 21 update(counters); 22 } 23 } 24 } 25 26 //corner case 27 if(counters.size() == 0) { 28 return Integer.MIN_VALUE; 29 } 30 31 //clear count 32 for(int key : counters.keySet()) { 33 counters.put(key, 0); 34 } 35 36 //recalculate the counter 37 for(int num : nums) { 38 if(counters.containsKey(num)) { 39 counters.put(num, counters.get(num) + 1); 40 } 41 } 42 43 int result = 0, maxCount = Integer.MIN_VALUE; 44 for(int key : counters.keySet()) { 45 int count = counters.get(key); 46 if(count > maxCount) { 47 result = key; 48 maxCount = count; 49 } 50 } 51 52 return result; 53 } 54 55 private void update(HashMap<Integer, Integer> counters) { 56 ArrayList<Integer> removeList = new ArrayList<Integer>(); 57 for(int key : counters.keySet()) { 58 counters.put(key, counters.get(key) - 1); 59 if(counters.get(key) == 0) { 60 removeList.add(key); 61 } 62 } 63 64 for(int key : removeList) { 65 counters.remove(key); 66 } 67 } 68 }
Complexity:
时间复杂度是O(n * k)。
Reference:
http://www.geeksforgeeks.org/given-an-array-of-of-size-n-finds-all-the-elements-that-appear-more-than-nk-times/