💥💥 Beats 100% on runtime and memory [EXPLAINED]
IntuitionFind the minimum number of moves needed to place k ones in a contiguous subarray, considering a few modifications (maxChanges). We need to efficiently
# Intuition
Find the minimum number of moves needed to place k ones in a contiguous subarray, considering a few modifications (maxChanges). We need to efficiently calculate distances and shifts while keeping track of ones in the array.

# Approach
I start by finding the positions of ones and calculating the distance sums for different subarrays, adjusting the window by adding or removing ones and updating the steps accordingly. This uses arrays to store distance sums and counters for efficient lookup.
In the solution, arrays like IntArray are used to store the positions and counts, making it easy to track the number of ones and their distances.

# Complexity
- Time complexity:
O(n), where n is the length of the array. We traverse the array a few times (like finding ones and calculating distances).

- Space complexity:
O(n), because we store intermediate results (like nearest moves and steps) in arrays.

# Code
```kotlin []
class Solution {

    fun findMinMovesForXNearest(nums: IntArray, x: Int): LongArray {
        val nearest = LongArray(nums.size) { 0L }
        var l = 0
        var r = 0

        // Find the leftmost 1
        for (i in nums.indices) {
            if (nums[i] == 1) {
                l = i
                break
            }
        }

        // Find the distance sum for index 0
        var moveSum = 0L
        var cntOne = 0
        for (i in l until nums.size) {
            if (nums[i] == 1) {
                moveSum += i
                cntOne++
            }
            if (cntOne == x) {
                r = i
                break
            }
        }

        var cntPass1 = 0
        var nextR = r + 1
        // Find the new nextR
        while (nextR < nums.size) {
            if (nums[nextR] == 1) {
                break
            }
            nextR++
        }

        nearest[0] = moveSum
        if (nums[0] == 1) cntPass1 = 1 else cntPass1 = 0
        for (i in 1 until nums.size) {
            nearest[i] = nearest[i - 1] + cntPass1 - (x - cntPass1)
            // Adjust the window, remove l and add nextR if nextR is closer to i
            if (nextR < nums.size && Math.abs(i - l) > Math.abs(i - nextR)) {
                var nextL = l + 1
                while (nextL < nums.size) {
                    if (nums[nextL] == 1) {
                        break
                    }
                    nextL++
                }

                nearest[i] -= Math.abs(i - l).toLong()
                nearest[i] += Math.abs(i - nextR).toLong()

                if (l < i && nextR > i) {
                    cntPass1--
                }

                // Find the next 1
                nextR++
                while (nextR < nums.size) {
                    if (nums[nextR] == 1) {
                        break
                    }
                    nextR++
                }
                l = nextL
            }

            if (nums[i] == 1) {
                cntPass1++
            }
        }

        return nearest
    }

    fun minimumMoves(nums: IntArray, k: Int, maxChanges: Int): Long {
        var res = Long.MAX_VALUE
        val nearest = Array(4) { LongArray(nums.size) }

        if (k > maxChanges) {
            for (i in 0..3) {
                nearest[i] = findMinMovesForXNearest(nums, k - maxChanges + i)
            }
        }

        val numOnes = nums.count { it == 1 }

        for (i in nums.indices) {
            var curSteps = 0L
            if (k > maxChanges) {
                var cnt1 = 0
                if (i > 0 && nums[i - 1] == 1) cnt1++
                if (nums[i] == 1) cnt1++
                if (i < nums.size - 1 && nums[i + 1] == 1) cnt1++
                val useNei = Math.min(maxChanges, cnt1)
                var minSteps = Long.MAX_VALUE
                // Try different values of C
                for (un in 0..useNei) {
                    if (k - maxChanges + un > numOnes) continue
                    var steps = 0L
                    steps += (maxChanges - un) * 2
                    steps += nearest[un][i]
                    minSteps = Math.min(minSteps, steps)
                }
                curSteps = minSteps
            } else {
                var needOnes = k
                if (nums[i] == 1) {
                    needOnes--
                }
                if (needOnes == 0) return 0
                if (i > 0 && nums[i - 1] == 1) {
                    needOnes--
                    curSteps++
                }
                if (needOnes == 0) {
                    res = Math.min(res, curSteps)
                    continue
                }
                if (i < nums.size - 1 && nums[i + 1] == 1) {
                    needOnes--
                    curSteps++
                }
                if (needOnes == 0) {
                    res = Math.min(res, curSteps)
                    continue
                }
                curSteps += needOnes * 2
            }

            res = Math.min(res, curSteps)
        }

        return res
    }
}

```
['Math', 'Binary Search', 'Dynamic Programming', 'Greedy', 'Sliding Window', 'Suffix Array', 'Binary Tree', 'Prefix Sum', 'Kotlin']