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]); } }