> 文档中心 > 每日一题 - 算法 - 001 - 原地移除数组中所有的元素val

每日一题 - 算法 - 001 - 原地移除数组中所有的元素val

每日一题系列


文章目录

  • 原地移除数组中所有的元素val(c语言实现)
  • ①、思路一:将等于 val 值的元素移动到最后面
    • 下面给出代码
  • ②、思路二:把原数组虚拟成一个新数组,将不等于 val 值的元素拷贝到新数组中
    • 下面给出代码
  • // 后记

原地移除数组中所有的元素val(c语言实现)

🏃 题目要求:给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。
🏃 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入
🏃 无需考虑数组的顺序

💘举个栗子:
输入

数组 = 1 2 3 3 4 5
size = 6(size为数组的长度)
val = 3

输出

数组 = 1 2 4 5(不考虑顺序)
size = 4(size为数组的长度)

①、思路一:将等于 val 值的元素移动到最后面

🏃定义左右两个指针
🏃left指针向右移动来寻找val值

在这里插入图片描述

🏃 找到之后与right的值交换,并让 size-1,right-1
🏃 此时数组中等于 val 值的元素就转移到数组的最后面,size的值-1保证我们遍历数组的时候遍历不到此元素。
🏃 注意此时left不移动(因为right的值可能是val)

在这里插入图片描述

🏃 重复此过程,直到 right < left 为止
🏃 此时 left 的下标值就是数组中元素的个数

在这里插入图片描述

🏃 这里一定注意一个细节,判断结束条件是 right < left 而不是 right = left。
🏃 因为如果数组中的数全部都是val的话,第一个元素不会被判断,循环就停止了。

下面给出代码

int removeElement(int* nums, int numsSize, int val){int left = 0, right = numsSize - 1;while (left <= right)//结束条件{if (nums[left] != val)//如果left的值不等于val,left继续向后寻找{left++; }else//如果相等{//交换两个元素int tmp = nums[left];nums[left] = nums[right];nums[right] = tmp;//改变right和数组的大小right--;numsSize--;}}return left;}int main(){int nums[10] = { 1,2,3,4,1,2,3,4,1,2 };int newlen = removeElement(nums, 10, 2);int i = 0;for (i = 0; i < newlen; i++){printf("%d ", nums[i]);}return 0;}

②、思路二:把原数组虚拟成一个新数组,将不等于 val 值的元素拷贝到新数组中

🏃 虚拟出来一个同等大小的数组,但是是在原数组中进行改动。
🏃 如果我们有一个同等大小的数组的话,我们可以遍历原数组,将其中不等于 val 值的元素统统拷贝到新数组。

在这里插入图片描述

🏃 上图中的思路是重新创建一个新数组。
🏃 但是实际上我们可以在原数组中直接拷贝,直接将原数组虚拟成新数组。
🏃 与 val 值不相等直接拷贝在 dest 指针的位置上;与 val 值相等,不拷贝,只移动 src 指针,寻找 val 值。

下面给出代码

int removeElement(int* nums, int numsSize, int val){int src = 0;//src记录原数组位置int dest = 0;//dest记录虚拟出来的新数组的位置while (src < numsSize)//遍历整个数组{//如果不等于val,拷贝if (nums[src] != val){nums[dest] = nums[src];dest++; src++;}//如果等于val不拷贝else{src++;}}//此时dest的下标就是数组中元素的个数return dest;}int main(){int nums[10] = { 1,2,3,4,1,2,3,4,1,2 };int newlen = removeElement(nums, 10, 2);int i = 0;for (i = 0; i < newlen; i++){printf("%d ", nums[i]);}return 0;}

// 后记

🏃以后每天更新一道算法题,并且附带超级详细的讲解和注释,所有代码均可复制到编译器里自测。
🏃如果有疑问的小伙伴,欢迎评论留言,我会详细解答。

// 文章中任何错误都请大佬指正。