0

I made a function for finding largest subarray length. It works fine but with some input it doesn't show the correct output.

Here is my code:

    function maxLength(a, k) {
      function sumOfArray(arr) {
        return arr.reduce((a, b) => a + b, 0);
      }

      var sub_array = [];
      for (var i = 0; i < a.length; i++) {
        for (var j = i + 1; j < a.length; j++) {
          if (j - i > sub_array.length && sumOfArray(a.slice(i, j)) < k) {
            sub_array = a.slice(i, j);
          }
        }
      }
      return sub_array.length;
    }


console.log(maxLength([3,1,2,1,4], 4))

The input which shows wrong answer is: [3,1,2,1,4] and k = 4 which the output is 2 but the correct answer is 3

How can I fix the code

Any help will be appreciated

10
  • what does the subarray contain? Commented Aug 30, 2018 at 14:01
  • 2
    So what is an example of an input that is wrong, what is one that is right? Commented Aug 30, 2018 at 14:02
  • @epascarello I mentioned in the question the case which is wrong and the correct answer for that Commented Aug 30, 2018 at 14:03
  • One that works would help as well. But there are two parameters to the function. For what value of k does [3,1,2,1,4] not work? Commented Aug 30, 2018 at 14:04
  • 2
    So do expect 3 because it's the length of [1, 2, 1]? If so, then you need to change < k to <= k. Commented Aug 30, 2018 at 14:07

4 Answers 4

1

If I am not wrong the you are trying the subarray with max length whoes sum is as input(k).

For this change in your if condition=> < k to < =k

if (j - i > sub_array.length && sumOfArray(a.slice(i, j)) < k) 

to

if (j - i > sub_array.length && sumOfArray(a.slice(i, j)) <= k)  

function maxLength(a, k) {
  function sumOfArray(arr) {
    return arr.reduce((a, b) => a + b, 0);
  }

  var sub_array = [];
  for (var i = 0; i < a.length; i++) {
    for (var j = i + 1; j < a.length; j++) {
      if (j - i > sub_array.length && sumOfArray(a.slice(i, j)) <= k) {
        sub_array = a.slice(i, j);
      }
    }
  }
  return sub_array.length;
}
console.log(maxLength([3,1,2,1,4],4));
console.log(maxLength([3,1,2,1,4],7));
console.log(maxLength([1,1,1,1,3,1,2,1,4],7));

Sign up to request clarification or add additional context in comments.

1 Comment

I have tried this before. But it shows the same output
1

After testing with different cases finally I got that some part of the code should be changed.

First for loop must i <= a.length and also second for loop j <= a.length

Also in if statement sumOfArray(a.slice(i, j)) < k should be change to:

sumOfArray(a.slice(i, j)) <= k

These changes show the correct answer for all cases.

So here is the code:

function maxLength(a, k) {
function sumOfArray(arr) {
  return arr.reduce((a, b) => a + b, 0);
}

var sub_array = [];
for (var i = 0; i <= a.length; i++) {
  for (var j = i + 1; j <= a.length; j++) {
    if (j - i > sub_array.length && sumOfArray(a.slice(i, j)) <= k) {
      sub_array = a.slice(i, j);
    }
  }
} 
return sub_array.length;

}

Comments

0

@NullPointer gave the simple modification that seems to make your function work. Here is another approach that I think simplifies the problem:

const sum = (xs) => xs.reduce((a, b) => a + b, 0)
const range = (lo, hi) => [...new Array(hi - lo + 1)].map((_, i) => i + lo);

const subarrays = (arr) => arr
  .map((x, i) => range(i + 1, arr.length + 1).map(j => arr.slice(i, j)))  
  .reduce((a, b) => a.concat(b), [[]])

const maxLength = (arr, limit) => Math.max.apply(null,
  subarrays(arr)
    .filter(xs => sum(xs) <= limit)
    .map(xs => xs.length)
)

console.log(maxLength([3, 1, 2, 1, 4], 4))

  • sum gives the sum of the values in an array.
  • range creates an array of numbers between lo and high
  • subarrays lists the subarrays of an array. For instance subarrays([2, 3, 5]) returns [[], [2], [2, 3], [2, 3, 5], [3], [3, 5], [5]]

and of course

  • maxLength is the function you're trying to write.

There are certainly potential efficiencies lost in this approach, involving not having to test subarrays that extend one that already exceeds the limit. But those efficiencies are not used in the original either.

sum and range here are clearly reusable functions, and it's possible that subarrays might also come in handy.

Comments

0

A few issues with the above:

  • is not defensive (i could also check type in my code)
  • starts at the smallest blocks, do the biggest spans first so you can terminate early

Try:

function maxLength(a, k) {
  if(!a || !k) return 0
  for(let scanlen = a.length; scanlen; scanlen--){
    for(let start = 0; start+scanlen<=a.length; start++){
      if( a.slice(start, start+scanlen).reduce((acc,curr)=> acc+curr ) <= k)
         return scanlen
    }
  }
  return 0
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.