力扣刷题记录
01二分查找
力扣链接
几个注意点
- 1.设置三个变量,【left,right】区间的左右值,以及区间中点middle;
- 2.注意左闭右闭与左闭右开对几个变量的影响
- 3.返回-1是在while循环结束还未找到target值时执行的,因此在while循环结束之后执行的
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while(left <= right){
int middle = (left + right)/2;
if(target < nums[middle]){
right = middle -1;
}
else if(target > nums[middle]){
left = middle +1;
}
else{
return middle;
}
}
return -1;
}
};
02利用二分查找搜索插入位置
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
while(left <= right){
int middle = (left + right)/2;
if(target < nums[middle]){
right = middle - 1;
}
else if(target > nums[middle]){
left = middle + 1;
}
else if(target == nums[middle]){
return middle;
}
}
return right + 1;
}
};
- 注意最后的return right + 1 为什么要+1,因为设置的循环条件是left <= right,所以最后一个循环时left与right值相同,会再执行一次right = middle - 1;语句
- 只要看到面试题里给出的数组是有序数组,都可以考虑使用二分法。最好是无重复的数组,因为重复数组二分法返回数值不唯一
03查找数组中一个元素的第一个位置和最后一个位置(二分法)
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.empty()) return {-1,-1};
int l = 0, r = nums.size() - 1; //二分范围
while( l < r) //查找元素的开始位置
{
int mid = (l + r )/2;
if(nums[mid] >= target) r = mid;
else l = mid + 1;
}
if( nums[r] != target) return {-1,-1}; //查找失败
int L = r;
l = 0, r = nums.size() - 1; //二分范围
while( l < r) //查找元素的结束位置
{
int mid = (l + r + 1)/2;
if(nums[mid] <= target ) l = mid;
else r = mid - 1;
}
return {L,r};
}
};
细节太多,做吐了
04移除元素
力扣链接
暴力法:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
for (int i = 0; i < size; i++) {
if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
size--; // 此时数组的大小-1
}
}
return size;
}
};
- 需要注意的是如果按下文编写,比如数组十个元素,l = i = 9时,nums[9] = nums[10];显然越位了。(朝哥,你就是我的神!)
for (int l = i; l < len; l++){
nums[l] = nums[l + 1];
}
双指针法:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
if (val != nums[fastIndex]) {
nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
};
- i++是先取i的值再+1,如a=i++是先进行a=i的赋值操作,然后i+1
- ++i则相反,先进行i+1然后再取i的值
i++与++i区别

浙公网安备 33010602011771号