双指针在O(1)的时间内原地移除元素
核心思想:保证一个区间[0,left)或者[0,left]的元素满足题意,从0变大,直到快指针到头
leetcode-26. 删除有序数组中的重复项

思路:线性时间删除重复元素,left,right从0开始索引
- left慢指针,表示[0,left]都是不重复的元素
- 如果碰到下一个不相等的元素,left++,nums[left]=nums[right],可以保证slow是之后的第一个不相等的元素。解释:如果right和right+1是相等的,判断nums[left]!=nums[right]就是false,right就继续往后走。
核心:left保存后面的第一个之前未出现的元素,有因为是有序的,则可以保证right后面重复的元素不被保存。
返回的时候,要返回left+1,因为left是最后一个元素的坐标,而范围是[0.left],则返回left+1。
关键点:[0,left]保证不重复;right往后走,如果碰见不重复的放入这个区间;最后返回left+1
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size()==0) return 0;
int left=0,right=0;
while(right<nums.size()){
if(nums[left]!=nums[right]){
left++;
nums[left]=nums[right];
}
right++;
}
return left+1;
}
};
leetcode-83. 删除排序链表中的重复元素

思路:同删除数组元素,也可以直接删除节点
代码:
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if(!head) return head;
ListNode *pre=head,*post=head;
while(post!=NULL){
if(post->val!=pre->val){
pre=pre->next;
pre->val=post->val;
}
post=post->next;
}
pre->next=NULL;
ListNode* temp=pre->next;
while(temp!=NULL){
ListNode* t=temp->next;
delete temp;
temp=t;
}
return head;
}
};
leetcode-27. 移除元素

思路:保证[0,left)的元素不是val,right往后走,如果碰见不是val的就添加进去
代码:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
if(nums.size()==0) return 0;
int left=0,right=0;
while(right<nums.size()){
if(nums[right]!=val){
nums[left]=nums[right];
left++;
}
right++;
}
return left;
}
};
leetcode-283. 移动零

思路:相当于把0的元素删除,最后的位置补0。
即保证[0,left)的元素不为0,right到头后,给剩余的元素改为0
代码:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int left=0,right=0;
while(right<nums.size()){
if(nums[right]!=0){
nums[left]=nums[right];
left++;
}
right++;
}
while(left<nums.size())
nums[left++]=0;
}
};
版权声明:本文为woaiwojia6699原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。