[学习报告]《LeetCode零基础指南》(第8讲)二级指针

[学习报告]《LeetCode零基础指南》(第8讲)二级指针

一、今日知识点总结

学习内容:https://blog.csdn.net/WhereIsHeroFrom/article/details/120875692

1 二级指针
1.1 二级指针是啥?

首先,他是变量,一个指向指针的指针,通过 & 获取它的地址

指针,是指向某个变量的地址;存储着某个基本数据变量的地址;那么这个指针,有他自己的地址。

二级指针,则是指向某个指针的地址;存储着某个指针的变量的地址

int a =10;
int *p1 = &a;
int **p2 = &p1;
int ***p3 = &p2;//几乎很少用到

//解引用
int *p = *p2;
int b = *p;
image-20220314214053602
1.1 哪些是二级指针

矩阵 | 二维数组

二维数组,实际上是由一个一维数组,该数组每一项的值是一个一维数组的方式形成的。而一维数组变量实际上是指向第一个元素的地址的指针。则二维数组变量则是指向存储着这些指针地址的指针,故为二级指针。

1.2 怎么用?

力扣中会出现如下情况:

int** func(int** matrix,int matrixSize,int * matrixColSize, int* returnSize, int** returnColumnSizes){
  
}
参数名变量类型实际含义
matrix二级指针矩阵(二维数组)首地址 ---- 数组变量是指向数组首地址的指针变量
matrixSize普通变量矩阵 行数
matrixColSize一级指针存储每行的列数的数组 --> 矩阵每行的列数 --> 每一行有几个元素 -->是个数组
returnSize一级指针返回的矩阵(自行申请内存新建的)的行数:作为参数返回,通过指针取地址的方式传入,方法体中通过解引用来赋值
returnColumnSizes二级指针返回的矩阵,每一行的列数,作为参数返回,所以是通过指针取地址的方式传入,而记录每行的列数是一个数组,所以此处取地址传入时就是二级指针(作为数组返回)
2 内存申请模板

模板 === 每个题目都可以套用

二维数组的内存申请模板
//大致声明
int **myMalloc(int r, int c,int* returnSize,int** returnColummSizes);
int **myMalloc(int r,int c,int* returnSize,int** retrunColumnSizes){
		int i;
		int **ret = (int **)malloc(sizeof(int *) *r ); //先创建一个指针类型的数组,长度为行数r
  																								//二维数组的内存,行数为r,首地址为ret,二维数组类型为int **
  	*returnColumnSizes = (int *)malloc(sizeof(int) * r);//记录每行有多少列的数组也需要初始化
		*returnSize = r;//矩阵的行数则为r
		for(i = 0;i<r;i++){//找到每一行的首位
			ret[i] = (int *)malloc(sizeof(int) * c);//让每一行的首位指向一个int数组的首地址
			(*returnColumnSizes)[i] = c;//则每一行的列数为c (先解引用取得数组变量)
		}
		return ret;
}
3 可以解哪类题目?
题目类型解法
翻转图像通过内存申请模板获得一个新的二维数组矩阵,遍历新矩阵,每一项 ret[i][j]= 水平翻转后的位置再取反 = 1- img[i][c-1-j] (数组翻转的操作 依次首末位互换)
转置矩阵转置:主对角线翻转,行索引与列索引互换 ==>ret[i][j] = matrix[j][i] ===> 建立一个「行=原矩阵列,列为原矩阵行」的新矩阵,根据转置公式赋值。
重塑矩阵关键思路:将二维坐标转换成一维连续的数值;再将一维连续数值,按序散落到n行m列中image-20220314225538545
一维数组转二维数组关键: ret[i][j] = original[i*n+j]; 二维数组每一项和一维数组的对应关系 == 二维数组下标 求 一维数组下标
4 重点知识点:

二、今日解题

image-20220321182915900

832. 翻转图像
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** flipAndInvertImage(int** image, int imageSize, int* imageColSize, int* returnSize, int** returnColumnSizes){
    int r = imageSize;
    int c = imageColSize[0];
    int i,j;
  	//通过双指针的方式传入了一维数组的变量,解引用得到一维数组首地址
   	(*returnColumnSizes) = (int *)malloc(sizeof(int)*r);//二维数组每行的列数,是通过一个一维数组来记录的
    int **ret = (int **)malloc( sizeof(int *)*r);//创建一个二维数组
  	
    for( i = 0; i<r; i++){
      	//给二维数组的每一行创建一个一维数组,至此,二维数组构建完毕
        ret[i] = (int *)malloc(sizeof(int) * c);
      	//每一行的列数 = c
        (*returnColumnSizes)[i] = c;
    }
    //水平翻转
    for(i = 0;i<r;i++){
        if(c&1){
            ret[i][c/2] = !image[i][c/2];
        }
        for(j=0;j<c/2;j++){
            ret[i][j] = !image[i][c-j-1];
            ret[i][c-j-1] = !image[i][j];
        }
    }
    *returnSize = r;
    return ret;

    

}
867. 转置矩阵
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** transpose(int** matrix, int matrixSize, int* matrixColSize, int* returnSize, int** returnColumnSizes){
		
  	//注意这里,行和列交互了 ==> n!=m的情况,行列的结构也会交换
    int c = matrixSize;
    int r = matrixColSize[0];
    int i,j;
    *returnColumnSizes = (int *)malloc( sizeof(int) * r);
    *returnSize = r;
    //构建二维数组
    int **ret = (int **)malloc( sizeof(int **) * r);
    for(i = 0; i<r; i++){
        ret[i] = (int *)malloc( sizeof(int) * c);
        (*returnColumnSizes)[i] = c;
    }

    //转置公式 ret[i][j] = matrix[j][i]
    for(i = 0;i<r;i++){
        for(j=0;j<c;j++){
            ret[i][j] = matrix[j][i];
        }
    }
    
    return ret;

    

}
566. 重塑矩阵
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes){


   if(matSize * matColSize[0] != r*c){
        *returnSize = matSize;
        *returnColumnSizes = matColSize;
        return mat;
    }

    int** ret = (int **)malloc( sizeof(int*) * r);
    *returnSize = r;
    *returnColumnSizes = (int *)malloc(sizeof(int)*r);
    for(int i = 0;i<r;i++){
        ret[i] = (int *)malloc(sizeof(int)*c);
        (*returnColumnSizes)[i] = c;
        
    }

   for(int i = 0;i<matSize;i++){
       for(int j=0;j<matColSize[0];j++){
           int count = i*matColSize[0]+j;
           ret[count/c][count%c] = mat[i][j];
       }
   }
    // int n  =matColSize[0];
    // for(int i=0;i<r;i++){
    //     for(int j=0;j<c;j++){
    //         int id = i*c +j;
    //         ret[i][j] = mat[id/n][id%n];
    //     }
    // }
    return ret;

}

三、今日收获

四、今日疑问

暂无

五、其他参考

用一维数组来表示二维数组

https://www.bilibili.com/s/video/BV1XJ411a7A8

主要助于理解 一维数组和二维数组转换之间的下标关系求解

image-20220314233739271 image-20220314233505009 image-20220314233555384 image-20220314233622402
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忘词木头人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值