我的LeetCode代码仓:https://github.com/617076674/LeetCode
题目描述:
知识点:二分搜索法
思路:floor函数和ceil函数
本题的算法逻辑很清楚,本质上就是floor()函数和ceil()函数的实现。其实比floor()函数和ceil()函数的实现还要简单点,因为当找不到target时,我们直接返回-1。
floor()函数的实现过程:
(1)令left的初始值为-1,right的初始值为nums.length - 1。
(2)当left < right时进行以下循环,
a.计算mid时,为了防止死循环的出现,需要向上取整。
b.当target小于等于nums[mid]时,我们应该在左半部分寻找,令right = mid - 1。当target大于nums[mid]时,我们应该在右半部分寻找,令left = mid。
(3)结束循环后,如果left + 1不越界且nums[left + 1]的值为target,说明target在数组nums中存在,其开始位置为left + 1。否则,说明target在数组nums中不存在,直接返回-1。其实结束循环后left和right的值是相等的,因此这里left + 1换成right + 1也没问题。
ceil()函数的实现过程:
(1)令left的初始值为0,right的初始值为nums.length。
(2)当left < right时进行以下循环,
a.计算mid时,为了防止死循环的出现,需要向下取整。
b.当target大于等于nums[mid]时,我们应该在右半部分寻找,令left = mid + 1。当target小于nums[mid]时,我们应该在左半部分寻找,令right = mid。
(3)结束循环后,如果right - 1不越界且nums[right - 1]的值为target,说明target在数组nums中存在,其结束位置为right - 1。否则,说明target在数组nums中不存在,直接返回-1。其实结束循环后left和right的值是相等的,因此这里right - 1换成left - 1也没问题。
floor()函数和ceil()函数的时间复杂度都是O(logn)级别的,因此总的时间复杂度也是O(logn)级别的。整个算法没有使用额外的辅助空间,其空间复杂度是O(1)级别的。
JAVA代码:
public class Solution {
public int[] searchRange(int[] nums, int target) {
int[] result = new int[2];
result[0] = floor(nums, target);
result[1] = ceil(nums, target);
return result;
}
private int floor(int[] nums, int target) {
int left = -1;
int right = nums.length - 1;
while(left < right) {
int mid = left + (right - left + 1) / 2;
if(target <= nums[mid]) {
right = mid - 1;
}else {
left = mid;
}
}
if(left + 1 < nums.length && nums[left + 1] == target) {
return left + 1;
}else {
return -1;
}
}
private int ceil(int[] nums, int target) {
int left = 0;
int right = nums.length;
while(left < right) {
int mid = left + (right - left) / 2;
if(target >= nums[mid]) {
left = mid + 1;
}else {
right = mid;
}
}
if(right - 1 >= 0 && nums[right - 1] == target) {
return right - 1;
}else {
return -1;
}
}
}
LeetCode解题报告: