LeetCode in Kotlin

3948. Lexicographically Maximum MEX Array

Hard

You are given an integer array nums.

You want to construct an array result by repeatedly performing the following operation until nums becomes empty:

Return the lexicographically maximum array result that can be obtained after performing the operations.

The MEX of an array is the smallest non-negative integer not present in the array.

An array a is lexicographically greater than an array b if in the first position where a and b differ, array a has an element that is greater than the corresponding element in b. If the first min(a.length, b.length) elements do not differ, then the longer array is the lexicographically greater one.

Example 1:

Input: nums = [0,1,0]

Output: [2,1]

Explanation:

Example 2:

Input: nums = [1,0,2]

Output: [3]

Explanation:

Example 3:

Input: nums = [3,1]

Output: [0,0]

Explanation:

Constraints:

Solution

class Solution {
    fun maximumMEX(nums: IntArray): IntArray {
        val n = nums.size
        val suffixMex = IntArray(n)
        val seen = BooleanArray(n + 2)
        var currMex = 0
        for (i in n - 1 downTo 0) {
            if (nums[i] < n + 2) {
                seen[nums[i]] = true
            }
            while (seen[currMex]) {
                currMex++
            }
            suffixMex[i] = currMex
        }
        val result = IntArray(n)
        var resIdx = 0
        val seenAtStep = IntArray(n + 2)
        var stepCounter = 0
        var i = 0
        while (i < n) {
            val m = suffixMex[i]
            result[resIdx++] = m
            if (m == 0) {
                i++
            } else {
                stepCounter++
                var found = 0
                var j = i
                while (j < n) {
                    if (nums[j] < m && seenAtStep[nums[j]] != stepCounter) {
                        seenAtStep[nums[j]] = stepCounter
                        found++
                    }
                    if (found == m) {
                        i = j + 1
                        break
                    }
                    j++
                }
            }
        }
        val finalResult = IntArray(resIdx)
        System.arraycopy(result, 0, finalResult, 0, resIdx)
        return finalResult
    }
}