2
\$\begingroup\$

The problem quoted:

https://leetcode.com/problems/single-element-in-a-sorted-array/

Given a sorted array consisting of only integers where every element appears exactly twice except for one element which appears exactly once. Find this single element that appears only once.

Example 1:

Input: [1,1,2,3,3,4,4,8,8]
Output: 2

Example 2:

Input: [3,3,7,7,10,11,11]
Output: 10

Note: Your solution should run in O(log n) time and O(1) space.


The answer:

var singleNonDuplicate = function(nums) {
    var low = 0, high = nums.length - 2, mid;

    while (low < high) {
        mid = low + Math.floor((high - low) / 2);
        if (mid % 2 === 1) mid--;           // make sure it is even

        if (nums[mid] !== nums[mid+1]) {    // the single element already happened on the left
            high = mid - 1;
        } else {
            low = mid + 2;
        }
    }
    return nums[low];
};

The fourth line:

while (low < high) {

if changed to

while (low <= high) {

can also pass all tests on the website. But which version is correct or more robust?

I also had to decide whether it is better to set the initial high to

high = nums.length - 2

or to

high = nums.length - 1

The same with

high = mid - 1;

I wonder if it is best to set it to mid - 1 or mid - 2.

It seems it can be complicated near the "end game", when there are 3, 5, 7, 9 remaining array elements, when the mid, low, high can be calculated in the way that the loop will not terminate or find the incorrect answer. If there are many elements remaining, such as 21, 31, etc, the algorithm in general works. It seems you have to consider the small cases when the number of remaining elements is small.

\$\endgroup\$

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.