首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

一杯蜜桃四季春的时间吃透一道高频面试算法题——旋转图像

  • 25-04-25 13:21
  • 4198
  • 14191
juejin.cn

题目描述——旋转图像

给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。

你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。

  示例 1:

lua
代码解读
复制代码
输入: matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出: [[7,4,1],[8,5,2],[9,6,3]]

示例 2:

lua
代码解读
复制代码
输入: matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]] 输出: [[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

  提示:

  • n == matrix.length == matrix[i].length
  • 1 <= n <= 20
  • -1000 <= matrix[i][j] <= 1000

二、题解

js
代码解读
复制代码
/** * @param {number[][]} matrix * @return {void} Do not return anything, modify matrix in-place instead. */ var rotate = function(matrix) { const n = matrix.length; // 逐层处理,外层到内层的边界 for (let layer = 0; layer < Math.floor(n / 2); layer++) { const first = layer; // 当前层的起始索引 const last = n - 1 - layer; // 当前层的结束索引 // 遍历当前层的元素 for (let i = first; i < last; i++) { const offset = i - first; // 当前元素的偏移量 // 依次交换四个角的元素,实现旋转 // 1. 保存 top-left const topLeft = matrix[first][i]; // 2. 赋值 bottom-left 到 top-left matrix[first][i] = matrix[last - offset][first]; // 3. 赋值 bottom-right 到 bottom-left matrix[last - offset][first] = matrix[last][last - offset]; // 4. 赋值 top-right 到 bottom-right matrix[last][last - offset] = matrix[i][last]; // 5. 将之前保存的 top-left 放入 top-right matrix[i][last] = topLeft; } } };

核心思想:

将矩阵的旋转分解为逐层旋转。每一“层”可以想象成一个围绕矩阵的边框。 对于一个 n x n 的矩阵,最多有 n / 2 层需要旋转(如果 n 是奇数,最中央的元素不需要旋转)。 对于每一层,我们围绕其边界上的元素执行四路交换,模拟旋转 90 度的过程。 即 Top -> Right, Right -> Bottom, Bottom -> Left, Left -> Top。

详细解释:

  1. 分层旋转 (Layer-by-Layer Rotation):

    • 算法的核心思想是,将整个正方形矩阵的旋转,转化为对矩阵每一圈元素的旋转。 想象一下,一个嵌套的正方形,从最外层开始,逐步向内。
    • 对每一层独立地执行旋转操作。
    • Math.floor(n / 2) 确定了需要处理的“层”的数量。 如果 n 是奇数,那最中心的单个元素或者小的 1x1 方块是不需要旋转的。
  2. 边界确定 (Boundary Definition):

    • first = layer:当前层的起始索引,代表从矩阵最外侧的第 layer 层开始处理。
    • last = n - 1 - layer:当前层的结束索引,代表到矩阵内侧的第 layer 层结束。
  3. 四路交换 (Four-Way Swap):

    • 这是实现旋转的关键。 对于当前层的每一个元素(除了最后一个),执行四次赋值操作,模拟元素旋转到新的位置:

      • topLeft = matrix[first][i] : 保存当前层的“左上角”的值。 这个值会被后续的赋值覆盖,因此需要保存起来。 这里的“左上角”实际上指的是当前行从左至右的某个元素。
      • matrix[first][i] = matrix[last - offset][first] : 将底部的元素移动到顶部。 该行的index为first, 列的index为 i, last - offset是底部对应位置的索引,从而实现底部->顶部。
      • matrix[last - offset][first] = matrix[last][last - offset] : 将右侧的元素移动到底部。 last是底部的行index. last - offset 是右侧列的index.
      • matrix[last][last - offset] = matrix[i][last] : 将顶部的元素移动到右侧。 i 为顶部的行。last为右侧的列,
      • matrix[i][last] = topLeft: 将临时保存的左上角元素(初始值)移动到左侧。topLeft保存开始旋转之前的顶部元素。现在旋转到左边了。
    • 使用 offset 变量来确定每一边的对应元素,确保每一圈都能正确旋转。

注意事项:

  1. 理解层的概念:  代码中 “层” 是指从矩阵外向内的一圈圈的元素。 要理解外圈如何影响内圈。
  2. 坐标计算:  需要非常小心计算行和列的索引,尤其是在使用 offset 的时候。 确保正确对应需要交换的四个元素。
  3. 边界条件:  for (let i = first; i < last; i++) 中的 i < last 是为了避免重复操作最后一个元素。 例如一个4x4 的矩阵,在layer=0时, i的取值为 0,1,2。
  4. 原地操作:  理解为什么这个算法可以原地旋转矩阵。 它只使用了有限的几个变量(layer, first, last, i, offset, topLeft)来辅助旋转,不需要额外的矩阵空间。
  5. 调试:  调试的时候可以使用小规模的矩阵, 手动模拟坐标的改变,能更好地理清代码的逻辑。
  6. 避免混淆:  i 用来遍历一行的元素,layer用来表示不同的圈层, offset用来根据当前圈层计算对应位置,first确定每一圈的起始坐标 last 确定结束坐标。

三、结语

再见!

注:本文转载自juejin.cn的天天扭码的文章"https://juejin.cn/post/7496369162485153807"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

104
前端
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top