首页 > 学院 > 开发设计 > 正文

Searchforarange寻找上下界-Leetcode

2019-11-14 15:36:52
字体:
来源:转载
供稿:网友

原题如下:

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].


思路如下:

很明显这是一道考察二分法的题目。我一开始的思路是利用二分找到该目标元素,然后向左右两侧递增和递减。但是这样它就不是O(log n)的复杂度了。

后来在别人的答案里看到一个非常巧妙的实现,利用了二分法的一点变化。传统的二分法采用如下结构:

 1     int left=0; 2     int right=length-1; 3     int middle=(left+right)/2; 4     while(left<right){ 5         if(middle>target){ 6             right=middle-1; 7         } 8         else if(middle>target){ 9             left=middle+1;10         }11         else{12         return middle;13         }14     }15     return left;

在这个题目中,我们不是要找到一个特定的元素,而是要找到这样一组元素的上下界。那就要对二分法进行修改。

不再是找到相等元素就跳出循环,而是找到相等元素就继续把边界向另一端推进,直到推进到相等元素的最后一个为止。

这样一来,我们只需运行两次方向不同的二分就可以找到上下界了。

代码如下:

 1 public class Solution { 2     public int[] searchRange(int[] nums, int target) { 3         int left=0,right=nums.length;//注意 右边界不是取的nums.length-1。这是为了方便做第29行的判断. 4         int mid=(left+right)/2; 5         while(left<right){ 6             if(nums[mid]>=target){ 7                 right=mid; 8             } 9             else{10                 left=mid+1;11             }12             mid=(left+right)/2;13         }14         int start=left;15         left=start;16         right=nums.length;17         mid=(left+right)/2;18         while(left<right){19             if(nums[mid]>target){20                 right=mid;21             }22             else{23                 left=mid+1;24             }25             mid=(left+right)/2;26         }27         int end=right;28         return (start==end)?new int[]{-1,-1}:new int[]{start,end-1};29     }30 }

 关于二分法,还有重要的一个陷阱:

left+right是有可能超出int上下界的!后果话美不看!


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表