lt.704 二分查找
[案例需求]
[思路分析]
- 二分法典型例题, 有什么好说的, 我秒了(误)
- 口误啊口误, 可不敢说秒二分. 本题是二分法的标准入门题, 本意还是通过二分查找值, 是前面讲过的二分查找的第一个模板, 在这里就不讲太多了, 好好看下前面文章哈.
[代码实现]
class Solution {
public int search(int[] nums, int target) {
// // 左开右闭
// int left = 0;
// int right = nums.length;
// while(left < right){
// int mid = left + (right - left)/2;
// if(nums[mid] == target){
// return mid;
// }else if(nums[mid] < target){
// left = mid + 1;
// }else if(nums[mid] > target){
// right = mid;
// }
// }
//二分查找, 左闭右闭
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + (right - left)/2;
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}
}
return -1;
}
}
lt.33-搜索旋转排序数组
[案例需求]
[思路分析]
[代码实现]
class Solution {
public int search(int[] nums, int target) {
//数组局部有序 + 不重复, 考虑用二分查找
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + (right - left)/2;
//跳出遍历的出口
if(nums[mid] == target) return mid;
//遍历部分有序的序列, 对这部分有序的序列进行二分查找
//在有序的左半段(nums[left] < nums[mid])
if(nums[left] <= nums[mid]){
//缩小左半段的边界(左半段的左边界), 去除组织这个序列单调的数
if(nums[left] <= target && nums[mid] > target){
right = mid - 1; //左半段的单调序列
}else{
left = mid + 1; //右半段的单调序列
}
}else{
//右半段有序的序列
//缩小右边届的左半段
if(nums[mid] < target && nums[right] >= target){
left = mid + 1; //右半段的单调序列
}else{
right = mid - 1;//左半段的单调序列
}
}
}
return -1;
}
}
lt.34-在排序数组中查找元素的第一个和最后一个位置
[案例需求]
[思路分析]
[代码实现]
class Solution {
public int[] searchRange(int[] nums, int target) {
// 要求 o(logn), 并且是有序序列, 二分法走起
//特例
if(nums.length == 0) return new int[]{
-1,-1};
//左边界和右边界,
return new int[]{
bsfirst(nums, target), bslast(nums, target)};
}
public int bsfirst(int[] nums, int target){
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + ((right - left) >> 1);
if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}else if(nums[mid] == target){
///
if(mid == 0 || nums[mid - 1] != target){
return mid;
}else{
right = mid - 1;
}
}
}
return -1;
}
public int bslast(int[] nums, int target){
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + ((right - left) /2);
if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}else if(nums[mid] == target){
if(mid == nums.length - 1 || nums[mid + 1] != target){
return mid;
}else{
left = mid + 1;
}
}
}
return -1;
}
}
lt.35-搜索插入位置
[案例需求]
[思路分析]
[代码实现]
class Solution {
public int searchInsert(int[] nums, int target) {
// //logn 二分
// int left = 0;
// int right = nums.length - 1;
// int mid = 0;
// while(left <= right){
// mid = left + (right - left)/2;
// if(nums[mid] == target){
// return mid;
// }else if(nums[mid] > target){
// right = mid - 1;
// }else if(nums[mid] < target){
// left = mid + 1;
// }
// }
// return left;
// }
int left = 0;
int right = nums.length -1;
while(left <= right){
int mid = left + ((right - left) /2);
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target){
right = mid - 1;
}else if(nums[mid] < target){
left = mid + 1;
}
}
return left;
}
}