五月集训(第11天) —— 矩阵

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了五月集训(第11天) —— 矩阵相关的知识,希望对你有一定的参考价值。

文章目录

前言

        此为《英雄算法联盟:算法集训》的内容,具体内容详见:知识星球:英雄算法联盟。加入星球后,即可享用星主 CSDN付费专栏 免费阅读 的权益。
        欢迎大家积极在评论区留言发表自己的看法,知无不言,言无不尽,养成每天刷题的习惯,也可以自己发布优质的解题报告,供社区一同鉴赏,吸引一波自己的核心粉丝。
        希望大家先自己思考,如果实在没有想法,再看下面的算法思路,如果有思路但是写不出来,可以参考朋友圈中其他人的代码,总有一款是适合你的,关注一下他,取其之长,补给之短。
        今天集训的内容是:矩阵
        前三题较为简单,第四题有一些技巧,想出来以后就会很有成就感,建议想一想。

一、练习题目

题目链接难度
1351. 统计有序矩阵中的负数★☆☆☆☆
1672. 最富有客户的资产总量★☆☆☆☆
832. 翻转图像★☆☆☆☆
1329. 将矩阵按对角线排序★★★☆☆

二、算法思路

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

        (1)直接遍历矩阵,用一个计数器统计负数即可。

class Solution 
public:
    int countNegatives(vector<vector<int>>& grid) 
        int i, j;
        int ans = 0;
        int n = grid.size();
        int m = grid[0].size();
        for(i = 0; i < n; ++i) 
            for(j = 0; j < m; ++j) 
                ans += (grid[i][j] < 0) ? 1 : 0;
            
        
        return ans;
    
;

2、最富有客户的资产总量

        (1)对于矩阵的每一行,计算加和;
        (2)这样就转变成了一个一维列向量的最大值问题,直接遍历即可;

class Solution 
public:
    int maximumWealth(vector<vector<int>>& accounts) 
        int m = accounts.size();
        int n = accounts[0].size();
        int i, j;
        int ret = -10000000;
        for(i = 0; i < m; ++i) 
            int sum = 0;
            for(j = 0; j < n; ++j) 
                sum += accounts[i][j];
            
            ret = max(ret, sum);
        
        return ret;
    
;

3、翻转图像

        (1)枚举矩阵的每一行,对每一行进行一个翻转,翻转操作类似于字符串的反转;
        (2)然后对矩阵的每个数字异或 1 即可,实现了一个原地反转。

class Solution 
    void swap(int *a, int *b) 
        int tmp;
        tmp = *a, *a = *b, *b = tmp;
    
public:
    vector<vector<int>> flipAndInvertImage(vector<vector<int>>& image) 
        int i, j;
        int n = image.size();
        int m = image[0].size();
        for(i = 0; i < n; ++i) 
            for(j = 0; j < m/2; ++j) 
                swap(&image[i][j], &image[i][m-1-j]);
            
            for(j = 0; j < m; ++j) 
                image[i][j] ^= 1;
            
        
        return image;
    
;

4、将矩阵按对角线排序

        (1)枚举每行开头、每列开头的对角线元素;
        (2)往右下角进行遍历塞入另一个数组中,然后对数组排序,再按照同样方式放置回来。

class Solution 
    void sortDiagonal(vector<vector<int>>& mat, int m, int n, int sr, int sc) 
        int r, c, x;
        vector<int> temp;
        r = sr, c = sc;    
        while(r < m && c < n) 
            temp.push_back(mat[r][c]);
            ++r, ++c;
        
        sort(temp.begin(), temp.end());
        r = sr, c = sc, x = 0;    
        while(r < m && c < n) 
            mat[r][c] = temp[x++];
            ++r, ++c;
        
    
public:
    vector<vector<int>> diagonalSort(vector<vector<int>>& mat) 
        int m = mat.size();
        int n = mat[0].size();
        int i, j, r, c, x;
        for(i = 0; i < m; ++i) 
            sortDiagonal(mat, m, n, i, 0);
        
        for(i = 1; i < n; ++i) 
            sortDiagonal(mat, m, n, 0, i);
        
        return mat;
    
;

以上是关于五月集训(第11天) —— 矩阵的主要内容,如果未能解决你的问题,请参考以下文章

五月集训(第14天) —— 栈

五月集训(第24天) —— 线段树

五月集训(第31天) —— 状态压缩

五月集训(第25天) —— 树状数组

五月集训(第30天) —— 拓扑排序

五月集训(第28天) —— 动态规划