leetcode刷题——数组篇(二)
本文已参与[新人创作礼]活动,一起开启掘金创作之路
数组篇(二)
参考解法来源——代码随想录
leetcode27——27. 移除元素
自己思路
对于题目要求——
- 对数组删除指定的整数
- 输出删除后的数组长度
- 输出删除后的数组
- 只能使用O(1)的额外空间
- 只能原地处理数组
错误代码:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int i;
int x;
for(i = 0 ;i < nums.size(); i++){
if (nums[i] == val){
auto x = nums.erase(nums.begin()+i);
}
}
cout << "" << nums.size()<<endl;
for (i = 0; i < nums.size(); i++){
cout << nums[i] <<"";
}
return nums.size();
}
};
我原本想的是利用vector 的erase函数来删除该数组中的目标数字,结果在([0,1,2,2,3,0,4,2] 2)出错,究其原因,
非常惊艳:!!!!!
思路没有问题,但最重要的是——没有考虑到再erase进行删除时,for循环中的i实际上在新的数组中是i+1,因此在if的条件中应该加上一条——“i--”
于是——————就成功了!!!!!
附上代码:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int i;
int x;
for(i = 0 ;i < nums.size(); i++){
if (nums[i] == val){
auto x = nums.erase(nums.begin()+i);
i --;//此处是关键
}
}
cout << "" << nums.size()<<endl;
for (i = 0; i < nums.size(); i++){
cout << nums[i] <<"";
}
return nums.size();
}
};
随想录思路
-
就是暴力解法,他是自己用两个for循环完成的
(一个for循环遍历数组元素 ,第二个for循环更新数组)
采用数组的直接覆盖
// 时间复杂度:O(n^2) // 空间复杂度:O(1) 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; } };- 最受欢迎的双指针法(快慢指针法):
通过一个快指针和慢指针在一个for循环下完成两个for循环的工作
常用于数组和链表
// 时间复杂度:O(n) // 空间复杂度:O(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; } };分析:也是先分成三个情况:
- 目标有元素在数组开头
- 目标元素都在数组中间
- 目标有元素在数组尾端
该双指针法的主要思想是将输出的数组全放在slowindex里,
- 如果右指针指向的元素不等于val,它一定是输出数组的一个元素,我们就将右指针指向的元素复制到左指针位置,然后将左右指针同时右移;
- 如果右指针指向的元素等于 val,它不能在输出数组里,此时左指针不动,右指针右移一位。
- 区间 [0,left) 中的元素都不等于 val。当左右指针遍历完输入数组以后,left 的值就是输出数组的长度。
衍生题目
26、删除有序数组中的重复项
283、移动零
844. 比较含退格的字符串
977. 有序数组的平方
总结:
- 数组题目默认是不能调换数组的顺序的
- 在数组题目的增删改查加入循环时要密切注意i,j等标记点的变化
- 明白了双指针的用法——对数组和链表的操作有帮助。

浙公网安备 33010602011771号