[Classic algorithm] Elegant realization of clockwise printing matrix

I remember this was a question I was asked when I was interviewing at Google. Regarding the description of the clockwise printing matrix problem, you can search for the following topic. The general information is as follows:
Given a matrix of m*n, it is required to print clockwise from the outer layer until all elements are printed,
such as:
1, 2*2 matrix
   1 2
   3 4

output: 1 2 4 3

2, 3*4 matrix
   1 2 3 4
   5 6 7 8
   9 1 2 3

output: 1 2 3 4 8 3 2 1 9 5 6

7 Simple, especially in the interview, with the goal of writing the code as quickly as possible, directly write the code with 4 for loops. However, in the process of writing, I found that there are many boundary problems to pay attention to, but in the end I stumbled and finished writing. After that, I didn't think about it anymore. Until recently, I happened to see some solutions on the Internet, and I wondered if there was a more elegant way to write it. After thinking, you only need to consider the four coordinates of the matrix and control it through the boundaries of the four coordinates. Each time the outermost layer is looped, the four boundaries can be reduced by one layer. Finally, whether there is a printout can be used as the end condition of the outermost loop. This way, it's done with just one for loop, which perfectly solves the problem in the most elegant way. At the same time, minimal loops are required to avoid complex boundary judgments.

Not much nonsense, go directly to the code, welcome to shoot bricks.



public class Test {
        
        private boolean valid(int cc, int m, int n){
                if( cc >= m && cc <= n ){
                        return true;
                }
                return false;
        }
        
        public void print(int m, int n, int a[][], boolean visited[][]){
                int offsetX[] = new int[]{0,1,0,-1};
                int offsetY[] = new int[]{1, 0, -1, 0};
                
                int sX = 0, eX = n - 1;
                int sY = 0, eY = m - 1;
                
                boolean flag = false;
                do{
                        if( sX > eX || sY > eY ){
                                break;
                        }
                        int xTmp = sX;
                        int yTmp = sY;
                        for( int ii = 0; ii < offsetX.length;){
                                if( valid( xTmp, sY, eY) && valid(yTmp, sX, eX) && !visited[xTmp][yTmp]){
                                        System.out.print(a[xTmp][yTmp]+"\t");
                                        visited[xTmp][yTmp] = true;
                                        flag = true;
                                }
                                
                                if( valid(xTmp + offsetX[ii], sY, eY) && valid(yTmp + offsetY[ii], sX, eX) ){
                                        xTmp += offsetX[ii];
                                        yTmp += offsetY[ii];
                                }else{
                                        ii++;
                                }
                                
                        }
                        sX++;
                        eX--;
                        sY ++;
                        eY--;
                }while( flag );
        }
        
        public static void main(String[] args) {
                int a[][];
                int m = (int)(Math.random() * 5)+1;
                int n = (int)(Math.random() * 5)+1;
                
//                m = 10;
//                n = 1;
                
                a = new int[m][n];
                boolean visited[][] = new boolean[m][n];
                
                System.out.println( m + " * " + n);
                
                for( int i = 0; i < m; i++ ){
                        for( int j = 0; j < n; j++ ){
                                int tmp = (int)(Math.random() * 10);
                                a[i][j] = tmp;
                                visited[i][j] = false;
                                System.out.print(tmp+"\t");
                        }
                        System.out.println();
                }
                System.out.println();
                
                System.out.println("Print clockwise: ");
                Test t = new Test();
                t.print(m, n, a, visited);
        }
        
}


Regardless of the printing direction, only a for loop is used to gracefully complete the clockwise printing task. Decide as few boundary conditions as possible, thereby reducing the probability of error.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327081636&siteId=291194637