[学习报告]《LeetCode零基础指南》(第七讲) 二维数组
学习内容:https://blog.csdn.net/WhereIsHeroFrom/article/details/120875842
一、今日知识点总结
二维数组,也就是线代的矩阵。线代里面许多对矩阵的操作思维,会在代码上有呈现的方式。
矩阵通过C语言的二维数组来表示:A[n][m],n是行,m是列。二维数组就是一维数组的基础上,存的每一个元素也是一个一维数组。矩阵的每一行的元素,用一个一维数组来表示,存到另一个一维数组的元素里面,就形成了二维数组。通过A[i][j]的方式,可以表示第i行第j列的值。
既然是矩阵,就有翻转操作。
水平翻转
每一行的元素逆序,也就是对代表每一行的一维数组做翻转倒序排列操作。此操作,行列的数目没有发生改变。
垂直翻转
对每一列的元素进行逆序操作。次操作,行列的数目没有发生改变。
顺时针旋转
顺时针旋转90°,行列数目会交换,原来的m*n,旋转后为n*m。
逆时针旋转
可以理解为顺时针旋转270°,即顺时针旋转90°*3次
二维数组C语言表示
int a[3][4] = {
{1,2,3,0},
{1,0,0,0},
{1,1,0,0}
}
二维数组传参
//两个* 的mat代表二维数组的首地址,matSize表示行数,*matColSize代表每一行的个数,也就是列数,每一行的元素数目不一定相同。要看题目定义,若是n*m的矩阵,一般都表示列数相同,取matColSize[0]作为列数即可。
int sum(int **mat,int matSize, int *matColSize){
//声明行、列数的变量,就可以简化后续对行、列的取值,更易读不易出错
int row = matSize;
int col = matColSize[0];
}
二、今日解题
战绩:
1351. 统计有序矩阵中的负数
int countNegatives(int** grid, int gridSize, int* gridColSize){
int i,j,sum = 0;
int r = gridSize;
int c = gridColSize[0];
for(i=0;i<r;i++){
for(j = 0;j<c;j++){
if(grid[i][j]<0){
sum++;
}
}
}
return sum;
}
1572. 矩阵对角线元素的和
int diagonalSum(int** mat, int matSize, int* matColSize){
int r = matSize;
int c = matColSize[0];
int sum = 0;
for(int i = 0;i<matSize;i++){
sum += mat[i][i];
if(matSize-1-i != i){
sum += mat[matSize-1-i][i];
}
}
return sum;
}
//第二次做的思路
int diagonalSum(int** mat, int matSize, int* matColSize){
int r = matSize;
int c = matColSize[0];
int i,j,sum = 0;
for(i = 0;i<r;i++){
j = i;
if(j == c-1-j){
sum += mat[i][j];
}else{
sum += mat[i][j] + mat[i][c-1-j];
}
}
return sum;
}
1672. 最富有客户的资产总量
每一行的元素之和为客户的总资产,遍历每一行,在遍历每一行上的元素组个加起来,再做的最大值比较。
int maximumWealth(int** accounts, int accountsSize, int* accountsColSize){
int max = 0;//最大值比较,都要先初始化一个变量并赋值为最小值
int sum = 0;//每行的和
for(int i = 0; i<accountsSize ; i++ ){
for(int j = 0;j<accountsColSize[i];j++){
sum += accounts[i][j];//把当前行的每一列元素相加
}
if(sum>max){//若当前行的和大于最大值
max = sum;
}
sum = 0;//对和计数器清零
}
return max;
}
766. 托普利茨矩阵
拓普利兹矩阵就是对角线都相同(非正方形矩阵)
那就遍历每一条对角线,看上面的元素是否都一致
关键在于①如何确定除了正对角线[i][i]之外的其余对角线的i-j关系。②要分做下半和右上半矩阵来进行检查。③每次到遍历对角线的结束条件:可能是行数到头了或列数到头了。
注意就是到了左下、右上两个角不需要比较。
//方法1
bool isToeplitzMatrix(int** matrix, int matrixSize, int* matrixColSize){
for(int i = 0;i<matrixSize-1;i++){
int first = matrix[i][0];
int j = 0;
while(1){
if(matrix[i+j][j]!=first){
return false;
}
j++;
if(i+j==matrixSize || j == matrixColSize[0]){
break;
}
}
}
for(int i = 1;i<matrixColSize[0]-1;i++){
int first = matrix[0][i];
int j = 0;
while(1){
if(matrix[j][i+j]!=first){
return false;
}
j++;
if(i+j==matrixColSize[0] || j == matrixSize){
break;
}
}
}
return true;
}
//方法2 **
//判断当前元素开头的对角线每个元素是否一致
//sr、sc为起始的i、j
bool checkSame(int ** matrix, int sr, int sc,int maxr, int maxc){
int step = 0;
while(1){
//判断对角线元素是否完了(越界即对角线元素已经比较完了)
if(sr+step>=maxr){
break;
}
if(sc+step>=maxc){
break;
}
//每一条的对角线的元素下标,就是对角线初始位置的下标分别加1(同一个值)
if(matrix[sr+step][sc+step] != matrix[sr][sc]){
return false;
}
step++;
}
return true;
}
bool isToeplitzMatrix(int** matrix, int matrixSize, int* matrixColSize){
int r = matrixSize;
int c = matrixColSize[0];
int i,j;
//左下半部分的对角线首位
for(i = 0;i<r;i++){
if(!checkSame(matrix,i,0,r,c)){
return false;
}
}
//右上半部分的对角线首位
for(i =1;i<c;i++){
if(!checkSame(matrix,0,i,r,c)){
return false;
}
}
return true;
}
1380. 矩阵中的幸运数
思路:通过两个数组rmin[r]、cmax[c],分别记录每一行的最小值,以及每一行的最大值。
通过遍历每一行每一列得到上述两个数组后。此时,rmin[i]表示第i行的最小值,cmax[j]表示第j行的最小值
关键理解在于(1),我们取得其中一个元素a[i][j],若这个数等于rmin[i],也就是a[i][j]是这行最小数;若等于cmax[j],也就是a[i][j]是这一列的最大数,那么就符合要求。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* luckyNumbers (int** matrix, int matrixSize, int* matrixColSize, int* returnSize){
int r = matrixSize;
int c = matrixColSize[0];
int *ret = (int *)malloc( sizeof(int) * r * c);
int rmin[r];
int cmax[c];
//找到每一行的最小值
for(int i = 0;i<r;i++){
rmin[i] = 100000;
for(int j = 0;j<c;j++){
rmin[i] = rmin[i]>matrix[i][j]?matrix[i][j]:rmin[i];
}
}
//找到每一列的最大值
for(int i = 0;i<c;i++){
cmax[i] = 0;
for(int j = 0;j<r;j++){
cmax[i] = cmax[i]<matrix[j][i]?matrix[j][i]:cmax[i];
}
}
//rmin的下标表示行,cmax的下标表示列
//遍历一遍矩阵,若该元素等于该行的最小值,且等于该列的最大值,则是幸运数
*returnSize = 0;
for(int i = 0;i<r;i++){
for(int j = 0;j<c;j++){
if(matrix[i][j] == rmin[i] && matrix[i][j]==cmax[j]){ //(1)
ret[(*returnSize)++] = matrix[i][j];
}
}
}
return ret;
}
待完成:
1582. 二进制矩阵中的特殊位置
463. 岛屿的周长
三、今日收获
二维数组的题理解不是很踏实,多做多练吧