咱们先来看题目,题目如下
题目如上,例如一个数组里面存放的数据为 3 2 2 3,给你一个指定的val值(例如为3),那么经过这一移除数组的操作后,我们的新数组就会变成 2 2 …后面的元素是什么不用管,并且返回原数组除了val值后的元素个数,例如原数组中有4个元素,val为3,那么经过程序运行后,返回2,也就是 2 2里面非val值的元素个数。
这里咱们教授大家一个重要的算法思想,那就是:双指针法。
(1)定义两个指针
两个指针均指向我们数组的首元素,例如下图
(2)一个探路,一个在原始地段当哨兵
让src指针在前面探路,如果src指向的数组元素不是val值,那就赋值给dst指针指向的元素,如果是val就跳过去找后面的
什么意思呢?我们目的是让非val值的元素排在前面,所以数组元素中为val的排到后面去
给大家两张图,方便了解
src指针指向的是val值,所以跳过(val值就是我们想要删除的值)
然后把src指针指向的值(已经确定不是等于val值的了,应该如果src指向的值是val值,那我们就自动让他跳过),赋值给哨兵dst,为什么要让dst从0开始就是这样,从前往后把我们想要的值赋值给原数组里的值。
注意,src赋值给dst后,src和dst指针都要向后++。src++的原因:src要继续向后判断看哪个元素不等于val,然后赋值给dst指向的元素;dst++的原因:新数组需要从前向后覆盖原先的值,所以有不是val值的元素给dst后,dst都要++,以便覆盖下一个原数组的元素
由图可知,src指向的元素依然不是val值,所以依旧赋值给dst指向的元素,然后双指针同时++
tips:如果当时src指向的元素不是val值,那么src向后++以寻找非val的值,而dst指针无需++,因为它需要的是非val的值)
由上图可知,src指针指向了val的值,所以src++跳过,而跳过之后,来到了数组外面,自此,遍历结束,我们的程序到这也就进行完了,而我们也需要返回2。
接下来我们,上代码,实操一下
int removeElemment(int nums,int numsSize,int val)//nums:数组名,numsSize:数组元素个数,val:要删除的值
{
int dst = 0;
int src = 0;
while(src<numsSize)//src肯定先到达终点,src指向数组外面的时候,遍历结束
{
if(nums[src] != val)//如果src指向的值不等于val,那就赋值给dst
{
nums[dst] = nums[src];//完成赋值
dst++;//赋值后dst需要加加,以方便存放下一个非val值的元素
}
src++;//无论src遇到的是否为val值,我们都需要对src进行++,所以我们把src++放到if循环外面,每次都会++
}
return dst;//返回的dst正是非val值的个数,你就说巧不巧秒
}
return dst刚好就是非val值的元素个数
本次博客到此结束,有疑问的可以咨询博主,博主免费为大家解决疑惑。