数组
特点
- 连续存储
- 支持随机访问 O(1)
- 索引与寻址
- 头部地址+偏移量=目标位置的数据
- 插入元素:先移动,再插入 时间复杂度 O(N)
- 删除元素:移动覆盖 时间复杂度** O(N)**
实战
1.leetcode 226 删除数组中重复的数字
规律总结
- 操作数组
- 保序
- 留下需要的 过滤掉不用的
- 采用filter的思想
循环遍历,保留,返回,添加保留的条件,判断边界
int n=0;
for(int i=0;i<num.size();i++)
{//保留的条件 不重复要 检查程序的边界
if(i==0||(num[i]!=num[i-1]))
{//保留
nums[n]=num[i];
n++;
}
}
return n;
2.283 移动0
int n=0;
for(int i=0;i<num.size();i++)
{//保留的条件 非0 要 0不要
if(num[i]!=0)
{//保留
nums[n]=num[i];
n++;
}
}
//后面补0
while(n<num.size())
{
num[n]=0;
}
3.88 合并2个有序数组
顺着做不行就倒着做
- 正着做
vector<int>result;
int i=0,j=0;
while(i<m||j<n)
{
if(j>=n||num1[i]<num2[j])
{//什么时候要num1[i] j出界或者ij都没有出界, 要小的
result.push_back(num1[i]);
i++;
}
else
{
result.push_back(num2[i]);
j++;
}
}
- 倒着做:谁大要谁
int i=m-1;
int j=n-1;
for(int k=m+n-1;k>=0;k--)
{
//什么时候要nums1[i] j出界了或者i,j都没有出界,要大的
if(j<0||(i>=0&&(num1[i]>num2[j])))
{
num1[k]=num1[i];
i--;
}
else
{
num1[k]=num2[j];
j--;
}
}
设计变长数组
特点:
- 支持索引与随机访问
- 分配多长的连续空间?
- 空间不够用了怎么办?
- 空间剩余很多如何回收?
例子:C++ 的vector
简易的实现方法
- 初始:空数组,分配常数空间,记录实际长度size和容量
- push back:若空间不够,重新申请2倍大小的连续空间,拷贝到新空间,释放旧空间
- pop back:若空间利用率size/capacity不到25%,释放一半的空间
- 均摊O(1)