zoukankan      html  css  js  c++  java
  • LeetCode第[34]题(Java):Search for a Range

    题目:搜索目标范围

    难度:Medium

    题目内容

    Given an array of integers nums sorted in ascending order, 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].

    翻译

    给定一个按升序排序的整数,找到给定目标值的起始和结束位置。

    您的算法的运行时复杂性必须按照O(log n)的顺序。

    如果在数组中找不到目标,返回[-1,-1]。

    我的思路:数组、有序、查找、lgn————》二分法

        找到后用两个指针向两边移动,直到不等于,就是他的范围。

    MyCode

     1     public int[] searchRange(int[] nums, int target) {
     2         if (nums.length == 0) {
     3             return new int[]{-1,-1};
     4         }
     5         int loc = binaryFind(nums, target);
     6         if (loc == -1) {
     7             return new int[]{-1,-1};
     8         }
     9         int start = loc;
    10         int end = loc;
    11         while (start-1 > -1 && nums[start-1] == nums[loc])
    12             start--;
    13         while (end+1 < nums.length && nums[end+1] == nums[loc])
    14             end++;
    15         return new int[]{start, end};
    16     }
    17     
    18     static int binaryFind(int[] nums, int target) {
    19         int low = 0;
    20         int high = nums.length - 1;
    21         while (low <= high) {
    22             int mid = low + (high - low)/2;
    23             if (nums[mid] == target) {
    24                 return mid;
    25             } else if (nums[mid] > target) {
    26                 high = mid - 1;
    27             } else {
    28                 low = mid + 1;
    29             }
    30         }
    31         return -1;
    32     }

    我的复杂度:O(logN)+ O(N) = O(N)

    因为后面的双向移动确实有可能将所有元素进行一次遍历,所以达不到O(logN)级别

    编码过程中出现问题

    1、length 写成了 lengh;

    2、high的初始值设置成了length,应该为length-1;

    3、 while(start-1 > -1 && nums[start-1] == nums[loc])  注意这个写法,如果将start--放入此处判断,那么最后的值就多减了1;

    4、没找到的时候别忘了return [-1,-1]。

    答案代码

     1     public int[] searchRange(int[] A, int target) {
     2         int start = Solution.firstGreaterEqual(A, target);
     3         if (start == A.length || A[start] != target) {
     4             return new int[]{-1, -1};
     5         }
     6         return new int[]{start, Solution.firstGreaterEqual(A, target + 1) - 1};
     7     }
     8 
     9     private static int firstGreaterEqual(int[] A, int target) {
    10         int low = 0, high = A.length;
    11         while (low < high) {
    12             int mid = low + ((high - low) >> 1);
    13             //A[low] <= target < A[high]
    14             if (A[mid] < target) {
    15                 low = mid + 1;
    16             } else {
    17                 high = mid;
    18             }
    19         }
    20         return low;
    21     }

    答案复杂度:O(logN)

    答案思路:在二分法的基础上做出了改进,即最后返回大于等于target的第一个数(所有target里最左边的那一个)

    所以不仅当target>A[mid],并且target==A[mid]的时候,此时都应该向左边继续搜寻

    但是此时是令high = mid,而不是mid-1,是因为A[mid]<=target的时候,包括了A[mid]==target,此时如果取high = mid-1,则有可能将唯一的一个target给弄到右边去

    最后得到start,然后再将方法的target给+1再传入此方法,那么就能找到target右边的那一个数字的下标。

    举个例子:

    [1,2,3,5,5,9],target=5

    首先定位到下标2——3,因为3<target,要找的点必定在右边:lo=mid+1

    再定位下标4——5,因为5>=target,所以也要向左寻找:high=mid

    。。。

    扩展:我们也可以求的小于等于target的第一个数,即所有target最右边的那个数,那么当target>=A[mid]的时候,此时继续向右边搜索。。。

  • 相关阅读:
    15个新鲜出炉的 Photoshop 文本效果教程
    10个美丽的例子,插图在网页设计中的应用
    分享8个非常时髦的翻页特效(附代码片段)
    【Vue课堂】Vue.js 父子组件之间通信的十种方式
    Tippy.js – 轻量的 Javascript Tooltip 工具库
    12个美丽的网站与受到日出启发的配色方案
    精选:3个可以下载免费的高质量照片的网站
    nativefier
    Mark Text
    Puppeteer
  • 原文地址:https://www.cnblogs.com/Xieyang-blog/p/8999367.html
Copyright © 2011-2022 走看看