算法-leetcode-数组问题- 48. 旋转图像

文章目录

    • 旋转图像
      • 思路1: 先行转列,再进行行内前后替换即可
      • 思路2:把matrix分成四部分:左上,右上,右下,左下四部分,一次旋转即可
      • 思路2优化:不用tmp存储直接交换即可

旋转图像

https://leetcode-cn.com/problems/rotate-image/

思路1: 先行转列,再进行行内前后替换即可

  • 第一步:矩阵转置,也就是行转列
  • 第二步:每一行进行对称对调
package com.shangguigu.dachang.algrithm.A01_arrays;

/**
 * @author : 不二
 * @date : 2021/12/21-下午4:03
 * @desc : 旋转图像
 * 参考:https://leetcode-cn.com/problems/rotate-image/
 *
 *
 **/
public class A19_rotate {

    public static void main(String[] args) {
        int[][] image1 = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
        };

        int[][] image2 = {
                {5, 1, 9, 11},
                {2, 4, 8, 10},
                {13, 3, 6, 7},
                {15, 14, 12, 16}
        };
        rotate(image2);
        printMetrix(image2);
    }

    public static void rotate(int[][] matrix) {
        // 其实分两步:
        // 第一步:矩阵转置,也就是行转列
        // 第二步:每一行进行对称对调
        for(int i=0;i<matrix.length;i++){
            // 注意:这里是遍历每一行具体的内容哈,然后把对应数据的行列号给交换即可
            for(int j=i+1;j<matrix[i].length;j++){
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }

        // 第二步:每一行进行对称对调
        for(int i=0;i<matrix.length;i++){

            // 1,这里直接循环一半交换
            /*for (int j = 0; j < matrix[i].length/2; j++) {
                System.out.println(i + "---" + j);
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[i][matrix.length-1-j];
                matrix[i][matrix.length-1-j] = tmp;
            }*/

            // 2,这里用双指针交换
            int start = 0;
            int end = matrix[i].length-start-1;
            while(start < end) {
                int temp = matrix[i][start];
                matrix[i][start] = matrix[i][end];
                matrix[i][end] = temp;
                start++;
                end--;
            }
        }
    }

    private static void printMetrix(int[][] maxtrix) {
        for (int[] lines : maxtrix) {
            for (int point : lines) {
                System.out.print(point + "\t");
            }
            System.out.println();
        }
    }
}

思路2:把matrix分成四部分:左上,右上,右下,左下四部分,一次旋转即可

package com.shangguigu.dachang.algrithm.A01_arrays;

/**
 * @author : 不二
 * @date : 2021/12/21-下午4:03
 * @desc : 旋转图像
 * 参考:https://leetcode-cn.com/problems/rotate-image/
 *
 *
 **/
public class A19_rotate {

    public static void main(String[] args) {
        int[][] image1 = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
        };

        int[][] image2 = {
                {5, 1, 9, 11},
                {2, 4, 8, 10},
                {13, 3, 6, 7},
                {15, 14, 12, 16}
        };
        rotateDirect(image2);
        printMetrix(image2);
    }

    /**
     * 直接旋转法优化版本:
     * @param matrix
     */
    public static void rotateOptimize(int[][] matrix) {

    }

    /**
     * 直接旋转法:左上旋转到右上:原先列等于旋转后行,且:原先行 + 旋转后列 = 总行数/总列数
     *           右上旋转到右下:原先列等于旋转后行,且:原先行 + 旋转后列 = 总行数/总列数
     *           右下旋转到左下:原先列等于旋转后行,且:原先行 + 旋转后列 = 总行数/总列数
     *           左下旋转到左上:原先列等于旋转后行,且:原先行 + 旋转后列 = 总行数/总列数
     *
     *  遍历规则是:行数: 0 - length/2 + length%2;
     *                 列数: 0 - length/2
     *
     *
     * @param matrix
     */
    public static void rotateDirect(int[][] matrix) {

        // i是行,j是列, 这里遍历的应该是左上部分, 这里需要留意,如果是奇数,则需要计算一次
        for (int i = 0; i < matrix.length / 2 + matrix.length % 2; i++) {
            for (int j = 0; j < matrix.length / 2; j++) {
                // 记录每一次遍历的这个位置对应的:左上,右上,右下,左下四部分的数据
                int[] tmp = new int[4];


                // 因为row, col是需要更改的,所以这里需要重新定义两个值
                int row = i;
                int col = j;
                // 对于一个位置(i, j), 假设说对于3个长度的matrix,是(1, 0)这个位置,那么对应的四个部分分别是:(1,0), (0,1), (1,2), (2,1)
                for (int k = 0; k < 4; k++) {
                    tmp[k] = matrix[row][col];
                    int x = row;
                    // 原先列 等于 旋转后行,也就是新的行 等于 旋转前 列
                    row = col;
                    col = matrix.length-1-x;
                }

                // 数据已经记录到tmp里面了, 然后写个循环把这四个数据从前到后替换一下即可
                for (int k = 0; k < 4; k++) {
                    matrix[row][col] = tmp[(k + 3) % 4];

                    int x = row;
                    // 原先列 等于 旋转后行,也就是新的行 等于 旋转前 列
                    row = col;
                    col = matrix.length-1-x;
                }
            }
        }
    }

    private static void printMetrix(int[][] maxtrix) {
        for (int[] lines : maxtrix) {
            for (int point : lines) {
                System.out.print(point + "\t");
            }
            System.out.println();
        }
    }
}

思路2优化:不用tmp存储直接交换即可

package com.shangguigu.dachang.algrithm.A01_arrays;

/**
 * @author : 不二
 * @date : 2021/12/21-下午4:03
 * @desc : 旋转图像
 * 参考:https://leetcode-cn.com/problems/rotate-image/
 *
 *
 **/
public class A19_rotate {

    public static void main(String[] args) {
        int[][] image1 = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
        };

        int[][] image2 = {
                {5, 1, 9, 11},
                {2, 4, 8, 10},
                {13, 3, 6, 7},
                {15, 14, 12, 16}
        };
        // rotateDirect(image2);
        rotateOptimize(image2);
        printMetrix(image2);
    }

    /**
     * 直接旋转法优化版本:不需要tmp记录,而是直接交换即可
     * @param matrix
     */
    public static void rotateOptimize(int[][] matrix) {
        // i是行,j是列, 这里遍历的应该是左上部分
        for (int i = 0; i < matrix.length / 2 + matrix.length % 2; i++) {
            for (int j = 0; j < matrix.length / 2; j++) {

                int n = matrix.length;
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[n-1-j][i];
                matrix[n-1-j][i] = matrix[n-i-1][n-1-j];
                matrix[n-1-i][n-1-j] = matrix[j][n-1-i];
                matrix[j][n-1-i] = tmp;

                /*// 记录每一次遍历的这个位置对应的:左上,右上,右下,左下四部分的数据
                int[] tmp = new int[4];
                // 因为row, col是需要更改的,所以这里需要重新定义两个值
                int row = i;
                int col = j;
                // 对于一个位置(i, j), 假设说对于3个长度的matrix,是(1, 0)这个位置,那么对应的四个部分分别是:(1,0), (0,1), (1,2), (2,1)
                for (int k = 0; k < 4; k++) {
                    tmp[k] = matrix[row][col];
                    int x = row;
                    // 原先列 等于 旋转后行,也就是新的行 等于 旋转前 列
                    row = col;
                    col = matrix.length-1-x;
                }

                // 数据已经记录到tmp里面了, 然后写个循环把这四个数据从前到后替换一下即可
                for (int k = 0; k < 4; k++) {
                    matrix[row][col] = tmp[(k + 3) % 4];

                    int x = row;
                    // 原先列 等于 旋转后行,也就是新的行 等于 旋转前 列
                    row = col;
                    col = matrix.length-1-x;
                }*/
            }
        }
    }

    /**
     * 直接旋转法:左上旋转到右上:原先列等于旋转后行,且:原先行 + 旋转后列 = 总行数/总列数
     *           右上旋转到右下:原先列等于旋转后行,且:原先行 + 旋转后列 = 总行数/总列数
     *           右下旋转到左下:原先列等于旋转后行,且:原先行 + 旋转后列 = 总行数/总列数
     *           左下旋转到左上:原先列等于旋转后行,且:原先行 + 旋转后列 = 总行数/总列数
     *
     *  遍历规则是:行数: 0 - length/2 + length%2;
     *                 列数: 0 - length/2
     *
     *
     * @param matrix
     */
    public static void rotateDirect(int[][] matrix) {

        // i是行,j是列, 这里遍历的应该是左上部分
        for (int i = 0; i < matrix.length / 2 + matrix.length % 2; i++) {
            for (int j = 0; j < matrix.length / 2; j++) {
                // 记录每一次遍历的这个位置对应的:左上,右上,右下,左下四部分的数据
                int[] tmp = new int[4];


                // 因为row, col是需要更改的,所以这里需要重新定义两个值
                int row = i;
                int col = j;
                // 对于一个位置(i, j), 假设说对于3个长度的matrix,是(1, 0)这个位置,那么对应的四个部分分别是:(1,0), (0,1), (1,2), (2,1)
                for (int k = 0; k < 4; k++) {
                    tmp[k] = matrix[row][col];
                    int x = row;
                    // 原先列 等于 旋转后行,也就是新的行 等于 旋转前 列
                    row = col;
                    col = matrix.length-1-x;
                }

                // 数据已经记录到tmp里面了, 然后写个循环把这四个数据从前到后替换一下即可
                for (int k = 0; k < 4; k++) {
                    matrix[row][col] = tmp[(k + 3) % 4];

                    int x = row;
                    // 原先列 等于 旋转后行,也就是新的行 等于 旋转前 列
                    row = col;
                    col = matrix.length-1-x;
                }
            }
        }
    }

    private static void printMetrix(int[][] maxtrix) {
        for (int[] lines : maxtrix) {
            for (int point : lines) {
                System.out.print(point + "\t");
            }
            System.out.println();
        }
    }
}

你可能感兴趣的:(算法,java,算法,leetcode)