「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」。
1.题目
在排序数组中查找元素的第一个和最后一个位置:
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:
你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8 输出:[3,4] 示例 2:
输入:nums = [5,7,7,8,8,10], target = 6 输出:[-1,-1] 示例 3:
输入:nums = [], target = 0 输出:[-1,-1]
思路
可能有多个目标值,所以先根据二分法缩小范围直到某个范围的中点值等于target,此时再向外扩张判断是否有周围是否有同样的target值。
代码
var searchRange = function(nums, target) {
let left = 0;
let right = nums.length - 1;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
if (nums[mid] === target) {
left = mid - 1;
right = mid + 1;
while (true) {
if (nums[left] === target) {
left--;
} else if (nums[right] === target) {
right++;
} else return [left + 1, right - 1];
}
}
if (target < nums[mid]) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return [-1, -1];
};
2.题目
搜索旋转排序数组:
整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0 输出:4
示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3 输出:-1
示例 3:
输入:nums = [1], target = 0 输出:-1
思路
由于题目说数字了无重复,举个例子:
1 2 3 4 5 6 7 可以大致分为两类,
第一类 2 3 4 5 6 7 1 这种,也就是 nums[start] <= nums[mid]。此例子中就是 2 <= 5。
这种情况下,前半部分有序。因此如果 nums[start] <=target<nums[mid],则在前半部分找,否则去后半部分找。
第二类 6 7 1 2 3 4 5 这种,也就是 nums[start] > nums[mid]。此例子中就是 6 > 2。
这种情况下,后半部分有序。因此如果 nums[mid] <target<=nums[end],则在后半部分找,否则去前半部分找。
总结:就始终在有序的范围内二分查找。
代码
let search = (nums, target) => {
if(nums.length == 0) return -1;
let l = 0, r = nums.length - 1;
let mid;
while(l <= r){
mid = ~~((l + r) / 2);
if(nums[mid] == target) return mid;
if(nums[l] <= nums[mid]){ //这一半有序, 进一步判断 target是否在其中
if(target < nums[mid] && target >= nums[l]) r = mid - 1; // 在其中
else l = mid + 1;
}else{
if(target > nums[mid] && target <= nums[r]) l = mid + 1;
else r = mid - 1;
}
}
return -1;
}
3.题目
搜索二维矩阵
编写一个高效的算法来判断 m x n 矩阵中,是否存在一个目标值。该矩阵具有如下特性:
每行中的整数从左到右按升序排列。 每行的第一个整数大于前一行的最后一个整数。
思路
先判断在哪一行之后在这一行内进行查找
代码
var searchMatrix = function(matrix, target) {
let m = matrix.length;
let n = matrix[0].length
for(let i = 0; i < m; i++) {
if( matrix[i][n-1] >= target && target >= matrix[i][0] ) {
console.log(i)
for(let j = 0; j < n; j++) {
if(matrix[i][j] === target) {
return true;
}
}
return false
}
}
return false
};