Leetcode 1498. 满足条件的子序列数目

1.题目基本信息

1.1.题目描述

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

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

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

1.2.题目地址

https://leetcode.cn/problems/number-of-subsequences-that-satisfy-the-given-sum-condition/description/

2.解题方法

2.1.解题思路

遍历第一个元素,以第一个元素为锚,二分查找第二个边界条件

2.2.解题步骤

第一步,将数组进行升序排列

第二步,预处理2的n次方的取模值,应用的原理是(ab)%MOD=[(a%MOD)(b%MOD)]%MOD

第三步,遍历第一个值i,通过二分法找到最后一个j使得nums[i]+nums[j]<=target,累加2**(j-i)即为题解(注意取模)

3.解题代码

Python代码

python 复制代码
class Solution:
    # 遍历第一个元素,以第一个元素为锚,二分查找第二个边界条件
    def numSubseq(self, nums: List[int], target: int) -> int:
        length=len(nums)
        # 第一步,将数组进行升序排列
        nums.sort()
        # 第二步,预处理2的n次方的取模值,应用的原理是(a*b)%MOD=[(a%MOD)*(b%MOD)]%MOD
        modVal=10**9 + 7
        power2ModArr=[0]*length
        power2ModArr[0]=1
        for i in range(1,len(power2ModArr)):
            power2ModArr[i]=power2ModArr[i-1]*2%modVal
        # print(power2ModArr)
        # 第三步,遍历第一个值i,通过二分法找到最后一个j使得nums[i]+nums[j]<=target,累加2**(j-i)即为题解(注意取模)
        result=0
        for i in range(length):
            if nums[i]*2>target:
                break
            # 二分找到最后一个j使得nums[i]+nums[j]<=target
            # 红:nums[i]+nums[j]<=target处,蓝:大于target;左闭右闭:left-1始终指向红色,right+1始终指向蓝色。最终的right即为需要找到的j
            left,right=i,length-1
            while left<=right:
                mid=(right-left)//2+left
                if nums[i]+nums[mid]<=target:
                    left=mid+1
                else:
                    right=mid-1
            if right>=i:
                result+=power2ModArr[right-i]
        return result%modVal

C++代码

cpp 复制代码
class Solution {
public:
    int numSubseq(vector<int>& nums, int target) {
        int length=nums.size();
        sort(nums.begin(),nums.end());
        int modVal=1E9+7;
        vector<int> power2ModArr(length,0);
        power2ModArr[0]=1;
        for(int i=1;i<length;++i){
            power2ModArr[i]=power2ModArr[i-1]*2%modVal;
        }
        long long result=0;
        for(int i=0;i<length;++i){
            if(nums[i]*2>target){
                break;
            }
            int left=1,right=length-1;
            while(left<=right){
                int mid=(right-left)/2+left;
                if(nums[i]+nums[mid]<=target){
                    left=mid+1;
                }else{
                    right=mid-1;
                }
            }
            if(right>=i){
                result+=power2ModArr[right-i];
            }
        }
        return result%modVal;
    }
};

4.执行结果

相关推荐
逑之14 分钟前
C语言笔记10:sizeof和strlen,指针与数组
c语言·笔记·算法
求梦82018 分钟前
【力扣hot100题】旋转图像(15)
算法·leetcode·职场和发展
C雨后彩虹5 小时前
任务最优调度
java·数据结构·算法·华为·面试
少林码僧7 小时前
2.31 机器学习神器项目实战:如何在真实项目中应用XGBoost等算法
人工智能·python·算法·机器学习·ai·数据挖掘
钱彬 (Qian Bin)7 小时前
项目实践15—全球证件智能识别系统(切换为Qwen3-VL-8B-Instruct图文多模态大模型)
人工智能·算法·机器学习·多模态·全球证件识别
Niuguangshuo7 小时前
EM算法详解:解密“鸡生蛋“的机器学习困局
算法·机器学习·概率论
a3158238067 小时前
Android 大图显示策略优化显示(一)
android·算法·图片加载·大图片
一条大祥脚8 小时前
26.1.9 轮廓线dp 状压最短路 构造
数据结构·c++·算法
鲨莎分不晴8 小时前
反向传播的数学本质:链式法则与动态规划的完美共舞
算法·动态规划
sonadorje8 小时前
逻辑回归中的条件概率
算法·机器学习·逻辑回归