二分法-中等难度
二分法
东西其实并不难,如果你理解不了,说明教的不好
二分法实际是一个比较简单的方法
基础的原理:在一个排序好的数组中,寻找一个值,可以看中间元素值的大小,跟目标值进行比较,确定以一个搜索范围,每次搜索范围可以减半,搜索效率大大提升。
二分法一个写的比较清楚的视频 分享给大家: leetcode34
二分法的解题模板:
public int binarySearch(int[] nums, int target){
int left = 0;
int right = nums.length;
int ans = -1;
while(left<=right){ // 这个等号很有学问,如果后面left,right=mid,等号不能加,如果=mid+1或mid-1,需要加=号
int mid= left+(right-left)/2; // 这块可以避免(left+right)/2引入的溢出问题
if(nums[mid]< target){
left = mid+1;
} else if(nums[mid]> target){
right = mid-1;
} else{
// 这块的代码是核心,需要按照不同题目好好设计,设计好了问题会很简单
ans = mid;
}
return ans;
}
}
力扣上的部分二分法题目及我的答案
[34. 在排序数组中查找元素的第一个和最后一个位置](https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/)
class Solution {
public int[] searchRange(int[] nums, int target) {
int firstIndex = binarySearch(nums, target, true);
if (firstIndex == -1) {
return new int[]{-1, -1};
}
int lastIndex = binarySearch(nums, target, false);
return new int[]{firstIndex, lastIndex};
}
public int binarySearch(int[] nums, int target, boolean first) {
int left = 0;
int right = nums.length - 1;
int ans = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
if (first) {
right = mid - 1;
ans = mid;
} else {
left = mid + 1;
ans = mid;
}
}
}
return ans;
}
}
[33. 搜索旋转排序数组](https://leetcode-cn.com/problems/search-in-rotated-sorted-array/)
class Solution {
public int search(int[] nums, int target) {
int conv = findConvert(nums) + 1;
int ans1 = binarySearch(Arrays.copyOfRange(nums, 0, conv), target);
int ans2 = binarySearch(Arrays.copyOfRange(nums, conv, nums.length), target);
if (ans1 != -1) {
return ans1;
} else if (ans2 != -1) {
return ans2 + conv;
} else {
return -1;
}
}
public int findConvert(int[] nums) {
int left = 0;
int right = nums.length - 1;
int ans = -1;
while (left < right) {
final int mid = left + (right - left) / 2;
if (nums[mid] <= nums[left]) {
right = mid;
ans = mid;
} else {
left = mid;
}
}
return ans;
}
public int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
int ans = -1;
while (left <= right) {
final int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
right = mid - 1;
ans = mid;
}
}
return ans;
}
}
[74. 搜索二维矩阵](https://leetcode-cn.com/problems/search-a-2d-matrix/)
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int[] nums = new int[matrix.length * matrix[0].length];
int count = 0;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[0].length; j++) {
nums[count++] = matrix[i][j];
}
}
return binarySearch(nums, target);
}
public boolean binarySearch(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) {
left = mid + 1;
} else if (nums[mid] > target) {
right = mid - 1;
} else {
return true;
}
}
return false;
}
}