代码随想录算法训练营 Day1
- 知识点:
- 数组基础
- 二分查找
- 双指针
704. 二分查找
- 思路:二分
- 模板:
acwing的模板比较好记
整数二分的本质是——找区间内定义的某种性质,该性质可以将区间一分为二,二分法可以找这两个区间的边界。
模板1:二分出左区间,右边界点, l=mid,满足性质的在左区间
bool check(int x) {/* ... */} // 检查x是否满足某种性质
// 向下取整,区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
int bsearch_1(int l, int r)
{
while (l < r)
{
**int mid = l + r + 1 >> 1;**
if (check(mid)) l = mid;
else r = mid - 1;
}
return l;
}
模板2:二分出右区间,左边界点, r=mid,满足性质的元素在右区间
bool check(int x) {/* ... */} // 检查x是否满足某种性质
// 向上取整,区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_2(int l, int r)
{
while (l < r)
{
**int mid = l + r >> 1;**
if (check(mid)) r = mid; // check()判断mid是否满足性质
else l = mid + 1;
}
return l;
}
记法:左区间左闭右闭补上加1
- 答案:
class Solution {
public:
int search(vector<int>& nums, int target) {
int l = 0, r = nums.size()-1;
while (l < r) {
int mid = l + r + 1>> 1;
if (nums[mid] <= target) l = mid;
else r = mid - 1;
}
if (nums[l]==target) return l;
return -1;
}
};
[TODO]相关题目:
35.搜索插入位置
34. 在排序数组中查找元素的第一个和最后一个位置
27. 移除元素
-
解法:
1.暴力法
2.双指针 -
暴力法:
-
过程:
1. 外层循环遍历元素,判断是否等于val
2. 内层循环覆盖等于val的元素到新数组的最后一个元素 -
关键:变量是数组的长度,如何找到数组长度的变化规律
1. 每找到一个等于val的元素,后面的元素就往前补一位→len-1
2. 同时对应的i值也要往前挪一位到覆盖i的元素那里
-
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int len = nums.size();
for (int i = 0; i < len; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < len; j++)
nums[j-1] = nums[j];
i--;
len--;
}
}
return len;
}
};
- 双指针:
思路:快慢指针,快指针判断是不是等于val,慢指针覆盖,直接把不等于val的值往前挪。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slow = 0;
for (int fast = 0; fast < nums.size(); fast++) {
if (nums[fast] != val)
nums[slow++] = nums[fast];
}
return slow;
}
};