0
点赞
收藏
分享

微信扫一扫

数组元素移除问题的总结和延伸


本文对使用和操作数组时常遇到的一类数组元素移除问题的高效解决方法(O(N))做一总结,并对其中用到的思想做一些总结和延伸。本文以leetcode中的三道算法题为例进行说明。


无序数组中指定元素的移除

题目链接:​​移除元素​​

问题简述:使用原地算法移除数组中的指定元素​​target​

分析

若使用数组元素覆盖的方式,最坏情况为数组元素全部为​​target​​,逐个覆盖的时间复杂度为​​O(N^2)​​,这里不予讨论。

若要在线性时间复杂度解决这个问题,可以最先想到利用空间换时间的方法,另外开辟一个数组,择原数组中的非​​target​​​元素放入新数组,即可完成​​target​​​元素的移除,但是这种方法不满足空间复杂度​​O(1)​​的要求,但是可以沿用其中的思想。

具体做法为:双指针(​​res​​​, ​​cur​​​)遍历数组,若​​cur​​​指针指向的元素为​​targrt​​​元素,则右移​​cur​​​;否则将​​nums[cur]​​​赋给​​nums[res]​​​以实现对​​target​​​元素的覆盖。可以发现,此时res左侧的数组总是不含target元素的数组。

数组元素移除问题的总结和延伸_双指针

代码

int removeElement(int* nums, int numsSize, int val)
{
int cur = 0;
int res = 0;
while(cur < numsSize)
{
if(nums[cur] != val)
{
nums[res++] = nums[cur];
}
cur++;
}
return res;
}


有序数组中重复元素的部分移除

题目链接:​​删除有序数组中的重复项​​

问题简述:对有序数组中的元素进行原地去重操作,使重复的元素最终只保留一个

分析

类似上一个问题,此问题也可以另外开辟一个数组​resArr​​​,使用两个指针分别遍历两个数组,通过比较两个指针指向两个数组的元素可以决定是否将原数组中的元素移动到​​resArr​​中,以实现去重操作。沿用这个思路,可以另外使用常数空间复杂度的方法原地解决这个问题。

具体做法为:双指针(​​res​​​,​​ cur​​​)遍历数组,若​​res​​​指针指向的元素与​​cur​​​指针指向的元素相等,则右移​​cur​​​;否则将​​nums[cur]​​​赋给​​nums[res]​​​,以实现非重复元素的左移。可以发现,此时res指针的左侧总不包含重复元素。

数组元素移除问题的总结和延伸_去重_02

代码

int removeDuplicates(int* nums, int numsSize)
{
int res = 0;
int cur = 0;
while(cur < numsSize)
{
if(nums[cur] == nums[res]) {
cur++;
}
else {
nums[++res] = nums[cur++];
}
}
return res + 1;
}


一个延伸:合并两个有序数组

题目链接:​​合并两个有序数组​​

问题简述:在​​nums1​​​中合并两个非递减数组​​nums1​​​和​​nums2​

分析

若要合并​​nums1​​​和​​num2​​​于另一个数组中,则可以这样做:从头遍历​​num1​​​和​​num2​​,不断择较小值放入​​resArr​​​,则最后的​​retArr​​即为合并后的有序数组。

在这个问题中,要求在​​nums1​​​中进行合并,则可以考虑将​​nums1​后面的空余空间视为​​retArr​​​,从后向前遍历​​nums1​​​的有效数据部分和​​nums2​​​,择较大值放入​​nums1​​​以进行覆盖,最后得到的​​nums1​​​即为所要求的数组。注意当最后​​nums2​​​有剩余时,要将​​nums2​​​的剩余部分覆盖到​​nums1​​。

数组元素移除问题的总结和延伸_数组_03

代码

void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n)
{
int end1 = m - 1;
int end2 = n - 1;
int end = m + n - 1;
while(end1 >= 0 && end2 >= 0)
{
if(nums1[end1] > nums2[end2]) {
nums1[end--] = nums1[end1--];
}
else {
nums1[end--] = nums2[end2--];
}
}
while(end2 >= 0)
{
nums1[end--] = nums2[end2--];
}
}

举报

相关推荐

0 条评论