每日一题 - 算法 - 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;}
// 后记
🏃以后每天更新一道算法题,并且附带超级详细的讲解和注释,所有代码均可复制到编译器里自测。
🏃如果有疑问的小伙伴,欢迎评论留言,我会详细解答。
// 文章中任何错误都请大佬指正。