zoukankan      html  css  js  c++  java
  • Leetcode 33. Search in Rotated Sorted Array

    Suppose a sorted array is rotated at some pivot unknown to you beforehand.

    (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

    You are given a target value to search. If found in the array return its index, otherwise return -1.

    You may assume no duplicate exists in the array.


    解题思路:

    高频题。

    binary search 的本质就是每次扔掉一部分。只要确定答案不在这一部分,就扔掉这一部分。

    Leetcode Find Minimum in Rotated Sorted Array  Leetcode Find Minimum in Rotated Sorted Array II 是一个类型的题目。

    用binary search,Complexity: O(logn), 关键点在于每次要能判断出target位于左半还是右半序列。解这题得先在纸上写几个rotated sorted array的例子出来找下规律。Rotated sorted array根据旋转得多少有两种情况:

    原数组:0 1 2 4 5 6 7
    情况1:  6 7 0 1 2 4 5    起始元素0在中间元素的左边
    情况2:  2 4 5 6 7 0 1    起始元素0在中间元素的右边

    两种情况都有半边是完全sorted的。根据这半边,当target != A[mid]时,可以分情况判断:

    当A[mid] < A[end] < A[start]:情况1,右半序列A[mid+1 : end] sorted
    A[mid] < target <= A[end], 右半序列,否则为左半序列。

    当A[mid] > A[start] > A[end]:情况2,左半序列A[start : mid-1] sorted
    A[start] <= target < A[mid], 左半序列,否则为右半序列

    Base case:当start + 1 = end时
    假设 2 4:
    A[mid] = A[start] = 2 < A[end],A[mid] < target <= A[end] 右半序列,否则左半序列

    假设 4 2:
    A[mid] = A[start ] = 4 > A[end],  A[start] <= target < A[mid] 左半序列,否则右半序列

    加入base case的情况,最终总结的规律是:

    A[mid] =  target, 返回mid,否则
    (1) A[mid] < A[end]: A[mid+1 : end] sorted

    A[mid] < target <= A[end]  右半,否则左半。
    (2) A[mid] > A[end] : A[start : mid-1] sorted

    A[start] <= target < A[mid] 左半,否则右半。

    方法一: recursive, 方法二: iterative, 对recursive 的简单改写。


    Java code :
    1. recursive

    public class Solution {
        public int search(int[] nums, int target) {
            return binarySearch(nums, 0, nums.length-1, target);
        }
        
        public int binarySearch(int[] nums, int left, int right, int target){
            if(left > right) {
                return -1;
            }
            int mid = left + (right - left)/2;
            if(target == nums[mid]){
                return mid;
            }
            if(nums[mid] < nums[right]) { //right half sorted
                if(nums[mid] < target && target <= nums[right]){
                    return binarySearch(nums, mid+1, right, target); 
                }else {
                    return binarySearch(nums, left, mid-1, target); 
                }
            }else { //left half sorted
                if(nums[left] <= target && target < nums[mid]){
                    return binarySearch(nums, left, mid-1, target); 
                }else{
                    return binarySearch(nums, mid+1, right, target); 
                }
            }
        }    
    }

    2. iterative

    public class Solution {
        public int search(int[] nums, int target) {
            int left = 0, right = nums.length-1;
            while(left <= right){
                int mid = left + (right - left)/2;
                if(nums[mid] == target) {
                    return mid;
                }
                if(nums[mid] < nums[right]) { //right half sorted
                    if(target > nums[mid] && target <= nums[right]){
                        left = mid+1;
                    }else{
                        right = mid-1;
                    }
                }else { //left half sorted
                    if(target >= nums[left] && target < nums[mid]){
                        right = mid-1;
                    }else {
                        left = mid+1;
                    }
                }
            }
            return -1;
        }
    }

    3. 九章算法答案,画图解决,理解binary search 的本质,就是每次扔掉一部分。2016.01.15

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

    Reference:

    1. http://bangbingsyb.blogspot.com/2014/11/leetcode-search-in-rotated-sorted-array.html

    2. http://www.programcreek.com/2014/06/leetcode-search-in-rotated-sorted-array-java/

  • 相关阅读:
    setsid
    dup
    信号量
    linux标准输入输出
    linux守护进程范例
    c++字符串操作
    浏览器缓存
    bfc
    苹果手机自制铃声
    vue-cli 源码解读
  • 原文地址:https://www.cnblogs.com/anne-vista/p/4899752.html
Copyright © 2011-2022 走看看