这里写目录标题
螺旋矩阵
54. 螺旋矩阵
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。
解题思想:
每一轮螺旋遍历都要重复的走上述四条边,因此只需要在循环内部控制四条边的起始点即可。
循环内部是对四条边的顺序遍历。
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
int len1=matrix.length;
int len2=matrix[0].length;
int l=0,r=len2-1;
int t=0,b=len1-1;
List<Integer> res=new ArrayList<Integer>();
while(true){
//第一条线:从左到右横
for(int j=l;j<=r;j++){
res.add(matrix[t][j]);
}
t++;
if(t>b) break;
//第二线:从上到下右
for(int i=t;i<=b;i++){
res.add(matrix[i][r]);
}
r--;
if(r<l) break;
//第三条线:从右到左横
for(int j=r;j>=l;j--){
res.add(matrix[b][j]);
}
b--;
if(b<t) break;
//第四条线:从下到上左
for(int i=b;i>=t;i--){
res.add(matrix[i][l]);
}
l++;
if(l>r) break;
}
return res;
}
}
59. 螺旋矩阵 II
题目描述:
给你一个正整数 n ,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。
解题思想0:
直接参考上一题,自定义一个n*n的矩阵,然后对矩阵进行螺旋遍历赋值即可。
class Solution {
public int[][] generateMatrix(int n) {
//最直接的思想:直接定义一个n*n的数组然后对其进行螺旋赋值
int[][] res=new int[n][n];
int x=1;
int l=0,r=n-1,t=0,b=n-1;
//开始进行螺旋遍历
while(true){
for(int j=l;j<=r;j++){
res[t][j]=x++;
}
t++;
if(t>b) break;
for(int i=t;i<=b;i++){
res[i][r]=x++;
}
r--;
if(r<l) break;
for(int j=r;j>=l;j--){
res[b][j]=x++;
}
b--;
if(b<t) break;
for(int i=b;i>=t;i--){
res[i][l]=x++;
}
l++;
if(l>r) break;
}
return res;
}
}
解题思想1:
(代码随想录思想)
以圈数为循环条件,
在循环中进行每一圈数据的填充:
从左到右
从上到下
从右到左
从下到上
设置四个边界变量left,right,top,bottom控制填充的范围,
注意在填充时,控制每条边填充的范围,此处设置填充范围为左闭右开,即[left,right)范围。
一圈数据填充完毕后,要移动四个边界,并且进行loop++,进入下一圈填充。
注意:循环结束后,如果n是奇数,最中间的一个元素会没有填充到,因此在最后要进行判断。
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
// 代码随想录思想
int left=0,right=n-1,top=0,bottom=n-1;
int loops=n/2,loop=1;
int mid=n/2;
int num=1;
vector<vector<int>> matrix(n, vector<int>(n, 0));
int i=0,j=0;
//按照圈数进行循环
while(loop<=loops){
//每圈的填充:遵循左闭右开原则:例如从左到右填充时,仅填充这些元素[left,right)
//1.从左到右
for(i=top,j=left;j<right;j++){
matrix[i][j]=num++;
}
//2.从上到下
for(i=top,j=right;i<bottom;i++){
matrix[i][j]=num++;
}
//3.从右到左
for(i=bottom,j=right;j>left;j--){
matrix[i][j]=num++;
}
//4.从下到上
for(i=bottom,j=left;i>top;i--){
matrix[i][j]=num++;
}
//一圈元素填充完毕后,将圈的四个边界收缩,然后loop++,进入下一圈的填充
right--;
top++;
bottom--;
left++;
loop++;
}
if(n%2!=0){
matrix[mid][mid]=n*n;
}
return matrix;
}
};
解题思想2:☆
思想参考:
https://leetcode.cn/problems/spiral-matrix-ii/solution/spiral-matrix-ii-mo-ni-fa-she-ding-bian-jie-qing-x/
以填充元素为循环:
class Solution(object):
def generateMatrix(self,n):
"""
:type n: int
:rtype: List[List[int]]
"""
left, right, bottom, top = 0, n - 1, n - 1, 0
i, j = 0, 0
res = [[0] * n for _ in range(n)]
num=1
while num<=n**2:
for j in range(left,right+1):
res[i][j]=num
num+=1
top+=1
for i in range(top,bottom+1):
res[i][j]=num
num+=1
right-=1
for j in range(right,left-1,-1):
res[i][j]=num
num+=1
bottom-=1
for i in range(bottom,top-1,-1):
res[i][j]=num
num+=1
left+=1
return res
有序二维数组中元素的查找
题目描述:
在一个二维数组中,每一行数据都是按照从左到右递增的顺序;
每一列数据都是从上到下递增。
实现一个函数,输入一个这样的二维数组,以及一个整数,要求判断该数是否存在于该数组中。
例:
1 2 8 9
2 4 9 12
4 7 10 13
6 8 11 15
解题思想:
一般拿到一个数组,第一反应都是从数组的左上角开始对数据进行处理;
但其实从这个题目分析,给定一个数字,从矩阵的左上角开始搜索,如果大于当前值,那么后续待查找的位置仅剔除了当前位置,因为当前位置其右侧以及下方的值都是大于该元素的。
换一个角度,从数组的右上角开始搜索:
- 如果大于当前值,那么可以剔除掉当前行的所有元素,从其下方的行继续查找;
- 如果小于当前元素,那么可以剔除当前列,从其右方的列继续查找。
bool find(vector<vector<int>> nums,int target){
int row=nums.size();
int col=nums[0].size();
int x=0,y=col-1;
while(x<row&& y>=0){
if(nums[x][y]==target) return true;
else if(nums[x][y]<target) row++;
else col--;
}
return false;
}