LeetCode 每日一题笔记 日期:2025.03.25 题目:3546.等和矩阵分割

LeetCode 每日一题笔记

0. 前言

  • 日期:2025.03.25
  • 题目:3546.等和矩阵分割
  • 难度:中等
  • 标签:数组 矩阵 前缀和

1. 题目理解

问题描述

给你一个由正整数组成的 m x n 矩阵 grid。你的任务是判断是否可以通过 一条水平或一条垂直分割线 将矩阵分割成两部分,使得:

分割后形成的每个部分都是 非空 的。

两个部分中所有元素的和 相等。

如果存在这样的分割,返回 true;否则,返回 false。

示例

输入: grid = [[1,4],[2,3]]

输出: true

解释:矩阵总和为 10,目标和为 5。

水平分割第一行,和为 5,满足条件。

2. 解题思路

核心观察

  • 要将矩阵分成和相等的两部分,总和必须是偶数,否则直接返回 false;
  • 水平分割:从上到下累加行和,若某一行累加和等于总和的一半,则可分割;
  • 垂直分割:从左到右累加列和,若某一列累加和等于总和的一半,则可分割;
  • 矩阵元素全为正整数,累加和单调递增,无需考虑重复或回退。

算法步骤

  1. 计算矩阵所有元素的总和 total;
  2. 若 total 是奇数,直接返回 false;
  3. 计算目标和 target = total / 2;
  4. 从上到下逐行累加,判断是否存在行前缀和等于 target;
  5. 从左到右逐列累加,判断是否存在列前缀和等于 target;
  6. 满足任一条件返回 true,否则返回 false。

3. 代码实现

java 复制代码
class Solution {
    public boolean canPartitionGrid(int[][] grid) {
        int n = grid.length;
        int m = grid[0].length;
        long total = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                total += grid[i][j];
            }
        }
        if (total % 2 != 0) return false;
        long target = total / 2;
        long sum = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                sum += grid[i][j];
            }
            if (sum == target) {
                return true;
            }
        }
          long colSum = 0;
        for (int j = 0; j < m; j++) {
            for (int i = 0; i < n; i++) {
                colSum += grid[i][j];
            }
            if (colSum == target) return true;
        }
        return false;
    }
}

4. 代码优化说明

优化点:提前终止遍历

由于元素均为正整数,当前累加和超过 target 时可直接终止当前方向的遍历,减少无效计算:

java 复制代码
class Solution {
    public boolean canPartitionGrid(int[][] grid) {
        int n = grid.length;
        int m = grid[0].length;
        long total = 0;
        for (int[] row : grid) {
            for (int num : row) total += num;
        }
        if (total % 2 != 0) return false;
        long target = total / 2;

        long rowSum = 0;
        for (int[] row : grid) {
            for (int num : row) rowSum += num;
            if (rowSum == target) return true;
            if (rowSum > target) break;
        }

        long colSum = 0;
        for (int j = 0; j < m; j++) {
            for (int i = 0; i < n; i++) colSum += grid[i][j];
            if (colSum == target) return true;
            if (colSum > target) break;
        }
        return false;
    }
}

5. 复杂度分析

  • 时间复杂度:(O(m \times n))

    • 遍历矩阵计算总和:(O(mn));
    • 水平/垂直遍历:各一次完整矩阵遍历,总复杂度线性。
  • 空间复杂度:(O(1))

    • 仅使用常量级额外空间。

6. 总结

  • 核心思路:总和判断 + 行/列前缀和验证
  • 关键技巧:利用正整数单调性,只需一次顺序遍历即可判断可分割性;
  • 适用场景:单条水平/垂直线分割、两部分非空、和相等的矩阵判定问题。

关键点回顾

  1. 总和必须为偶数是可分割的必要条件;
  2. 只需检查行前缀和、列前缀和是否等于总和一半;
  3. 正整数保证累加和单调,可提前终止无效遍历。
相关推荐
承渊政道11 小时前
【递归、搜索与回溯算法】(二叉树深搜模型拆解与经典题型全面突破)
数据结构·c++·学习·算法·leetcode·macos·bfs
鱼鳞_11 小时前
Java学习笔记_Day32(IO流字符集字符流)
java·笔记·学习
lkbhua莱克瓦2411 小时前
ZogginWeb 电脑端沉浸式记单词功能优化升级业务需求文档
笔记·电脑
泽020211 小时前
OJBalancer ----- 基于负载均衡仿leetcode的刷题界面
linux·leetcode·负载均衡
kobesdu12 小时前
【ROS2实战笔记-4】Gazebo:从通信桥接到性能瓶颈相关技术梳理
笔记·机器人·ros·gazebo
EQ-雪梨蛋花汤12 小时前
【笔记】安卓毛玻璃效果(Blur)实现笔记(使用BlurView)(结尾附:源码)
android·笔记
zore_c12 小时前
【C++】C++——类的默认成员函数(构造、析构、拷贝构造函数)
java·c语言·c++·笔记·算法·排序算法
夜瞬20 小时前
NLP学习笔记01:文本预处理详解——从清洗、分词到词性标注
笔记·学习·自然语言处理
中屹指纹浏览器20 小时前
指纹浏览器内核级渲染伪造技术:Canvas/WebGL/AudioContext深度伪造与检测绕过实战
经验分享·笔记
-Springer-21 小时前
STM32 学习 —— 个人学习笔记11-1(SPI 通信协议及 W25Q64 简介 & 软件 SPI 读写 W25Q64)
笔记·stm32·学习