【九日集训】第八天:二级指针

二级指针顾名思义就是指针又嵌套了一个指针;
常用的变量是这样的int p = 1;
一级指针指向该变量 int * p1 = &p;
二级指针指向一级指针 int ** p2 = &p1;

解引用方法:
一级指针解引用是变量 int x = * p1;
二级指针解引用是一级指针 int * x1 = *p2;

二级指针内存申请模版:

int **myMalloc(int r, int c, int * returnSize, int ** returnColumnSizes) {
    // 创建返回二级指针数组
    int **ret = (int **)malloc(sizeof(int *) * r);
    // returnColumnSizes是二级指针,加一个*是一级指针,代表行;
    *returnColumnSizes = (int *)malloc(sizeof(int) * r);
    // returnSize解引用是常量,代表有多少行;
    *returnSize = r;
    // 遍历ret,设置每行列
    for(int i = 0; i < r; ++i) {
        ret[i] = (int *)malloc(sizeof(int) * c);
        (*returnColumnSizes)[i] = c;
    }
    return ret;
}

第一题 867. 转置矩阵

https://leetcode.cn/problems/transpose-matrix/description/
创建一个二级指针模版,只需要将数组中的ij变换位置即可;

/**
 * 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 **myMalloc(int r, int c, int * returnSize, int ** returnColumnSizes) {
    int ** ret = (int **)malloc(sizeof(int *) * r);
    *returnColumnSizes = (int *)malloc(sizeof(int) * r);
    *returnSize = r;
    for(int i = 0; i < r; ++i) {
        ret[i] = (int *)malloc(sizeof(int) * c);
        (*returnColumnSizes)[i] = c;
    }
    return ret;
}

int** transpose(int** matrix, int matrixSize, int* matrixColSize, int* returnSize, int** returnColumnSizes) {
    int r = matrixColSize[0];
    int c = matrixSize;
    int ** res = myMalloc(r, c, returnSize, returnColumnSizes);

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

第二题 832. 翻转图像

https://leetcode.cn/problems/flipping-an-image/description/

/**
 * 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 ** myMalloc(int r, int c, int * returnSize, int ** returnColumnSizes) {
    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;
    }
    return ret;
}
 
int** flipAndInvertImage(int** image, int imageSize, int* imageColSize, int* returnSize, int** returnColumnSizes) {
    int n = imageSize;
    int ** res = myMalloc(n, n, returnSize, returnColumnSizes);

    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < n; ++j) {
            res[i][j] = 1 - image[i][n - 1 - j];
        }
    }
    return res;

}

第三题 566. 重塑矩阵

https://leetcode.cn/problems/reshape-the-matrix/description/

/**
 * 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 **myMalloc(int r, int c, int * returnSize, int ** returnColumnSizes) {
    // 创建返回二级指针数组
    int **ret = (int **)malloc(sizeof(int *) * r);
    // returnColumnSizes是二级指针,加一个*是一级指针,代表行;
    *returnColumnSizes = (int *)malloc(sizeof(int) * r);
    // returnSize解引用是常量,代表有多少行;
    *returnSize = r;
    // 遍历ret,设置每行列
    for(int i = 0; i < r; ++i) {
        ret[i] = (int *)malloc(sizeof(int) * c);
        (*returnColumnSizes)[i] = c;
    }
    return ret;
}

int** matrixReshape(int** mat, int matSize, int* matColSize, int r, int c, int* returnSize, int** returnColumnSizes) {
    int n = matSize;
    int m = matColSize[0];

    int **res = myMalloc(r, c, returnSize, returnColumnSizes);
    if(n * m != r * c) {
        *returnSize = n;
        for(int i = 0; i < n; ++i) {
            (*returnColumnSizes)[i] = m;
        }
        return mat;
    }
    int id;
    for(int i = 0; i < r; ++i) {
        for(int j = 0; j < c; ++j) {
            id = i * c + j;
            res[i][j] = mat[id / m][id % m];
        }
    }
    return res;
}

第四题 2022. 将一维数组转变成二维数组

https://leetcode.cn/problems/convert-1d-array-into-2d-array/description/
第一种:
这种方法好理解,创建二维数组判断是否能够构成二维数组都不难;
如果m * n != 一维数组长度则不能构成;
一维变为二维那里,可以先遍历原数组,然后根据二维数组每一行的开始元素都等于一维数组的0 n 2n 3n...判断是否可以整除n

int **myMalloc(int r, int c, int * returnSize, int **returnColumnSizes) {
    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;
    }
    return ret;
}

int** construct2DArray(int* original, int originalSize, int m, int n, int* returnSize, int** returnColumnSizes) {
    int ** res = myMalloc(m, n, returnSize, returnColumnSizes);
    if(m * n != originalSize) {
        *returnSize = 0;
        return NULL;
    }
    int tr = 0, tc = 1;
    res[0][0] = original[0];
    for(int i = 1; i < originalSize; ++i) {
        if(i % n == 0) {
            tr++;
            tc = 0;
        }
        res[tr][tc++] = original[i];
    }
    return res;
}

第五题 1260. 二维网格迁移

https://leetcode.cn/problems/shift-2d-grid/description/



/**
 * 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 **myMalloc(int r, int c, int * returnSize, int ** returnColumnSizes) {
    // 创建返回二级指针数组
    int **ret = (int **)malloc(sizeof(int *) * r);
    // returnColumnSizes是二级指针,加一个*是一级指针,代表行;
    *returnColumnSizes = (int *)malloc(sizeof(int) * r);
    // returnSize解引用是常量,代表有多少行;
    *returnSize = r;
    // 遍历ret,设置每行列
    for(int i = 0; i < r; ++i) {
        ret[i] = (int *)malloc(sizeof(int) * c);
        (*returnColumnSizes)[i] = c;
    }
    return ret;
}

int** shiftGrid(int** grid, int gridSize, int* gridColSize, int k, int* returnSize, int** returnColumnSizes){
    int r = gridSize;
    int c = gridColSize[0];
    int ** res = myMalloc(r, c, returnSize, returnColumnSizes);
    for(int i = 0; i < r; ++i) {
        for(int j = 0; j < c; ++j) {
            int index = (i * c + j + k) % (r * c);
            res[index / c][index % c] = grid[i][j];
        }
    }
   
    return res;
}

第六题 661. 图片平滑器

https://leetcode.cn/problems/image-smoother/description/

/**
 * 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 **myMalloc(int r, int c, int * returnSize, int ** returnColumnSizes) {
    // 创建返回二级指针数组
    int **ret = (int **)malloc(sizeof(int *) * r);
    // returnColumnSizes是二级指针,加一个*是一级指针,代表行;
    *returnColumnSizes = (int *)malloc(sizeof(int) * r);
    // returnSize解引用是常量,代表有多少行;
    *returnSize = r;
    // 遍历ret,设置每行列
    for(int i = 0; i < r; ++i) {
        ret[i] = (int *)malloc(sizeof(int) * c);
        (*returnColumnSizes)[i] = c;
    }
    return ret;
}
int rn[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
int cn[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
int** imageSmoother(int** img, int imgSize, int* imgColSize, int* returnSize, int** returnColumnSizes) {
    int r = imgSize;
    int c = imgColSize[0];
    
    int **res = myMalloc(r, c, returnSize, returnColumnSizes);

    for(int i = 0; i < r; ++i) {
        for(int j = 0; j < c; ++j) {
            int temp = img[i][j];
            int s = 1;
            for(int x = 0; x < 8; ++x) {
                int ir = i + rn[x];
                int ic = j + cn[x];
                if(ir < 0 || ic < 0 || ir >= r || ic >= c) {
                    continue;
                }else {
                    temp += img[ir][ic];
                    s++;
                }
            }
            temp /= s;
            res[i][j] = temp;
        }
    }
    return res;
}

第七题 1314. 矩阵区域和

https://leetcode.cn/problems/matrix-block-sum/description/
这道题正规解法应该是前缀和,但是由于我才疏学浅,只能用四重循环暴力解出来了;
没想到竟然还能过~~~

 int **myMalloc(int r, int c, int * returnSize, int ** returnColumnSizes) {
    // 创建返回二级指针数组
    int **ret = (int **)malloc(sizeof(int *) * r);
    // returnColumnSizes是二级指针,加一个*是一级指针,代表行;
    *returnColumnSizes = (int *)malloc(sizeof(int) * r);
    // returnSize解引用是常量,代表有多少行;
    *returnSize = r;
    // 遍历ret,设置每行列
    for(int i = 0; i < r; ++i) {
        ret[i] = (int *)malloc(sizeof(int) * c);
        (*returnColumnSizes)[i] = c;
    }
    return ret;
}


int** matrixBlockSum(int** mat, int matSize, int* matColSize, int k, int* returnSize, int** returnColumnSizes) {
    int m = matSize;
    int n = matColSize[0];
    
    int ** ret = myMalloc(m, n, returnSize, returnColumnSizes);

    for(int i = 0; i < m; ++i) {
        for(int j = 0; j < n; ++j) {
            ret[i][j] = 0;
            for(int x = i - k; x <= i + k; ++x) {
                if(x < 0 || x >= m)continue;
                for(int y = j - k; y <= j + k; ++y) {
                    if(y < 0 || y >= n) continue;
                    ret[i][j] += mat[x][y];
                }
            }
        }
    }
    return ret;
}

你可能感兴趣的:(C语言九日集训,数据结构)