Online Election

Similar Problems:

In 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 <= 5000
- 0 <= persons[i] <= persons.length
- times 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].

Github: code.dennyzhang.com

Credits To: leetcode.com

Leave me comments, if you have better ways to solve.

- Solution:

// https://code.dennyzhang.com/online-election // Basic Ideas: binarysearch // candidates[n]: get the top voted candidate for the given timestamp // Complexity: Time O(log(n)), Space O(n) type TopVotedCandidate struct { persons []int times []int candidates []int } func Constructor(persons []int, times []int) TopVotedCandidate { candidates := make([]int, len(persons)) m := map[int]int{} index := 0 for i, p := range persons { m[p]++ if m[p] >= m[persons[index]] { index = i } candidates[i] = persons[index] } return TopVotedCandidate{persons:persons, times:times, candidates:candidates} } func (this *TopVotedCandidate) Q(t int) int { // binarysearch: search insert location left, right := 0, len(this.times)-1 // 0, 5, 10, 15, 20; 12 for left<right { mid := (right-left)/2+left if this.times[mid] == t { return this.candidates[mid] } if this.times[mid] > t { // left half right = mid } else { left = mid+1 } } if this.times[left] <= t { return this.candidates[left] } else { return this.candidates[left-1] } } /** * Your TopVotedCandidate object will be instantiated and called as such: * obj := Constructor(persons, times); * param_1 := obj.Q(t); */