【每日一题】1498. 满足条件的子序列数目

1498. 满足条件的子序列数目 - 力扣(LeetCode)

给你一个整数数组 nums 和一个整数 target 。

请你统计并返回 nums 中能满足其最小元素与最大元素的  小于或等于 target 的 非空 子序列的数目。

由于答案可能很大,请将结果对 109 + 7 取余后返回。

示例 1:

输入:nums = [3,5,6,7], target = 9
输出:4
解释:有 4 个子序列满足该条件。
[3] -> 最小元素 + 最大元素 <= target (3 + 3 <= 9)
[3,5] -> (3 + 5 <= 9)
[3,5,6] -> (3 + 6 <= 9)
[3,6] -> (3 + 6 <= 9)

示例 2:

输入:nums = [3,3,6,8], target = 10
输出:6
解释:有 6 个子序列满足该条件。(nums 中可以有重复数字)
[3] , [3] , [3,3], [3,6] , [3,6] , [3,3,6]

示例 3:

输入:nums = [2,3,3,4,6,7], target = 12
输出:61
解释:共有 63 个非空子序列,其中 2 个不满足条件([6,7], [7])
有效序列总数为(63 - 2 = 61)

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 106
  • 1 <= target <= 106
class Solution {int mod = (int)1e9 + 7;public int numSubseq(int[] nums, int target) {Arrays.sort(nums);int len = nums.length;int low = 0;int high = len - 1;long sum = 0;int prel = high;int preh = 0;int flag = 0;int[] pow = new int[len+1];pow[0] = 1;for (int i = 1; i <= len; i++) {pow[i] = pow[i - 1] * 2 % mod;}while(prel!=low||preh!=high) {int left = low;int right = high;prel = low;preh = high;while(left < right) {int mid = (left+right) / 2;if(nums[prel]+nums[mid] > target) right = mid;else left = mid+1;}//这里出来之后,left是满足的条件的后一项。if(nums[prel]+nums[left] > target ) right = left - 1; //right这时就是目标下标。int fps;if(right < prel) {break;}else fps = right;high = fps;left = prel;while(left < right) {int mid = (left+right) / 2;if(nums[fps]+nums[mid] > target) right = mid;else  left = mid+1;}//这里出来后,left是第一次区间内不满足条件的后一项low = left;if(nums[fps]+nums[left] > target)  left -= 1; int sps;sps = fps-left;left += 1;fps=fps-prel+1;      if(prel!=low||preh!=high||flag==0){long tmp = pow[fps]-pow[sps];if(pow[fps]-pow[sps] < 0) tmp = pow[fps]-pow[sps]+mod; sum = (sum+tmp)%mod;// System.out.println("fps:"+fps);// System.out.println("sps:"+sps);// System.out.println("每次tmp1结果:"+tmp1);// //System.out.println("每次tmp2结果:"+tmp2);// System.out.println("每次sum结果:"+sum);// System.out.println("------------------");}flag++;} return (int)sum;}
}

         每日一题,今天是中等题。虽然是中等题,但是使用到了多种知识,难度估计能比肩困难题了。

        读题。首先要了解子序列的概念!子序列的定义:子序列就是在原来序列中找出一部分组成的序列(子序列不一定连续)。也就是说,子序列对顺序没有要求,本质是求组合数。而对于序列的排列求法,有公式:2的个数次方,减一是不包含空集,不减一是包含空集。所以,求子序列的个数实际上可以转化为求集合个数,由集合个数再去处理。而题目要求的只有集合内最大数和最小数的和小于target即可。所以,我们可以将数组排序,接下来就是找个数的问题,看一眼数量,就知道不可能使用O(n)的方法处理了。所以自然就想到二分

        抛去循环,我们先来看看一次的过程。由于已经排完序了,所以要找最大值和最小值的和小于target,实际上的最小值就是下标为0的数值了,所以实际上是不用改变的。要找的只有右边的最大值的地方。所以我们可以写一个二分。二分的写法有很多,但是大家要注意处理好边界的问题。博主这里使用的是我最常用的写left在所求值后一个的位置。(这种方法要处理的边界一般在于两侧。)至于后面用于循环的prel暂且可以先当成0(下标)。所以,出第一个二分循环之后的left,实际上会是目标值的前一个,但有可能left在len-1的位置,这个位置就需要边界处理。有可能是最后一个不符合,也可能都符合,所以需要多处理一个判断。这里使用fps(first position)来存储第一个循环的位置,这个位置代表了,从当前最小值开始所能组成的符合要求的最多元素的集合。即【0,left】是目前符合要求的。

        不一定这个集合里所有的数都可以,比如【0,5,8,12,16】taget是12,实际上对于0到12的集合是可以处理的,但5到12的集合是不可以的,所以第二个循环就用来处理实际循环内不符合要求的返回,也就是【5,12】这个位置,例子中12这个位置会在第一次的fps的位置就找到,第二次找到的位置也需要存储。博主这里采用的是存储个数,所以第一个fps不需要处理。而第二个sps【second position】就需要使用fps-left的位置。那么这时候符合要求的集合个数实际上就知道了,是pow(2,fps)-pow(2,sps)。因为两边都会计算空集,所以相减完就可以相互抵消,不需要做多余的处理。那第一次循环的处理就完了,接下来是多次的循环。

        在首次循环中不符合条件的集合中也有可能出现符合条件的集合,如【0,5,6,8,12,16】 target为12。在这个集合中,第一次找到的仍然是【0,12】的集合,但实际上【5,6】的集合也是符合条件的,也可以找到相应的子序列。所以一次显然是不够的。那有循环就需要循环终止的条件,用什么来做循环终止的条件呢?就是两次找到的集合边界都一样的时候。这时候就说明,这个集合里不存在符合条件的子集了。所以,需要prel(prelow)和preh(prehigh)来记录一下边界。而且需要一个flag来记录循环了。这涉及到了对最终数据的处理。如果循环的边界和前一次相同就不需要在继续循环了。但一开始的边界是会相同的,所以一开始需要使用flag来让第一次的结果可以计入sum。而后续flag就不需要了。判断边界是否相同即可。不同则可以计入sum。相同就不需要计入。这里还需要对fps的位置做一次判断,如果fps的位置<0,那么说明这个集合里没有子集是符合条件的。(在这之前会对fps的位置(实际上是right)做一个判断)

        处理完循环。就到了处理最终数据的处理了。这会涉及到大数处理和前缀和的知识。

由于数值过大,基本上确定会超过int的计数范围,所以需要开long,而且在计算过程中就需要对其进行处理。使用一个数组来存储各个pow(2,n)的数值,并且在数值过程中对其进行mod运算(这个会对我们后续处理有点影响)。这个会使用到前缀和的知识,开一个len+1的数组,给pow[0]赋值1也就是2的0次方,之后对每个位置的值乘2处理,并乘2过程中进行mod处理。这样在最后求职时就可以常数时间拿到数值。

        这里就要填坑了,由于过程中mod的处理,所以有可能出现2的高次方减去2的低次方出现负数的情况,这种情况我们需要一点数学知识,如果高次方模完减低次方出现了负数,就需要加上一个mod(模数),这样才能得到正确答案。

        最后,运行,通过。

     最后,祝大家国庆快乐呀!!!!! 

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

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

相关文章

stm32无人机-飞行力学原理

惯性导航&#xff0c;是一种无源导航&#xff0c;不需要向外部辐射或接收信号源&#xff0c;就能自主进行确定自己在什么地方的一种导航方法。 惯性导航主要由惯性器件计算实现&#xff0c;惯性器件包括陀螺仪和加速度计。一般来说&#xff0c;惯性器件与导航物体固连&#xf…

CTFSHOW SSTI

目录 web361 【无过滤】 subprocess.Popen os._wrap_close url_for lipsum cycler web362 【过滤数字】 第一个通过 计算长度来实现 第二个使用脚本输出另一个数字来绕过 使用没有数字的payload web363 【过滤引号】 使用getitem 自定义变量 web364 【过…

数据集笔记:OpenCelliD(手机基站开放数据库)

下载数据的方式可见&#xff1a;【数据获取】全球最大手机基站开源数据库 1 读取数据 import pandas as pdpd.read_csv(C:/Users/16000/Downloads/454.csv/454.csv,headerNone,names[Radio,MCC,MNC,LAC/TAC/NID,CID,Longitude,Latitude,Range,Samples,Changeable1,Changeable…

设计模式6、适配器模式 Adapter

解释说明&#xff1a;将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作 目标接口&#xff08;Target&#xff09;&#xff1a;当前系统所期待的接口&#xff0c;它可以是抽象类或接口 适配者&#xff08;Adaptee&#xff09;&#xff1a…

AIGC(生成式AI)试用 7 -- 桌面小程序

生成式AI&#xff0c;别人用来写作&#xff0c;我先用来写个桌面小程序。 桌面小程序&#xff1a;计算器 需求 Python开发图形界面&#xff0c;标题&#xff1a;计算器 - * / 基本运算计算范围&#xff1a;-999999999 ~ 999999999** 乘方计算&#xff08;例&#xff0c;2*…

LLM之Colossal-LLaMA-2:Colossal-LLaMA-2的简介、安装、使用方法之详细攻略

LLM之Colossal-LLaMA-2&#xff1a;Colossal-LLaMA-2的简介、安装、使用方法之详细攻略 导读&#xff1a;2023年9月25日&#xff0c;Colossal-AI团队推出了开源模型Colossal-LLaMA-2-7B-base。Colossal-LLaMA-2项目的技术细节&#xff0c;主要核心要点总结如下: >> 数据处…

分布式事务-TCC异常-幂等性

1、幂等性问题&#xff1a; 二阶段提交时&#xff0c;如果二阶段执行成功通知TC时出现网路或其他问题中断&#xff0c;那么TC没有收到执行成功的通知&#xff0c;TC内部有定时器不断的重试二阶段方法&#xff0c;导致接口出现幂等性问题。 2、解决方法 和空回滚问题一样也是…

Kotlin只截取Float小数点后数值DecimalFormat

Kotlin只截取Float小数点后数值DecimalFormat import java.text.DecimalFormatfun main(args: Array<String>) {val pi 3.141516Fvar p pi - pi.toInt()println(p)val decimalFormat DecimalFormat("00.0000")val format decimalFormat.format(p)println(…

UE5屏幕适配

一、本程序设计发布在手机上&#xff0c;首先确定屏幕的设计分辨率&#xff0c;这里我们选择iphone6s&#xff0c;750x1334。 二、设置DPI Scale为1.0的比例&#xff0c;点击齿轮标志 因为我们这个程序是手机竖屏使用的&#xff0c;所以DPI Scale Rule选择Shortest Side&#…

c语言常用语法,长时间不用容易忘。

关键字 auto 声明自动变量const 定义常量&#xff0c;如果一个变量被 const 修饰&#xff0c;那么它的值就不能再被改变extern 声明变量或函数是在其它文件或本文件的其他位置定义register 声明寄存器变量signed 声明有符号类型变量或函数static 声明静态变量&#xff0c;修饰…

APA技术架构与说明

1.自动泊车的硬件架构 2.APA自动泊车辅助系统 1&#xff09;APA主要包括以下典型功能 &#xff08;1&#xff09;泊车入库&#xff1a;利用超声波雷达或环视摄像头实现车位识别&#xff0c;并计算出合适行驶轨迹&#xff0c;对车辆进行横向/纵向控制使车辆驶入车位&#xff1…

在MyBatisPlus中添加分页插件

开发过程中&#xff0c;数据量大的时候&#xff0c;查询效率会有所下降&#xff0c;这时&#xff0c;我们往往会使用分页。 具体操作入下&#xff1a; 1、添加分页插件&#xff1a; package com.zhang.config;import com.baomidou.mybatisplus.extension.plugins.Pagination…

基于微信小程序的停车场预约收费小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

CCF CSP认证历年题目自练 Day15

CCF CSP认证历年题目自练 Day15 题目一 试题编号&#xff1a; 201709-1 试题名称&#xff1a; 打酱油 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 256.0MB 问题描述&#xff1a; 问题描述   小明带着N元钱去买酱油。酱油10块钱一瓶&#xff0c;商家进行促销&#xf…

【运维日常】华为云专线实现idc通过nat出网

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

04、EL和JSTL核心技术

目录 1 EL表达式&#xff08;熟悉&#xff09; 1.1 基本概念 1.2 主要功能 1.3 访问内置对象的数据 1.3.1访问方式 1.3.2 执行流程 1.4 访问请求参数的数据 1.5 访问Bean对象的属性 1.5.1 访问方式 1.5.2 主要区别 1.6 访问集合中的数据 1.7 常用的内置对象 …

JVM111

JVM1 字节码与多语言混合编程 字节码 我们平时说的java字节码&#xff0c; 指的是用java语言编译成的字节码。准确的说任何能在jvm平台上执行的字节码格式都是一样的。所以应该统称为:jvm字节码。不同的编译器&#xff0c;可以编译出相同的字节码文件&#xff0c;字节码文件…

Spring Security 简单token配置

Spring Security 简单token配置 说明&#xff1a;非表单配置 先上码&#xff1a; https://gitee.com/qkzztx_admin/security-demo/tree/master/demo-two 环境&#xff1a;win10 idea2023 springboot2.7.6 maven3.8.6 代码清单说明 依赖&#xff1a; <dependency><…

通过茶叶酒水小程序商城的作用是什么?

茶叶酒水往往会在一起经营&#xff0c;同时又具备较强的送礼属性&#xff0c;需求度较高但经营商家同样不少&#xff0c;同行竞争激烈&#xff0c;加之同城生意有限、外地客户难以拓展、销售营销不足、品牌宣传效果差等痛点&#xff0c;传统酒水茶叶门店需要线上带来增长。 那…

VBA技术资料MF61:按每行指定字符数自动换行

【分享成果&#xff0c;随喜正能量】人生的旅途&#xff0c;一时的失意&#xff0c;一时的挫折&#xff0c;跌了一跤&#xff0c;不是人生的全部&#xff0c;只是人生的一个逗点&#xff0c;未来的成就、光辉&#xff0c;还有很多的虚线有待你继续去完成。。 我给VBA的定义&am…