LeetCode430周赛T3

题目描述

给定一个只包含正整数的数组 nums,我们需要找到其中的特殊子序列。特殊子序列是一个长度为4的子序列,用下标 (p, q, r, s) 表示,它们满足以下条件:

  1. 索引顺序p < q < r < s,且相邻坐标之间至少间隔一个数字,即 q - p > 1r - q > 1s - r > 1
  2. 乘积关系nums[p] * nums[r] == nums[q] * nums[s]

子序列指的是从原数组中删除零个或多个元素后,剩下元素不改变顺序组成的序列。

示例 1:

输入:nums = [1,2,3,4,3,6,1]
输出:1
解释:
nums 中只有一个特殊子序列。
(p, q, r, s) = (0, 2, 4, 6) :对应的元素为 (1, 3, 3, 1)。
nums[p] * nums[r] = 1 * 3 = 3
nums[q] * nums[s] = 3 * 1 = 3

示例 2:

输入:nums = [3,4,3,4,3,4,3,4]
输出:3
解释:
nums 中共有三个特殊子序列。
1. (p, q, r, s) = (0, 2, 4, 6) :对应元素为 (3, 3, 3, 3)。nums[p] * nums[r] = 3 * 3 = 9nums[q] * nums[s] = 3 * 3 = 9
2. (p, q, r, s) = (1, 3, 5, 7) :对应元素为 (4, 4, 4, 4)。nums[p] * nums[r] = 4 * 4 = 16nums[q] * nums[s] = 4 * 4 = 16
3. (p, q, r, s) = (0, 2, 5, 7) :对应元素为 (3, 3, 4, 4)。nums[p] * nums[r] = 3 * 4 = 12nums[q] * nums[s] = 3 * 4 = 12

提示:

  • 7 <= nums.length <= 1000
  • 1 <= nums[i] <= 1000

解题思路

为了高效地解决这个问题,我们需要利用数学和数据结构的结合。以下是详细的解题步骤:

  1. 问题转换

    题目要求 nums[p] * nums[r] == nums[q] * nums[s],我们用a,b,c,d定义nums[p],nums[q],nums[r],num[s],可以将其转换为分数的形式:
    a b = d c \frac{a}{b} = \frac{d}{c} ba=cd

    这样,a b 都在 cd 的左边,便于使用前缀和后缀的方法进行分解和统计。

  2. 统计后缀中的最简分数

    首先,统计下标 [4, n−1] 中所有满足间隔至少一个数的数对 (c, d) 的最简分数,并记录到一个哈希表 suf 中。最简分数是指分子和分母互质的分数。如果分子和分母不互质,可以通过它们的最大公约数(GCD)进行约简。例如,分数 4/6 的最简分数是 2/3

  3. 枚举并统计前缀中的最简分数

    然后,枚举 b 的位置,以及 b 左边满足间隔条件的 a,计算 a/b 的最简分数,并在 suf 中查找相等的最简分数的数量,将其累加到结果中。

  4. 动态更新后缀哈希表

    在从左向右枚举 b 的过程中,动态地维护和更新 suf 中的最简分数的个数,以保证统计的准确性。

代码实现

以下是基于上述思路的C++代码实现:

typedef long long LL;
class Solution {
public:long long numberOfSubsequences(vector<int>& nums) {int n = nums.size();LL res = 0;unordered_map<int,int> mp;// 预先统计所有 (c, d) 的最简分数for(int c = 4; c < n - 2; c ++) {for(int d = c + 2; d < n; d ++) {int gcd_val = __gcd(nums[c], nums[d]);int x = nums[c] / gcd_val;int y = nums[d] / gcd_val;mp[y << 16 | x ] ++;}}// 枚举 b,并统计满足条件的 afor(int b = 2; b <= n - 5; b ++) {for(int a = 0; a <= b - 2; a ++) {int gcd_val = __gcd(nums[a], nums[b]);int x = nums[a] / gcd_val;int y = nums[b] / gcd_val;res += mp[x << 16 | y];}// 更新后缀哈希表,移除已经不满足间隔条件的 (c, d)for(int d = b + 4; d < n; d ++) {int gcd_val = __gcd(nums[b + 2], nums[d]);int x = nums[b + 2] / gcd_val;int y = nums[d] / gcd_val;mp[y << 16 | x] --;}}return res;}
};

代码解析

  1. 哈希表 mp 的使用

    我们使用一个 unordered_map<int, int> 来存储后缀中所有 (c, d) 对应的最简分数。为了高效存储分数,我们将分子和分母合并成一个整数,其中分母占高16位,分子占低16位。

  2. 预处理后缀部分

    在初始阶段,我们遍历数组中满足条件的 (c, d) 对,并将其最简分数存入哈希表 mp

  3. 枚举 b 并统计符合条件的 a

    对于每一个可能的 b,我们枚举所有满足条件的 a,计算其最简分数,并在哈希表 mp 中查找相等的最简分数的数量,将其累加到结果 res 中。

  4. 动态更新哈希表 mp

    随着 b 的增大,一些 (c, d) 对将不再满足间隔条件,需要从哈希表中移除。这通过减小相应分数的计数来实现。

复杂度分析

  • 时间复杂度:O(n²),其中 n 是数组的长度。主要来自于两层嵌套循环,分别用于预处理后缀和枚举 b 以及 a
  • 空间复杂度:O(n²),用于存储哈希表 mp 中可能的所有 (c, d) 对的最简分数。

总结

通过巧妙地将乘积关系转换为分数关系,并利用哈希表高效地统计和查找最简分数,我们成功地将原本可能的四重循环优化为两重循环,大大提升了算法的效率。这种方法不仅适用于本题,也为解决类似的组合类问题提供了有益的思路。

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

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

相关文章

网页的语义结构

1.含义 HTML 标签的一个重要作用&#xff0c;就是声明网页元素的性质&#xff0c;使得用户只看标签&#xff0c;就能了解这个元素的意义&#xff0c;阅读 HTML 源码就能了解网页的大致结构。这被称为 HTML 的语义原则。 下面就是一个典型的语义结构的网页。 <body><…

RabbitMQ基础篇之Java客户端快速入门

文章目录 需求 项目设置与依赖管理 配置RabbitMQ的连接信息创建队列与消息发送创建消费者&#xff08;消息接收&#xff09;环境准备与操作 需求 利用控制台创建队列 simple.queue在 publisher 服务中&#xff0c;利用 SpringAMQP 直接向 simple.queue 发送消息在 consumer 服…

学技术学英文:Tomcat的线程模型调优

导读&#xff1a; tomcat 线程调优关键需要理解下面这几个参数&#xff1a; 1. maxConnections 描述&#xff1a;指定服务器能够同时接受和处理的最大连接数。也就是说&#xff0c;服务器在任何时候都能处理的最大并发连接数。作用&#xff1a;限制服务器在任何给定时间点能…

【微信小程序获取用户手机号

微信小程序获取用户手机号有2种,一种是前端自己解密,一种是获取后发给后端,后端去解密 重点:要在微信公众平台设置里面绑定微信开放平台账号,不然反解不出来用户手机号上代码: <button style"font-size: 16px;" open-type"getPhoneNumber" getphonenumb…

单片机-静动态数码管实验

P0控制数码管 &#xff0c;P0低电平 P1,P2,P3高电平 1、静态数码管 需求&#xff1a;数码管显示0&#xff0c;即让p0端口输出数字0的段码0x3f(共阴) #include "reg52.h" typedef unsigned int u16; typedef unsigned char u8; //数码管显示数字的数组 共阴极 …

创龙3588——debian根文件系统制作

文章目录 build.sh debian 执行流程build.sh源码流程 30-rootfs.sh源码流程 mk-rootfs-bullseys.sh源码流程 mk-sysroot.sh源码流程 mk-image.sh源码流程 post-build.sh 大致流程系统制作步骤 build.sh debian 执行流程 build.sh 源码 run_hooks() {DIR"$1"shiftf…

管理者管理上班摸鱼

管理者管理上班摸鱼的问题,实际上涉及到员工工作态度、时间管理、团队文化等方面。以下是一些有效的管理策略: 明确期望与目标 确保每个员工了解他们的工作职责、目标以及衡量工作表现的标准。明确的期望有助于避免模糊空间,让员工知道自己的任务和责任,不容易找到摸鱼的借…

聆听音乐 1.5.9 | 畅听全网音乐,支持无损音质下载

聆听音乐手机版是面向广大音乐爱好者的移动应用程序&#xff0c;用户可以随时随地通过手机享受丰富的音乐资源。它提供了多种魅力功能&#xff0c;让用户在手机上畅享更舒适的音乐体验&#xff0c;每位用户都能享受精彩纷呈的收听体验。此外&#xff0c;软件还支持无损音质音乐…

day-104 组合总和 Ⅳ

思路 动态规划 解题过程 假设dfs(target)表示组成target的组合数&#xff0c;可得转换方程dfs(target)dfs(target-nums[0])dfs(target-nums[1])…以此类推 注意&#xff1a;nums[i]需要小于等于当前的target Code class Solution {public int combinationSum4(int[] nums, i…

汽车燃油软件标定测试

油箱测试 确定油箱的参数&#xff1a; 总容积&#xff0c;额定容积&#xff0c;不可用容积等。油泵测试&#xff08;静态&#xff09; 分为加油测试&#xff0c;减油测试&#xff0c;1L或者500ml增减&#xff1b; 分别测试油泵的阻值输出&#xff0c;类似&#xff1a; 油量 阻…

MATLAB中binopdf函数用法

目录 语法 说明 示例 计算并绘制二项概率密度函数 binopdf函数的功能是计算二项概率密度函数。 语法 y binopdf(x,n,p) 说明 y binopdf(x,n,p) 使用 n 中对应的试验次数和 p 中每次试验的成功概率&#xff0c;计算 x 中每个值处的二项概率密度函数。 x、n 和 p 可以是…

linux tar 文件解压压缩

文件压缩和解压 tar -c: 建立压缩档案 -x&#xff1a;解压 -t&#xff1a;查看内容 -r&#xff1a;向压缩归档文件末尾追加文件 -u&#xff1a;更新原压缩包中的文件 -z&#xff1a;有gzip属性的 -j&#xff1a;有bz2属性的 -v&#xff1a;显示所有过程 -O&#xff1a;…

Spring Boot日志处理

文章目录 Spring Boot日志处理1. 日志存入数据库&#xff08;AOP&#xff09;2. 日志控制台打印与写入文件&#xff08;logback&#xff09; Spring Boot日志处理 1. 日志存入数据库&#xff08;AOP&#xff09; 引入aop依赖 <dependency><groupId>org.springfram…

vite6+vue3+ts+prettier+eslint9配置前端项目(后台管理系统、移动端H5项目通用配置)

很多小伙伴苦于无法搭建一个规范的前端项目&#xff0c;导致后续开发不规范&#xff0c;今天给大家带来一个基于Vite6TypeScriptVue3ESlint9Prettier的搭建教程。 目录 一、基础配置1、初始化项目2、代码质量风格的统一2.1、配置prettier2.2、配置eslint2.3、配置typescript 3、…

GitHub的简单操作

引言 今天开始就要开始做项目了&#xff0c;上午是要把git搭好。搭的过程中遇到好多好多的问题。下面就说一下git的简单操作流程。我们是使用的GitHub,下面也就以这个为例了 一、GitHub账号的登录注册 https://github.com/ 通过这个网址可以来到GitHub首页 点击中间绿色的S…

详细的一条SQL语句的执行流程

SQL 语句的执行流程会因数据库管理系统的不同而略有差异&#xff0c;但一般来说&#xff0c;主要包括以下几个阶段&#xff1a; 查询解析 词法分析&#xff1a;数据库系统首先将输入的 SQL 语句按字符流进行扫描&#xff0c;依据词法规则把它分割成一个个的单词&#xff0c;如…

基于CentOS的Docker + Nginx + Gitee + Jenkins部署总结

一、部署环境概述 本文阐述在CentOS系统上运用PowerShell命令部署Docker、Nginx、Gitee&#xff08;文中未详细提及Gitee相关配置&#xff0c;可根据实际情况与其他代码托管平台类比&#xff09;和Jenkins&#xff0c;实现前端自动化部署的流程&#xff0c;包含从系统环境准备…

OpenCV调整图像亮度和对比度

【欢迎关注编码小哥&#xff0c;学习更多实用的编程方法和技巧】 1、基本方法---线性变换 // 亮度和对比度调整 cv::Mat adjustBrightnessContrast(const cv::Mat& src, double alpha, int beta) {cv::Mat dst;src.convertTo(dst, -1, alpha, beta);return dst; }// 使用…

《机器学习》——逻辑回归(下采样)

文章目录 什么是下采样&#xff1f;为什么在逻辑回归中要使用下采样&#xff1f;使用下采样和不使用下采样的区别实例1、实例内容2、实例步骤 什么是下采样&#xff1f; 下采样&#xff08;Down - Sampling&#xff09;是一种数据处理技术&#xff0c;主要用于处理数据集中不同…

Python实现接口签名调用

目录: 1、第三方接口签名调用2、调用结果 1、第三方接口签名调用 import json import requests import hashlib import time import hmac access_key xxxxxxxxxxxxxxx secret_key xxxxxxxxxxxxxxx # 应用信息 def _wps4_sig(method, url, date, body): print(body)if bod…