Home > Back-end >  DSA: Trapping water problem solution issue
DSA: Trapping water problem solution issue

Time:02-05

My brute solution works fine with a break condition handled by a map.

enter image description here

function trap_a(arr) {
    let result = 0;
    for (let i=1; i<arr.length-1; i  ) {
        const curr = arr[i];
        let left = 0;
        let right = 0;
        let li = i-1;
        let ri = i 1;
        const hasNext = { left: true, right: true }; // <== here
        while(hasNext.left || hasNext.right) {  // <== here
            left = Math.max(left, arr[li]);
            right = Math.max(right, arr[ri]);
            if (arr[li-1] != undefined) {
                li--;
            }  else {
                hasNext.left = false;  // <== here
            }
            if (arr[ri 1] != undefined) {
                ri  ;
            } else {
                hasNext.right = false;  // <== here
            }
        }
        result  = Math.min(left, right) - curr;
    }
    return Math.abs(result);
}

This compares the biggest on the left side of the current element and same on the right.

But when I try to simplify the code by NOT using a map, it gives a different answer (wrong):

function trap_b(arr) {
    let result = 0;
    for (let i=1; i<arr.length-1; i  ) {
        const curr = arr[i];
        let left = 0;
        let right = 0;
        let li = i-1;
        let ri = i 1;
        while(arr[li-1] !== undefined || arr[ri 1] !== undefined) { // <== here
            left = Math.max(left, arr[li]);
            right = Math.max(right, arr[ri]);
            if (arr[li-1] != undefined) {
                li--;
            }  
            if (arr[ri 1] != undefined) {
                ri  ;
            } 
        }
        result  = Math.min(left, right) - curr;
    }
    return Math.abs(result);
}

Test case:

    console.log(trap_a([4,1,0,3,2,5]) === 10); // passes
    console.log(trap_b([4,1,0,3,2,5]) === 10); // fails

I am not sure what I am doing wrong in the second solution, it is literally doing the same thing. Am I missing something here?

CodePudding user response:

In trap_b, when you decrement li (respectively, increment ri), you check a different index in the loop test instead of the same one, so the loop exits early.

CodePudding user response:

It seems that trap_b is unable to iterate through the loop entirely. More specifically the right most element of the array is unreachable.

So in the first iteration, "right" is never updated to 5. This in turn results in

Math.max(left, right) - curr = Math.max(4, 3) - 1 = 2.

It should be:

Math.max(left, right) - curr = Math.max(4, 5) - 1 = 3.

Here is a small change that I made to the algorithm that ensures that left and right variables are updated correctly.

function trap_b(arr) {
    let result = 0;
    for (let i=1; i<arr.length-1; i  ) {
        const curr = arr[i];
        let left = 0;
        let right = 0;
        let li = i-1;
        let ri = i 1;
        while(arr[li-1] !== undefined || arr[ri 1] !== undefined) { // <== here
            left = Math.max(left, arr[li]);
            right = Math.max(right, arr[ri]);
            if (arr[li-1] != undefined) {
                li--;
            }  
            if (arr[ri 1] != undefined) {
                ri  ;
            } 
        }
        //Here is the change
        left = Math.max(left, arr[li]);
        right = Math.max(right, arr[ri]);
        //end of change

        result  = Math.min(left, right) - curr;
    }
    
    return Math.abs(result);
}
  • Related