LeetCode 每日一题笔记 日期:2026.05.09 题目:1914. 循环轮转矩阵

LeetCode 每日一题笔记

0. 前言

  • 日期:2026.05.09
  • 题目:1914. 循环轮转矩阵
  • 难度:中等
  • 标签:数组、矩阵、模拟

1. 题目理解

问题描述

给你一个 m x n 的整数矩阵 grid,其中 mn 都是偶数;另给你一个整数 k。矩阵由若干层组成,循环轮转是分别对每一层完成的。对某一层进行一次循环旋转操作时,层中的每一个元素将会取代其逆时针方向 的相邻元素。返回执行 k 次循环轮转操作后的矩阵。

示例

输入:grid = \[40,10,30,20], k = 1

输出:\[10,20,40,30]

解释:矩阵只有一层,逆时针轮转一次后,元素按 40→10→20→30→40 的顺序移动,得到新矩阵。

2. 解题思路

核心观察

  • 矩阵的每一层可以独立处理,轮转操作不影响其他层;
  • 每一层的元素按逆时针顺序排列成一维数组后,轮转 k 次等价于对数组做一次左移 k(模层长度);
  • 左移 k 位可通过拼接 list[k:]list[:k] 实现,无需多次循环。

算法步骤

  1. 分层处理 :遍历矩阵的每一层,层数为 min(m, n) / 2
  2. 抽取层元素:按上→右→下→左的逆时针顺序,将当前层元素存入一维列表;
  3. 计算轮转偏移shift = k % 层长度,避免无效的完整轮转;
  4. 构建轮转后列表 :将原列表从 shift 处断开,拼接为新列表;
  5. 写回矩阵:按抽取顺序将轮转后的元素写回原矩阵的当前层。

3. 代码实现

java 复制代码
package lc1914;

import java.util.ArrayList;
import java.util.List;

class Solution {
    public int[][] rotateGrid(int[][] grid, int k) {
        int m = grid.length;
        int n = grid[0].length;
        int layers = Math.min(m, n) / 2;

        for (int layer = 0; layer < layers; layer++) {
            List<Integer> list = new ArrayList<>();
            for (int j = layer; j < n - layer; j++) {
                list.add(grid[layer][j]);
            }
            for (int i = layer + 1; i < m - layer; i++) {
                list.add(grid[i][n - layer - 1]);
            }
            for (int j = n - layer - 2; j >= layer; j--) {
                list.add(grid[m - layer - 1][j]);
            }
            for (int i = m - layer - 2; i > layer; i--) {
                list.add(grid[i][layer]);
            }

            int len = list.size();
            int shift = k % len;
            if (shift == 0) continue;

            List<Integer> rotated = new ArrayList<>();
            for (int i = shift; i < len; i++) {
                rotated.add(list.get(i));
            }
            for (int i = 0; i < shift; i++) {
                rotated.add(list.get(i));
            }

            int idx = 0;
            for (int j = layer; j < n - layer; j++) {
                grid[layer][j] = rotated.get(idx++);
            }
            for (int i = layer + 1; i < m - layer; i++) {
                grid[i][n - layer - 1] = rotated.get(idx++);
            }
            for (int j = n - layer - 2; j >= layer; j--) {
                grid[m - layer - 1][j] = rotated.get(idx++);
            }
            for (int i = m - layer - 2; i > layer; i--) {
                grid[i][layer] = rotated.get(idx++);
            }
        }
        return grid;
    }
}

4. 代码优化说明

  • 利用 k % len 消除完整轮转,避免无效操作;
  • 用一次列表拼接替代 k 次循环移动,将层内轮转的时间复杂度从 O(k*len) 降为 O(len)
  • 原地修改矩阵,无需额外空间存储副本,节省内存。

5. 复杂度分析

  • 时间复杂度 :O(m×n)O(m \times n)O(m×n)
    • 每个元素仅被抽取、轮转、写回各一次,总操作数为矩阵元素总数。
  • 空间复杂度 :O(min⁡(m,n))O(\min(m, n))O(min(m,n))
    • 每层最多存储一圈元素,最大长度为 2*(m + n),实际为矩阵周长的一半量级。

6. 总结

  • 核心思路是分层抽取 + 一维轮转,将二维矩阵的层操作转化为一维数组的拼接操作;
  • 关键技巧:利用模运算消除无效轮转,通过一次列表拼接实现多次轮转的效果;
  • 该方法时间复杂度为线性级,是矩阵层轮转问题的最优实现方式。
相关推荐
FellAveal12 小时前
【Go语言入门学习笔记】Part18.工作池与WaitGroup(也即协程池)
笔记·学习·golang
xqqxqxxq12 小时前
Java Socket 多人聊天室(私聊+群聊)技术笔记(V4版本)
java·网络·笔记
龙仔72512 小时前
人大金仓OS_Core数据库自动备份实施笔记(银河麒麟Linux)
linux·数据库·笔记·备份·人大金仓
小poop13 小时前
轮转数组:从暴力到最优,一题掌握算法复杂度分析
数据结构·算法·leetcode
Z59981784114 小时前
c#软件开发学习笔记--Modbus-RTU通讯
笔记·学习·c#
quanjui15 小时前
【医学尝试】基于Segment Anything Model的医学图像分割研究:眼底OCT与X线胸片微调实战
人工智能·笔记·学习
小黄蚁15 小时前
FreeRTOS学习笔记(十二)
笔记·学习
茯苓gao16 小时前
嵌入式开发笔记:电机参数辨识与自学习完全指南——从电气参数到机械特性的深度解析
笔记·嵌入式硬件·学习
优化Henry16 小时前
学习笔记之VoNR语音业务注册流程
网络·笔记·学习·5g·信息与通信
玖玥拾16 小时前
LeetCode 27 移除元素
算法·leetcode