题目:
题目信息:
小智在玩数组遍历的游戏,他设计了一个程序可以实现以下功能:
现给定一个m行n列的整数数组arr,要求从arr[0][0]元素开始,按从左上到右下的对角线顺序遍历整个数组。

输入格式
输入的第一行上有两个整数,依次为m和n。
余下有m行,每行包含n个整数,构成一个整型二维数组。
(注:输入的m和n保证0 < m < 100, 0 < n < 100)
输出格式
按以上的遍历法则输出每个整数。每个整数占一行。
输入样例
3 4
1 2 4 7
3 5 8 10
6 9 11 12
输出样例
1
2
3
4
5
6
7
8
9
10
11
12
解答:
题目分析:
考点为二维数组
二维数组有m行n列
按从左上到右下的顺序遍历(难点)
题目理解:
虽然整体遍历顺序是从左上到右下,但是实际上可以看出每一轮的循环都是从右上到左下,而且每一轮的元素arr[i][j]都满足i+j的值是固定的,所以我们可以定义一个变量sum=i+j,来表示是第几轮循环,之后再根据i的值来判断什么时候进入下一轮循环
理论实现:
定义变量 m, n 来控制需要得到二维数组的大小
定义 m 行 n 列的二维数组arr[m][n]
定义变量 i 来表示数组arr的行下标,定义变量 sum 来表示该轮列下标和行下标的和,则列下标为 sum-i
使用嵌套循环输入二维数组
用do-while语句循环输出数组,循环条件为sum < m+n-2,即sum小于列下标和行下标的和,否则的话会数组越界
在循环开始用if语句判断 i 是否会发生数组越界,可知当i 大于 sum的值或者 i 大于数组的最大行 m-1时数组越界,要进行下一轮循环,进行sum++并重置i,可将i重置为sum 减去数组的最大列(n-1)得到行下标,此时又可能出现i<0的情况,所以再写一个嵌套if语句,判断如果i<0则将i赋值为0
代码实现:
import java.util.Scanner;
public class test {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int m, n;
m = scanner.nextInt();
n = scanner.nextInt();
int[][] arr;
arr = new int[m][n];
int i = 0, sum = 0;
for(int p = 0; p < m; p++)
{
for(int q = 0; q < n; q++)
{
arr[p][q] = scanner.nextInt();
}
}
do{
if(i > sum || i > (m-1))
{
sum++;
i = sum - (n-1);
if(i < 0)
{
i = 0;
}
}
System.out.println(arr[i][sum - i]);
i++;
}while(sum < m+n-2);
}
}
tips:
刚才看到另一种思路,与前面的代码基本一致,输出的思路不同,时间复杂度会比我写的高一些,但是会简单一些
理论实现:
输出时,遍历所有数组,行下标为a,列下标为b
最外层用变量sum进行循环,使sum从0到m+n-2遍历
每当a+b == sum时,输出当前数组元素,因为数组是从左到右从上到下遍历的,所以也可以达成我们的目标
import java.util.Scanner;
public class test {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
int m, n;
m = scanner.nextInt();
n = scanner.nextInt();
int[][] arr;
arr = new int[m][n];
int i = 0, sum = 0;
for(int p = 0; p < m; p++)
{
for(int q = 0; q < n; q++)
{
arr[p][q] = scanner.nextInt();
}
}
for(sum = 0; sum <= m+n-2; sum++)
{
for(int a = 0; a < m; a++)
{
for(int b = 0; b < n; b++)
{
if(a + b == sum)
{
System.out.println(arr[a][b]);
}
}
}
}
}
}
优点:
容易想到,实现简单,可以在较短的时间内完成
缺点:
时间复杂度高,会访问大量无用数组元素,从而降低代码运行效率