添加 problem 991

This commit is contained in:
YDZ
2019-12-06 11:48:35 +08:00
parent ea730bc878
commit 461f8a9a5d
4 changed files with 140 additions and 11 deletions

View File

@ -60,6 +60,7 @@ What is the minimum number of moves that you need to know with certainty what 
<p align='center'>
<img src='https://img.halfrost.com/Leetcode/leetcode_887_8.png'>
</p>
- 换个角度来看这个问题,定义 `dp[k][m]` 代表 `K` 个鸡蛋,`M` 次移动能检查的最大楼层。考虑某一步 `t` 应该在哪一层丢鸡蛋呢?一个正确的选择是在 `dp[k-1][t-1] + 1` 层丢鸡蛋,结果分两种情况:
1. 如果鸡蛋碎了,我们首先排除了该层以上的所有楼层(不管这个楼有多高),而对于剩下的 `dp[k-1][t-1]` 层楼,我们一定能用 `k-1` 个鸡蛋在 `t-1` 步内求解。因此这种情况下,我们总共可以求解无限高的楼层。可见,这是一种非常好的情况,但并不总是发生。
2. 如果鸡蛋没碎,我们首先排除了该层以下的 `dp[k-1][t-1]` 层楼,此时我们还有 `k` 个蛋和 `t-1` 步,那么我们去该层以上的楼层继续测得 `dp[k][t-1]` 层楼。因此这种情况下,我们总共可以求解 `dp[k-1][t-1] + 1 + dp[k][t-1]` 层楼。
@ -72,29 +73,38 @@ What is the minimum number of moves that you need to know with certainty what 
<p align='center'>
<img src='https://img.halfrost.com/Leetcode/leetcode_887_1.png'>
</p>
`g(t,k) = f(t,k) - f(t,k-1)`,可以得到:
-`g(t,k) = f(t,k) - f(t,k-1)`,可以得到:
<p align='center'>
<img src='https://img.halfrost.com/Leetcode/leetcode_887_2.png'>
</p>
可以知道 `g(t,k)` 是一个杨辉三角,即二项式系数:
- 可以知道 `g(t,k)` 是一个杨辉三角,即二项式系数:
<p align='center'>
<img src='https://img.halfrost.com/Leetcode/leetcode_887_3.png'>
</p>
利用裂项相消的方法:
- 利用裂项相消的方法:
<p align='center'>
<img src='https://img.halfrost.com/Leetcode/leetcode_887_4.png'>
</p>
于是可以得到:
- 于是可以得到:
<p align='center'>
<img src='https://img.halfrost.com/Leetcode/leetcode_887_5.png'>
</p>
其中:
- 其中:
<p align='center'>
<img src='https://img.halfrost.com/Leetcode/leetcode_887_6.png'>
</p>
于是针对每一项的二项式常数,都可以由前一项乘以一个分数得到下一项。
- 于是针对每一项的二项式常数,都可以由前一项乘以一个分数得到下一项。
<p align='center'>
<img src='https://img.halfrost.com/Leetcode/leetcode_887_7.png'>
</p>
利用二分搜索,不断的二分 `t`,直到逼近找到 `f(t,k) ≥ N` 时候最小的 `t`。时间复杂度 `O(K * log N)`,空间复杂度 `O(1)`
- 利用二分搜索,不断的二分 `t`,直到逼近找到 `f(t,k) ≥ N` 时候最小的 `t`。时间复杂度 `O(K * log N)`,空间复杂度 `O(1)`

View File

@ -0,0 +1,38 @@
package leetcode
import (
"sort"
)
// TopVotedCandidate define
type TopVotedCandidate struct {
persons []int
times []int
}
// Constructor911 define
func Constructor911(persons []int, times []int) TopVotedCandidate {
leaders, votes := make([]int, len(persons)), make([]int, len(persons))
leader := persons[0]
for i := 0; i < len(persons); i++ {
p := persons[i]
votes[p]++
if votes[p] >= votes[leader] {
leader = p
}
leaders[i] = leader
}
return TopVotedCandidate{persons: leaders, times: times}
}
// Q define
func (tvc *TopVotedCandidate) Q(t int) int {
i := sort.Search(len(tvc.times), func(p int) bool { return tvc.times[p] > t })
return tvc.persons[i-1]
}
/**
* Your TopVotedCandidate object will be instantiated and called as such:
* obj := Constructor(persons, times);
* param_1 := obj.Q(t);
*/

View File

@ -0,0 +1,28 @@
package leetcode
import (
"fmt"
"testing"
)
func Test_Problem911(t *testing.T) {
obj := Constructor911([]int{0, 1, 1, 0, 0, 1, 0}, []int{0, 5, 10, 15, 20, 25, 30})
fmt.Printf("obj.Q[3] = %v\n", obj.Q(3)) // 0
fmt.Printf("obj.Q[12] = %v\n", obj.Q(12)) // 1
fmt.Printf("obj.Q[25] = %v\n", obj.Q(25)) // 1
fmt.Printf("obj.Q[15] = %v\n", obj.Q(15)) // 0
fmt.Printf("obj.Q[24] = %v\n", obj.Q(24)) // 0
fmt.Printf("obj.Q[8] = %v\n", obj.Q(8)) // 1
obj = Constructor911([]int{0, 0, 0, 0, 1}, []int{0, 6, 39, 52, 75})
fmt.Printf("obj.Q[45] = %v\n", obj.Q(45)) // 0
fmt.Printf("obj.Q[49] = %v\n", obj.Q(49)) // 0
fmt.Printf("obj.Q[59] = %v\n", obj.Q(59)) // 0
fmt.Printf("obj.Q[68] = %v\n", obj.Q(68)) // 0
fmt.Printf("obj.Q[42] = %v\n", obj.Q(42)) // 0
fmt.Printf("obj.Q[37] = %v\n", obj.Q(37)) // 0
fmt.Printf("obj.Q[99] = %v\n", obj.Q(99)) // 0
fmt.Printf("obj.Q[26] = %v\n", obj.Q(26)) // 0
fmt.Printf("obj.Q[78] = %v\n", obj.Q(78)) // 0
fmt.Printf("obj.Q[43] = %v\n", obj.Q(43)) // 0
}

View File

@ -0,0 +1,53 @@
# [911. Online Election](https://leetcode.com/problems/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]`.
## 题目大意
在选举中 i 张票是在时间为 times[i] 时投给 persons[i] 的。
现在,我们想要实现下面的查询函数: TopVotedCandidate.q(int t) 将返回在 t 时刻主导选举的候选人的编号。
 t 时刻投出的选票也将被计入我们的查询之中。在平局的情况下,最近获得投票的候选人将会获胜。
提示:
1. 1 <= persons.length = times.length <= 5000
2. 0 <= persons[i] <= persons.length
3. times 是严格递增的数组所有元素都在 [0, 10^9] 范围中。
4. 每个测试用例最多调用 10000  TopVotedCandidate.q。
5. TopVotedCandidate.q(int t) 被调用时总是满足 t >= times[0]。
## 解题思路
- 给出一个 2 个数组,分别代表第 `i` 人在第 `t` 时刻获得的票数。需要实现一个查询功能的函数,查询在任意 `t` 时刻,输出谁的选票领先。
- `persons[]` 数组里面装的是获得选票人的编号,`times[]` 数组里面对应的是每个选票的时刻。`times[]` 数组默认是有序的,从小到大排列。先计算出每个时刻哪个人选票领先,放在一个数组中,实现查询函数的时候,只需要先对 `times[]` 数组二分搜索,找到比查询时间 `t` 小的最大时刻 `i`,再在选票领先的数组里面输出对应时刻领先的人的编号即可。