首页 > 试题广场 >

顺时针打印矩阵

[编程题]顺时针打印矩阵
  • 热度指数:21935 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

对于一个矩阵,请设计一个算法从左上角(mat[0][0])开始,顺时针打印矩阵元素。

给定int矩阵mat,以及它的维数nxm,请返回一个数组,数组中的元素为矩阵元素的顺时针输出。

测试样例:
[[1,2],[3,4]],2,2
返回:[1,2,4,3]
import java.util.*;

public class Printer {
    public int[] clockwisePrint(int[][] mat, int n, int m) {
        // write code here
        //左上角坐标
        int x1 = 0;
        int y1 = 0;
        //右下角坐标
        int x2= n-1;
        int y2= m-1;
        //定义数组
        int[] arr = new int[n*m];
        int index = 0;
        while(x1<=x2&&y1<=y2){
            //第一行:x1,yi~y2
            for(int i = y1;i <= y2;i++)
                arr[index++] = mat[x1][i];
            //最后一列:x1+1,x2,y2
            for(int i = x1+1;i <= x2;i++)
                arr[index++] = mat[i][y2];
            //最后一行:x2,,y2-1~y1;
            if( x1 < x2 ){
                for(int i= y2-1;i >= y1;i--)
                    arr[index++] = mat[x2][i];
            }
            //第一列:x2-1~x1+1,y1
            if(y1 < y2){
                for(int i = x2-1;i >=x1+1;i--)
                    arr[index++] = mat[i][y1];
            }
            x1++;
            y1++;
            x2--;
            y2--;
         
        }
         return arr;
    }
}

发表于 2021-06-15 23:55:52 回复(0)

递归:设置四个方向。

返回:每次递归之后 需要返回 return ; 的递归出口。

顺序:为right down left up right

临界条件:如果当前点的下一个点越界或者已经走过 则以当前点为新起点 进入下一个方向 。否则,存储该元素,flag++,递归进入下一个点。

标记:flag记录遍历了多少个数 当flag==mat.length*mat[0].length-1 说明当前元素就是矩阵的最后一个元素,直接存储 。

记录方便以后复习。

代码如下:

public List<Integer> list=new ArrayList<Integer>();     public int r2;     public int l2;     public int flag=0;     public int[] clockwisePrint(int[][] mat, int n, int m) {         r2=n;         l2=m;         boolean [][]vis=new boolean[n][m];         right(mat,0,0,vis);         int[] array = new int[list.size()];         int index=0;         for(Integer i:list)         {             array[index++]=i;         }         return  array;     }     public void right(int[][] mat,int x,int y,boolean [][]vis)     {         if(flag==mat.length*mat[0].length-1) {             list.add(mat[x][y]);             return;         } // 右 x y+1         if(x<0||y+1<0||x>r2-1||y+1>l2-1||vis[x][y+1])         {            down(mat,x,y,vis);            return ;         }         vis[x][y]=true;         flag++;         list.add(mat[x][y]);         right(mat,x,y+1,vis);     }     public void left(int[][] mat,int x,int y,boolean [][]vis)     {         if(flag==mat.length*mat[0].length-1) {             list.add(mat[x][y]);             return;         } // 左 x y-1         if(x<0||y-1<0||x>r2-1||y-1>l2-1||vis[x][y-1])         {             up(mat,x,y,vis);             return ;         }         vis[x][y]=true;         flag++;         list.add(mat[x][y]);         left(mat,x,y-1,vis);     }     public void up(int[][] mat,int x,int y,boolean [][]vis)     {         if(flag==mat.length*mat[0].length-1) {             list.add(mat[x][y]);             return;         } //上 x-1 y         if(x-1<0||y<0||x-1>r2-1||y>l2-1||vis[x-1][y])         {             right(mat,x,y,vis);             return ;         }         vis[x][y]=true;         flag++;         list.add(mat[x][y]);         up(mat,x-1,y,vis);     }     public void down(int[][] mat,int x,int y,boolean [][]vis)     {         if(flag==mat.length*mat[0].length-1) {             list.add(mat[x][y]);             return;         } //下 x+1 y         if(x+1<0||y<0||x+1>r2-1||y>l2-1||vis[x+1][y])         {             left(mat,x,y,vis);             return ;         }         vis[x][y]=true;         flag++;         list.add(mat[x][y]);         down(mat,x+1,y,vis);     }


编辑于 2020-06-10 16:13:40 回复(0)

public int[] clockwisePrint(int[][] mat, int n, int m) {

    int tR = 0;
    int tC = 0;
    int dR = n - 1;
    int dC = m - 1;
    int index = 0;
    int[] res = new int[n * m];
    while (tR <= dR && tC <= dC) {
        if (tR == dR) {// 只有一行的时候
            for (int i = tC; i <= dC; i++) {
                res[index++] = mat[tR][i];
            }
        } else if (tC == dC) {// 只有一列的时候
            for (int i = tR; i <= dR; i++) {
                res[index++] = mat[i][tC];
            }
        } else {
            int curC = tC;
            int curR = tR;
            while (curC != dC) {// 从左到右打印
                res[index++] = mat[tR][curC];
                curC++;
            }
            while (curR != dR) {// 从上往下打印
                res[index++] = mat[curR][dC];
                curR++;
            }
            while (curC != tC) {// 从右往左打印
                res[index++] = mat[dR][curC];
                curC--;
            }
            while (curR != tR) {// 从下往上打印
                res[index++] = mat[curR][tC];
                curR--;
            }
        }
        tR++;
        tC++;
        dR--;
        dC--;

    }
    System.out.println(Arrays.toString(res));
    return res;
}
发表于 2018-03-13 17:45:51 回复(1)
public int[] clockwisePrint(int[][] mat, int n, int m) {
		int[] res = new int[n * m];
		int index = 0;
		// 定义初始点x/y 结束点x/y的坐标
		int startX = 0;
		int startY = 0;
		int endX = n - 1;
		int endY = m - 1;
		while (startX <= endX && startY <= endY) {
			// 从左往右
			if (startY <= endY) {
				for (int i = startY; i <= endY; i++) {
					res[index++] = mat[startX][i];
				}
			}
			// 从上往下
			if (startX < endX) {
				for (int i = startX + 1; i <= endX; i++) {
					res[index++] = mat[i][endY];
				}
			}
			// 从右往左
			if (startX < endX && startY <= endY) {
				for (int i = endY - 1; i >= startY; i--) {
					res[index++] = mat[endX][i];
				}
			}
			// 从下往上
			if (startX < endX && startY < endY) {
				for (int i = endX - 1; i > startX; i--) {
					res[index++] = mat[i][startY];
				}
			}
			startX++;
			startY++;
			endX--;
			endY--;
		}
		//
		return res;
	}

发表于 2017-06-04 21:57:49 回复(0)
思路很简单,矩阵的顺时针一圈,为一次轮回。period记录圈数,每次只要调整好i和j的位置就OK了。还有要时刻判断k是不是等于total
public static int[] clockwisePrint(int[][] mat, int n, int m)
{
        int total = n*m;
        int[] nums = new int[n*m];
        int k = 0, i = 0, j = 0, period = 0;
        while (k <= total-1)
        {
            while (j < m-period)//从左往右, keep i
            {
                nums[k++] = mat[i][j++];
                if (k == total) break;
            }
            j--;
            if (k == total) break;
            while (i < n-period-1 && j == m-period-1)// keep j
            {
                nums[k++] = mat[++i][j];
                if (k == total) break;
            }
            if (k == total) break;
            while (j > period) //keep i
            {
                nums[k++] = mat[i][--j];
                if (k == total) break;
            }
            if (k == total) break;
            period++;
            while (i > period)//keep j
            {
                nums[k++] = mat[--i][j];
                if (k == total) break;
            }
            //一次顺时针结束,j+1
            j++;
        }
        return nums;
}
发表于 2016-09-10 10:34:52 回复(1)
import java.util.*;

public class Printer {
    public List<Integer> printCircle(List<Integer> list,int[][] mat, int n, int m,int start)
    {
        int i = start;
        int j = start;
        while(m-j-1!=start&&i==start)
        {
            list.add(mat[i][j]);
            j++;
        }
        while(n-i-1!=start&&j==m-start-1)
        {
            list.add(mat[i][j]);
            i++;
        }
        if(n-2*start!=1) {
            while (j != start && i == n-start-1) {
                list.add(mat[i][j]);
                j--;
            }

        }
        else{
            list.add(mat[i][j]);
        }
        if(m-start*2!=1)
        {
            while(i!=start&&j==start)
            {
                list.add(mat[i][j]);
                i--;
            }
        }
        else{
            list.add(mat[i][j]);
        }
        return list;
    }
    public int[] clockwisePrint(int[][] mat, int n, int m) {
        // write code here
        int count = 0;
        List<Integer> list = new ArrayList<Integer>();
        while(n-2*count>0&&m-2*count>0)
        {
            list = printCircle(list,mat, n, m,count);
            count++;
        }
        int []mat1 = new int[n*m];
        for(int i=0;i<m*n;i++)
        {
            mat1[i] = list.get(i);
        }
        return mat1;
    }
}
发表于 2016-08-22 18:08:47 回复(0)
import java.util.*;

public class Printer {
    public int[] clockwisePrint(int[][] mat, int n, int m) {
        int mark = 0;
        int[] result = new int[m*n];
        int startRow = 0;
        int startCol = 0;
        int endRow = n-1;
        int endCol = m-1;
        while((startRow < endRow && startCol <= endCol) || (startRow <= endRow && startCol < endCol)){
            int[] res = oneClockwise(startRow,startCol,endRow,endCol,mat);
            for(int i=0;i<res.length;i++){
                result[mark] = res[i];
                mark++;
            }
            startRow++;
            startCol++;
            endRow--;
            endCol--;
        }
        if(m==n){
           result[n*m-1] = mat[startRow][endRow]; 
        }
        return result;
    }
    
    public static int[] oneClockwise(int startRow,int startCol,int endRow,int endCol,int[][] mat){
        int mark = 0;
        int size = 2*(endRow-startRow)+2*(endCol-startCol);
        if(endRow == startRow && endCol!=startCol){
        size = endCol-startCol+1;
        int[] res = new int[size];
        for(int i=startCol;i<=endCol;i++){
                res[mark] = mat[startRow][i];
                mark++;
            }
        return res;
        }
        if(endCol ==startCol && endRow!=startRow){
        size = endRow-startRow+1;
        int[] res = new int[size];
        for(int i=startRow;i<=endRow;i++){
                res[mark] = mat[i][endCol];
                mark++;
            }
        return res;
        }
        int[] res = new int[size];
        for(int i=startCol;i<=endCol;i++){
            res[mark] = mat[startRow][i];
            mark++;
        }
        for(int i=1+startRow;i<=endRow;i++){
            res[mark] = mat[i][endCol];
            mark++;
        }
        for(int i=endCol-1;i>=startCol;i--){
            res[mark] = mat[endRow][i];
            mark++;
        }
        for(int i=endRow-1;i>=startRow+1;i--){
            res[mark] = mat[i][startCol];
            mark++;
        }
        return res;  
    }
}
发表于 2016-06-29 23:29:34 回复(0)

问题信息

难度:
11条回答 29249浏览

热门推荐

通过挑战的用户

查看代码
顺时针打印矩阵