给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
首先可以按26题思路来(双指针)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
if (nums.empty())
return 0;
int pf = 0, pl = nums.size();
for (; p0 < pl; ++pmove)
{
if (nums[pmove] != val)
nums[p++] = nums[pmove];
}
return p;
}
};
但是这样可能会导致移动大量元素,题中说明可以改变元素顺序,就可以可以交换,所以遇到相同的,可以把末尾的交换到最前面。
第一个版本,没有考虑到最后一次交换后的情况,以及只有一个元素的情况。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
if (nums.empty())
return 0;
int pf = 0, pl = nums.size()-1;
for (; pf < pl;)
{
if (nums[pf] == val)
nums[pf] = nums[pl--];
else
++pf;
}
return pf+1;
}
};
解决方法:看下最后一个元素是不是val,是的话,长度为pf,不是则为pf+1
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
if (nums.empty())
return 0;
int pf = 0, pl = nums.size()-1;
for (; pf < pl;)
{
if (nums[pf] == val)
nums[pf] = nums[pl--];
else
++pf;
}
return nums[pf]==val?pf:pf+1;
}
};
看了下官方解法,相当巧妙,他是多检查了一次,因为初始pl为num.size(),做交换的也是pf和pl-1,所以可以检查到pl-1,最后返回的也是pl刚好等于长度。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
if (nums.empty())
return 0;
int pf = 0, pl = nums.size();
for (; pf < pl;)
{
if (nums[pf] == val)
{nums[pf] = nums[pl-1];
pl--;}
else
++pf;
}
return pl;
}
};