splice 、 slice 、split傻傻分不清 | 刷题打卡

184 阅读3分钟

坑还是要先挖好,尽管昨天挖的坑还没有填,但意识到了从业多年基础依旧薄弱的问题,因此,先把牛吹起来,这个月一定要完成数组、树的学习,每天一题。多思考,少抱怨,未来会更美好!

题目描述

分类困难度👍👎
算法简单 (52.91%)1866-
标签 数组双指针
公司 bloomberg | facebook | microsoft

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,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。

你不需要考虑数组中超出新长度后面的元素。

说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

思路分析

首先想到的是 JavaScript 中的奇技淫巧-- new Set(),尝试了[...new Set(nums)]Array.from(new Set(nums)),似乎都不能通过测试,都提示输入[1,1,2]时返回了[],大概是因为开辟了新的空间。ES6 中的 Set 和 Map 主要用于数组去重和数据存储,类似于集合和字典,不确定是不是 new 的原原因。

不过没关系,依旧暴力破解法走起,留下了没有技术的眼泪。依旧双重 for 循环,嵌套循环中从 i+1 开始,也就是比较前一个元素和后一个元素,如果相等则使用 splice 移除后一个元素,由于此时数组长度发生了变化,因此我们需要 j-- 。既然给出的数据已经排好序了,那直至没有相等元素结束循环,返回的数组也就是处理好的结果了。

AC 代码

暴力解法

/*
 * @lc app=leetcode.cn id=26 lang=javascript
 *
 * [26] 删除排序数组中的重复项
 */

// @lc code=start
/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
   for( let i = 0; i< nums.length; i++ ) {
       for(let j = i + 1; j < nums.length; j++ ) {
           if(nums[i] === nums[j]) {
               nums.splice(j,1)
               j--
           }
       }
   }
   return nums
};
// @lc code=end


待补充

总结

没有深入探索 Set 和 Map , 平时习惯了复制粘贴,思维逐渐固化。此外对常用的 API 也变得陌生, “splice 、 slice 、split傻傻分不清”。 各位大佬有啥技巧吗?

本文正在参与「掘金 2021 春招闯关活动」, 点击查看活动详情