LeetCode 566重塑矩阵 指针操作理解笔记

题目来源: 力扣题库(LeetCode) 566. 重塑矩阵

前言:

本来刚看到题目的时候,我是很开心的,这题不就是把二维数组“排扁”成一维数组,然后再排列成一个新的二维数组嘛!关键就是把一维数组重新映射回二维数组的关系式,这个我熟!(OS:终于有道名副其实的简单题了)但是LeetCode给出的待补充函数里一堆一级二级指针、还要涉及动态内存分配,属实把我整沉默了TAT,再翻翻官方给出的答案,凡是跟指针有关的我貌似是一句都看不懂呐(╯‵□′)╯︵┻━┻

一览题目

  1. 重塑矩阵

在 MATLAB 中,有一个非常有用的函数 reshape ,它可以将一个 m x n 矩阵重塑为另一个大小不同(r x c)的新矩阵,但保留其原始数据。

给你一个由二维数组 mat 表示的 m x n 矩阵,以及两个正整数 r 和 c ,分别表示想要的重构的矩阵的行数和列数。

重构后的矩阵需要将原始矩阵的所有元素以相同的 行遍历顺序 填充。

如果具有给定参数的 reshape 操作是可行且合理的,则输出新的重塑矩阵;否则,输出原始矩阵。

img

示例 1:
输入:mat = [[1,2],[3,4]], r = 1, c = 4
输出:[[1,2,3,4]]

img

示例 2:
输入:mat = [[1,2],[3,4]], r = 2, c = 4
输出:[[1,2],[3,4]]

提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 100
-1000 <= mat[i][j] <= 1000
1 <= r, c <= 300

一览代码

/**
 * 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 n = matColSize[0];
    int m = matSize;
    if(r * c != m * n)
    {
        *returnColumnSizes = matColSize;
        *returnSize = matSize;
        return mat;
    }

    int **ans = malloc(sizeof(int *) * r);
    *returnColumnSizes = malloc(sizeof(int) * r);
    *returnSize = r;
    for(int i = 0; i < r; i ++)
    {
        (*returnColumnSizes)[i] = c;
        ans[i] = malloc(sizeof(int) * c);
    }
    for(int i = 0; i < m * n; i ++)
    {
        ans[i / c][i % c] = mat[i / n][i % n];
    }
    return ans;
}

对各个参数的理解

对于

int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes)

其中:
mat为整型的二级指针,是原始矩形(二维数组)
matSize为整型变量,是矩阵的行数
matColSize为整型变量,是矩形的列数
r为整型变量,是重塑矩形的行数
c为整型变量,是重塑矩形的列数
returnSize为整型的一级指针
returnColumnSizes为整型的二级指针,是重塑矩形各行的列数(一维数组)(不是都一样吗?LeetCode莫名奇妙的数据要求???)

对指针操作的理解

通过声明一个二级指针,开辟一个二维数组

//声明二级指针部分
int **ans = malloc(sizeof(int *) * r);
//循环开辟二维数组部分
    for(int i = 0; i < r; i ++)
    {
        (*returnColumnSizes)[i] = c;//这条下面再讲(*^_^*)、
        /*
        开辟出容量为c个int的内存,将其首地址赋给ans[i]
        */
        ans[i] = malloc(sizeof(int) * c);
    }

  二级指针指向一级指针所在的内存,解引用得到一级指针指向的变量所在的内存。
  声明部分中,开辟出rint指针,这r个指针的内存是连续的。那么malloc返回的是在连续内存上的这rint指针的首地址。将其赋给ans后,我们得到了一个一维指针数组,完成了二维数组开辟中的创建!

问题来咯:这时候可以将整型赋值给数组了吗?其实只要将单个整型变量的地址赋给每个一级指针,那么我们就得到一个一维数组啦😅,那么如果是多个在连续内存上的整型呢?

  循环部分中,ans[i]访问的是第i个一级指针,而malloc返回的是在连续内存上的cint变量的首地址,也就是一个长度为c的一维数组的首地址。将其赋给一级指针ans[i]后,一级指针ans[i]便指向一个一维数组的首地址,这样一来,二维数组也开辟好啦!!!我们便可以通过ans[i][j]访问数组中的每个元素啦哈哈哈~(((φ(◎ロ◎;)φ)))

通过二级指针,开辟一维数组([ ]和*的优先级问题)

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

  理解了上文,这个就更好理解了:把多个在连续内存上的整型变量(相当于一个一维数组)的首地址赋给了一级指针*returnColumnSizes,而二级指针returnColumnSizes指向一级指针的内存,对其解引用得到的是一维数组的首地址.
  我们看下面这段代码

    for(int i = 0; i < r; i ++)
    {
        (*returnColumnSizes)[i] = c;
        ans[i] = malloc(sizeof(int) * c);//这条上面讲过了,忽略!
    }

(*returnColumnSizes)是一个二维数组,为什么要包含于括号内呢?自然是优先级的问题:

优先级 运算符
1 数组下标 [ ]
2 取值运算符 *
可见,如果是这样的*returnColumnSizes[i] = c,那么运算的过程就是:对二级指针数组的第i个元素解引用,取出一级指针的指向的内存地址.问题是我们并没有开辟出这样的内存,指定是越界访问内存了,所以编译的时候就寄了O(∩_∩)O😅😅😅
continue;
//还没写完~

原文地址:http://www.cnblogs.com/yousa/p/16827898.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性