【LeetCode 0-Start】[数组]特定顺序遍历二维数组
前言
特定顺序遍历二维数组
题目序号: 54、59、498
一、[中等]54. 螺旋矩阵
题目来源
算法思想:二维矩阵
java代码
思路:螺旋,一层层读取数据;
注意:在本题中,因为不是方阵,是m*n,即m有可能不等于n;所以要时刻判断元素个数,是否读取完成,避免读取多了,即每个for循环中要判断N>0
主要思路与下面相似,要特别注意以上条件;
分析来源.
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<Integer>();
if (matrix.length == 0) {//如果为空,直接返回
return res;
}
int r = matrix[0].length-1;//右边界
int l = 0;//左边界
int t = 0;//上边界
int b = matrix.length-1;//下边界
int n = matrix[0].length*matrix.length;//元素总数量,用来判断是否还要继续读取
while (n > 0) {//未读满时,继续读取
for (int i = l; n > 0 && i <= r; i++) {//从左往右
res.add(matrix[t][i]);
n--;
}
t++;//缩小上边界
for (int i = t; n > 0 && i <= b; i++) {//从上往下
res.add(matrix[i][r]);
n--;
}
r--;//缩小右边界
for (int i = r; n > 0 && i >= l; i--) {//从左往右
res.add(matrix[b][i]);
n--;
}
b--;//缩小下边界
for (int i = b; n > 0 && i >= t; i--) {//从下往上
res.add(matrix[i][l]);
n--;
}
l++;//缩小左边界
}
return res;//返回
}
}
二、[中等]59. 螺旋矩阵 II
题目来源
算法思想:二维数组;
java代码
思路:螺旋,一层层生成数据;
分析来源.
class Solution {
public int[][] generateMatrix(int n) {
if (n == 0) {
return null;
}
int[][] res = new int[n][n];
int r = n-1;//右边界
int l = 0;//左边界
int t = 0;//上边界
int b = n-1;//下边界
int num = 1;//填入的数字
n = n*n;//元素总数量,用来判断是否还要继续
while (n > 0) {
for (int i = l; i <= r; i++) {//从左往右
res[t][i] = num;
num++;
n--;
}
t++;//缩小上边界
for (int i = t; i <= b; i++) {//从上往下
res[i][r] = num;
num++;
n--;
}
r--;//缩小右边界
for (int i = r; i >= l; i--) {//从左往右
res[b][i] = num;
num++;
n--;
}
b--;//缩小下边界
for (int i = b; i >= t; i--) {//从下往上
res[i][l] = num;
num++;
n--;
}
l++;//缩小左边界
}
return res;
}
}
三、[中等]498. 对角线遍历
题目来源
算法思想:二维数组;
java代码
class Solution {
public int[] findDiagonalOrder(int[][] matrix) {
if (matrix.length == 0) {//[],的情形
return new int[0];
}
int M = matrix.length;//二维数组行数量
int N = matrix[0].length;//二维数组列数量
int[] res = new int[M * N];
if (M == 1){//只有一行的情况
for (int i = 0; i < N ; i++) {
res[i]=matrix[0][i];
}
return res;
}
if (N == 1){//只有一列的情况
for (int i = 0; i < M; i++) {
res[i]=matrix[i][0];
}
return res;
}
//定义:向上(左下到右上)向下(右上到左下)
boolean flag = true;//true标记向上,false标记向下
int i = 0;
int j = 0;
for (int k = 0; k < res.length; k++) {//遍历
res[k] = matrix[i][j];//填入res
if (flag) {//如果向上,向右上角移动
i--;
j++;
}else {//如果向下,向左下角移动
i++;
j--;
}
//判断是否越界,越界需要变换方向
//向上越界情形:
if (i < 0 || j >= N) {//左下到右上,越界情况:在第一行和最后一列越界
if (j < N) {//在第一行越界
i++;
flag = false;//方向修改为向下
}else {//在最后一列越界
i = i + 2;
j--;
flag = false;//方向修改为向下
}
}
//向下越界情形:
if (j < 0 || i >= M) {//右上到左下,越界情况:第一列和最后一行越界
if (i < M) {//第一列越界
j++;
flag = true;//方向修改为向上
}else {//最后一行越界
j = j + 2;
i--;
flag = true;//方向修改为向上
}
}
}
return res;
}
}