leetcode打卡-0026删除数组中重复项
题目描述
给你一个有序数组nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用O(1)额外空间的条件下完成。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array
解题思路
1. 双指针
按照正常思维思考这题,可以划分一个额外的临时数组tmp,从头遍历原始数组nums,不断地比较,将新元素放进tmp里,不过题目要求原地删除,所以需要简单修改一下,将新元素直接放到原始nums里去,占用以前元素的位置。
用一个慢指针slow指向有效数组的最后一个位置,用来记录不重复数组的尾部,用一个快指针fast顺序遍历数组。
当fast与slow所指的值不一致时,证明这是两个不重复元素,将slow后一位的值改为fast指向的值,slow前进一位,fast继续遍历即可,最后返回长度即为slow+1。
1 | # Python实现 |
顺便练习一下Rust
1 | impl Solution { |
2. 通用套路思维
如果将原问题的「最多保留1位」修改为「最多保留k位」,问题会更有通用性,例如leetcode第80题。
这个想法来自于宫水三叶的题解,很巧妙,此处参考引证一下。
- 由于是保留k个相同数字,对于前k个数字,我们可以直接保留。
- 对于后面的任意数字,能够保留的前提是:与当前写入的位置前面的第k个元素进行比较,不相同则保留。
第一条很好理解,因为这是有序数组,所以前k个元素里,每种数字都会符合不超过k个的条件;第二条,就是反向思考,一个数字与写入位置的第前k个元素对比,如果相同,证明写入位置之前已经写满了k个当前元素,那么写入位置就需要寻找一个新元素写入了,如果不同,就把当前元素复制过去补位。
所以,通用的Python实现代码如下:
1 | def process(nums, k): |
总结
双指针的方法很容易想到,在处理字符串问题是比较常用,不过后面的通用解法,它是建立在“数组有序”且“保留逻辑”的基础上,可以作为解决这种字符串问题的套路尝试。