题目
类型:design
解题思路
- 根据题意,会在
times[i]时刻为persons[i]候选人增加一票。 - 利用
times数组严格递增,可以在处理times时(模拟加票过程),使用一个变量 val 来维护当前得票的最大数量,使用 list 来记录不同时刻点的候选人交替情况。 - 起始时 val = 0,当出现票数大于等于 val 时,往 list 追加二元组记录
list[idx] = (times[i], persons[i]),并更新 val。
每个list[idx]代表了当前候选人list[idx][1] 的首次当选时刻为 list[idx][0]。
若 i = list[idx][0], j = list[idx + 1][0],则意味着在时间段 [i, j) 内当选的候选人为list[idx][1]。
在查询时,只需要通过「二分」找到 list 中满足 list[i][0]<=t 的分割点 r(最大下标),取list[r][1]即是答案。
代码
class TopVotedCandidate {List<Integer> tops;Map<Integer, Integer> voteCounts;int[] times;public TopVotedCandidate(int[] persons, int[] times) {tops = new ArrayList<Integer>();voteCounts = new HashMap<Integer, Integer>();voteCounts.put(-1, -1);int top = -1;for (int i = 0; i < persons.length; ++i) {int p = persons[i];voteCounts.put(p, voteCounts.getOrDefault(p, 0) + 1);if (voteCounts.get(p) >= voteCounts.get(top)) {top = p;}tops.add(top);}this.times = times;}public int q(int t) {int l = 0, r = times.length - 1;// 找到满足 times[l] <= t 的最大的 lwhile (l < r) {int m = l + (r - l + 1) / 2;if (times[m] <= t) {l = m;} else {r = m - 1;}}return tops.get(l);}}
