Reputation: 1848
I wrote this code that works just fine. However I think there may be a cleaner/better way of doing this. Basically I have to create a function that takes 2 arguments (array and sum), and return the 2 elements that when adding them together is equals the sum parameter. Does anyone know how to refactor this code or make it simpler?
Here's my code:
var list = [2, 6, 20, 4, 11, 30, 5];
var sum = 9;
var myArray = [];
function findTwoNumbers(arr, sum) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] + arr[j] === sum) {
myArray.push(arr[i], arr[j]);
}
}
}
return myArray;
}
console.log(findTwoNumbers(list, sum)); // [4 , 5]
Upvotes: 0
Views: 739
Reputation: 34556
The obvious problem with your code currently as it will return an array of multiple pairs if there is more than one combination to achieve the sum from the input numbers. So for example:
let list = [1, 2, 4, 1];
let sum = 5;
//would give [1, 4, 4, 1];
Assuming you want just the first pair, there's no reason to maintain an array (and certainly not one outside the function) - just return immediately:
function findTwoNumbers(arr, sum) {
for (let i = 0; i < arr.length; i++)
for (let j = i + 1; j < arr.length; j++)
if (arr[i] + arr[j] === sum)
return [arr[i], arr[j]];
}
There are further efficiencies and simplicities we can make. Firstly, the loop should ignore any number which is, in itself, higher than sum-1 (since this is the highest a number can be to still achieve the sum with the help of another number, which have to be 1.)
And since it's midnight, how about some pointless syntax sugar?
function findTwoNumbers(arr, sum) {
let nums = arr.filter(num => num < sum);
return nums.map(num => {
return nums.filter(num2 => num + num2 == sum)[0];
}).filter(x => x);
}
Upvotes: 0
Reputation: 8668
How about this:
Basically take the sum and subtract the first number in the array to get the remainder, then check if the remainder exists in the array, if not move on to the next.
let list = [2, 6, 20, 4, 11, 30, 5];
let sum = 9;
function findTwoNumbers(list, sum) {
for (let i = 0; i < list.length; i++) {
let n =list[i];
if (list.includes(sum - n)) {
return [sum - n, n];
}
}
}
console.log(findTwoNumbers(list, sum))
Upvotes: 0
Reputation: 198314
Your code is O(N^2). You can reduce it a bit by using a set (though it has a startup cost of constructing the set, so you probably get raw speedup only for large arrays):
function findTwoNumbers(arr, sum) {
const arrset = new Set(arr);
const answer = arr.find(e => e + e !== sum && arrset.has(sum - e));
return answer === undefined ? null : [answer, sum - answer];
}
Upvotes: 3
Reputation: 780724
Turn the array into a Set. Then iterate through the array and test whether sum - element
is in the set.
I need to check for diff == element
to prevent returning a match from adding an element to itself.
var list = [2, 6, 20, 4, 11, 30, 5];
var sum = 9;
function findTwoNumbers(arr, sum) {
const set = new Set(arr);
for (let i = 0; i < arr.length; i++) {
let element = arr[i];
let diff = sum - element;
if (diff != element && set.has(diff)) {
return [element, diff];
}
}
}
console.log(findTwoNumbers(list, sum)); // [4 , 5]
console.log(findTwoNumbers([2, 5], 4)); // undefined
Upvotes: 2
Reputation: 26
Another way would be to first sort the array (O(nlog(n)) then traverse the array and for each element, find the difference between (sum - element) and then do a binary search (O(log(n)) for that value.
For example, the first element is 2, so you would binary search the sorted array for 7 (9 - 2 = 7) and if you find it, then 2 and 7 are a pair. You can stop short too as soon as you reach an element that is greater than (sum/2).
Hope this helps.
Upvotes: 0
Reputation: 12196
You can return an array without the need of external array
function findTwoNumbers(arr, sum){
for (var i = 0; i < arr.length; i++) {
for(var j = i + 1; j < arr.length; j++){
if(arr[i] + arr[j] === sum){
return [arr[i] , arr[j]];
}
}
}
return [];
}
Note: This will only search for the first pair that satisfy the condition, there could be more pairs down the iteration path.
Upvotes: 0