【图文详解】经典题目——移除重复元素

经典题目:移除重复元素

1.原地删除值=val的元素

题目描述:
点击跳转到Leetcode----移除元素
题目描述

  如果不考虑空间复杂度,可以用拷贝新数组的方法:
在这里插入图片描述
  用src指针挨个遍历数组元素,如果数组元素不等于val,就把下标为src的元素拷贝到新数组中,然后为了储存下一个不等于val的数,新数组中的dst++。

  最后把弄好的新数组拷贝回去,毕竟是要改变原来的数组。

  拷贝结束的新数组中,dst的下标就是新数组的长度。

动态图示:

在这里插入图片描述

  但这种方法的空间效率比较低,需要开辟新的空间,空间复杂度为O(N),不符合这道题的要求。

  开辟新数组的方法实质上是通过指针异地拷贝,既然可以异地拷贝,那么大概率也可以原地拷贝,换汤不换药,原地拷贝的思路是一样的。
在这里插入图片描述
原地拷贝:

  动态图示:
在这里插入图片描述

  类比上面新数组的方法,用src指针挨个遍历数组元素,如果数组元素不等于val,就把下标为src的元素拷贝到下标为dst的位置上,然后为了存下一个不等于val的数,dst++

  优化后的空间复杂度为O(1),时间复杂度为O(N)。

代码:

int removeElement(int* nums,int numsSize,int val){
	int src=0;
	int dst=0;
	while(src < numSize){
		if(nums[src]!=val){
			nums[dst++] = nums[src++];
		}
		else
		{
			src++;	
		}	
	}
	return dst;
}

2.删除有序数组中的重复项

题目描述
点击跳转到Leetcode----删除有序数组中的重复项
在这里插入图片描述

  类似的,只不过这道题的比较标准不是固定的一个"val"而是一个变化的数了,初始位置src在下标1,dst在下标0,初始时将两个指针指向的位置错开,才能保证src和dst能前后比较。

  新数组的长度是dst+1。

动态图示:

在这里插入图片描述

代码:

int removeDuplicates(int* nums, int numsSize){
    int src=1;
    int dst=0;
    while(src < numsSize){
        if(nums[src] != nums[dst]){
            nums[++dst]=nums[src];
        }
        src++;
    }
    return dst+1; 
    } 
   

总结

  以上题目的算法可以说是由开辟新数组的算法优化来的,我们由开辟新数组的过程优化出了空间复杂度更低的算法,通过了题目。
  如果一开始碍于题目的种种限制,比如空间复杂度、时间复杂度等要求,而一时想不出来思路,可以先忽视题目要求,使用常规的、普通的方法解题,然后进行类比,或许就能开发出效率更高的且符合题目要求的算法。

本文结束。
                (如果文章有错误之处,请在评论区点醒作者,谢谢!)

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嫋嫋.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值