Buttercola: Indeed: Find elements more than K times
Given m sorted lists, find out the elements more than k times. If an element appear more than once in a list, count it only once.
Example:
1->2->2->4
2->3->4
3->3->4
k = 2
Output:
2 (appear twice)
3 (appear twice)
4 (appear 3 times)
Naive Solution:
Use a HashMap 做 词频统计,注意每一个list 相同的值只统计一次。最后再扫一遍Map, 对 大于等于 k 的elements 输出。
时间复杂度:统计词频 O(n * m). 输出 freq >= k,最坏情况 O(n * m). 每个数字只出现了一次。Overall, O(n * m)
空间复杂度: O(n * m).
A space efficient solution:
Naive 的方法的问题在于如果n 很长(题目的假设),这样子空间的开销太大。有没有少用空间的方法?
Use a min-heap. 类似于merge k-sorted lists的方法。首先把每个list的第一个元素放入min PQ 中去。
Read full article from Buttercola: Indeed: Find elements more than K times
Given m sorted lists, find out the elements more than k times. If an element appear more than once in a list, count it only once.
Example:
1->2->2->4
2->3->4
3->3->4
k = 2
Output:
2 (appear twice)
3 (appear twice)
4 (appear 3 times)
Naive Solution:
Use a HashMap 做 词频统计,注意每一个list 相同的值只统计一次。最后再扫一遍Map, 对 大于等于 k 的elements 输出。
时间复杂度:统计词频 O(n * m). 输出 freq >= k,最坏情况 O(n * m). 每个数字只出现了一次。Overall, O(n * m)
空间复杂度: O(n * m).
A space efficient solution:
Naive 的方法的问题在于如果n 很长(题目的假设),这样子空间的开销太大。有没有少用空间的方法?
Use a min-heap. 类似于merge k-sorted lists的方法。首先把每个list的第一个元素放入min PQ 中去。
List<Integer> findMoreThanKTimes(List<List<Integer>> lists, int k) { if (lists == null || lists.size() == 0) { return null; } List<Integer> result = new ArrayList<>(); PriorityQueue<Node> minPQ = new PriorityQueue<>(new MyNodeComparator()); // step 1: put the first node of each list into the queue for (List<Integer> list : lists) { if (list != null && !list.isEmpty()) { minPQ.offer(new Node(list.iterator())); } } while (!minPQ.isEmpty()) { Node curr = minPQ.poll(); int currVal = curr.val; int count = 1; // put the next node into pq, skip the repeated element while (curr.iterator.hasNext()) { int nextVal = curr.iterator.next(); if (currVal == nextVal) { continue; } else { curr.val = nextVal; minPQ.offer(curr); break; } } // get all repeated elements from the pq while (!minPQ.isEmpty() && currVal == minPQ.peek().val) { count++; Node node = minPQ.poll(); int nodeVal = node.val; // put the next node into pq, skip the repeated elements while (node.iterator.hasNext()) { int nextNodeVal = node.iterator.next(); if (nodeVal == nextNodeVal) { continue; } else { node.val = nextNodeVal; minPQ.offer(node); break; } } } if (count >= k) { result.add(currVal); } } return result; } class MyNodeComparator implements Comparator<Node>{ @Override public int compare(Node a, Node b) { return a.val - b.val; } } class Node { int val; Iterator<Integer> iterator; public Node(Iterator<Integer> iterator) { this.iterator = iterator; val = iterator.next(); } }