911.在线选举

72 阅读1分钟

题目:
给你两个整数数组 persons 和 times 。在选举中,第 i 张票是在时刻为 times[i] 时投给候选人 persons[i] 的。

对于发生在时刻 t 的每个查询,需要找出在 t 时刻在选举中领先的候选人的编号。

在 t 时刻投出的选票也将被计入我们的查询之中。在平局的情况下,最近获得投票的候选人将会获胜。

实现 TopVotedCandidate 类:

  • TopVotedCandidate(int[] persons, int[] times) 使用 persons 和 times 数组初始化对象。
  • int q(int t) 根据前面描述的规则,返回在时刻 t 在选举中领先的候选人的编号。
    算法:
    方法一:动态规划(预处理+二分查找)
    dp[i]为时间i时刻结束时,票数最大的候选人。
    dp[i] = dp[i - 1] ; person[i] != person[i-1] && votes(dp[i - 1]) >= votes(person[i] + 1)
    dp[i] = person[i] ; person[i] != person[i-1] && votes(dp[i - 1]) < votes(person[i] + 1)
    边界条件:
    dp[0] = person[0]
    dp设置好之后用二分查找结果
type TopVotedCandidate struct {
	DP []int
	Times []int
}


func Constructor(persons []int, times []int) TopVotedCandidate {
	voteCount := make(map[int]int)
	dp := make([]int, len(persons))
	dp[0] = persons[0]
	voteCount[persons[0]] = 1
	for i := 1; i < len(persons); i ++ {
		voteCount[persons[i]] ++
		if dp[i - 1] != persons[i] {
			if voteCount[dp[i - 1]] >  voteCount[persons[i]] {
				dp[i] = dp[i - 1]
			} else if voteCount[dp[i - 1]] <=  voteCount[persons[i]] {
				dp[i] = persons[i]
			}
		} else {
			dp[i] = dp[i - 1]
		}
	}
	return TopVotedCandidate{dp, times}
}


func (this *TopVotedCandidate) Q(t int) int {
    // fmt.Println("t", t, this.Times, this.DP)
	// 找到dp中,小于等于t的最小值
	left, right := 0, len(this.Times) - 1
	for left < right {
		mid := (left + right) / 2
        // fmt.Println("t1",t, left,mid,right)
		if this.Times[mid] == t {
            return this.DP[mid]
        } else if this.Times[mid] < t {
			if mid + 1 < len(this.Times) && this.Times[mid + 1] <= t {
				left = mid + 1
			} else {
				return this.DP[mid]
			}
		} else {
			right = mid - 1
		}
	}
    
	return  this.DP[left]
}