题目:
给你两个整数数组 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]
}