周赛351(模拟、枚举答案、乘法原理+双指针(隔板问题)、栈的应用)

news2024/11/15 4:46:09

文章目录

  • 周赛351
    • [2748. 美丽下标对的数目](https://leetcode.cn/problems/number-of-beautiful-pairs/)
      • 模拟
      • O(10n)做法
    • [2749. 得到整数零需要执行的最少操作数](https://leetcode.cn/problems/minimum-operations-to-make-the-integer-zero/)
      • 枚举答案
    • [2750. 将数组划分成若干好子数组的方式](https://leetcode.cn/problems/ways-to-split-array-into-good-subarrays/)
      • 乘法原理 + 同向双指针(转换题意)
      • 隔板问题
    • [2751. 机器人碰撞](https://leetcode.cn/problems/robot-collisions/)
      • 用栈模拟(行星碰撞)

周赛351

2748. 美丽下标对的数目

难度简单0

给你一个下标从 0 开始的整数数组 nums 。如果下标对 ij 满足 0 ≤ i < j < nums.length ,如果 nums[i]第一个数字nums[j]最后一个数字 互质 ,则认为 nums[i]nums[j] 是一组 美丽下标对

返回 nums美丽下标对 的总数目。

对于两个整数 xy ,如果不存在大于 1 的整数可以整除它们,则认为 xy 互质 。换而言之,如果 gcd(x, y) == 1 ,则认为 xy 互质,其中 gcd(x, y)xk 最大公因数

示例 1:

输入:nums = [2,5,1,4]
输出:5
解释:nums 中共有 5 组美丽下标对:
i = 0 和 j = 1 :nums[0] 的第一个数字是 2 ,nums[1] 的最后一个数字是 5 。2 和 5 互质,因此 gcd(2,5) == 1 。
i = 0 和 j = 2 :nums[0] 的第一个数字是 2 ,nums[1] 的最后一个数字是 1 。2 和 5 互质,因此 gcd(2,1) == 1 。
i = 1 和 j = 2 :nums[0] 的第一个数字是 5 ,nums[1] 的最后一个数字是 1 。2 和 5 互质,因此 gcd(5,1) == 1 。
i = 1 和 j = 3 :nums[0] 的第一个数字是 5 ,nums[1] 的最后一个数字是 4 。2 和 5 互质,因此 gcd(5,4) == 1 。
i = 2 和 j = 3 :nums[0] 的第一个数字是 1 ,nums[1] 的最后一个数字是 4 。2 和 5 互质,因此 gcd(1,4) == 1 。
因此,返回 5 。

示例 2:

输入:nums = [11,21,12]
输出:2
解释:共有 2 组美丽下标对:
i = 0 和 j = 1 :nums[0] 的第一个数字是 1 ,nums[1] 的最后一个数字是 1 。gcd(1,1) == 1 。
i = 0 和 j = 2 :nums[0] 的第一个数字是 1 ,nums[1] 的最后一个数字是 2 。gcd(1,2) == 1 。
因此,返回 2 。

提示:

  • 2 <= nums.length <= 100
  • 1 <= nums[i] <= 9999
  • nums[i] % 10 != 0

模拟

class Solution {
    public int countBeautifulPairs(int[] nums) {
        int ans = 0;
        int n = nums.length;
        for(int i = 0; i < n; i++){
            for(int j = i+1; j < n; j++){
                int p = nums[i], q = nums[j];
                while(p >= 10) p /= 10;
                q = q % 10;
                if(gcd(p, q) == 1) ans += 1;
            }
        }
        return ans;
    }

    public int gcd(int x, int y){
        return y == 0 ? x : gcd(y, x % y);
    }
}

O(10n)做法

class Solution {
    // 同两数之和,用哈希表统计前面第一个数字在[0,9]的出现次数
    public int countBeautifulPairs(int[] nums) {
        int[] cnt = new int[10];
        int ans = 0;
        for(int num : nums){
            for(int y = 1; y < 10; y++){
                if(gcd(num % 10, y) == 1) 
                    ans += cnt[y];
            }
            while(num >= 10) num /= 10;
            cnt[num] += 1;
        }
        return ans;
    }

    public int gcd(int x, int y){
        return y == 0 ? x : gcd(y, x % y);
    }
}

2749. 得到整数零需要执行的最少操作数

难度中等4

给你两个整数:num1num2

在一步操作中,你需要从范围 [0, 60] 中选出一个整数 i ,并从 num1 减去 2i + num2

请你计算,要想使 num1 等于 0 需要执行的最少操作数,并以整数形式返回。

如果无法使 num1 等于 0 ,返回 -1

示例 1:

输入:num1 = 3, num2 = -2
输出:3
解释:可以执行下述步骤使 3 等于 0 :
- 选择 i = 2 ,并从 3 减去 22 + (-2) ,num1 = 3 - (4 + (-2)) = 1 。
- 选择 i = 2 ,并从 1 减去 22 + (-2) ,num1 = 1 - (4 + (-2)) = -1 。
- 选择 i = 0 ,并从 -1 减去 20 + (-2) ,num1 = (-1) - (1 + (-2)) = 0 。
可以证明 3 是需要执行的最少操作数。

示例 2:

输入:num1 = 5, num2 = 7
输出:-1
解释:可以证明,执行操作无法使 5 等于 0 。

提示:

  • 1 <= num1 <= 109
  • -109 <= num2 <= 109

枚举答案

题解:https://leetcode.cn/problems/minimum-operations-to-make-the-integer-zero/solution/mei-ju-da-an-pythonjavacgo-by-endlessche-t4co/

class Solution {
    // 从小到大枚举答案
    // 假设操作了k次,那么操作后 num1 变成 num1 - num2*k 再减去 k个2^i
    //          问题变成:num1-num2*k能否拆分成k个2^i之和
    // 设 x = num1 - num2*k
    //      如果 x < 0, 无解
    //      否则如果 x < k, 那么即使每次操作取i = 0, 也至少要把 x 拆分成 k 个 1 之和,这是不可能的
    //      否则如果 x 中二进制 1的个数大于k,也无法拆分成 k 个2^i之和,无解
    //      否则分解方案一定存在,返回k
    public int makeTheIntegerZero(int num1, int num2) {
        for(long k = 1; k <= num1 - num2*k; k++){
            if(k >= Long.bitCount(num1 - num2 * k))
                return (int)k;
        }    
        return -1;
    }
}

为什么x中二进制1的个数小于k的时候就是有解的?

因为每一个 2^i 都可以拆分成 2个 2^(i-1) 的和,相当于1次操作我可以选择性地让其裂变成2次操作,总体操作数的增量是1,这样我始终可以慢慢递增操作数直到达到我想要的k。举个例子二进制数1001,k是3,我就可以把2^3拆成2个2^2,从而使操作数恰好为3。而如果二进制数是11,k是6,这个怎么拆呢?这就属于x < k 的情况,已经在前面排除掉了

2750. 将数组划分成若干好子数组的方式

难度中等0

给你一个二元数组 nums

如果数组中的某个子数组 恰好 只存在 个值为 1 的元素,则认为该子数组是一个 好子数组

请你统计将数组 nums 划分成若干 好子数组 的方法数,并以整数形式返回。由于数字可能很大,返回其对 109 + 7 取余 之后的结果。

子数组是数组中的一个连续 非空 元素序列。

示例 1:

输入:nums = [0,1,0,0,1]
输出:3
解释:存在 3 种可以将 nums 划分成若干好子数组的方式:
- [0,1] [0,0,1]
- [0,1,0] [0,1]
- [0,1,0,0] [1]

示例 2:

输入:nums = [0,1,0]
输出:1
解释:存在 1 种可以将 nums 划分成若干好子数组的方式:
- [0,1,0]

提示:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] <= 1

乘法原理 + 同向双指针(转换题意)

class Solution {
    // 两个相邻的1之间只有 0个数+1 中分割方法
    // 乘法原理 + 同向双指针,双指针找到每一个相邻1之间有多少个0
    private static final int MOD = (int)1e9+7;
    public int numberOfGoodSubarraySplits(int[] nums) {
        double ans = 1.0;
        int left = 0, n = nums.length;
        while(left < n && nums[left] == 0) left++; // 找到第一个1
        if(left == n) return 0;
        int right = left + 1;
        while(right < n){
            while(right < n && nums[right] == 0)
                right++;
            // 此时 left 和 right 都指向1
            if(right != n){
                ans = (ans * (right - left)) % MOD;
                left = right;
                right += 1;
            }
        }
        return (int)ans;
    }
}

另外一种写法

class Solution {
    public int numberOfGoodSubarraySplits(int[] nums) {
        final long MOD = (long) 1e9 + 7;
        long ans = 1;
        int pre = -1, n = nums.length;
        for (int i = 0; i < n; i++) {
            if (nums[i] == 0) continue;
            if (pre >= 0) ans = ans * (i - pre) % MOD;
            pre = i;
        }
        return pre < 0 ? 0 : (int) ans;
    }
}

隔板问题

数学题,任意两个1之间0的数目乘积就是答案,本质上是枚举两个子数组的边界自由度,“2147题分隔长廊的方案数”和这个题一样。

这是个典型的隔板问题,分割子数组相当于在相邻两个1之间的位置放入隔板,问有几种放法

显然总数等于sum(Π(a_{i+1} - a{i}))

class Solution:
    def numberOfGoodSubarraySplits(self, nums: List[int]) -> int:
        mod = 10 ** 9 + 7
        pos = []
        for i, v in enumerate(nums):
            if v:
                pos.append(i)
        if len(pos) == 0: return 0
        ans = 1
        for i in range(1, len(pos)):
            cnt = pos[i] - pos[i-1]
            ans = ans * cnt % mod
        return ans

2751. 机器人碰撞

难度困难0

现有 n 个机器人,编号从 1 开始,每个机器人包含在路线上的位置、健康度和移动方向。

给你下标从 0 开始的两个整数数组 positionshealths 和一个字符串 directionsdirections[i]‘L’ 表示 向左‘R’ 表示 向右)。 positions 中的所有整数 互不相同

所有机器人以 相同速度 同时 沿给定方向在路线上移动。如果两个机器人移动到相同位置,则会发生 碰撞

如果两个机器人发生碰撞,则将 健康度较低 的机器人从路线中 移除 ,并且另一个机器人的健康度 减少 1 。幸存下来的机器人将会继续沿着与之前 相同 的方向前进。如果两个机器人的健康度相同,则将二者都从路线中移除。

请你确定全部碰撞后幸存下的所有机器人的 健康度 ,并按照原来机器人编号的顺序排列。即机器人 1 (如果幸存)的最终健康度,机器人 2 (如果幸存)的最终健康度等。 如果不存在幸存的机器人,则返回空数组。

在不再发生任何碰撞后,请你以数组形式,返回所有剩余机器人的健康度(按机器人输入中的编号顺序)。

**注意:**位置 positions 可能是乱序的。

示例 1:

img

输入:positions = [5,4,3,2,1], healths = [2,17,9,15,10], directions = "RRRRR"
输出:[2,17,9,15,10]
解释:在本例中不存在碰撞,因为所有机器人向同一方向移动。所以,从第一个机器人开始依序返回健康度,[2, 17, 9, 15, 10] 。

示例 2:

img

输入:positions = [3,5,2,6], healths = [10,10,15,12], directions = "RLRL"
输出:[14]
解释:本例中发生 2 次碰撞。首先,机器人 1 和机器人 2 将会碰撞,因为二者健康度相同,二者都将被从路线中移除。接下来,机器人 3 和机器人 4 将会发生碰撞,由于机器人 4 的健康度更小,则它会被移除,而机器人 3 的健康度变为 15 - 1 = 14 。仅剩机器人 3 ,所以返回 [14] 。

示例 3:

img

输入:positions = [1,2,5,6], healths = [10,10,11,11], directions = "RLRL"
输出:[]
解释:机器人 1 和机器人 2 将会碰撞,因为二者健康度相同,二者都将被从路线中移除。机器人 3 和机器人 4 将会碰撞,因为二者健康度相同,二者都将被从路线中移除。所以返回空数组 [] 。

提示:

  • 1 <= positions.length == healths.length == directions.length == n <= 105
  • 1 <= positions[i], healths[i] <= 109
  • directions[i] == 'L'directions[i] == 'R'
  • positions 中的所有值互不相同

用栈模拟(行星碰撞)

同 735. 行星碰撞

class Solution {
    public List<Integer> survivedRobotsHealths(int[] positions, int[] healths, String directions) {
        int n = positions.length;
        int[][] robots = new int[n][4];
        for(int i = 0; i < n; i++){
            robots[i][0] = i;
            robots[i][1] = positions[i];
            robots[i][2] = healths[i];
            robots[i][3] = (directions.charAt(i) == 'L') ? -1 : 1;
        }
        // 按照线路上的位置进行排序
        Arrays.sort(robots, (a, b) -> a[1] - b[1]);
        // 维护一个栈,同 735. 行星碰撞
        Deque<Integer> dq = new ArrayDeque<>();
        for(int i = 0; i < n; i++){
            if(robots[i][3] > 0){ // 往右,直接入栈
                dq.push(i);
            }else{
                boolean alive = true; // 标记当前元素n是否存活
                while(alive && !dq.isEmpty() && robots[dq.peek()][3] > 0){
                    // 如果两个机器人的健康度相同,则将二者都从路线中移除。
                    if(robots[i][2] == robots[dq.peek()][2]){
                        alive = false;
                        dq.poll();
                    // 如果两个机器人发生碰撞,则将 健康度较低 的机器人从路线中 移除 
                    //      并且另一个机器人的健康度 减少 1 
                    }else if(robots[i][2] > robots[dq.peek()][2]){
                        dq.poll();
                        robots[i][2] -= 1;
                    }else{
                        alive = false;
                        robots[dq.peek()][2] -= 1;
                    }
                }
                if(alive) dq.push(i);
            }
        }
        // 栈中的机器人都是存活的,将其按照编号顺序排序,然后将健康值放入答案中
        List<int[]> list = new ArrayList<>();
        while(!dq.isEmpty()){
            list.add(robots[dq.poll()]);
        } 
        Collections.sort(list, (a, b) -> a[0] - b[0]);
        List<Integer> ans = new ArrayList<>();
        for(int i = 0; i < list.size(); i++){
            ans.add(list.get(i)[2]);
        }
        return ans;
    }
}

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

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

相关文章

ElementUI Table 表格动态添加行和列

一、效果 懒得发什么动态图&#xff0c;直接静态就好了。 二、代码 本文参考代码&#xff1a;https://blog.csdn.net/qq_33791597/article/details/125605873 有需求的可以去看下原文&#xff0c;我是参考后又改造了一番 <template> <div style"padding:10px&q…

磁盘 - 内存 - 中央处理器缓存 / 用户缓存区 - 内核缓存区 / 零拷贝

文章目录 磁盘 - 内存 - 中央处理器缓存用户缓存区 - 内核缓存区零拷贝意义 这些概念比较常用&#xff0c;涉及到物理设备 - 操作系统概念&#xff0c;操作系统概念 - 数据结构的区分。记录一下以供后人取笑。 磁盘 - 内存 - 中央处理器缓存 这些是计算机中比较常用的物理设备…

stable-diffusion-webui 安装问题记录

安装完成后&#xff0c;浏览器打开&#xff1a;http://127.0.0.1:7860/&#xff0c;无论点哪里&#xff0c;只要触发交互&#xff0c;都提示&#xff1a; 解决办法&#xff1a; 1、关闭&#xff08;墙外魔法工具&#xff09;软件&#xff08;不一定有效&#xff09; 2、需要不…

将 Layui 日历框,一周开始由星期日改为星期一

Layui 的日历框控件中&#xff0c;一周的开始是星期日。 但是我更习惯一周开始为星期一。在 ISO8601:2000 中&#xff0c;其中也是规定了&#xff1a;每个日历星期从星期一开始&#xff0c;星期日为第 7 天。 所以改一下。 改 layui.all.js 或 laydate.js&#xff08;取决于…

今日分享:如何文本转语音

嘿&#xff0c;各位小伙伴们&#xff01;你们有没有遇到过想看文章但是又赶时间的情况呢&#xff1f;这时候&#xff0c;文本转语音工具就可以帮助你啦&#xff01;通过使用文本转语音工具&#xff0c;你就可以实现听取文章内容而不必亲自看它们了&#xff0c;真是省时又省力。…

node对应的npm版本

官网地址&#xff1a;node对应的npm版本地址

HTML5+CSS3+JS小实例:Tab选项卡动画切换效果

实例:Tab选项卡动画切换效果 技术栈:HTML+CSS+JS 字体图标库:font-awesome 效果: 源码: 【html】 <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name=&q…

eclipse中maven项目pom.xml文件报错:Missing artifact com.sun:tools:jar:1.8.0解决

背景&#xff1a;在引入新的jar包后&#xff0c;突然pom.xml文件就飘红了&#xff0c;提示Missing artifact xxx 原因&#xff1a;新导入的jar包依赖别的jar包&#xff0c;别的jar包因为比较旧&#xff0c;缺失相关文件 处理&#xff1a; 1、找到本地的repository地址&#…

openlayers:圆孔相机根据卫星经度、纬度、高度、半径比例推算绘制地面的拍摄的区域

本示例的目的是介绍演示如何在vue+openlayers中模拟圆孔相机的拍摄场景,根据卫星经度、纬度、高度、半径比例推算绘制地面的拍摄的区域。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果OpenStreetMap无法加载,请加载其他来练习 文章目录 示…

[算法前沿]--021-baichuan-7B的测试教程

1.百川模型介绍 baichuan-7B不仅在C-Eval、AGIEval和Gaokao中文权威评测榜单上,以显著优势全面超过了ChatGLM-6B等其他大模型,并且在MMLU英文权威评测榜单上,大幅领先LLaMA-7B。baichuan-7B是由百川智能开发的一个开源的大规模预训练模型。基于Transformer结构,在大约1.2万…

推或拉? rabbitMQ 消费模式该如何选择

系列文章目录 消息队列选型——为什么选择RabbitMQ RabbitMQ 五种消息模型 RabbitMQ 能保证消息可靠性吗 文章目录 系列文章目录前言一、推拉两种模式的概念二、推模式的使用及优势1. 使用2. 优劣 三、拉模式的使用及优势1. 使用2. 优劣 四、消费端Ack模式与Qos1. Ack模式2. Q…

Linux——1初识linux

目录 1.1 硬件和软件 1.2 初识Linux 1.2.1 Linux的诞生 1.2.2 LInux内核 1.2.3 Linux发行版 1.3 虚拟机介绍 1.4 VMware WorkStation 安装 1.5 在VMware上安装Linux 1.6 远程连接Linux系统 1.6.1 图形化、命令行 1.6.2 FinalShell 1.1 硬件和软件 我们所熟知的计算…

6.S081——设备中断与驱动部分(串口驱动与Console)——xv6源码完全解析系列(8)

0.briefly speaking 点此返回上一篇博客 上一篇博客中我们简单介绍了UART和PLIC的初始化过程&#xff0c;并迭代式的分析了console的读写操作&#xff0c;这篇博客接着上一篇的话题&#xff0c;研究一下一个字符是怎么一步步被显示到我们的屏幕上的&#xff0c;经过了哪些设备…

PyCharm 2021.1.1 x64的安装 和环境搭建

环境变量 D:\Python38 path 免安装

【id:80】【20分】B. 复数的加减乘运算(运算符重载)

题目描述 定义一个复数类&#xff0c;通过重载运算符&#xff1a;、-、*&#xff0c;实现两个复数之间的各种运算。 class Complex { private:float real, image; public:Complex(float x 0, float y 0);friend Complex operator(Complex&, Complex&);friend Comple…

python中使用OAK-D PRO相机实现OCR功能

目录 OAK简介Tesseract简介Tesseract OCR安装包安装 Tesseract OCR 代码实现 OAK简介 OAK&#xff08;OpenCV AI Kit&#xff09;是一个开源的智能视觉平台&#xff0c;它集成了硬件和软件组件&#xff0c;旨在提供高性能的实时目标检测、识别和跟踪等视觉AI功能。OAK由Luxoni…

【夜深人静学JAVA | 第二十三篇】集合体系结构

目录 前言&#xff1a; 单列集合&#xff1a; set与list的区别&#xff1a; 双列集合&#xff1a; map的特点&#xff1a; 总结&#xff1a; 前言&#xff1a; JAVA中为我们提供了很多集合&#xff0c;这些集合都有自己很独特的特点&#xff0c;因此我们要学习所有的…

【Nginx】第五章 Nginx配置实例-负载均衡

5.1 实现效果 浏览器地址栏输入地址 http://192.168.6.100/edu/index.html&#xff0c;负载均衡效果&#xff0c;将请求平均分配到8080和8081两台服务器上。 5.2 准备工作 &#xff08;1&#xff09;准备两台tomcat服务器&#xff0c;一台8080&#xff0c;一台8081 &#x…

数据结构C语言版本(上)

第一章 绪论 第一节 什么是数据结构&#xff1f; 估猜以下软件的共性&#xff1a;学生信息管理、图书信息管理、人事档案管理。   数学模型&#xff1a;用符号、表达式组成的数学结构&#xff0c;其表达的内容与所研究对象的行为、特性基本一致。 信息模型&#xff1a;信息…

FANUC机器人SRVO-220 SDI保险丝熔断报警处理方法

FANUC机器人SRVO-220 SDI保险丝熔断报警处理方法 一般在R-30iB Mate Plus柜的机器人上会遇到这个报警&#xff0c;R-30iB Plus柜则不会遇到这个报警。 如下图所示&#xff0c; 故障原因&#xff1a; 机器人EE接口的接线有短路的情况&#xff0c;检查EE接口的接线&#xff0…