In an election, the i
-th vote was cast for persons[i]
at time times[i]
.html
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
. git
Votes cast at time t
will count towards our query. In the case of a tie, the most recent vote (among tied candidates) wins.github
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]
.
這道題是關於線上選舉的問題,這年頭感受選舉都是得網絡者得天下啊,不少都是先在網上造成了一股潮流,好比美國的特朗普,英國的約翰遜,臺灣的韓國瑜等等,感受各個都是社交媒體上的紅人,不走尋常路啊。扯遠了,拉回本題,其實剛開始博主看了幾遍題目,愣是沒理解題意,因而去論壇上逛逛,發現也有好多人不清楚,內心稍微舒坦點。這裏給了兩個數組 persons 和 times,表示在某個時間點 times[i],i這我的把選票投給了 persons[i],如今有一個q函數,輸入時間點t,讓返回在時間點t時得票最多的人,當得票數相等時,返回最近得票的人。由於查詢需求的時間點是任意的,在某個查詢時間點可能並無投票發生,但須要知道當前的票王,固然最傻的辦法就是每次都從開頭統計到當前時間點,找出票王,但這種方法大機率會超時,正確的方法其實是要在某個投票的時間點,都統計出當前的票王,而後在查詢的時候,查找恰好大於查詢時間點的下一個投票時間點,返回前一個時間點的票王便可,因此這裏可使用一個 TreeMap 來創建投票時間點和當前票王之間的映射。如何統計每一個投票時間點的票王呢,可使用一個 count 數組,其中 count[i] 就表示當前i得到的票數,還須要一個變量 lead,表示當前的票王。如今就能夠開始遍歷全部的投票了,對於每一個投票,將票數加到 count 中對應的人身上,而後跟 lead 比較,若當前人的票數大於等於 lead 的票數,則 lead 更換爲當前人,同時創建當前時間點和票王之間的映射。在查詢的時候,因爲時間點是有序的,因此可使用二分搜索法,因爲使用的是 TreeMap,具備自動排序的功能,能夠直接用 upper_bound 來查找第一個比t大的投票時間,而後再返回上一個投票時間點的票王便可,參見代碼以下:函數
解法一:this
class TopVotedCandidate { public: TopVotedCandidate(vector<int>& persons, vector<int>& times) { int n = persons.size(), lead = 0; vector<int> count(n + 1); for (int i = 0; i < n; ++i) { if (++count[persons[i]] >= count[lead]) { lead = persons[i]; } m[times[i]] = lead; } } int q(int t) { return (--m.upper_bound(t))->second; } private: map<int, int> m; };
咱們也能夠用 HashMap 來取代 TreeMap,但由於 HashMap 沒法進行時間點的排序,很差使用二分搜索法了,因此就須要記錄投票時間數組 times,保存在一個私有變量中。在查詢函數中本身來寫二分搜索法,是博主以前的總結帖 LeetCode Binary Search Summary 二分搜索法小結 中的第三類,查找第一個大於目標值的數。因爲要返回上一個投票時間點,因此要記得減1,參見代碼以下:code
解法二:orm
class TopVotedCandidate { public: TopVotedCandidate(vector<int>& persons, vector<int>& times) { int n = persons.size(), lead = 0; vector<int> count(n + 1); this->times = times; for (int i = 0; i < n; ++i) { if (++count[persons[i]] >= count[lead]) { lead = persons[i]; } m[times[i]] = lead; } } int q(int t) { int left = 0, right = times.size(); while (left < right) { int mid = left + (right - left) / 2; if (times[mid] <= t) left = mid + 1; else right = mid; } return m[times[right - 1]]; } private: unordered_map<int, int> m; vector<int> times; };
Github 同步地址:htm
https://github.com/grandyang/leetcode/issues/911
參考資料: