Saturday, August 26, 2017

81. Search in Rotated Sorted Array II

三刷

Runtime: 1 ms, faster than 80.32% of Java online submissions for Search in Rotated Sorted Array II.
Memory Usage: 43.6 MB, less than 64.65% of Java online submissions for Search in Rotated Sorted Array II.

class Solution {
    public boolean search(int[] nums, int target) {
        if (nums == null) {
            return false;
        }
        int start = 0, end = nums.length - 1;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] == target) {
                return true;
            }
            if (nums[mid] == nums[start]) {
                start++;
            } else if (nums[mid] == nums[end]) {
                end--;
            } else if (nums[mid] > nums[start]) {
                if (nums[start] <= target && target < nums[mid]) {
                    end = mid - 1;
                } else {
                    start = mid + 1;
                }
            } else {
                if (nums[mid] < target && target <= nums[end]) {
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
            }
        }
        if (nums[start] == target || nums[end] == target) {
            return true;
        }
        return false;
    }
}

二刷
The only difference is that due to the existence of duplicates, we can have nums[left] == nums[mid] and in that case, the first half could be out of order (i.e. NOT in the ascending order, e.g. [3 1 2 3 3 3 3]) and we have to deal this case separately. In that case, it is guaranteed that nums[right] also equals to nums[mid], so what we can do is to check if nums[mid]== nums[left] == nums[right] before the original logic, and if so, we can move left and right both towards the middle by 1. and repeat.
29.43 %
class Solution {
    public boolean search(int[] nums, int target) {
        if (nums == null || nums.length == 0) {
            return false;
        }
        int start = 0;
        int end = nums.length - 1;
        while (start < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] == target) {
                return true;
            }
            if (nums[start] == nums[mid] && nums[mid] == nums[end]) {
                start++;
                end--;
            } else if (nums[start] <= nums[mid]) { // [start, mid] is sorted
                if (nums[start] <= target && nums[mid] > target) {
                    end = mid - 1;
                } else {
                    start = mid + 1;
                }
            } else { // [mid, end] is sorted
                if (nums[mid] < target && nums[end] >= target) {
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
            }
        }
        return nums[start] == target;
    }
}

一刷

Submission Result: Wrong Answer More Details 

Input:[1,3,1,1,1] 3
Output:false
Expected:true

3 1 2 3 3 3 3 
3 3 3 3 1 2 3

一开始以为duplicates不会有影响,后来发现too young too simple了
上面是两个反例
所以用< 和 > 判断出fully ordered之后, 还存在start == mid || end == mid 的情况
这种情况下只能排除start和end,所以start++ || end--
Time worst case O(n) General case O(logn)
12.55 %

class Solution {
    public boolean search(int[] nums, int target) {
        if (nums == null || nums.length == 0) return false;
        int start = 0, end = nums.length - 1;
        // exit when start == end
        while (start < end) {
            int mid = start + (end - start) / 2;
            if (nums[mid] == target) return true;
            // first half is fully ordered
            if (nums[start] < nums[mid]) {
                if (nums[start] <= target && nums[mid] > target) end = mid - 1;
                else start = mid + 1;
            // second half is fully ordered
            } else if (nums[end] > nums[mid]) {
                if (nums[mid] < target && nums[end] >= target) start = mid + 1;
                else end = mid - 1;
            } else {
                if (nums[start] == nums[mid]) start++;
                if (nums[end] == nums[mid]) end--;
            }
        }
        return nums[start] == target;
     
    }
}





No comments:

Post a Comment