搜索插入位置-LCR068-[简单]

. - 力扣(LeetCode)

总结

二分查找看起简单,新手就是撸不出来

关键1:中间位置mid = ((right - left) / 2) + left 或 (left + right) / 2 防止溢出

关键2:循环终止判断,while循环,left>=right 就停止

关键3:mid位置不断移动

 

方法1

  1. ans的初始化位置不是很好直观理解,也是官方答案的写法
  2. 中间位置的计算方法:int mid = ((right - left) / 2) + left;其它地方也是这样算
  3. 第一步转化公式
  4. 第二步根据转化公式,找到:在一个有序数组中找第一个大于等于 target的下标,等于就是找到了,第一个大于就是插入的位置
/**
 * 考虑这个插入的位置 pos,它成立的条件为:
 * nnums[pos−1]<target≤nums[pos]
 *
 * 其中 nums代表排序数组。由于如果存在这个目标值,我们返回的索引也是 pos,因此我们可以将两个条件合并得出最后的目标:
 * 「在一个有序数组中找第一个大于等于 target的下标」。
 *
 * 问题转化到这里,直接套用二分法即可,即不断用二分法逼近查找第一个大于等于 target的下标 。
 * 下文给出的代码是笔者习惯的二分写法,ans初值设置为数组长度可以省略边界条件的判断,
 * 因为存在一种情况是 target大于数组中的所有数,此时需要插入到数组长度的位置。

 */
class Solution {
    public int searchInsert(int[] nums, int target) {
        int n = nums.length;

        int left = 0, right = n - 1, ans = n;

        while (left <= right) {
            int mid = ((right - left) / 2) + left;
            if (target <= nums[mid]) {
                ans = mid;
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return ans;
    }
}

方法2

  1. 返回的是left的值,如果left>right了,这个时候left已经加1了,这个时候left的位置刚好是要插入的位置
  2. 学习视频:二分查找 红蓝染色法_哔哩哔哩_bilibili
package algorithm.second.array.and.string.topic_LCR068;

/**
 * link{https://leetcode.cn/problems/N6YdxV/solutions/1398925/cha-zhao-cha-ru-wei-zhi-by-leetcode-solu-inlw/}
 */
class Solution2 {
    /**
     *[left,right] 是闭区间
     */
    public int searchInsert(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return left;
    }

    /**
     *[left,right) 是开区间
     */
    public int searchInsert2(int[] nums, int target) {
        int left = 0, right = nums.length;
        while (left < right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid;
            }
        }
        return left;
//        return right; 返回 left,right 都可以
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值