Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You are given a 0-indexed array arr consisting of n positive integers, and a positive integer k.
The array arr is called K-increasing if arr[i-k] <= arr[i] holds for every index i, where k <= i <= n-1.
arr = [4, 1, 5, 2, 6, 2] is K-increasing for k = 2 because:
arr[0] <= arr[2] (4 <= 5)arr[1] <= arr[3] (1 <= 2)arr[2] <= arr[4] (5 <= 6)arr[3] <= arr[5] (2 <= 2)arr is not K-increasing for k = 1 (because arr[0] > arr[1]) or k = 3 (because arr[0] > arr[3]).In one operation, you can choose an index i and change arr[i] into any positive integer.
Return the minimum number of operations required to make the array K-increasing for the given k.
Example 1:
Input: arr = [5,4,3,2,1], k = 1 Output: 4 Explanation: For k = 1, the resultant array has to be non-decreasing. Some of the K-increasing arrays that can be formed are [5,6,7,8,9], [1,1,1,1,1], [2,2,3,4,4]. All of them require 4 operations. It is suboptimal to change the array to, for example, [6,7,8,9,10] because it would take 5 operations. It can be shown that we cannot make the array K-increasing in less than 4 operations.
Example 2:
Input: arr = [4,1,5,2,6,2], k = 2 Output: 0 Explanation: This is the same example as the one in the problem description. Here, for every index i where 2 <= i <= 5, arr[i-2] <= arr[i]. Since the given array is already K-increasing, we do not need to perform any operations.
Example 3:
Input: arr = [4,1,5,2,6,2], k = 3 Output: 2 Explanation: Indices 3 and 5 are the only ones not satisfying arr[i-3] <= arr[i] for 3 <= i <= 5. One of the ways we can make the array K-increasing is by changing arr[3] to 4 and arr[5] to 5. The array will now be [4,1,5,4,6,5]. Note that there can be other ways to make the array K-increasing, but none of them require less than 2 operations.
Constraints:
1 <= arr.length <= 1051 <= arr[i], k <= arr.lengthProblem summary: You are given a 0-indexed array arr consisting of n positive integers, and a positive integer k. The array arr is called K-increasing if arr[i-k] <= arr[i] holds for every index i, where k <= i <= n-1. For example, arr = [4, 1, 5, 2, 6, 2] is K-increasing for k = 2 because: arr[0] <= arr[2] (4 <= 5) arr[1] <= arr[3] (1 <= 2) arr[2] <= arr[4] (5 <= 6) arr[3] <= arr[5] (2 <= 2) However, the same arr is not K-increasing for k = 1 (because arr[0] > arr[1]) or k = 3 (because arr[0] > arr[3]). In one operation, you can choose an index i and change arr[i] into any positive integer. Return the minimum number of operations required to make the array K-increasing for the given k.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Binary Search
[5,4,3,2,1] 1
[4,1,5,2,6,2] 2
[4,1,5,2,6,2] 3
longest-increasing-subsequence)minimum-swaps-to-make-sequences-increasing)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2111: Minimum Operations to Make the Array K-Increasing
class Solution {
public int kIncreasing(int[] arr, int k) {
int n = arr.length;
int ans = 0;
for (int i = 0; i < k; ++i) {
List<Integer> t = new ArrayList<>();
for (int j = i; j < n; j += k) {
t.add(arr[j]);
}
ans += lis(t);
}
return ans;
}
private int lis(List<Integer> arr) {
List<Integer> t = new ArrayList<>();
for (int x : arr) {
int idx = searchRight(t, x);
if (idx == t.size()) {
t.add(x);
} else {
t.set(idx, x);
}
}
return arr.size() - t.size();
}
private int searchRight(List<Integer> arr, int x) {
int left = 0, right = arr.size();
while (left < right) {
int mid = (left + right) >> 1;
if (arr.get(mid) > x) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}
// Accepted solution for LeetCode #2111: Minimum Operations to Make the Array K-Increasing
func kIncreasing(arr []int, k int) int {
searchRight := func(arr []int, x int) int {
left, right := 0, len(arr)
for left < right {
mid := (left + right) >> 1
if arr[mid] > x {
right = mid
} else {
left = mid + 1
}
}
return left
}
lis := func(arr []int) int {
var t []int
for _, x := range arr {
idx := searchRight(t, x)
if idx == len(t) {
t = append(t, x)
} else {
t[idx] = x
}
}
return len(arr) - len(t)
}
n := len(arr)
ans := 0
for i := 0; i < k; i++ {
var t []int
for j := i; j < n; j += k {
t = append(t, arr[j])
}
ans += lis(t)
}
return ans
}
# Accepted solution for LeetCode #2111: Minimum Operations to Make the Array K-Increasing
class Solution:
def kIncreasing(self, arr: List[int], k: int) -> int:
def lis(arr):
t = []
for x in arr:
idx = bisect_right(t, x)
if idx == len(t):
t.append(x)
else:
t[idx] = x
return len(arr) - len(t)
return sum(lis(arr[i::k]) for i in range(k))
// Accepted solution for LeetCode #2111: Minimum Operations to Make the Array K-Increasing
/**
* [2111] Minimum Operations to Make the Array K-Increasing
*
* You are given a 0-indexed array arr consisting of n positive integers, and a positive integer k.
* The array arr is called K-increasing if arr[i-k] <= arr[i] holds for every index i, where k <= i <= n-1.
*
* For example, arr = [4, 1, 5, 2, 6, 2] is K-increasing for k = 2 because:
*
* arr[0] <= arr[2] (4 <= 5)
* arr[1] <= arr[3] (1 <= 2)
* arr[2] <= arr[4] (5 <= 6)
* arr[3] <= arr[5] (2 <= 2)
*
*
* However, the same arr is not K-increasing for k = 1 (because arr[0] > arr[1]) or k = 3 (because arr[0] > arr[3]).
*
* In one operation, you can choose an index i and change arr[i] into any positive integer.
* Return the minimum number of operations required to make the array K-increasing for the given k.
*
* Example 1:
*
* Input: arr = [5,4,3,2,1], k = 1
* Output: 4
* Explanation:
* For k = 1, the resultant array has to be non-decreasing.
* Some of the K-increasing arrays that can be formed are [5,<u>6</u>,<u>7</u>,<u>8</u>,<u>9</u>], [<u>1</u>,<u>1</u>,<u>1</u>,<u>1</u>,1], [<u>2</u>,<u>2</u>,3,<u>4</u>,<u>4</u>]. All of them require 4 operations.
* It is suboptimal to change the array to, for example, [<u>6</u>,<u>7</u>,<u>8</u>,<u>9</u>,<u>10</u>] because it would take 5 operations.
* It can be shown that we cannot make the array K-increasing in less than 4 operations.
*
* Example 2:
*
* Input: arr = [4,1,5,2,6,2], k = 2
* Output: 0
* Explanation:
* This is the same example as the one in the problem description.
* Here, for every index i where 2 <= i <= 5, arr[i-2] <= arr[i].
* Since the given array is already K-increasing, we do not need to perform any operations.
* Example 3:
*
* Input: arr = [4,1,5,2,6,2], k = 3
* Output: 2
* Explanation:
* Indices 3 and 5 are the only ones not satisfying arr[i-3] <= arr[i] for 3 <= i <= 5.
* One of the ways we can make the array K-increasing is by changing arr[3] to 4 and arr[5] to 5.
* The array will now be [4,1,5,<u>4</u>,6,<u>5</u>].
* Note that there can be other ways to make the array K-increasing, but none of them require less than 2 operations.
*
*
* Constraints:
*
* 1 <= arr.length <= 10^5
* 1 <= arr[i], k <= arr.length
*
*/
pub struct Solution {}
// problem: https://leetcode.com/problems/minimum-operations-to-make-the-array-k-increasing/
// discuss: https://leetcode.com/problems/minimum-operations-to-make-the-array-k-increasing/discuss/?currentPage=1&orderBy=most_votes&query=
// submission codes start here
impl Solution {
pub fn k_increasing(arr: Vec<i32>, k: i32) -> i32 {
0
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore]
fn test_2111_example_1() {
let arr = vec![5, 4, 3, 2, 1];
let k = 1;
let result = 4;
assert_eq!(Solution::k_increasing(arr, k), result);
}
#[test]
#[ignore]
fn test_2111_example_2() {
let arr = vec![4, 1, 5, 2, 6, 2];
let k = 2;
let result = 0;
assert_eq!(Solution::k_increasing(arr, k), result);
}
#[test]
#[ignore]
fn test_2111_example_3() {
let arr = vec![4, 1, 5, 2, 6, 2];
let k = 3;
let result = 2;
assert_eq!(Solution::k_increasing(arr, k), result);
}
}
// Accepted solution for LeetCode #2111: Minimum Operations to Make the Array K-Increasing
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #2111: Minimum Operations to Make the Array K-Increasing
// class Solution {
// public int kIncreasing(int[] arr, int k) {
// int n = arr.length;
// int ans = 0;
// for (int i = 0; i < k; ++i) {
// List<Integer> t = new ArrayList<>();
// for (int j = i; j < n; j += k) {
// t.add(arr[j]);
// }
// ans += lis(t);
// }
// return ans;
// }
//
// private int lis(List<Integer> arr) {
// List<Integer> t = new ArrayList<>();
// for (int x : arr) {
// int idx = searchRight(t, x);
// if (idx == t.size()) {
// t.add(x);
// } else {
// t.set(idx, x);
// }
// }
// return arr.size() - t.size();
// }
//
// private int searchRight(List<Integer> arr, int x) {
// int left = 0, right = arr.size();
// while (left < right) {
// int mid = (left + right) >> 1;
// if (arr.get(mid) > x) {
// right = mid;
// } else {
// left = mid + 1;
// }
// }
// return left;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Check every element from left to right until we find the target or exhaust the array. Each comparison is O(1), and we may visit all n elements, giving O(n). No extra space needed.
Each comparison eliminates half the remaining search space. After k comparisons, the space is n/2ᵏ. We stop when the space is 1, so k = log₂ n. No extra memory needed — just two pointers (lo, hi).
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Setting `lo = mid` or `hi = mid` can stall and create an infinite loop.
Usually fails on: Two-element ranges never converge.
Fix: Use `lo = mid + 1` or `hi = mid - 1` where appropriate.