提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
LeetCode:27.移除元素
思路:
数组是一片连续的内存,无法从中删除元素,只能通过覆盖方式。
一、暴力解法
可以利用两层for循环:
- 第一层for循环用来遍历数组
- 第二层for循环用来更新数组
代码如下:
class solution{
public:
int removeElement(vector<int> &nums,int val){
int size = nums.size();
for(int i = 0; i < size; i++)
{
if(val == nums[i])
{
for(int j = i; j < size-1; j++)
{
nums[j] = nums[j+1];
}
/*这里必须i--,不然实际会产生两次i++,
一次for循环里的i++,一次从后往前元素覆盖后的i++*/
i--;
size--;
}
}
return size;
}
};
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
二、双指针法
双指针法:通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针:
- 慢指针:用来指向等于val的元素
- 快指针:用来寻找非val的元素
代码如下:
class solution{
public:
int removeElement(vector<int> &nums,int val){
int slow = 0;//慢指针:用来指向等于val的元素
int fast = 0;//快指针:用来寻找非val的元素
for(fast = 0; fast < nums.size(); fast++){
if(val != nums[fast]){
nums[slow++] = nums[fast];
}
}
return slow;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(1)
总结
双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组、链表、字符串等操作的面试题,都使用双指针法。