Non-decreasing Array, by LeetCode

New problem by LeetCode, right here: https://leetcode.com/problems/non-decreasing-array/description/

Given an array with n integers, your task is to check if it could become non-decreasing by modifying at most 1 element.
We define an array is non-decreasing if array[i] <= array[i + 1] holds for every i (1 <= i < n).
Example 1:
Input: [4,2,3]
Output: True
Explanation: You could modify the first 4 to 1 to get a non-decreasing array.
Example 2:
Input: [4,2,1]
Output: False
Explanation: You can't get a non-decreasing array by modify at most one element.
Note: The n belongs to [1, 10,000].
The solution that I came up is not the most glamorous one, but beat the majority of the other submissions. Here is the idea: you're going to do one pass thru the array looking to see if it is in "ascending" order (ascending is in quotes because you may have dupes). That's O(n). As you do so check how many "errors" you find where an error is A[i] > A[i+1]. If you find more than one of those errors, you can bail, it is a Nay in such a case. But if you find only one, well, you want to see if there is a way to fix it. There are only two options here:
 - Either setting A[i] to be the same as A[i+1] will do it (another check here: O(n))
 - Or setting A[i+1] to be the same as A[i] will do it (another check here: O(n))
Hence, a total of O(3n), or a max of 30,000 iterations. Code is down below, cheers, Marcelo.


public class Solution
{
public bool CheckPossibility(int[] nums)
{
int instances = 0;

for (int i = 0; i < nums.Length - 1; i++)
{
if (nums[i] > nums[i + 1])
{
instances++;
if (instances > 1) return false;

//Check both sides
bool oneSideWorks = false;

int temp = nums[i];
nums[i] = nums[i + 1];
if (IsSorted(nums)) oneSideWorks = true;
nums[i] = temp;

if (!oneSideWorks)
{
temp = nums[i + 1];
nums[i + 1] = nums[i];
if (IsSorted(nums)) oneSideWorks = true;
nums[i + 1] = temp;
}

if (!oneSideWorks) return false;
}
}

return true;
}

private bool IsSorted(int[] nums)
{
for (int i = 0; i < nums.Length - 1; i++)
{
if (nums[i] > nums[i + 1]) return false;
}
return true;
}
}

Comments

  1. Well done, Marcelo! I'm usually lazy to spend much time working on an elegant solution for easy problems, so my solution is not elegant at all:

    class Solution {
    private:
    bool movingSourceToDestinationHelps(vector& nums, int i, int src, int dest) {
    int old_value = nums[dest];
    nums[dest] = nums[src];
    bool helps = nonDecreasing(nums, i > 0 ? i - 1 : i);
    nums[dest] = old_value;
    return helps;
    }

    bool nonDecreasing(const vector& nums, int start) {
    for (int i = start; i < nums.size() - 1; ++i) {
    if (nums[i] > nums[i+1]) return false;
    }
    return true;
    }
    public:
    bool checkPossibility(vector& nums) {
    for (int i = 0; i < nums.size() - 1; ++i) {
    if (nums[i] <= nums[i+1]) continue;
    return movingSourceToDestinationHelps(nums, i, i, i + 1) || movingSourceToDestinationHelps(nums, i, i + 1, i);
    }
    return true;
    }
    };

    Have a splendid weekend!
    Cheers,
    Taras

    ReplyDelete

Post a Comment

Popular posts from this blog

Changing the root of a binary tree

ProjectEuler Problem 719 (some hints, but no spoilers)

The Power Sum, a recursive problem by HackerRank