LeetCode 每日一题笔记 日期:2025.03.22 题目:1886.判断矩阵经轮转后是否一致

LeetCode 每日一题笔记

0. 前言

  • 日期:2025.03.22
  • 题目:1886.判断矩阵经轮转后是否一致
  • 难度:简单
  • 标签:数组 矩阵 旋转 模拟

1. 题目理解

问题描述

给你两个大小为 n x n 的二进制矩阵 mat 和 target 。现以 90 度顺时针轮转矩阵 mat 中的元素若干次,如果能够使 mat 与 target 一致,返回 true ;否则,返回 false 。

示例

输入:mat = [[0,1],[1,0]], target = [[1,0],[0,1]]

输出:true

解释:

mat 顺时针轮转 90 度后:

原矩阵 [[0,1],[1,0]] → 旋转90度后 [[1,0],[0,1]],与 target 一致,因此返回 true。

补充说明:

  • 正方形矩阵顺时针旋转90度最多旋转4次会回到原始状态;
  • 需检查旋转0次(原矩阵)、90次、180次、270次后是否与target一致。

2. 解题思路

核心观察

  • 正方形矩阵顺时针旋转90度的规律:先转置矩阵(行列互换),再反转每一行;
  • 矩阵最多旋转4次就会回到初始状态,因此只需检查0/90/180/270度旋转后的结果;
  • 若旋转4次后仍未匹配target,则返回false。

算法步骤

  1. 前置校验:检查mat和target的行列数是否一致,不一致直接返回false;
  2. 检查初始状态:若mat未旋转时已与target一致,直接返回true;
  3. 模拟旋转并校验
    • 对mat执行90度顺时针旋转;
    • 检查旋转后的矩阵是否与target一致,一致则返回true;
    • 重复旋转和校验操作,直到完成3次旋转(覆盖90/180/270度);
  4. 最终判断:若4种旋转状态均不匹配,返回false。

3. 代码实现

java 复制代码
class Solution {
    public static boolean same(int[][] mat, int[][] target, int a, int b) {
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < b; j++) {
                if (mat[i][j] != target[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }
    public static int[][] switchroom(int[][] mat) {
        int n = mat.length;
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                int temp = mat[i][j];
                mat[i][j] = mat[j][i];
                mat[j][i] = temp;
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n / 2; j++) {
                int temp = mat[i][j];
                mat[i][j] = mat[i][n - 1 - j];
                mat[i][n - 1 - j] = temp;
            }
        }
        return mat;
    }
    public boolean findRotation(int[][] mat, int[][] target) {
        int a = mat.length;
        int b = mat[0].length;
        int c = target.length;
        int d = target[0].length;
        if (a != c || b != d) {
            return false;
        }
        if (same(mat, target, a, b)) {
            return true;
        }
        switchroom(mat);
        if (same(mat, target, a, b)) {
            return true;
        }
        switchroom(mat);
        if (same(mat, target, a, b)) {
            return true;
        }
        switchroom(mat);
        if (same(mat, target, a, b)) {
            return true;
        }
        return false;
    }
}

4. 代码优化说明

优化点1:避免修改原矩阵(无副作用)

原代码直接修改输入的mat矩阵,可能对外部使用造成影响,优化为复制矩阵后旋转:

java 复制代码
public boolean findRotation(int[][] mat, int[][] target) {
    int n = mat.length;
    // 复制原矩阵,避免修改输入
    int[][] copy = new int[n][n];
    for (int i = 0; i < n; i++) {
        System.arraycopy(mat[i], 0, copy[i], 0, n);
    }
    // 检查4种旋转状态
    for (int i = 0; i < 4; i++) {
        if (same(copy, target, n, n)) {
            return true;
        }
        copy = switchroom(copy);
    }
    return false;
}

优化点2:简化旋转逻辑(提取独立方法)

将旋转逻辑封装为更清晰的方法,提升可读性:

java 复制代码
private int[][] rotate90(int[][] matrix) {
    int n = matrix.length;
    int[][] res = new int[n][n];
    // 直接计算旋转后位置,无需转置+反转(更直观)
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            res[j][n - 1 - i] = matrix[i][j];
        }
    }
    return res;
}

优化点3:提前终止循环

原代码重复调用switchroom和same,优化为循环遍历4次,匹配后立即返回:

java 复制代码
public boolean findRotation(int[][] mat, int[][] target) {
    int n = mat.length;
    if (n != target.length || n != target[0].length) return false;
    int[][] curr = mat;
    for (int i = 0; i < 4; i++) {
        if (same(curr, target, n, n)) return true;
        curr = switchroom(curr);
    }
    return false;
}

5. 复杂度分析

  • 时间复杂度:(O(n^2))

    • 每次矩阵旋转的时间为 (O(n^2))(转置+反转每行);
    • 每次矩阵比较的时间为 (O(n^2));
    • 最多执行4次旋转+4次比较,总时间为 (4 \times (n^2 + n^2) = O(n^2))(常数系数可忽略)。
  • 空间复杂度

    • 原代码:(O(1))(原地旋转,仅使用常量临时变量);
    • 优化版(不修改原矩阵):(O(n^2))(存储矩阵副本)。

6. 总结

  • 核心思路是模拟旋转 + 逐次校验:利用矩阵旋转规律模拟90度顺时针旋转,检查4种旋转状态是否匹配target;
  • 关键技巧:正方形矩阵顺时针旋转90度可通过"转置+反转每行"实现,且最多旋转4次必回原状态;
  • 优化方向:避免修改原矩阵提升代码鲁棒性,直接计算旋转后位置简化旋转逻辑。

关键点回顾

  1. 矩阵顺时针旋转90度的两种实现方式:转置+反转行,或直接计算位置 res[j][n-1-i] = matrix[i][j]
  2. 只需检查0/90/180/270度四种旋转状态,无需无限旋转;
  3. 原地旋转空间复杂度为 (O(1)),是该问题的最优空间方案。
相关推荐
还不秃顶的计科生1 小时前
力扣第84题:完全平方数
算法·leetcode·职场和发展
云边散步1 小时前
godot2D游戏教程系列二(19)
笔记·学习·游戏·游戏开发
sonnet-10292 小时前
拓扑排序的实现
java·c语言·开发语言·笔记·算法
米粒12 小时前
力扣算法刷题 Day 20
算法·leetcode·职场和发展
带娃的IT创业者2 小时前
意图识别与工具智能路由:17 维关键词矩阵如何让 LLM 精准选择 38 个工具
线性代数·矩阵
不想看见4042 小时前
Min Stack栈和队列--力扣101算法题解笔记
java·笔记·leetcode
马猴烧酒.2 小时前
【面试八股|计算机网络】计算机网络常见面试题详解笔记
java·开发语言·网络·笔记·计算机网络·算法·面试
学机械的鱼鱼2 小时前
【学习笔记】如何快速理解ROS2
笔记·学习
北顾笙9802 小时前
测开准备-day04数据结构力扣
数据结构·算法·leetcode