📜  根据给定的投票系统查找谁赢得了选举

📅  最后修改于: 2022-05-13 01:56:08.514000             🧑  作者: Mango

根据给定的投票系统查找谁赢得了选举

给定一个{X, Y}形式的对arr[][]数组,其中每个arr[i]表示候选人 ID 为Y的候选人被投票的时间X和一个由M组成的查询数组query[]正整数,每个查询Q[i]的任务是找到投票Q[i]时的获胜候选人 ID。

注意:如果在给定时间有 2 个候选人的票数K相同,则打印最先获得这些票数的候选人。

例子:

方法:给定的问题可以通过预先计算数组arr[]中每个即将到来的时间间隔的获胜者并将其存储在另一个数组中来解决,例如Ans[]{timeInterval,winnerCandidateID}的形式,然后对于每个查询query[ i]对数组Ans[ ] 执行二分搜索,以在时间query[i]获得获胜的候选人。请按照以下步骤解决问题:

  • 初始化一个向量,比如Ans[] ,它在每个传入的时间间隔arr[i].first存储获胜者。
  • 初始化一个无序映射,比如Map[] ,它存储候选人 ID 在每个传入时间间隔的频率。
  • 初始化一对,比如previous[] ,它会跟踪获胜的候选人。
  • 推入向量Ans[]中的第一对并将其标记为前一对。
  • 使用变量i遍历范围[1, N – 1]并执行以下步骤:
    • 在地图Map中将当前候选arr[i].second的频率增加1
    • 如果当前候选人赢到现在,则更新之前的对。
    • 将前一个插入向量Ans[]中。
  • 使用变量i迭代范围[0, M)并执行以下步骤:
    • 对于每个查询,对向量对Ans[]执行二进制搜索以找到获胜的候选者。
    • 对时间即对向量Ans[]的第一个值进行二分查找,找到小于等于query[ I ]的最大值,并打印出对应的candidateID

下面是上述方法的实现:

C++
// C++ program for the above approach
#include "bits/stdc++.h"
using namespace std;
 
// Function to perform binary search
// to find the candidate with most votes
// for a particular time
int binarySearch(vector >& Ans, int low,
                 int high, int value)
{
    // Base Cases
    if (value <= Ans[low].first)
        return Ans[low].second;
    if (value >= Ans[high].first)
        return Ans[high].second;
 
    int winningCandidate;
 
    while (low <= high) {
 
        // Find the mid
        int mid = low + (high - low) / 2;
 
        // If the value at mid is the
        // result
        if (Ans[mid].first == value) {
            winningCandidate = Ans[mid].second;
            break;
        }
 
        // Update the ranges
        else if (Ans[mid].first < value) {
            winningCandidate = Ans[mid].second;
            low = mid + 1;
        }
        else {
            high = mid - 1;
        }
    }
 
    return winningCandidate;
}
 
// Function to find the winner for each query
void findWinner(pair arr[], int N, int query[],
                int M)
{
 
    // Map to store the frequency
    unordered_map Map;
 
    // Stores the winning candidate till
    // a particular time
    vector > Ans;
 
    // Starting Reference
    pair previous
        = { arr[0].first, arr[0].second };
    Ans.push_back(previous);
    Map[arr[0].second]++;
 
    // Iterate over the range
    for (int i = 1; i < N; i++) {
 
        // Increase the frequency
        Map[arr[i].second]++;
 
        // Update the reference if another
        // candidate gets more votes than
        // the one considered
        if (Map[arr[i].second] > Map[previous.second]) {
            previous.second = arr[i].second;
        }
 
        previous.first = arr[i].first;
 
        // Push into the vector
        Ans.push_back(previous);
    }
 
    // Iterate over the range
    for (int i = 0; i < M; i++) {
        cout << binarySearch(Ans, 0, N - 1, query[i])
             << ' ';
    }
}
 
// Driver Code
int main()
{
    pair arr[]
        = { { 1, 2 }, { 2, 2 }, { 4, 1 },
            { 5, 5 }, { 7, 1 }, { 11, 1 } };
    int query[] = { 2, 8, 12 };
    int N = 6;
    int M = 3;
 
    findWinner(arr, N, query, M);
 
    return 0;
}


Python3
# Python 3 program for the above approach
from collections import defaultdict
 
# Function to perform binary search
# to find the candidate with most votes
# for a particular time
def binarySearch(Ans,
                 low,  high,  value):
 
    # Base Cases
    if (value <= Ans[low][0]):
        return Ans[low][1]
    if (value >= Ans[high][0]):
        return Ans[high][1]
 
    while (low <= high):
 
        # Find the mid
        mid = low + (high - low) // 2
 
        # If the value at mid is the
        # result
        if (Ans[mid][0] == value):
            winningCandidate = Ans[mid][1]
            break
 
        # Update the ranges
        elif (Ans[mid][0] < value):
            winningCandidate = Ans[mid][1]
            low = mid + 1
 
        else:
            high = mid - 1
 
    return winningCandidate
 
# Function to find the winner for each query
 
 
def findWinner(arr,
               N,  query,
               M):
 
    # Map to store the frequency
    Map = defaultdict(int)
 
    # Stores the winning candidate till
    # a particular time
    Ans = []
 
    # Starting Reference
    previous = [arr[0][0], arr[0][1]]
    Ans.append([previous[0], previous[1]])
    Map[arr[0][1]] += 1
 
    # Iterate over the range
    for i in range(1, N):
 
        # Increase the frequency
        Map[arr[i][1]] += 1
 
        # Update the reference if another
        # candidate gets more votes than
        # the one considered
        if (Map[arr[i][1]]
                > Map[previous[1]]):
            previous[1] = arr[i][1]
 
        previous[0] = arr[i][0]
 
        # Push into the vector
        Ans.append([previous[0], previous[1]])
 
    # Iterate over the range
    for i in range(M):
        print(binarySearch(
            Ans, 0, N - 1, query[i]), end=' ')
 
# Driver Code
if __name__ == "__main__":
 
    arr = [[1, 2], [2, 2], [4, 1],
           [5, 5], [7, 1], [11, 1]]
    query = [2, 8, 12]
    N = 6
    M = 3
 
    findWinner(arr, N, query, M)
 
    # This code is contributed by ukasp.


输出:
2 2 1

时间复杂度: O(max(N, M*log(N)))
辅助空间: O(N)