Leetcode 704. 二分查找
初见想法:之前做过,注意lo和hi的取值
左闭右闭解法:
class Solution {
public:
int search(vector<int>& nums, int target) {
int lo = 0, hi = nums.size()-1;
while (lo <= hi)
{
// 注意mid不能直接等于(lo+hi)/2,int类型可能会越界,这样写能保证mid <= hi
int mid = lo + (hi-lo)/2;
// 先判断 < 和 >,大概率不会先直接相等
if (target < nums[mid]) hi = mid-1;
else if (target > nums[mid]) lo = mid+1;
else return mid;
}
// 没有搜索到,返回-1
return -1;
}
};
使用while循环不断缩小搜索区间,每次搜索范围为闭区间,因此可能出现lo == hi的情况,所以while的循环条件为lo <= hi,结束时lo = hi+1。
lo的初始值为0, 而hi的初始值为nums.size()-1,因为搜索时会到nums.size()-1。
左闭右开解法:
class Solution {
public:
int search(vector<int>& nums, int target) {
int lo = 0, hi = nums.size();
// 搜索区间:左闭右开, 相等时无意义, eg. [1,1)
while (lo < hi)
{
int mid = lo + ((hi-lo) >> 1);
// 虽然targert < nums[mid],表示target不等于nusm[mid],
// 循环的搜索区间不会到达mid,所以hi = mid
if (target < nums[mid]) hi = mid;
// 搜索区间为左闭右开
else if (target > nums[mid]) lo = mid+1;
else return mid;
}
return -1;
}
};
整个nums被拆分为[lo, hi),mid,[lo,hi)这样的区间
只有当lo < hi才会循环,一旦lo == hi就会停止循环
while循环的判断条件和mid是否需要+1或者-1对应
Leetcode 27. 移除元素
初见想法:for循环暴力搜索,检测到对应元素就依次复制后面的
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int cnt = 0;
while (cnt != nums.size())
{
if (nums[cnt] == val)
{
for (int j = cnt+1; j < nums.size(); j++)
{
nums[j-1] = nums[j];
}
nums.pop_back();
}
else
{
cnt++;
}
}
return nums.size();
}
};
双指针法:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int j = 0, sz = nums.size();
for (int i = 0; i < sz; i++)
{
if (nums[i] != val)
{
swap(nums[i], nums[j++]);
}
}
return j;
}
};
两个指针,慢指针用来保存数据,快指针用来遍历原数组
swap的过程就是在记录不是val的值,遇到val,快指针就直接跳过去,不交换