题目:
思路:
题目要求原地移除nums中数值等于val的值,返回数组的新长度,那么我们的任务就是边移除边计算移除了几个元素即可。
为了一次性连续移除元素,可以先排个序,再遍历执行。
因为要原地修改,所以就想到了vector的pop_back()可以删除最后一个元素,但是这样的话就要把所有要移除的元素放在末尾。vector还有一个函数是erase(),能够删除vector容器中的元素,通识容器的size减一。
题解:
法一:
- 遍历数组nums
- 如果该元素与指定元素val相等,则调用erase()函数移除
- 遍历结束后,重新计算容器的size,和之前的size相减得到移除了几个元素
法二:
-
采用双指针,一个慢一个快,边移动边交换,能够保证原地修改
-
起始时,两个指针一起移动,直到找到需要移除的元素。
-
每找到一个目标,慢指针滞后一次,交换快指针和慢指针所指元素
-
快指针和慢指针同时移动(快指针比慢指针快n个位置,n为找到的目标个数),边移动边交换,直到快指针指到容器末尾
-
注意题目中这句话,我们可以直接返回慢指针位置,忽略后面的元素。
代码:
法一:调用vector的erase()函数
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int s1 = nums.size();
for (int i = 0; i < nums.size(); i++) {
if (nums[i] == val) {
//cout << i << endl;
nums.erase(nums.begin() + i);
i--;
}
}
int s2 = nums.size();
int n = s1 - s2;
return 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];
slow++;
}
}
return slow;
}
};
Debug过程:
法一:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int s1 = nums.size();
for (int i = 0; i < s1; i++) {
if (nums[i] == val) {
nums.erase(nums.begin() + i);
}
}
int s2 = nums.size();
int n = s2 - s1;
return n;
}
};
vector subscript out of range 数组下标越界,是因为for循环有问题。把vector的赋值改为push_back,循环改为for (int i = 0; i < nums.size(); i++)
,问题解决。如下:
vector<int> nums;
nums.push_back(0);
nums.push_back(1);
nums.push_back(2);
nums.push_back(2);
nums.push_back(3);
nums.push_back(0);
nums.push_back(4);
nums.push_back(2);
for (int i = 0; i < nums.size(); i++)
不知道为什么力扣上过不不去,vs上运行是对的。。后面再来更新
法二:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int fast = 0;
int slow = 0;
for (int i = 0; fast < nums.size(); i++) {
if (nums[i] == val) {
fast++;
}
swap(nums[fast], nums[slow]);
fast++;
slow++;
}
return slow;
}
};
return 0;
第一次写成了swap
,答案错误,然后改成赋值
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int fast = 0;
int slow = 0;
for (int i = 0; fast < nums.size(); i++) {
if (nums[i] == val) {
fast++;
}
nums[slow] = nums[fast];
fast++;
slow++;
}
return slow;
}
};
发现还是错误,因为不能把循环i
,而是应该把fast
当作i
来循环,于是改为最终代码,通过。
优化:
暂无