1.1整数二分
//性质1将数组分为 <= target 的部分
//寻找满足性质1数组的后一个元素
//[1,2,8,8,9,10]
//分割后数组[1,2,8,8,|9,10]
//左边的数组满足性质
//本质为返回满足 <= target 的部分数组中的最后一个元素
//找到 index = 3 的8
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
//性质2 将数组分为 >=target 的部分
//寻找满足性质2数组的第一个元素
//[1,2,8,8,9,10]
//分割后数组[1,2,|8,8,9,10]
//右边的数组满足性质
//本质为返回满足 >= target 的部分数组中的第一个元素
//找到 index = 2 的8
int bsearch_2(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1; // + 1防止infinite loop
if (check(mid)) l = mid;
else r = mid - 1;
}
return l;
}
更加详细的话: 这篇博客将模板讲解的非常好
基于二段性的二分查找,五分钟学会并且最好用的模板(出自Acwing创始人yxc),内附leetcode经典例题讲解 - 知乎
这样的模板总能在循环结束后找到一个数字,要判断是否为target。
1.2. 单用模板其中一个模板也可以找没有重复target的情况
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
// ML
int BS(int l, int r, vector<int>& nums, int target){
while(l < r){
int mid = (1 + r + l)/2;
if(nums[mid] <= target) l = mid;
else r = mid - 1;
}
if(nums[l] == target) return l;
else return -1;
}
int search(vector<int>& nums, int target) {
int index = BS(0, nums.size() - 1, nums, target);
return index;
}
};
2. 双指针删除元素
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
--思路:
用slow index 指向当前元素放入地方;
fast index 指向需要的元素,遇到要被删除的就跳过,把需要的元素放到slow index指向的地方
双指针 将暴力的O(n^2)变成了只要遍历一边
确定哪个指针是要遍历的
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];
}
//循环结束后 slow + 1
return slow;
}
};