2022-6-11 零矩阵,矩阵置零,重新排列后的最大子矩阵,边界着色,将字符串翻转到单调递增

1. 零矩阵

编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。

Example 1

输入:
[ [1,1,1],
  [1,0,1],
  [1,1,1] ]
输出:
[ [1,0,1],
  [0,0,0],
  [1,0,1] ]

Example 2

输入:
[ [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5] ]
输出:
[ [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0] ]

代码

void setZeroes(vector<vector<int>> &matrix) {
    list<tuple<int, int>> pos;
    for (int i = 0; i < matrix.size(); ++i) {
        for (int j = 0; j < matrix[0].size(); ++j) {
            if (matrix[i][j] == 0) pos.push_back({i, j});
        }
    }
    for_each(pos.begin(), pos.end(), [&](const tuple<int, int> &tp) {
        for (int i = 0; i < matrix.size(); ++i) matrix[i][get<1>(tp)] = 0;
        for (int j = 0; j < matrix[0].size(); ++j) matrix[get<0>(tp)][j] = 0;
    });
}

2. 矩阵置零

Given an m x n integer matrix matrix, if an element is 0, set its entire row and column to 0’s.

You must do it in place.

Example 1

img

Input: matrix = [[1,1,1],[1,0,1],[1,1,1]]
Output: [[1,0,1],[0,0,0],[1,0,1]]

Example 2

img

Input: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]]
Output: [[0,0,0,0],[0,4,5,0],[0,3,1,0]]

Constraints:

  • m == matrix.length
  • n == matrix[0].length
  • 1 <= m, n <= 200
  • -2^31 <= matrix[i][j] <= 2^31 - 1

Follow up:

  • A straightforward solution using O(mn) space is probably a bad idea.
  • A simple improvement uses O(m + n) space, but still not the best solution.
  • Could you devise a constant space solution?

代码

void setZeroes(vector<vector<int>> &matrix) {
    bool rowResetFlag = any_of(matrix.begin(), matrix.end(), [](const vector<int> &line) {
        return line[0] == 0;
    });
    bool colResetFlag = any_of(matrix[0].begin(), matrix[0].end(), [](int val) {
        return val == 0;
    });
    for (int i = 1; i < matrix.size(); ++i) {
        for (int j = 1; j < matrix[0].size(); ++j) {
            if (matrix[i][j] == 0) matrix[i][0] = matrix[0][j] = 0;
        }
    }
    auto resetRow = [&](int x) { for (int j = 0; j < matrix[0].size(); ++j) matrix[x][j] = 0; };
    auto resetCol = [&](int y) { for (int i = 0; i < matrix.size(); ++i) matrix[i][y] = 0; };
    for (int i = 1; i < matrix.size(); ++i) {
        if (matrix[i][0] == 0) resetRow(i);
    }
    for (int j = 0; j < matrix[0].size(); ++j) {
        if (matrix[0][j] == 0) resetCol(j);
    }
    if (rowResetFlag) resetCol(0);
    if (colResetFlag) resetRow(0);
}

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

You are given a binary matrix matrix of size m x n, and you are allowed to rearrange the columns of the matrix in any order.

Return the area of the largest submatrix within matrix where every element of the submatrix is 1 after reordering the columns optimally.

Example 1

[外链图片转存中…(img-r7jZ1nWr-1654908026707)]

Input: matrix = [[0,0,1],[1,1,1],[1,0,1]]
Output: 4
Explanation: You can rearrange the columns as shown above.
The largest submatrix of 1s, in bold, has an area of 4.

Example 2

img

Input: matrix = [[1,0,1,0,1]]
Output: 3
Explanation: You can rearrange the columns as shown above.
The largest submatrix of 1s, in bold, has an area of 3.

Constraints:

  • m == matrix.length
  • n == matrix[i].length
  • 1 <= m * n <= 10^5
  • matrix[i][j] is either 0 or 1.

代码

int largestSubmatrix(vector<vector<int>> matrix) {
    for (int i = 0; i < matrix.size(); ++i)
        for (int j = 0; j < matrix[0].size(); ++j)
            if (matrix[i][j] != 0 & i > 0) matrix[i][j] += matrix[i - 1][j];
    int result = 0;
    for (auto &line:matrix) {
        sort(line.begin(), line.end(), greater<>());
        for (int j = 0; j < line.size(); ++j) result = max(result, line[j] * (j + 1));
    }
    return result;
}

4. 边界着色

You are given an m x n integer matrix grid, and three integers row, col, and color. Each value in the grid represents the color of the grid square at that location.

Two squares belong to the same connected component if they have the same color and are next to each other in any of the 4 directions.

The border of a connected component is all the squares in the connected component that are either 4-directionally adjacent to a square not in the component, or on the boundary of the grid (the first or last row or column).

You should color the border of the connected component that contains the square grid[row][col] with color.

Return the final grid.

Example 1

Input: grid = [[1,1],[1,2]], row = 0, col = 0, color = 3
Output: [[3,3],[3,2]]

Example 2

Input: grid = [[1,2,2],[2,3,2]], row = 0, col = 1, color = 3
Output: [[1,3,3],[2,3,3]]

Constraints:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • 1 <= grid[i][j], color <= 1000
  • 0 <= row < m
  • 0 <= col < n

代码

class Solution {
private:
    vector<pair<int, int>> DIR{{1,  0},{-1, 0},{0,  1},{0,  -1}};

    void dfs(vector<vector<int>> &grid, int x, int y, vector<vector<bool>> &visited, vector<pair<int, int>> &borders, int originalColor) {
        int m = grid.size(), n = grid[0].size();
        bool isBorder = false;
        for (auto&[dx, dy]:DIR) {
            int nx = x + dx, ny = y + dy;
            if (nx < 0 || nx >= m || ny < 0 || ny >= n || grid[nx][ny] != originalColor) {
                isBorder = true;
            } else if (!visited[nx][ny]) {
                visited[nx][ny] = true;
                dfs(grid, nx, ny, visited, borders, originalColor);
            }
        }
        if (isBorder) borders.emplace_back(x, y);
    }

public:
    vector<vector<int>> colorBorder(vector<vector<int>> grid, int row, int col, int color) {
        int m = grid.size(), n = grid[0].size();
        vector<vector<bool>> visited(m, vector<bool>(n, false));
        vector<pair<int, int>> borders;
        visited[row][col] = true;
        dfs(grid, row, col, visited, borders, grid[row][col]);
        for (auto &[x, y] : borders) grid[x][y] = color;
        return grid;
    }
};

5. 将字符串翻转到单调递增

A binary string is monotone increasing if it consists of some number of 0’s (possibly none), followed by some number of 1’s (also possibly none).

You are given a binary string s. You can flip s[i] changing it from 0 to 1 or from 1 to 0.

Return the minimum number of flips to make s monotone increasing.

Example 1

Input: s = "00110"
Output: 1
Explanation: We flip the last digit to get 00111.

Example 2

Input: s = "010110"
Output: 2
Explanation: We flip to get 011111, or alternatively 000111.

Constraints:

  • 1 <= s.length <= 105
  • s[i] is either '0' or '1'.

代码

int minFlipsMonoIncr(string s) {
    vector<int> left(s.size()); // left[i] s[0,i] 包含1的个数
    vector<int> right(s.size()); // right[i] s[i,n] 包含0的个数
    for (int i = 0, cnt = 0; i < s.size(); ++i) left[i] = cnt = cnt + (s[i] == '1');
    for (int i = s.size() - 1, cnt = 0; i >= 0; --i) right[i] = cnt = cnt + (s[i] == '0');
    int result = INT_MAX;
    for (int i = 0; i < s.size(); ++i) {
        result = min(result, (i > 0 ? left[i - 1] : 0) + (i + 1 < s.size() ? right[i + 1] : 0));
    }
    return result;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值