leetcode上关于二分查找的题目汇总
题目描述:
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]
.
class Solution {
public:
vector<int> searchRange(int A[], int n, int target) {
int i = 0,j=n-1;
while(i<=j){ //二分查找找左边界
int mid= (i+j)/2;
if(target>A[mid])
i = mid+1;
else j = mid-1;
}
int st = i;
j = n-1;
while(i<=j){ //二分查找找右边界
int mid = (i+j)/2;
if(target>=A[mid])
i = mid+1;
else j = mid-1;
}
int end = j;
vector<int> ans;
if(st>=n){ //无解
ans.push_back(-1);
ans.push_back(-1);
return ans;
}
ans.push_back(st);
ans.push_back(end);
return ans;
}
};
这个题就是考了二分找lower_bound和upper_bound的方法,具体在我前面
面试总结之-查找算法分析讲到了。
Search in Rotated Sorted Array:
题目描述:
Suppose a sorted array is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
这个题只有在输入是没有重复的时候才能使用二分查找,所以注意了,要是面试问到了,记得跟面试官沟通清楚,数组有没有重复元素。
code:
class Solution {
public:
int search(int A[], int n, int target) {
for(int i=0, j=n-1;i<=j;)
{
int mid = i+(j-i)/2;
if(A[mid] == target) return mid;
if((A[mid]>=A[i]&&(target>A[mid]||target<A[i]))||(target<=A[j]&&target>A[mid]))
i = mid + 1;
else j = mid - 1;
}
return -1;
}
};
上面有一串相当复杂的判断条件,其实就是根据mid的位置(在左半还是右半)来判断现在应该搜索左边还是右边。跟一般的二分比较一下,差别完全就在于中间那个相当长的if语句了。另外,在leetcode还有一个加强版,把上面题目中“不存在重复元素”这个条件去掉了,名字叫做:Search in Rotated Sorted Array II。我觉得这个题应该是没有一个在最坏情况优于O(n)的算法的。要是有这个解请务必告诉我~
题目描述:
Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You may assume no duplicates in the array.
Here are few examples.
[1,3,5,6]
, 5 → 2
[1,3,5,6]
, 2 → 1
[1,3,5,6]
, 7 → 4
[1,3,5,6]
, 0 → 0
二分查找,妥妥的,不解释。
class Solution {
public:
int searchInsert(int A[], int n, int target) {
int i = 0, j = n-1;
while(i<=j)
{
int mid = (i+j)/2;
if(target>A[mid])
i = mid+1;
else j = mid-1;
}
return i;
}
};
Sqrt(x):
题目描述:
Implement int sqrt(int x)
.
Compute and return the square root of x.
实际上这个题还可以用牛顿迭代法做,复杂度上比二分要更好(貌似是loglogn),不过这个复杂度证明不好证,还是主流一点,二分吧。
class Solution {
public:
int BS(int s,int e,int tar)
{
while(s<=e)
{
double mid = (s+e)/2;
if(mid*mid>tar)
e = mid-1;
else
s = mid + 1;
}
return e;
}
int sqrt(int x) {
if(x<0) return -1;
return BS(0,x,x);
}
};
中间用了个double,为什么,你懂的。
===========================以后补充的分界线===================以后补充的分界线===================以后补充的分界线================