zoukankan      html  css  js  c++  java
  • LeetCode:Search Insert Position,Search for a Range (二分查找,lower_bound,upper_bound)

    Search Insert Position

    Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

    You may assume no duplicates in the array.

    Here are few examples.
    [1,3,5,6], 5 → 2
    [1,3,5,6], 2 → 1
    [1,3,5,6], 7 → 4
    [1,3,5,6], 0 → 0

    这就是普通的二分查找,需要注意的地方代码注释中都有。其中特别注意的是:middle=(low+high)/ 2 ,可能会溢出,可以替换为middle = low + ((high - low)>>2);

    class Solution {
    public:
        int searchInsert(int A[], int n, int target) {
            //二分查找
            int low = 0, high = n-1;//注意这里high是初始化为n-1
            while(low <= high)//注意这里是<=号
            {
                //int middle = (low + high) / 2;
                int middle = low + ((high - low)>>2); //可以防止low + high 溢出
                if(A[middle] < target)
                    low = middle + 1;
                else if(A[middle] > target)
                    high = middle - 1;
                else return middle;
            }
            return low;//注意返回值是low
        }
    };

    根据程序员编程艺术第二十五章:Jon Bentley:90%无法正确实现二分查找, 如果high初始化为n, 那么while判断语句就应该是low<high, 下面的A[middle] > target分支中,就应该是high = middle


    Search for a Range

    Given a sorted array of integers, find the starting and ending position of a given target value.

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

    If the target is not found in the array, return [-1, -1].

    For example,
    Given [5, 7, 7, 8, 8, 10] and target value 8,
    return [3, 4].

    看到这个有没有想到STL中的equal_range函数,这个函数是调用lower_boundupper_bound, 下面我们仿照STL的实现。相比上一题的二分查找,lower_bound当A[middle] == target时,继续向左半部分查找,它返回的是第一个不小于目标数的元素位置;upper_bound当A[middle] == target时,继续向右半部分查找,它返回的是第一个大于目标数的元素位置。    本文地址

    class Solution {
    public:
        vector<int> searchRange(int A[], int n, int target) {
            vector<int> res(2, -1);
            int low = 0, high = n-1;
            while(low <= high)
            {
                int middle = low + ((high - low)>>2);
                if(A[middle] < target)
                    low = middle + 1;
                else if(A[middle] > target)
                    high = middle - 1;
                else
                {
                    res[0] = lowerBound(A, low, middle - 1, target);
                    res[1] = upperBound(A, middle + 1, high, target) - 1;
                    return res;
                }
            }
            return res;
        }
        
        //找到范围内[left,right]内第一个不小于target的元素
        int lowerBound(int A[], int left, int right, int target)
        {
            int low = left, high = right;
            while(low <= high)
            {
                int middle = low + ((high - low)>>2);
                if(A[middle] < target)
                    low = middle + 1;
                else high = middle - 1;
            }
            return high + 1;//注意这里返回值不是low
        }
        //找到范围[left,right]内第一个大于target的元素
        int upperBound(int A[], int left, int right, int target)
        {
            int low = left, high = right;
            while(low <= high)
            {
                int middle = low + ((high - low)>>2);
                if(A[middle] <= target)
                    low = middle + 1;
                else high = middle - 1;
            }
            return low;
        }
    };

    【版权声明】转载请注明出处http://www.cnblogs.com/TenosDoIt/p/3681677.html

  • 相关阅读:
    php Thinkphp 经纬度查位置(误差200米左右)
    php redis 基础操作 Thinkphp 直接套用
    超实用的华为云服务器选购技巧经验!
    连续四年第一!华为云FusionAccess夺桌面云市场桂冠
    华为云服务器、云数据库、云安全免费送!
    Linux_CentOS_6.5安装Nginx
    PHP破解wifi密码(wifi万能钥匙的接口)
    PHP+json开发API接口实例
    52首歌,一个你
    js 获取前天、昨天、今天、明天、后天的时间
  • 原文地址:https://www.cnblogs.com/TenosDoIt/p/3681677.html
Copyright © 2011-2022 走看看