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.执行结果

相关推荐
小王子0091 小时前
链式前向星(最通俗易懂的讲解)
算法
通信仿真实验室1 小时前
(13)MATLAB莱斯(Rician)衰落信道仿真3
开发语言·人工智能·算法·matlab
Tisfy2 小时前
LeetCode 0983.最低票价:记忆化搜索
算法·leetcode·题解·记忆化搜索·哈希表
丁丁Tinsley11172 小时前
数据结构——顺序表(基础代码题)
c语言·数据结构·算法
xiao_fwuu2 小时前
LeetCode 918. 环形子数组的最大和
算法·leetcode·职场和发展
2401_857297913 小时前
秋招内推--招联金融2025
java·前端·算法·金融·求职招聘
闲人编程3 小时前
使用Python实现图形学的阴影贴图算法
python·算法·图形学·贴图·阴影贴图
MarisTang3 小时前
Go语言实现随机森林 (Random Forest)算法
算法·随机森林·golang
育种数据分析之放飞自我4 小时前
GWAS分析中显著位点如何注释基因:excel???
linux·算法·excel
碧海蓝天20225 小时前
C++ 线性表、内存操作、 迭代器,数据与算法分离。
开发语言·数据结构·c++·算法