JS Leetcode 80. 删除有序数组中的重复项 II题解,常规解法与快慢双指针做法
壹 ❀ 引
今天的题目来自LeetCode80. 删除有序数组中的重复项 II,是一道难度中等,但实际挺简单的一道题,题目描述如下:
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums); // 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
示例 1:
输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。
示例 2:输入:nums = [0,0,1,1,1,1,2,3,3]
输出:7, nums = [0,0,1,1,2,3,3]
解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。
1 <= nums.length <= 3 * 104-104 <= nums[i] <= 104nums已按升序排列
贰 ❀ 简单分析,按题意硬解
我们简单提取下题目信息,给定一个升序排列的数组,要求在经过处理过,数组中连续的重复的数字最多不超过两个,题目要求不能使用额外数组,我们必须原地修改数组。
当看到这,我的第一感觉就是使用计数,统计一个数字出现的次数,如果出现次数少于2之前,我们可以继续往后找,而当超过2次时就需要剔除掉当前元素,完整遍历一次后自然就是我们想要的结果了。
当然,我想到这就开始写代码了,然后写出了如下笨比代码,当然也通过了:
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function (nums) {
//用于记录数字出现的次数
let map = {};
// 记录相同数字出现的次数,超过2删除掉
for (let i = 0; i < nums.length;) {
// 第一次出现时
if (map[nums[i]] === undefined) {
map[nums[i]] = 1;
i++;
// 记录多次时要判断有没有超过2
} else if (map[nums[i]] + 1 > 2) {
nums.splice(i,1);
}else{
map[nums[i]] = map[nums[i]]+1;
i++;
};
};
return nums.length;
};
上面代码思路其实是对的,只是一时半会还没完成理清,就有点硬编码的意思,下面这段代码是在看了题解后,重新整理的逻辑,思路与上方代码相同:
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function (nums) {
// 根据题意,至少有一个元素
let s = 1;
// 因此遍历从1开始
let i = 1;
while (i < nums.length) {
// 比如,第二个跟第一个还相同,应该让s加1,但需要考虑的是,超出了2了怎么办
if (nums[i] === nums[i - 1]) {
if (s === 2) {
nums.splice(i, 1);
} else {
i++;
s++;
}
} else {
// 如果不相等,说明遇到了不同的元素了,重置mark
s = 1;
i++;
}
}
};
唯一有点区别的是,上述代码使用了一个数字用于单独记录相同数字出现的次数,而非我前面使用对象一一去记录。
叁 ❀ 快慢双指针
在题目实例说明中,其实特意强调了一句不需要考虑数组中超出新长度后面的元素,什么意思呢,比如如下数组:
[1,1,1,2,2,3]
//经过某种处理可以转变成
[1,1,2,2,3,3]
也就是说,因为期望的答案是[1,1,2,2,3],而上面转变后的数组,前五个也满足预期答案,超出的部分可以不用考虑,也因为如此,才支撑了接下来的解法。
我们已知数组中数字最多不超过2个,也就是,不管给定一个什么数组,前2位一定是合格的,比如[1,2]或者[1,1],真正需要考虑的元素应该是从第三位开始。
我们可以定义快慢两个指针,快指针总是从头到尾遍历,而慢指针,当遇到超出三个的时候就停下来,让快指针继续搜索,直到遇到不相同的元素了,就替换掉慢指针所在元素,如果成功替换,慢指针进一位,说起来可能有点模糊,我们先看代码:
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function(nums) {
// 这里做了通用,比如题目说最多三个相同,这里就传递3
return process(nums, 2)
};
function process(nums, k) {
// 这里的s就是慢指针
let s = 0
// 这里的i是快指针
for (let i=0;i<nums.length;i++) {
// s<k是因为前k个数字一定不会不满足条件,满足前者即可
if (s < k || nums[s - k] !== nums[i]) {
nums[s] = nums[i]
s++;
};
};
return s;
}
慢指针s与快指针i初始都是0,根据提议,前2个数字一定满足条件,因此才有s<k,所以前两次循环因为s<k满足,后面的条件就不会比较,直接更新两次慢指针的数字,并让慢指针右移动。
从第三次比较开始,nums[s - k]也就是nums[2 - 2]与快指针的nums[i]相同,此时i已经是3了,这说明已经超出了最多2个的范围了,怎么办?当然是不做操作,快指针i继续往后跑,直到遇到nums[s - k] !== nums[i]的数字,说明可以用不同的数字对刚才慢指针所在的数字进行替换了,一直到快指针遍历完成,原数组中所有数字都会满足最多不超过2个的情况。
其实今天还是有点累了,就偷个懒不画图了,如果这里比较难理解,可以断点跟一下代码,自己尝试画图理一理,那么就先记录到这里了。
JS Leetcode 80. 删除有序数组中的重复项 II题解,常规解法与快慢双指针做法的更多相关文章
- [LeetCode每日一题]80. 删除有序数组中的重复项 II
[LeetCode每日一题]80. 删除有序数组中的重复项 II 问题 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度. 不要使用额外 ...
- 【LeetCode】80. 删除有序数组中的重复项 II
80. 删除有序数组中的重复项 II 知识点:数组:排序:双指针: 题目描述 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度. 不要使 ...
- 80. 删除有序数组中的重复项 II
题目 给你一个有序数组 nums ,请你原地删除重复出现的元素(不需要考虑数组中超出新长度后面的元素),使每个元素最多出现两次 ,返回删除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入 ...
- LeetCode 80. 删除排序数组中的重复项 II
LeetCode 80. 删除排序数组中的重复项 II
- Java实现 LeetCode 80 删除排序数组中的重复项 II(二)
80. 删除排序数组中的重复项 II 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O ...
- 4.19——数组双指针——26. 删除有序数组中的重复项 & 27. 删除有序数组中的重复项II & 80. 删除有序数组中的重复项 II
第一次做到数组双指针的题目是80: 因为python的List是可以用以下代码来删除元素的: del List[index] 所以当时的我直接用了暴力删除第三个重复元素的做法,大概代码如下: n = ...
- Leetcode 80.删除排序数组中的重复项 II By Python
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 ...
- LeetCode 80. 删除排序数组中的重复项 II(Remove Duplicates from Sorted Array II)
题目描述 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成 ...
- 删除有序数组中的重复项II
题目描述 给你一个有序数组 nums ,请你原地删除重复出现的元素,使每个元素最多出现两次,返回删除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组 并在使用O(1)额外空间的条件下 ...
- [LeetCode]26.删除有序数组中的重复项(Java)
原题地址: remove-duplicates-from-sorted-array 题目描述: 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的 ...
随机推荐
- keystore 与 trust store 的区别 及 keytool 常用命令
本文为博主原创,未经允许不得转载: 1. key store 与 trust store 区别 2. java 配置 单向认证与双向认证的过程 3. key store 与 trust store 常 ...
- 基于html5+javascript技术开发的房贷利率计算器,买房的码农们戳进来
房贷计算器是一款专为购房者设计的实用工具应用,其主要功能是帮助用户详细计算房贷的还款金额.利息以及还款计划等.通过这款软件,用户可以更加便捷地了解到自己的还款情况和计划,从而更好地规划自己的财务.下面 ...
- 永久激活Windows10专业版及其它版本【亲测有效2022-03-16,两种方式】
前言 小编最近使用公司的电脑,开始出现让你激活的提示,而且每次开机都会弹出来,小编忍住了:但是过不了半个月开始给你在桌面上显示了,一直显示和水印一样.小编忍无可忍,必须找个办法给你消灭掉!!,于是小编 ...
- 【MMC子系统】 一、MMC/SD/SDIO介绍
1.前言 该节学习Linux Kernel的MMC子系统,也称为块设备驱动,正如其名,与字符驱动相比,MMC子系统以块为单位进行操作. 同时,由于MMC Card.SD Card.SDIO Card等 ...
- K8S_IPV6 POD与数据库联通方法以及快速网络调试的一个思路
K8S_IPV6 POD与数据库联通方法以及快速网络调试的一个思路 背景 前端时间搭建了一套K8S only IPV6 Single Stack的测试环境 因为自己长时间不搞K8S了, 并且IPV6的 ...
- [转帖]Redis优化:Redis使用TCMalloc提高内存分配性能
TCMalloc(Thread-Caching Malloc)是google开发的开源工具──"google-perftools"中的成员.与标准的glibc库的malloc相比, ...
- 申威3231服务器Redis性能验证-及最全信创CPU性能分析
申威3231服务器Redis性能验证-及最全信创CPU性能分析 背景 公司里面新进了几台服务器. 有台申威服务器. 因为前段时间参与过一次申威的POC验证. 当时对性能有一点简单的理解. 但是因为不方 ...
- 【转帖】MySQL 8.0 hash join有重大缺陷?
我并不这么看. 友情提醒:本文建议在PC端阅读. 徐春阳老师发文爆MySQL 8.0 hash join有重大缺陷. 文章核心观点如下:多表(比如3个个表)join时,只会简单的把表数据量小的放在前面 ...
- 【转帖】32.MinorGC、MajorGC和FullGC的对比
目录 1.MinorGC.MajorGC和FullGC的对比 2.GC触发机制 1.MinorGC.MajorGC和FullGC的对比 1.JVM在进行GC的时候,并不是每次都是对新生代.老年代.永久 ...
- CentOS7最小安装注意事项
CentOS7最小安装注意事项 背景与说明 公司很多项目现在都是最小化安装的了. 自己之前为了方便都是使用GUI安装,很多地方可能都有遗漏 这里进行一下简单的安装总结, 避免以后新安装有缺失的项目 安 ...