码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode 1-search

时间:2014-11-18 23:27:24      阅读:578      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   sp   for   

1. Search Insert Position

 1 class Solution {
 2 public:
 3     int searchInsert(int A[], int n, int target) {
 4         int left=0,right=n-1;
 5         while(left<=right)
 6         {
 7             int mid=left+(right-left)/2;
 8             if(A[mid]==target) return mid;
 9             if(A[mid]<target)
10                 left=mid+1;
11             else right=mid-1;
12         }
13         return left;
14     }
15 };

当循环结束时,如果没有找到目标元素,那么left一定停在恰好比目标大的index上,right一定停在恰好比目标小的index上.

特殊点的例子:当在{1,2,3,4,5}里执行二分查找找0时,此时的left=0, right=-1.(left和right也是挺拼的,为了比target大/小,不惜越界。)

这个规律非常有用,合理利用left和right在未找到target的情况下退出while循环时的特性,能解决很多问题,尤其体现在实现upperBound和lowerBound函数时。如果要利用left或right,需要保证target不在当前区间内,这样才能让while循环以未找到target的状态退出。为了实现这一点,我们需要在即使发现target==A[mid]的情况下仍然假装没看见,继续缩小搜索范围。

因此如果要在二分搜索的基础上计算bound的话,其实就是怎么处理那几个值为target的元素的问题。也就是是否把这部分值恰好为target的元素纳入下一轮搜索范围。(二分搜索本质上就是不断缩小搜索范围)。

以upperBound为例。upperBound函数是找[left,right]内第一个大于target的元素下标------所以值为target的元素肯定要排除在搜索范围之外。这样当A[mid]==target时我们仍将其排除在搜索范围外,即让low=mid+1。一直到搜索范围里已经没有值为target的元素了,此时根据二分查找的性质,当区间里没有找到target时,while循环退出后low指向刚好大于target的位置,high指向刚好小于target的位置。所以此时我们返回low即为刚好大于target的位置,即——第一个大于target的位置。

lowerBound同理。lowerBound是寻找[left,right]内第一个值不小于target的元素下标。“不小于”target的不好求,但刚好小于target的那个元素位置比较好求,因为这就是right的返回值。所以我们按照上述思路,在遇到A[mid]==target的情况下仍假装看不见,继续缩小搜索范围,直到当前范围里没有了target,最终循环退出时right就指向值刚好小于target的元素位置。而(right+1)即为不小于target的元素下标。

 lowerBound和upperBound的实现代码在下一题代码中。

What if there are duplicates?

 

2. Search for a Range

 

 1 class Solution {
 2 public:
 3     vector<int> searchRange(int A[], int n, int target) {
 4         int left=0,right=n-1;
 5         vector<int> res(2,-1);//[-1,-1]是默认值
 6         while(left<=right)
 7         {
 8             int mid=left+(right-left)/2;
 9             if(A[mid]<target) 
10                 left=mid+1;
11             else if(A[mid]>target)
12                 right=mid-1;
13             else
14             {
15                 res[0]=lowerBound(A,left,mid,target);
16                 res[1]=upperBound(A,mid,right,target)-1;//别忘了减1                                
17                 return res;
18             }
19         }
20         return res;//这一句别忘了。当查找失败时返回[-1,-1].
21     }
22 private:
23     int upperBound(int A[], int left, int right, int target)
24     {
25         int low = left, high = right;
26         while (low <= high)
27         {
28             int mid = low + (high - low) / 2;
29             if (A[mid] <= target)
30                 low = mid + 1;
31             else
32                 high = mid - 1;
33         }
34         return low;
35     }
36     int lowerBound(int A[], int left, int right, int target)
37     {
38         int low = left, high = right;
39         while (low <= high)
40         {
41             int mid = low + (high - low) / 2;
42             if (A[mid] >= target)
43                 high = mid - 1;
44             else
45                 low = mid + 1;
46         }
47         return high + 1;
48     }
49 };

lowerBound和upperBound与binarySearch之间的关系上一题里已经分析过了。

注意几个小细节,已在注释中标明。细节决定成败,bug-free需要谨小慎微。

 

3. Search in Rotated Sorted Array

 

 1 class Solution {
 2 public:
 3     int search(int A[], int n, int target) {
 4         int left=0,right=n-1;
 5         while(left<=right)
 6         {
 7             int mid=left+(right-left)/2;
 8             if(A[mid]==target) return mid;
 9             if(A[mid]<A[right])//说明右半段是有序的
10             {
11                 if(target>A[mid]&&target<=A[right])
12                     left=mid+1;
13                 else
14                     right=mid-1;                    
15             }
16             else
17             {
18                 if(target>=A[left]&&target<A[mid])
19                     right=mid-1;
20                 else
21                     left=mid+1;
22             }
23         }
24         return -1;
25     }
26 };

最关键的把握这个规律:"总有一半是有序的,而且和另一半无区间重叠"。code ganker的总结很好。

 

leetcode 1-search

标签:style   blog   http   io   ar   color   os   sp   for   

原文地址:http://www.cnblogs.com/forcheryl/p/4106547.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!