其他分享
首页 > 其他分享> > [学习报告]《LeetCode零基础指南》(第七讲) 二维数组

[学习报告]《LeetCode零基础指南》(第七讲) 二维数组

作者:互联网

[学习报告]《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];
  
}

二、今日解题

战绩:

image-20220320181732984

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. 岛屿的周长

三、今日收获

二维数组的题理解不是很踏实,多做多练吧

四、今日疑问

五、其他参考

标签:指南,return,matrix,int,sum,二维,数组,对角线,LeetCode
来源: https://blog.csdn.net/campchan/article/details/123618174