Leetcode 第 408 场周赛题解

news2024/9/30 13:25:03

Leetcode 第 408 场周赛题解

  • Leetcode 第 408 场周赛题解
    • 题目1:3232. 判断是否可以赢得数字游戏
      • 思路
      • 代码
      • 复杂度分析
    • 题目2:3233. 统计不是特殊数字的数字数量
      • 思路
      • 代码
      • 复杂度分析
    • 题目3:3234. 统计 1 显著的字符串的数量
      • 思路
      • 代码
      • 复杂度分析
    • 题目4:3235. 判断矩形的两个角落是否可达
      • 思路
      • 代码
      • 复杂度分析

Leetcode 第 408 场周赛题解

题目1:3232. 判断是否可以赢得数字游戏

思路

用一个 sum1 统计个位数的和,sum2 统计十位数的和。

只要 sum1 和 sum2 不相等,Alice 拿大的就能赢得这场游戏。

代码

/*
 * @lc app=leetcode.cn id=3232 lang=cpp
 *
 * [3232] 判断是否可以赢得数字游戏
 */

// @lc code=start
class Solution
{
public:
    bool canAliceWin(vector<int> &nums)
    {
        int sum1 = 0, sum2 = 0;
        for (int &num : nums)
        {
            if (num / 10)
                sum2 += num;
            else
                sum1 += num;
        }
        return sum1 != sum2;
    }
};
// @lc code=end

复杂度分析

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

空间复杂度:O(1)。

题目2:3233. 统计不是特殊数字的数字数量

思路

埃式筛 + 计数

正难则反,统计区间 [l,r] 内有多少个特殊数字。

这等价于区间 [0, r] 内的特殊数字个数,减去区间 [0, l−1] 内的特殊数字个数。

代码

/*
 * @lc app=leetcode.cn id=3233 lang=cpp
 *
 * [3233] 统计不是特殊数字的数字数量
 */

// @lc code=start
const int MX = 31622; // floor(sqrt(10^9))
bool inited = false;
vector<int> pi(MX + 5, 0);

// 埃氏筛 O(Mlog(logM))
void init()
{
    if (inited)
        return;
    for (int i = 2; i <= MX; i++)
    {
        if (pi[i] == 0)
        { // i 没有被标记,i 是质数
            pi[i] = pi[i - 1] + 1;
            for (int j = i * i; j <= MX; j += i)
            { // 标记 i 的倍数为合数
                pi[j] = -1;
            }
        }
        else
        {
            pi[i] = pi[i - 1];
        }
    }
    inited = true;
}

class Solution
{
public:
    int nonSpecialCount(int l, int r)
    {
        init();
        return r - l + 1 - (pi[(int)sqrt(r)] - pi[(int)sqrt(l - 1)]);
    }
};

// @lc code=end

复杂度分析

时间复杂度:O(1)。不计入预处理的时间。

空间复杂度:O(1)。不计入预处理的空间。

题目3:3234. 统计 1 显著的字符串的数量

思路

注意到,如果子串中的 0 非常多,多到 0 的个数的平方比 1 的个数都要大,那么这样的子串必然不是 1 显著子串。

设 cnt0 为子串中的 0 的个数,cnt1 为子串中的 1 的个数,那么必须满足:cnt0 * cnt0 <= cnt1 <= n,所以子串中的 0 的个数不会超过 sqrt(n)。

在这里插入图片描述

代码

/*
 * @lc app=leetcode.cn id=3234 lang=cpp
 *
 * [3234] 统计 1 显著的字符串的数量
 */

// @lc code=start
class Solution
{
public:
    int numberOfSubstrings(string s)
    {
        int n = s.length();
        vector<int> a;
        for (int i = 0; i < n; i++)
            if (s[i] == '0')
                a.push_back(i);

        int tot1 = n - a.size();
        a.push_back(n); // 哨兵

        int ans = 0, i = 0; // >= left 的第一个 0 的下标是 a[i]

        // 枚举子串左端点
        for (int left = 0; left < n; left++)
        { // 枚举子串有多少个 0
            // 枚举 0 的下标
            for (int k = i; k < a.size() - 1; k++)
            {
                int cnt0 = k - i + 1;
                if (cnt0 * cnt0 > tot1)
                    break;
                int p = a[k], q = a[k + 1];
                int cnt1 = a[k] - left - (k - i);
                if (cnt1 >= cnt0 * cnt0)
                {
                    // p, p+1, ..., q-1 都可以作为子串的右端点
                    ans += q - p;
                }
                else
                {
                    // cnt1 的个数少,补充 cnt0 * cnt0 - cnt1 个
                    ans += max(q - p - (cnt0 * cnt0 - cnt1), 0);
                }
            }
            // 没有 0 的情况
            if (s[left] == '0')
            {
                i++; // 这个 0 后面不会再枚举到了
            }
            else
            {
                ans += a[i] - left; // 不含 0 的子串个数
                tot1--;
            }
        }
        return ans;
    }
};
// @lc code=end

复杂度分析

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

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

题目4:3235. 判断矩形的两个角落是否可达

思路

如果从矩形【上边界/左边界】到矩形【右边界/下边界】的路被圆堵死,则无法从矩形左下角移动到矩形右上角。

怎么判断呢?

首先考虑圆心都在矩形内部的情况。如果圆和圆相交或相切,则相当于在两个圆之间架起了一座桥。如果圆和矩形边界相交或相切,则相当于在矩形边界和圆之间架起了一座桥。如果可以从矩形【上边界/左边界】通过桥到达矩形【右边界/下边界】,则说明路被堵死,无法从矩形左下角移动到矩形右上角。

也可以把桥理解成切割线,如果能把从矩形左下角到矩形右上角的路径切断,则无法从矩形左下角移动到矩形右上角。

用图论的术语来说,就是把圆抽象成节点,在相交或相切的节点之间连边,得到一张无向图。如果从与【上边界/左边界】相交的节点出发,DFS 这张图,到达与【右边界/下边界】相交的节点,则说明无法从矩形左下角移动到矩形右上角。

从与矩形【上边界/左边界】相交/相切的圆开始 DFS。

如果当前 DFS 到了圆 i:

先判断其是否与矩形【右边界/下边界】相交或相切,如果是,则 DFS 返回 true。
否则,判断其是否与其他圆 j 相交或相切,如果是,则判断点 A 是否严格在矩形内,如果在,则递归 j,如果收到了 true,则 DFS 返回 true。
最后,如果最外层调用 DFS 的地方收到了 true,则表示无法从矩形左下角移动到矩形右上角,返回 false。

代码实现时,可以在递归之前,特判圆包含矩形左下角或者矩形右上角的情况,此时可以直接返回 false。

代码

/*
 * @lc app=leetcode.cn id=3235 lang=cpp
 *
 * [3235] 判断矩形的两个角落是否可达
 */

// @lc code=start
class Solution
{
    // 判断点 (x, y) 是否在圆 (ox, oy, r) 内
    bool in_circle(long long ox, long long oy, long long r, long long x, long long y)
    {
        return (ox - x) * (ox - x) + (oy - y) * (oy - y) <= r * r;
    }

public:
    bool canReachCorner(int X, int Y, vector<vector<int>> &circles)
    {
        int n = circles.size();
        vector<int> vis(n);
        auto dfs = [&](auto &&dfs, int i) -> bool
        {
            long long x1 = circles[i][0], y1 = circles[i][1], r1 = circles[i][2];
            // 圆 i 是否与矩形右边界/下边界相交相切
            if (y1 <= Y && abs(x1 - X) <= r1 ||
                x1 <= X && y1 <= r1 ||
                x1 > X && in_circle(x1, y1, r1, X, 0))
            {
                return true;
            }
            vis[i] = true;
            for (int j = 0; j < n; j++)
            {
                long long x2 = circles[j][0], y2 = circles[j][1], r2 = circles[j][2];
                // 在两圆相交相切的前提下,点 A 是否严格在矩形内
                if (!vis[j] && (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) <= (r1 + r2) * (r1 + r2) &&
                    x1 * r2 + x2 * r1 < (r1 + r2) * X &&
                    y1 * r2 + y2 * r1 < (r1 + r2) * Y &&
                    dfs(dfs, j))
                {
                    return true;
                }
            }
            return false;
        };
        for (int i = 0; i < n; i++)
        {
            long long x = circles[i][0], y = circles[i][1], r = circles[i][2];
            if (in_circle(x, y, r, 0, 0) || // 圆 i 包含矩形左下角
                in_circle(x, y, r, X, Y) || // 圆 i 包含矩形右上角
                // 圆 i 是否与矩形上边界/左边界相交相切
                !vis[i] && (x <= X && abs(y - Y) <= r || y <= Y && x <= r || y > Y && in_circle(x, y, r, 0, Y)) && dfs(dfs, i))
            {
                return false;
            }
        }
        return true;
    }
};
// @lc code=end

复杂度分析

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

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

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

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

相关文章

Pycharm can‘t open file ‘D:\\Program‘: [Errno 2] No such file or directory

问题描述 Pycharm 使用Python 3.11.9 版本调试代码报错&#xff1a; 解决方案 1、WindowsR&#xff0c;调起CMD&#xff08;PowerShell不行&#xff09;&#xff0c;执行以下指令&#xff1a; mklink /J "D:\PyCharm" "D:\Program Files\JetBrains\PyCharm 2…

react学习之useState和useEffect

useState useState 可以使函数组件像类组件一样拥有 state&#xff0c;函数组件通过 useState 可以让组件重新渲染&#xff0c;更新视图。 实际使用 setstate()中回调函数的返回值将会成为新的state值回调函数执行时&#xff0c; React会将最新的state值作为参数传递 const A…

Vulkan进阶系列1 - Raytracing 光线查询

一:概述 为了提高效率,光线追踪需要将几何体组织成加速结构(AS, 即Acceleration Structure),以减少渲染过程中光线与三角形的相交测试次数。这种层次结构通常在硬件中实现,但只有两个层级对用户可见:一个顶层加速结构(TLAS),它引用任意数量的底层加速结构(BLAS)。通…

Linux进程间的通信(一)exec函数族,getenv获取系统环境变量,system和popen的区别,文件和记录锁定通信

目录 几个系统关键api exec函数族 getenv() system() 文件和记录锁定通信 在Linux/Unix系统中&#xff0c;进程间通信方式&#xff08;Inter-Process Comunication&#xff09;通常有如下若干中方式&#xff1a; 1、文件和记录锁定 2、管道 3、信号 4、system-V 5、PO…

贪心算法三道经典题(买卖股票,分发饼干)

贪心算法 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 步骤&#xff1a; 将问题分解为若干个子问题找出适合的贪心策略求解每一个子问题的最优解将局部最优解堆叠成全局最优解 分发饼干 LeetCode原题 找满足孩子数量的最大值———最优解问题 什么…

数据同步大冒险:PostgreSQL到MySQL的奇妙之旅

引言&#xff1a;一场跨数据库的浪漫邂逅 &#x1f491; 在数据的世界里&#xff0c;不同数据库系统就像是来自不同星球的恋人&#xff0c;它们各自拥有独特的魅力&#xff0c;但偶尔也会渴望一场跨越界限的亲密接触。今天&#xff0c;我们就来见证一场PostgreSQL与MySQL之间的…

初赛试题-2022年CSP-J3

先言 本次试卷 完善程序 三、完善程序&#xff08;每题3分&#xff0c;共30分&#xff09; &#xff08;1&#xff09; 【答案】 A B C D A &#xff08;2&#xff09; 【答案】 A B C D A

探索用于小占用关键词检测的TinyML框架:一个简明概述

目录 摘要 第一部分&#xff1a;引言 第二部分&#xff1a;部署TinyML的常见挑战 第三部分&#xff1a;SF-KWS的不同方法 A. 网络架构&#xff08;Network Architecture&#xff09; B. 学习技术&#xff08;Learning Techniques&#xff09; C. 模型压缩&#xff08;Mo…

最新黑名单查询录入系统PHP网站源码

源码介绍&#xff1a; 最新黑名单查询录入系统PHP网站源码 前端html 后端layui 操作部分都采用API接口的方式实线 集结了layui表格的多数据操作&#xff0c;添加&#xff0c;批量删除&#xff0c;分页&#xff0c;单项删除 后台数据修改采用绑定参数的形式来进行修改可以很…

C语言函数递归(含扫雷进阶思路)

文章目录 一、什么是递归二、递归的使用思路和限制条件1.递归的使用思路2.递归的限制条件 三、递归的举例举例1&#xff1a;求n的阶乘2.举例2&#xff1a;顺序打印⼀个整数的每⼀位 四、递归与迭代对比五、递归与迭代对比举例七、扫雷进阶思路 一、什么是递归 递归是学习C语⾔函…

暄桐教室分享“闲人”指南

一种理想的生活状态&#xff0c;叫“做个闲人”&#xff0c;如苏东坡《行香子述怀》那般&#xff0c;“对一张琴&#xff0c;一壶酒&#xff0c;一溪云”&#xff0c;放下纷扰&#xff0c;好自在。然而&#xff0c;闲并不是简单的无事可做&#xff0c;让自己时光充沛、能量聚集…

MacOS使用FileZilla通过ssh密钥文件连接远程服务器(已解决)

需求描述 mac电脑,使用filezilla通过FTP连接远程服务器,使用ssh密钥文件代替密码。 版本信息 MacOS:Sonoma 14.5 M3芯片 FileZilla:3.66.5 在这里插入图片描述 连接 1. 创建站点 打开filezilla工具,右上角选择“文件 -> 站点管理器”,打开站点管理器弹窗。 2.…

vue 动态替换父组件

替换父组件&#xff1f;&#xff1f; 什么鬼&#xff1f;&#xff1f;&#xff1f; 这个场景的确很少见&#xff01;&#xff01;不过我们要说的的确是要替换父组件&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 就是子组件内容不变但是父组件变…

【HuggingFace Transformers】LlamaDecoderLayer源码解析

LlamaDecoderLayer源码解析 1. LlamaDecoderLayer 介绍2. LlamaDecoderLayer 类源码解析 1. LlamaDecoderLayer 介绍 LlamaDecoderLayer 是 LLaMA 模型中的一个关键组件&#xff0c;它结合了自注意力机制、全连接层和残差连接&#xff0c;以及对输入数据的归一化。主要流程为&…

SpringCloud之一IDEA导入已有微服务项目并启动服务

一|、导入已有微服务项目 启动idea&#xff0c;file --> open&#xff0c;选择项目根目录&#xff1b;点击屏幕右侧maven projects按钮 -->点那个绿&#xff0c;如果屏幕右侧没有maven projects按钮&#xff0c;点击Help->Find Action&#xff0c;输入maven&#xff…

算法-存在重复元素(219)

这道题一眼看过去暴力&#xff0c;两层循环&#xff0c;找到相等的数字&#xff0c;然后判断一下就行&#xff0c;但是这样的话不符合哈希表使用原则。这道题同样利用了hash表键值配对的规则。 class Solution {public boolean containsNearbyDuplicate(int[] nums, int k) {M…

C语言 | Leetcode C语言题解之第382题链表随机节点

题目&#xff1a; 题解&#xff1a; typedef struct {struct ListNode * head; } Solution;Solution* solutionCreate(struct ListNode* head) {Solution * obj (Solution *)malloc(sizeof(Solution));assert(obj ! NULL);obj->head head;return obj; }int solutionGetRa…

keil中内存的存储规律

keil中内存的存储规律 keil中内存的存储规律 文章目录 keil中内存的存储规律keil中内存的存储规律 keil中内存的存储规律 #include <stdlib.h> #include "gd32f30x.h" #include "led_drv.h" #include "delay.h" #include "key_drv.…

GIT 下载安装使用教程

一. GIT下载 git下载地址https://git-scm.com/downloads 二. git安装 1. 许可声明 看完许可声明&#xff0c;点击Next就好了 2. 选择安装路径 默认为C盘&#xff0c;可以修改&#xff0c;这里修改为D盘&#xff0c;点击Next 3. 组件选择 勾选添加在桌面上&#xff0c;就是…