-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathonline-election.cpp
123 lines (107 loc) · 2.84 KB
/
online-election.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* Copyright (c) 2018 Christopher Friedt
*
* SPDX-License-Identifier: MIT
*/
#include <cstdlib>
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
// https://leetcode.com/problems/online-election/
class TopVotedCandidate {
protected:
struct ent {
int time;
int candidate; // candidate who received vote at 'time' (i.e. most recent)
int leader;
int leader_count;
ent() : time(0), candidate(0), leader(0), leader_count(0) {}
ent(int time, int candidate, int leader,
int leader_count /* , unordered_map<int,int> tally */)
: time(time), candidate(candidate), leader(leader),
leader_count(leader_count) /* , tally( tally ) */
{}
};
public:
TopVotedCandidate(vector<int> &persons, vector<int> ×) : times(times) {
size_t N = times.size();
ea = vector<ent>(N, ent());
unordered_map<int, int> tally;
for (size_t i = 0; i < N; i++) {
int leader_count;
int leader;
if (0 == i) {
leader_count = -1;
leader = -1;
} else {
leader_count = ea[i - 1].leader_count;
leader = ea[i - 1].leader;
}
int candidate = persons[i];
auto it = tally.find(candidate);
if (tally.end() == it) {
tally[candidate] = 1;
} else {
it->second++;
}
if (tally[candidate] >= leader_count) {
leader_count = tally[candidate];
leader = candidate;
// cerr << "candidate " << candidate << " took the lead at time " <<
// times[ i ] << " with a score of " << leader_count << endl;
}
ea[i] = ent(times[i], candidate, leader, leader_count);
}
}
static int compare(int t, int t1, int t2) {
if (t >= t1 && (-1 == t2 || t < t2)) {
return 0;
}
if (t < t1) {
return -1;
}
// -1 != t2 && t >= t2
return +1;
}
int q(int t) {
int i = 0;
for (int L = 0, U = times.size() - 1; L <= U;) {
int M = (L + U) / 2;
int direction =
compare(t, times[M], (M < (int)times.size() - 1) ? times[M + 1] : -1);
if (0 == direction) {
i = M;
break;
}
if (direction < 0) {
U = M;
}
if (direction > 0) {
if (U - L == 1 && M == L) {
L = U;
} else {
L = M;
}
}
}
return ea[i].leader;
}
protected:
vector<int> times;
vector<ent> ea;
static unordered_map<int, int> add(const unordered_map<int, int> &a,
const unordered_map<int, int> &b) {
unordered_map<int, int> c = a;
for (auto &kv : b) {
c[kv.first] += kv.second;
}
return c;
}
};
/**
* Your TopVotedCandidate object will be instantiated and called as such:
* TopVotedCandidate* obj = new TopVotedCandidate(persons, times);
* int param_1 = obj->q(t);
*/