constint DIR[4][2] = {{0,1},{1,0},{0,-1},{-1,0}}; vector<vector<int>> spiralMatrixIII(int rows, int cols, int rStart, int cStart) { vector<vector<int>> ans; int total = rows*cols; int num = 1; int i = rStart,j = cStart; //令i,j记录路径的实时位置 int left = cStart - 1,right = cStart + 1,top = rStart - 1,bottom = rStart + 1; //确定边界 int dir=0; //记录方向 while(num <= total){ if(i>=0&&i<rows&&j>=0&&j<cols){ //当路径到达矩阵内部时,记录当前位置 ans.push_back({i,j}); num++; } if(dir==0&&j==right){ //如果向右移动触碰右边界 dir+=1; //则转向 right++; //并拓展右边界 }elseif(dir==1&&i==bottom){ //如果向下移动触碰下边界 dir+=1; //则转向 bottom++; //并拓展下边界 }elseif(dir==2&&j==left){ //... dir+=1; left--; }elseif(dir==3&&i==top){ //... dir=0; top--; } i += DIR[dir][0]; //根据方向来更新位置 j += DIR[dir][1]; } return ans; }
规律法
我们可以观察螺线路径的一个显著规律:每转向两次会更新一次前进的步长
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
constint DIR[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; vector<vector<int>> spiralMatrixIII(int R, int C, int r0, int c0) { int num=0; int dir=0; int run=2; //步长计数器 vector<vector<int>> ans;
while(num < R * C){ for(int i = 0; i < run / 2; i ++){ //遍历步长,每转两下就会增加一步 if(r0 >= 0 && r0 < R && c0 >= 0 && c0 < C) ans.push_back({r0, c0}), ++ num; r0 += DIR[dir][0]; c0 += DIR[dir][1]; } pos = (pos + 1) % 4; //每遍历一次步长,就转向 run++; //利用取整的性质,每转向两次才会增加一次步长 } return ans; }