54. 螺旋矩阵
给定一个包含 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;
}
先看一下题目描述:
48. 旋转图像
给定一个 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--;
}
}
}
240. 搜索二维矩阵 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;
}
74. 搜索二维矩阵
编写一个高效的算法来判断 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%
的用户