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

Leetcode 第 136 场双周赛题解

Leetcode 第 136 场双周赛题解

  • Leetcode 第 136 场双周赛题解
    • 题目1:3238. 求出胜利玩家的数目
      • 思路
      • 代码
      • 复杂度分析
    • 题目2:3239. 最少翻转次数使二进制矩阵回文 I
      • 思路
      • 代码
      • 复杂度分析
    • 题目3:3240. 最少翻转次数使二进制矩阵回文 II
      • 思路
      • 代码
      • 复杂度分析
    • 题目4:3241. 标记所有节点需要的时间
      • 思路
      • 代码
      • 复杂度分析

Leetcode 第 136 场双周赛题解

题目1:3238. 求出胜利玩家的数目

思路

遍历 pick,用一个 n×11 大小的矩阵,统计每个玩家得到的每种颜色的球的个数。

遍历每个玩家,如果该玩家至少有一种颜色的球大于玩家编号,则把答案加一。

代码

/*
 * @lc app=leetcode.cn id=3238 lang=cpp
 *
 * [3238] 求出胜利玩家的数目
 */

// @lc code=start
class Solution
{
public:
    int winningPlayerCount(int n, vector<vector<int>> &pick)
    {
        vector<vector<int>> cnt(n, vector<int>(11, 0));
        for (auto &p : pick)
            cnt[p[0]][p[1]]++;
        int ans = 0;
        for (int i = 0; i < n; i++)
        {
            bool judge = false;
            for (int j = 0; j < cnt[i].size(); j++)
                if (cnt[i][j] > i)
                    judge = true;
            if (judge)
                ans++;
        }
        return ans;
    }
};
// @lc code=end

复杂度分析

时间复杂度:O(nU+m),其中 m 是数组 pick 的长度,U 是 yi 的最大值。

空间复杂度:O(nU),其中 U 是 yi 的最大值。

题目2:3239. 最少翻转次数使二进制矩阵回文 I

思路

先计算所有行变成回文最少需要翻转多少次。

也就是对于每一行 row,计算这一行变成回文最少需要翻转多少次。

也就是累加 row[j]!=row[n−1−j] 的个数,其中 0≤j≤⌊n/2⌋。

对于列,统计方式同理。

两种情况取最小值,即为答案。

代码

/*
 * @lc app=leetcode.cn id=3239 lang=cpp
 *
 * [3239] 最少翻转次数使二进制矩阵回文 I
 */

// @lc code=start
class Solution
{
public:
    int minFlips(vector<vector<int>> &grid)
    {
        int m = grid.size(), n = m ? grid[0].size() : 0;
        
        int diff_row = 0;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n / 2; j++)
                diff_row += grid[i][j] != grid[i][n - 1 - j];

        int diff_col = 0;
        for (int j = 0; j < n; j++)
            for (int i = 0; i < m / 2; i++)
                diff_col += grid[i][j] != grid[m - 1 - i][j];

        return min(diff_row, diff_col);
    }
};
// @lc code=end

复杂度分析

时间复杂度:O(m * n),其中 m 和 n 分别为数组 grid 的行数和列数。

空间复杂度:O(1)。

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

思路

分类讨论。

在这里插入图片描述

特殊情况:

讨论正中间一排(如果 m 是奇数)和正中间一列(如果 n 是奇数)中的格子要如何翻转。

在这里插入图片描述

综上所述:

  • 如果 diff>0,额外把 diff 加入答案。
  • 如果 diff=0,额外把 cnt1 mod4 加入答案。

代码

/*
 * @lc app=leetcode.cn id=3240 lang=cpp
 *
 * [3240] 最少翻转次数使二进制矩阵回文 II
 */

// @lc code=start
class Solution
{
public:
    int minFlips(vector<vector<int>> &grid)
    {
        int m = grid.size(), n = m ? grid[0].size() : 0;
        int ans = 0;
        for (int i = 0; i < m / 2; i++)
            for (int j = 0; j < n / 2; j++)
            {
                int cnt1 = grid[i][j] + grid[i][n - 1 - j] + grid[m - 1 - i][j] + grid[m - 1 - i][n - 1 - j];
                ans += min(cnt1, 4 - cnt1); // 全为 1 或全为 0
            }
        if (m % 2 && n % 2 && grid[m / 2][n / 2] == 1)
        {
            // 正中间的数必须是 0
            ans++;
        }

        int diff = 0, cnt1 = 0;
        if (m % 2)
        {
            // 统计正中间这一排
            for (int j = 0; j < n / 2; j++)
            {
                if (grid[m / 2][j] != grid[m / 2][n - 1 - j])
                    diff++;
                else
                    cnt1 += grid[m / 2][j] * 2;
            }
        }
        if (n % 2)
        {
            // 统计正中间这一列
            for (int i = 0; i < m / 2; i++)
            {
                if (grid[i][n / 2] != grid[m - 1 - i][n / 2])
                    diff++;
                else
                    cnt1 += grid[i][n / 2] * 2;
            }
        }
        if (cnt1 % 4 == 0)
        {
            // 把这 diff 对数全部变成 0
            ans += diff;
        }
        else
        {
            if (diff)
            {
                // 把一对数都变成 1,其余全变成 0,要翻转 diff 个数
                ans += diff;
            }
            else
            {
                // 把两个 1 翻转为 0
                ans += 2;
            }
        }
        return ans;
    }
};
// @lc code=end

复杂度分析

时间复杂度:O(m * n),其中 m 和 n 分别为数组 grid 的行数和列数。

空间复杂度:O(1)。

题目4:3241. 标记所有节点需要的时间

思路

换根DP。

题解:【模板】第二类换根 DP(Python/Java/C++/Go)

代码

/*
 * @lc app=leetcode.cn id=3241 lang=cpp
 *
 * [3241] 标记所有节点需要的时间
 */

// @lc code=start
class Solution
{
public:
    vector<int> timeTaken(vector<vector<int>> &edges)
    {
        vector<vector<int>> g(edges.size() + 1);
        for (auto &e : edges)
        {
            int x = e[0], y = e[1];
            g[x].push_back(y);
            g[y].push_back(x);
        }

        // nodes[x] 保存子树 x 的最大深度 max_d,次大深度 max_d2,以及最大深度要往儿子 my 走
        vector<tuple<int, int, int>> nodes(g.size());
        auto dfs = [&](auto &&dfs, int x, int fa) -> int
        {
            int max_d = 0, max_d2 = 0, my = 0;
            for (int y : g[x])
            {
                if (y == fa)
                {
                    continue;
                }
                int depth = dfs(dfs, y, x) + 2 - y % 2; // 从 x 出发,往 my 方向的最大深度
                if (depth > max_d)
                {
                    max_d2 = max_d;
                    max_d = depth;
                    my = y;
                }
                else if (depth > max_d2)
                {
                    max_d2 = depth;
                }
            }
            nodes[x] = {max_d, max_d2, my};
            return max_d;
        };
        dfs(dfs, 0, -1);

        vector<int> ans(g.size());
        auto reroot = [&](auto &&reroot, int x, int fa, int from_up) -> void
        {
            auto &[max_d, max_d2, my] = nodes[x];
            ans[x] = max(from_up, max_d);
            for (int y : g[x])
            {
                if (y != fa)
                {
                    reroot(reroot, y, x, max(from_up, (y == my ? max_d2 : max_d)) + 2 - x % 2);
                }
            }
        };
        reroot(reroot, 0, -1, 0);
        return ans;
    }
};
// @lc code=end

复杂度分析

时间复杂度:O(n),其中 n 是数组 edges 的长度。

空间复杂度:O(n),其中 n 是数组 edges 的长度。


http://www.kler.cn/a/284059.html

相关文章:

  • MySQL重难点(一)索引
  • ArkTs简单入门案例:简单的图片切换应用界面
  • [前端]NodeJS常见面试题目
  • 【初阶数据结构与算法】链表刷题之移除链表元素、反转链表、找中间节点、合并有序链表、链表的回文结构
  • 基于迭代重加权最小二乘法的算法及例程
  • 24/11/13 算法笔记<强化学习> DQN算法
  • MyBatis之XML配置文件(一)
  • IT服务器安全规范 2024.08
  • Nginx: https解决安全问题
  • 对各项数据的统计汇总,集中展示,便于查看厂区情况的智慧物流开源了。
  • 【机器学习】决策树------迅速了解其基本思想,Sklearn的决策树API及构建决策树的步骤!!!
  • java虚拟JVM性能优化汇总
  • 鸿蒙开发—黑马云音乐之music页面播放音乐(下)
  • NestJs bull 用法
  • Python结构语句总结
  • 麒麟V10(x86_64)安装部署MySQL-5.1.70
  • 这个项目所需的配置文件和依赖
  • 280Hz显示器 - HKC G27H3显示器
  • 树、二叉树
  • MP条件构造器之常用功能详解(between、notBetween、like)
  • 为什么在JDBC中使用PreparedStatement?
  • HCIP笔记9-BGP(3)
  • Day51 | 117. 软件构建(拓扑排序)47. 参加科学大会 dijkstra(朴素版)
  • JavaScript 小测验 toString
  • 无人机之使用技巧篇
  • Tomcat Manager 上传 war 包大小的限制