一:题目描述
二:题目分析
本题目的主要用意就是想要在一个“有序数组”的内部将一些重复的元素都删除,最后返回剩余非重复元素的数组长度
题目分析:
假设我们设置一个升序数组:
我们需要将nums中的重复的0、1、2、3都删除,此刻我们需要三个指向数组的参数来进行数组遍历,请看下图:
i 是数组最初的位置,j是数组后面需要比较的位置,dest则是用来接收非重复数组的位置。
当nums[i] == nums[j]的时候,说明此时的j所处的位置还是重复元素,所以此刻只需要往后继续遍历就行了。
当nums[j]指向的元素已经与nums[i]的元素不会重复的时候,此刻我们就将
nums[dest] = nums[i];
dest++;
此刻我们的dest已经把第一个元素接受了,此时i所处的位置以及后面刚刚遍历完的重复元素的位置已经作废,因为已经被接收到dest这个位置上了,此刻就应该更新i的位置
i = j;
j++;
此刻我们的i所处的位置就是最新的非初始重复元素的位置,j也已经往后偏移一位了
此时就继续重复上述的操作,直到遇到下方的情况:
遇到这种情况时候,j已经越界了(结束循环),此时的i还仍然没有被收纳,所以最后一个操作就是收纳最后一位元素
还有另外一种情况:
此时的情况下也是同样使用下方的方式,将此时i的位置的元素放置在dest的位置上。
nums[dest] = nums[i]
dest++;
此时dest的位置就是所有非重复元素的后面,也就是说此时dest的数值就是所有非重复元素的下标的后面一位,但恰好,此时的dest的数值就正是所有非重复元素的个数。
代码如下:
int removeDuplicates(int* nums, int numsSize){
int dest = 0; //读取元素的位置
int i = 0; //外部循环
int j = 1; //内部循环,数组初元素位置的下一个位置
if(numsSize == 0){ //如果这个数组是空的,那就返回数组的长度为0
return 0;
}else{ //如果数组不是空的
while(j < numsSize){
if(nums[i] == nums[j]){ //如果i位置的元素和j位置的元素一致的话,那就不要
管,让j继续往后走
j++;
}else{ //如果i位置的元素和j位置的元素不一致的时候,
nums[dest] = nums[i]; //让dest初位置先把初位置i的元素接收,然后dest
再往后移动
++dest;
i = j; //与此同时,由于i后面的重复元素已经遍历完了,所以直接让i的位置与此
时的最新元素的位置接轨
++j; //继续让j往后遍历
}
}
}
nums[dest] = nums[i]; //如果遍历到最后,i的位置肯定会被搁置,所以此时将i的位置数的元素
放在dest的位置上
++dest; //dest长度自增,也就是数组此时存放的非重复性元素的长度
return dest;
}
感谢大家持续关注我的博客,我将在后面会持续为大家更新LeetCode的刷题日志!