二分查找,注意target可能不存在,要返回应该插入的位置
/**
* 自己的代码1,recursive
* Runtime: 0 ms, faster than 100.00%
* Memory Usage: 40.4 MB, less than 7.46%
*/
class Solution {
public int searchInsert(int[] nums, int target) {
return binarySearch(nums, 0, nums.length - 1, target);
}
private int binarySearch(int[] nums, int start, int end, int target) {
if (nums[start] >= target) {
return start;
}
if (nums[end] < target) {
return end + 1;
}
int mid = (start + end) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[mid] < target) {
return binarySearch(nums, mid + 1, end, target);
}
return binarySearch(nums, start, mid - 1, target);
}
}
/**
* 自己的代码2,比上一段简化一点
* Runtime: 0 ms, faster than 100.00%
* Memory Usage: 40.7 MB, less than 6.18%
*/
class Solution {
public int searchInsert(int[] nums, int target) {
return binarySearch(nums, 0, nums.length - 1, target);
}
private int binarySearch(int[] nums, int start, int end, int target) {
if (start > end) {
return start;
}
int mid = (start + end) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[mid] < target) {
return binarySearch(nums, mid + 1, end, target);
}
return binarySearch(nums, start, mid - 1, target);
}
}
/**
* while循环,non-recursive
* Runtime: 0 ms, faster than 100.00%
* Memory Usage: 38.7 MB, less than 47.43%
*/
class Solution {
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;
}
if (nums[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}
}
/**
* 对上一段mid取法的改良
* 涉及取mid的时候应该考虑到两头的数相加溢出的问题
* 本题中因为给出范围限制不会存在溢出
* 但使用 mid = left + (right - left) / 2; 永远是最保险的方式
* Runtime: 0 ms, faster than 100.00%
* Memory Usage: 40.9 MB, less than 6.18%
*/
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[mid] > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return left;
}
}