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.
------------------------------------------------------------
reference with excellent explanation
array is half sorted and the half rotated. Always start with the sorted half then determine which half that our target resides in
class Solution {
public:
int search(int A[], int n, int target) {
int start = 0, end = n - 1;
while (start <= end) {
int mid = start + (end - start) / 2;
if (A[mid] == target) {
return mid;
}
// first half is sorted
if (A[start] <= A[mid]) {
if (A[start] <= target && target <= A[mid]) {
end = mid - 1;
}else {
start = mid + 1;
}
}else { // second half is sorted
if (A[mid] <= target && target <= A[end]) {
start = mid + 1;
}else {
end = mid - 1;
}
}
}
return -1;
}
};
Update on Dec-15-2014 A[end] would never have a chance to be equal to A[mid]. However, A[start] would in the cases that only contain two elements
that's why A[start] <= A[mid]
Search for a Range
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].
-----------------------------------------------------------------
注意掌握以下第一种方法
binary search
if hit target, continue searching to expand the range
class Solution {
public:
void bin (int A[], int start, int end, int target, vector<int> &ret) {
if (start > end) return;
int mid = start + (end - start) / 2;
if (A[mid] == target) {
if (mid < ret[0] || ret[0] == -1) {
ret[0] = mid;
bin(A,start,mid - 1, target, ret);
}
if (mid > ret[1]) {
ret[1] = mid;
bin(A,mid + 1,end, target, ret);
}
}else if (A[mid] < target) {
bin(A,mid + 1,end, target, ret);
}else {
bin(A,start,mid - 1, target, ret);
}
}
vector<int> searchRange(int A[], int n, int target) {
vector<int> ret(2,-1);
bin(A,0,n-1,target,ret);
return ret;
}
};
class Solution {
public:
void leftSearch(int A[], int left, int right, int target, vector<int> &range) {
if (left > right) {
return;
}
int mid = left + (right - left) / 2;
if (A[mid] == target) {
range[0] = mid;
leftSearch(A,left,mid - 1,target,range);
}else if (A[mid] < target) {
leftSearch(A,mid + 1,right,target,range);
}
}
void rightSearch(int A[], int left, int right, int target, vector<int> &range) {
if (left > right) {
return;
}
int mid = left + (right - left) / 2;
if (A[mid] == target) {
range[1] = mid;
rightSearch(A,mid + 1,right,target,range);
}else if (A[mid] > target) {
rightSearch(A,left,mid - 1,target,range);
}
}
vector<int> searchRange(int A[], int n, int target) {
int left = 0;
int right = n - 1;
vector<int> range(2,-1);
while (left <= right) {
int mid = left + (right - left) / 2;
if (A[mid] == target) {
range[0] = mid;
range[1] = mid;
leftSearch(A,left,mid - 1,target,range);
rightSearch(A,mid + 1,right,target,range);
break;
}else if (A[mid] < target) {
left = mid + 1;
}else {
right = mid - 1;
}
}
return range;
}
};
iterative,用2个额外二分法函数,一个是找连续target的起始点,一个是找连续target的终止点设置好循环的终止条件就行
No comments:
Post a Comment