给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 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
按照二分法思路列举示例归纳规律:[1,3,5,6]
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int index = -1;
int begin = 0, end = nums.size() - 1;
while (index == -1) {
int mid = (begin + end) >> 1;
if (target == nums[mid]) index = mid;
else if (target < nums[mid]) {
if (mid == 0 || target > nums[mid-1]) {
index = mid;
}
end = mid - 1;
}
else if (target > nums[mid]){
if (mid == nums.size()-1 || target < nums[mid+1]) {
index = mid + 1;
}
begin = mid + 1;
}
}
return index;
}
};
小节:二分查找的实质就是不断更新mid,然后来锁定要找的target,本题同样也是这样,不过不同的是本题还需要对mid周围的值施加限制:target只能是出现在mid的左/右两边,或者是出现在左右边界。
这个对mid周围值施加限制条件的思想,还会在下一题中应用的到。
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O ( l o g n ) O(log n) O(logn) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
分析:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> ans;
ans.push_back(left_bound(nums, target));
ans.push_back(right_bound(nums, target));
return ans;
}
int left_bound(vector<int>& nums, int target) {
int begin = 0;
int end = nums.size()-1;
while (begin <= end) {
int mid = (begin+end)>>1;
if (target == nums[mid]) {
if (mid == 0 || target > nums[mid-1]) {
return mid;
}
end = mid - 1;
}
else if (target < nums[mid]) {
end = mid - 1;
}
else if (target > nums[mid]) {
begin = mid + 1;
}
}
return -1;
}
int right_bound(vector<int>& nums, int target) {
int begin = 0;
int end = nums.size()-1;
while (begin <= end) {
int mid = (begin+end)>>1;
if (target == nums[mid]) {
if (mid == nums.size()-1 || target < nums[mid+1]) {
return mid;
}
begin = mid + 1;
}
else if (target < nums[mid]) {
end = mid - 1;
}
else if (target > nums[mid]) {
begin = mid + 1;
}
}
return -1;
}
};
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。
示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4
示例 2:
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1
分析:同样还是需要思考+举例
class Solution {
public:
int search(vector<int>& nums, int target) {
int begin = 0;
int end = nums.size()-1;
while (begin <= end) {
int mid = (begin + end)>>1;
if (target == nums[mid]) return mid;
else if (nums[0] <= nums[mid]) {
if (nums[begin] <= target && target <= nums[mid]) {
end = mid - 1;
}
else {
begin = mid + 1;
}
}
else if (nums[mid] <= nums[end]) {
if (nums[mid] <= target && target <= nums[end]) {
begin = mid + 1;
}
else {
end = mid - 1;
}
}
}
return -1;
}
};
https://leetcode-cn.com/problems/search-insert-position/ ↩︎
https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/ ↩︎
https://www.bilibili.com/video/BV1GW411Q77S?p=6 ↩︎ ↩︎ ↩︎
https://leetcode-cn.com/problems/search-in-rotated-sorted-array/ ↩︎