27. 移除元素 26. 删除有序数组中的重复项 88. 合并两个有序数组(双指针遍历)

目录
下面的几道题,都运用一个双指针(下标)遍历法
27. 移除元素-力扣

示例1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
示例2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
这道题最容易想到的思想是开辟一个新数组,然后遍历原数组,如果原数组中的某个值不等于val的值,就把这个值放到新数组中
如图:
最开始src指向的元素等于val,src向后走,des不变
src指向的值不等于val,所以将这个值放到des指向的空间中,接着src和des都向后移
接下来的步骤以此类推,最终会得到一个合适的数组
但是这个方法显然不满足题中要求的原地修改,但是我们可以借助这个思想,只不过是在原数组上进行操作
让src和des都指向原数组,其余步骤都与上面那个方法类似

最开始src指向的元素等于val,src向后走,des不变

接着src指向的元素的值不等于val,把这个值赋给des指向的空间中,接着src des向后挪

src指向的元素的值不等于val,把这个值赋给des指向的空间中,接着src des向后挪

src指向的元素等于val,src向后走,des不变

此时,src已经遍历出了数组,遍历结束,可以看到实际上操作后的数组就是[2,2],长度是2,也正好是作为下标的des的值,所以最后返回des的值。
代码如下:
int removeElement(int* nums, int numsSize, int val) {int des = 0;for (int src = 0; src < numsSize; src++) {if (nums[src] != val) {nums[des] = nums[src];des++;}}return des;
}
26. 删除有序数组中的重复项

这道题的思想与上一题思维类似,也是运用双指针遍历法
这道题的做法是:
定义2个指针,一个作为des指向第一个元素,一个作为src指向第二个元素
如果des与src指向的元素相同,就src++
如果des与src指向的元素不同,因为此前des已经保存了之前的值,所以先des++,再把src的值放到des中,再src++
代码如下:
int removeDuplicates(int* nums, int numsSize){int src = 1;int des = 0;while(src<numsSize){if(nums[src]==nums[des]){src++;}else{nums[++des] = nums[src++];}}return des+1;}
88. 合并两个有序数组

合并2个有序数组,这里可以使用归并排序的思想,但是这题与归并思想有些区别
这道题是把值最后都归到数组nums1中,如果还是按照归并做法从前往后操作则会覆盖的值
所以这道题我们从后往前归并

在begin1和begin2中选出较大的值,放到des中,然后des--,以及对应元素较大的那个begin减1
接着还有个问题:
- 如果
begin2先循环完,因为数组都是有序的,所以这是已经合并结束 - 如果
begin1先循环完,nums2中的部分数据可能还没有合并到nums1中,所以这里可以把nums2中的元素拷贝到nums1中,拷贝的个数其实是des+1
代码如下:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){int des = nums1Size-1;int begin1 = m-1;int begin2 = n-1;while(begin1>=0&&begin2>=0){if(nums1[begin1]>nums2[begin2]){nums1[des] = nums1[begin1];begin1--;des--;}else if(nums1[begin1]<=nums2[begin2]){nums1[des] = nums2[begin2];begin2--;des--;}}if(begin2<0){return;}else if(begin1<0){memmove(nums1,nums2,sizeof(int)*(des+1));}}
下面还有一个牛客网的题,也是运用双指针(下标)遍历法
牛客网:BC98 序列中删除指定数字

代码如下:
#include <stdio.h>
int main()
{//输入各个值int N= 0;scanf("%d",&N);int arr[N];for(int i=0;i<N;i++){scanf("%d",&arr[i]);}int val = 0;scanf("%d",&val);//删除指定数字int des = 0;for(int src=0;src<N;src++){if(arr[src]!=val){arr[des] = arr[src];des++;}}//输出修改后的序列for(int i = 0;i<des;i++){printf("%d ",arr[i]);}
}





