目录
一:移除元素
思路:
二:删除有序数组中的重复项
思路:
三:合并两个有序数组
思路1:
什么?你不知道qsort()
思路2:
一:移除元素
27. 移除元素 - 力扣(LeetCode)
给你一个数组
nums
和一个值val
,你需要 原地 移除所有数值等于val
的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用
O(1)
额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
思路:
使用快慢指针 !
定义两个变量,一个用来遍历数组查看是否有和val值相等的,一个用来记录下来不等于val值的,放入数组中;
//27移除元素int removeElement(int* nums, int numsSize, int val)
{int src = 0; //遍历 快指针int dst = 0; //记录有效值 慢指针
//另外一种实现//for (src; src < numsSize; ++src)//{// if (nums[src] != val)// {// nums[dst++] = nums[src];// }//}while (src < numsSize){if (nums[src] != val){nums[dst++] = nums[src++]; //将有效值存到有效范围}else{src++;}}return dst;
}
int main()
{int nums[] = { 0, 1, 2, 2, 3, 0, 4, 2 };int numsSize = sizeof(nums) / sizeof(nums[0]);int val = 2;int dst = removeElement(nums, numsSize, val);printf("%d\n", dst); //vs调试写的,及以下可忽略while (dst--){printf("%d ", nums[dst]);}return 0;
}
时间复杂度:O(n),其中 n 为序列的长度。我们只需要遍历该序列至多两次。
空间复杂度:O(1)。我们只需要常数的空间保存若干变量。
二:删除有序数组中的重复项
26. 删除有序数组中的重复项 - 力扣(LeetCode)
思路:
这里依旧可以使用快慢指针;
我这里还多定义了一个遍量,拿来记录有效值;不过显得冗余,但非常容易理解;
最后一步是将最后一个不同值记录下来;
从图可以看到dst走到最后一个元素时,此元素也应该记录;
int removeDuplicates(int* nums, int numsSize) {int src = 1; //快指针int dst = 0; //慢指针int k = 0; //记录有效值while (src < numsSize){if (nums[src] != nums[dst]){nums[k++] = nums[dst++]; //将慢指针值放入有效范围中src++;}else{src++; dst++;}}nums[k++] = nums[dst]; //将最后不同的值放入return k;
}
刚刚也说了,可以对此想法进行优化
我们可以发现时删除重复项,也就说第一个元素该值都是有效的,可以定义变量从1开始;
然后定义遍历变量就行for循环,前后比较,将有效值放到有效位置中
int removeDuplicates(int* nums, int numsSize){int index = 1; //第一个值默认有效for(int i =1;i<numsSize;i++) {if(nums[i-1] != nums[i]) //前后比较{nums[index++] = nums[i]; //将快指针值放入有效位置中}}return index;
}
三:合并两个有序数组
88. 合并两个有序数组 - 力扣(LeetCode)
思路1:
题目说了 数组1是可以包容数组2进去的,我们可以直接将数组2有效值放入数组1最后一个有效值后,先将两个数组值合并在数组1中,再直接qsort排序即可啦
int compare(const void* e1, const void* e2)
{return *(int*)e1 - *(int*)e2;
}
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){//合并两个数组int j =m;for(int i =0;i<n;i++){nums1[j++] = nums2[i];}qsort(nums1,nums1Size,sizeof(nums1[0]),compare);
}
什么?你不知道qsort()
欧克,锁定往期文章【C语言】进阶——指针_敷敷_的博客-CSDN博客
里面详细讲述了关于 qsort()的使用哦,
思路2:
我们换一种方式,不使用qsort,
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {// end1、end2:分别标记nums1 和 nums2最后一个有效元素位置// end标记nums1的末尾,因为nums1和nums2中的元素从后往前往nums1中存放// ,否则会存在数据覆盖int end1 = m - 1;int end2 = n - 1;int index = m + n - 1;// 从后往前遍历,将num1或者nums2中较大的元素往num1中end位置搬移// 直到将num1或者num2中有效元素全部搬移完while (end1 >= 0 && end2 >= 0){if (nums1[end1] > nums2[end2]){nums1[index--] = nums1[end1--];}else{nums1[index--] = nums2[end2--];}}// num2中的元素可能没有搬移完,将剩余的元素继续往nums1中搬移while (end2 >= 0){nums1[index--] = nums2[end2--];}// num1中剩余元素没有搬移完 ---不用管了,因为num1中剩余的元素本来就在num1中
}