# 第80期-基础技巧:双指针 删除有序数组中的重复项
Python是一门需要不断实践练习的编程语言,本文档将AI大学堂学员交流群的Python每周练习进行汇总,希望各位小伙伴能够多进行实践练习,逐渐爱上这门神奇的编程语言,掌握它并在生活中能够使用它。
# 1 问题描述
给你一个有序数组 nums ,请你原地删除重复出现的元素,使每个元素只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
示例 1:
输入: nums = [1,1,2]
输出: 2, nums = [1,2]
解释: 函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:
输入: nums = [0,0,1,1,1,2,2,3,3,4]
输出: 5, nums = [0,1,2,3,4]
解释: 函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
初始代码
from typing import List
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
#在此之间填写代码
print(Solution().removeDuplicates([1,1,2]))
print(Solution().removeDuplicates([0,0,1,1,1,2,2,3,3,4]))
2
3
4
5
6
7
# 2 解题思路
- 标签:双指针
- 这道题目的要求是:对给定的有序数组 nums 删除重复元素,在删除重复元素之后,每个元素只出现一次,并返回新的长度,上述操作必须通过原地修改数组的方法,使用 O(1) 的空间复杂度完成。
- 由于给定的数组nums是有序的,因此对于任意 i<j,如果 nums[i]=nums[j],则对任意i≤k≤j,必有nums[i]=nums[k]=nums[j],即相等的元素在数组中的下标一定是连续的。利用数组有序的特点,可以通过双指针的方法删除重复元素。
# 3 解题方法
from typing import List
class Solution:
def removeDuplicates(self, nums: List[int]) -> int:
i,j=1,1
n=len(nums)
while i<n:
if nums[i]!=nums[i-1]:
nums[j]=nums[i]
j+=1
i+=1
print(nums[:j])
return j
print(Solution().removeDuplicates([1,1,2]))
print(Solution().removeDuplicates([0,0,1,1,1,2,2,3,3,4]))
2
3
4
5
6
7
8
9
10
11
12
13
14
15
第1-3,14-15行: 题目中已经给出的信息,运行代码时要根据这些代码进行编辑
第4行: 定义变量i,j分别赋值1,1,用于表示快慢指针
第5行: 定义变量n并赋值nums列表的长度
第6行: 当快指针i小于n时,执行循环
第7行: 判断快指针对应的元素是否与其前一个元素相等
第8-9行: 若不相等,则令慢指针对应的元素等于快指针对应的元素
第10行: 慢指针进一
第11行: 不管是否相等,快指针都进一
第12行: 输出列表慢指针改变过的那一段列表
第13行: 输出改变过的列表长度
代码运行结果为:
# 算法讲解
这里用到了基础技巧:双指针,简单讲解下这个技巧:
什么是双指针(对撞指针、快慢指针)
双指针,指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。
用法
对撞指针
对撞指针是指在有序数组中,将指向最左侧的索引定义为左指针(left),最右侧的定义为右指针(right),然后从两头向中间进行数组遍历。
对撞数组适用于有序数组,也就是说当你遇到题目给定有序数组时,应该第一时间想到用对撞指针解题。
快慢指针
快慢指针也是双指针,但是两个指针从同一侧开始遍历数组,将这两个指针分别定义为快指针(fast)和慢指针(slow),两个指针以不同的策略移动,直到两个指针的值相等(或其他特殊条件)为止,如fast每次增长两个,slow每次增长一个。
# 4 视频解析
高清视频讲解,请查看AI大学堂Python基础实战100例 (opens new window)
关注『讯飞AI大学堂』公众号,发送 python100 即可领取Python基础实战100例源代码