顺时针打印矩阵
问题描述
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵:
[[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]
基本思路
递归打印 先外后内
使用了递归,外层打印完毕后,再进行内层打印。
public static void print(int[][] arr,int row_begin,int row_end,int col_begin,int col_end)
print(arr,row_begin+1,row_end-1,col_begin+1,col_end-1);
正常例子:
输入:
4 4
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
递归出口
if (row_begin>=row_end||col_begin>=col_end){
return;
}
考虑极端例子:
原本没有考虑到特殊情况
如
用flag 判断本轮打印是否终止
于是考虑到了用flag
boolean flag_continue = true;
for (col=col_begin,flag_continue = false;col<col_end;col++,flag_continue=true){
newArray.add(arr[row_begin][col]);
}
如果一轮完全没有进行,那么就说明后面也不会进行了,设flag为false,结束。
最终代码:
import java.util.ArrayList;
import java.util.Scanner;
/**
* 描述:给定一个数字矩阵,请设计一个算法从左上角开始顺时针打印矩阵元素;
*
*
*
* 输入描述
* 第一行是两个数字,分别代表行数M和列数N;
* 接下来是M行,每行N个数字,表示这个矩阵的所有元素;
* 当读到M=-1,N=-1时,输入终止;数字间均有空格隔开。
*
* 输出描述
* 请按逗号分割顺时针打印矩阵元素(注意最后一个元素末尾不要有逗号!
* 例如输出“1,2,3”,而不是“1,2,3,”),每个矩阵输出完成后记得换行;
* 测试用例:
(1)
2 2
0 1
3 2
0, 1, 2, 3
(2)
3 3
0 1 2
7 8 3
6 5 4
(3)
5 1
1
2
3
4
5
*
* */
public class Main {
public static ArrayList<Integer> newArray;
public static void main(String[] args) {
int row = 0;
int col = 0;
Scanner scanner=new Scanner(System.in);
row=scanner.nextInt();
col=scanner.nextInt();
newArray = new ArrayList<>();
int[][] arr = new int[row][col];
for (int i=0;i<row;i++){
for (int j=0;j< col;j++){
arr[i][j] = scanner.nextInt();
}
}
print(arr,0,row,0,col);
int len= newArray.size();
for (int i=0;i< len-1;i++){
System.out.print(newArray.get(i)+",");
}
System.out.println(newArray.get(len-1));
}
public static void print(int[][] arr,int row_begin,int row_end,int col_begin,int col_end){
if (row_begin>=row_end||col_begin>=col_end){
return;
}
int col;
int row;
boolean flag_continue = true;
for (col=col_begin,flag_continue = false;col<col_end;col++,flag_continue=true){
// System.out.print(arr[row_begin][col]+", ");
newArray.add(arr[row_begin][col]);
}
if(!flag_continue)
{
return;
}
for (row=row_begin+1,col--,flag_continue=false;row<row_end;row++,flag_continue=true){
// System.out.print(arr[row][col]+", ");
newArray.add(arr[row][col]);
}
if(!flag_continue)
{
return;
}
for (col--,row--,flag_continue=false;col>=col_begin;col--,flag_continue=true){
// System.out.print(arr[row][col]+", ");
newArray.add(arr[row][col]);
}
if(!flag_continue)
{
return;
}
for (row--,col++;row>row_begin && col<col_end;row--){
// System.out.print(arr[row][col]+", ");
newArray.add(arr[row][col]);
}
print(arr,row_begin+1,row_end-1,col_begin+1,col_end-1);
}
}
总结
像这类题目,不需要特殊的知识,比如像图、树、回溯问题、动态规划问题都需要特殊的方法,如果没有学过,就基本做不出。而像这类能够通过暴力方法得到,但是又很考验细心程度的题目,比较考验细心程度和编程思维。唉,其实还是自己不会图、树、回溯、动态规划,给自己找借口罢了。。。
这类题目很俗,就是考基本的循环,考递归、考特殊情况处理、考思考问题的全面性,不考数据结构。
再贴个奖杯,给自己打打气!加油吧。