zoukankan      html  css  js  c++  java
  • [LeetCode] 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].

    二分查找很简单,可是二分查找真的很简单吗?考虑下面几个问题:

    1. 二分查找target,返回任意找到的下标,没找到返回-1;

    2.二分查找第一次出现target的下标,没找到返回-1;

    3.二分查找最后一次出现target的下标,没找到返回-1;

    4.二分查找数组中比target小的最大的数,不存在返回-1;

    5.二分查找数组中比target大的最小的数,不存在返回-1.

    如果能快速写出上面5个问题的代码,那么你已经基本掌握二分查找了。那么再来看这道题,对应的就是上面的问题2和问题3了。怎么处理这种问题呢?其实只要把复杂的问题简单化,我们就能很快找到其中的奥秘。那么不妨我们就考虑只有两个元素的情况,一般来说,我习惯让R = n - 1,这样M一定是两个元素中的第一个元素:

    如果我们要找最左边的位置,那么当A[M]==target时,就应该固定L,改变R,也就是:

    if(A[M] >= target) R = M - 1;

    最后的L就是我们要找的;

    反之,如果要找最右边的位置,那么就固定R,改变L,也就是:

    if(A[M] <= target) L = M + 1;

    最后的R就是我们要找的。

    这样是不是就很清楚了呢?而对于4,5问,也是同样的道理,只对2,3问我们想到的分别是L,R,而4,5问我们要的是R,L,或者说是L-1,R+1。

     1 class Solution {
     2 public:
     3     int searchLeft(int A[], int n, int target) {
     4         int L = 0, R = n - 1, M;
     5         while (L <= R) {
     6             M = L + ((R - L) >> 1);
     7             if (A[M] >= target) R = M - 1;
     8             else L = M + 1;
     9         }
    10         return (A[L] != target) ? -1 : L;
    11     }
    12     
    13     int searchRight(int A[], int n, int target) {
    14         int L = 0, R = n - 1, M;
    15         while (L <= R) {
    16             M = L + ((R - L ) >> 1);
    17             if (A[M] <= target) L = M + 1;
    18             else R = M - 1;
    19         }
    20         return (A[R] != target) ? -1 : R;
    21     }
    22     
    23     vector<int> searchRange(int A[], int n, int target) {
    24         vector<int> res(2);
    25         res[0] = searchLeft(A, n, target);
    26         res[1] = searchRight(A, n, target);
    27         return res;
    28     }
    29 };

    这里有个小问题,如果数组里没有target,且target比最小数还小或者比最大数还大,可能会出现下标访问越界,所以访问前要先判断一下返回的下标是不是在0~n-1之间。

  • 相关阅读:
    git查看工作状态和历史提交
    PowerDesigner工具栏palette的方法
    WCF证书制作
    ASP.NET.4 高级程序第4版 第3章Web窗体
    tbar居右显示的两种方法
    测试
    转载extj grid
    正值
    网站HTML,XHTML,XML,WML,CSS等测试验证工具介绍[转]
    SQL Server 启用“IP+端口”连接
  • 原文地址:https://www.cnblogs.com/easonliu/p/4371591.html
Copyright © 2011-2022 走看看