专题总结—二分查找与旋转排序数组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了专题总结—二分查找与旋转排序数组相关的知识,希望对你有一定的参考价值。

  1、二分搜索的模板。

     算法面试中,如果需要优化O(n)的时间复杂度,那么只能是O(logn)的二分法。

     注意二分法大多数情况都是适用于排序数组。

http://www.lintcode.com/zh-cn/problem/first-position-of-target/

class Solution {
public:
    /**
     * @param nums: The integer array.
     * @param target: Target number to find.
     * @return: The first position of target. Position starts from 0. 
     */
    int binarySearch(vector<int> &array, int target) {
        // write your code here
        if(array.size()==0){
            return -1;
        }
        int start = 0,end = array.size() - 1;    
        while( start + 1 < end ){
            int mid = start + ( end - start ) / 2;
            if(array[mid]==target){
                end=mid;//找某个元素,直接return mid;找第一个元素end=mid;找last元素start=mid;
            }
            else if(array[mid]<target){
                start=mid;
            }
            else{
                end=mid;
            }
        }
        if(array[start]==target){
            return start;
        }
        else if(array[end]==target){
            return end;
        }
         return -1;
    }
};

模板有四点注意:

1)start+1<end;(最后会得到start,end两项)

2)mid=start+(end-start)/2;//为了防止start+end超出计算机表示范围

3)A[mid]==,<,>;

4)A[start]A[end]?target。(找第一个元素就是把A[start]放在前面,否则end放在if前面)

2、使用二分搜索解决问题以及变种问题

找第一个位置&&找最后一个位置。

2.1搜索区间

http://www.lintcode.com/zh-cn/problem/search-for-a-range/

思路:使用二分搜索分别找到第一个等于target的元素和最后一个等于target的元素。(使用if判断一定要有对应的else,逻辑才会正确,不然会出错)

技术分享
class Solution {
    /** 
     *@param A : an integer sorted array
     *@param target :  an integer to be inserted
     *return : a list of length 2, [index1, index2]
     */
public:
    vector<int> searchRange(vector<int> &A, int target) {
        // write your code here
        //find first target‘s position
        vector<int> result;
        if(A.size()==0)
            return {-1,-1};
        int start=0,end=A.size()-1;
        while(start+1<end){
            int mid=start+(end-start)/2;
            if(A[mid]==target){
                end=mid;
            }
            else if(A[mid]<target){
                start=mid;
            }
            else{
                end=mid;
            }                    
        }
        if(A[start]==target){
            result.push_back(start);
        }
        else if(A[end]==target){
            result.push_back(end);
        }
        else{
            result.push_back(-1);
        }
        
        //find last target‘s position        
        start=0;
        end=A.size()-1;
        while(start+1<end){
            int mid=start+(end-start)/2;
            if(A[mid]==target){
                start=mid;
            }
           else if(A[mid]<target){
                start=mid;
            }
            else{
                end=mid;
            }                    
        }
        if(A[end]==target){
            result.push_back(end);
        }
        else if(A[start]==target){
            result.push_back(start);
        }
        else{
            result.push_back(-1);
        }
        
    return result;    
    }
};
View Code

 

以上是关于专题总结—二分查找与旋转排序数组的主要内容,如果未能解决你的问题,请参考以下文章

leetcode-81. 搜索旋转排序数组 II(二分查找返回true/false)

leetcode-81. 搜索旋转排序数组 II(二分查找返回true/false)

leetcode-81. 搜索旋转排序数组 II(二分查找返回true/false)

二分查找专题总结 - 基础篇

二分查找4寻找旋转排序数组中的最小值 II(hard)

二分查找4寻找旋转排序数组中的最小值 II(hard)