给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
【解答】:二分法
class Solution {
public int[] searchRange(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return new int[]{-1,-1};
}
if (nums.length == 1 && nums[0] == target) {
return new int[]{0,0};
}
int[] result = {nums.length,-1};
findIndex(nums, result, target, 0, nums.length-1);
if (result[0] == nums.length) {
result[0] = -1;
}
return result;
}
public void findIndex(int[] arr, int[] indexArr, int target, int left, int right) {
if (left > right || left < 0 || right > arr.length-1) {
return;
}
if (left == right && arr[left] == target) {
if (left > indexArr[1]) {
indexArr[1] = left;
}
if (left < indexArr[0]) {
indexArr[0] = left;
}
return;
}
int mid = (left+right)/2;
if (arr[mid] > target) {
findIndex(arr, indexArr, target, left, mid-1);
} else if (arr[mid] < target) {
findIndex(arr, indexArr, target, mid+1, right);
} else {
if (mid > indexArr[1]) {
indexArr[1] = mid;
}
if (mid < indexArr[0]) {
indexArr[0] = mid;
}
findIndex(arr, indexArr, target, left, mid);
findIndex(arr, indexArr, target, mid+1, right);
}
}
}
【解答】:先用二分法找左边,右边也是二分,注意边界判断
class Solution {
public int[] searchRange(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return new int[]{-1,-1};
}
if (target < nums[0] || nums[nums.length-1] < target) {
return new int[]{-1,-1};
}
int[] result = new int[]{findLeftIndex(nums, 0, nums.length-1, target), findRightIndex(nums, 0, nums.length-1, target)};
return result;
}
public int findLeftIndex(int[] nums, int left, int right, int target) {
if (right == left) {
if (nums[left] == target) {
return left;
} else return -1;
}
int midIndex = (left+right)/2;
if (nums[midIndex] < target) {
return findLeftIndex(nums, midIndex+1, right, target);
} else if (nums[midIndex] > target) {
return findLeftIndex(nums, left, midIndex-1, target);
} else {
return findLeftIndex(nums, left, midIndex, target);
}
}
public int findRightIndex(int[] nums, int left, int right, int target) {
if (right == left) {
if (nums[left] == target) {
return left;
} else return -1;
}
int midIndex = (left+right)/2+1;
if (nums[midIndex] < target) {
return findRightIndex(nums, midIndex+1, right, target);
} else if (nums[midIndex] > target) {
return findRightIndex(nums, left, midIndex-1, target);
} else {
return findRightIndex(nums, midIndex, right, target);
}
}
}