LeetCode周赛#103 Q4 Online Election (优先队列)

题目来源:https://leetcode.com/contest/weekly-contest-103/problems/online-election/

问题描述

911. Online Election

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. 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].

------------------------------------------------------------

题意

给出两个长度为T的数组times[T]和persons[T]表示T次投票发生的时间和投给的候选人编号。然后给出一个长度为K的时间数组q[K]表示询问,求每次询问时哪一个候选人是胜者。胜者的定义是得票最多的候选人,如果若干个候选人得票相同,则得最后一票最晚的候选人为胜者。总共有N个候选人。

要求给出投票计数器的构造函数和查询函数。

------------------------------------------------------------

思路

将任务分解:构造函数里计算每个发生投票的时刻过后的胜者,保存在长度为T的数组leader中;查询函数里根据待查询的时间位于哪两次投票之间,查leader数组得到此时刻的胜者。

构造函数每次判断胜者如果采用简单遍历,则复杂度为O(TN),会TLE. 采用优先队列优化,每次发生投票就将投票数更新的那个候选人放入优先队列,此时优先队列的队首元素就是这次投票过后的胜者。采用优先队列优化的构造函数复杂度为O(TlogT).

注意优先队列第三项比较项要写成类或结构体,并重载"()"运算符,如果是最大堆,则用"()"实现“小于”的逻辑,如果是最小堆,则用"()"实现“大于”的逻辑(正好是反过来的)。

------------------------------------------------------------

代码

class TopVotedCandidate {
public:
    struct node {
        int id, num, last;                  // id: voter id, num: votes number, last: last votes time
        
        node (void) {}
        node (int ii, int nn, int ll): id(ii), num(nn), last(ll) {}
    };
    
    struct NodeCompare {
        bool operator() (const node &n1, const node &n2)    // check leader   
        {
            if (n1.num < n2.num)
            {
                return true;
            }
            else if (n1.num == n2.num && n1.last < n2.last)
            {
                return true;
            }
            return false;
        }
    };
    
    vector<int> leader;                 // leader at times when vote happens
    vector<int> mytime;                 // times when vote happens
    int votes[5005];                    // votes for every candidate
    int lasts[5005];                    // last vote time for every candidate
    priority_queue<node, vector<node>, NodeCompare> pq;            // for fast leader selection
    TopVotedCandidate(vector<int> persons, vector<int> times) {
        mytime = times;
        memset(votes, 0, sizeof(votes));
        memset(lasts, 0, sizeof(lasts));
        int i, j, len = times.size(), maxid = -1;
        for (i=0; i<len; i++)
        {
            votes[persons[i]]++;
            lasts[persons[i]] = times[i];
            pq.push(node(persons[i], votes[persons[i]], lasts[persons[i]]));
            maxid = pq.top().id;
            leader.push_back(maxid);
        }
        mytime.push_back(1000000000+5); // maxium time possible
    }
    
    int q(int t) {
        int i, len = mytime.size();
        for (i=0; i<len-1; i++)
        {
            if (t >= mytime[i] && t < mytime[i+1])
            {
                return leader[i];
            }
        }
    }
};

/**
 * Your TopVotedCandidate object will be instantiated and called as such:
 * TopVotedCandidate obj = new TopVotedCandidate(persons, times);
 * int param_1 = obj.q(t);
 */

猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/82831873
Q4