sisterAn/JavaScript-Algorithms

剑指Offer&Bigo:旋转矩阵

sisterAn opened this issue · 6 comments

给你一幅由 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

思路: 按对角线反转后再逐行倒序

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

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

[
    [7,4,1],     
    [8,5,2],     =>   
    [9,6,3]
]
/**
 * @param {number[][]} matrix
 * @return {void} Do not return anything, modify matrix in-place instead.
 */
var rotate = function(matrix) {
    const n = matrix.length;
    //对角线反转 0,0  n-1,n-1
    for(let i = 0; i < n; i++) {
        for(let j = 0; j < i; j++) {
            swap(matrix, [i, j], [j, i]);
        }
    }

    //中线左右反转
    for(let i = 0; i < n; i++) {
        for(let j = 0; j < n / 2; j++) {
            swap(matrix, [i, j], [i, n - 1 - j]);
        }
    }

    function swap(matrix, [x1, y1], [x2, y2]) {
        const tmp = matrix[x1][y1];
        matrix[x1][y1] = matrix[x2][y2];
        matrix[x2][y2] = tmp;
    }
};
function rotateMatrix(mat) {
  const len = mat.length

  for(let i = 0;i < len;i ++) {
    for (let j = i;j < len;j ++) {
      let tmp = mat[i][j]
      mat[i][j] = mat[j][i]
      mat[j][i] = tmp
    }
  }

  for(let i = 0;i< len;i ++) {
    for(let j = 0;j < Math.floor(len / 2);j ++) {
      let tmp = mat[i][j]
      mat[i][j] = mat[i][len - j - 1]
      mat[i][len - j - 1] = tmp
    }
  }
}
const fun = (arr) => {
    for(let i=0,len=arr.length;i<len;i++){
        for(let j=i;j<len;j++){
            const temp = arr[i][j]
            arr[i][j] = arr[j][i]
            arr[j][i] = temp
        }
    }
    arr.forEach(val=>{
        val.reverse()
    })
}
const rotate = (matrix) =>{
    for(let i = 0; i < matrix.length; i++){
        for (let j = i; j < matrix[i].length; j++){
            [matrix[i][j],matrix[j][i]] = [matrix[j][i],matrix[i][j]]
        }
    }
    matrix.forEach(row=> row.reverse())
};

思路:
es6 结构赋值,解决 不占用额外内存空间;
通过两个指针来实现旋转;
/**

  • @param {number[][]} matrix
  • @return {void} Do not return anything, modify matrix in-place instead.
    */
var rotate = function(matrix) {
    const n  = matrix[0].length
    for(let i = 0 ;i<=(n/2-1);i++){
        for(let j = i; j<n-i-1; j++){
            [matrix[i][j], matrix[j][n-i-1], matrix[n-i-1][n-j-1], matrix[n-j-1][i]] =  [matrix[n-j-1][i], matrix[i][j],  matrix[j][n-i-1], matrix[n-i-1][n-j-1]] 
        }
    }
    return matrix
};
i7eo commented

// 思路:先转置后反转

var rotate = function(matrix) {
    var n = matrix.length
    for(let i = 0; i< n; i++) {
        // i + 1 是为了避免不必要的交换,加快速度
        for(let j = i+1; j< n; j++){
            var temp = matrix[i][j]
            matrix[i][j] = matrix[j][i]
            matrix[j][i] = temp
        }
        // 没有这一句就是矩阵转置,加上后就是旋转矩阵。反转每一行即可达到目的
        matrix[i].reverse()
    }
    return matrix
};