编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 01.用类实现一维数组
  • 02.从数组中删除重复项
  • 03.啤酒与饮料
  • 04.二维数组中查找
  • 05.数组中重复的数字
  • 06.和为s的两个数字
  • 07.数组中只出现一次数字
  • 08.数组中只出现一次的数字
  • 09.买卖股票最佳时机
  • 10.调整数组顺序
  • 11.找出常用的数字
  • 12.旋转数组的最小数字
  • 13.调整数组顺序使奇数位于偶数前面
  • 14.顺时针打印矩阵
  • 15.数组中出现次数超过一半的数字
  • 16.最小的k个数
  • 17.连续子数组的最大和
  • 18.把数组排成最小的数
  • 19.数组中的逆序对
  • 20.在排序数组中出现的次数
  • 21.滑动窗口的最大值

14.顺时针打印矩阵

目录介绍

  • 01.题目要求
  • 02.问题分析
  • 03.实例代码

01.题目要求

  • 问题如下所示:
    • 输入一个矩阵,按照从外向里以顺时针的顺序依次扫印出每一个数字。
  • 示例 :

02.问题分析

  • 把打印一圈分为四步:第一步从左到右打印一行,第二步从上到下打印一列,第三步从右到左打印一行,第四步从下到上打印一列。每一步我们根据起始坐标和终止坐标用一个循环就能打印出一行或者一列。
  • 不过值得注意的是,最后一圈有可能退化成只有一行、只有一列,甚至只有一个数字,因此打印这样的一圈就不再需要四步。
  • 因此我们要仔细分析打印时每一步的前提条件。第一步总是需要的, 因为打印一圈至少有一步。如果只有一行,那么就不用第二步了。也就是需要第二步的前提条件是终止行号大于起始行号。需要第三步打印的前提条件是圈内至少有两行两列,也就是说除了要求终止行号大于起始行号之外,还要求终止列号大于起始列号。同理,需要打印第四步的前提条件是至少有三行两列,因此要求终止行号比起始行号至少大2 , 同时终止列号大于起始列号。

03.实例代码

  • 如下所示
    public class Test {
        /**
         * 输入一个矩阵,按照从外向里以顺时针的顺序依次打印每一个数字
         *
         * @param numbers 输入的二维数组,二维数组必须是N*M的,否则分出错
         */
        public static void printMatrixClockWisely(int[][] numbers) {
            // 输入的参数不能为空
            if (numbers == null) {
                return;
            }
    
            // 记录一圈(环)的开始位置的行
            int x = 0;
            // 记录一圈(环)的开始位置的列
            int y = 0;
            // 对每一圈(环)进行处理,
            // 行号最大是(numbers.length-1)/2
            // 列号最大是(numbers[0].length-1)/2
            while (x * 2 < numbers.length && y * 2 < numbers[0].length) {
                printMatrixInCircle(numbers, x, y);
                // 指向下一个要处理的的环的第一个位置
                x++;
                y++;
            }
        }
    
        public static void printMatrixInCircle(int[][] numbers, int x, int y) {
            // 数组的行数
            int rows = numbers.length;
            // 数组的列数
            int cols = numbers[0].length;
    
            // 输出环的上面一行,包括最中的那个数字
            for (int i = y; i <= cols - y - 1; i++) {
                System.out.print(numbers[x][i] + " ");
            }
    
            // 环的高度至少为2才会输出右边的一列
            // rows-x-1:表示的是环最下的那一行的行号
            if (rows - x - 1 > x) {
                // 因为右边那一列的最上面那一个已经被输出了,所以行呈从x+1开始,
                // 输出包括右边那列的最下面那个
                for (int i = x + 1; i <= rows - x - 1; i++) {
                    System.out.print(numbers[i][cols - y - 1] + " ");
                }
            }
    
            // 环的高度至少是2并且环的宽度至少是2才会输出下面那一行
            // cols-1-y:表示的是环最右那一列的列号
            if (rows - x - 1 > x && cols - 1 - y > y) {
                // 因为环的左下角的位置已经输出了,所以列号从cols-y-2开始
                for (int i = cols - y - 2; i >= y; i--) {
                    System.out.print(numbers[rows - 1 - x][i] + " ");
                }
            }
    
            // 环的宽度至少是2并且环的高度至少是3才会输出最左边那一列
            // rows-x-1:表示的是环最下的那一行的行号
            if (cols - 1 - y > y && rows - 1 - x > x + 1) {
                // 因为最左边那一列的第一个和最后一个已经被输出了
                for (int i = rows - 1 - x - 1; i >= x + 1; i--) {
                    System.out.print(numbers[i][y] + " ");
                }
            }
        }
    }
贡献者: yangchong211
上一篇
13.调整数组顺序使奇数位于偶数前面
下一篇
15.数组中出现次数超过一半的数字