367 二分查找深入理解
关注查找的区间问题
This commit is contained in:
parent
01864dd56d
commit
d19cd4f072
109
src/main/java/cn/whaifree/leetCode/middle/LeetCode34.java
Normal file
109
src/main/java/cn/whaifree/leetCode/middle/LeetCode34.java
Normal file
@ -0,0 +1,109 @@
|
||||
package cn.whaifree.leetCode.middle;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* 34. 在排序数组中查找元素的第一个和最后一个位置
|
||||
* 中等
|
||||
* 给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
|
||||
*
|
||||
* 如果数组中不存在目标值 target,返回 [-1, -1]。
|
||||
*
|
||||
* 你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
|
||||
* 示例 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]
|
||||
*
|
||||
*
|
||||
* 提示:
|
||||
*
|
||||
* 0 <= nums.length <= 105
|
||||
* -109 <= nums[i] <= 109
|
||||
* nums 是一个非递减数组
|
||||
* -109 <= target <= 109
|
||||
*/
|
||||
public class LeetCode34 {
|
||||
/**
|
||||
* 非递减顺序排列的整数数组
|
||||
* [0,length]
|
||||
* [5,8,8,8,8,10]
|
||||
* @param nums
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public int[] searchRange(int[] nums, int target) {
|
||||
int[] ans = new int[2];
|
||||
// 三头
|
||||
int left = 0;
|
||||
int right = nums.length - 1;
|
||||
while (left <= right) {
|
||||
int middle = (left + right) / 2;
|
||||
if (nums[middle] == target) {
|
||||
// 在[left,middle) , (middle,right]区间里找到第一个和最后一个target
|
||||
|
||||
// break;
|
||||
// 找到了一个
|
||||
if (nums[left] == target && nums[right] == target) {
|
||||
ans[0] = left;
|
||||
ans[1] = right;
|
||||
return ans;
|
||||
} else if (nums[left] == target) {
|
||||
right--;
|
||||
} else if (nums[right] == target) {
|
||||
left++;
|
||||
} else {
|
||||
right--;
|
||||
left++;
|
||||
}
|
||||
} else if (nums[middle] < target) {
|
||||
left = middle + 1;
|
||||
} else {
|
||||
right = middle - 1;
|
||||
}
|
||||
}
|
||||
ans[0] = -1;
|
||||
ans[1] = -1;
|
||||
return ans;
|
||||
}
|
||||
public int[] searchRange2(int[] nums, int target) {
|
||||
int leftIdx = binarySearch(nums, target, true);
|
||||
int rightIdx = binarySearch(nums, target, false) - 1;
|
||||
if (leftIdx <= rightIdx && rightIdx < nums.length && nums[leftIdx] == target && nums[rightIdx] == target) {
|
||||
return new int[]{leftIdx, rightIdx};
|
||||
}
|
||||
return new int[]{-1, -1};
|
||||
}
|
||||
|
||||
public int binarySearch(int[] nums, int target, boolean lower) {
|
||||
int left = 0, right = nums.length - 1, ans = nums.length;
|
||||
while (left <= right) {
|
||||
int mid = (left + right) / 2;
|
||||
if (nums[mid] > target || (lower && nums[mid] >= target)) {
|
||||
right = mid - 1;
|
||||
ans = mid;
|
||||
} else {
|
||||
left = mid + 1;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
for (int i : searchRange2(new int[]{5,8,8,8,8,10}, 8)) {
|
||||
System.out.println(i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user