二分法查找适用于数据量较大时,但是数据需要先排好顺序
下面给大家介绍我遇到的一些问题,和力扣实际题的思路
注意循环跳不出问题和细节
!!!
right=mid时(不是mid-1)
while里left不能等于right
否则会跳不出循环
!!!
while(left<right){
mid=left+(right-left+1)/2;
if(nums[mid]>target) right=mid-1;
else left=mid;
}
mid=left+(right-left+1)/2;必须+1,否则会跳不出循环
因为int小数自动消除,所以是优先满足left,当等于的条件left未-1的情况下,mid就必须加1/2
mid=(left+right)/2;可能会溢出
mid=left+(right-left)/2; 等于 mid=((right-left)>>>1)+left;
1.三路比较
class Solution {
public int searchInsert(int[] nums, int target) {
int n = nums.length;
int left=0,right=n-1,mid;
while(left<=right){
mid=left+(right-left)/2;
if(nums[mid]<target)
left=mid+1;
else if(nums[mid]>target)
right=mid-1;
else return mid;
}
return -1;
}
}
重复应用减半原理
迭代次数O(log N)
2.两路比较
class Solution {
public int searchInsert(int[] nums, int target) {
int n = nums.length;
int left=0,right=n-1,mid;
while(left<right){
mid=left+(right-left)/2;
if(nums[mid]<target)
left=mid+1;
else right=mid;
}
if(nums[right]==target) return right;
return -1;
}
}
优化的二分查找能将次数减少约一半
对于一个成功的查找,把所有情况缩减到一个项,用循环外的一个单独测试来判断
3.力扣实际题目运用
3.1未找到目标值顺序插入表中
return left;
left左边的值一直保持小于等于target,right右边的值一直保持大于等于target
3.2旋转后数组
3.2.1先找分界(旋转点)
两路比较
a=mid;
if(nums[0]>target){
left=a+1;
right=n-1;
}
else{
left=0;
right=a;
}
3.2.2分为左右两部分
一定一部分有序,一部分无序
//有序为左边
if (nums[left] <= nums[mid]) {
//target在有序里
if (nums[left]<=target&&target<nums[mid]) right=mid-1;
//无序里
else left=mid+1;
}
//有序为右边
else {
//有序里
if (nums[mid]<target&&target<=nums[right]) left=mid+1;
//无序里
else right=mid-1;
}
3.3数组查找元素第一位和最后一位
先找>=target的位置,第二次找最后<=target的位置
right=nums.length-1;
left=0;
//先找的<=target位置赋值于a
while(left<right){
mid=left+(right-left+1)/2;
if(nums[mid]>target) right=mid-1;
else left=mid;
}
int a=0;
a=left;
right=nums.length-1;
left=0;
//后找的>=target位置为right
while(left<right){
mid=left+(right-left)/2;
if(nums[mid]<target) left=mid+1;
else right=mid;
}
return new int []{right,a};
3.4 二维数组查找元素
1 2 3 4 5
6 7 8 9 10
11 12 13 14
二维数组matrix [] [] ,matrix[0] [] 表示第一行 1 2 3 4 5
3.4.1先找到在哪一行
while(left<right){
mid=left+(right-left)/2;
if(matrix[mid][n-1]>=target) right=mid;
else left=mid+1;
}
int a=right;
3.4.2拼接,当成一个一维数组
int x=matrix[mid/n][mid%n];
不足和错误地方请多多指教