704 二分查找
题目链接:https://leetcode.cn/problems/binary-search/
文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715
适用条件
- 有序数组
- 无重复元素
定义搜索区间(后面所有内容都由这个定义决定)
while (left <= right)
这个意味着实际的区间是[left, right],因为此时left == right 是有意义的,是数组中的值。因此在if (nums[middle] > target) 时,right = middle - 1。
while (left < right)
这个意味着实际的区间是[left,right)。同理,right = middle。
class Solution {
public:
int search(vector<int>& nums, int target) {
#if 0
//[]
int left = 0, right = nums.size() - 1;
int mid = (left + right) / 2;
while(left <= right) {
mid = (left + right) / 2;
if (target == nums[mid]) {
return mid;
}
else if (target > nums[mid]) {
left = mid + 1;
}
else
right = mid - 1;
}
return -1;
#endif
//[)
int left = 0, right = nums.size();
int mid = (left + right) / 2;
while (left < right) {
mid = (left + right) / 2;
if (target == nums[mid]) {
return mid;
}
else if (target > nums[mid]) {
left = mid + 1;
}
else
right = mid;
}
return -1;
}
};
27 移除元素
其实是实现vector容器中的erase方法。这个方法的时间复杂度其实是O(n)。
使用双指针的思想
要理解双指针也就是快慢指针分别对应的含义。
- 快指针:指向新数组所需要的元素。也就是说遇到要删除的元素,就跳过。
- 慢指针:指向新数组的插入下标。当快指针找到新数组所需元素时,慢指针要插入这个元素,并+1指向下一个。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
#if 0
//brute-force
int count = nums.size();
for (int i = 0; i < count; ++i) {
if (nums[i] == val) {
for (int j = i + 1; j < count; ++j) {
nums[j - 1] = nums[j];
}
i--;
count--;
}
}
return count;
#endif
int left = 0, right = 0;
while (right < nums.size()) {
if (nums[right] != val)
nums[left++] = nums[right];
right++;
}
return left;
}
};