前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【二分法】LeetCode-Search Insert Position

【二分法】LeetCode-Search Insert Position

作者头像
MapleYe
发布2020-03-28 21:04:24
5140
发布2020-03-28 21:04:24
举报
文章被收录于专栏:MapleYe

前言

今天在LeetCode遇到一个这样的题目.

SearchInsertPosition@2x.png

题目意思就是给一个排好序的数组和要寻找的数,若数组存在,返回它的index,否则返回它该插入的位置。

思考

拿到这个问题,哇,这不就是普通的二分法吗?那就刷刷的写下了二分法的代码:

代码语言:javascript
复制
func searchInsert(_ nums: [Int], _ target: Int) -> Int {
    var low = 0
    var high = nums.count - 1
    var mid = -1
    while low <= high {
        mid = (high + low) / 2
        if target == nums[mid] {
            return mid
        }else if target > nums[mid] {
            low = mid + 1
        }else {
            high = mid - 1
        }
    }
    return -1
}

以上代码是最原始的二分查找法,若存在返回对应的索引,不存在返回-1。而题目额外要求找不到,就返回要插入的位置。这时候我就纠结low,mid,high之间,究竟哪一个才是要插入的位置呢?想了半天没思绪,看了下答案,只需要将return -1改为return low就可以了。

疑惑

为什么是返回low,而不是返回high,或者是返回mid。所以我又搜了一下关于二分法的相关资料,看完这篇博客后,恍然大悟。

二分法有很多变种形式,例如查找最后一个等于或者小于key的元素等形式(可以去看该博客)。最后该博客,总结了二分法各形式变化,以下为该博客的结论:

1、首先确定返回的是left,还是right

  • 跳出while (left <= right)循环条件是right < left,且right = left - 1。
  • right和left一定是卡在"边界值"的左右两边
  • 如果是比较值为key,查找小于等于(或者是小于)key的元素,则边界值就是等于key的所有元素的最左边那个,其实应该返回left。

例子

以数组{1, 2, 3, 3, 4, 5}为例,如果需要查找第一个等于或者小于3的元素下标,我们比较的key值是3,则最后left和right需要满足以下条件:

例子.png

我们比较的key值是3,所以此时我们需要返回left

2、判断出比较符号

代码语言:javascript
复制
int mid = (left + right) / 2;
if (array[mid] ? key) {
    //... right = xxx;
}
else {
    // ... left = xxx;
}

也就是这里的 if (array[mid] ? key) 中的判断符号,结合步骤1和给出的条件,如果是查找小于等于key的元素,则知道应该使用判断符号>=,因为是要返回left,所以如果array[mid]等于或者大于key,就应该使用>=,以下是完整代码

代码语言:javascript
复制
// 查找小于等于key的元素
int mid = (left + right) / 2;
if (array[mid] >= key) {
    right = mid - 1;
}
else {
    left = mid + 1;
}

为什么返回的是low

套用结论,high = low - 1

  • target小于所有元素,插入的位置是0,high为-1,low=0才能跳出循环
  • target大于所有元素,插入的位置的数组的长度count,high为count-1,low=count才能跳出循环
  • target小于数组中某些元素,大于某些元素,问题就转化为查找第一个大于target的元素下标。根据结论,high和low总是在临界值的两边,那么就相当于 high-target-low,因此返回low

总上述三种情况,返回low都符合题目要求

总结

看似简单的二分法,如果换种提问方式,或许就绕进去出不来了。因此,在这里做这个总结,加深自己的理解

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 思考
  • 疑惑
    • 1、首先确定返回的是left,还是right
      • 例子
    • 2、判断出比较符号
    • 为什么返回的是low
    • 总结
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档