Skip to content

Commit 6ac3b50

Browse files
committed
Add LeetCode Biweekly Contest 61
1 parent 2b2d9ba commit 6ac3b50

File tree

8 files changed

+260
-0
lines changed

8 files changed

+260
-0
lines changed

leetcode/biweekly/61/a/a.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package main
2+
3+
// O(n) 做法
4+
5+
// github.com/EndlessCheng/codeforces-go
6+
func countKDifference(nums []int, k int) (ans int) {
7+
cnt := map[int]int{}
8+
for _, v := range nums {
9+
cnt[v]++
10+
}
11+
for _, v := range nums {
12+
ans += cnt[v-k]
13+
}
14+
return
15+
}

leetcode/biweekly/61/a/a_test.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

leetcode/biweekly/61/b/b.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package main
2+
3+
import "sort"
4+
5+
// 排序+遍历
6+
7+
// github.com/EndlessCheng/codeforces-go
8+
func findOriginalArray(changed []int) (original []int) {
9+
sort.Ints(changed)
10+
cnt := map[int]int{}
11+
for _, v := range changed {
12+
if cnt[v] == 0 { // v 不是双倍后的元素
13+
cnt[v*2]++ // 标记一个双倍元素
14+
original = append(original, v)
15+
} else {
16+
cnt[v]-- // 清除一个标记
17+
if cnt[v] == 0 {
18+
delete(cnt, v)
19+
}
20+
}
21+
}
22+
// 只有当所有双倍标记都被清除掉时,才能说明 changed 是一个双倍数组
23+
if len(cnt) == 0 {
24+
return
25+
}
26+
return nil
27+
}

leetcode/biweekly/61/b/b_test.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

leetcode/biweekly/61/c/c.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package main
2+
3+
/* 动态规划
4+
5+
定义 $f[i]$ 表示行驶到 i 时的最大盈利。考虑状态转移,一方面,我们可以不接终点为 $i$ 的乘客,这样有 $f[i]=f[i-1]$;另一方面,我们可以接所有终点为 $i$ 的乘客,这样有 $f[i] = \max f[start]+end-start+tip$,二者取最大值。
6+
7+
最终答案为 $f[n]$。
8+
9+
*/
10+
11+
// github.com/EndlessCheng/codeforces-go
12+
func maxTaxiEarnings(n int, rides [][]int) int64 {
13+
f := make([]int, n+1)
14+
groups := make([][][2]int, n+1)
15+
for _, r := range rides {
16+
start, end, tip := r[0], r[1], r[2]
17+
groups[end] = append(groups[end], [2]int{start, tip})
18+
}
19+
for end := 1; end <= n; end++ {
20+
f[end] = f[end-1]
21+
for _, r := range groups[end] {
22+
start, tip := r[0], r[1]
23+
f[end] = max(f[end], f[start]+end-start+tip)
24+
}
25+
}
26+
return int64(f[n])
27+
}
28+
29+
func max(a, b int) int {
30+
if b > a {
31+
return b
32+
}
33+
return a
34+
}

leetcode/biweekly/61/c/c_test.go

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

leetcode/biweekly/61/d/d.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package main
2+
3+
import "sort"
4+
5+
/* 排序+去重+二分
6+
7+
考虑最多可以保留多少个元素不变。由于元素的位置不影响答案,且要求所有元素互不相同,我们可以将 $\textit{nums}$ 排序,并去掉重复元素。
8+
9+
记原数组长度为 $n$。对排序去重后的 $\textit{nums}'$ 中的一段区间 $[l,r]$,若要保留这段区间内的所有元素,我们需要替换区间外的元素,填充到 $[\textit{nums}'[l],\textit{nums}'[r]]$ 内缺失的元素上。
10+
11+
需要填充的元素个数为
12+
13+
$$\textit{nums}'[r]-\textit{nums}'[l]+1-(r-l+1)$$
14+
15+
区间外有 $n-(r-l+1)$ 个元素,由于区间外的元素个数不能少于需要填充的元素个数,所以有
16+
17+
$$
18+
\textit{nums}'[r]-\textit{nums}'[l]+1-(r-l+1) \le n-(r-l+1)
19+
$$
20+
21+
上式可化简为
22+
23+
$$
24+
\textit{nums}'[l]\ge\textit{nums}'[r]-n+1
25+
$$
26+
27+
根据该式,我们可以遍历 $\textit{nums}'[r]$,二分得到最小的满足该式的 $l$,此时 $[l,r]$ 区间内的元素均可以保留。用 $n$ 减去最多可以保留的元素个数,就是答案。
28+
29+
时间复杂度:$O(n\log n)$。
30+
31+
空间复杂度:$O(1)$。只需要常数的空间存放若干变量。
32+
33+
*/
34+
35+
// github.com/EndlessCheng/codeforces-go
36+
func minOperations(nums []int) (ans int) {
37+
n := len(nums)
38+
sort.Ints(nums)
39+
nums = unique(nums)
40+
for r, v := range nums {
41+
l := sort.SearchInts(nums[:r], v-n+1)
42+
ans = max(ans, r-l+1) // [l,r] 内的元素均可以保留
43+
}
44+
return n - ans
45+
}
46+
47+
// 原地去重
48+
func unique(a []int) []int {
49+
k := 0
50+
for _, v := range a[1:] {
51+
if a[k] != v {
52+
k++
53+
a[k] = v
54+
}
55+
}
56+
return a[:k+1]
57+
}
58+
59+
func max(a, b int) int {
60+
if b > a {
61+
return b
62+
}
63+
return a
64+
}

leetcode/biweekly/61/d/d_test.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)