PPAP到底要提交什么
2026/8/11 1:38:28
**数组(Array)**是一种线性数据结构,由相同类型的元素按一定顺序排列而成,通过索引访问元素。
示例:
一维数组:[1, 2, 3, 4, 5] 索引: 0 1 2 3 4 二维数组(矩阵): [1, 2, 3] [4, 5, 6] [7, 8, 9] 行索引:0, 1, 2 列索引:0, 1, 2一维数组遍历:
// 方式1:索引遍历for(inti=0;i<nums.size();i++){// 访问 nums[i]}// 方式2:范围遍历for(intnum:nums){// 访问 num}二维数组遍历:
// 遍历二维数组for(inti=0;i<matrix.size();i++){for(intj=0;j<matrix[i].size();j++){// 访问 matrix[i][j]}}重要特性:
示例:
// 删除索引为index的元素voidremoveElement(intarr[],int&size,intindex){if(index<0||index>=size){return;// 索引无效}// 将后续元素前移for(inti=index;i<size-1;i++){arr[i]=arr[i+1];}size--;// 减少数组大小}前缀和是数组中前i个元素的和,用于快速计算区间和。
定义:
prefix[i] = arr[0] + arr[1] + ... + arr[i][a, b]的和 =prefix[b] - prefix[a-1](a > 0)[0, b]的和 =prefix[b]示例:
原数组:[1, 2, 3, 4, 5] 前缀和:[1, 3, 6, 10, 15] 计算区间[1, 3]的和: prefix[3] - prefix[0] = 10 - 1 = 9 验证:2 + 3 + 4 = 9 ✓核心思路:
模板代码:
// 构造前缀和数组vector<int>prefix(n);intpresum=0;for(inti=0;i<n;i++){presum+=arr[i];prefix[i]=presum;}适用场景:多次查询数组的区间和
核心思路:
模板代码:
// LeetCode 58. 区间和#include<iostream>#include<vector>usingnamespacestd;intmain(){intn,a,b;cin>>n;vector<int>vec(n);// 输入数组vector<int>p(n);// 前缀和数组intpresum=0;// 构造前缀和数组for(inti=0;i<n;i++){scanf("%d",&vec[i]);presum+=vec[i];p[i]=presum;}// 查询区间和while(~scanf("%d%d",&a,&b)){intsum;if(a==0){sum=p[b];// 区间[0, b]的和}else{sum=p[b]-p[a-1];// 区间[a, b]的和}printf("%d\n",sum);}return0;}关键点:
p[i]表示前i+1个元素的和[a, b]的和 =p[b] - p[a-1]p[b]**矩阵(Matrix)**是二维数组,由行和列组成。
基本操作:
matrix[i][j](第i行第j列)matrix.size()matrix[0].size()按行遍历:
for(inti=0;i<matrix.size();i++){for(intj=0;j<matrix[i].size();j++){// 访问 matrix[i][j]}}按列遍历:
for(intj=0;j<matrix[0].size();j++){for(inti=0;i<matrix.size();i++){// 访问 matrix[i][j]}}适用场景:按螺旋顺序遍历或生成矩阵
核心思路:
适用场景:按螺旋顺序遍历矩阵并输出元素
模板代码:
// LeetCode 54. 螺旋矩阵classSolution{public:vector<int>spiralOrder(vector<vector<int>>&matrix){vector<int>ans;intm=matrix.size();intn=matrix[0].size();intstartx=0,starty=0;// 起始位置intoffset=1;// 每圈的偏移量intloop=min(m,n)/2;// 循环圈数// 处理单行或单列if(m==1){returnmatrix[0];}if(n==1){for(intk=0;k<m;k++){ans.push_back(matrix[k][0]);}returnans;}// 按圈遍历(左闭右开)while(loop--){inti=startx,j=starty;// 第一行:从左到右for(;j<n-offset;j++){ans.push_back(matrix[i][j]);}// 最后一列:从上到下for(;i<m-offset;i++){ans.push_back(matrix[i][j]);}// 最后一行:从右到左for(;j>starty;j--){ans.push_back(matrix[i][j]);}// 第一列:从下到上for(;i>startx;i--){ans.push_back(matrix[i][j]);}startx++;starty++;offset++;}// 处理剩余的单行或单列if(min(m,n)%2==1){if(m<=n){// 剩余单行for(intjj=starty;jj<n-offset+1;jj++){ans.push_back(matrix[startx][jj]);}}else{// 剩余单列for(intii=startx;ii<m-offset+1;ii++){ans.push_back(matrix[ii][starty]);}}}returnans;}};关键点:
适用场景:生成一个n×n的螺旋矩阵
模板代码:
// LeetCode 59. 螺旋矩阵IIclassSolution{public:vector<vector<int>>generateMatrix(intn){vector<vector<int>>vec(n,vector<int>(n));intstartx=0,starty=0;// 起始位置intoffset=1;// 每圈的偏移量intcount=1;// 填充的数字intcir=n/2;// 循环圈数intmid=n/2;// 中间位置// 按圈填充(左闭右开)while(cir--){inti=startx,j=starty;// 第一行:从左到右for(;j<n-offset;j++){vec[i][j]=count++;}// 最后一列:从上到下for(;i<n-offset;i++){vec[i][j]=count++;}// 最后一行:从右到左for(;j>startx;j--){vec[i][j]=count++;}// 第一列:从下到上for(;i>starty;i--){vec[i][j]=count++;}startx++;starty++;offset++;}// 处理中间元素(n为奇数时)if(n%2){vec[mid][mid]=count;}returnvec;}};关键点:
适用场景:统计矩阵的行和、列和等
模板代码:
// 统计矩阵的行和与列和vector<int>horizontal(n,0);// 每行的和vector<int>vertical(m,0);// 每列的和// 统计行和for(inti=0;i<n;i++){for(intj=0;j<m;j++){horizontal[i]+=matrix[i][j];}}// 统计列和for(intj=0;j<m;j++){for(inti=0;i<n;i++){vertical[j]+=matrix[i][j];}}| 操作 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
| 访问元素 | O(1) | O(1) | 通过索引直接访问 |
| 遍历数组 | O(n) | O(1) | 需要访问所有元素 |
| 查找元素 | O(n) | O(1) | 线性查找 |
| 插入元素 | O(n) | O(1) | 需要移动后续元素 |
| 删除元素 | O(n) | O(1) | 需要移动后续元素 |
| 前缀和构造 | O(n) | O(n) | 需要额外空间存储前缀和 |
| 区间和查询 | O(1) | O(1) | 使用前缀和数组 |
| 矩阵遍历 | O(m × n) | O(1) | m为行数,n为列数 |
| 螺旋矩阵 | O(m × n) | O(1) | 需要遍历所有元素 |
注意:
区间和问题
矩阵遍历问题
数组基本操作
二维数组问题
当遇到以下情况时,考虑使用数组技巧:
示例:
// 问题:多次查询数组的区间和// 暴力解法:每次查询O(n)for(inti=a;i<=b;i++){sum+=arr[i];}// 前缀和解法:预处理O(n),查询O(1)vector<int>prefix(n);// 构造前缀和数组for(inti=0;i<n;i++){prefix[i]=(i==0?arr[i]:prefix[i-1]+arr[i]);}// 查询区间和intsum=prefix[b]-(a>0?prefix[a-1]:0);区间和查询
子数组和问题
螺旋矩阵
矩阵统计
矩阵遍历
数组遍历
数组修改
普通数组是基础的数据结构,掌握数组的基本操作和常用技巧对于解决算法问题至关重要。
核心要点:
使用建议:
常见题型总结: