当前位置: 首页 > news >正文

矩阵——矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。

这道题要求原地修改矩阵(不能使用额外的矩阵空间),核心思路是:用矩阵的第一行和第一列作为标记位,记录哪些行/列需要置零:最后统一置零。

解题思路:

  1. 标记首行首列是否需要置零:因为首行首列要用来做标记,所以先单独记录它们原本是否有0.
  2. 用首行首列标记:遍历矩阵其他元素,若matrix[i][j] = 0,则标记matirx[i][0] = 0(第i行需要置零)、matrix[0]j。
  3. 置零非首行首列:根据首行首列的标记,把对应行/列置零。
  4. 最后置零首行、首列:根据第一步的标记,处理首行首列。

完整代码实现如下:
#include
#include
using namespace std;

class Solution {
public:
void setZeroes(vector<vector>& matrix) {

    int m = matrix.size();    // 矩阵行数int n = matrix[0].size(); // 矩阵列数bool firstRow = false;   // 标记第一行是否需要置零bool firstCol = false;   // 标记第一列是否需要置零// 1. 检查第一行是否有 0for (int j = 0; j < n; j++) {if (matrix[0][j] == 0) {firstRow = true;break;}}// 2. 检查第一列是否有 0for (int i = 0; i < m; i++) {if (matrix[i][0] == 0) {firstCol = true;break;}}// 3. 用第一行第一列标记需要置零的行和列(遍历除首行首列外的元素)for (int i = 1; i < m; i++) {for (int j = 1; j < n; j++) {if (matrix[i][j] == 0) {matrix[i][0] = 0; // 标记第 i 行matrix[0][j] = 0; // 标记第 j 列}}}// 4. 根据标记置零非首行首列的元素for (int i = 1; i < m; i++) {if (matrix[i][0] == 0) { // 第 i 行需要置零for (int j = 1; j < n; j++) {matrix[i][j] = 0;}}}for (int j = 1; j < n; j++) {if (matrix[0][j] == 0) { // 第 j 列需要置零for (int i = 1; i < m; i++) {matrix[i][j] = 0;}}}// 5. 最后置零第一行和第一列if (firstRow) {for (int j = 0; j < n; j++) {matrix[0][j] = 0;}}if (firstCol) {for (int i = 0; i < m; i++) {matrix[i][0] = 0;}}
}

};

// 测试代码
int main() {

vector<vector<int>> matrix = {{1, 1, 1}, {1, 0, 1}, {1, 1, 1}};
Solution sol;
sol.setZeroes(matrix);// 输出结果
for (auto& row : matrix) {for (int num : row) {cout << num << " ";}cout << endl;
}
return 0;

}

代码说明:

  1. 空间复杂度:O(1),仅使用了两个bool变量,完全满足原地算法要求。
  2. 时间复杂度:O(m×n),遍历矩阵常数次,效率最优。
  3. 关键细节
  • 必须先单独标记首行首列,否则会被后续标记覆盖(后续处理非行首列需要是以首行首列为标记位的,会将首行首列的对应位置置零),导致结果错误。
  • 先处理非首行首列,最后处理首行首列,避免标记被提前覆盖。(非首行首列是以首行首列的标记来置零的,先处理完首行首列的话会把标记覆盖掉

总结:先标记首行首列,再标记非首行首列,先处理非首行首列,再处理首行首列

http://www.jsqmd.com/news/562198/

相关文章:

  • 颈椎病:低头族的隐形警报,你的脖子正在求救!
  • 点云处理实战:如何用RMLS算法保留锐利边缘(附Python代码示例)
  • Odoo文档自动化与电子签名:企业数字化转型的终极解决方案
  • 导师推荐!盘点2026年当红之选的AI论文平台
  • React Native Splash Screen终极适配指南:完美适配不同设备的5个关键技巧
  • ColorControl终极指南:3分钟掌握显卡和电视控制神器
  • 告别耦合!用FastAPI为MinerU 2.0封装轻量Web API,无缝集成你的RAGFlow项目
  • Whisper-large-v3企业实操:金融电话录音合规审查自动化流水线
  • 第一届智慧农业与人工智能国际学术会议(SAAI 2025)的发表文章
  • SQLAdvisor终极调优指南:如何根据业务特点优化工具参数
  • 终极BewlyBewly插件指南:5分钟打造个性化Bilibili界面
  • Notepad--:跨平台中文编码支持的国产文本编辑器解决方案
  • 100101
  • 如何通过Windows Cleaner实现C盘空间释放:提升系统性能的完整指南
  • 终极指南:如何快速集成第三方SDK到NativeScript-Vue应用
  • PaddleOCR Docker镜像实战:从Java调用到表格识别,一个容器搞定OCR全流程
  • 颠覆式突破限制:五大核心技术实现网盘下载加速革命
  • 【译】 再次革新 .NET 的构建和发布方式(三)
  • Laravel Activitylog权限控制终极指南:基于角色的日志访问管理
  • 快速掌握Makefile:Hello World实例终极指南
  • Bud框架终极指南:如何快速搭建你的第一个Go全栈应用
  • VIBE革命性视频人体姿态估计:CVPR2020获奖论文完整实现解析
  • PowerBI进阶技巧:利用SWITCH函数实现动态自定义排序
  • ESP32-C2固件烧录:从硬件准备到成功下载的全流程解析
  • 西门子1200地铁扶梯控制系统超牛仿真,一台电脑轻松搞定
  • OpenClaw故障排查手册:GLM-4.7-Flash接口连接常见问题解决
  • 腰椎间盘突出:久坐办公族的隐形炸弹,腰痛别再忍了!
  • 保姆级教程:用RV1126的CIF和ISP双链路,搞定GC2053/IMX415摄像头Raw与NV12数据采集
  • 如何提升Lapce代码质量:从复杂度分析到优化实践
  • 从ChatGPT插件到MCP:一个AI开发者亲历的工具集成进化史