一直在刷LeetCode,也沒有放在博客上面,題目太多感覺也沒有必要放在這上面。
有興趣的可以看我的GitHub題解: https://github.com/xdxTao/LeetCode
1、什麼是螺旋矩陣呢?
1-1:我們正常的遍歷二維數組都是一層一層的遍歷。
1-2:但是螺旋遍歷的方式是這樣的
2、解題思路
2-1:遍歷的方式是:我們每次只移動 i、j,其中一個,並且一直移動到底。
2-2:我們需要考慮每一個臨界點上的變化。
2-3:我們可以定義三個變量來輔助我們判斷
- int moveFlag = ‘j’; (當moveFlag=i,的時候是移動 i,否則移動 j)
- char jDir = ‘→’; (j 移動的方向,用這種箭頭太直接了,哈哈)
- char iDir = ‘↓’; (同理 i,的移動方向)
3、舉例(下面以leetcode上面兩個題爲例)
59. 螺旋矩陣 II
題解:
- new 一個空數組裏面每一個默認數據都是0 ,(我將返回的數組命名爲 result)
- 到達右邊界 : j+1 >= n || result[i][j+1] != 0
- 到達左邊界 : j-1 < 0 || result[i][j-1] != 0
- 到達下邊界 : i+1 >= n || result[i+1][j] != 0
- 到達上邊界 : i-1 < 0 || result[i-1][j] != 0
- 其實也很好理解,就是判斷是否 超出數組範圍、和已經賦過值了
代碼:
public int[][] generateMatrix(int n) {
if (n <= 0){
return new int[][]{};
}
int[][] result = new int[n][n];
int i = 0,j = 0;
int moveFlag = 'j';
char jDir = '→';
char iDir = '↓';
int cur = 1;
while (cur <= n * n){
result[i][j] = cur;
if (moveFlag == 'j'){
if (jDir == '→'){
// 到達了右邊界
if (j+1 >= n || result[i][j+1] != 0){
// 這時,我們應該讓i,向下
moveFlag = 'i';
iDir = '↓';
i ++;
}else{
j++;
}
}else{
// 到達了左邊界
if (j-1 < 0 || result[i][j-1] != 0){
// 這時,我們應該讓i,向上
moveFlag = 'i';
iDir = '↑';
i --;
}else {
j --;
}
}
}else {
if (iDir == '↓'){
// 到了下邊界
if (i+1 >= n || result[i+1][j] != 0){
// 這時候,我們應該讓j,向左
moveFlag = 'j';
jDir = '←';
j --;
}else{
i ++;
}
}else {
// 到達了上邊界
if (i-1 < 0 || result[i-1][j] != 0){
// 這時候,我們應該讓j,向右
moveFlag = 'j';
jDir = '→';
j ++;
}else{
i --;
}
}
}
}
return result;
}
54. 螺旋矩陣
題解:
- 這題給出的二維數組名稱是 matrix,因爲數組數據可能是0,所以我們這次用 Integer.MAX_VALUE 來輔助判斷
- 到達右邊界 : j+1 >= m || matrix[i][j+1] == Integer.MAX_VALUE
- 到達左邊界 : j-1 < 0 || matrix[i][j-1] == Integer.MAX_VALUE
- 到達下邊界 : i+1 >= n || matrix[i+1][j] == Integer.MAX_VALUE
- 到達上邊界 : i-1 < 0 || matrix[i-1][j] == Integer.MAX_VALUE
- 就是判斷是否 超出數組範圍、和是否已經遍歷過了 (遍歷過的 Integer.MAX_VALUE)
代碼:
public List<Integer> spiralOrder(int[][] matrix) {
if (matrix == null || (matrix.length == 0 || matrix[0].length == 0)){
return new ArrayList<>();
}
int n = matrix.length;
int m = matrix[0].length;
int i = 0,j = 0;
int moveFlag = 'j';
char jDir = '→';
char iDir = '↓';
List<Integer> result = new ArrayList<>();
while (true){
result.add(matrix[i][j]);
matrix[i][j] = Integer.MAX_VALUE;
if (
(i-1 < 0 || matrix[i-1][j] == Integer.MAX_VALUE) &&
(i+1 >= n || matrix[i+1][j] == Integer.MAX_VALUE) &&
(j - 1 < 0 || matrix[i][j-1] == Integer.MAX_VALUE) &&
(j+1 >= m || matrix[i][j+1] == Integer.MAX_VALUE)){
return result;
}
if (moveFlag == 'j'){
if (jDir == '→'){
// 到達了右邊界
if (j+1 >= m || matrix[i][j+1] == Integer.MAX_VALUE){
// 這時,我們應該讓i,向下
moveFlag = 'i';
iDir = '↓';
i ++;
}else{
j++;
}
}else{
// 到達了左邊界
if (j-1 < 0 || matrix[i][j-1] == Integer.MAX_VALUE){
// 這時,我們應該讓i,向上
moveFlag = 'i';
iDir = '↑';
i --;
}else {
j --;
}
}
}else {
if (iDir == '↓'){
// 到了下邊界
if (i+1 >= n || matrix[i+1][j] == Integer.MAX_VALUE){
// 這時候,我們應該讓j,向左
moveFlag = 'j';
jDir = '←';
j --;
}else{
i ++;
}
}else {
// 到達了上邊界
if (i-1 < 0 || matrix[i-1][j] == Integer.MAX_VALUE){
// 這時候,我們應該讓j,向右
moveFlag = 'j';
jDir = '→';
j ++;
}else{
i --;
}
}
}
}
}