[算法-java] 将一个矩阵按照从外向里以顺时针的顺序打印出每一元素

11 篇文章 0 订阅
import java.util.*;

import static java.lang.System.out;
/**
 * 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,
 * 例如,如果输入如下矩阵:
 * 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.
 * Created by ZeHua on 2017/5/14.
 */

/**
 * 矩阵下标
 */
class Matrix_index{
    int i;
    int j;
    Matrix_index(int i,int j){
        this.i=i;
        this.j=j;
    }
}

public class ClockwisePrintArray {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
        if(matrix==null||matrix[0]==null)return null;

        ArrayList<Integer> res = new ArrayList<>();

        /**
         * 矩阵元素个数
         */
        int num_matrix = matrix.length*matrix[0].length;

        /**
         * 控制遍历的水平方向
         * -1,0,1
         */
        int horizon = 1;//刚开始为水平向右遍历

        /**
         * 控制遍历的垂直方向
         * -1,0,1
         */
        int vertical = 0;//刚开始为水平向右遍历,故而垂直为0

        /**
         * 遍历方向转换标志队列,除最外层
         */
        LinkedList<Matrix_index> border_queue = new LinkedList<Matrix_index>();

        border_queue.add(new Matrix_index(0,0));//刚开始为水平向右遍历
        res.add(matrix[0][0]);

        /**
         * 当前位置
         */
        int cur_i=0,cur_j=0;

        for(int t=2 ;t<=num_matrix;t++){
            Matrix_index border = border_queue.peek();
            int prehoricon=horizon,prevertical=vertical;
            if(horizon==1&&vertical==0){//如果水平向右遍历
                if(cur_i==border.i&&cur_j==border.j-1){
                    horizon=0;//水平方向
                    vertical=1;//垂直方向
                    border_queue.poll();
                }
                if(cur_j==matrix[0].length-1){
                    horizon=0;//水平方向
                    vertical=1;//垂直方向
                }
            }
            if(horizon==0&&vertical==1){//垂直向下
                if(cur_i==border.i-1&&cur_j==border.j){
                    horizon=-1;//水平方向
                    vertical=0;//垂直方向
                    border_queue.poll();
                }
                if(cur_i==matrix.length-1){
                    horizon=-1;//水平方向
                    vertical=0;//垂直方向
                }
            }
            if(horizon==-1&&vertical==0){//水平向左
                if(cur_i==border.i&&cur_j==border.j+1){
                    horizon=0;//水平方向
                    vertical=-1;//垂直方向
                    border_queue.poll();
                }
                if(cur_j==0){
                    horizon=0;//水平方向
                    vertical=-1;//垂直方向
                }
            }
            if(horizon==0&&vertical==-1){//垂直向上
                if(cur_i==border.i+1&&cur_j==border.j){
                    horizon=1;//水平方向
                    vertical=0;//垂直方向
                    border_queue.poll();
                }
            }

            //前进
            cur_i= cur_i+vertical;
            cur_j= cur_j+horizon;
            res.add(matrix[cur_i][cur_j]);

            if(prehoricon!=horizon||prevertical!=vertical){//如果改变了方向,就新边界入队
                border_queue.add(new Matrix_index(cur_i,cur_j));
            }

        }

        return res;
    }

    public static void main(String[] args) {
        int[][] matrix = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}};
        out.println(new ClockwisePrintArray().printMatrix(matrix));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值