[LeetCode] 911. Online Election 在線選舉



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. 1 <= persons.length = times.length <= 5000
  2. 0 <= persons[i] <= persons.length
  3. times is a strictly increasing array with all elements in [0, 10^9].
  4. TopVotedCandidate.q is called at most 10000 times per test case.
  5. 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



參考資料:

https://leetcode.com/problems/online-election/

https://leetcode.com/problems/online-election/discuss/173382/C%2B%2BJavaPython-Binary-Search-in-Times

https://leetcode.com/problems/online-election/discuss/191898/Anybody-has-a-magic-general-formula-for-Binary-Search



LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索