LeetCode in Kotlin

2601. Prime Subtraction Operation

Medium

You are given a 0-indexed integer array nums of length n.

You can perform the following operation as many times as you want:

Return true if you can make nums a strictly increasing array using the above operation and false otherwise.

A strictly increasing array is an array whose each element is strictly greater than its preceding element.

Example 1:

Input: nums = [4,9,6,10]

Output: true

Explanation: In the first operation: Pick i = 0 and p = 3, and then subtract 3 from nums[0], so that nums becomes [1,9,6,10]. In the second operation: i = 1, p = 7, subtract 7 from nums[1], so nums becomes equal to [1,2,6,10]. After the second operation, nums is sorted in strictly increasing order, so the answer is true.

Example 2:

Input: nums = [6,8,11,12]

Output: true

Explanation: Initially nums is sorted in strictly increasing order, so we don’t need to make any operations.

Example 3:

Input: nums = [5,8,3]

Output: false

Explanation: It can be proven that there is no way to perform operations to make nums sorted in strictly increasing order, so the answer is false.

Constraints:

Solution

class Solution {
    private fun primesUntil(n: Int): IntArray {
        if (n < 2) return intArrayOf()
        val primes = IntArray(200)
        val composite = BooleanArray(n + 1)
        primes[0] = 2
        var added = 1
        var i = 3
        while (i <= n) {
            if (composite[i]) {
                i += 2
                continue
            }
            primes[added++] = i
            var j = i * i
            while (j <= n) {
                composite[j] = true
                j += i
            }
            i += 2
        }
        return primes.copyOf(added)
    }

    fun primeSubOperation(nums: IntArray): Boolean {
        var max = 0
        for (n in nums) {
            max = max.coerceAtLeast(n)
        }
        val primes = primesUntil(max)
        var prev = 0
        for (n in nums) {
            val pos = primes.binarySearch(n - prev - 1)
            if (pos == -1 && n <= prev) return false
            prev = n - if (pos == -1) 0 else if (pos < 0) primes[-pos - 2] else primes[pos]
        }
        return true
    }
}