讲透LeetCode35.搜索插入位置(二分查找例题)

35.搜索插入位置(二分查找例题)

leetcode题目链接
在这里插入图片描述

思路:

因为题目中说明了数组是排序数组,这是使用二分查找的前提条件,所以我们考虑这道题是否可以使用二分查找的方法来解决。

这道题使用二分查找会出现两种情况,第一种情况是在数组中我们找到了相应的目标值,那么这道题就是最简单的二分查找题目,我们可以通过基础的模板来解决。第二种情况就是在数组中我们找不到对应的值,那么我们需要返回它将被按顺序插入的位置,即我们需要找到最后一个小于它的数或者第一个大于它的数,如果找最后一个小于它的数,则返回结果为最后一个小于它的数的位置+1;如果找第一个大于它的数,返回的结果就是第一个大于它的数的位置。

由题目可以知道,示例2和示例3都是第二种情况,所以我们对示例2和示例3进行二分查找模拟。

当使用左闭右闭区间时:

按照示例2所示:

leftrightmiddlenums[middle]
0313
0001
10

按照示例3所示:

leftrightmiddlenums[middle]
0313
2325
3336
43

根据上述示例2和示例3,我们可以知道二分查找退出循环后,left代表的就是第一个大于目标值的数,而right代表的就是最后一个小于目标值的数。

当使用左闭右开区间时:

按照示例2所示:

leftrightmiddlenums[middle]
0425
0213
0101
11

按照示例3所示:

leftrightmiddlenums[middle]
0425
3435
44

根据上述示例2和示例3,我们可以知道二分查找退出循环后,left和right都是代表第一个大于目标值的数。

我对上述结果的思考是:在正常的二分查找中,如果我们想要找到排序数组中的一个值,那么left和right都是会逐渐逼近这个值的,在正常的情况下,如果排序数组中有这个值,那么只需要left或者right搜寻到就可以了。但是如果排序数组中没有这个值,我们在搜索的过程中是一定遇到left==right的情况,当我们使用的是左闭右闭的区间时,当left>right时,循环才会结束,我们需要考虑left与right相等时的情况,如果相等时的值是大于目标值的话,那么right需要减一,然后结束循环,如果相等时的值是小于目标值的话,那么left需要加1,所以目标值是在区间[right,left]之间的,所以我们的结果应该为left+1或者right。当我们使用的是左闭右开的区间的话,当left与right相等时,循环就结束了,那我们是否可以这么认为nums[left]<target和nums[right]>target在二分查找的整个过程中是一直成立的,那么在left等于right的前一步应该总是left+1=right的情况,然后再跳到left=right的情况,所以在循环结束后,left和right都是第一个大于target的数,所以直接输出就可以了。

代码:

左闭右闭区间的两种代码:

class Solution {
    public int searchInsert(int[] nums, int target) {
            int left=0;
            int right=nums.length-1;
            while(left<=right)
            {
                int middle=left+(right-left)/2;
                if(nums[middle]>target)
                {
                    right=middle-1;
                }
                else if(nums[middle]<target)
                {
                    left=middle+1;
                }
                else
                    return middle;
            }
            return right+1;
            
    }
}
class Solution {
    public int searchInsert(int[] nums, int target) {
            int left=0;
            int right=nums.length-1;
            while(left<=right)
            {
                int middle=left+(right-left)/2;
                if(nums[middle]>target)
                {
                    right=middle-1;
                }
                else if(nums[middle]<target)
                {
                    left=middle+1;
                }
                else
                    return middle;
            }
            return left;
            
    }
}

左闭右开区间的两种代码:

class Solution {
    public int searchInsert(int[] nums, int target) {
            int left=0;
            int right=nums.length;
            while(left<right)
            {
                int middle=left+(right-left)/2;
                if(nums[middle]>target)
                {
                    right=middle;
                }
                else if(nums[middle]<target)
                {
                    left=middle+1;
                }
                else
                    return middle;
            }
            return right;
            
    }
}
class Solution {
    public int searchInsert(int[] nums, int target) {
            int left=0;
            int right=nums.length;
            while(left<right)
            {
                int middle=left+(right-left)/2;
                if(nums[middle]>target)
                {
                    right=middle;
                }
                else if(nums[middle]<target)
                {
                    left=middle+1;
                }
                else
                    return middle;
            }
            return left;
            
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值