一、移除元素
这个题让我们移除数组nums中值为val的元素,最后返回k(不是val的元素个数)
这样显然我们就不能再创建一个数组来解决这个问题了,只能另辟蹊径
思路:双指针
这里定义两个指针(l1,l2)(l1,l2是整数,通过下标访问数组元素)都指向数组的起始位置,然后循环判断l1指向的元素是否等于val?如果等于,就让l2++;如果不等于,那就将l2的值赋给l1指向的元素,然后l1++,l2++。
这样遍历完数组后,l1的值就是不等于val的元素的个数。
这里以题目中给的案例来分析以下:
nums[l2]等于val(3),l2++;
nums[l2]不等于val(3),nums[l1++]=num[l2++];
nums[l2]不等于val(3),nums[l1++]=num[l2++];
nums[l2]等于val(3),l2++;
跳出循环,次数l1的值就是数据个数k
int removeElement(int* nums, int numsSize, int val) { int p1=0,p2=0; while(p2<numsSize) { if(nums[p2]==val) { p2++; } else { nums[p1]=nums[p2]; p1++; p2++; } } return p1; }
二、删除有序数组的重复项
这个题让我们删除非严格递增排列的数组中的重复数字个数,最后返回元素个数k
思路:双指针
定义l1,l2两个指针(与上面一样,l1,l2都是整数,通过下标访问数组元素),这里l1从0开始,l2从1开始
判断nums[l1]是否等于nums[l2]?如果等于,l2++;
如果不等于,l1++后再nums[l1]=num[l2];最后l2++;
循环结束后,l1++就是元素个数k
用题目给的示例来分析一下:
nums[l1]等于nums[l2],l2++;
nums[l1]等于nums[l2],nums[++l1]=nums[l2++];
跳出循环,此时l1=1,l1++就是不同的元素个数。
int removeDuplicates(int* nums, int numsSize) { int l1 = 0, l2 = 1; while(l2<numsSize) { if(nums[l1]!=nums[l2]) { l1++; nums[l1]=nums[l2]; l2++; } else { l2++; } } return ++l1; }
三、合并两个有序数组
题目要求合并两个有序数组,合并后是非递减序列,最后返回nums1数组的地址。
思路:三指针
定义三个指针(l1,l2,l3)l1指向nums1数组的最后一个有效数字,l2指向nums2数组的最后一个有效数字,l3指向nums1数组的最后一个位置。与前面的一样这三个指针也是整数,通过下标访问数组元素。
循环中,如果nums1[l1]>nums2[l2]就让l1指向的数据存放到l3处,并l1--,l3--;
如果nums1[l1]<=nums2[l2],就让l2指向的数据存放到l3处,并l2-- ,l3--;
还是以题目所给的示例来分析:
nums1[l1]<nums2[l2],执行
nums1[l3]=nums2[l2];l2--;l3--;
nums1[l1]<nums2[l2],执行
nums1[l3]=nums2[l2];l2--;l3--;
现在,nums1[l1]>nums2[l2],执行
nums1[l3]=nums1[l1];l1--;l1--;
nums1[l1]等于nums2[l2],执行
nums1[l3]=nums2[l2];l2--;l3--;
现在,l2已经小于0了,循环结束,这时,nums1数组就是合并好的数组
这里注意,如果l1先小于0,我们就需要吧nums2中剩余的数据赋给数组nums2
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) { int l1=m-1,l2=n-1,l3=m+n-1; while(l1>=0&&l2>=0) { if(nums1[l1]>nums2[l2]) { nums1[l3]=nums1[l1]; l1--; l3--; } else { nums1[l3]=nums2[l2]; l2--; l3--; } } if(m==0) { nums1[l3]=nums2[l2]; } if(l2>=0) { while(l2>=0) { nums1[l3]=nums2[l2]; l2--; l3--; } } }
如果本篇内容对你有帮助,可以一键三连支持一下!!!
如有错误的地方,也请各位大佬们指出纠正