方法一:双指针法
class Solution
{
public:
int removeElement(vector<int>& nums, int val)
{
int len = nums.size();
if (len == 0) return 0;
int slow = 0;
int fast = 0;
while (fast < len)
{
if (nums[fast] != val)
{
nums[slow++] = nums[fast++];
}
else
{
++fast;
}
}
return slow;
}
};
int main()
{
Solution A;
vector<int> vec{ 0,1,2,2,3,0,4,2 };
cout<<A.removeElement(std::ref(vec), 2) << endl;
return 0;
}
时间复杂度:O(n),其中 n 为序列的长度。我们只需要遍历该序列至多两次
空间复杂度:O(1),我们只需要常数的空间保存若干变量
方法二:双指针法优化
如果要移除的元素恰好在数组的开头,例如序列 [1,2,3,4,5],当 val 为 1 时,我们需要把每一个元素都左移一位。注意到题目中说:「元素的顺序可以改变」。实际上我们可以直接将最后一个元素 5 移动到序列开头,取代元素 1,得到序列 [5,2,3,4],同样满足题目要求。这个优化在序列中 val 元素的数量较少时非常有效
class Solution
{
public:
int removeElement(vector<int>& nums, int val)
{
int len = nums.size();
if (len == 0) return 0;
int slow = 0;
int fast = len - 1;
while (slow <= fast)
{
if (nums[slow] == val)
{
nums[slow] = nums[fast];
--fast;
}
else
{
++slow;
}
}
return slow;
}
};
int main()
{
Solution A;
vector<int> vec{ 1,2,2,3,1 };
cout<<A.removeElement(std::ref(vec), 1) << endl;
return 0;
}
时间复杂度:O(n),其中 n 为序列的长度。我们只需要遍历该序列至多一次
空间复杂度:O(1),我们只需要常数的空间保存若干变量