• 33. Search in Rotated Sorted Array(二分查找)


    Suppose an array sorted in ascending order 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.

    Your algorithm's runtime complexity must be in the order of O(log n).

    Example 1:

    Input: nums = [4,5,6,7,0,1,2], target = 0
    Output: 4
    

    Example 2:

    Input: nums = [4,5,6,7,0,1,2], target = 3
    Output: -1


    法1:将数组一分为二,其中一定有一个是有序的,另一个可能是有序,也能是部分有序。此时有序部分用二分法查找。无序部分再一分为二,其中一个一定有序,另一个可能有序,可能无序。就这样循环.

    class Solution {
    public:
        int search(vector<int>& nums, int target) {
            if(nums.size()==0) return -1;
            return bt_search(nums, 0,nums.size()-1,target);
        }
       
        int bt_search(vector<int>& a, int low, int high, int target) {
            int mid = low + (high - low) / 2;
            if(a[low]==target) return low;
            if(a[high]==target) return high;
            if(low>=high) return -1;
    
    
    
            if (a[low] < a[mid]) {
                if (a[low]  <target && target<  a[mid]) {    
                    return bt_search(a, low+1, mid-1, target);
                }
                else {
                    return bt_search(a,mid, high, target);
                }
            } else {
                if (a[mid] <target && target <a[high]) {    
                    return bt_search(a, mid+1, high-1, target);
                }
                else {
                    return bt_search(a,low, mid, target);
                }
            }
            return -1;
        }
    };
    

      

      


    从左向右,如果左边的点比右边的点小,说明这两个点之间是有序的。
         如果左边的点比右边的点大,说明中间有个旋转点,所以一分为二后,肯定有一半是有序的。所以还可以用二分法。
            不过先要判断左边有序还是右边有序,如果左边有序,则直接将目标与左边的边界比较,就知道目标在不在左边,
            如果不在左边肯定在右边。


     1 class Solution {
     2     public int search(int[] a, int target) {
     3         int n = a.length;
     4         int lo = 0;
     5         int hi = n - 1;
     6         while(lo<=hi){
     7             int mid = lo+(hi-lo)/2;
     8             if(a[mid]== target)
     9                 return mid;
    10             
    11             if(a[lo]<=a[mid]){//左半边有序
    12                 if(a[lo]<=target && target<=a[mid])//目标值在左半边
    13                     hi = mid - 1;
    14                 else
    15                     lo = mid + 1; 
    16             }
    17             else{//右半边有序
    18                 if(a[mid]<=target && target<=a[hi])
    19                     lo = mid + 1;
    20                 else
    21                     hi = mid - 1;
    22             }
    23         }
    24         return -1;  
    25         
    26     }
    27 }
  • 相关阅读:
    kill process
    USB development guide
    MMC device
    memtester
    printf()格式化输出详解
    C语言动态内存分配
    归并排序C语言
    c 文件操作
    数据包分析
    C语言文件操作函数大全
  • 原文地址:https://www.cnblogs.com/zle1992/p/8996225.html
Copyright © 2020-2023  润新知