LeetCode 第26题:删除有序数组中的重复项
LeetCode 第26题:删除有序数组中的重复项
题目描述
给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。
将最终结果插入 nums 的前 k 个位置后返回 k 。
不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
难度
简单
题目链接
https://leetcode.cn/problems/remove-duplicates-from-sorted-array/
示例
示例 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 。不需要考虑数组中超出新长度后面的元素。
提示
- 1 <= nums.length <= 3 * 104
- -104 <= nums[i] <= 104
- nums 已按 升序 排列
解题思路
方法:双指针
使用快慢指针的方法,慢指针指向当前已处理好的数组的最后一个位置,快指针用于遍历数组。
关键点:
- 数组已经排序,相同元素相邻
- 使用快慢指针处理
- 原地修改数组
- 保持相对顺序
具体步骤:
- 如果数组为空,返回0
- 初始化慢指针slow = 0
- 使用快指针fast遍历数组:
- 如果nums[fast] != nums[slow],说明遇到新元素
- 将slow指针前进一位,并将新元素复制到slow位置
- 返回slow + 1(新数组的长度)
时间复杂度:O(n),其中n是数组的长度
空间复杂度:O(1)
代码实现
C# 实现
public class Solution {
public int RemoveDuplicates(int[] nums) {
if (nums == null || nums.Length == 0) return 0;
int slow = 0;
for (int fast = 1; fast < nums.Length; fast++) {
if (nums[fast] != nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
}
return slow + 1;
}
}
代码详解
- 边界检查:
- 处理空数组和长度为0的情况
- 双指针使用:
- slow指针指向当前不重复序列的最后位置
- fast指针用于遍历数组寻找新元素
- 数组修改:
- 只在找到新元素时修改数组
- 保证原地修改且空间复杂度为O(1)
执行结果
- 执行用时:124 ms
- 内存消耗:44.1 MB
总结与反思
- 这是一道经典的数组处理题目:
- 考察双指针技巧
- 考察原地修改数组
- 考察空间效率
- 解题要点:
- 利用数组已排序的特性
- 使用双指针降低时间复杂度
- 原地修改避免额外空间
- 优化思路:
- 可以添加快速判断相邻元素
- 考虑特殊情况的优化
- 注意边界条件的处理

浙公网安备 33010602011771号