- - - 次の日 - - -
どういう意味ですか?次の2次元配列を例にとってみましょう。
左上の要素1から始め、時計回りにらせん状にトラバースし、すべての要素をトラバースする必要があります。トラバースのパスは次の図のようになります。
この走査の後、返される要素の結果は次のとおりです。
1、2、3、4、5、10、15、20、19、18、17、16、11、6、7、8、9、14、13、12
————————————
レベル1
「トップ」を左から右にトラバースします。
「右」を上から下に移動します。
「下」を右から左に移動します。
「左」を下から上に移動します。
レベル2
「トップ」を左から右にトラバースします。
「右」を上から下に移動します。
「下」を右から左に移動します。
「左」を下から上に移動します。
レベル3
「トップ」を左から右にトラバースします。
「右」を上から下に移動します。
「下」を右から左に移動します。
3番目のレイヤーの「左」をトラバースする必要がなくなり、2次元配列のトラバースが完了しました。
public class SpiralOrder {
public static List<Integer> spiralOrder(int[][] matrix) {
List<Integer> list = new ArrayList<Integer>();
//当二维数组是空或任何一个维度是0,直接返回
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return list;
}
//m是矩阵的行数
int m = matrix.length;
//n是矩阵的列数
int n = matrix[0].length;
//大循环,从外向内逐层遍历矩阵
for(int i=0; i<(Math.min(m, n)+1)/2; i++) {
//从左到右遍历“上边”
for (int j=i; j<n-i; j++) {
list.add(matrix[i][j]);
}
//从上到下遍历“右边”
for (int j=i+1; j<m-i; j++) {
list.add(matrix[j][(n-1)-i]);
}
//从右到左遍历“下边”
for (int j=i+1; j<n-i; j++) {
list.add(matrix[(m-1)-i][(n-1)-j]);
}
//从下到上遍历“左边”
for (int j=i+1; j<m-1-i; j++) {
list.add(matrix[(m-1)-j][i]);
}
}
return list;
}
public static void main(String[] args) {
int[][] matrix = {
{ 1, 2, 3, 4, 5 },
{ 6, 7, 8, 9, 10 },
{ 11, 12, 13, 14, 15 },
{ 16, 17, 18, 19, 20 }
};
int[][] matrix2 = {
{ 1, 2, 3, 4, 5 },
{ 6, 7, 8, 9, 10 },
{ 11, 12, 13, 14, 15 },
{ 16, 17, 18, 19, 20 },
{ 21, 22, 23, 24, 25 }
};
List<Integer> resultList1 = spiralOrder(matrix);
System.out.println(Arrays.toString(resultList1.toArray()));
List<Integer> resultList2 = spiralOrder(matrix2);
System.out.println(Arrays.toString(resultList2.toArray()));
}
}
上記のコードでは、大きなループに4つの小さなループが含まれています。大きなループは各レイヤーのトラバースを制御し、4つの小さなループはそれぞれ同じレイヤーの上側、右側、下側、左側のトラバースを実現します。
最も内側のレイヤーに移動するとき、4つの小さなループはすべて実行されません。たとえば、テストコードのmatrix2の最も内側のレイヤーに要素13が1つしかない場合、最初の小さなループが実行された後、次の3つの小さなループに入りません。サイクル:
- - -終わり - - -
この記事を気に入っている友人、公式アカウントプログラマXiaohuiをフォローして、 よりエキサイティングなコンテンツをご覧ください
点个[在看],是对小灰最大的支持!