0

When i was doing leetcode 88.merge sorted array, I tried two similar solutions. First solution is correct but the second solution causes array index out of bounds exception.

The difference is (p1 < m && nums1_copy[p1] < nums2[p2]) in the first solution and (nums1_copy[p1] < nums2[p2] && p1 < m) in the second solution.

What is the reason? I am a beginner in java and I was working with javascript and never faced this issue.

Thanks a lot.

// first solution
  public void merge(int[] nums1, int m, int[] nums2, int n) {
        int[] nums1_copy = new int[m];
        int p1 = 0;
        int p2 = 0; 
        
        for (int i = 0; i < m; i++) {
            nums1_copy[i] = nums1[i];
        }
        
        for (int i = 0; i < m + n; i++) {
            if (p2 >= n || (p1 < m && nums1_copy[p1] < nums2[p2])) {
                nums1[i] = nums1_copy[p1++];
            } else {
                nums1[i] = nums2[p2++];
            }
        }
    }
// second solution
public void merge(int[] nums1, int m, int[] nums2, int n) {
        int[] nums1_copy = new int[m];
        int p1 = 0;
        int p2 = 0; 
        
        for (int i = 0; i < m; i++) {
            nums1_copy[i] = nums1[i];
        }
        
        for (int i = 0; i < m + n; i++) {
            if (p2 >= n || (nums1_copy[p1] < nums2[p2] && p1 < m)) {
                nums1[i] = nums1_copy[p1++];
            } else {
                nums1[i] = nums2[p2++];
            }
        }
    }
jps
  • 20,041
  • 15
  • 75
  • 79
Will
  • 1
  • 1
    Are you familiar with logical operator [short-circuiting](https://stackoverflow.com/q/8759868/12567365)? This means the `&&` expression in the first solution is not equivalent to the `&&` expression in the second solution. (Short circuiting applies in Java and JavaScript, just as an aside). – andrewJames May 30 '22 at 16:21
  • Thanks, I didn't think of this when coding and completely forgot this rule. I thought it read `nums1_copy[p1]` first in the second solution and thus threw the exception immediately. – Will May 30 '22 at 16:44

1 Answers1

0

In the first snippet, you check the index p1 before accessing it in nums_copy, in the second you check it after. The way && works is that it evaluates the first operand. If it's true, it goes on to evaluate the second operand. If not, then the second operand is skipped because A && B requires both A and B to be true in order to be true, so if A is false you know A && B is false regardless of B. This is called short-circuiting. Note something similar happens with ||, which doesn't evaluate the second operand if the first one is already true (since it knows then that the whole expression will be true for sure).

To come back to your case, this means the access to index p1 will be skipped in your first solution when this access is illegal (i.e. when p1 >= m) but the illegal access will still occur in the second solution, hence the exception.

Dici
  • 25,226
  • 7
  • 41
  • 82