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 ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的 ...
随机推荐
- 在Python中使用Process创建子进程遇到的问题
假如使用Process创建子进程,那么在最后的函数调用时需要加上if __name__ == "__main__":语句,否则会报错. 未使用该语句 代码示例 from multi ...
- Linux查看文件内容与处理文件
Linux查看文件内容与处理文件 目录 Linux查看文件内容与处理文件 查看文件内容 1.查看文件类型 2.查看整个文件 3.查看部分文件 处理文件 1.创建空文件 2.过滤文件内容 3.统计文件内 ...
- 使用python的os.walk()对目标路径进行遍历
需求背景 在使用python处理和扫描系统文件的过程中,经常要使用到目录或者文件遍历的功能,这里通过引入os.walk()的功能直接来实现这个需求. 使用示例 由于功能模块本身比较简单,这里直接提供一 ...
- Oracle数据类型的简单学习之一
Oracle数据类型的简单学习之一 背景 因为信创安可替代的发展 有很多项目提到了数据库切换到国产数据库的要求. 一般情况是要求从Oracle/SQLServer 迁移到国产的: 达梦/瀚高/人大金仓 ...
- [转帖]tidb-lightning 逻辑模式导入
https://docs.pingcap.com/zh/tidb/stable/tidb-lightning-configuration 本文档介绍如何编写逻辑导入模式的配置文件,如何进行性能调优等内 ...
- [转帖]Linux之pure-ftpd安装和使用
一.pure-ftpd简介 PureFTPd是一款专注于程序健壮和软件安全的免费FTP服务器软件(基于BSD License),以安全和配置简单为设计目标,支持虚拟主机,IPV6,PAM等功能.. ...
- [转帖]深度解读:传奇的Alpha处理器
https://jishuin.proginn.com/p/763bfbd2cf85 来源:科技新报(台) 长期关心处理器技术发展者,这20年来,很难不每隔一段时间就会偶尔听到「这技术受Alpha影响 ...
- 转载:ubuntu各个版本的发行时间和停止支持的时间,更新到最新版和代号。
版本:20.10 代号:Groovy Gorilla 发布时间:2020/10/22 版本:20.04 LTS 代号:Focal Fossa 发布时间:2020/4/23 版本:19.10 ...
- Nginx反向代理总结
反向代理的种类 1. LVS的方案 2. DNS轮询的方案 3. Nginx的4层代理 4. Nginx的7层代理 5. 网络NAT的处理 Nginx的反向代理-四层` 编译时增加 --with-st ...
- java 调优需要关闭的组建