LeetCode:347. Top K Frequent Elements(找出出現頻率最高的K個數)
阿新 • • 發佈:2018-11-23
Given a non-empty array of integers, return the k most frequent elements.
Example 1:
Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]
Example 2:
Input: nums = [1], k = 1
Output: [1]
Note:
- You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
- Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
方法一:利用自己的方法做了一遍;
思路:
1.用map儲存數字關鍵字和出現的次數;
2.然後將value值儲存到list當中,對它進行逆序排序;
3.通過value值的大小,找出key的值,存入到newList當中,然後返回newList
class Solution { public List<Integer> topKFrequent(int[] nums, int k) { Map<Integer, Integer> map = computeAppearTimes(nums); List<Integer> list = getReverseSortList(map); List<Integer> newList = new ArrayList<Integer>(); for (int i = 0; i < k; i++) { for (int key : map.keySet()) { if (map.get(key) == list.get(i)) { newList.add(key); map.put(key, 0); } } } return newList; } // 將value儲存到連結串列,並倒序排列 public List getReverseSortList(Map<Integer, Integer> map) { List<Integer> list = new ArrayList<Integer>(); for (int i : map.keySet()) { list.add(map.get(i)); } Collections.sort(list); Collections.reverse(list); return list; } // 出現次數用表儲存起來 private Map<Integer, Integer> computeAppearTimes(int[] arr) { Map<Integer, Integer> map = new TreeMap(); for (int i = 0; i < arr.length; i++) { if (!map.keySet().contains(arr[i])) { map.put(arr[i], 1); } else { map.put(arr[i], map.get(arr[i]) + 1); } } return map; } }
時間複雜度:O(log(n).n)
空間複雜度:O(n)
顯然這種效率不是很高,實現起來比較容易;
我看了,答案當中有堆排序,桶排序的實現,實現思路如下:
方法二:(效率肯定比第一種高,雖然時間複雜度是一樣) 利用堆和hashmap兩種資料結構方式實現
class Solution { public List<Integer> topKFrequent(int[] nums, int k) { List<Integer> result = new ArrayList<>(); if (nums.length == 0) { return result; } HashMap<Integer, Integer> map = getfreqmap(nums); PriorityQueue<Map.Entry<Integer, Integer>> minheap = new PriorityQueue<Map.Entry<Integer, Integer>>(k, new Comparator<Map.Entry<Integer, Integer>>() { public int compare(Map.Entry<Integer, Integer> e1, Map.Entry<Integer, Integer> e2) { return e1.getValue().compareTo(e2.getValue()); } }); for (Map.Entry<Integer, Integer> entry: map.entrySet()) { if (minheap.size() < k) { minheap.offer(entry); } else { if (entry.getValue() > minheap.peek().getValue()) { minheap.poll(); minheap.offer(entry); } } } while (!minheap.isEmpty()) { result.add(0, minheap.poll().getKey()); } return result; } private HashMap<Integer, Integer> getfreqmap(int[] nums) { HashMap<Integer, Integer> map = new HashMap<>(); for (int num: nums) { Integer count = map.get(num); if (count == null) { map.put(num, 1); } else { map.put(num, count + 1); } } return map; } }
時間複雜度:O(n.log(n))
空間複雜度:O(n)
方法三:利用桶排序的思路實現
class Solution {
public List<Integer> topKFrequent(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
List<Integer>[] bucket = new List[nums.length+1];
for (int num : nums) {
map.put(num, map.getOrDefault(num,0)+1);
}
for (int num : map.keySet()) {
int freq = map.get(num);
if (bucket[freq] == null) {
bucket[freq] = new ArrayList<Integer>();
}
bucket[freq].add(num);
}
List<Integer> res = new ArrayList<>();
for (int i = nums.length; i >= 0 && res.size() < k; i--) {
if(bucket[i] != null) {
res.addAll(bucket[i]);
}
}
return res;
}
}
時間複雜度:O(n)
空間複雜度:O(kn)