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.
Move from brute-force thinking to an efficient approach using array strategy.
You are given an integer array nums. In one operation, you can select a subarray and replace it with a single element equal to its maximum value.
Return the maximum possible size of the array after performing zero or more operations such that the resulting array is non-decreasing.
Example 1:
Input: nums = [4,2,5,3,5]
Output: 3
Explanation:
One way to achieve the maximum size is:
nums[1..2] = [2, 5] with 5 → [4, 5, 3, 5].nums[2..3] = [3, 5] with 5 → [4, 5, 5].The final array [4, 5, 5] is non-decreasing with size 3.
Example 2:
Input: nums = [1,2,3]
Output: 3
Explanation:
No operation is needed as the array [1,2,3] is already non-decreasing.
Constraints:
1 <= nums.length <= 2 * 1051 <= nums[i] <= 2 * 105Problem summary: You are given an integer array nums. In one operation, you can select a subarray and replace it with a single element equal to its maximum value. Return the maximum possible size of the array after performing zero or more operations such that the resulting array is non-decreasing.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Stack · Greedy
[4,2,5,3,5]
[1,2,3]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3523: Make Array Non-decreasing
class Solution {
public int maximumPossibleSize(int[] nums) {
int ans = 0, mx = 0;
for (int x : nums) {
if (mx <= x) {
++ans;
mx = x;
}
}
return ans;
}
}
// Accepted solution for LeetCode #3523: Make Array Non-decreasing
func maximumPossibleSize(nums []int) int {
ans, mx := 0, 0
for _, x := range nums {
if mx <= x {
ans++
mx = x
}
}
return ans
}
# Accepted solution for LeetCode #3523: Make Array Non-decreasing
class Solution:
def maximumPossibleSize(self, nums: List[int]) -> int:
ans = mx = 0
for x in nums:
if mx <= x:
ans += 1
mx = x
return ans
// Accepted solution for LeetCode #3523: Make Array Non-decreasing
fn maximum_possible_size(nums: Vec<i32>) -> i32 {
let mut ret = 0;
let mut prev = 0;
for num in nums {
if num >= prev {
prev = num;
ret += 1;
}
}
ret
}
fn main() {
let nums = vec![4, 2, 5, 3, 5];
let ret = maximum_possible_size(nums);
println!("ret={ret}");
}
#[test]
fn test() {
{
let nums = vec![4, 2, 5, 3, 5];
let ret = maximum_possible_size(nums);
assert_eq!(ret, 3);
}
{
let nums = vec![1, 2, 3];
let ret = maximum_possible_size(nums);
assert_eq!(ret, 3);
}
}
// Accepted solution for LeetCode #3523: Make Array Non-decreasing
function maximumPossibleSize(nums: number[]): number {
let [ans, mx] = [0, 0];
for (const x of nums) {
if (mx <= x) {
++ans;
mx = x;
}
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
For each element, scan left (or right) to find the next greater/smaller element. The inner scan can visit up to n elements per outer iteration, giving O(n²) total comparisons. No extra space needed beyond loop variables.
Each element is pushed onto the stack at most once and popped at most once, giving 2n total operations = O(n). The stack itself holds at most n elements in the worst case. The key insight: amortized O(1) per element despite the inner while-loop.
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: Pushing without popping stale elements invalidates next-greater/next-smaller logic.
Usually fails on: Indices point to blocked elements and outputs shift.
Fix: Pop while invariant is violated before pushing current element.
Wrong move: Locally optimal choices may fail globally.
Usually fails on: Counterexamples appear on crafted input orderings.
Fix: Verify with exchange argument or monotonic objective before committing.