标题唐是因为要满五个字。
矩阵矩阵,我终于舍得碰你了
螺旋矩阵
模拟转圈的过程,算模拟题
其实开始写这篇的时候,我还是没搞懂^^(我觉得有点像指针)
希望在写的结尾我懂了
模拟:一圈一圈转,一行一列转,二维数组下标相当于坐标,一圈转完记得缩小
看代码随想录的视频思路倒是懂了,在细节上依旧nonono
找了个luogu的题自己先写写
luoguP2239 [NOIP 2014 普及组] 螺旋矩阵
自己写以为会AC的代码
#include <bits/stdc++.h> using namespace std; int nums[30000][30000]; int main() { int n, i, j; cin >> n >> i >> j; int x = 0; int y = 0; int val = 1; int setoff = 0; // 偏移量从0开始 while (setoff < n / 2) { // 循环条件为圈数判断 // 上边界:从左到右 for (x = setoff; x < n - setoff - 1; x++) { nums[setoff][x] = val++; } // 右边界:从上到下(跳过角点) for (y = setoff; y < n - setoff - 1; y++) { nums[y][n - setoff - 1] = val++; } // 下边界:从右到左(跳过角点) for (x = n - setoff - 1; x > setoff; x--) { nums[n - setoff - 1][x] = val++; } // 左边界:从下到上(跳过角点) for (y = n - setoff - 1; y > setoff; y--) { nums[y][setoff] = val++; } setoff++; // 进入内层 } // 如果是奇数阶矩阵,填充中心位置 if (n % 2 == 1) { nums[n / 2][n / 2] = val; } cout << nums[i-1][j-1] << endl; // 输出指定位置的值,注意索引从0开始 return 0; }实则大no特no,会MLE内存限制问题(Memory Limit Exceeded, MLE),问题在于nums[30000][30000]内存浪费,世界选择c++的原因是什么,灵活好用方便(瞎编的),这次问的千老师,不是顶楼的千老师啊喂,it said为了避免这个问题,可以使用动态内存分配,并且只在需要时分配内存
加了以下代码依旧MLE......
// 动态分配二维数组 int** nums = new int*[n]; for (int k = 0; k < n; k++) { nums[k] = new int[n]; } //while循环体省略 // 释放动态分配的内存 for (int k = 0; k < n; k++) { delete[] nums[k]; } delete[] nums;D老师说直接创建二维vector,vector会自动释放内存!
(但是在luogu里试了依旧不能解决MLE的问题)
P2239 [NOIP 2014 普及组] 螺旋矩阵 - 洛谷 o而k之链接放这里,解决超内存的题解五花八门,后续慢慢看,小萌鹅先学会螺旋矩阵的构造吧
以下为力扣中的一道螺旋矩阵
我按照我在luogu写的代码改编了一下,发现会超出一位,加上条件判断就不会了,代码如下:
#include <vector> class Solution { public: std::vector<int> spiralOrder(std::vector<std::vector<int>>& matrix) { int n = matrix.size(); int m = matrix[0].size(); std::vector<int> ans; int x = 0; int y = 0; int val = 0; int setoff = 0; // 循环条件为偏移量小于行数和列数的一半 while (setoff * 2 < n && setoff * 2 < m) { // 上边界:从左到右 for (x = setoff; x < m - setoff; ++x) { ans.push_back(matrix[setoff][x]); } // 右边界:从上到下 for (y = setoff + 1; y < n - setoff; ++y) { ans.push_back(matrix[y][m - setoff - 1]); } // 处理只有一行或只有一列的特殊情况 if (n - 2 * setoff > 1 && m - 2 * setoff > 1) { // 下边界:从右到左 for (x = m - setoff - 2; x >= setoff; --x) { ans.push_back(matrix[n - setoff - 1][x]); } // 左边界:从下到上 for (y = n - setoff - 2; y > setoff; --y) { ans.push_back(matrix[y][setoff]); } } setoff++; } return ans; } };一开始又犯了一个特别致命的错误,直接索引空容器的下标了......
虽然AC了依旧含有凑的成分在哈
以下为一位大佬@kaddy的题解:(清爽&&逻辑强)
class Solution { public: vector<int> spiralOrder(vector<vector<int>>& matrix) { int n=matrix.size(); int m=matrix[0].size(); vector<int> ans; int left=0,top=0,right=m-1,bottom=n-1; while(ans.size()<n*m) { for(int j=left;j<=right && ans.size()<n*m;j++) ans.push_back(matrix[top][j]); top++; for(int i=top;i<=bottom && ans.size()<n*m;i++) ans.push_back(matrix[i][right]); right--; for(int j=right;j>=left && ans.size()<n*m;j--) ans.push_back(matrix[bottom][j]); bottom--; for(int i=bottom;i>=top && ans.size()<n*m;i--) ans.push_back(matrix[i][left]); left++; } return ans; } };矩阵乘法等等后续编辑加上,今日先END!