算法与数据结构——二维数组打印问题【zigzag、螺旋打印】以及二维数组旋转(Java)

zigzag

image-20220714104156691

不要想局部位置怎么变

看整体宏观调整过程

规定两个点,一开始都在左上角,假设分别为a和b

a一直往右走,走到不能走就往下走

b一直往下走,走到不能走就往右走

每次两个点走一步

两个点确定一条斜线

轮流按照从右上到左下和从左下到右上的顺序打印斜线即可

public static void printMatrixZigZag(int[][] matrix) {
    int tR = 0;
    int tC = 0;
    int dR = 0;
    int dC = 0;
    int endR = matrix.length - 1;
    int endC = matrix[0].length - 1;
    boolean fromUp = false;
    while (tR != endR + 1) {
        printLevel(matrix, tR, tC, dR, dC, fromUp);
        tR = tC == endC ? tR + 1 : tR;//a的行走到不能再往右走 再往下走
        tC = tC == endC ? tC : tC + 1;
        dR = dR == endR ? dR : dR + 1;//b的行走到不能再往下走 再往右走
        dC = dR == endR ? dC + 1 : dC;
        fromUp = !fromUp;
    }
    System.out.println();
}

public static void printLevel(int[][] m, int tR, int tC, int dR, int dC,
                              boolean f) {
    if (f) {
        while (tR != dR + 1) {
            System.out.print(m[tR++][tC--] + " ");//从右上到左下
        }
    } else {
        while (dR != tR - 1) {
            System.out.print(m[dR--][dC++] + " ");//从左下到右上
        }
    }
}

螺旋打印矩阵

image-20220714104856162

这种类似的螺旋问题不要关注局部位置是怎么变化的

关注宏观调度过程

锁定两个点:左上角和右下角的点

用四个变量记录两个点的位置

两个点可以锁定一个框

框的打印顺序是右下左上

打印完一个框左上角的点向右下方移动,右下角的点向左上方移动

继续打印新的框直到行或者列交错了就停

处理三个情况:

普遍情况

左上角和右下角是一条横线

左上角和右下角是一条竖线

image-20220714105154290

public void spiralOrderPrint(int[][] matrix){
    int tR=0;
    int tC=0;
    int dR=matrix.length-1;
    int dC=matrix[0].length-1;
    while(tR<=dR&&tC<=dC){
        printEdge(matrix,tR++,tC++,dR--,dC--);
    }
}

public void printEdge(int[][] m,int a,int b,int c,int d){//(a,b)代表左上角的点 (c,d)代表右下角的点
    if(a==c){//在同一行 是一条横线
        for(int i=b;i<=d;i++){
            System.out.print(m[a][i]+" ");
        }
    }else if(b==d){//在同一列 是一条竖线
        for(int i=a;i<=c;i++){
            System.out.print(m[i][b]+" ");
        }
    }else{//普遍情况  按照右下左上的顺序打印
        int curR=a;
        int curC=b;
        while(curC!=d){
            System.out.print(m[a][curC]+" ");
            curC++;
        }
        while(curR!=c){
            System.out.print(m[curR][d]+" ");
            curR++;
        }
        while(curC!=b){
            System.out.print(m[c][curC]+" ");
            curC--;
        }
        while(curR!=a){
            System.out.print(m[curR][b]+" ");
            curR--;
        }
    }
}

二维数组顺时针转动

image-20220714112217521

与上题类似

用两个点去定义框

用函数实现框怎么移动即可

将框进行分组

组数为框的边长上的点数-1

如下面的例子:4x4的框组数为3 每个图形代表一组

每一组的四个数进行交换即可

image-20220714112701937

image-20220714113150683

public void rotate(int[][] matrix){
    int a=0;
    int b=0;
    int c=matrix.length-1;
    int d=matrix[0].length-1;
    while(a<c){
        rotateEdge(matrix,a++,b++,c--,d--);
    }
}

public void rotateEdge(int[][] m,int a,int b,int c,int d){
    int tmp=0;
    for(int i=0;i!=d-b;i++){
        tmp=m[a][b+i];
        m[a][b+i]=m[c-i][b];
        m[c-i][b]=m[c][d-i];
        m[c][d-i]=m[a+i][d];
        m[a+i][d]=tmp;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值