大家好,我是吴师兄。
如果要用一些词来形容东南亚人群的特征,「
内卷
」这个词肯定是其中一个,国人在激烈的考公考研、35岁天花板的现象下,对此高度共鸣,“卷王”频出的舆论场,曾衍生出一句经典口号:“宁可累死自己,也要卷死别人”。
程序员群体尤为感同身受,一旦公司或者部门来了一个卷王,会被动的导致整个部门都进入卷的状态,而这种改变很多时候都是无效内卷。
前几天在网上看到一个程序员的吐槽贴,他们公司最近招进了一批35岁左右的新员工,这批新员工习惯天天卷到八点多才下班,慢慢地这种加班文化就开始在团队中蔓延,老员工为了不让领导觉得自己懈怠,也不得不跟着加班,结果导致现在整个公司都要到八点才能下班。
可能有些人认为八点下班不算卷,很多公司都是九点甚至十点才下班,但没必要比烂呀,要看到他们公司这种变化的趋势。
不过话又说回来,35 岁的同事们,之前肯定已经习惯了这样的工作方式,同时又更加珍惜现在好不容易找到的工作,只能通过这种方式来维持现状。
有点无解。
继续今天的算法学习,来一个简单的算法题:
删除有序数组中的重复项
。
一、题目描述
给你一个
升序排列
的数组
nums
,请你原地删除重复出现的元素,使每个元素
只出现一次
,返回删除后数组的新长度。元素的
相对顺序
应该保持
一致
。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有
k
个元素,那么
nums
的前
k
个元素应该保存最终结果。
将最终结果插入
nums
的前
k
个位置后返回
k
。
不要使用额外的空间,你必须在
原地
修改输入数组
并在使用 O(1) 额外空间的条件下完成。
判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案
int k = removeDuplicates(nums); // 调用
assert k == expectedNums.length;
for (int i = 0; i assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被
通过
。
示例 1:
输入:nums = [1,1,2] 输出:2, nums = [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] 解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
提示:
-
1 <= nums.length <= 3 * 10^4
-
-
二、题目解析
在这个问题中,主要涉及到对数组的操作。数组是一种线性表数据结构,具有连续的内存空间,可以通过下标来访问其中的元素。
算法考察点
-
数组遍历:遍历数组是这个问题的核心操作,需要通过循环遍历数组元素。
-
指针操作:使用指针来记录当前处理的位置,可以减少不必要的移动操作。
-
数组元素去重:需要去除数组中的重复元素,可以通过比较相邻元素来实现。
算法思路
-
初始化两个指针
i
和
j
,其中
i
用于遍历数组,
j
用于记录即将被赋值的位置,初始值为 0。
-
-
如果当前元素与上一个元素不相同,说明出现了新的元素,将其赋值给
nums[j]
,并将
j
后移一位。
-
如果当前元素与上一个元素相同,则跳过,继续向后遍历。
算法的优势
-
算法通过一次遍历数组即可完成去重操作,时间复杂度较低。
-
使用两个指针来记录当前处理的位置,避免了对数组进行频繁的移动操作。
算法的适用性
-
适用于需要对排序数组进行去重的情况,时间复杂度与数组长度成线性关系。
易错点