刷题专练之数组移除元素
文章目录
- 前言
- 一、移除元素
- 1.题目介绍
- 2.思路:
- 3.代码
- 二、移动零
- 1.题目介绍
- 2.思路
- 3.代码
- 三、删除有序数组中的重复项
- 1.题目介绍
- 2.思想
- 3.代码
- 四、80. 删除有序数组中的重复项 II
- 1.题目介绍
- 2.思路
- 3.代码
- 4.推荐题解
前言
我每个刷题篇的题目顺序都是特别安排的,目的是循序渐进,以到彻底掌握此类方法,主要分享算法,对于暴力求解的解法不会写,本文章即用的是双指针
一、移除元素
1.题目介绍
对应的是力扣的27.移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
2.思路:
我们用快慢指针,快指针向后找不等于val的数(即新数组所需要的值),将其赋给慢指针所在的值,这样子当fast遍历完之后,我们就将不等于val的所有数全部搬到前面了
3.代码
int removeElement(int* nums, int numsSize, int val){
int slow =0;
int fast=0;
if(numsSize==0)
{
return 0;
}
while(fast<numsSize)
{
if(nums[fast]!=val)
{
nums[slow++]=nums[fast];
}
fast++;
}
return slow;
}
二、移动零
1.题目介绍
题目对应力扣26. 删除有序数组中的重复项
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
2.思路
有了前面一题的思路打了基础后,这题基本就和容易就做出来了,我们就可以吧0当成val,让fast找不等于val的值,然后赋给slow所在值,最后将slow以后的值都赋0就行
3.代码
void moveZeroes(int* nums, int numsSize){
int slow=0;
int fast=0;
while(fast<numsSize)
{
if(nums[fast]!=0)
{
nums[slow++]=nums[fast];
}
fast++;
}
for(int i=slow;i<numsSize;i++)
{
nums[i]=0;
}
}
三、删除有序数组中的重复项
1.题目介绍
2.思想
我们定义一个slow和fast,只有fast不等于slow就可以将fast覆盖给slow+1,我们就保留了一个slow
3.代码
int removeDuplicates(int* nums, int numsSize){
int slow=0;
int fast=0;//这里可以=1,因为第一个始终是会保留的
while(fast<numsSize)
{
if(nums[fast]!=nums[slow])
{
nums[slow+1]=nums[fast];
slow++;
}
fast++;
}
return slow+1;
}
四、80. 删除有序数组中的重复项 II
1.题目介绍
这题就是检验你是否对于上一题理解是否深刻,题目对应力扣80. 删除有序数组中的重复项 II
2.思路
双指针移除法虽然是原地操作的算法,但是我们移除元素不就是从待处理的数组里面重新构造出我们所需要的数组,所以这题需要我们有这样子的思想,我们才能理解这种方法,这题需要保留使得出现次数超过两次的元素只出现两次 ,那么我们就需要将处理的数组与我们需要构造的的数组的前两个比较,只有不一样的才能赋给slow
3.代码
int removeDuplicates(int* nums, int numsSize) {
if (numsSize <= 2) {
return numsSize;
}
int slow = 2, fast = 2;
while (fast < numsSize) {
if (nums[slow - 2] != nums[fast]) {
nums[slow] = nums[fast];
++slow;
}
++fast;
}
return slow;
}
4.推荐题解
该题解的解析配合我的解析更加清晰