题目:删除排序数组中的重复项
leetcode链接:数组-删除排序数组中的重复项
说明:给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。
将最终结果插入 nums 的前 k 个位置后返回 k 。
不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成
理解:
1、将提供一个升序数组nums:说明即使有重复元素彼此也是相邻的。
2、原地删除数组中重复的元素:说明不能使用临时表来存储非重复元素。
3、返回删除重复元素后的数组长度:return 处理过后nums数组的length。
4、空间复杂度为O(1)
大致思路:
1、由于要求原地删除,那么可以利用数组的删除API及下标来完成
2、统计不重复元素的个数
3、不删除元素,但可以替换掉重复元素
题解:
1、方案一:删除数组重复元素
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function(nums) {
for (var i = 0; i < nums.length;i++) {
if (nums[i] === nums[i+1]) {
// 删除重复元素
nums.splice(i, 1)
// 由于删除了重复元素,数组长度减了1,因此数组下标需同步减1
i--
}
}
return nums.length
}
2、方案二:双指针法
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function(nums) {
const n = nums.length;
if (n == 0) {
return 0;
}
let fast = 1, slow = 1;
while (fast < n) {
// 比较前后元素是否重复
if (nums[fast] != nums[fast - 1]) {
// 不重复时,将快指针的元素赋值给慢指针指定的元素
nums[slow] = nums[fast];
// 慢指针下标+1
++slow;
}
// 无论是否重复,只要fast < n,则继续完成数组元素的循环,
++fast;
}
// 最终返回慢指针的下标,即为去重后数组的长度
return slow;
}
3、方案三:确保前K个结果不重复
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function(nums) {
let org = 0;
for(let now = 1;now < nums.length; now++){
if(nums[org] != nums[now]){
nums[++org] = nums[now];
}
}
return !nums.length ? 0 : org+1;
}
说明
上面三个方案是按照执行时间由长到短来排的,或许还有更多更优的解体方案,但时间有限就先整理这么多了