27. 移除元素
1.快慢指针
-
和26. 删除有序数组中的重复项中的技巧一样,我们仍然可以用一快一慢两个指针来完成这个任务,快指针遍历元素,慢指针指向保存元素的位置。
-
还有同样应用快慢指针的场景,可以一起完成:
-
移除元素:26. 删除有序数组中的重复项
-
判断链表中是否有环:141. 环形链表
题解:141. 环形链表题解
-
判断链表是否是回文链表:234. 回文链表
-
移除元素:27. 移除元素
-
-
最坏情况下,快慢两个指针都完整的遍历了数组,共遍历了两次。(我们能否至多一次遍历就完成?)
class Solution { public: int removeElement(vector<int>& nums, int val) { int slow=0,fast=0; for(;fast<nums.size();fast++){ if(nums[fast]!=val){ nums[slow++]=nums[fast]; } } return slow; } };
2.快慢指针优化
-
这是官方题解中给出的非常巧妙的优化方式:题目只要求数组前N个元素没有目标值即可,并不要求顺序。
-
因此我们两个指针分别指向首尾,左指针不断向右遍历:
- 如果遇到了val,就把右指针指向的位置的元素放到左指针处覆盖val,并且右指针左移。
- 没有遇到val,左指针右移,知道两指针相遇。
-
这样就在左指针扫描过的范围里确保了没有val的存在,并且两个指针加起来只遍历了一次。
class Solution { public: int removeElement(vector<int>& nums, int val) { int left=0,right=nums.size()-1; while(left<=right){ if(nums[left]!=val){ left++; }else{ nums[left]=nums[right]; right--; } } return left; } };