题目描述
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
力扣原题目地址:https://leetcode.cn/problems/...
解法一,使用数组原生方法indexOf
var search = function (nums, target) {
return nums.indexOf(target)
};
数组的原生方法,使用真方便。不过有时候需要多拓展一些处理问题的方式,以后遇到需求时,大有裨益
解法二,循环所有判断是否等于目标值
var search = function (nums, target) {
let whichIndex = -1
for (let i = 0; i < nums.length; i++) {
if (nums[i] == target) {
whichIndex = i
return whichIndex
}
}
return whichIndex
};
假设我们要找的值,就是正好在最后一个位置,那么就得把整个循环全部走一遍,才能找到我们所要找的那个数值。所以时间复杂度就是O(n)
。为了进一步提升效率,减少用时,所以二分法解题的方式就应运而生
解法三,二分法解题
所谓二分法可以简单理解为:
- 指定开始位置、结束位置、然后不断缩小其范围最终找到我们想要找到的值;
- 由于二分法的一半一半的缩小范围,所以其时间复杂度是
O(\log n)
另外注意:
- 二分法适用于有序的数组,即从小到大或者从大到小的数组
- 二分法搭配while循环可读性会更加直观明了
在工作中for循环使用次数比较多,while循环并不是特别多,所以为了更好的理解二分法的,我们来简单复习一下while的循环知识
while循环复习
// 当符合condition条件的时候,会继续不断循环执行花括号里面的代码
// 所以当达到某种情况下的时候,需要让condition条件变为false,这样的话,才会结束循环
// 要不然就会死循环哦
while (condition) {
// .....
}
// eg:使用while循环打印0~10
let num = 0
while (num <= 10) { // 翻译:当num的值小于等于10的时候,就不断循环
console.log(num);
num++
}
while和for循环的区别
固定数组、固定长度、固定执行次数一般使用for循环
做边界区分、不知道要循环多少次一般使用while循环
while比for功能更加强大
二分法代码
var search = function (arr, num) {
let firstIndex = 0
let lastIndex = arr.length - 1
// 注意firstIndex是要小于等于lastIndex值的,因为区间不断缩小最终重合
while (firstIndex <= lastIndex) {
// console.log('firstIndex', firstIndex, 'lastIndex', lastIndex); // 看打印结果,有助于更好理解
let middleIndex = Math.floor((firstIndex + lastIndex) / 2) // 数组长度为偶数时要向下取整,所以干脆都向下取整呗
if (arr[middleIndex] == num) { // 若恰好中间索引数正好是我们所要找的那个数,返回索引即可
return middleIndex
} else if (arr[middleIndex] > num) { // 若中间数比要找的数大,说明要找到数在左边,那么开始区间不用动,结束区间更改为中间数左边一个位置即可
lastIndex = middleIndex - 1
} else if (arr[middleIndex] < num) { // 同理...
firstIndex = middleIndex + 1
}
}
return -1 // 找不到的话,返回-1
};
这里大家可以把while (firstIndex <= lastIndex) {......}
改为while (true) {......}
看看打印结果就会更好的理解了。虽然会死循环
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。