73.矩阵置零
思路:
遍历一次数组,当元素为0则元素所在行和列状态都设为0,遍历结束后统一更替。
要想空间复杂度达到O(1),就用数组的第一行第i列表示i列是否应该置为0,第一列第i行表示i行是否应该设为0。对于第一行和第一列额外开两个变量特判。在遍历数组的过程中如果该行/列应该置为0,他的matrix数组对应的第一行/列的元素已经置为0,后续不需要再特殊处理。
此时遍历n-1的大小的矩阵,将其按照状态置换。最后根据判断处理第一行/列。
代码:
时间复杂度O(m+n)
空间复杂度O(1)
cpp
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int n=matrix.size();
int m=matrix[0].size();
bool row1=0;
bool col1=0;
for(int i=0;i<n;i++){
if(matrix[i][0]==0){
col1=1;
}
}
for(int j=0;j<m;j++){
if(matrix[0][j]==0){
row1=1;
}
}
for(int i=1;i<n;i++)
{
for(int j=1;j<m;j++)
{
if(matrix[i][j]==0){
matrix[i][0]=0;
matrix[0][j]=0;
}
}
}
for(int i=1;i<n;i++)
{
for(int j=1;j<m;j++)
{
if(matrix[i][0]==0||matrix[0][j]==0)
{
matrix[i][j]=0;
}
}
}
if(col1==1){
for(int i=0;i<n;i++){
matrix[i][0]=0;
}
}
if(row1==1){
for(int j=0;j<m;j++){
matrix[0][j]=0;
}
}
}
};
54.螺旋矩阵
思路:
直接模拟,但不同于不控制边界,一旦发现下一步越界了或者走到了已经访问过的格子,就立刻顺时针切换方向。
此方法利用边界变量控制行走的范围,按顺时针方向逐层收缩,不需要额外开数组记录格子是否走过。
代码:
时间复杂度:O(m*n)m,n为行列数
空间复杂度:抛开输出数组,空间复杂度为O(1)
cpp
class Solution {
public:
vector<int> spiralOrder(vector<vector<int>>& matrix) {
if(matrix.size()==0 ||matrix[0].size()==0)
return{};
vector<int>ans;
int rowBegin=0,rowEnd=matrix.size()-1;
int colBegin=0,colEnd=matrix[0].size()-1;
while(true){
for(int i=colBegin;i<=colEnd;i++){
ans.push_back(matrix[rowBegin][i]);
}
if(++rowBegin>rowEnd)break;
for(int i=rowBegin;i<=rowEnd;i++){
ans.push_back(matrix[i][colEnd]);
}
if(--colEnd<colBegin)break;
for(int i=colEnd;i>=colBegin;i--){
ans.push_back(matrix[rowEnd][i]);
}
if(--rowEnd<rowBegin)break;
for(int i=rowEnd;i>=rowBegin;i--){
ans.push_back(matrix[i][colBegin]);
}
if(++colBegin>colEnd)break;
}
return ans;
}
};
48.旋转图像
思路:
先上下对称旋转,再主对角线对称旋转。
代码:
时间复杂度O(n的二次方)
空间复杂度O(1)
cpp
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int n = matrix.size();
for (int i = 0; i < n / 2; i++) {
for (int j = 0; j < n; j++) {
swap(matrix[i][j], matrix[n - i - 1][j]);
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
swap(matrix[i][j], matrix[j][i]);
}
}
}
};
240.搜索二维矩阵II
思路:
从最右上方点(x,y)开始,如果matrix[x][y]小于需要值,那么一定不在他左侧,向下移动一格,如果大于需要值,一定不在他下侧,向左移动一格,直到找到即可。
如果到了边界还没有找到就是false,时间复杂度为O(n+m),n m为数组长宽
代码:
cpp
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int i=matrix.size()-1;
int j=0;
while(j>=0 && j<matrix[0].size()){
if(matrix[i][j]>target )
{
if(i==0){
return false;
}
else{i--;}
}
else if(matrix[i][j]<target)
j++;
else return true;
}
return false;
}
};