剑指Offer(59)-[Array&String]顺时针打印矩阵

本文详细解析了一道复杂的剑指Offer面试题,即按顺时针方向打印矩阵中的数字。通过将问题分解为四步并考虑特殊情况,如矩阵退化为一行、一列或单一数字的情况,提供了清晰的解决思路。使用Java实现了算法,有效地处理了各种边界条件。

点击查看剑指Offer全解【Java & Golang】实现

题目描述

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.


思路

这道题应该是剑指Offer中最复杂的一个问题了,因为它难在思考过程简单,但是实现起来需要判断的边界条件多,这里给剑指Offer的讲解:

把打印一圈分为四步:第一步从左到右打印一行,第二步从上到下打印一列,第三步从右到左打印一行,第四步从下到上打印一列。每一步我们根据起始坐标和终止坐标用一个循环就能打印出一行或者一列。

不过值得注意的是,最后一圈有可能退化成只有一行、只有一列,甚至只有一个数字,因此打印这样的一圈就不再需要四步。图中是几个退化的例子, 打印一圈分别只需要三步、两步甚至只有一步。

在这里插入图片描述

Java实现

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int[][] matrix) {
        ArrayList<Integer> res = new ArrayList<>();
        if (matrix.length == 0) {
            return res;
        }
        int row = matrix.length;
        int col = matrix[0].length;
        // 上下左右
        int top = 0, bottom = row - 1, left = 0, right = col - 1;
        while (top <= bottom && left <= right) {
            // 从左到右打印
            for (int i = left; i <= right; i++) {
                res.add(matrix[top][i]);
            }
            // 从上到下打印
            for (int i = top + 1; i <= bottom; i++) {
                res.add(matrix[i][right]);
            }
            // 从右到左打印
            // 防止只有一行的情况
            if (top != bottom) {
                for (int i = right - 1; i >= left; i--) {
                    res.add(matrix[bottom][i]);
                }
            }
            // 从下到上打印
            // 防止只有一列的情况
            if (left != right) {
                for (int i = bottom - 1; i >= top + 1; i--) {
                    res.add(matrix[i][left]);
                }
            }
            // 下一圈
            top++;bottom--;left++;right--;
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值