有序数组去重Javascript解决方案失效问题排查
问题排查与修复方案
先拆解你代码里的核心问题:
1. Map对象的使用错误
你初始化了new Map(),但判断元素是否存在时用了nums[i] in map,赋值时用了map[nums[i]] = i——这根本不是在操作Map结构,而是给Map实例添加了普通对象属性。正确的Map操作应该用map.has(key)判断存在性,用map.set(key, value)添加键值对,in操作符会遍历对象原型链,完全不符合你的判重预期。
2. splice删除元素导致索引跳过
你已经注意到splice会改变数组索引,但没做对应处理:当用splice(i,1)删除当前元素后,数组后续元素会往前挪一位,此时i位置的元素变成了原i+1位的元素,但循环的i会自增,直接跳过了这个新的i位置元素,导致漏判重复项。比如数组[1,1,1],i=0添加元素到Map,i=1删除元素后数组变成[1,1],i自增到2,循环直接结束,最后数组里还剩两个1,漏处理了重复项。
3. 未返回题目要求的数组长度
LeetCode该题要求函数返回修改后数组的长度,你的函数没有return语句,这会直接导致判题系统判定结果不符合要求。
修复后的Map版本代码
解决Map使用错误,同时处理splice的索引问题,加上返回值:
var removeDuplicates = function(nums) { const map = new Map(); let i = 0; while (i < nums.length) { if (map.has(nums[i])) { nums.splice(i, 1); // 删除后不移动i,因为下一个元素已经移到当前i位置 } else { map.set(nums[i], true); i++; } } return nums.length; };
更优的双指针解法(适配有序数组特性)
因为题目是有序数组,重复元素必然连续,完全不需要额外的Map空间,双指针法时间复杂度O(n)、空间复杂度O(1),是这道题的最优解:
var removeDuplicates = function(nums) { if (nums.length === 0) return 0; let slow = 0; for (let fast = 1; fast < nums.length; fast++) { if (nums[fast] !== nums[slow]) { slow++; nums[slow] = nums[fast]; } } return slow + 1; };
内容的提问来源于stack exchange,提问作者User9123
相关产品推荐
相关产品推荐

