6
6
7
7
<!-- 这里写题目描述 -->
8
8
9
- <p >在选举中,第  ; <code >i</code >  ; 张票是在时间为   ; <code >times[i]</code >  ; 时投给 & nbsp ; <code >persons[i]</code >  ; 的。</p >
9
+ <p >给你两个整数数组 < code >persons</ code > 和 < code >times</ code > 。 在选举中,第  ; <code >i</code >  ; 张票是在时刻为   ; <code >times[i]</code >  ; 时投给候选人 <code >persons[i]</code >  ; 的。</p >
10
10
11
- <p >现在,我们想要实现下面的查询函数: <code >TopVotedCandidate.q(int t) </code > 将返回在   ; <code >t</code > 时刻主导选举的候选人的编号 。</p >
11
+ <p >对于发生在时刻 <code >t </code > 的每个查询,需要找出在   ; <code >t</code > 时刻在选举中领先的候选人的编号 。</p >
12
12
13
13
<p >在  ; <code >t</code > 时刻投出的选票也将被计入我们的查询之中。在平局的情况下,最近获得投票的候选人将会获胜。</p >
14
14
15
+ <p >实现 <code >TopVotedCandidate</code > 类:</p >
16
+
17
+ <ul >
18
+ <li><code>TopVotedCandidate(int[] persons, int[] times)</code> 使用 <code>persons</code> 和 <code>times</code> 数组初始化对象。</li>
19
+ <li><code>int q(int t)</code> 根据前面描述的规则,返回在时刻 <code>t</code> 在选举中领先的候选人的编号。</li>
20
+ </ul >
21
+   ;
22
+
15
23
<p ><strong >示例:</strong ></p >
16
24
17
- <pre ><strong >输入:</strong >[" ; 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]]
18
- <strong >输出:</strong >[null,0,1,1,0,0,1]
25
+ <pre >
26
+ <strong >输入:</strong >
27
+ ["TopVotedCandidate", "q", "q", "q", "q", "q", "q"]
28
+ [[[0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]], [3], [12], [25], [15], [24], [8]]
29
+ <strong >输出:</strong >
30
+ [null, 0, 1, 1, 0, 0, 1]
31
+
19
32
<strong >解释:</strong >
20
- 时间为 3,票数分布情况是 [0],编号为 0 的候选人领先。
21
- 时间为 12,票数分布情况是 [0,1,1],编号为 1 的候选人领先。
22
- 时间为 25,票数分布情况是 [0,1,1,0,0,1],编号为 1 的候选人领先(因为最近的投票结果是平局)。
23
- 在时间 15、24 和 8 处继续执行 3 个查询。
33
+ TopVotedCandidate topVotedCandidate = new TopVotedCandidate([0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]);
34
+ topVotedCandidate.q(3); // 返回 0 ,在时刻 3 ,票数分布为 [0] ,编号为 0 的候选人领先。
35
+ topVotedCandidate.q(12); // 返回 1 ,在时刻 12 ,票数分布为 [0,1,1] ,编号为 1 的候选人领先。
36
+ topVotedCandidate.q(25); // 返回 1 ,在时刻 25 ,票数分布为 [0,1,1,0,0,1] ,编号为 1 的候选人领先。(在平局的情况下,1 是最近获得投票的候选人)。
37
+ topVotedCandidate.q(15); // 返回 0
38
+ topVotedCandidate.q(24); // 返回 0
39
+ topVotedCandidate.q(8); // 返回 1
24
40
</pre >
25
41
26
42
<p >  ; </p >
27
43
28
44
<p ><strong >提示:</strong ></p >
29
45
30
- <ol >
31
- <li><code>1 <= persons.length = times.length <= 5000</code></li>
32
- <li><code>0 <= persons[i] <= persons.length</code></li>
33
- <li><code>times</code> 是严格递增的数组,所有元素都在 <code>[0, 10^9]</code> 范围中。</li>
34
- <li>每个测试用例最多调用 <code>10000</code> 次 <code>TopVotedCandidate.q</code>。</li>
35
- <li><code>TopVotedCandidate.q(int t)</code> 被调用时总是满足 <code>t >= times[0]</code>。</li>
36
- </ol >
46
+ <ul >
47
+ <li><code>1 <= persons.length <= 5000</code></li>
48
+ <li><code>times.length == persons.length</code></li>
49
+ <li><code>0 <= persons[i] < persons.length</code></li>
50
+ <li><code>0 <= times[i] <= 10<sup>9</sup></code></li>
51
+ <li><code>times</code> 是一个严格递增的有序数组</li>
52
+ <li><code>times[0] <= t <= 10<sup>9</sup></code></li>
53
+ <li>每个测试用例最多调用 <code>10<sup>4</sup></code> 次 <code>q</code></li>
54
+ </ul >
37
55
38
56
## 解法
39
57
40
58
<!-- 这里可写通用的实现逻辑 -->
41
59
60
+ 二分查找。
61
+
62
+ 先预处理得到每个时刻的领先的候选人编号 ` wins[i] ` 。
63
+
64
+ 然后对于每次查询 q,二分查找得到小于等于 t 时刻的最大时刻 left,返回 ` wins[left] ` 即可。
65
+
42
66
<!-- tabs:start -->
43
67
44
68
### ** Python3**
49
73
class TopVotedCandidate :
50
74
51
75
def __init__ (self , persons : List[int ], times : List[int ]):
76
+ mx = cur = 0
77
+ counter = Counter()
52
78
self .times = times
53
- mx, cur_win, n = - 1 , - 1 , len (persons)
54
- counter = [0 ] * (n + 1 )
55
- self .win_persons = [0 ] * n
79
+ self .wins = [0 ] * len (persons)
56
80
for i, p in enumerate (persons):
57
81
counter[p] += 1
58
82
if counter[p] >= mx:
59
- mx = counter[p]
60
- cur_win = p
61
- self .win_persons[i] = cur_win
83
+ mx, cur = counter[p], p
84
+ self .wins[i] = cur
62
85
63
86
def q (self , t : int ) -> int :
64
- left, right = 0 , len (self .win_persons ) - 1
87
+ left, right = 0 , len (self .wins ) - 1
65
88
while left < right:
66
89
mid = (left + right + 1 ) >> 1
67
90
if self .times[mid] <= t:
68
91
left = mid
69
92
else :
70
93
right = mid - 1
71
- return self .win_persons[left]
94
+ return self .wins[left]
95
+
72
96
73
97
# Your TopVotedCandidate object will be instantiated and called as such:
74
98
# obj = TopVotedCandidate(persons, times)
@@ -126,35 +150,35 @@ class TopVotedCandidate {
126
150
class TopVotedCandidate {
127
151
public:
128
152
vector<int > times;
129
- vector<int > winPersons ;
153
+ vector<int > wins ;
130
154
131
155
TopVotedCandidate(vector<int>& persons, vector<int>& times) {
132
- this->times = times;
133
- int mx = -1, curWin = -1;
134
156
int n = persons.size();
135
- vector<int> counter(n + 1);
136
- winPersons.resize(n);
157
+ wins.resize(n);
158
+ int mx = 0, cur = 0;
159
+ this->times = times;
160
+ vector<int> counter(n);
137
161
for (int i = 0; i < n; ++i)
138
162
{
139
- if (++counter[persons[i]] >= mx)
163
+ int p = persons[i];
164
+ if (++counter[p] >= mx)
140
165
{
141
- mx = counter[persons[i] ];
142
- curWin = persons[i] ;
166
+ mx = counter[p ];
167
+ cur = p ;
143
168
}
144
- winPersons [i] = curWin ;
169
+ wins [i] = cur ;
145
170
}
146
-
147
171
}
148
172
149
173
int q (int t) {
150
- int left = 0, right = winPersons .size() - 1;
174
+ int left = 0, right = wins .size() - 1;
151
175
while (left < right)
152
176
{
153
- int mid = ( left + right + 1) >> 1;
177
+ int mid = left + right + 1 >> 1;
154
178
if (times[ mid] <= t) left = mid;
155
179
else right = mid - 1;
156
180
}
157
- return winPersons [ left] ;
181
+ return wins [ left] ;
158
182
}
159
183
};
160
184
@@ -169,29 +193,27 @@ public:
169
193
170
194
```go
171
195
type TopVotedCandidate struct {
172
- times []int
173
- winPersons []int
196
+ times []int
197
+ wins []int
174
198
}
175
199
176
200
func Constructor(persons []int, times []int) TopVotedCandidate {
177
- mx, curWin , n := -1, -1 , len(persons)
178
- counter := make([]int, n+1 )
179
- winPersons := make([]int, n)
201
+ mx, cur , n := 0, 0 , len(persons)
202
+ counter := make([]int, n)
203
+ wins := make([]int, n)
180
204
for i, p := range persons {
181
205
counter[p]++
182
206
if counter[p] >= mx {
183
207
mx = counter[p]
184
- curWin = p
208
+ cur = p
185
209
}
186
- winPersons[i] = curWin
187
- }
188
- return TopVotedCandidate{
189
- times, winPersons,
210
+ wins[i] = cur
190
211
}
212
+ return TopVotedCandidate{times, wins}
191
213
}
192
214
193
215
func (this *TopVotedCandidate) Q(t int) int {
194
- left, right := 0, len(this.winPersons )-1
216
+ left, right := 0, len(this.wins )-1
195
217
for left < right {
196
218
mid := (left + right + 1) >> 1
197
219
if this.times[mid] <= t {
@@ -200,7 +222,7 @@ func (this *TopVotedCandidate) Q(t int) int {
200
222
right = mid - 1
201
223
}
202
224
}
203
- return this.winPersons [left]
225
+ return this.wins [left]
204
226
}
205
227
206
228
/**
0 commit comments