2024-08-10:用go语言,给定两个下标从 1 开始的整数数组 nums
和 changeIndices
,分别长度为 n
和 m
。最初,nums
中的所有下标都是未标记的。
你的任务是标记 nums
中所有的下标。你可以在从第 1 秒到第 m 秒的时间段内执行以下操作之一:
1.选择范围 [1, n] 中的一个下标 i
,将 nums[i]
减少 1。
2.如果 nums[changeIndices[s]]
等于 0,标记下标 changeIndices[s]
。
3.不进行任何操作。
请返回一个整数,表示在最优操作下,标记所有下标所需的最早秒数。如果无法标记所有下标,则返回 -1。
输入:nums = [2,2,0], changeIndices = [2,2,2,2,3,2,2,1]。
输出:8。
解释:这个例子中,我们总共有 8 秒。按照以下操作标记所有下标:
第 1 秒:选择下标 1 ,将 nums[1] 减少 1 。nums 变为 [1,2,0] 。
第 2 秒:选择下标 1 ,将 nums[1] 减少 1 。nums 变为 [0,2,0] 。
第 3 秒:选择下标 2 ,将 nums[2] 减少 1 。nums 变为 [0,1,0] 。
第 4 秒:选择下标 2 ,将 nums[2] 减少 1 。nums 变为 [0,0,0] 。
第 5 秒,标记 changeIndices[5] ,也就是标记下标 3 ,因为 nums[3] 等于 0 。
第 6 秒,标记 changeIndices[6] ,也就是标记下标 2 ,因为 nums[2] 等于 0 。
第 7 秒,什么也不做。
第 8 秒,标记 changeIndices[8] ,也就是标记下标 1 ,因为 nums[1] 等于 0 。
现在所有下标已被标记。
最早可以在第 8 秒标记所有下标。
所以答案是 8 。
答案2024-08-10:
题目来自leetcode3046。
大体步骤如下:
Go完整代码如下:
package main
import (
"fmt"
"sort"
)
func earliestSecondToMarkIndices(nums, changeIndices []int) int {
n, m := len(nums), len(changeIndices)
if n > m {
return -1
}
done := make([]int, n) // 避免反复创建和初始化数组
ans := n + sort.Search(m+1-n, func(mx int) bool {
mx += n
exam, study := n, 0
for i := mx - 1; i >= 0; i-- {
idx := changeIndices[i] - 1
if done[idx] != mx {
done[idx] = mx
exam-- // 考试
study += nums[idx] // 需要复习的天数
} else if study > 0 {
study-- // 复习
}
}
return exam == 0 && study == 0 // 考完了并且复习完了
})
if ans > m {
return -1
}
return ans
}
func main() {
nums := []int{2, 2, 0}
changeIndices := []int{2, 2, 2, 2, 3, 2, 2, 1}
fmt.Println(earliestSecondToMarkIndices(nums, changeIndices))
}