【LeetCode】每日一题 2024_11_16 最少翻转次数使二进制矩阵回文 II(矩阵,分类讨论)

前言

每天和你一起刷 LeetCode 每日一题~

本期看点:究极分类讨论

LeetCode 启动!

今天发现力扣多了一个新功能,在题目右下角可以看到同时在线刷题的有几个人:

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

代码与解题思路

先读题:题目要求我们找到把矩阵的行和列全部变成回文且 1 的数量能被 4 整除的最小操作数

怎么样才能满足这个条件呢?

核心操作:让矩阵的四角全变成 1 或者全变成 0(取最小的操作次数)这样既能达成回文,也能达成被 4 整除的条件,接着对特殊情况进行分类讨论:

1、如果矩阵行列都是偶数,直接返回结果就行

2、如果矩阵行列都是奇数,需要增加将中间的 1 改成 0 这个操作(把中间多出来的那个元素处理掉,保证 1 的数量能够被 4 整除)

3、如果矩阵的 行/列 是奇数,那就需要对多出来的那一 行/列 进行特殊处理

如何处理?再进行分类讨论:(可以直接看代码中的解释)

1、如果 1 的数量能整除,直接累加修改次数

2、如果修改过元素,又因为 1 的数量是偶数次出现的,比如出现 2 个 1 或 6 个 1 等情况,那直接修改 diff 次就能符合被 4 整除的这个条件

3、如果没修改过元素,1 的数量又不是 4 的倍数,那就只剩一种情况了,比如出现 2 个 1 或 6 个 1 等情况,直接进行 2 次修改就能被 4 整除了

(可以尝试用样例模拟一下)代码如下:

go 复制代码
func minFlips(grid [][]int) (ans int) {
    n, m := len(grid), len(grid[0])

    // 将四角的元素都改成 0 或 1
    for i := 0; i < n/2; i++ {
        for j := 0; j < m/2; j++ {
            x, y := n-1-i, m-1-j
            cnt := grid[i][j]+grid[i][y]+grid[x][j]+grid[x][y]
            ans += min(cnt, 4-cnt)
        }
    }

    // 如果矩阵行列都是奇数,需要增加将中间的 1 改成 0 这个操作
    if n&1 == 1 && m&1 == 1 {
        ans += grid[n/2][m/2]
    }

    // diff 记录需要修改的点,cnt1 记录 1 的数量(因为 1 数量需要被 4 整除)
    diff, cnt1 := 0, 0

    // 如果矩阵的行是奇数
    if n&1 == 1 {
        for j := 0; j < m/2; j++ {
            if grid[n/2][j] == grid[n/2][m-1-j] {
                cnt1 += grid[n/2][j]*2
            } else {
                diff++
            }
        } 
    }

    // 如果矩阵的列是奇数
    if m&1 == 1 {
        for i := 0; i < n/2; i++ {
            if grid[i][m/2] == grid[n-1-i][m/2] {
                cnt1 += grid[i][m/2]*2
            } else {
                diff++
            }
        }
    }

    // 分类讨论:
    // 1、如果 1 的数量能整除,直接累加修改次数
    // 2、如果修改过元素,又因为 1 的数量是偶数次出现的
    // 比如出现 2 个 1 || 6 个 1 等情况,那直接修改 diff 次就能符合被 4 整除的这个条件
    // 3、如果没修改过元素,1 的数量又不是 4 的倍数,那就只剩一种情况了
    // 比如出现 2 个 1 || 6 个 1 等情况,直接进行 2 次修改就能被 4 整除了
    if cnt1%4 == 0 || diff > 0 {
        ans += diff
    } else {
        ans += 2
    }

    // 如果矩阵行列都是偶数,直接返回即可
    return ans
}

每天进步一点点,我们明天不见不散~

可以和我刷一辈子的每日一题吗?

一题一题,积累起来就是一辈子。

相关推荐
Dream it possible!5 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode
夏末秋也凉5 小时前
力扣-回溯-46 全排列
数据结构·算法·leetcode
南宫生5 小时前
力扣每日一题【算法学习day.132】
java·学习·算法·leetcode
柠石榴5 小时前
【练习】【回溯No.1】力扣 77. 组合
c++·算法·leetcode·回溯
Leuanghing5 小时前
【Leetcode】11. 盛最多水的容器
python·算法·leetcode
qy发大财5 小时前
加油站(力扣134)
算法·leetcode·职场和发展
qy发大财5 小时前
柠檬水找零(力扣860)
算法·leetcode·职场和发展
计算机软件程序设计8 小时前
深度学习在图像识别中的应用-以花卉分类系统为例
人工智能·深度学习·分类
不想编程小谭11 小时前
力扣LeetCode: 2506 统计相似字符串对的数目
c++·算法·leetcode
01_12 小时前
力扣hot100——LRU缓存(面试高频考题)
leetcode·缓存·面试·lru