02. 移除元素
移除元素
LeetCode链接
解题思路
1.利用函数api(暴力)
解题思路
- 利用迭代器遍历数组
- 等于val,就调用 erase 函数删除元素;反之,迭代器后移
- 最后利用 size 函数返回元素个数
代码流程
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
//遍历
for(vector<int>::iterator it = nums.begin(); it != nums.end();){
if(*it == val){
nums.erase(it); //删除
}else{
it++; //指针后移
}
}
return nums.size();
}
};
复杂度分析
时间复杂度:O(log(n))
空间复杂度:O(1)
2.双指针
解题思路
- 利用不需要考虑返回值后数据的特性
- 使用两个指针,一个用于遍历数组(right),一个指向保存数据的索引(left)
- 当值不相等时,数据需要保留,将right指向的值赋值给left,left 和 right 指针后移;反之,right 指针后移
- 最终 left 的值为元素个数
代码流程
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int left = 0;
for(int right = 0; right < nums.size(); right++){ //遍历
if( val != nums[right]){ //元素需要保留
nums[left] = nums[right];
left++;
}
}
return left;
}
};
复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
3.双指针(优化)
解题思路
- 上一个方案最差情况我们需要遍历2次,我们可以将指针定义在数组头部和末尾,同时向中间移动,可以将遍历次数降低到1次
- 当left == val,将 right 指向的值复制到 left,并将 right 左移;反之 left 右移。知道 right < left 退出
- 此时 left 即为元素个数
代码流程
//双指针优化
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int left = 0;
int right = nums.size()-1;
//遍历
while(right >= left){
if(nums[left] == val){
nums[left] = nums[right]; //执行条件
right--;
}else{
left++;
}
}
return left;
}
};
复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
总结
此类题型有一个通用模板:
- 遍历
- 通过不同条件执行不同的操作,指针进行相应的移动
浙公网安备 33010602011771号