5798. Cyclic rotation matrix (simulation questions)
Link to the topic: https://leetcode-cn.com/problems/cyclically-rotating-a-grid/
topic:
You are given an integer matrix grid of size mxn, where m and n are even numbers; you are also given an integer k. The matrix is composed of several layers, as shown in the figure below, each color represents a layer: the
cyclic rotation of the matrix is done by cyclically rotating each layer in the matrix separately. When performing a circular rotation operation on a layer, each element in the layer will replace its counterclockwise adjacent elements. An example of rotation is as follows:
return the matrix after performing k times of cyclic rotation operations.
Example 1:
输入: grid = [[40,10],[30,20]], k = 1
输出: [[10,20],[40,30]]
解释: 上图展示了矩阵在执行循环轮转操作时每一步的状态。
Example 2:
输入: grid = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]], k = 2
输出: [[3,4,8,12],[2,11,10,16],[1,7,6,15],[5,9,13,14]]
解释: 上图展示了矩阵在执行循环轮转操作时每一步的状态。
Notice:
- m == grid.length
- n == grid[i].length
- 2 <= m, n <= 50
- m and n are both even numbers
- 1 <= grid[i][j] <= 5000
- 1 <= k <= 1 0 9 10^9 109
Problem-solving ideas:
The meaning of the question is very clear. Go around the edge of the matrix, layer by layer, just like peeling an apple. The layering effect is as follows:
We let n and m be the height and width of the matrix, so how many layers can we divide along the edge of the matrix? After a simple calculation, we will know that
the number of layers is: min (n, m) / 2 the number of layers is: min (n, m)/2The number of layers is : m i n ( n ,m ) / 2
The title is to let us move k steps counterclockwise for each layer, and ask us what the matrix looks like after moving k steps.
Observing the value range of k, we will find that it is very large, as high as 1 0 9 10^9109 . Move1 0 9 10^910The time complexity of 9 steps is very high. How can we reduce the time complexity?
If the length of our layer is l, we need to move k steps counterclockwise. Then we find that moving l % k is equivalent to moving l steps. If the length of our layer is l, we need to move k steps counterclockwise. Then we find that moving l\%k is equivalent to moving l stepsIf the length of our layer is l ,Need to move k steps counterclockwise . Then we find that moving l % k is equivalent to moving l steps
Then we only need to ask for the length ll of this layerl , movel % kl\%kl % k steps are enough. We assumeleft , right , top , bottom left , right , top , bottoml e ft , r igh t , top , b ot to m respectively correspond to the left boundary, right boundary, upper boundary and lower boundaryof this layer , then lll:
l = ( b o t t o m − t o p + 1 ) ∗ 2 + ( r i g h t − l e f t − 1 ) ∗ 2 l=(bottom-top+1)*2+(right-left-1)*2 l=(bottom−top+1)∗2+(right−left−1)∗2
Next we need to simulate moving one step counterclockwise. The core code is as follows:
for(int i=bottom;i>top;i--)
grid[i][left]=grid[i-1][left]; //left
grid[top][left]=top_left;
for(int j=right;j>left+1;j--)
grid[bottom][j]=grid[bottom][j-1]; // bottom
grid[bottom][left+1]=bottom_left;
for(int i=top;i<bottom-1;i++) //right
grid[i][right]=grid[i+1][right];
grid[bottom-1][right]=bottom_right;
for(int j=left+1;j<right-1;j++)//top
grid[top][j]=grid[top][j+1];
grid[top][right-1]=top_right;
leetcode AC code
class Solution {
public:
vector<vector<int>> rotateGrid(vector<vector<int>>& grid, int k) {
int n,m;
n=grid.size();
m=grid[0].size();
int top,bottom,left,right,sum,t;
int bottom_left,bottom_right,top_left,top_right;
for(int ii=0;ii<min(n,m)/2;ii++)
{
top=ii;
bottom=n-1-ii;
left=ii;
right=m-1-ii;
sum=(bottom-top+1)*2+(right-left-1)*2;
/*if(sum==0)
{
vector<int>in;
in.push_back(1);
in.push_back(1);
in.push_back(1);
vector<vector<int>> out;
out.push_back(in);
return out;
}*/
t=k%sum;
while(t--)
{
top_left=grid[top][left+1];
bottom_left=grid[bottom][left];
bottom_right=grid[bottom][right];
top_right=grid[top][right];
for(int i=bottom;i>top;i--)
grid[i][left]=grid[i-1][left]; //left
grid[top][left]=top_left;
for(int j=right;j>left+1;j--)
grid[bottom][j]=grid[bottom][j-1]; // bottom
grid[bottom][left+1]=bottom_left;
for(int i=top;i<bottom-1;i++) //right
grid[i][right]=grid[i+1][right];
//grid[top][right-1]=top_right;
grid[bottom-1][right]=bottom_right;
for(int j=left+1;j<right-1;j++)//top
grid[top][j]=grid[top][j+1];
grid[top][right-1]=top_right;
}
}
return grid;
}
};
Finally, thank you for your study~