当前位置: 首页 > news >正文

矩阵类问题处理技巧

矩阵类问题处理技巧

作者:Grey

原文地址:

博客园:矩阵类问题处理技巧

CSDN:矩阵类问题处理技巧

给定一个正方形矩阵,原地调整成顺时针90度转动的样子

题目链接见:LeetCode 48. Rotate Image

本题主要的限制条件是:原地调整,即不开辟额外的二维数组来做。

主要思路如下

第一步,先处理外围的圈 然后同理依次处理每个内圈。

image

第二步,每个圈分组,组内每次一个元素占据下一个元素的位置,如果是N*N就分(N-1)*(N-1)个组。如下图。颜色一样的就是同一组。

image

第三步,每个组的每个数可以通过组号来定位。如下图:

image

编号一样的就是同一组,同一组的某个位置,按顺时针方向,可以很方便定位到本组下一个位置。

组内调整的核心代码如下

    private static void rotate(int n, int[][] matrix, int zuoshangX, int zuoshangY, int youxiaX, int youxiaY) {
        int zu = n - 1;
        int youshangX = zuoshangX;
        int youshangY = youxiaY;
        int zuoxiaX = youxiaX;
        int zuoxiaY = zuoshangY;
        for (int i = 1; i <= zu; i++) {
            // 每组内部调整
            int tmp = matrix[zuoshangX][zuoshangY];
            matrix[zuoshangX][zuoshangY++] = matrix[zuoxiaX][zuoxiaY];
            matrix[zuoxiaX--][zuoxiaY] = matrix[youxiaX][youxiaY];
            matrix[youxiaX][youxiaY--] = matrix[youshangX][youshangY];
            matrix[youshangX++][youshangY] = tmp;
        }
    }

完整代码见

class Solution {
    public static void rotate(int[][] matrix) {
        int n = matrix.length;
        int zuoshangX = 0;
        int zuoshangY = 0;
        int youxiaX = n - 1;
        int youxiaY = n - 1;
        while (n > 0) {
            // 先处理外围,然后逐步处理内圈。
            rotate(n, matrix, zuoshangX++, zuoshangY++, youxiaX--, youxiaY--);
            n -= 2;
        }
    }

    private static void rotate(int n, int[][] matrix, int zuoshangX, int zuoshangY, int youxiaX, int youxiaY) {
        int zu = n - 1;
        int youshangX = zuoshangX;
        int youshangY = youxiaY;
        int zuoxiaX = youxiaX;
        int zuoxiaY = zuoshangY;
        for (int i = 1; i <= zu; i++) {
            // 每组内部调整
            int tmp = matrix[zuoshangX][zuoshangY];
            matrix[zuoshangX][zuoshangY++] = matrix[zuoxiaX][zuoxiaY];
            matrix[zuoxiaX--][zuoxiaY] = matrix[youxiaX][youxiaY];
            matrix[youxiaX][youxiaY--] = matrix[youshangX][youshangY];
            matrix[youshangX++][youshangY] = tmp;
        }
    }
}

给定一个长方形矩阵,实现转圈打印

LeetCode 54. Spiral Matrix

和上一题类似,先打印外围圈圈,然后切换到内圈,用同样的方式打印内圈,依次循环。

打印的时候,我们只需要定位左上和右下两个点的坐标位置即可确定一个矩形。

image

需要注意的是,最后有可能是一条直线,比如下述两种情况中的标红位置

image

image

对于形成一条直线的情况,单独处理并打印即可。

完整代码见

class Solution {
    public static List<Integer> spiralOrder(int[][] matrix) {
        if (null == matrix || matrix.length == 0 || matrix[0].length == 0) {
            return new ArrayList<>();
        }
        int m = matrix.length;
        int n = matrix[0].length;
        // 左上角点
        int a = 0, b = 0;
        // 右下角点
        int c = m - 1, d = n - 1;
        List<Integer> ans = new ArrayList<>();
        while (a <= c && b <= d) {
            spiral(matrix, a++, b++, c--, d--, ans);
        }
        return ans;
    }

    public static void spiral(int[][] matrix, int a, int b, int c, int d, List<Integer> ans) {
        if (a == c) {
            // 形成一条直线:共行
            for (int i = b; i <= d; i++) {
                ans.add(matrix[a][i]);
            }
            return;
        }
        if (b == d) {
            // 形成一条直线:共列
            for (int i = a; i <= c; i++) {
                ans.add(matrix[i][b]);
            }
            return;
        }
        for (int i = b; i < d; i++) {
            ans.add(matrix[a][i]);
        }
        for (int i = a; i < c; i++) {
            ans.add(matrix[i][d]);
        }
        for (int i = d; i > b; i--) {
            ans.add(matrix[c][i]);
        }
        for (int i = c; i > a; i--) {
            ans.add(matrix[i][b]);
        }
    }
}

zigzag打印矩阵

题目描述见:LintCode 185 · Matrix Zigzag Traversal

zigzag 方式如下

image

本题的主要思路是

从左上角的开始位置,准备两个变量 A 和 B,A 往左边走,走到不能再走的时候,往下走
B 往下走,走到不能再往下的时候,往左边走,每次 AB 构成的连线进行打印(方向交替变化)

完整代码见:

public class Solution {
    /**
     * @param matrix: An array of integers
     * @return: An array of integers
     */
    public static int[] printZMatrix(int[][] matrix) {
        if (null == matrix || matrix.length == 0 || matrix[0].length == 0) {
            return null;
        }
        int m = matrix.length;
        int n = matrix[0].length;
        int[] ans = new int[m * n];
        ans[0] = matrix[0][0];
        // 右边-->下边
        int a = 0, b = 0;
        // 下边-->右边
        int c = 0, d = 0;
        int index = 1;
        boolean topToDown = true;
        for (int k = 0; k < m + n; k++) {
            if (b < n - 1) {
                b++;
            } else if (b == n - 1) {
                a++;
            }
            if (c < m - 1) {
                c++;
            } else if (c == m - 1) {
                d++;
            }
            if (topToDown) {
                int j = b;
                for (int i = a; i <= c; i++) {
                    ans[index++] = matrix[i][j--];
                }
            } else {
                int j = d;
                for (int i = c; i >= a; i--) {
                    ans[index++] = matrix[i][j++];
                }
            }
            topToDown = !topToDown;
        }
        return ans;
    }
}

螺旋打印星号

依旧是先处理外圈,然后依次内圈的处理方式,

完整代码见

package snippet;

// 螺旋打印星号
public class Code_0093_PrintStar {

    public static void printStar(int N) {
        int leftUp = 0;
        int rightDown = N - 1;
        char[][] m = new char[N][N];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                m[i][j] = ' ';
            }
        }
        while (leftUp <= rightDown) {
            set(m, leftUp, rightDown);
            leftUp += 2;
            rightDown -= 2;
        }
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                System.out.print(m[i][j] + " ");
            }
            System.out.println();
        }
    }

    public static void set(char[][] m, int leftUp, int rightDown) {
        for (int col = leftUp; col <= rightDown; col++) {
            m[leftUp][col] = '*';
        }
        for (int row = leftUp + 1; row <= rightDown; row++) {
            m[row][rightDown] = '*';
        }
        for (int col = rightDown - 1; col > leftUp; col--) {
            m[rightDown][col] = '*';
        }
        for (int row = rightDown - 1; row > leftUp + 1; row--) {
            m[row][leftUp + 1] = '*';
        }
    }

    public static void main(String[] args) {
        printStar(5);
    }

}

打印结果如下

* * * * * 
        * 
  * *   * 
  *     * 
  * * * * 

更多

算法和数据结构笔记

相关文章:

  • MyBatis Plus (三) --------- 入门 HelloWorld
  • 云安全践行者:亚马逊云科技如何打好“安全”牌?
  • 第8章 Spring AOP
  • 操作系统 | 【一 概述】强化阶段 —— 应用题总结
  • 深度学习(PyTorch)——python中的两大法宝(dir与help)
  • 记一次vue^2.6.5-router^3.0.6的keep-alive事故
  • vi vim 快速跳到文件末尾 在最后一行下方新增一行 (光标换行,文字不换行)
  • 【我不熟悉的css】03. 使用px、em、rem
  • 1.直流无刷电机BLDC转速计算推论
  • 猿创征文|小而巧的API文档生成工具之smart-doc
  • PyTorch错误定位系列之DDP训练中 double free or corruption (out)
  • Go template详解(中)- 变量使用、if语句、迭代(数组、切片、map)、内置函数(比较、逻辑判断、打印、索引、函数调用)
  • JavaScript(三):理解异步
  • JVM阶段(3)-OutOfMemoryError异常
  • 企业运维容器之 docker 网络
  • css的样式优先级
  • Js基础知识(一) - 变量
  • Netty源码解析1-Buffer
  • Redux 中间件分析
  • sessionStorage和localStorage
  • vue.js框架原理浅析
  • 算法系列——算法入门之递归分而治之思想的实现
  • 听说你叫Java(二)–Servlet请求
  • 一些css基础学习笔记
  • 异常机制详解
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • # include “ “ 和 # include < >两者的区别
  • #pragma 指令
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (笔试题)合法字符串
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (附源码)php新闻发布平台 毕业设计 141646
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (译)2019年前端性能优化清单 — 下篇
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)拼包函数及网络封包的异常处理(含代码)
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .NET性能优化(文摘)
  • .NET中的十进制浮点类型,徐汇区网站设计
  • 。Net下Windows服务程序开发疑惑
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具
  • [ vulhub漏洞复现篇 ] struts2远程代码执行漏洞 S2-005 (CVE-2010-1870)
  • [383] 赎金信 js
  • [Angular] 笔记 9:list/detail 页面以及@Output
  • [APIO2012] 派遣 dispatching
  • [BT]小迪安全2023学习笔记(第15天:PHP开发-登录验证)
  • [BZOJ] 2427: [HAOI2010]软件安装
  • [C++随笔录] 红黑树
  • [CakePHP] 在Controller中使用Helper
  • [Electron]ipcMain.on和ipcMain.handle的区别
  • [gdc19]《战神4》中的全局光照技术
  • [Google Guava] 1.1-使用和避免null