数组长度:数组中实际存放元素的总个数。
区别于内存容量:
长度:有效元素个数(程序业务使用)
容量:数组开辟的内存空间大小(底层使用)
关键特性:
1、数组下标从0开始,最后一个元素下标 = 数组长度 - 1
2、数组长度不可变(静态数组),一旦初始化,内存连续固定
3、遍历数组的标准终止条件:< nums.length'
一、左右指针(对撞指针)
left左指针,起始在数组下标0;
right右指针,起始在数组最后下标 n-1;
适用场景:有序数组(数组必须有序才能左右对撞)
有序数组平方977
有序数组两数之和,找两个数相加等于target
重点:1、初始化
int left = 0
int right = numsSize -1
2、循环条件:while(left<=right)
left == right的时候,还有一个元素没有处理,不能漏掉
如果写left < right,中间剩下的那一个元素直接跳过,出错。
3、移动规则:根据条件判断,只移动其中一个指针,或者两个一起移动。
4、特点:两个指针相向而行(面对面走)
二、快慢指针
两个指针都从数组头部0位置出发,同向,同一个方向右跑。
快指针fast:探路,走得更快(每次循环必走)
慢指针slow:收集结果,满足条件才移动。
两种用法:1、数组原地覆盖
fast逐个遍历全部元素;slow保存有效元素的位置。
fast遇到符合条件的元素,就赋值给slow位置,slow++。
fast一直在跑,slow只存有用数据。
2、滑动数据(299长度最小子数组)
fast(右指针) = 快指针:不断向右扩大窗口,纳入新元素。
slow(左指针) = 慢指针:满足条件的时候,才向右收缩窗口。
两个指针同时向右,不是面对面。fast一次走两步,slow一次走一步;用来找链表中点,判断链表是否有环。
题目:977.有序数组的平方
给一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组要求也按照非递减顺序排序。
思路(双指针最优解)
1、新建结果数组,长度和原数组一致
2、左指针再投,右指针在尾,
3、倒序填充结果数组(从大到小填)
4、比较左右平方,大的放末尾,指针转动)

函数拆解:
int* nums:传入数组,C语言数组传到函数实际是指针,拿不到数组长度。
int numsSize:手动传入数组的元素个数,这里是5。
int* rrturnSize:输入参数,告诉数组有多少个元素。

新数组和原数组元素数量一样,把5写进returnSize指向的变量。

malloc在堆内存开辟一块新数组。
千万不要写int res5;这种局部数组。局部数组在栈上,函数结束就销毁,返回出去会乱码崩溃。
堆内存手动开辟,使用完main里面必须free(ans);否则内存泄漏。
指针变量:

初始状态:nums:-4,-1,0,3,10
left->0; right->4
res:?,?,?,?,?
index = 4(res的最后一格)
while循环while(left <= right)
条件必须写<=,不能写< 当left和right指向同一个元素的时候,代表还剩最后一个数字,也要处理。如果写<,最后中间元素直接漏掉。

leftSquare:左边指针向数字的平方
rightSquare:右边指针指向的数字平方
resindex:结果数组当前要填写的位置(从数组尾部开始)
left++:左边指针向右走一步
right--:右边指针向右走一步
if分支:leftSquare > rightSquare
条件成立:左边的平方更大,大数要放到resindex(结果数组靠后的位置)
else分支:1、右边平方更大 2、两边平方相等
main测试部分拆解:

只有main函数内部,可以用sizeof计算数组长度;放到自定义函数里面做不到。

&retSize传地址,函数内部给*returnSize赋值,retSize就拿到新数组长度 = 5。
打印循环输出每一个元素。

malloc开辟堆内存,用完必须释放,C语言重要考点,不写会内存泄漏。