【leetCode】 - 在排序数组中查找元素的第一个和最后一个位置

149 阅读2分钟

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

题目

链接:leetcode-cn.com/problems/fi…

解析

PS:其实我觉得这个题目应该属于【easy】级别的。。。

顺序

如果是按照顺序进行查找,实际上是很简单的,声明了一个left和一个right指针之后,我们只需要:

  • 找到数字出现的第一个位置,让left和right都指向这个位置
  • 然后在数组中接着往下查找,每获取一次和数字相同的值,就让right指向这个位置
  • 直到找到了第一个不等于数字的值

此时我们将left,right返回,目的就达到了。

代码

 public static int[] searchRange(int[] nums, int target) {
     int left = -1,right = -1;
     for (int i = 0; i < nums.length; i++) {
         if(nums[i] > target) break;
         if(nums[i] == target){
             if(left == -1){
                 left = i;
                 right = i;
             }else{
                 right++;
             }
         }
     }
     return new int[]{left,right};
 }

二分

如果是按照题目中暗示的:

  • 在o(logn)时间复杂度中解决这个问题

那么问题就比较复杂了,没办法直观地决定如何取得左右区间的值。

既然我们选定了使用二分法来进行左右区间的获取,不妨回顾一下二分法最简单的应用二分查找:

  • 在排序好的数组中,我们取中点值进行判断
  • 如果比值大,那么我们往左;如果比值小,我们往右。
  • 循环这个过程,直到最后无值可取了。

除了最终的结果稍微不同,我们的目的和已知条件都是一样的,那么我们依然可以使用这个思路,只是:

  • 我们要查找的值,在数组中有多个。

那么仿照上面二分查找的思路,我们试着来解释我们如何解决这个问题的:

  • 在排序好的数组中,我们取中点值进行判断

  • 如果比值大,那么我们往左;如果比值小,我们往右。

  • 如果比值小:(这个就是我们比最简单的二分查找,多出来的地方)

    • 我们查找左边界到(中点-1)位置上的索引,并使用它的左边界作为最终结果
    • 我们查找(中点+1)到右边界位置上的索引,并使用它的右边界作为最终结果
  • 循环这个过程,直到最后左右边界相等或不符合逻辑。

代码

 //binarySearch
 public static int[] searchRange2(int[] nums, int target) {
     return searchRangeR(nums,target,0,nums.length-1);
 }
 ​
 public static int[] searchRangeR(int[] nums, int target,int start,int end){
     if(start == end){
         if(nums[start] == target) return new int[]{start,start};
         return new int[]{-1,-1};
     }
     if(start>end) return new int[]{-1,-1};
     int mid = (start+end)/2;
     int[] res = new int[2];
     if(nums[mid]<target){
         res = searchRangeR(nums, target, mid+1, end);
     }else if(nums[mid] >target){
         res = searchRangeR(nums, target, start, mid-1);
     }else{//equals
         res[0] = searchRangeR(nums, target,start,mid-1)[0];
         if(res[0] == -1) res[0] = mid;
         res[1] = searchRangeR(nums,target,mid+1,end)[1];
         if(res[1]==-1) res[1] = mid;
     }
     return res;
 }

\