Problem
n an election, theĀ i-thĀ vote was cast forĀ persons[i]Ā at timeĀ times[i].
Now, we would like to implement the following query function:Ā TopVotedCandidate.q(int t)Ā will return the number of 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.
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: At time 3, the votes are [0], and 0 is leading. At time 12, the votes are [0,1,1], and 1 is leading. At time 25, the votes are [0,1,1,0,0,1], and 1 is leading (as ties go to the most recent vote.) This continues for 3 more queries at time 15, 24, and 8.
Note:
1 <= persons.length = times.length <= 50000 <= persons[i] <= persons.lengthtimesĀ is a strictly increasing array with all elements inĀ[0, 10^9].TopVotedCandidate.qĀ is called at mostĀ10000Ā times per test case.TopVotedCandidate.q(int t)Ā is always called withĀt >= times[0].
Solution: HashTable + Binary Search
Compute the leads for each t in times using a hash table.
binary search the upper bound of t, and return the lead of previous entry.
Time complexity: Constructor O(n), Query: O(logn)
Space complexity: O(n)
C++
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Author: Huahua class TopVotedCandidate { public: TopVotedCandidate(vector<int> persons, vector<int> times) { vector<int> votes(persons.size() + 1); int last_lead = persons.front(); for (int i = 0; i < persons.size(); ++i) { if (++votes[persons[i]] >= votes[last_lead]) last_lead = persons[i]; leads_[times[i]] = last_lead; } } int q(int t) { return prev(leads_.upper_bound(t))->second; } private: map<int, int> leads_; // time -> lead }; |






