Java数据结构与算法——二分查找

本文详细介绍了二分查找算法在不同场景下的应用,包括常规的有序数组查找、旋转数组查找和二维数组查找。通过实例解析了二分查找的迭代过程和关键细节,如循环跳出条件、防止溢出的计算方式等,并展示了如何通过优化减少迭代次数。同时,文章还提及了在力扣(LeetCode)实际题目中如何运用二分查找解决插入排序和搜索元素的问题。
摘要由CSDN通过智能技术生成

二分法查找适用于数据量较大时,但是数据需要先排好顺序

下面给大家介绍我遇到的一些问题,和力扣实际题的思路

注意循环跳不出问题和细节

!!!

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旋转后数组

力扣第33题

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数组查找元素第一位和最后一位

力扣第34题

先找>=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 二维数组查找元素

力扣第74题

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];

不足和错误地方请多多指教

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值