今天是刷题打卡第一天,可能博客还不是很会写。
27题链接https://leetcode.cn/problems/remove-element/submissions/
因为数组在内存中是一段连续的空间,所以我们不能直接删除数组中的某个元素
首先我们可以暴力用两个循环写出来:
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];
}
len--;
i--;
}
}
return len;
}
};
这样的话,时间复杂度是O(n2),所以我们能不能用巧妙一点的方法?
C++中有一个函数erase,可以通过整体替换的原理达到O(n)的时间复杂度
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)
{
nums.erase(nums.begin()+i);
size--;
i--;
}
}
return nums.size();
}
};
最后是双指针算法,复杂度也是0(n),感觉真的非常神奇。
用一个快指针表示要留下的数,进行更新
一个慢指针表示新数组下标
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int fast = 0;
int slow = 0;
for(fast; fast<nums.size(); fast++){
if(nums[fast] != val){
nums[slow++] = nums[fast];
}
}
return slow;
}
};
704题链接https://leetcode.cn/problems/binary-search/
这是一个很经典的二分,做过很多次了
先是一个我之前的写法:
class Solution {
public:
int search(vector<int>& nums, int target) {
int l=-1,r=nums.size();
while(l+1!=r){
int mid=(l+r)>>1;
if(nums[mid]>=target)r=mid;
else l=mid;
}
if(r==nums.size())return -1;
else if(nums[r]!=target) return -1;
else return r;
}
};
看了讲解后,注意到题目是一个左闭右闭区间
class Solution {
public:
int search(vector<int>& nums, int target) {
int l = 0, r = nums.size()-1;
while(l<=r){
int mid = (l+r)/2;
if(nums[mid] > target){
r = mid-1;
}else if(nums[mid] < target){
l = mid+1;
}else {
return mid;
}
}
return -1;
}
};