2601. 质数减法运算

78 阅读1分钟

题目:
相关企业

给你一个下标从 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]
}