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 ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的 ...
随机推荐
- Kubernetes 网络:Pod 和 container 的那点猫腻
1. Kubernetes 网络模型 在 Kubernetes 的网络模型中,最小的网络单位是 Pod.Pod 的网络设计原则是 IP-per-Pod,即 Pod 中 container 共享同一套网 ...
- 在线视频点播网站(python实现)
本文将会对该项目进行一个简单的介绍,包括项目名称.项目背景.项目功能.技术栈等等. 项目名称 在线视频点播网站开发(python+django) 项目背景 学习完毕python和django之后,想找 ...
- HttpClient获取不到最新的系统代理
默认情况下,HttpClient是默认采用系统代理,但是,如果你在程序运行过程中,手动修改系统代理,对于HttpClient是无效的,它依然会用老的代理去访问. 解决方法 使用下面的代码,你可以自己实 ...
- [转帖]TLS/SSL (Schannel SSP) 中的密码套件
https://learn.microsoft.com/zh-cn/windows/win32/secauthn/cipher-suites-in-schannel 密码套件是一组加密算法. TLS/ ...
- [转帖]“炫技” 还是 “真硬核”,OpenPPL 实测阿里「倚天 710」芯片
https://my.oschina.net/openppl/blog/5524424 本文将以深度学习模型推理应用为出发点,对「倚天 710」这款 ARM Server 芯片进行性能方面的实测. ...
- [转帖]JVM 输出 GC 日志导致 JVM 卡住,我 TM 人傻了
https://www.jianshu.com/p/51380e04eab1 最近,我们升级了 Java 17.后来,我们的 k8s 运维团队为了优化我们的应用日志采集, 将我们所有 pod (你可以 ...
- [转帖]如何在KingbaseES数据库查看数据库和表的大小
关键字 kingbaseES,数据库大小,表大小 1.查看单个数据库的大小 使用ksql连接到数据库,使用sys_database_size函数 kapp=# select sys_database_ ...
- [转帖]elasticsearch8.0以上版本修改内置用户密码
https://www.cnblogs.com/zhang-ding-1314/p/16199682.html 修改密码需要在es启动,并cd到es的bin目录下执行: 1.重置密码并在控制台显示新密 ...
- [转帖]ES集群开启X-pack认证
https://www.cnblogs.com/jclty/p/12913996.html 1.下载 1 # wget https://artifacts.elastic.co/downloads/e ...
- [转帖]wmic命令介绍
https://www.jianshu.com/p/3e1a5a8fa23b How to Get Your System Serial Number PS C:\windows\system32&g ...