数据结构:顺序表与链表经典算法实战
在面试和实际开发中,顺序表和链表的操作是考察指针逻辑的基石。今天我们把高频考点串起来,重点讲解双指针、快慢指针以及哨兵位技巧的应用。代码部分采用 C 语言实现,注重空间复杂度优化。
顺序表算法(双指针法)
移除元素
核心思路是用两个指针,一个负责探路(src),一个负责记录有效位置(dst)。遇到目标值就跳过,否则覆盖写入。
int removeElement(int* nums, int numsSize, int val) {
int src = 0, dst = 0;
while (src < numsSize) {
if (nums[src] != val) {
nums[dst++] = nums[src];
}
src++;
}
return dst;
}
时间复杂度 O(N),空间 O(1)。注意返回的是新长度,原数组前 dst 个元素即为结果。
删除有序数组中的重复项
利用数组有序的特性,比较当前元素与前一个不重复元素。如果不同则后移 dst 并赋值。
int removeDuplicates(int* nums, int numsSize) {
if (numsSize == 0) return 0;
int src = 1, dst = 0;
while (src < numsSize) {
if (nums[src] != nums[dst]) {
nums[++dst] = nums[src];
}
src++;
}
return dst + 1;
}
这里有个小细节:++dst 直接写在判断里,避免了自己给自己赋值的冗余操作。
合并两个有序数组
不要从前往后合并,那样会覆盖未处理的数据。建议从后往前遍历,谁大谁先放后面。
void merge(int* nums1, int nums1Size, int m, int* nums2, nums2Size, n) {
l1 = m - , l2 = n - , l3 = m + n - ;
(l1 >= && l2 >= ) {
(nums1[l1] > nums2[l2]) {
nums1[l3--] = nums1[l1--];
} {
nums1[l3--] = nums2[l2--];
}
}
(l2 >= ) {
nums1[l3--] = nums2[l2--];
}
}


