Search Insert Position

来源:互联网 发布:淘宝企业自营店可靠吗 编辑:程序博客网 时间:2024/06/16 20:49
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




0 0