Leetcode 第 422 场周赛题解

news2024/11/5 16:52:26

Leetcode 第 422 场周赛题解

  • Leetcode 第 422 场周赛题解
    • 题目1:3340. 检查平衡字符串
      • 思路
      • 代码
      • 复杂度分析
    • 题目2:3341. 到达最后一个房间的最少时间 I
      • 思路
      • 代码
      • 复杂度分析
    • 题目3:3342. 到达最后一个房间的最少时间 II
      • 思路
      • 代码
      • 复杂度分析
    • 题目4:3343. 统计平衡排列的数目
      • 思路
      • 代码
      • 复杂度分析

Leetcode 第 422 场周赛题解

题目1:3340. 检查平衡字符串

思路

模拟。

代码

/*
 * @lc app=leetcode.cn id=3340 lang=cpp
 *
 * [3340] 检查平衡字符串
 */

// @lc code=start
class Solution
{
public:
    bool isBalanced(string num)
    {
        int oddSum = 0, evenSum = 0;
        for (int i = 0; i < num.length(); i++)
            (i % 2 ? oddSum : evenSum) += (num[i] - '0');

        return oddSum == evenSum;
    }
};
// @lc code=end

复杂度分析

时间复杂度:O(n),其中 n 是字符串 num 的长度。

空间复杂度:O(1)。

题目2:3341. 到达最后一个房间的最少时间 I

思路

广度优先搜索。

一个节点的最短路径可能来自于上下左右,单纯用BFS会导致重复访问节点,造成死循环问题。为此,使用一个distance[m][n]的数组来记录从(0,0)节点到当前节点(i,j)的最短路径,当重复访问节点时,只有在当前最小值被更新时,才将这个节点加入队列(相当于更新操作,重新从该点出发去找寻到达最终节点的最短路径),否则不加入队列,这样就不会造成死循环问题。

代码

/*
 * @lc app=leetcode.cn id=3341 lang=cpp
 *
 * [3341] 到达最后一个房间的最少时间 I
 */

// @lc code=start
class Solution
{
private:
    const int dx[4] = {0, 1, 0, -1};
    const int dy[4] = {1, 0, -1, 0};

public:
    int minTimeToReach(vector<vector<int>> &moveTime)
    {
        int m = moveTime.size(), n = m ? moveTime[0].size() : 0;

        // distance[i][j]记录从节点(0,0)到当前节点(i,j)的最短路径
        vector<vector<int>> distance(m, vector<int>(n, INT_MAX / 2));
        queue<pair<int, int>> q;
        int ans = INT_MAX;

        q.push({0, 0});
        distance[0][0] = 0;

        while (!q.empty())
        {
            auto t = q.front();
            q.pop();
            int x = t.first / n, y = t.first % n;

            if (x == m - 1 && y == n - 1)
                ans = min(ans, t.second);

            for (int i = 0; i < 4; i++)
            {
                int r = x + dx[i], c = y + dy[i];
                if (r >= 0 && r < m && c >= 0 && c < n)
                {
                    if (moveTime[r][c] >= distance[x][y])
                    {
                        if (distance[r][c] <= moveTime[r][c] + 1)
                            continue;
                        distance[r][c] = moveTime[r][c] + 1;
                        q.push({r * n + c, distance[r][c]});
                    }
                    else
                    {
                        if (distance[r][c] <= distance[x][y] + 1)
                            continue;
                        distance[r][c] = distance[x][y] + 1;
                        q.push({r * n + c, distance[r][c]});
                    }
                }
            }
        }

        return ans;
    }
};
// @lc code=end

复杂度分析

时间复杂度:O(m * n),其中 m 和 n 分别表示二维数组 moveTime 的长度和宽度。

空间复杂度:O(m * n),其中 m 和 n 分别表示二维数组 moveTime 的长度和宽度。

题目3:3342. 到达最后一个房间的最少时间 II

思路

题目要计算从左上角到右下角的最短路,这可以用 Dijkstra 算法解决。

设从起点走到 (i,j) 的最短路为 distance[i][j]。

那么从 (i,j) 走到相邻格子 (x,y),到达 (x,y) 的时间为 max(dis[i][j],moveTime[x][y])+time。

对于本题,由于每走一步 time 都会在 1,2 之间变化,联系国际象棋棋盘,(i+j) 的奇偶性就决定了 time,即 time=(i+j)mod2+1。

由于一定可以从起点走到终点,我们可以在循环中判断,只要出堆的点是终点,就立刻返回 dis[m−1][n−1]。

代码

/*
 * @lc app=leetcode.cn id=3342 lang=cpp
 *
 * [3342] 到达最后一个房间的最少时间 II
 */

// @lc code=start
class Solution
{
private:
    const int dx[4] = {0, 1, 0, -1};
    const int dy[4] = {1, 0, -1, 0};

public:
    int minTimeToReach(vector<vector<int>> &moveTime)
    {
        int m = moveTime.size(), n = m ? moveTime[0].size() : 0;

        // distance[i][j]记录从节点(0,0)到当前节点(i,j)的最短路径
        vector<vector<int>> distance(m, vector<int>(n, INT_MAX));
        priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;

        pq.emplace(0, 0, 0);
        distance[0][0] = 0;

        while (1)
        {
            auto [dis, x, y] = pq.top();
            pq.pop();

            if (x == m - 1 && y == n - 1)
                return dis;

            if (dis > distance[x][y])
                continue;

            for (int i = 0; i < 4; i++)
            {
                int r = x + dx[i], c = y + dy[i];
                if (r >= 0 && r < m && c >= 0 && c < n)
                {
                    int new_dis = max(dis, moveTime[r][c]) + (x + y) % 2 + 1;
                    if (new_dis < distance[r][c])
                    {
                        distance[r][c] = new_dis;
                        pq.emplace(new_dis, r, c);
                    }
                }
            }
        }
    }
};
// @lc code=end

复杂度分析

时间复杂度:O(m * n * log(m * n)),其中 m 和 n 分别表示二维数组 moveTime 的长度和宽度。

空间复杂度:O(m * n),其中 m 和 n 分别表示二维数组 moveTime 的长度和宽度。

题目4:3343. 统计平衡排列的数目

思路

多重集排列数 + 计数 DP。

题解:https://leetcode.cn/problems/count-number-of-balanced-permutations/solutions/2975507/duo-zhong-ji-pai-lie-shu-ji-shu-dppython-42ky/

代码

/*
 * @lc app=leetcode.cn id=3343 lang=cpp
 *
 * [3343] 统计平衡排列的数目
 */

// @lc code=start
const int MOD = 1'000'000'007;
const int MX = 41;

long long F[MX];     // F[i] = i!
long long INV_F[MX]; // INV_F[i] = i!^-1

long long pow(long long x, int n)
{
    long long res = 1;
    for (; n; n /= 2)
    {
        if (n % 2)
        {
            res = res * x % MOD;
        }
        x = x * x % MOD;
    }
    return res;
}

auto init = []
{
    F[0] = 1;
    for (int i = 1; i < MX; i++)
    {
        F[i] = F[i - 1] * i % MOD;
    }
    INV_F[MX - 1] = pow(F[MX - 1], MOD - 2);
    for (int i = MX - 1; i; i--)
    {
        INV_F[i - 1] = INV_F[i] * i % MOD;
    }
    return 0;
}();

class Solution
{
public:
    int countBalancedPermutations(string num)
    {
        int cnt[10];
        int total = 0;
        for (char c : num)
        {
            cnt[c - '0']++;
            total += c - '0';
        }

        if (total % 2)
            return 0;

        // 原地求前缀和
        partial_sum(cnt, cnt + 10, cnt);

        int n = num.size(), n1 = n / 2;
        vector<vector<vector<int>>> memo(10, vector(n1 + 1, vector<int>(total / 2 + 1, -1))); // -1 表示没有计算过
        auto dfs = [&](auto &dfs, int i, int left1, int left_s) -> int
        {
            if (i < 0)
            {
                return left_s == 0;
            }
            int &res = memo[i][left1][left_s]; // 注意这里是引用
            if (res != -1)
            { // 之前计算过
                return res;
            }
            res = 0;
            int c = cnt[i] - (i ? cnt[i - 1] : 0);
            int left2 = cnt[i] - left1;
            for (int k = max(c - left2, 0); k <= min(c, left1) && k * i <= left_s; k++)
            {
                int r = dfs(dfs, i - 1, left1 - k, left_s - k * i);
                res = (res + r * INV_F[k] % MOD * INV_F[c - k]) % MOD;
            }
            return res;
        };
        return F[n1] * F[n - n1] % MOD * dfs(dfs, 9, n1, total / 2) % MOD;
    }
};
// @lc code=end

复杂度分析

时间复杂度:O(n2S),其中 n 为字符串 num 的长度,S 为字符串 num 的数字和的一半,这不超过 9n/2。注意本题要把状态 i 和枚举 k 结合起来看,这二者一起是 O(n) 的。

空间复杂度:O(DnS),其中 D=10。保存多少状态,就需要多少空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2233691.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

服务器作业(2)

架设一台NFS服务器&#xff0c;并按照以下要求配置 关闭防火墙 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 配置文件设置&#xff1a; [rootlocalhost ~]# vim /etc/exports 1、开放/nfs/shared目录&#xff0c;供所有用户查询资料 共享…

架构师备考-软件工程相关补充

目录 软件开发生命周期 软件工程过程 软件维护分类 遗留系统 软件重用 逆向工程 相关概念 抽象层次 需求工程 需求工程主要活动 需求管理的主要活动 需求获取的主要步骤 需求获取方法 需求变更管理的过程 净室软件工程 定义 理论基础 技术手段 应用 缺点 软…

基于SSM+VUE小型企业财务报销管理系统JAVA|VUE|Springboot计算机毕业设计源代码+数据库+LW文档+开题报告+答辩稿+部署教+代码讲解

源代码数据库LW文档&#xff08;1万字以上&#xff09;开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统&#xff1a;Window操作系统 2、开发工具&#xff1a;IntelliJ IDEA或者Eclipse 3、数据库存储&#xff1a…

站大爷代理IP工具的导入功能介绍

在数字化时代&#xff0c;代理IP成为了网络爬虫、数据挖掘等网络活动中不可或缺的工具。站大爷代理IP工具深刻理解用户的需求&#xff0c;提供了多种代理IP导入方式&#xff0c;让代理IP的管理变得简单高效。下面就来详细了解一下这些便捷的导入方法&#xff1a; 一、站大爷AP…

CSP-J2023T4 旅游巴士(同余最短路)

题目链接&#xff1a;https://www.luogu.com.cn/problem/P9751 题意&#xff1a;给定 n 个点&#xff0c; m 条单向边&#xff0c;一个时间间隔 k 。有这样一些限制条件&#xff1a; 1&#xff09;1号点是入口&#xff0c; n 号点是出口&#xff1b; 2&#xff09;经过一条边…

React系列教程(2)React哲学

豆约翰习惯将掌握某一技术分为5个层次&#xff1a;初窥门径&#xff0c;小试牛刀&#xff0c;渐入佳境&#xff0c;得心应手&#xff0c;玩转自如 本篇属于React框架中的第1层次即初窥门径 我们认为&#xff0c;React 是用 JavaScript 构建快速响应的大型 Web 应用程序的首选方…

「Mac畅玩鸿蒙与硬件29」UI互动应用篇6 - 多选问卷小应用

本篇将带你实现一个多选问卷小应用&#xff0c;用户可以勾选选项并点击提交按钮查看选择的结果。通过本教程&#xff0c;你将学习如何使用 Checkbox 组件、动态渲染列表、状态管理及用户交互&#xff0c;构建完整的应用程序。 关键词 UI互动应用Checkbox 组件状态管理动态列表…

【linux 多进程并发】0203 网络资源的多进程处理,子进程完全继承网络套接字,避免“惊群”问题

0203 网络资源的多进程处理 ​专栏内容&#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 一、概…

江协科技STM32学习- P32 MPU6050

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

程序设计方法与实践-时空权衡

什么是时空权衡&#xff1f; 时空权衡是算法设计中的一个众所周知的问题&#xff0c;也就是对算法的空间和时间效率做出权衡&#xff0c;它大概有分两种形式&#xff1a; 对输入的部分数据或者全部数据作预处理&#xff0c;然后对于获得额外信息储存起来&#xff0c;从而加快…

STM32F1学习——TIM

一、STM32中的定时器 在STM32中分为三种定时器&#xff0c;分别是基本定时器&#xff0c;通用定时器和高级定时器&#xff0c;每种定时器都是向下兼容的。 二、定时器详细介绍 a、基本定时器 基本定时器主要由下面与分频器、计数器 和 自动重装寄存器三个组成的时基单元&#…

W5500-EVB-Pico2评估板介绍

目录 1 概述 2 板载资源 2.1 硬件规格 2.2 硬件规格 2.3 工作条件 3 参考资料 3.1 RP2350 数据手册 3.2 W5500 数据手册 3.3 原理图 原理图 & 物料清单 & Gerber 文件 3.3 尺寸图 (单位 : mm) 3.4 参考例程 认证 CE FCC AWS 资质 Microsoft Azure 认证…

FFmpeg 4.3 音视频-多路H265监控录放C++开发十二:在屏幕上显示多路视频播放,可以有不同的分辨率,格式和帧率。

上图是在安防领域的要求&#xff0c;一般都是一个屏幕上有显示多个摄像头捕捉到的画面&#xff0c;这一节&#xff0c;我们是从文件中读取多个文件&#xff0c;显示在屏幕上。

Oracle视频基础1.4.3练习

15个视频 1.4.3 できない dbca删除数据库 id ls cd cd dbs ls ls -l dbca# delete a database 勾选 # chris 勾选手动删除数据库 ls ls -l ls -l cd /u01/oradata ls cd /u01/admin/ ls cd chris/ ls clear 初始化参数文件&#xff0c;admin&#xff0c;数据文件#新版本了…

一个由Deno和React驱动的静态网站生成器

大家好&#xff0c;今天给大家分享一个由 Deno React 驱动的静态网站生成器Pagic。 项目介绍 Pagic 是一个由 Deno React 驱动的静态网站生成器。它配置简单&#xff0c;支持将 md/tsx 文件渲染成静态页面&#xff0c;而且还有大量的官方或第三方主题和插件可供扩展。 核心…

1分钟解决Excel打开CSV文件出现乱码问题

一、编码问题 1、不同编码格式 CSV 文件有多种编码格式&#xff0c;如 UTF - 8、UTF - 16、ANSI 等。如果 CSV 文件是 UTF - 8 编码&#xff0c;而 Excel 默认使用的是 ANSI 编码打开&#xff0c;就可能出现乱码。例如&#xff0c;许多从网络应用程序或非 Windows 系统生成的 …

发布天工AI高级搜索功能,昆仑万维做最懂科研学术的AI搜索

今天&#xff0c;昆仑万维天工AI正式发布最新版本的AI高级搜索功能。 一年时光&#xff0c;栉风沐雨。昆仑万维致力于通过领先的AI技术&#xff0c;为全球用户提供创新的智能搜索和信息处理解决方案。无论是金融、科技领域的专业搜索还是文档分析&#xff0c;「天工AI高级搜索…

mac找到主目录下的文件夹

访达-&#xff08;上方状态栏显示&#xff09;-然后在

安装fpm,解决*.deb=> *.rpm

要从生成 .deb 包转换为 .rpm 包&#xff0c;可以按照以下步骤修改打包脚本 1. 使用 fpm 工具 fpm 是一个强大的跨平台打包工具&#xff0c;可以将 .deb 包重新打包成 .rpm&#xff0c;也可以直接从源文件打包成 .rpm。 安装 fpm sudo apt-get install ruby-dev sudo gem in…

分布式光伏管理办法

随着分布式光伏项目的不断增加&#xff0c;传统的管理方式已经难以满足高效、精准的管理需求。光伏业务管理系统作为一种集信息化、智能化于一体的管理工具&#xff0c;正在逐步成为分布式光伏项目管理的重要支撑。 光伏业务管理系统通过数字化手段实现对光伏业务全流程的精细化…