Search code examples
javascriptnode.jsarraysperformancemin

Find Minimum and Maximum in given array where constraints should minimum value index should be less than its maximum


Given Array ["1510", "1518", "1520", "1523", "1530", "1483", "1485"] Expected output :-

Smallest - 1510
Largest - 1530

Another Array ["310", "314", "320", "319", "323", "313", "330"] Expected output :-

Smallest - 310
Largest - 330

My code below gets the minimum value and maximum value it's having issues with solving the first problem listed above since it's returning 1483 as smallest and 1485 as the largest. The difference between max and min should be larger.

Any idea on how to get that?

function minMax(array) {
    if(array.length <= 0) return [0, 0];
    let max = Math.max.apply(null, array);
    let min = Math.min.apply(null, array);
    let max_index = array.lastIndexOf(String(max));
    let min_index = array.indexOf(String(min));
    if(min_index >= max_index) {
        array.splice(max_index, 1);
        [min, max] = minMax(array);
    }
    return [min, max];
}

Solution

  • A single pass over the array:

    1. Iterate from the end of the array to the beginning.
    2. Keep track of max and min as well as list of min/max pairs
    3. Check each item
      • If the item found is more than the current max,
        • add current min/max to the list of pairs
        • make the current item the max and reset the min
      • Otherwise, if the current item is less than the current min, make it the min.
      • Otherwise do nothing.
    4. Afterwards add the last min/max pair to the list.

    At this point you have a list of potential min/max pairs to return. You have to check them from the end to the start to find the first one where the minimum is set and return it. Or return a default set of min/max.

    function minMax(arr) {
      let max = -Infinity;
      let min = Infinity;
      const candidates = [];
      for (let i = arr.length-1; i >= 0; i--) {
        const item = Number(arr[i]);
        if (item > max) {
          candidates.push([min, max]);
          max = item;
          min = Infinity;
        } else if (item < min) {
          min = item;
        }
      }
      candidates.push([min, max]);
    
      // Instead of return fixed first or last element below code would return first element from last which is finite.
      for(let i = candidates.length - 1; i >= 0; i--) {
          if(Number.isFinite(candidates[i][0])) return candidates[i];
       }
       return [0, 0];
    }
    console.log(minMax(["1510", "1518", "1520", "1523", "1530", "1483", "1485"]));
    console.log(minMax(["310", "314", "320", "319", "323", "313", "330"]));
    console.log(minMax(["350", "314", "320", "319", "323", "313", "330"]));
    console.log(minMax(["7", "6", "1", "2"]));
    console.log(minMax(["4", "3", "2", "1"]));