本节我们将对顺序表相关数组题进行详细分析
下面就开始叭!🎈🎈🎈
1.移除元素
题目 :给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
要求 :不要使用额外的数组空间,你必须仅使用 O(1)额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
原地移除数组中所有的元素val,要求时间复杂度为O(N),空间复杂度为O(1)。
画图分析:
代码运行:
c
void Swap(int* p1, int* p2) {
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
int main() {
int arr[] = { 1, 3, 4, 3, 5, 3 };
int sz = sizeof(arr) / sizeof(arr[0]);
//要删除的元素
int k = 3;
// 双指针法:将非3元素前移
//目标指针
int* dst = arr;
//遍历数组指针
int* src = arr;
for (src; src < arr + sz; src++)
{
if (*src != k)
{
//将src指向的元素复制到dst上
*dst = *src;
dst++;
}
}
// 计算剩余元素数量
int remain = dst - arr;
// 打印结果
for (int i = 0; i < remain; i++) {
printf("%d ", arr[i]);
}
return 0;
}
运行结果:

2...删除有序数组中的重复项
题目:
输入: nums = [0,0,1,1,1,2,2,3,3,4]
输出: 5,nums = [0,1,2,3,4]
解释: 函数应该返回新的长度5,并且原数组 nums 的前五个元素被修改为0,1,2,3,4。不需要考虑数组中超出新长度后面的元素。
画图分析:
代码运行:
c
void Swap(int* p1, int* p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
int main()
{
int arr[] = { 0,0,1,1,2,2,3,3,4 };
int sz = sizeof(arr) / sizeof(arr[0]);
//开始指针
int* sta = arr;
//遍历指针
int* dst = arr;
//末尾指针
int* end = arr + sz;//指向数组后面这个元素
int num = 0;//用于记录去重后数组中元素的个数(不包括第一个元素),初始值为 0
while (dst < end)
{
if (*sta == *dst)
{
dst++;
}
else
{
sta++;//注意这里要先挪再交换
Swap(dst, sta);//交换
dst++;
num++;//?
}
}
int i = 0;
for (i = 0; i <= num; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
注意num的使用技巧:
在这段代码中,num
变量的主要作用是记录去重后数组中除第一个元素之外的元素个数。由于原数组是有序的,第一个元素必然会被保留在去重后的数组中
,所以num
从0
开始计数,每发现一个与前面元素不同的新元素,num
的值就加 1。最终,num + 1
就代表了去重后数组的元素总数。
当dst
指针遍历完整个数组后,循环结束。此时 num
的值表示去重后数组中除第一个元素外的元素个数。++对于数组 {0, 0, 1, 1, 2, 2, 3, 3, 4},去重后的数组为 {0, 1, 2, 3, 4},num 的最终值为 4,代表除第一个元素 0 外,还有 4 个不同的元素。++
运行结果:
3.归并数组
题目: 给你两个按
非递减顺序
排列的整数数组nums1
和nums2
,另有两个整数m
和n
分别表示nums1
和nums2
中的元素数目。请你合并nums2
到nums1
中,使合并后的数组同样按非递减顺序
排列。
注意: 最终,合并后数组不应由函数返回,而是存储在数组nums1
中。为了应对这种情况,numsl
的初始长度为m+n
,其中前m
个元素表示应合并的元素,后n
个元素为0
,应忽略。nums2
的长度为n
。
题目解析:
画图解析:

代码运行:
c
int main()
{
int arr_1[10] = { 0,1,2,3,6 };
int arr_2[5] = { 1,1,3,4,5 };
int end_1 = 4;
int end_2 = 4;
int end = sizeof(arr_1) / sizeof(arr_1[0]) - 1;
//两个数组end下标都>=0表示没有走完
while (end_1 >= 0 && end_2 >= 0)
{
//如果第一个数组元素大于等于第二个,那么先放第一个
if (arr_1[end_1] >= arr_2[end_2])
{
//这里是先将end_1的值赋值到end 然后再--
arr_1[end--] = arr_1[end_1--];//注意这里先赋值再减减
}
else
{
arr_1[end--] = arr_2[end_2--];
}
}
//数组一:end_1走完了,直接将end_2压入到前面
while (end_2 >= 0)
{
arr_1[end--] = arr_2[end_2--];
}
//数组二:end_2走完了,那么就不需要考虑end_1,因为2压到后面,1是有序的直接排好了
//遍历打印
int i = 0;
for (i = 0; i < sizeof(arr_1) / sizeof(arr_1[0]); i++)
{
printf("%d ", arr_1[i]);
}
return 0;
}
运行结果:

🎉🎉🎉
在这里本章就完结啦~
我们下期见噢~