算法练习第29题-旋转矩阵

467 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

一、题目

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

不占用额外内存空间能否做到?

示例 1:

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]


示例 2:

给定 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]
]

作者:力扣 (LeetCode)

链接:leetcode-cn.com/leetbook/re…

来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

二、思路

思路1

  • 创建一个新的二维数组

  • 通过嵌套循环将数据赋值给新的数组

  • 先看下赋值的规律,先看转变后的数组

// let matrix = [     
//   [7,4,1],
//   [8,5,2],
//   [9,6,3]
// ]
  • 这里我们要先拿到每行的数组,第一行是[7,4,1]

  • 在嵌套for循环中,第二层要从大到小循环

  • for(let j = len-1; j >= 0; j--)

  • 这样就可以按顺序拿到7,4,1的值

  • 依次循环拿到二维数组

  • 之后再通过嵌套循环赋值给matrix

思路2

// let matrix = [     
//   [1,2,3],
//   [4,5,6],
//   [7,8,9]
// ]
// let matrix = [     
//   [7,4,1],
//   [8,5,2],
//   [9,6,3]
// ]
  • 思路看图写代码,不然第一次写脑子真的不够用
  • 定义长度len = matrix.length
  • 把坐标定位X,Y轴, 旋转90度
  • 移动过程 1 => 3 3 => 9 9 => 7 7 => 1
  • 但是赋值的话,需要先拿出1的位置,然后7 赋值到1,然后 9=> 7 3=>9 1 => 3
  • 遍历的长度,X轴的一半,Math.floor(len / 2) => 1 得到的遍历就是 0
  • Y轴 遍历一半以上 Math.foor((len+1)/2) => 2 得到的遍历就是0,1
  • 双层嵌套,首先得到1,将1赋值给newData
  • 现在想将7赋值给1,还要考虑赋值7之后是4, 那么就是matrix[i][j] = matrix[len - j - 1][i]
  • 这里要了解j是i的内层,j循环一遍后,i才会增1
  • 赋值完7,要找给7赋值的参数,是9,那么就是matrix[len - j - 1][i] = matrix[len - j - 1][len - i - 1]
  • 依次找赋值给9的参数,是3 => matrix[len - i - 1][len - j - 1] = matrix[j][len - i - 1]
  • 3赋值的参数 1 => matrix[j][len - i - 1] = newData
  • 到这里形成了一个闭环,如果是44 => 55 或者更多,还会依次往内部循环

三、代码

思路1代码

let matrix = [     
  [1,2,3],
  [4,5,6],
  [7,8,9]
]

// let matrix = [     
//   [7,4,1],
//   [8,5,2],
//   [9,6,3]
// ]
let rotate = function(matrix) {
  /**
   * 思路1
   * 创建一个新的二维数组
   * 通过嵌套循环将数据赋值给新的数组
   * 先看下赋值的规律,先看转变后的数组
   * 
   * */ 
  // let matrix = [     
  //   [7,4,1],
  //   [8,5,2],
  //   [9,6,3]
  // ]
  /**
   * 这里我们要先拿到每行的数组,第一行是[7,4,1]
   * 在嵌套for循环中,第二层要从大到小循环
   * for(let j = len-1; j >= 0; j--)
   * 这样就可以按顺序拿到7,4,1的值
   * 依次循环拿到二维数组
   * 
   * 之后再通过嵌套循环赋值给matrix
   * */ 
  let len = matrix.length
  const newArr = new Array(len).fill(0).map(() => new Array(len).fill(0))
  for(let i = 0; i < len; i++) {
    for(let j = len-1; j >= 0; j--) {
      newArr[i][len - j - 1] = matrix[j][i]
    }
  }
  for(let i = 0; i < len; i++) {
    for(let j = 0; j < len; j++) {
      matrix[i][j] = newArr[i][j]
    }
  }

}
rotate(matrix)

思路2代码

let rotate = function(matrix) {
  // let matrix = [     
  //   [1,2,3],
  //   [4,5,6],
  //   [7,8,9]
  // ]
  // let matrix = [     
  //   [7,4,1],
  //   [8,5,2],
  //   [9,6,3]
  // ]
  /**
   * 思路看图写代码,不然第一次写脑子真的不够用
   * 定义长度len = matrix.length
   * 把坐标定位X,Y轴, 旋转90度
   * 移动过程 1 => 3  3 => 9 9 => 7  7 => 1
   * 但是赋值的话,需要先拿出1的位置,然后7 赋值到1,然后 9=> 7 3=>9 1 => 3
   * 遍历的长度,X轴的一半,Math.floor(len / 2) => 1 得到的遍历就是 0
   * Y轴 遍历一半以上 Math.foor((len+1)/2) => 2 得到的遍历就是0,1
   * 双层嵌套,首先得到1,将1赋值给newData
   * 现在想将7赋值给1,还要考虑赋值7之后是4, 那么就是matrix[i][j] =  matrix[len - j - 1][i]
   * 这里要了解j是i的内层,j循环一遍后,i才会增1
   * 赋值完7,要找给7赋值的参数,是9,那么就是matrix[len - j - 1][i] = matrix[len - j - 1][len - i - 1]
   * 依次找赋值给9的参数,是3 => matrix[len - i - 1][len - j - 1] = matrix[j][len - i - 1]
   * 3赋值的参数 1 => matrix[j][len - i - 1] = newData
   * 到这里形成了一个闭环,如果是4*4 => 5*5 或者更多,还会依次往内部循环
   * */ 
  let len = matrix.length
  let len1 = Math.floor(len/2)
  let len2 = Math.floor((len+1)/2)
  for(let i = 0; i < len1; i++) {
    console.log(i)
    for(let j = 0; j < len2; j++) {
      let index1 = len - j - 1
      let index2 = len - i - 1
      const newData = matrix[i][j]
      matrix[i][j] = matrix[index1][i]
      matrix[index1][i] = matrix[index2][index1]
      matrix[index2][index1] = matrix[j][index2]
      matrix[j][index2] = newData
    }
  }
  
}
rotate(matrix)

四、测试结果

测试结果1

image.png

测试结果2

image.png