附上个人github仓库,会不断更新leetcode解题答案,提供一个思路,你们共勉git
在个人主页和github上能够看到更多的关于leetcode的解题报告!(由于不知道为何掘金没有将其发布出来,目前已经联系掘金客服)
但愿能够给star,鼓励继续更新解题思路
author: thomasgithub
No34:Search for Range(
Medium
)
题目
Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.算法
Your algorithm's runtime complexity must be in the order of O(log n).数组
If the target is not found in the array, return [-1, -1].bash
For exampleui
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4]. // 下标3,4是数组8
复制代码
这道题让咱们在一个有序整数数组中寻找相同目标值的起始和结束位置,没若是没有找到就返回[-1,-1]spa
思路
这道题让咱们在一个有序整数数组中寻找相同目标值的起始和结束位置,并且限定了时间复杂度为O(logn),这是典型的二分查找法的时间复杂度
,因此这道题咱们也须要用此方法。code
方法一:cdn
代码
let arr1 = [1,1,2,2,3,4,4,7,8];
let arr = [5,7,7,8,8,10],
target = 8;
let searchRange = function(arr, target) {
let len = arr.length,
res = [-1, -1];
for (let i = 0, j = len-1; i <= j;) {
let mid = Math.floor((i + j) / 2);
if (arr[mid] < target) { // 先判断小于target的状况
i = mid + 1;
}else {
j = mid - 1; // 应对恰好i = mid + 1后就指向了target值
if (arr[mid] === target) {
res[0] = mid; // 获得起始index
}
}
}
for (let i = 0, j = len-1; i <= j;) {
let mid = Math.floor((i + j) / 2);
if (arr[mid] > target) {// 先判断大于target的状况
j = mid - 1;
}else {
i = mid + 1; // 应对恰好i = mid + 1后就指向了target值
if (arr[mid] === target) {
res[1] = mid; // 获得结束index
}
}
}
return res;
};
console.log(searchRange(arr,target)); // [3, 4]
复制代码
/**
* 方法2
*
* 找到res[0]以后,就向右遍历,直到不是该值,就能够获得右边界了
* 时间复杂度没上面的方法好
*/
let searchRange1 = function(arr, target) {
let len = arr.length,
res = [-1, -1];
for (let i = 0, j = len-1; i <= j;) {
let mid = Math.floor((i + j) / 2);
if (arr[mid] < target) {
i = mid + 1;
}else {
j = mid - 1; // 应对恰好i = mid + 1后就指向了target值
if (arr[mid] === target) {
res[0] = mid; // 获得最左边的值
}
}
}
let k;
res[1] = res[0];
for (k = res[0] + 1; k < len; k++) { // 找到右边界
if (arr[k] === target) {
res[1] += 1;
}
}
return res;
};
console.log(searchRange1([1],1)); // [0, 0]
console.log(searchRange1([2,2],2)); // [0, 1]
console.log(searchRange1([5,7,7,8,8,10],8)); // [3, 4]
console.log(searchRange1([1,3],1)); // [0, 0]
console.log(searchRange1([3,3,3],3)); // [0, 0]
复制代码
注:二分法:其假设咱们找到目标值(可是有多个目标值连在一块儿)blog
先判断arr[mid] < target(先判断小于target的状况)
,再判断剩下的,最后获得的结果就是要找的多个目标值target的最左边的值先判断arr[mid] > target(也就是先判断大于target的状况)
,再判断剩下的,最后获得的结果就是要找的多个目标值target的最右边的值No35:Search Insert Position(
Easy
)
题目
从给定排好顺序的数组,找出给定目标数字下标,存在则返回下标,不存在则返回目标数应该插入的位置下标。 Example 1:
Input: [1,3,5,6], 5
Output: 2
复制代码
Example 2:
Input: [1,3,5,6], 2
Output: 1
复制代码
Example 3:
Input: [1,3,5,6], 7
Output: 4
复制代码
Example 4:
Input: [1,3,5,6], 0
Output: 0
复制代码
思路
思路就是每次取中间,若是等于目标即返回,不然根据大小关系切去一半。所以算法复杂度是O(logn),空间复杂度O(1)
代码
let arr = [1,3,5,6],
target = 5;
let searchInset = function(arr, target) {
let len = arr.length,
res = 0;
for (let i = 0, j = len -1; i <= j;) {
let mid = Math.floor((i+j)/2);
if (arr[mid] === target) {
return mid;
}
if (arr[mid] < target) {
i = mid + 1;
res = mid+1; // 更新res
}else {
j = mid - 1;
}
}
return res; //
}
console.log(searchInset(arr,target)); // 2
console.log(searchInset([1,3,5,6],2)); // 2
复制代码
注意:二分法有一个好处:就是当循环结束时:
(1)若是找到目标元素,那么就返回当前位置
(2)若是没有找到目标元素,那么i必定停在刚好比目标大的index上,j必定停在刚好比目标小的index上,因此我的比较推荐这种实现方式。(初始i在左,j在右)