Skip to content

Missing number problem#1336

Open
shinjaneegupta wants to merge 1 commit intosuper30admin:masterfrom
shinjaneegupta:master
Open

Missing number problem#1336
shinjaneegupta wants to merge 1 commit intosuper30admin:masterfrom
shinjaneegupta:master

Conversation

@shinjaneegupta
Copy link

No description provided.

@super30admin
Copy link
Owner

Strengths:

  • You have chosen the right algorithm (binary search) to achieve O(log n) time complexity.
  • The code is clean and well-structured with appropriate variable names.
  • You considered the overflow prevention in mid calculation.

Areas for Improvement:

  • The logic inside the binary search needs correction. The condition if arr[mid] <= (mid + 1) is not accurate. Instead, you should compare the value at mid with the expected value (which is mid + 1) to determine if the missing number is on the left or right. For instance, if arr[mid] == mid + 1, then the missing number is to the right; if arr[mid] > mid + 1, then the missing number is to the left. However, note that in this problem, the array starts at 1 and goes to n, so the expected value at index i is i+1.
  • Consider using the difference method as in the reference solution: if arr[mid] - mid is 1 (which it should be for all elements before the missing number), then the missing number is to the right; otherwise, it's to the left. Actually, for the left part, arr[i] - i = 1, and for the right part, arr[i] - i = 2.
  • Test your code with the provided examples. For input [1,2,3,5,6,7,8], your code returns low+1. Let's simulate:
    Initially: low=0, high=6.
    mid = 3 -> arr[3]=5. Check: 5 <= 4? No -> high = 2.
    Then low=0, high=2 -> mid=1 -> arr[1]=2 <= 2? Yes -> low=2.
    Then low=2, high=2 -> mid=2 -> arr[2]=3 <= 3? Yes -> low=3.
    Then low=3, high=2 -> exit. Return 3+1=4. This happens to work for this case. But try with another example: [1,2,4,5,6,7,8,9] (missing 3).
    low=0, high=7.
    mid=3 -> arr[3]=5 <= 4? No -> high=2.
    Then low=0, high=2 -> mid=1 -> arr[1]=2 <= 2? Yes -> low=2.
    Then low=2, high=2 -> mid=2 -> arr[2]=4 <= 3? No -> high=1.
    Then low=2, high=1 -> exit. Return 2+1=3. This also works. But what if the missing number is at the beginning? [2,3,4,5] (missing 1). The array has n-1=4 elements, n=5.
    low=0, high=3.
    mid=1 -> arr[1]=3 <= 2? No -> high=0.
    Then low=0, high=0 -> mid=0 -> arr[0]=2 <= 1? No -> high=-1.
    Then exit, return 0+1=1. This works.
    What if the missing number is at the end? [1,2,3,4] (missing 5). n=5.
    low=0, high=3.
    mid=1 -> arr[1]=2 <= 2? Yes -> low=2.
    Then low=2, high=3 -> mid=2 -> arr[2]=3 <= 3? Yes -> low=3.
    Then low=3, high=3 -> mid=3 -> arr[3]=4 <= 4? Yes -> low=4.
    Then exit, return 4+1=5. This works.

Surprisingly, the solution seems to work for these cases. However, let's test with a different one: [1,3,4,5] (missing 2). n=5.
low=0, high=3.
mid=1 -> arr[1]=3 <= 2? No -> high=0.
Then low=0, high=0 -> mid=0 -> arr[0]=1 <= 1? Yes -> low=1.
Then exit, return 1+1=2. This works.

But wait, what about [2,4,5,6] (missing 3)? n=5.
low=0, high=3.
mid=1 -> arr[1]=4 <= 2? No -> high=0.
Then low=0, high=0 -> mid=0 -> arr[0]=2 <= 1? No -> high=-1.
Return 0+1=1, but expected 3. This fails.

So the solution does not work for all cases. The issue is that the condition arr[mid] <= (mid+1) is not sufficient. In the failing case, at index0, value=2 which is greater than 1, so it should indicate that the missing number is to the left? But actually the missing number is 3 which is to the right of index0.

The correct approach is to note that if the array is complete, then arr[i] = i+1. If there is a missing number, then for all indices from the missing number onward, arr[i] > i+1. So we need to find the first index i where arr[i] != i+1. Then the missing number is i+1.

So the binary search should be designed to find the smallest index i such that arr[i] != i+1. Then return i+1.

Alternatively, we can use the difference: if arr[mid] - mid == 1, then the missing number is to the right; else to the left.

Revised approach:
low, high = 0, len(arr)-1
while low <= high:
mid = (low+high)//2
if arr[mid] == mid+1:
low = mid+1
else:
high = mid-1
return low+1

This is actually the same as the student's code? Because if arr[mid] == mid+1, then we go right. But if not, we go left. But in the student's code, they have if arr[mid] <= (mid+1) which is different.

In the failing case [2,4,5,6]:
low=0, high=3.
mid=1: arr[1]=4, which is not equal to 2? So else: high=0.
Then low=0, high=0: mid=0: arr[0]=2 != 1? So else: high=-1.
Then return low+1=1, but expected 3.

This revised approach also fails for this case because the array does not start with 1. So we need to consider that if the first element is not 1, then the missing number is 1. But in the binary search, we are looking for the first index where arr[i] != i+1. However, in [2,4,5,6], at index0, arr[0]=2 !=1, so the missing number should be 1? But actually it is 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments