Google-Find Winner
有一个class代表投票,candidate是投给谁,time是投票时间。
class LogEntry {
String candidate;
int time;
}
[Problem]
问题是给一个List<LogEntry>和一个时间,求截止到这个时间为止得票最多的candidate。
[Follow up]
求截止到这个时间为止的top k
[Solution]
典型的k smallest number/quick select 问题
用Hash table存每个candidate的得票数,然后用quick select algorithm
[Time&Space]
O(n) average, O(n^2) worst case
O(n) space
Read full article from Google-Find Winner
有一个class代表投票,candidate是投给谁,time是投票时间。
class LogEntry {
String candidate;
int time;
}
[Problem]
问题是给一个List<LogEntry>和一个时间,求截止到这个时间为止得票最多的candidate。
[Follow up]
求截止到这个时间为止的top k
[Solution]
典型的k smallest number/quick select 问题
用Hash table存每个candidate的得票数,然后用quick select algorithm
[Time&Space]
O(n) average, O(n^2) worst case
O(n) space
class LogEntry { String candidate; int time; public LogEntry(String candidate, int time) { this.candidate = candidate; this.time = time; }}class Solution { public List<String> findKWinner(int time, List<LogEntry> logs, int k) { List<String> result = new ArrayList<>(); if (logs == null || logs.isEmpty()) { return result; } Map<String, Integer> map = new HashMap<>(); for (LogEntry log : logs) { if (log.time <= time) { map.put(log.candidate, map.getOrDefault(log.candidate, 0) + 1); } } List<Map.Entry<String, Integer>> list = new ArrayList<>(); list.addAll(map.entrySet()); int value = kthSmallest(list, 0, list.size() - 1, map.size() - k); for (String candidate : map.keySet()) { if (map.get(candidate) > value) { result.add(candidate); } } return result; } private int kthSmallest(List<Map.Entry<String, Integer>> list, int l, int r, int k) { int index = partition(list, l, r); int cnt = index - l + 1; if (cnt == k) { return list.get(index).getValue(); } else if (cnt > k) { return kthSmallest(list, l, index - 1, k); } else { return kthSmallest(list, index + 1, r, cnt - k); } } private int partition(List<Map.Entry<String, Integer>> list, int l, int r) { int pivot = list.get(l).getValue(); int left = l; int right = r + 1; while (true) { while (++left < r && list.get(left).getValue() < pivot); while (--right > l && list.get(right).getValue() > pivot); if (left < right) { swap(list, left, right); } else{ break; } } swap(list, right, l); return right; } private void swap(List<Map.Entry<String, Integer>> list, int l, int r) { Map.Entry<String, Integer> tmp = list.get(l); list.set(l, list.get(r)); list.set(r, tmp); }}