给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
思路
循环 对比 比前面的大 你后面的小于或者等于
这就得到了target <= nums[i]
上代码
let data = [1,3,5,6]
let r = 5 ;
var searchInsert = function(nums, target) {
if(target == 0) return 0
if(nums[0] == target) return 0
for (let i = 0; i < nums.length; i++) {
if (target <= nums[i]) {
return i;
}
}
return nums.length;
};
console.log(searchInsert(data,r))
这是常规的
看看 官方的给的
二分查找
var searchInsert = function(nums, target) {
const n = nums.length;
let left = 0, right = n - 1, ans = n;
while (left <= right) {
let mid = ((right - left) >> 1) + left;
if (target <= nums[mid]) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
};
分析题意,挖掘题目中隐含的 单调性;
while (left < right) 退出循环的时候有 left == right 成立,因此无需考虑返回 left 还是 right;
始终思考下一轮搜索区间是什么,如果是 [mid, right] 就对应 left = mid ,如果是 [left, mid - 1] 就对应 right = mid - 1,是保留 mid 还是 +1+1、-1−1 就在这样的思考中完成;
从一个元素什么时候不是解开始考虑下一轮搜索区间是什么 ,把区间分为 22 个部分(一个部分肯定不存在目标元素,另一个部分有可能存在目标元素),问题会变得简单很多,这是一条 非常有用 的经验;
每一轮区间被划分成 22 部分,理解 区间划分 决定中间数取法( 无需记忆,需要练习 + 理解 ),在调试的过程中理解 区间和中间数划分的配对关系:
划分 [left, mid] 与 [mid + 1, right] ,mid 被分到左边,对应 int mid = left + (right - left) / 2;;
划分 [left, mid - 1] 与 [mid, right] ,mid 被分到右边,对应 int mid = left + (right - left + 1) / 2;。
至于为什么划分是这种对应关系,原因在于区间只有 22 个数的时候,如果中间数的取法不对,一旦进入的分支不能使得区间缩小,会出现 死循环。暂时不理解问题不大,需要在练习中进行调试;
退出循环的时候有 left == right 成立,此时如果能确定问题一定有解,返回 left 即可,如果不能确定,需要单独判断一次。
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/search-insert-position/solution/te-bie-hao-yong-de-er-fen-cha-fa-fa-mo-ban-python-/
虽然实现 但是要学习算法 还是要跟着官方的思路走是没有坏处的