要注意边界!细节是魔鬼!
class Solution {
public int[] searchRange(int[] nums, int target) {
int[] res = new int[]{-1, -1};
res[0] = findLeftBound(nums, target);
res[1] = findRightBound(nums, target);
return res;
}
public int findLeftBound(int[] nums, int target) {
if (nums.length == 0) return -1;
int left = 0;
int right = nums.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
right = mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
if (left < nums.length && nums[left] == target) {
return left;
}
return -1;
}
public int findRightBound(int[] nums, int target) {
if (nums.length == 0) return -1;
int left = 0;
int right = nums.length;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
left = mid + 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid;
}
}
if (left > 0 && nums[left - 1] == target) {
return left - 1;
}
return -1;
}
}
思路:如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的,我们只要在有序的半段里用首尾两个数组来判断目标值是否在这一区域内,这样就可以确定保留哪半边了
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
}
else if (nums[mid] < nums[right]) {
if (nums[mid] < target && nums[right] >= target) {
left = mid + 1;
} else {
right = mid - 1;
}
} else {
if (nums[mid] > target && nums[left] <= target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
}
return -1;
}
}