题目:
相关企业
给你一个下标从 0 开始的整数数组 nums ,数组长度为 n 。
你可以执行无限次下述运算:
- 选择一个之前未选过的下标
i,并选择一个 严格小于nums[i]的质数p,从nums[i]中减去p。
如果你能通过上述运算使得 nums 成为严格递增数组,则返回 true ;否则返回 false 。
严格递增数组 中的每个元素都严格大于其前面的元素。
算法:
方法一:质数筛+贪心
func primeSubOperation(nums []int) bool {
primes := make([]int, 0)
notPrime := make(map[int]bool, 0)
maxVal := 1000
// 初始化小于等于maxVal的所有质数
for i := 2; i < maxVal; i ++ {
if !notPrime[i] {
primes = append(primes, i)
for j := i * i; j < maxVal; j = j + i{
notPrime[j] = true
}
}
}
// 贪心,每次先减去最大的质数,这样nums后面的数有更大的空间
// pre上一个被减去最大质数后的数的值
pre := 0
for i := range nums {
if nums[i] <= pre {
return false
}
// 减去nums[i] - pre的最大质数
// 因为pre < nums[i] - prime
// prime < nums[i] - pre,所以nums[i]要减去比nums[i] - pre小的最大质数
pre = nums[i] - searchLessThan(primes, nums[i] - pre)
}
return true
}
// 找到比num小的第一个数,没有就返回0
func searchLessThan(nums []int, num int) int {
left, right := 0, len(nums) - 1
for left < right {
mid := (left + right) / 2 + 1
if nums[mid] < num {
left = mid
} else {
right = mid - 1
}
}
if nums[left] >= num {
return 0
}
return nums[left]
}