0

So I was tasked with making a function that cycles through an array of any given length, and return the largest value found within.

Easy right? Not when you can only use for loops, and no Math functions. I know about Math.max() but I couldn't implement it here, which made me think things through.

It took me about two hours, and about 30 minutes of really slow debugging, but I think I finally have it figured out. Here's what I came up with:

function findMax(myArray) {
    aLength = myArray.length;
for(var i = 0; i < aLength - 1; i++){

    var maxNumber;
    var currentNumber = myArray[i];
    var nextNumber = myArray[i + 1];
    if(maxNumber > currentNumber){
         maxNumber = maxNumber}

    else if(currentNumber > nextNumber){
         maxNumber = currentNumber;

    } else if (nextNumber > currentNumber){
         maxNumber = nextNumber;
    }

} return maxNumber;

This worked like a charm, I just thought it was a bit large and maybe could be condensed for performance?

I know some of you will say "Why did you declare a variable set to the length of the array instead of just using myArray.length where aLength is?

Well, I don't know about you guys, but Google Chrome's Web Dev Tool throws me false positives all day long, and it wasn't reading the length property within the for loop condition statement.

How would you guys have written this code?

  • What was the reason you couldn't use `Math.max`? – Andy Jan 19 '19 at 02:33
  • 1
    If you have working code that you would like reviewed the question could/should be put on https://codereview.stackexchange.com. –  Jan 19 '19 at 02:35
  • You didn’t declare a variable set to the length of the array; you forgot to and it became a global. Make sure to work in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode). Anyway, can you explain your thinking for why `nextNumber` was necessary? – Ry- Jan 19 '19 at 02:42
  • What do you think Math.max() does? – Bayleef Jan 19 '19 at 02:47
  • It was to compare the next number with the current number in order to accept the larger of the two. Why couldn't I use Math.max()? This was an exercise in logical thinking, of course. Using the given Math functions would obviously be easy, but this is an exercise to familiarize yourself with the process of creating working functions. – Chris Schurmann Jan 21 '19 at 15:46

5 Answers5

4

this might help:

function findMax(arr) {
  let max = arr[0] || -Infinity;
  for (let i of arr)
    max = max > i ? max : i;
  return max;
}

if you cannot use Math.max() only because you have an array then you may try:

Math.max.apply(null, array);

or

Math.max(...array);  // using spread operator in ECMA-script
PranshuKhandal
  • 739
  • 7
  • 19
3

Currently, your function actually doesn't work. For example, if you input [1, 200, 3, 400] it will result in 200 not 400.

The purpose of this task seems to be to get you thinking about how you can implement an algorithm to find the maximum value in an array, hence the ban on Math functions.

When approached with such a task it is important to think about it logically and sequentially. Sometimes it can be useful to think about how you, as a human, would solve such a problem. It can be easier to write your algorithm/function when you have done this and broken down the logic into steps. When going through the array you need to do the following (steps):

  1. Check if the current number is greater than the current maximum number.
  2. If this is the case, set the maximum number equal to the current number
  3. If this is not the case, you don't need to do anything. Instead, let your loop proceed to the next number in your array
  4. Repeat this cycle until you have looked at all numbers in your array.

That is the basic outline of how your algorithm should function. However, you may run into a few issues with this. For instance, when looking at the first number in your array what should be considered the current maximum number (as you haven't seen any previous values yet)? This problem can be solved by setting the current maximum number to the first element in your array at the beginning and then running your algorithm to find any number bigger than the maximum number (the first number) and updating its value accordingly (when a higher number is found).

Taking all this into consideration your findMax() function can be rewritten like so (read code comments for further explanation):

function findMax(myArray) {
  var maxNumber = myArray[0]; // when we first start, we can set the first element in our array to be the max number - it might not be the max number in the end, but it is a number we can compare the rest of the numbers in our array off of.
  
  for (var i = 1; i < myArray.length; i++) { // loop through our array. (we can start i at 1, because we don't need to check the first element as we have set it to the maxNumber above)
    var currentNumber = myArray[i]; // get the current number from the array.
    if(currentNumber > maxNumber) { // if the current number is greater than our maximum number (which we initially set to the first number in our array) we can change our maxNumber to be the currentNumber:
      maxNumber = currentNumber
    }
  }
  // When we run this code our loop would've finished, meaning we have gone through our entire array and found the maxNumber
  return maxNumber;
}

console.log(findMax([1, 200, , 3, 400])); // Output: 400

Now if you are being really pedantic about making your function work exactly like Math.max() you can see this answer which shows Chrome V8's implementation of this method.

This here is just one implementation on how you can implement an algorithm to find the highest value in an array.

If you are worried about performance it is also important to understand that condensed code doesn't necessarily equal better performance.

The solution I provided here has a time complexity of O(N), where N is the number of elements in your array. This means that in order to find the highest element in your array it needs to check every element in your array. This might not sound too bad, but if your array grows in size (say it has 1, 000, 000 numbers), this can take some time to calculate. However, the truth of the matter is, in order to find the highest number in an array you do in fact need to check every element.

However, with that being said, there are other data structures (such as a max-heap) you can implement which can provide you with better time complexity and performance. If you were for instance to use a 'max-heap' and all you wanted to do was find the max number, you could use it in such a way which allows you to find the max number (ie get the root node) in O(1) time complexity. This means that you can instantly get the maximum number from your data structure. This isn't anything that you need to implement per se, but rather it just something to know and have in the back of your mind.

Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
  • Nick, thank you for bringing that to my attention, it seems I was over-complicating it and introduced a flaw in the process. – Chris Schurmann Jan 19 '19 at 10:50
  • As soon as you explained that I would only have to compare the 'currentNumber' with the 'maxNumber', I instantly rewrote my code without looking at yours and came up with the same answer, but yours was slightly different in that I still decided to use an 'else' statement. – Chris Schurmann Jan 19 '19 at 10:52
  • @ChrisSchurmann no worries. That’s good that you worked it out!! Good job – Nick Parsons Jan 19 '19 at 10:53
2

You can use reduce too.

here is an example

const findMax = array => array.reduce((prev, actual) => {
 return actual > prev ? actual : prev;
})

findMax([1,3,4]) // 4

const findMax = array => array.reduce((prev, actual) => {
  return actual > prev ? actual : prev;
})

console.log(findMax([1,19,20]))
Fernando Colom
  • 337
  • 1
  • 3
1

Not sure the reason to use 3 if-else ifs below is direct way since for loop is run through till the array length anyways;

function findMax(myArray=[]) {
    aLength = myArray.length;
    if(aLength===0) return;

    var maxNumber = myArray[0];
  for(var i = 0; i < aLength; i++){
    if(myArray[i]>maxNumber) {
      maxNumber=myArray[i];
    }
  } 
  return maxNumber;
}

console.log(findMax([4,2,3,78,0,9]))
Gowri
  • 394
  • 2
  • 8
0

I think you overthink the problem. What does it mean to find the maximum of an array? To have an initial value and compare it with every value from the array. If it is bigger, then you update the max value found so far. If not, you don't do anything. At the end, you are 100% sure that the variable contains the biggest value in your array.

In the code below, I initialized max to null. If the array is empty, I just return max as null. This is just a convention I made, you might remove this if you are going to test only for arrays with at least an element or return something else if the array is empty.

Next, if this condition passed, it means that I have at least one element in the array, so I can initialize the max (so far) with the first element. Now, I only have to compare the max value with the other n - 1 elements in the array and update the max if necessary.

Sometimes, other implementations initialize the max value with Number.MIN_VALUE. Why min? So that every value from your array is bigger than this value and you can start the iteration from i = 0; however, it does not work if your array has Number.MIN_VALUE as an element.

function findMax(myArray) {
  let len = myArray.length;
  let max = null;
  
  if (len === 0)
    return max;
    
  max = myArray[0];
  
  for (var i = 1; i < len; i++) {
    if (myArray[i] > max)
      max = myArray[i];
  }
  
  return max;
}

let arr = [1, 3, 4, -2, -4, 8, 16, 0, -18, 6];
let empty = [];

console.log(findMax(arr));
console.log(findMax(empty));

Bonus: There are also some cool things in javascript called lambda functions. One of them is reduce. The reduce() method executes a reducer function (that you provide) on each member of the array resulting in a single output value. It works kind of the same, but it's more elegant and compact. a is the accumulator and e is the current element. We just compare a with e and keep the largest value. The second parameter (null is the initial value, as I explained before). Implementing Math.max with reduce is very simple:

function findMax(array) {
  return array.reduce((a, e) => a > e ? a : e, null);
}

let arr = [1, 3, 4, -2, -4, 8, 16, 0, -18, 6];
let empty = [];

console.log(findMax(arr));
console.log(findMax(empty));
Adrian Pop
  • 1,879
  • 5
  • 28
  • 40