Search Insert Position

本文介绍了一种特殊的二分查找算法实现方式,并通过一个具体的题目示例来展示如何利用该算法确定目标值在有序数组中应插入的位置。文章详细解释了算法流程及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You may assume no duplicates in the array.
Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4

[1,3,5,6], 0 → 0


    public int searchInsert(int[] A, int target) {
    int left = 0;
    int right = A.length - 1;
    int mid;
    
    if (target < A[0]) {
        return 0;
    }
    if (target > A[A.length - 1]) {
        return A.length;
    }
    // find the last number less than target
    while (left + 1 < right) {
        mid = left + (right - left) / 2;
        if (A[mid] == target) {
            return mid;
        } else if (A[mid] < target) {
            left = mid;
        } else {
            right= mid;
        }
    }   
    
    if (target == A[left]) {
        return left;
    }
    if (target == A[right]) {
        return right;
    }
    
    return left + 1;
}



这段程序中有几个需要注意的地方:

首先是使用了下面这个 binary search 模板

while (left + 1 < right) {
        mid = left + (right - left) / 2;
        if (A[mid] == target) {
            return mid;
        } else if (A[mid] < target) {
            left = mid;
        } else {
            right= mid;
        }
    }   
    
    if (target == A[left]) {
        // ...
    }
    if (target == A[right]) {
        // ...
    }
这个模板和普通 binary search 有个不同之处就是 while 循环的判断条件是: while (left + 1 < right)

也就是说,在这种判断条件下,当left index 和 right index 相邻时 (left + 1 == right),循环就会跳出。这个时候,left 和 right 对应的值肯定有一个还没有与 target 比较过。例如,如果上一次循环是 left = mid, 则当前的 right 还没有和 target 比较过。反过来,如果上次循环是 right = mid, 则当前的 left 还没有和 target 比较过。

另外一个不同之处就是: left = mid 和 right = mid, 而不是 left = mid + 1 和 right = mid - 1. 这是为了保证在跳出时 left 和 right 是相邻一位的。如果是常规写法,跳出时 left 和 right 重合


明确了这种写法在 left + 1 == right(相邻一位) 跳出后,再看针对这一题如何思考。首先:

if (target < A[0]) {
    return 0;
}
if (target > A[A.length - 1]) {
    return A.length;
}
确保了这两个特殊情况。

如果没有遇上两个特殊情况,则先进去循环,再跳出循环,此时 left 和 right 相邻一位。此时有3种可能:

target == A[left]

target == A[right]

target在 left 和 right 之间 --- > return left + 1




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值