Skip to main content
added 934 characters in body
Source Link
janos
  • 111.7k
  • 15
  • 152
  • 391

That's a nice simple solution, with two problems:

  1. It will give incorrect result when A contains all the values in the ranges [1..1000000] or [1..999999], returning undefined instead of 1000001 and 1000000, respectively.
  2. It doesn't meet the time complexity requirement, being \$O(n^2)\$ instead of \$O(n)\$.

The first problem is easy to fix by adjusting the end condition of the loop.

The second problem is trickier, and the interesting part of the exercise. Consider this algorithm, that's \$O(n)\$ in time and \$O(1)\$ in space:

  • Loop over the elements of A from the start, and for each value A[i], if A[i] - 1 is a valid index in the array, then repeatedly swap A[i] and A[A[i] - 1] until A[i] is in its correct place (value equal to i + 1), or A[i] and A[A[i] - 1] are equal.
    • This should order the values to their right places such that A[i] == i + 1, when possible
  • Loop over the elements again to find an index where A[i] != i + 1, if exists then the missing value is i + 1
  • If the end of the loop is reached without returning a value, then the missing value is A.length + 1.

Here's one way to implement this in JavaScript:

var firstMissingPositive = function(nums) {
    var swap = function(i, j) {
        var tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    };

    for (let i = 0; i < nums.length; i++) {
        while (0 < nums[i] && nums[i] - 1 < nums.length
                && nums[i] != i + 1
                && nums[i] != nums[nums[i] - 1]) {
            swap(i, nums[i] - 1);
        }
    }

    for (let i = 0; i < nums.length; i++) {
        if (nums[i] != i + 1) {
            return i + 1;
        }
    }
    return nums.length + 1;
};

Note: to verify this, or alternative implementations work, you could submit on leetcode.

That's a nice simple solution, with two problems:

  1. It will give incorrect result when A contains all the values in the ranges [1..1000000] or [1..999999], returning undefined instead of 1000001 and 1000000, respectively.
  2. It doesn't meet the time complexity requirement, being \$O(n^2)\$ instead of \$O(n)\$.

The first problem is easy to fix by adjusting the end condition of the loop.

The second problem is trickier, and the interesting part of the exercise. Consider this algorithm:

  • Loop over the elements of A from the start, and for each value A[i], if A[i] - 1 is a valid index in the array, then repeatedly swap A[i] and A[A[i] - 1] until A[i] is in its correct place (value equal to i + 1), or A[i] and A[A[i] - 1] are equal.
    • This should order the values to their right places such that A[i] == i + 1, when possible
  • Loop over the elements again to find an index where A[i] != i + 1, if exists then the missing value is i + 1
  • If the end of the loop is reached without returning a value, then the missing value is A.length + 1.

That's a nice simple solution, with two problems:

  1. It will give incorrect result when A contains all the values in the ranges [1..1000000] or [1..999999], returning undefined instead of 1000001 and 1000000, respectively.
  2. It doesn't meet the time complexity requirement, being \$O(n^2)\$ instead of \$O(n)\$.

The first problem is easy to fix by adjusting the end condition of the loop.

The second problem is trickier, and the interesting part of the exercise. Consider this algorithm, that's \$O(n)\$ in time and \$O(1)\$ in space:

  • Loop over the elements of A from the start, and for each value A[i], if A[i] - 1 is a valid index in the array, then repeatedly swap A[i] and A[A[i] - 1] until A[i] is in its correct place (value equal to i + 1), or A[i] and A[A[i] - 1] are equal.
    • This should order the values to their right places such that A[i] == i + 1, when possible
  • Loop over the elements again to find an index where A[i] != i + 1, if exists then the missing value is i + 1
  • If the end of the loop is reached without returning a value, then the missing value is A.length + 1.

Here's one way to implement this in JavaScript:

var firstMissingPositive = function(nums) {
    var swap = function(i, j) {
        var tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    };

    for (let i = 0; i < nums.length; i++) {
        while (0 < nums[i] && nums[i] - 1 < nums.length
                && nums[i] != i + 1
                && nums[i] != nums[nums[i] - 1]) {
            swap(i, nums[i] - 1);
        }
    }

    for (let i = 0; i < nums.length; i++) {
        if (nums[i] != i + 1) {
            return i + 1;
        }
    }
    return nums.length + 1;
};

Note: to verify this, or alternative implementations work, you could submit on leetcode.

deleted 1 character in body
Source Link
janos
  • 111.7k
  • 15
  • 152
  • 391

That's a nice simple solution, with two problems:

  1. It will give incorrect result when A contains all the values in the ranges [1..1000000] or [1..999999], returning undefined instead of 1000001 and 1000000, respectively.
  2. It doesn't meet the time complexity requirement, being \$O(n^2)\$ instead of \$O(n)\$.

The first problem is easy to fix by adjusting the end condition of the loop.

The second problem is trickier, and the interesting part of the exercise. Consider this algorithm:

  • Loop over the elements of A from the start, and for each value A[i], if A[i] - 1 is a valid index in the array, then recursivelyrepeatedly swap A[i] and A[A[i] - 1] until A[i] is in its correct place (value equal to i + 1), or A[i] and A[A[i] - 1] are equal.
    • This should order the values to their right places such that A[i] == i + 1, when possible
  • Loop over the elements again to find an index where A[i] != i + 1, if exists then the missing value is i + 1
  • If the end of the loop is reached without returning a value, then the missing value is A.length + 1.

That's a nice simple solution, with two problems:

  1. It will give incorrect result when A contains all the values in the ranges [1..1000000] or [1..999999], returning undefined instead of 1000001 and 1000000, respectively.
  2. It doesn't meet the time complexity requirement, being \$O(n^2)\$ instead of \$O(n)\$.

The first problem is easy to fix by adjusting the end condition of the loop.

The second problem is trickier, and the interesting part of the exercise. Consider this algorithm:

  • Loop over the elements of A from the start, and for each value A[i], if A[i] - 1 is a valid index in the array, then recursively swap A[i] and A[A[i] - 1] until A[i] is in its correct place (value equal to i + 1), or A[i] and A[A[i] - 1] are equal.
    • This should order the values to their right places such that A[i] == i + 1, when possible
  • Loop over the elements again to find an index where A[i] != i + 1, if exists then the missing value is i + 1
  • If the end of the loop is reached without returning a value, then the missing value is A.length + 1.

That's a nice simple solution, with two problems:

  1. It will give incorrect result when A contains all the values in the ranges [1..1000000] or [1..999999], returning undefined instead of 1000001 and 1000000, respectively.
  2. It doesn't meet the time complexity requirement, being \$O(n^2)\$ instead of \$O(n)\$.

The first problem is easy to fix by adjusting the end condition of the loop.

The second problem is trickier, and the interesting part of the exercise. Consider this algorithm:

  • Loop over the elements of A from the start, and for each value A[i], if A[i] - 1 is a valid index in the array, then repeatedly swap A[i] and A[A[i] - 1] until A[i] is in its correct place (value equal to i + 1), or A[i] and A[A[i] - 1] are equal.
    • This should order the values to their right places such that A[i] == i + 1, when possible
  • Loop over the elements again to find an index where A[i] != i + 1, if exists then the missing value is i + 1
  • If the end of the loop is reached without returning a value, then the missing value is A.length + 1.
Source Link
janos
  • 111.7k
  • 15
  • 152
  • 391

That's a nice simple solution, with two problems:

  1. It will give incorrect result when A contains all the values in the ranges [1..1000000] or [1..999999], returning undefined instead of 1000001 and 1000000, respectively.
  2. It doesn't meet the time complexity requirement, being \$O(n^2)\$ instead of \$O(n)\$.

The first problem is easy to fix by adjusting the end condition of the loop.

The second problem is trickier, and the interesting part of the exercise. Consider this algorithm:

  • Loop over the elements of A from the start, and for each value A[i], if A[i] - 1 is a valid index in the array, then recursively swap A[i] and A[A[i] - 1] until A[i] is in its correct place (value equal to i + 1), or A[i] and A[A[i] - 1] are equal.
    • This should order the values to their right places such that A[i] == i + 1, when possible
  • Loop over the elements again to find an index where A[i] != i + 1, if exists then the missing value is i + 1
  • If the end of the loop is reached without returning a value, then the missing value is A.length + 1.