{x}
blog image

Non-decreasing Array

Given an array nums with n integers, your task is to check if it could become non-decreasing by modifying at most one element.

We define an array is non-decreasing if nums[i] <= nums[i + 1] holds for every i (0-based) such that (0 <= i <= n - 2).

 

Example 1:

Input: nums = [4,2,3]
Output: true
Explanation: You could modify the first 4 to 1 to get a non-decreasing array.

Example 2:

Input: nums = [4,2,1]
Output: false
Explanation: You cannot get a non-decreasing array by modifying at most one element.

 

Constraints:

  • n == nums.length
  • 1 <= n <= 104
  • -105 <= nums[i] <= 105

Solution Explanation:

The problem asks whether we can make an array non-decreasing by modifying at most one element. A non-decreasing array means that each element is less than or equal to the next element (nums[i] <= nums[i+1]).

The solution iterates through the array, looking for violations of the non-decreasing condition (nums[i] > nums[i+1]). When a violation is found, it tries two possible modifications:

  1. Change nums[i] to nums[i+1]: This makes nums[i] <= nums[i+1], potentially fixing the current violation. The code then checks if the entire array is now non-decreasing.

  2. Change nums[i+1] to nums[i]: This makes nums[i] <= nums[i+1], potentially fixing the current violation. The code then checks if the entire array is now non-decreasing.

If either modification results in a non-decreasing array, the function returns true. If neither modification works, it means more than one element needs to be changed, so the function returns false.

If the loop completes without finding any violations, it means the array is already non-decreasing, and the function returns true.

Time Complexity Analysis:

The outer loop iterates through the array once, taking O(n) time, where n is the length of the array. The is_sorted (or equivalent) function also iterates through the array once, taking O(n) time. In the worst case, both these iterations happen for each violation, but there can be at most one violation that requires both modifications to be checked. Therefore, the overall time complexity remains O(n).

Space Complexity Analysis:

The space complexity is O(1) because the algorithm only uses a constant amount of extra space to store variables, regardless of the input array size. The in-place modifications within the array do not affect the space complexity.

Code Explanation (Python Example):

class Solution:
    def checkPossibility(self, nums: List[int]) -> bool:
        def is_sorted(nums: List[int]) -> bool:
            return all(a <= b for a, b in pairwise(nums))
 
        n = len(nums)
        for i in range(n - 1):
            a, b = nums[i], nums[i + 1]
            if a > b:
                nums[i] = b
                if is_sorted(nums):
                    return True
                nums[i] = a  # Restore to original value
                nums[i + 1] = a #Try the other modification.
                return is_sorted(nums)
        return True
 

The pairwise function (not shown explicitly in all examples but implied) is a helper function (often available in libraries like itertools in Python) that iterates through pairs of consecutive elements in the list. The is_sorted function efficiently checks if the array is non-decreasing. The rest of the code implements the algorithm as described above. The other language examples follow a very similar structure and logic.