1. Problem Summary
You are given an integer array nums. Your task is to determine whether the array can become non-decreasing by modifying at most one element.
A non-decreasing array satisfies:
nums[i] <= nums[i+1] for all i
Constraints and rules:
- You may change one element at most
- You may change it to any value
- If the array already meets the condition, return true
Example:
Input: [4,2,3] Output: true (modify 4 → 2 → [2,2,3])
Example:
Input: [4,2,1] Output: false (needs two modifications)
2. Key Insights
Insight 1: Violations tell the story
A violation occurs when:
nums[i] > nums[i+1]
If we encounter more than one violation, then one modification cannot fix the array.
Insight 2: When violation occurs, we must decide which value to change
There are two possibilities:
Option A: modify nums[i]
This works if:
i == 0 OR nums[i-1] <= nums[i+1]
Option B: modify nums[i+1]
Used when nums[i+1] must increase to avoid new violation.
Insight 3: We don’t need to actually modify values
We can reason conceptually.
Insight 4: One pass is enough
We scan once and keep track of violations.
3. Approach
Single-pass linear scan with conditional adjustment logic
Steps:
- Initialize:
violations = 0 - Iterate i from 0 to n-2
- If nums[i] > nums[i+1], then:
- increment violations
- if violations > 1, return false
- decide which element conceptually adjusts:
- if safe to lower nums[i], simulate that
- else simulate raising nums[i+1]
- If loop completes, return true
4. Time and Space Complexity
Time Complexity
O(N)
Space Complexity
O(1)
5. Java Solution
class Solution {
public boolean checkPossibility(int[] nums) {
int violations = 0;
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1]) {
violations++;
if (violations > 1) {
return false;
}
if (i == 0 || nums[i - 1] <= nums[i + 1]) {
nums[i] = nums[i + 1];
} else {
nums[i + 1] = nums[i];
}
}
}
return true;
}
}
6. Dry Run Examples
Example 1
Input:
[4,2,3]
Step:
- violation at (4 > 2)
- i == 0 → modify nums[0] → becomes [2,2,3]
Output:
true
Example 2
Input:
[4,2,1]
Steps:
- violation at 4 > 2
- modify to [2,2,1]
- violation at 2 > 1 → second violation
Output:
false
Example 3
Input:
[3,4,2,3]
Steps:
- 4 > 2 violation
- nums[1] > nums[2] and nums[0] > nums[2] → must adjust nums[2]
- array becomes conceptually [3,4,4,3]
- next violation → fail
Output:
false
Example 4
Input:
[1,2,3]
No violations.
Output:
true
Example 5
Input:
[2,3,3,2,4]
Only one violation and fixable.
Output:
true
7. Why This Solution Works
- Only one violation allowed, so violation counting solves feasibility
- Choosing which element to adjust prevents new violations
- Works for negative numbers and duplicates
- Handles boundary index correctly
- Single pass ensures optimal complexity
8. Common Mistakes
- Trying brute-force modification options
- Always modifying nums[i] — sometimes wrong choice
- Forgetting special case at index 0
- Continuing after second violation
- Misinterpreting non-decreasing as strictly increasing
