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

矩阵

1. 面试题 01.08. 零矩阵

    思路:
        标记0所在得行和列,对应行列全部置为0。

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int n = matrix.size(), i;
        int m = matrix[0].size(), j;
        bool row[n], colomn[m];
        memset(row, false, sizeof(row));
        memset(colomn, false, sizeof(colomn));
        for (i = 0; i < n; ++i) {
            for (j = 0; j < m; ++j) {
                if (!matrix[i][j]) {
                    if (!row[i]) row[i] = true;
                    if (!colomn[j]) colomn[j] = true;
                }
            }
        }
        for (i = 0; i < n; ++i) {
            if (row[i]) {
                for (j = 0; j < m; ++j) matrix[i][j] = 0;
            }
        }
        for (j = 0; j < m; ++j) {
            if (colomn[j]) {
                for (i = 0; i < n; ++i) matrix[i][j] = 0;
            }
        }
    }
};

2. 73. 矩阵置零

    思路:
        思路同第一题,优化掉$O(n)$的存储空间。

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int n = matrix.size(), i;
        int m = matrix[0].size(), j;
        bool colomn[m], row_flag = false;
        memset(colomn, false, sizeof(colomn));
        for (i = 0; i < n; ++i) {
            row_flag = false;
            for (j = 0; j < m; ++j) {
                if (matrix[i][j] == 0) {
                    row_flag = true;
                    if (!colomn[j]) {
                        for (int k = 0; k <= i; ++k) matrix[k][j] = 0;
                        colomn[j] = true;
                    }
                }
                if (j == m - 1 && row_flag) {
                    for (int k = 0; k < m; ++k) matrix[i][k] = 0;
                } else if (j == m - 1){
                    for (int k = 0; k < m; ++k) {
                        if (colomn[k]) matrix[i][k] = 0;
                    }
                }
            }
        }
    }
};

3. 1727. 重新排列后的最大子矩阵

    思路:
        统计每一行作为底边,向上生长可达得最大高度(即红色部分)。
偷英雄哥的图解释一下:
在这里插入图片描述
        对每行的最大可达高度升序排列,即当前行作为底边对应的最大面积就是当前列的最大高度 * (colomn - j),遍历一行得到该行的最大面积。对每一行更新答案,得到最终答案。


class Solution {
public:
    int largestSubmatrix(vector<vector<int>>& matrix) {
        int n = matrix.size(), i;
        int m = matrix[0].size(), j;
        int pline[m], tpline[m];
        int ans = 0;
        memset(pline, 0, sizeof(pline));
        for (i = 0; i < n; ++i) {
            for (j = 0; j < m; ++j) {
                if (matrix[i][j] == 0) {
                    pline[j] = 0;
                } else {
                    pline[j] += 1;
                }
            }
            for (j = 0; j < m; ++j) tpline[j] = pline[j];
            sort(tpline, tpline + m);
            for (j = 0; j < m; ++j) {
                ans = max(ans, tpline[j] * (m - j));
            }
        }
        return ans;
    }
};

4. 1034. 边界着色

    思路:
        题意 利用给定颜色给grid[row][col]所在的连通域的边界置为color。
E.g.1 grid = [[1,1],[1,2]], row = 0, col = 0, color = 3
[1,1]-->[3,3]
[1,2]-->[3,2]

E.g.2 grid = [[1,2,2],[2,3,2]], row = 0, col = 1, color = 3
[1,2,2]-->[1,3,3]
[2,3,2]-->[2,3,3]

E.g.3 grid = [[1,1,1],[1,1,1],[1,1,1]], row = 1, col = 1, color = 2
[1,1,1]-->[2,2,2]
[1,1,1]-->[2,1,2]
[1,1,1]-->[2,2,2]

        利用bfs从grid[row][col],开始搜索,找到其联通域的边界记录在margin中,最后利用margin将grid中目标联通域的边界着色,返回grid。


struct POS {
    int x, y;
};
class Solution {
    int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

    void bfs(vector<vector<int>> &grid, int row, int col, int color, vector<POS> &margin) {
        int gird_n = grid.size(), i;
        int grid_m = grid[0].size(), j;
        bool vis[gird_n][grid_m];
        int precolor = grid[row][col];
        memset(vis, false, sizeof(vis));
        queue<POS> Q;
        Q.push({row, col});
        vis[row][col] = true;

        while (!Q.empty()) {
            POS start = Q.front();
            Q.pop();
            vis[start.x][start.y] = true;
            POS temp_d;
            for (int k = 0; k < 4; ++k) {
                temp_d.x = start.x + dir[k][0];
                temp_d.y = start.y + dir[k][1];
                // 记录边界坐标
                if (temp_d.x < 0 || temp_d.x >= gird_n || temp_d.y < 0 || temp_d.y >= grid_m) {	/* 在网格边界为边界 */
                    margin.push_back(start);
                    continue;
                } 
                if (vis[temp_d.x][temp_d.y]) continue;
                if (grid[temp_d.x][temp_d.y] != precolor) {	/* 在连通域边界 */
                    margin.push_back(start);
                    continue;
                }
                Q.push(temp_d);
            }
        }
    }
public:
    vector<vector<int>> colorBorder(vector<vector<int>>& grid, int row, int col, int color) {
        vector<POS> margin;
        bfs(grid, row, col, color, margin);
        int margin_size = margin.size(), i;
        for (i = 0; i < margin_size; ++i) {
            grid[margin[i].x][margin[i].y] = color;
        }
        return grid;
    }
};
posted @ 2022-06-11 10:41  番茄元  阅读(42)  评论(0)    收藏  举报