顺序表相关的算法题
顺序表相关的算法题
- 1、移除元素
- 2、删除重复项
- 3、合并两个有序序列
1、移除元素
移除元素的链接


这里,我们使用双指针法:
- 定义两个指针
dest src,同时指向数组的首元素 src向前走,还未跳出数组时:- 如果遇到非
val值,nums[src]赋值给nums[dest],dest向前跳过一个元素,src再向前跳过一个元素 - 如果遇到
val,src直接向前跳过一个元素
- 如果遇到非
src跳出数组时,结束,返回dest

代码演示:
int removeElement(int* nums, int numsSize, int val) {int dest, src;// 数组 数组元素个数 被删除的数dest = src = 0;while (src < numsSize){if (nums[src] != val){nums[dest++] = nums[src++];}else if (nums[src] == val){src++;}}return dest;
}
2、删除重复项
删除重复项的链接


这里我们还是使用双指针法,不过,思路不太一样:
- 定义两个指针
dest src:dest指向数组首元素。src指向数组首元素的下一个元素
src向前走,还未跳出数组时:- 如果
nums[src]与nums[dest]不相等时:dest向前跳过一个元素nums[src]赋值给nums[dest]src向前跳过一个元素
- 当然,如果
dest就在src的前面,即dest + 1 == src(就出现了nums[src]与nums[dest]不相等),这种情况下,可以使用下面情况的处理方法: - 如果
nums[src]与nums[dest]相等时,src直接跳过一个元素
- 如果
- 注意,此时,返回
dest + 1
图示:

代码演示:
int removeDuplicates(int* nums, int numsSize) {int dest = 0; int src = dest + 1;while (src < numsSize){if (nums[src] != nums[dest] && ++dest != src){nums[dest] = nums[src];}src++;}return dest + 1;
}
3、合并两个有序序列
合并两个有序序列的链接


在这里,我们知道,nums1的长度nums1Size == m + n。那么,我们不妨反着来:
- 定义三个指针:
p1:用于遍历数组nums1,指向的是nums1的有效末元素p2:用于遍历数组nums2,指向的是nums2的有效末元素p3:用于存储数据,指向的是nums1的末尾
p1与p2遍历:- 如果
nums1[p1]比nums2[p2]大,nums1[p1]赋值给nums1[p3],然后p1++ p3++ - 如果
nums2[p2]比nums1[p1]大,nums2[p2]赋值给nums1[p3],然后p2++ p3++
- 如果
- 跳出该遍历循环,依然有两种情况:
- 如果
p2遍历完,说明p1还有数,不用再进行任何操作。 - 如果
p1遍历完,说明p1还有数,此时,将nums2中剩下的数,依次放到nums1中即可。
- 如果
代码演示:
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int p1 = m - 1;int p2 = n - 1;int p3 = nums1Size - 1;while (p1 >= 0 && p2 >= 0){if (nums1[p1] >= nums2[p2]){nums1[p3--] = nums1[p1--];}else{nums1[p3--] = nums2[p2--];}}while (p2 >= 0){nums1[p3--] = nums2[p2--];}
}
