[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 题目讲解汇总(持续更新中...)

相关文章
相关标签/搜索