Learnitweb

LeetCode Problem 665 Non-decreasing Array


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:

  1. Initialize: violations = 0
  2. Iterate i from 0 to n-2
  3. 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]
  4. 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

  1. Trying brute-force modification options
  2. Always modifying nums[i] — sometimes wrong choice
  3. Forgetting special case at index 0
  4. Continuing after second violation
  5. Misinterpreting non-decreasing as strictly increasing