题目:34 在排序数组中查找元素的第一个和最后一个位置(mid)
一、题目
Given an array of integers nums sorted in non-decreasing order, find the starting and ending position of a given target value.
If target is not found in the array, return [-1, -1].
You must write an algorithm with O(log n) runtime complexity.
Example 1:
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Example 2:
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
Example 3:
Input: nums = [], target = 0
Output: [-1,-1]
Constraints:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums is a non-decreasing array.
-109 <= target <= 109
二、 思路
有序数组考虑二分查找,因为要找区间,所以分开找左右边界,第一次和第二次写的思路是对的,但是这么分情况太麻烦了,又是leftBorder又是rightBorder还得分三种情况再讨论,写着写着就晕了,所以改进了写法,直接在getLeftBorder和getRightBorder内进行操作,最后直接返回数值就行了。
二、自己写的
1.代码
第一次写
class Solution {
//java变量名和方法名命名规则:第一个单词小写,后面单词第一个字母大写 eg:getLeftBorder、left
//java类名的命名规则:所有单词第一个字母全都大写 eg:ClassHelloWorld
//java常量的命名规则:全部字母大写 eg:COUNT
//java包的命名规则:全部字母小写 eg:workdesk
//一共三种情况
//第一种情况:target小于数组中最小的或者大于数组中最大的,返回[-1,-1]
//第二种情况:target在数组最大和最小的范围内,但是还是数组内没有这个值,返回[-1,-1](不好写)
//第三种情况:target在数组内存在,求出来范围
public int[] searchRange(int[] nums, int target) {
int leftBorder = getLeftBorder(int[] nums, int target);
int rightBorder = getRightBorder(int[] nums, int target);
//第一种情况:leftBorder或者rightBorder的值为-2
if (leftBorder == -2 || rightBorder == -2)
return new []int{
-1,-1};
//第三种情况:rightBorder - leftBorder的值肯定是大于等于0的
//(试过了,只有一个数的时候rightBorder==leftBorder)
else if ((rightBorder - leftBorder) >= 0)
return new []int{
leftBorder,rightBorder - 1}
//第二种情况:直接else
else
return new []int{
-1,-1};
}
//获取左边界leftBorder
int getLeftBorder(int[] nums, int target){
int left = 0, right = nums.length - 1;
int mid = 0;
int leftBorder = -2;
if (nums[left] > target)
return leftBorder;
while (left <= right) {
mid = left + (left + right) / 2;
if (nums[mid] > target)
right = mid - 1;
else if (nums[mid] == target) //因为要找左边界,mid找到了没用,还得接着往左走,找到最最左边的等于target的
right = mid - 1;
else
left = mid + 1;
leftBorder = left;
if (nums[left] == target) //左边界找到了,返回值
leftBorder = left;
return leftBorder;
}
}
//获取右边界rightBorder
int getRightBorder(int[] nums, int target){
i