「这是我参与2022首次更文挑战的第15天,活动详情查看:2022首次更文挑战」。
描述
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
做题
题目给出一个有序的数组,需要我们在这个数组上把没有重复的元素放到前面,然后返回没有重复元素的长度。
例如 [1,2,2,2,3,3]
我们把这个数组的元素修改成 [1,2,3,....],后面的元素是啥都可以,并且返回一个 3,那题目就会去判断,不重复的长度是否对 & 这个束组的前三位是不是不重复的。
再加上这个数组是有序的,降低了我们做题的难度。
我们这里采用双下标的方式来解题,也可以说是快慢指针。
第一个指针(慢),标记着下一个没有重复的元素该放哪里,每放置一个元素,就移向下一位。
第二个指针(快),就负责遍历每个元素,帮助我们判断这个元素是否重复。
因为数组是有序的,所以我们只需要使用快指针遍历判断当前下标的数是否和上一个数一样,如果一样,就说明这个元素是重复的,快指针往下;如果不一样,就说明这个元素是第一次遇到,把这个数插入到慢指针上,两个指针同时往下。
依旧以 a = [1,2,2,2,3,3] 为例。
因为我们要跟上一个元素比较,所以我们的下标起点要改成 1,如果跟下一个元素比,当到达最后一个元素时会出现数组越界的情况。
fastIndex = 1,slowIndex = 1.
a[1] != a[0],但这时的快慢指针是一样的,所以数组仍然不变。fastIndex++;slowIndex++;
a[2] == a[1],fastIndex++;
a[3] == a[2],fastIndex++;
a[4] != a[3],此时的 slowIndex 为 2,fastIndex 为 4,交换后数组变成 [1,2,3,2,2,3], fastIndex++;slowIndex++;
后面就不推演了。
这个做法没问题,开始敲代码。
public int removeDuplicates(int[] nums) {
if(nums.length == 0){
// 数组长度为 0,不作处理
return 0;
}
// 都从 1 开始
int fastIndex = 1;
int slowIndex = 1;
for(;fastIndex < nums.length;fastIndex++){
if(nums[fastIndex] == nums[fastIndex-1]){
// 和上一个元素相同,跳过
continue;
}
nums[slowIndex++] = nums[fastIndex];
}
return slowIndex;
}
这内存消耗居然这么大,这一定不是我的问题。😊
最后
今天就到这里了。
这里是程序员徐小白,【每日算法】是我新开的一个专栏,在这里主要记录我学习算法的日常,也希望我能够坚持每日学习算法,不知道这样的文章风格您是否喜欢,不要吝啬您免费的赞,您的点赞、收藏以及评论都是我下班后坚持更文的动力。