algorithm-base/animation-simulation/二分查找及其变种/leetcode34查找第一个位置和最后一个位置.md

171 lines
7.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

> **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈
>
>
>
> <u>[****](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
##
使
![](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/二分查找变种一.3axfe8rq0ei0.png)
5 5 5 5 使 5 5
#### [34. ](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/)
####
> nums target
>
> target [-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]
3
> nums = [], target = 0
> [-1,-1]
####
使使
```java
if (nums[mid] == target) {
return mid;
}else if (nums[mid] < target) {
//这里需要注意,移动左指针
left = mid + 1;
}else if (nums[mid] > target) {
//这里需要注意,移动右指针
right = mid - 1;
}
```
nums[mid] == target nums[mid] < target nums[mid] > target
nums[mid] = target , mid ![](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/二分查找下边界.m9m083jempc.png)
mid = 4 nums[mid] = 5, mid 5
mid 5
target <= nums[mid] right = mid - 1 mid 5
![1](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/左边界1.5o2ihokjfg80.png)
![2](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/左边界2.5wazlfm298s0.png)
target <= nums[mid] right = mid -1 left left = 3right = 2 left
****
![](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/二分查找下边界.u1cidx99yio.gif)
```java
int lowerBound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
//这里需要注意计算mid
int mid = left + ((right - left) >> 1);
if (target <= nums[mid]) {
//当目标值小于等于nums[mid]时,继续在左区间检索,找到第一个数
right = mid - 1;
}else if (target > nums[mid]) {
//目标值大于nums[mid]时,则在右区间继续检索,找到第一个等于目标值的数
left = mid + 1;
}
}
return left;
}
```
target <= nums[mid] right = mid -1target > nums[mid] left = mid + 1
target < nums[mid] right = mid -1; target >= nums[mid] left = mid + 1; right
****
```java
int upperBound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
//求mid
int mid = left + ((right - left) >> 1);
//移动左指针情况
if (target >= nums[mid]) {
left = mid + 1;
//移动右指针情况
}else if (target < nums[mid]) {
right = mid - 1;
}
}
return left;
}
```
#### ****
Java Code:
```java
class Solution {
public int[] searchRange (int[] nums, int target) {
int upper = upperBound(nums,target);
int low = lowerBound(nums,target);
//不存在情况
if (upper < low) {
return new int[]{-1,-1};
}
return new int[]{low,upper};
}
//计算下边界
int lowerBound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
//这里需要注意计算mid
int mid = left + ((right - left) >> 1);
if (target <= nums[mid]) {
//当目标值小于等于nums[mid]时,继续在左区间检索,找到第一个数
right = mid - 1;
}else if (target > nums[mid]) {
//目标值大于nums[mid]时,则在右区间继续检索,找到第一个等于目标值的数
left = mid + 1;
}
}
return left;
}
//计算上边界
int upperBound(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (target >= nums[mid]) {
left = mid + 1;
}else if (target < nums[mid]) {
right = mid - 1;
}
}
return right;
}
}
```