题目
思路
其实一开始的思路,是想数组中出现的元素,删掉不就好了嘛。
但是,要知道,C++中的数组中的元素是连续的,不能删除只能覆盖(不能跟python的列表混杂)。其实对于array类型的数组我们并没有删除操作,但是题中所给的vector容器是由erase操作的,但是通过代码实现发现vector容器并不能实现多次erase连续删除。
#include <iostream>
#include <vector>
using namespace std;
int main() {
int a[] = {3, 3, 2, 2}, val = 2;
vector<int> nums(a, a + 4);
for (int i = 0; i < 4; ++i) {
cout << a[i] << " ";
}
cout << endl;
nums.erase(nums.begin() + 2);
for (int i = 0; i < 3; ++i) {
cout << nums[i] << " ";
}
cout << endl;
nums.erase(nums.begin() + 1);
for (int i = 0; i < 3; ++i) {
cout << nums[i] << " ";
}
cout << endl;
}
结果是可以发现我们并不能连续的删除容器数组里面的数。
所以这题比较好的办法是快慢指针。让两个指针都在开头开始走,快指针遇到val的时候就跳过,没遇到val的时候就赋给下标left对应的数,这样就可以实现把所有的不是val数都移到前面,那么最后快指针遍历完后,慢指针对应的下标就是长度。
也可以使用左右指针。对于序列[1,2,3,4,5],如果val=1,即要找的值就在开头,如果用快慢指针就要所有的数进行左移。但是由于序列的顺序可以是打乱的,那么我们可以通过左右指针,将5移到开头,即可。
AC代码
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int len=nums.size();
int left=0;
for(int right=0;right<len;++right){
if(nums[right]!=val){
nums[left]=nums[right];
left++;
}
}
return left;
}
};
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int left=0,right=nums.size();//防止right=0
while(left<right){
if(nums[left]==val){
nums[left]=nums[right-1];
right--;
}else left++;
}
return left;
}
};