算法-矩陣遍歷問題專輯
1、螺旋矩陣
給定一個包含 m x n 個元素的矩陣(m 行, n 列),請按照順時針螺旋順序,返回矩陣中的所有元素。
示例 1:
輸入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
輸出: [1,2,3,6,9,8,7,4,5]
示例 2:
輸入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
輸出: [1,2,3,4,8,12,11,10,9,5,6,7]
這個題目其實很簡單,解決的關鍵在於怎麼確定遍歷的邊界條件。
把矩陣看成一個洋蔥,我們一層一層的撥開矩陣的心。也就是矩陣的層。
定義兩個變量:當前層layer、剩餘未打印元素數量count作爲邊界條件
我們再按照從左到右,東上到下,從右到左,從下到上四個方向遍歷一遍,即爲完成層數條件,每次打印的時候都減去一個元素,當元素減到0了,也就結束了遍歷
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> list=new ArrayList<>();
if(matrix.length==0){
return list;
}
int m=matrix.length-1;
int n=matrix[0].length-1;
int count=(m+1)*(n+1);
int layer=0;
while (count>0){
//從左到右
for (int i=layer;i<=n-layer&&count>0;i++){
list.add(matrix[layer][i]);
count--;
}
//從上到下
for (int i=layer+1;i<=m-layer&&count>0;i++){
list.add(matrix[i][n-layer]);
count--;
}
//從右到左
for (int i=n-layer-1;i>=layer&&count>0;i--){
list.add(matrix[m-layer][i]);
count--;
}
//從下到上
for (int i=m-layer-1;i>layer&&count>0;i--){
list.add(matrix[i][layer]);
count--;
}
layer++;//讀完一層,繼續下一層
}
return list;
}
2、旋轉圖像
先看一下題目描述:
給定一個 n × n 的二維矩陣表示一個圖像。
將圖像順時針旋轉 90 度。
說明:
你必須在原地旋轉圖像,這意味着你需要直接修改輸入的二維矩陣。請不要使用另一個矩陣來旋轉圖像。
示例 1:
給定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋轉輸入矩陣,使其變爲:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
示例 2:
給定 matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],
原地旋轉輸入矩陣,使其變爲:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]
感覺這題更像是一個數學題,對於本題,有兩種解決方案。
第一種:按順時針讀取元素到一個數組裏,然後調整數組元素填充到裏面去
第二種:取矩陣的轉置,然後按行反轉
第一種寫法較爲繁瑣,這裏給出第二種寫法
public void rotate(int[][] matrix) {
int n=matrix.length;
//矩陣轉置
for(int i=0;i<n;i++){
for(int j=0;j<=i;j++){
int temp=matrix[i][j];
matrix[i][j]=matrix[j][i];
matrix[j][i]=temp;
}
}
//按行反轉
for(int i=0;i<n;i++){
int left=0,right=n-1;
while(left<right){
int temp=matrix[i][left];
matrix[i][left]=matrix[i][right];
matrix[i][right]=temp;
left++;
right--;
}
}
}
3、搜索二維矩陣 II
編寫一個高效的算法來搜索 m x n 矩陣 matrix 中的一個目標值 target。該矩陣具有以下特性:
每行的元素從左到右升序排列。
每列的元素從上到下升序排列。
示例:
現有矩陣 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
給定 target = 5,返回 true。
給定 target = 20,返回 false。
這個題目的解法有點巧妙,本質上是剪枝法。從右上角開始搜,右上角的值與目標值對比,每次裁剪一行或者一列,複雜度O(m+n)
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix.length==0){
return false;
}
int right=matrix[0].length-1,top=0;//右上角
while(right>=0&&top<matrix.length){
if(matrix[top][right]>target){
right--;//裁掉一列
}else if(matrix[top][right]<target){
top++;//裁掉一行
}else{
return true;
}
}
return false;
}
4、搜索二維矩陣
編寫一個高效的算法來判斷 m x n 矩陣中,是否存在一個目標值。該矩陣具有如下特性:
每行中的整數從左到右按升序排列。
每行的第一個整數大於前一行的最後一個整數。
示例 1:
輸入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
輸出: true
示例 2:
輸入:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
輸出: false
這倆題是一樣的,直接套上就行了
public boolean searchMatrix(int[][] matrix, int target) {
if(matrix.length==0){
return false;
}
int right=matrix[0].length-1,top=0;//右上角
while(right>=0&&top<matrix.length){
if(matrix[top][right]>target){
right--;//裁掉一列
}else if(matrix[top][right]<target){
top++;//裁掉一行
}else{
return true;
}
}
return false;
}
效率也不賴
執行結果:
通過
顯示詳情
執行用時 :
0 ms
, 在所有 Java 提交中擊敗了
100.00%
的用戶
內存消耗 :
39.3 MB
, 在所有 Java 提交中擊敗了
94.29%
的用戶