leetcode 1914. 循环轮转矩阵 中等

给你一个大小为 m x n 的整数矩阵 grid​​​ ,其中 mn 都是 偶数 ;另给你一个整数 k

矩阵由若干层组成,如下图所示,每种颜色代表一层:

矩阵的循环轮转是通过分别循环轮转矩阵中的每一层完成的。在对某一层进行一次循环旋转操作时,层中的每一个元素将会取代其 逆时针方向的相邻元素。轮转示例如下:

返回执行 k 次循环轮转操作后的矩阵。

示例 1:

复制代码
输入:grid = [[40,10],[30,20]], k = 1
输出:[[10,20],[40,30]]
解释:上图展示了矩阵在执行循环轮转操作时每一步的状态。

示例 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]]
解释:上图展示了矩阵在执行循环轮转操作时每一步的状态。

提示:

  • m == grid.length
  • n == grid[i].length
  • 2 <= m, n <= 50
  • mn 都是 偶数
  • 1 <= grid[i][j] <= 5000
  • 1 <= k <= 10^9

分析:对于一个 m×n 的矩阵 grid,它的层数为 min(m/2,n/2)。可以从外向内枚举矩阵的每一层模拟循环轮转操作。

从左上角起按照逆时针方向遍历每一层的元素,遍历过程分为四个部分,每个部分按顺序遍历每条边除了最后一个元素以外的所有元素。将这些元素的值保存在数组 num 中,并计算元素总数,即数组的长度 len。此时,如果对该层元素进行 len 次循环轮转操作,那么该层元素不会改变。因此,实际的循环轮转操作数量即为 k=k%len。

之后重新按照顺时针遍历行列坐标数组,并在 grid 中更新每个坐标对应的轮转操作后的取值。枚举并更新完所有层后,grid 即为轮转操作后的矩阵。

cpp 复制代码
class Solution {
public:
    vector<vector<int>> rotateGrid(vector<vector<int>>& grid, int k) {
        vector<vector<int>>ans=grid;
        int m=grid.size(),n=grid[0].size(),layer=min(m,n)/2;
        for(int l=0;l<layer;++l)
        {
            int x=0+l,y=0+l,len=(m-l*2)*2+(n-l*2)*2-4,cnt=0;
            int left=y,right=n-l,down=m-l,f1,f2;f1=f2=0;
            vector<int>num;
            while(cnt<len)
            {
                num.push_back(grid[x][y]);cnt++;
                if(y+1<right&&!f1)y++;
                else if(x+1<down&&!f2)x++,f1=1;
                else if(y-1>=left)y--,f2=1;
                else x--;
            }
            f1=f2=0;

            x=0+l,y=0+l;
            for(int i=0,j=k%cnt;i<cnt;++i,j=(j+1)%cnt)
            {
                ans[x][y]=num[j];
                if(y+1<right&&!f1)y++;
                else if(x+1<down&&!f2)x++,f1=1;
                else if(y-1>=left)y--,f2=1;
                else x--;
            }
        }
        return ans;
    }
};
相关推荐
wabs6662 小时前
关于二叉树【力扣100.相同的树的思考】
数据结构·c++·算法·leetcode·二叉树·递归法
alphaTao3 小时前
LeetCode 每日一题 2026/9/14-2026/9/20
算法·leetcode
hanlin033 小时前
刷题笔记:力扣第560题-和为k的子数组
笔记·算法·leetcode
Navigator_Z15 小时前
LeetCode //C - 1252. Cells with Odd Values in a Matrix
c语言·算法·leetcode
语戚17 小时前
力扣 1621. 大小为K的不重叠线段的数目:动态规划(Java 实现)
java·算法·leetcode·动态规划·力扣·dp
青山木17 小时前
Hot 100 --- 最长有效括号
java·数据结构·算法·leetcode·动态规划
这料鬼有毒19 小时前
二刷hot100-1143.最长公共子序列
算法·leetcode·动态规划
Nil2081 天前
leetcode 394字符串解码
leetcode
一起努力啊~1 天前
算法题打卡力扣第1658题:将 x 减到 0 的最小操作数(mid)
学习·leetcode