Right now I’m solving some leetcode problems and I found a curious thing in my code for https://leetcode.com/problems/3sum/ but I don’t understand how it really works.
Problem of this code: Return in hasSimularArray doesn’t exits from the function when hasSimularArray used in threeSum function. The problems is that hasSimularArray keeps running as if it’s a recursion function but it’s not. So when it reaches this line of code "return true;" in hasSimularArray it has to stop execution code in the function.
function threeSum(nums: number[]): number[][] {
const tripletsResult = [];
nums.sort((a, b) => a - b);
for (let i = 0; i < nums.length - 2; i++) {
let j = i + 1;
let k = nums.length - 1;
while (j < k) {
const possibleResultEl = [nums[i], nums[j], nums[k]];
const threeNumsSum = nums[i] + nums[j] + nums[k];
if (threeNumsSum === 0) {
const hasVal = hasSimularArray(tripletsResult, possibleResultEl);
if (!hasVal) {
tripletsResult.push(possibleResultEl);
}
} else if (threeNumsSum < 0) {
j++;
} else {
k--;
}
}
}
return tripletsResult;
}
function hasSimularArray(mainArr: number[][], searchedArr: number[]) {
if (mainArr.length === 0) {
return false;
}
const searchArrayStr = JSON.stringify([...searchedArr].sort());
for (let el of mainArr) {
const elArrayStr = JSON.stringify([...el].sort());
if (elArrayStr === searchArrayStr) {
return true;
}
}
return false;
}
console.log(threeSum([0, 3, 0, 1, 1, -1, -5, -5, 3, -3, -3, 0]));
Sometime before I faced with a simular problem but it was a bit different code with the same return logic in a nested function and that return somehow exited not only from the nested function but also from the parent one.
Tried to understand what’s going on under the hood over debug mode but it didn’t give any clues to me.
In my case things got worse when I tested hasSimularArray by itself without parent function with the same values and it works as it should.
Could someone please explain what is happening here?
2
Answers
I don’t know how you have come to this conclusion, but there is no problem with the
return
statements inhasSimularArray
: they get executed and do exit the function. We could say it is an inefficient function, but that is not the main problem here.Simple debugging shows that your code gets into an infinite
while (j < k)
when the conditionthreeNumsSum === 0
becomes true. In that case, you don’t change the values ofj
nork
, so the next iteration of thewhile
loop will look at the exact same numbers and come to the same conclusion thatthreeNumsSum
is 0, repeating this indefinitely.You must make sure that the
while
loop makes the window(j, k)
smaller.In the case of
threeNumsSum
you can both increasej
and decreasek
:Your algorithm might be crashing and burning when the
nums
array is large.You can efficiently keep track of which triplets have already been found by using an Object (you could also use a Map). You can also use that same object to store the triplets that you’re going to return.