Search for a Range
来自 <https://leetcode.com/problems/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].
题目解读:
给定一个有序数组nums和一个整数target,找出target在数组中的起始位置。
算法的时间复杂度为O(logn).
如果target在数组中没有找到,则返回[-1, -1]。
例如
给定数组[5, 7, 7, 8, 8, 10] 和target值8.返回[3, 4]。
解析:根据题意可知,由于算法的时间复杂度为O(logn),并且数组是有序数组,所以要使用二分查找。在二分查找结束后,根据找到的一个索引,再向两边扩充。
Java代码一(递归):
public class Solution {
/**
* 二分查找递归
* @param nums
* @param target
* @return
*/
public int[] searchRange1(int[] nums, int target) {
int[] result = new int[2];
int low = 0;
int high = 0;
int location = binarysearch(nums, target, 0, nums.length-1);
/**
* 如果没有找到
*/
if(-1 == location) {
result[0]=-1;
result[1]=-1;
} else {
/**
* 如果找到其中的一个值
*/
//向左扩充
for(low=location; low>=0; low--) {
if(nums[low] != nums[location])
break;
}
//向右扩充
for(high=location; high<nums.length; high++) {
if(nums[high] != nums[location]) {
break;
}
}
result[0] = low+1;
result[1] = high-1;
}
return result;
}
/**
* 递归二分查找算法
* @param nums
* @param target
* @param low
* @param high
* @return
*/
public int binarysearch(int[] nums, int target, int low,int high) {
if(low>high)
return -1;
int mid = (low+high) /2;
if(target == nums[mid])
return mid;
else if(target > nums[mid])
return binarysearch(nums, target, mid+1, high);
else
return binarysearch(nums, target, low, mid-1);
}
}
递归性能:
Java代码二(非递归):
public class Solution {
/**
* 二分查找非递归
* @param nums
* @param target
* @return
*/
public int[] searchRange(int[] nums, int target) {
int[] result = new int[2];
int low = 0;
int high = nums.length-1;
int mid = 0;
/**
* 二分查找找出序列中的一个target值
*/
while(low<=high) {
mid = (low+high) / 2;
if(target == nums[mid])
break;
else if(target < nums[mid])
high = mid-1;
else
low = mid+1;
}
/**
* 如果没找到
*/
if(low > high) {
result[0] = -1;
result[1] = -1;
return result;
}
/**
* 如果找到其中的一个值
*/
//向左扩充
for(low=mid; low>=0; low--) {
if(nums[low] != nums[mid])
break;
}
//向右扩充
for(high=mid; high<nums.length; high++) {
if(nums[high] != nums[mid]) {
break;
}
}
result[0] = low+1;
result[1] = high-1;
return result;
}
}
非递归性能: