You are given two integer arrays persons
and times
. In an election, the ith
vote was cast for persons[i]
at time times[i]
.
For each query at a time t
, find the person that was leading the election at time t
. Votes cast at time t
will count towards our query. In the case of a tie, the most recent vote (among tied candidates) wins.
Implement the TopVotedCandidate
class:
TopVotedCandidate(int[] persons, int[] times)
Initializes the object with the persons
and times
arrays.int q(int t)
Returns the number of the person that was leading the election at time t
according to the mentioned rules.
Example 1:
Input ["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]] Output [null, 0, 1, 1, 0, 0, 1] Explanation TopVotedCandidate topVotedCandidate = new TopVotedCandidate([0, 1, 1, 0, 0, 1, 0], [0, 5, 10, 15, 20, 25, 30]); topVotedCandidate.q(3); // return 0, At time 3, the votes are [0], and 0 is leading. topVotedCandidate.q(12); // return 1, At time 12, the votes are [0,1,1], and 1 is leading. topVotedCandidate.q(25); // return 1, At time 25, the votes are [0,1,1,0,0,1], and 1 is leading (as ties go to the most recent vote.) topVotedCandidate.q(15); // return 0 topVotedCandidate.q(24); // return 0 topVotedCandidate.q(8); // return 1
Constraints:
1 <= persons.length <= 5000
times.length == persons.length
0 <= persons[i] < persons.length
0 <= times[i] <= 109
times
is sorted in a strictly increasing order.times[0] <= t <= 109
104
calls will be made to q
.This problem requires designing a data structure that efficiently handles queries about the leading candidate in an election at various points in time. The solution utilizes a combination of preprocessing and binary search for optimal performance.
Approach:
The core idea is to preprocess the input data to create a lookup table that stores the leading candidate at each time point. This preprocessing step allows us to answer queries in logarithmic time, significantly improving efficiency compared to repeatedly processing the entire vote history for each query.
Preprocessing:
persons
and times
arrays simultaneously.Counter
(Python) or a similar data structure (other languages).wins
. This forms our lookup table.Querying (q
function):
t
, we use binary search on the times
array to find the index i
such that times[i] <= t
and times[i+1] > t
(or times[i]
is the last element if t
is greater than all times).t
is then simply wins[i]
.Time Complexity Analysis:
__init__
(Constructor): The preprocessing step iterates through the persons
and times
arrays once, which takes O(n) time, where n is the number of votes.q
(Query): The binary search on the times
array takes O(log n) time.Space Complexity Analysis:
wins
array (or list) stores the leading candidate for each time point, requiring O(n) space.cnt
array (or similar data structure) used for vote counting during preprocessing also requires O(n) space in the worst case (all candidates are unique).Code Implementation (Python):
from collections import Counter
import bisect
class TopVotedCandidate:
def __init__(self, persons: List[int], times: List[int]):
self.times = times
self.wins = []
cnt = Counter()
leader = -1 # Initialize leader
for i, person in enumerate(persons):
cnt[person] += 1
if leader == -1 or cnt[person] >= cnt[leader]:
leader = person #Tie goes to the most recent
self.wins.append(leader)
def q(self, t: int) -> int:
index = bisect_right(self.times, t) -1 #Find the index of the greatest time less than or equal to t
return self.wins[index]
Other Languages: The implementations in Java, C++, Go, and TypeScript follow the same logic, adapting the data structures and binary search implementations to their respective language features. The core algorithm remains consistent. See the original response for those implementations.
This solution efficiently handles the online election problem by leveraging preprocessing and binary search, achieving a time complexity of O(n) for initialization and O(log n) for each query. The space complexity is O(n).