Leetcode打卡:最少翻转次数使二进制矩阵回文II

news/2024/11/19 12:13:44/

执行结果:通过

题目:3240 最少翻转次数使二进制矩阵回文II

给你一个 m x n 的二进制矩阵 grid 。

如果矩阵中一行或者一列从前往后与从后往前读是一样的,那么我们称这一行或者这一列是 回文 的。

你可以将 grid 中任意格子的值 翻转 ,也就是将格子里的值从 0 变成 1 ,或者从 1 变成 0 。

请你返回 最少 翻转次数,使得矩阵中 所有 行和列都是 回文的 ,且矩阵中 1 的数目可以被 4 整除 。

示例 1:

输入:grid = [[1,0,0],[0,1,0],[0,0,1]]

输出:3

解释:

输入:grid = [[0,1],[0,1],[0,0]]

输出:2

解释:

示例 3:

输入:grid = [[1],[1]]

输出:2

解释:

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m * n <= 2 * 105
  • 0 <= grid[i][j] <= 1

代码以及解题思路

代码:

int minFlips(int** grid, int gridSize, int* gridColSize) {int flips = 0;int m = gridSize, n = gridColSize[0];int midRow = m / 2, midCol = n / 2;for (int i = 0; i < midRow; i++) {for (int j = 0; j < midCol; j++) {int sum = grid[i][j] + grid[i][n - 1 - j] + grid[m - 1 - i][j] + grid[m - 1 - i][n - 1 - j];flips += fmin(sum, 4 - sum);}}if (m % 2 != 0 && n % 2 != 0) {flips += grid[midRow][midCol];}int midFlips = 0, ones = 0;if (m % 2 != 0) {for (int j1 = 0, j2 = n - 1; j1 < j2; j1++, j2--) {if (grid[midRow][j1] != grid[midRow][j2]) {midFlips++;} else {ones += grid[midRow][j1] * 2;}}}if (n % 2 != 0) {for (int i1 = 0, i2 = m - 1; i1 < i2; i1++, i2--) {if (grid[i1][midCol] != grid[i2][midCol]) {midFlips++;} else {ones += grid[i1][midCol] * 2;}}}if (midFlips == 0 && ones % 4 != 0) {midFlips += 2;}flips += midFlips;return flips;
}

解题思路:

  1. 初始化变量
    • flips 用于记录总的翻转次数。
    • m 和 n 分别表示网格的行数和列数。
    • midRow 和 midCol 分别表示网格中间行的索引和中间列的索引(如果网格的行数或列数是奇数,则midRowmidCol指向中间那一行或列)。
  2. 处理四个象限
    • 遍历网格的左上象限(不包括中间行和中间列),对于每个元素,计算它及其三个对称位置(右下、左下、右上)的元素之和sum
    • 如果sum为0或4,说明这四个元素已经相同,无需翻转。
    • 如果sum为1或3,说明这四个元素中有三个相同,一个不同,可以通过翻转不同的那个元素使其与其余三个相同,此时翻转次数加1。
    • 如果sum为2,说明这四个元素中有两个0和两个1,选择翻转其中两个元素使其全部变为0或全部变为1,此时翻转次数加2(但代码中通过fmin(sum, 4 - sum)优化为加1,因为无论翻转哪两个元素,最终效果相同,只需一次“操作”的考虑,这里“操作”可以是翻转两个或翻转零个,但结果都是使四个元素相同)。
  3. 处理中心元素
    • 如果网格的行数和列数都是奇数,那么中心元素无法通过对称位置来翻转,所以直接将其翻转(如果它是0则翻转为1,如果它是1则翻转为0),翻转次数加1。
  4. 处理中间行和中间列
    • 如果网格的行数是奇数,遍历中间行的元素,检查每一对对称的元素(例如最左边的和最右边的),如果它们不同,则需要进行一次翻转来使它们相同,记录翻转次数midFlips,如果相同,则记录这对元素为1的数量ones(乘以2是因为每次翻转都涉及两个元素)。
    • 如果网格的列数是奇数,处理同上,但遍历的是中间列的元素。
    • 最后,如果中间行和中间列都没有需要翻转的对(midFlips为0),但是ones的数量不是4的倍数(意味着无法通过一次翻转使所有元素相同),则需要额外的两次翻转(因为需要改变两个元素的状态来匹配其他元素),此时midFlips加2。
  5. 返回结果
    • 将所有计算得到的翻转次数相加,得到最终结果flips,并返回。

http://www.ppmy.cn/news/1548228.html

相关文章

[AI] 人工智能会导致大规模失业吗?——技术发展与就业关系的深度解析

近年来,人工智能(AI)的快速发展引发了社会对其潜在影响的深刻思考,其中一个核心问题就是:人工智能是否会导致大规模失业?事实上,人工智能在提高生产效率、优化工作流程、取代部分重复性工作的同时,也在为社会带来新的职业机会。然而,关于技术和就业的关系仍然存在诸多…

python贪心算法实现(纸币找零举例)

目录 问题描述 贪心策略 Python代码实现 代码解释 示例输出 注意事项 问题描述 给定一组纸币面值和一个目标金额&#xff0c;找出用最少数量的纸币来找零的方法。 贪心策略 每次选择面值最大的纸币&#xff0c;直到无法继续选择为止。 Python代码实现 def min_bills…

网络基础Linux

目录 计算机网络背景 网络发展 认识 "协议" 网络协议初识 OSI七层模型 TCP/IP五层(或四层)模型 网络传输基本流程 网络传输流程图 ​编辑 数据包封装和分用 网络中的地址管理 认识IP地址 认识MAC地址 笔记&#xff08;画的图&#xff09; 协议&#x…

如何确保爬取的数据准确性和完整性?

在数据驱动的业务环境中&#xff0c;爬虫程序的准确性和完整性至关重要。本文将探讨如何使用Java编写爬虫程序&#xff0c;并确保其在爬取数据时的准确性和完整性。 1. 精确的HTML解析 确保数据准确性的第一步是精确地解析HTML。Jsoup是Java中常用的HTML解析库&#xff0c;它提…

使用 PDF API 合并 PDF 文件

内容来源&#xff1a; 如何在 Mac 上合并 PDF 文件 1. 注册与认证 您可以注册一个免费的 ComPDFKit API 帐户&#xff0c;该帐户允许您在 30 天内免费无限制地处理 1,000 多个文档。 ComPDFKit API 使用 JSON Web Tokens 方法进行安全身份验证。从控制面板获取您的公钥和密钥&…

C# 用于将一个DataTable转换为Users对象的列表

1&#xff1a;第一种例子&#xff1a; /// <summary> /// 用户名循环赋值 /// </summary> /// <param name"dt"></param> /// <returns></returns> public List<Users> FenPeiFillModelUsers(DataTable dt) { …

版本控制【Git Bash】【Gitee】

目录 一、什么是版本控制&#xff1f; 二、版本控制的种类&#xff1a; 1、本地版本控制 2、集中版本控制 3、分布式版本控制 三、下载Git Bash 四、Git Bash 配置 五、Git Bash使用 1、切换目录&#xff1a;cd 2.查看当前文件路径&#xff1a;pwd 3.列出当前目录下文件…

工具类-基于 axios 的 http 请求工具 Request

基于 axios 的 http 请求工具 基于 axios 实现一个 http 请求工具&#xff0c;支持设置请求缓存和取消 http 请求等功能 首先实现一个 简单的 http 请求工具 import axios, {AxiosError,AxiosInterceptorManager,AxiosRequestConfig,AxiosResponse, } from axios;// 接口返回…