911. 在线选举
给你两个整数数组 persons
和 times
。在选举中,第 i
张票是在时刻为 times[i]
时投给候选人 persons[i]
的。
对于发生在时刻 t
的每个查询,需要找出在 t
时刻在选举中领先的候选人的编号。
在 t
时刻投出的选票也将被计入我们的查询之中。在平局的情况下,最近获得投票的候选人将会获胜。
实现 TopVotedCandidate
类:
-
TopVotedCandidate(int[] persons, int[] times)
使用persons
和times
数组初始化对象。 -
int q(int t)
根据前面描述的规则,返回在时刻t
在选举中领先的候选人的编号。
示例:
输入: ["TopVotedCandidate", "q", "q", "q", "q", "q", "q"] [[[0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]], [3], [12], [25], [15], [24], [8]] 输出: [null, 0, 1, 1, 0, 0, 1] 解释: TopVotedCandidate topVotedCandidate = new TopVotedCandidate([0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]); topVotedCandidate.q(3); // 返回 0 ,在时刻 3 ,票数分布为 [0] ,编号为 0 的候选人领先。 topVotedCandidate.q(12); // 返回 1 ,在时刻 12 ,票数分布为 [0,1,1] ,编号为 1 的候选人领先。 topVotedCandidate.q(25); // 返回 1 ,在时刻 25 ,票数分布为 [0,1,1,0,0,1] ,编号为 1 的候选人领先。(在平局的情况下,1 是最近获得投票的候选人)。 topVotedCandidate.q(15); // 返回 0 topVotedCandidate.q(24); // 返回 0 topVotedCandidate.q(8); // 返回 1
提示:
1 <= persons.length <= 5000
times.length == persons.length
0 <= persons[i] < persons.length
0 <= times[i] <= 109
-
times
是一个严格递增的有序数组 times[0] <= t <= 109
- 每个测试用例最多调用
104
次q
1 import java.util.HashMap; 2 3 public class TopVotedCandidate { 4 int n=0; 5 int[] ans,time; 6 public TopVotedCandidate(int[] persons, int[] times) { 7 ans=new int[times.length]; 8 n= times.length; 9 time=times; 10 //ans记录每个时间点票数最多的人 11 int indicate=-1,MAX=-1; 12 HashMap<Integer, Integer> map = new HashMap<>(); 13 //记录每个人的票数,维护每个时间段票数最多者 14 for (int i = 0; i < persons.length; i++) { 15 map.put(persons[i],map.getOrDefault(persons[i],0)+1); 16 if (indicate==-1){ 17 indicate=persons[i]; 18 MAX=map.get(persons[i]); 19 }else if (map.get(persons[i])>=MAX){ 20 MAX=map.get(persons[i]); 21 indicate=persons[i]; 22 } 23 //选出最多者的号码,并存入ans数组中 24 ans[i]=indicate; 25 } 26 } 27 28 public int q(int t) { 29 //二分查找t时间最近的时间点 30 int l=0,r=n-1; 31 while (l<=r){ 32 int mid=(l+r)/2; 33 if (time[mid]>t){ 34 r=mid-1; 35 }else if(time[mid]<t){ 36 l=mid+1; 37 }else{ 38 return ans[mid]; 39 } 40 } 41 return ans[r]; 42 } 43 44 public static void main(String[] args) { 45 int[] p={0, 1, 0, 1, 1}; 46 int[] t={24,29,31,76,81}; 47 int[] test={28,24,29,77,30,25,76,75,81,80}; 48 TopVotedCandidate topVotedCandidate = new TopVotedCandidate(p, t); 49 for (int j : test) { 50 System.out.println(topVotedCandidate.q(j)); 51 } 52 } 53 }
需要注意的是二分法寻找左边界的处理、
while (l<=r)对应l==r 的情况,所以返回ans[r]和ans[l]都是一样的
l<=r对应的r为n-1,如果r=n,则应为l<r
同时也对应mid是否应该加减1