顺时针打印矩阵

文章目录

  • 尝试一
  • 尝试二
  • 尝试三
  • 尝试四
  • 尝试五
  • 尝试六
  • 尝试七
  • 结论


题目内容

尝试一

结果:失败
代码:

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
       /*特殊处理,当matrix为null 或者{{}}情况*/
       if(matrix==null || matrix[0]==null){
           return null;
       }
       ArrayList<Integer> a=new ArrayList<>();
       //求循环结束标识
       int done=matrix.length/2+1;
       //min表示第几次顺时针旋转
       int min=0;
       int max=matrix.length-1;
       while(min<done){
           int i=min;
           int j=min;
           for(;j<=max;++j){
               //System.out.print(martrix[i][j]);
               a.add(matrix[i][j]);
           }
           for(i=i+1;i<=max;++i){
               //System.out.print(martrix[i][j]);
                a.add(matrix[i][j]);
           }
           for(j=j-1;j>=min;--j){
               //System.out.print(martrix[i][j]);
                a.add(matrix[i][j]);
           }
           /*注意i>min,因为上面已经打印过了*/
           for(i=i-1;i>min;--i){
                //System.out.print(martrix[i][j]);
                a.add(matrix[i][j]);
           }
           
           min+=1;
           max=max-1;
           
       }
        
       return a;
    }
}

测试用例:

不通过
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为0.00%

用例:
[[1]]

对应输出应该为:

[1]

你的输出为:

java.lang.ArrayIndexOutOfBoundsException: 1

分析:我上一个for循环时用到的循环变量值超界了,忘了进行处理了。如

		  for(;j<=max;++j){
               //System.out.print(martrix[i][j]);
               a.add(matrix[i][j]);
           }
           for(i=i+1;i<=max;++i){
               //System.out.print(martrix[i][j]);
                a.add(matrix[i][j]);
           }

j已经大于max了,我下面还在使用,当然出错了

尝试二

结果:通过率为36.36%
代码:

import java.util.ArrayList;
public class Solution {
     public ArrayList<Integer> printMatrix(int [][] matrix) {
        /*特殊处理,当matrix为null 或者{{}}情况*/
        if(matrix==null || matrix[0]==null){
            return null;
        }
        ArrayList<Integer> a=new ArrayList<>();
        //求循环结束标识
        int done=matrix.length/2+1;
        //min表示第几次顺时针旋转
        int min=0;
        int max=matrix.length-1;
        while(min<done){
            int i=min;
            int j=min;
            for(;j<=max;++j){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            j--;
            for(i=i+1;i<=max;++i){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            i--;
            for(j=j-1;j>=min;--j){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            ++j;
            /*注意i>min,因为上面已经打印过了*/
            for(i=i-1;i>min;--i){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }

            min+=1;
            max=max-1;

        }

        return a;
    }
}

测试用例:

不通过
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为36.36%

用例:
[[1],[2],[3],[4],[5]]

对应输出应该为:

[1,2,3,4,5]

你的输出为:

java.lang.ArrayIndexOutOfBoundsException: 1

分析:我以为是矩阵是nXn维的。粗心了。

尝试三

结果:不通过

import java.util.ArrayList;
public class Solution {
     public ArrayList<Integer> printMatrix(int [][] matrix) {
        /*特殊处理,当matrix为null 或者{{}}情况*/
        if(matrix==null || matrix[0]==null){
            return null;
        }
      
        ArrayList<Integer> a=new ArrayList<>();
        /*求循环结束标识*/
        int done;
        if(matrix.length<matrix[0].length){
            done=matrix.length-1;
        }else{
            done=matrix[0].length-1;
        }
        
        /*求每次循环起点。(根据起点是可以确定水平和竖着可走的范围),由于startI=startJ,所以只用一个变量表示*/
        int start=0;
        while(start<done){
            /*求每次移动的水平数值范围*/
            int endI=matrix.length-start-1;
            int endJ=matrix[0].length-start-1;
            int i=start;
            int j=start;
            for(;j<=endJ;++j){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            j--;
            for(i=i+1;i<=endI;++i){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            i--;
            for(j=j-1;j>=start;--j){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            ++j;
            /*注意i>min,因为上面已经打印过了*/
            for(i=i-1;i>start;--i){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }

            start=start+1;

        }

        return a;
    }
}

测试用例:

不通过
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为0.00%

用例:
[[1]]

对应输出应该为:

[1]

你的输出为:

[]

分析:没有考虑{{1}}这种情况。因为它与

1 2
3 4

不同,我是不取最大可包含的正方形的右下角 顶点的(也就是4)。在{{1}}是要取的

尝试四

结果:case通过率为81.82%
代码:

import java.util.ArrayList;
public class Solution {
     public ArrayList<Integer> printMatrix(int [][] matrix) {
        /*特殊处理,当matrix为null 或者{{}}情况*/
        if(matrix==null || matrix[0]==null){
            return null;
        }
         ArrayList<Integer> a=new ArrayList<>();
        /*考虑{{1}}这种情况*/
         if(matrix.length==1 ){
              for(int i=0;i<matrix[0].length;++i){
                  a.add(matrix[0][i]);
                  System.out.print(matrix[0][i]);
              }
              return a;
         }
         if(matrix[0].length==1){
              for(int i=0;i<matrix.length;++i){
                  a.add(matrix[i][0]);
                   System.out.print(matrix[i][0]);
              }
             return a;
         }
        
        /*求循环结束标识*/
        int done;
        if(matrix.length<matrix[0].length){
            done=matrix.length-1;
        }else{
            done=matrix[0].length-1;
        }
        
        /*求每次循环起点。(根据起点是可以确定水平和竖着可走的范围),由于startI=startJ,所以只用一个变量表示*/
        int start=0;
        while(start<done){
            /*求每次移动的水平数值范围*/
            int endI=matrix.length-start-1;
            int endJ=matrix[0].length-start-1;
            int i=start;
            int j=start;
            for(;j<=endJ;++j){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            j--;
            for(i=i+1;i<=endI;++i){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            i--;
            for(j=j-1;j>=start;--j){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            ++j;
            /*注意i>min,因为上面已经打印过了*/
            for(i=i-1;i>start;--i){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }

            start=start+1;

        }

        return a;
    }
}

测试用例:

不通过
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为81.82%

用例:
[[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15]]

对应输出应该为:

[1,2,3,4,5,10,15,14,13,12,11,6,7,8,9]

你的输出为:

[1,2,3,4,5,10,15,14,13,12,11,6,7,8,9,8,7]

分析:当最后打印时,只有一行时,会水平重复打印。

尝试五

结果:case通过率为90.91%
代码:

import java.util.ArrayList;
public class Solution {
     public ArrayList<Integer> printMatrix(int [][] matrix) {
        /*特殊处理,当matrix为null 或者{{}}情况*/
        if(matrix==null || matrix[0]==null){
            return null;
        }
         ArrayList<Integer> a=new ArrayList<>();
        /*考虑{{1}}这种情况*/
         if(matrix.length==1 ){
              for(int i=0;i<matrix[0].length;++i){
                  a.add(matrix[0][i]);
                  System.out.print(matrix[0][i]);
              }
              return a;
         }
         if(matrix[0].length==1){
              for(int i=0;i<matrix.length;++i){
                  a.add(matrix[i][0]);
                   System.out.print(matrix[i][0]);
              }
             return a;
         }
        
        /*求循环结束标识*/
        int done;
        if(matrix.length<matrix[0].length){
            done=matrix.length-1;
        }else{
            done=matrix[0].length-1;
        }
        
        /*求每次循环起点。(根据起点是可以确定水平和竖着可走的范围),由于startI=startJ,所以只用一个变量表示*/
        int start=0;
        while(start<done){
            /*求每次移动的水平数值范围*/
            int endI=matrix.length-start-1;
            int endJ=matrix[0].length-start-1;
            int i=start;
            int j=start;
            
            
            for(;j<=endJ;++j){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            j--;
            for(i=i+1;i<=endI;++i){
                System.out.print(matrix[i][j]);
                a.add(matrix[i][j]);
            }
            i--;
            if(endI-start!=0 && endJ-start!=0){
                for(j=j-1;j>=start;--j){
                    System.out.print(matrix[i][j]);
                    a.add(matrix[i][j]);
                }
                ++j;
                /*注意i>min,因为上面已经打印过了*/
                for(i=i-1;i>start;--i){
                    System.out.print(matrix[i][j]);
                    a.add(matrix[i][j]);
                }
            }

            start=start+1;

        }

        return a;
    }
}

测试用例:

您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为90.91%

用例:
[[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[16,17,18,19,20]]

对应输出应该为:

[1,2,3,4,5,10,15,20,19,18,17,16,11,6,7,8,9,14,13,12]

你的输出为:

[1,2,3,4,5,10,15,20,19,18,17,16,11,6,7,8,9,14,13,12,13]

分析:我的终结点找错了。我以为终结点是 最大可包含的正方形的右下角。然而测试用例告诉

 1, 2, 3, 4, 5
 6, 7, 8, 9,10
11,12,13,14,15
16,17,18,19,10

的终结点是(13),不是19。

尝试六

既然终结点找不了,我就用递归一个一个的试探。
结果:case通过率为18.18%

import java.util.ArrayList;
public class Solution {
     //从左-》右走
     private final int LTR=1;
     //从上-》下走
     private final int TTB=2;
     //从右-》左走
     private final int RTL=3;
     //从下-》上走
     private final int BTT=4;
     public ArrayList<Integer> printMatrix(int [][] matrix) {
        /*特殊处理,当matrix为null 或者{{}}情况*/
        if(matrix==null || matrix[0]==null){
            return null;
        }
        ArrayList<Integer> r=new ArrayList<>();
        boolean [][] mark=new boolean[matrix.length][matrix[0].length];
        printMatrix(0,0,matrix,LTR,mark,r);
        return r;
    }
    
    private void printMatrix(int x,int y,int [][] m,int o,boolean [][] mark,ArrayList<Integer> r){
        if(x>=m.length || y>=m[0].length || x<0 || y<0 || mark[x][y]==true){
            return;
        }
        mark[x][y]=true;
        r.add(m[x][y]);
        if(o==LTR){
            for(int j=y;j<m[0].length;++j){
                if(mark[x][j]!=true){
                    mark[x][j]=true;
                    r.add(m[x][j]);
                }
                break;
            }
        }
        else if(o==TTB){
            for(int i=x;i<m.length;++i){
                if(mark[i][y]!=true){
                    mark[i][y]=true;
                    r.add(m[i][y]);
                }
                break;
            }
        }else if(o==RTL){
            for(int j=y;j>0;--j){
                if(mark[x][j]!=true){
                    mark[x][j]=true;
                    r.add(m[x][j]);
                }
                break;
            }
        }else if(o==BTT){
             for(int i=x;i>0;--i){
                if(mark[i][x]!=true){
                    mark[i][x]=true;
                    r.add(m[i][x]);
                }
                break;
            }
        }
        printMatrix(x,y+1,m,LTR,mark,r);
        printMatrix(x+1,y,m,TTB,mark,r);
        printMatrix(x,y-1,m,RTL,mark,r);
        printMatrix(x-1,y,m,BTT,mark,r);
    }
}

测试用例:

不通过
您的代码已保存
答案错误:您提交的程序没有通过所有的测试用例
case通过率为18.18%

用例:
[[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]

你的输出为:

[1,2,3,4,8,12,16,15,14,13,9,11,10,6,7,5]

分析:

 1, 2, 3, 4
 5, 6, 7, 8
 9,10,11,12
 13,14,15,16

        printMatrix(x,y+1,m,LTR,mark,r);
        printMatrix(x+1,y,m,TTB,mark,r);
        printMatrix(x,y-1,m,RTL,mark,r);
        printMatrix(x-1,y,m,BTT,mark,r);
  • for循环里面的break出问题,因为每一次都要执行break
  • 还有,上面四行代码,每一次x,y都是从头开始的,在每一个函数里面都可能进行了移动,起点可能已经改变。

尝试七

结果:答案正确:恭喜!您提交的程序通过了所有的测试用例

import java.util.ArrayList;
public class Solution {
     //从左-》右走
     private final int LTR=1;
     //从上-》下走
     private final int TTB=2;
     //从右-》左走
     private final int RTL=3;
     //从下-》上走
     private final int BTT=4;
     public ArrayList<Integer> printMatrix(int [][] matrix) {
        /*特殊处理,当matrix为null 或者{{}}情况*/
        if(matrix==null || matrix[0]==null){
            return null;
        }
        ArrayList<Integer> r=new ArrayList<>();
        boolean [][] mark=new boolean[matrix.length][matrix[0].length];
        printMatrix(0,0,matrix,LTR,mark,r);
        return r;
    }
    
private void printMatrix(int x,int y,int [][] m,int o,boolean [][] mark,ArrayList<Integer> r){
        if(x>=m.length || y>=m[0].length || x<0 || y<0 || mark[x][y]==true){
            return;
        }
        mark[x][y]=true;
        r.add(m[x][y]);
        System.out.print(m[x][y]+" ");
        if(o==LTR){
            for( ++y;y<m[0].length;++y){
                if(mark[x][y]!=true){
                    mark[x][y]=true;
                    r.add(m[x][y]);
                    System.out.print(m[x][y]+" ");
                }else {
                    break;
                }
            }
            --y;
            //printMatrix(x+1,y,m,TTB,mark,r);
        }
        else if(o==TTB){
            for(++x;x<m.length;++x){
                if(mark[x][y]!=true){
                    mark[x][y]=true;
                    r.add(m[x][y]);
                    System.out.print(m[x][y]+" ");
                }else {
                    break;
                }
            }
            --x;
            //printMatrix(x,y-1,m,RTL,mark,r);
        }else if(o==RTL){
            for(--y;y>0;--y){
                if(mark[x][y]!=true){
                    mark[x][y]=true;
                    r.add(m[x][y]);
                    System.out.print(m[x][y]+" ");
                }else {
                    break;
                }
            }
            ++y;
            //printMatrix(x-1,y,m,BTT,mark,r);
        }else if(o==BTT){
            for(--x;x>0;--x){
                if(mark[x][y]!=true){
                    mark[x][y]=true;
                    r.add(m[x][y]);
                    System.out.print(m[x][y]+" ");
                }else {
                    break;
                }
            }
            ++x;
            //printMatrix(x,y+1,m,LTR,mark,r);
        }
        printMatrix(x,y+1,m,LTR,mark,r);
        printMatrix(x+1,y,m,TTB,mark,r);
        printMatrix(x,y-1,m,RTL,mark,r);
        printMatrix(x-1,y,m,BTT,mark,r);
    }
}

结论

  • 递归进行试探时,递归函数的参数不是应用类型的都不会被影响到。如:
		 printMatrix(x,y+1,m,LTR,mark,r);
        printMatrix(x+1,y,m,TTB,mark,r);

在第一行执行完后,x,y还是原来的x,y。不会在函数中被改变。

  • 递归可以做试探

你可能感兴趣的:(剑指offer)