开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情
分割数组中数字的数位
题目大意:给你一个字符串数组,把每个字符串拆分成字符数组,并拼接在一起返回
模拟
题目比较明确了,按照题意模拟即可
package main
import "strconv"
func separateDigits(nums []int) []int {
ans := make([]int, 0)
for i := 0; i < len(nums); i++ {
s := strconv.Itoa(nums[i])
for j := 0; j < len(s); j++ {
ans = append(ans, int(s[j]-'0'))
}
}
return ans
}
从一个范围内选择最多整数 I
题目大意:给你一个数组,你从1到n最多选(不能选数组里的数)几个数,使得和不超过k。
贪心
想要选的最多,就是优先选小的即可,从1开始枚举,如果不在数组里就选上,和大于k就停止。
package main
func maxCount(banned []int, n int, maxSum int) int {
ans := 0
m := make(map[int]bool)
for _, num := range banned {
m[num] = true
}
for i := 1; i <= n; i++ {
if maxSum < i {
break
}
if !m[i] {
maxSum -= i
ans++
}
}
return ans
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func abs(a int) int {
if a < 0 {
return -a
}
return a
}
两个线段获得的最多奖品
题意:在一个坐标轴上有一些奖品,你可以取两个长度为k的区间,奖品个数和最大为多少
贪心
我们可以利用双指针求一个长度为k的最大和,对于两个区间,我们分情况讨论
- 两区间有交集,相当于一个长度为2k的区间
- 无交集,双指针枚举第二个区间的右端点,第二个区间值+左端点左边的一个区间的最大值
package main
import "fmt"
type pos struct {
idx int
value int
maxk_left int
sumk_left int
left int
}
func getLeft(poss []*pos, right, k int) int {
l, r := 0, right
//fmt.Println("get", right, k, right-k)
for l < r {
mid := (l + r) / 2
if poss[mid].idx < poss[right].idx-k {
l = mid + 1
} else {
r = mid
}
}
//fmt.Println("get ans", l, poss[l].idx, right-k)
return l
}
func maximizeWin(prizePositions []int, k int) int {
poss := make([]*pos, 0)
for i := 0; i < len(prizePositions); i++ {
if len(poss) == 0 {
poss = append(poss, &pos{idx: prizePositions[i], value: 1})
} else {
if poss[len(poss)-1].idx == prizePositions[i] {
poss[len(poss)-1].value++
} else {
poss = append(poss, &pos{idx: prizePositions[i], value: 1})
}
}
}
summ := make([]int, len(poss))
// 前缀和
summ[0] = poss[0].value
for i := 1; i < len(poss); i++ {
summ[i] = summ[i-1] + poss[i].value
}
// 有交集时 2k
ans := 0
for i := 0; i < len(poss); i++ {
l := getLeft(poss, i, 2*k)
if l == 0 {
ans = max(ans, summ[i])
} else {
ans = max(ans, summ[i]-summ[l-1])
}
}
fmt.Println(1, ans)
// 无交集时
tmp := 0
for i := 0; i < len(poss); i++ {
l := getLeft(poss, i, k)
//fmt.Println(i, l, poss[i].idx, poss[l].idx, k)
poss[i].left = l
if l == 0 {
tmp = max(tmp, summ[i])
poss[i].sumk_left = summ[i]
} else {
tmp = max(tmp, summ[i]-summ[l-1])
poss[i].sumk_left = summ[i] - summ[l-1]
}
poss[i].maxk_left = tmp
}
// 贪心
for i := 1; i < len(poss); i++ {
if poss[i].left > 0 {
ans = max(ans, poss[poss[i].left-1].maxk_left+poss[i].sumk_left)
fmt.Println("-1", i, poss[i].left)
}
}
fmt.Println(2, ans)
//fmt.Println(summ)
return ans
}
func max(a, b int) int {
if a < b {
return b
}
return a
}
二进制矩阵中翻转最多一次使路径不连通
题意:给你01二维矩阵,问将一个1变为0是否可以使左上角与右下角不连通。 没想明白,嘎了