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();
}
}