首页 > 其他分享 >数组元素移除问题的总结和延伸

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

时间:2023-02-24 21:01:45浏览次数:62  
标签:cur nums int res 元素 数组 移除 nums1


本文对使用和操作数组时常遇到的一类数组元素移除问题的高效解决方法(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--];
}
}

标签:cur,nums,int,res,元素,数组,移除,nums1
From: https://blog.51cto.com/158SHI/6084376

相关文章

  • #yyds干货盘点# LeetCode面试题:删除有序数组中的重复项
    1.简述:给你一个升序排列的数组nums,请你原地删除重复出现的元素,使每个元素只出现一次,返回删除后数组的新长度。元素的相对顺序应该保持一致。由于在某些语言中不......
  • 【JavaScript】28_数组的常用方法
    9、数组的方法push()向数组的末尾添加一个或多个元素,并返回新的长度pop()删除并返回数组的最后一个元素unshift()向数组的开头添加一个或多个元素,并返回新的长度shift()删......
  • 一文搞懂Vue3中如何使用ref获取元素节点?
    一文搞懂Vue3中如何使用ref获取元素节点?会飞的猪开源网站:91huajian.cn 29人赞同了该文章​展开目录 前言虽然在Vue中......
  • 翻转数组(力扣)
    题目:给定一个整数数组nums,将数组中的元素向右轮转k个位置,其中k是非负数。示例1:输入:nums=[1,2,3,4,5,6,7],k=3输出:[5,6,7,1,2,3,4]解释:向右轮转1......
  • 1.2.1 数据、数据元素、数据项和数据对象
    1.2.1数据、数据元素、数据项和数据对象数据(Data)数据元素(dataElement)数据项(DataItem)数据对象(DataObject)数据:是能输入计算机且能被计算机处理的各种符号的......
  • JAVA 数组 数组算法 求平均值
    publicclassTest{publicstaticvoidmain(String[]args){int[]nums={1,2,3,4};//定义总和intsum=0;//定义平均值......
  • 二维数值数组
    二维数组数组的数组,例如arr[3][4]--------->3是行标,4是列标 二维数组的总大小==行数*列数*每个元素的大小数组的总大小    ==sizeof(arr)......
  • munpy 数组间运算
    数组间运算1.数组与数的运算arr=np.array([[1,2,3,2,1,4],[5,6,1,2,3,1]])arr+1#每个元素分别+1"""array([[2,3,4,3,2,5],[6,7,2,3,4,2]])"""......
  • JAVA 数组 数组算法 求最大值
    publicclassTest1{publicstaticvoidmain(String[]args){//需求:求最大值int[]nums={1,3,12,6,5};//定义最大值intma......
  • 循环删除数组指定下标的元素
    for(leti=0;i<selectedGroup.children.length;i++){letgroup=selectedGroup.children[i];deleteshapeList[group.myShapeIndex];/......