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

0.知识概念

  1. 一维数组名是一级指针,二维数组名是二级指针
int **matrix1;
int matrixSize1;
int matrixColSize1;
int returnSize1;
int **returnColumnSizes;

调用:func(matrix1,matrixSize1,&matrixColSize1,&returnSize1,returnColumnSizes1);

int return_r = returnSize1;
int return_c = (* returnColumnSizes)[j];//j代表第j行

int return_c = *(*(returnColumnSizes+i)+j);
因为是一维数组,
所以恒有i==0;
所以:int return_c = *(*(returnColumnSizes+0)+j);
即:int return_c = *(*(returnColumnSizes)+j);//return_c为返回矩阵第j行的列数。
等价于int return_c = (* returnColumnSizes)[j];


e.g.

int returnColumnSizes2[n];
func(matrix1,matrixSize1,&matrixColSize1,&returnSize1,&returnColumnSizes2);
/*&returnColumnSizes2==将列类型转变为行类型*/
int** func(int** matrix, int matrixSize, int* matrixColSize, int* returnSize, int** returnColumnSizes){
}

matrix—传入矩阵首地址
matrixSize—传入矩阵行数
matrixColsize–传入矩阵每行的列数
returnSize—传出的参数,要想传出,那就必须得是从外界传入地址,传入地址后
才能同步改变那个变量
returnColumnSizes—传出的参数是一维数组指针,因为这个一维数组里存放着矩阵中每一行的列数
e.g. int returnColumnSizes[n];

int **myMalloc(int r, int c, int *returnSize, int **returnColumnSizes)
{
	int i;


	int **ret =(int **)malloc(sizeof(int *)*r);/*可以写成int **ret;*/
	*returnColumnSizes = (int *)malloc(sizeof(int)*r); //(3)
	*returnSize = r;/*传出矩阵的行数*/                      
    for(i = 0; i < r; ++i) {
        ret[i] = (int *)malloc( sizeof(int) * c );   /*(4)与(3)等价*/
        (*returnColumnSizes)[i] = c; /*(5)一维数组看作是二维数组的第0行*/
    }    
    return ret;
}
}

2. 解题报告

Q1: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 i,j;
    int r = imageSize;
    int c = *(imageColSize);/*等价于imageColSize[0]*/
    
    /*新的二维数组retImage,新申请了一个空间,这个空间中的值都是指针。所以二维数组名是一个二级指针*/
    int **retImage = (int **)malloc(sizeof(int *)*imageSize);//(1)

    *returnColumnSizes = (int *)malloc(sizeof(int)*r);//(2)给一维数组开辟空间

    /*确定返回行数*/
    *returnSize = r;

    /*确定返回矩阵每行的列数*/
    for(i=0;i<r;++i)
    {
        /*最本质,指的是二维数组第i个元素的首地址,地址类型是整型,最核心的要求同.
        二维数组的每一个元素都是所申请的一维数组空间的首地址(2)*/
        *(retImage+i) = (int *)malloc(sizeof(int)*c);//(3)
        *((*returnColumnSizes)+i) = c;
    }

    /*首先翻转每一行*/
   
    for(i=0;i<r;++i)
    {
        for(j=0;j<c;++j)
        {
            retImage[i][j] = image[i][c-1-j];
        }
    }

    /*再翻转每一元素*/

    for(i=0;i<r;++i)
    {
        for(j=0;j<c;++j)
        {
            retImage[i][j] ^= 1;
        }
    }
    return retImage;


}


Q2: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){

    int r = matrixSize;
    int c = *(matrixColSize);
    int i,j;
    /*返回行数*/
    *returnSize = c;

    /*返回列数存在一个一维数组中,这个一维数组有c个整型元素,
    一维数组指针指向一维数组,一维数组指针的基类型是一维数组,
    二维数组的元素,是一维数组,用一维数组名表达,一维数组名是列元素地址。
    所以用列元素地址表达。
    */
    *returnColumnSizes = (int *)malloc(sizeof(int)*c);/*给一维数组申请空间*/

    /*申请新的二维矩阵空间*/
    int **retMatrix =(int **)malloc(sizeof(int *)*c);

    for(i=0;i<c;++i)
    {
        /*给二维数组(二维矩阵)的每一个元素赋值,该值是一维整型数组的的首地址*/
        *(retMatrix+i) = (int *)malloc(sizeof(int)*r);

        /*给一维数组元素赋值*/
       *((*returnColumnSizes)+i) = r;
    }
    /*------------------------------------------------------------------*/

    for(i = 0;i<r;++i)
    {
        for(j = 0;j<c;++j)
        {
            retMatrix[j][i] = matrix[i][j];
        }
    }
    return retMatrix;
}

Q3:566. 重塑矩阵

/*内存申请模板*/
int **myMalloc(int r, int c, int* returnSize, int** returnColumnSizes)
{
    int i;
    /*返回新二维数组的行数*/
    *returnSize = r;

    /*准备一个一维数组空间,来存每一行的列数*/
    *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);
        *((*returnColumnSizes)+i) = c;
    }

    return ret;
}



/**
 * 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){

    int ** ans;
    ans = myMalloc(r,c,returnSize,returnColumnSizes);
    int mr = matSize;
    int mc = *(matColSize);
    int i,j,id;

    if(mr*mc != r*c)
    {
        /*返回行参数*/
        *returnSize = mr;

        /*返回列参数,确定每行的列数为mc*/
        for(i=0;i<mr;++i)
        {
            (*returnColumnSizes)[i] = mc;
        }
        
        /*返回原矩阵,本函数结束*/
        return mat;
    }

    for(i=0;i<r;++i)
    {
        for(j=0;j<c;++j)
        {
            id = i*c + j;
            ans[i][j] = mat[id/mc][id%mc];/*注意运算逻辑*/
        }
    }

  return ans;

}
}


Q4:2022. 将一维数组转变成二维数组


int **myMatrix(int r,int c,int *returnSize,int **returnColumnSizes)
{
    *returnSize = r;
    *returnColumnSizes = (int *)malloc(sizeof(int)*r);
    int i ;
    int** ans =(int **)malloc(sizeof(int*)*r);

    for(i=0;i<r;++i)
    {
        *(ans + i) = (int *)malloc(sizeof(int)*c);/*给二维数组赋值*/
       *((*returnColumnSizes)+i) = c; /*给一维数组赋值*/
    }
    return ans;

}

/**
 * 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** construct2DArray(int* original, int originalSize, int m, int n, int* returnSize, int** returnColumnSizes){
    int **ret;
    int i,j;

    /*无法构成这样的二维数组*/
    if(originalSize != m*n)
    {
        *returnSize = 0;
        //int **returnColumnSizes;默认为NULL
        return ret;/*ret == NULL*/
    }

 int    r = m;
  int   c = n;
    ret = myMatrix(r,c,returnSize,returnColumnSizes);
    for(i=0;i<r;++i)
    {
        for(j=0;j<c;++j)
        {
            ret[i][j] = original[i*c+j];
        }
    }

    return ret;
}

3.思考总结

(1)

	int **ret =(int **)malloc(sizeof(int *)*r);

不只是给二级指针初始化赋值,
为了满足指针变量有实参?这一句省略等号右侧会报错吗?——等号右侧不可省略,ret的值参与到了给二维数组元素赋值的运算,偏移一个数组字节的大小。
开辟r个整型变量的地址空间
int (* ret)[r];
这个效果类似于静态分配,直接定义一个二维数组 int ret[r][c];

(2)

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

ret的值在for循环中,被替代了吗?
没有,在for循环中,ret[i]—代表二维数组第i个元素值,这个元素是一个一维数组名,代表地址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值