【解题笔记】二维数组

1.统计有序矩阵中的负数

给你一个 m * n 的矩阵 grid,矩阵中的元素无论是按行还是按列,都以非递增顺序排列。 。请你统计并返回 grid 中 负数 的数目。

int countNegatives(int** grid, int gridSize, int* gridColSize){
    int r = gridSize;
    int c = gridColSize[0];
    int cnt = 0;
    for(int i = 0; i < r; i++){
        for(int j = 0; j < c; j++){
            if(grid[i][j] < 0){
                cnt++;
            }
        }
    }
    return cnt;
}
//统计数组中的非负数,
//grid 是二维数组,grieSize 是二维数组的第一维有多少个,gridColSize 是二维数组中每个第一维内有多少个
//*和[]等价的
//若数字小于0,则计数器加1;穷举完所有

2.矩阵对角线元素的和

给你一个正方形矩阵 mat,请你返回矩阵对角线元素的和。请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和

int diagonalSum(int** mat, int matSize, int* matColSize){
    int r = matSize;
    int c = matColSize;
    int sum = 0, i = 0;
    for(i = 0; i < r; i++){
        sum += mat[i][i];
    }
    for(i = 0; i < r; i++){
        if(r - 1 - i != i){
            sum += mat[i][r -1 - i];
        }
    }
    return sum;
}
//主对角线下标相同,副对角线下标之和为r-1,每个元素都只加一次,所以,主副对角线交点的那个元素应该只加一次,当副对角线下标相同时,不再相加

3.最富有客户的资产总量

给你一个 m x n 的整数网格 accounts ,其中 accounts[i][j] 是第 i​​​​​ 位客户在第 j 家银行托管的资产数量。返回最富有客户所拥有的 资产总量 。客户的 资产总量 就是他们在各家银行托管的资产数量之和。最富有客户就是 资产总量 最大的客户。

int maximumWealth(int** accounts, int accountsSize, int* accountsColSize){
    int max = 0, sum = 0;
    int i = 0, j = 0;
    for(i = 0; i < accountsSize; i++){
        sum = 0;
        for(j = 0; j < accountsColSize[i]; j++){
            sum += accounts[i][j];
        }
        if(sum > max){
            max = sum;
        }
    }
    return max;
}
//求最富的一个人,在二维数组中,每一行都是一个人的钱,将每一行的元素加起来取最大的
//accountsColSize[i]表示每一行有多少元素
//accountsSize表示有多少行

4.托普利茨矩阵

给你一个 m x n 的矩阵 matrix 。如果这个矩阵是托普利茨矩阵,返回 true ;否则,返回 false 。如果矩阵上每一条由左上到右下的对角线上的元素都相同,那么这个矩阵是 托普利茨矩阵 。

int 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;
        }
        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];
    for(int i = 0; i < c; i++){
        if( !checksame(matrix, 0, i, r, c)){
            return false;
        }
    }
    for(int i = 0; i < r; i++){
        if( !checksame(matrix, i, 0, r, c)){
            return false;
        }
    }
    return true;
}
//验证一个矩阵是不是托普利茨矩阵,就是看左上到右下的元素是不是一样,若一样,则是;否则,不是
//先自己创建一个函数,用来检验斜的一列是不是相同
//    需要满足的条件是:1)不能超过数组的范围 2)元素是否相同
//从函数传入第一行和第一列的元素,然后每个元素的下标加1,就能够访问完所有的斜对角元素
//sr 是传入的行,sc 是传入的列,maxr 是行最大下标,maxc 是列最大下标
// 在函数中传入0和i,是逐渐将第一行的元素传入,检验上半部分是不是满足条件
// 在函数中传入i和0,是逐渐将第一列的元素传入,检验下半部分是不是满足条件
// false 是0
// true  是1
// !逻辑取反,将假的变为真,真的变为假

5.矩阵中的幸运数

给你一个 m * n 的矩阵,矩阵中的数字 各不相同 。请你按 任意 顺序返回矩阵中的所有幸运数。幸运数是指矩阵中满足同时下列两个条件的元素:1)在同一行的所有元素中最小2)在同一列的所有元素中最大

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int min(int a, int b){
    return a < b ? a : b;
}
int max(int a, int b){
    return a > b ? a : b;
}
int* luckyNumbers (int** matrix, int matrixSize, int* matrixColSize, int* returnSize){
    int r = matrixSize;
    int c = matrixColSize[0];
    int i = 0, j = 0, rmin[50], cmax[50];
    int *ret = (int *)malloc(sizeof(int) * r *c);
    *returnSize = 0;
    for(i = 0; i < r; i++){
        rmin[i] = 100000;
        for(j = 0; j < c; j++){
            rmin[i] = min(rmin[i], matrix[i][j]);
            }
        }
    for(j = 0; j < c; j++){
        cmax[j] = 0;
        for(i = 0; i < r; i++){
            cmax[j] = max(cmax[j], matrix[i][j]);
        }
    }
    for(i = 0; i < r; i++){
        for(j = 0; j < c; j++){
            if(matrix[i][j] == rmin[i] && matrix[i][j] == cmax[j]){
                ret[(*returnSize)++] = matrix[i][j];
                break;
            }
        }
    }
    return ret;
}
//找矩阵中的幸运数,行最小和列最大,返回一个符合上述条件的元素的数组,不要求顺序
//传建两个数组,一个存放每一行的最小值,另一个存放每一列的最大值;
//然后从数组中一个个与最小和最大比较,若同时满足,则这个数是幸运数,此时,换行,在下一行中继续寻找
//*++;++的优先级高于*;所以用()括起来;先将这个值赋给这个位置,然后下标加一,表示此时数组含有的元素
//返回新数组

6.二进制矩阵中的特殊位置

给你一个大小为 rows x cols 的矩阵 mat,其中 mat[i][j] 是 0 或 1,请返回 矩阵 mat 中特殊位置的数目 。特殊位置 定义:如果 mat[i][j] == 1 并且第 i 行和第 j 列中的所有其他元素均为 0(行和列的下标均 从 0 开始 ),则位置 (i, j) 被称为特殊位置。

int check(int **mat, int r, int c, int i, int j){
    int k = 0;
    if(mat[i][j] != 1)
        return 0;
    for (k = 0; k < r; k++){
        if(k != i && mat[k][j]){
            return 0;
        }
    }
    for (k = 0; k < c; k++){
        if (k != j && mat[i][k])
            return 0;
    }
    return 1;
}
int numSpecial(int** mat, int matSize, int* matColSize){
    int cnt = 0, r = matSize, c = matColSize[0], i, j, sum = 0;
    for (i = 0; i < r; i++){
        for (j = 0; j < c; j++){
            sum += check(mat, r, c, i, j);
        }
    }
    return sum;
}
//求矩阵中的特殊位置,这个位置是1,该位置横纵坐标都是0
//设置一个函数,用于检验这个位置的横纵坐标是否全为0,将二维数组中元素一个一个地传过去
//如果传过去的这个值是0,则直接返回0,表示这个地方不是特殊位置
//如果传过去的这个值是1,然后从这行第一个位置开始往后走,当不是传过去的那个值位置且不为1时,符合条件,若是0,返回0,不是特殊点
//若横纵全满足,则是特殊点,返回1,表示这个点是特殊点





7.岛屿的周长

给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长

const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};
int islandPerimeter(int** grid, int gridSize, int* gridColSize) {
    int n = gridSize, m = gridColSize[0];
    int ans = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (grid[i][j]) {
                int cnt = 0;
                for (int k = 0; k < 4; ++k) {
                    int tx = i + dx[k];
                    int ty = j + dy[k];
                    if (tx < 0 || tx >= n || ty < 0 || ty >= m || !grid[tx][ty]) {
                        cnt += 1;
                    }
                }
                ans += cnt;
            }
        }
    }
    return ans;
}
//如果一个数是1,看周围0的个数,存在一个0,周长加一
//若越过数组时,说明是边界,周长加一
int islandPerimeter(int** grid, int gridSize, int* gridColSize){
    int r = gridSize;
    int c = gridColSize[0];
    int sum = 0;
    for(int i = 0; i< r; i++){
        for(int j = 0; j < c; j++){
            if(grid[i][j]){
                sum += 4;
                if(j - 1 >= 0 && grid[i][j - 1])
                    sum -= 2;
                if(i + 1 < r && grid[i + 1][j])
                    sum -= 2;
            }
        }
    }
    return sum;
}
//如果有一个1,则周长加4,若存在相邻的两个一,则周长减2,左右和上下各一次,防止重复

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值