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次方的取模值,应用的原理是(a*b)%MOD=(a%MOD)*(b%MOD)%MOD

第三步,遍历第一个值i,通过二分法找到最后一个j使得numsi+numsj<=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.执行结果

相关推荐
kkeeper~4 小时前
0基础C语言积跬步之数据在内存中的存储
c语言·数据结构·算法
wabs6665 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
2401_876964135 小时前
【湖北专升本】2026湖北专升本真题PDF+备考资料汇总
数据结构·人工智能·经验分享·深度学习·算法·计算机视觉
嗝o゚6 小时前
CANN GE 算子融合——融合算法与调度策略
算法·昇腾·cann·ge
小江的记录本6 小时前
【JVM虚拟机】垃圾回收GC:垃圾回收算法:标记-清除、标记-复制、标记-整理、分代收集(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·安全·面试
Ulyanov8 小时前
用声明式语法重新定义Python桌面UI:QML+PySide6现代开发入门(一)
开发语言·python·算法·ui·系统仿真·雷达电子对抗仿真
数据科学小丫8 小时前
特征工程处理
人工智能·算法·机器学习
z落落8 小时前
C#参数区别
java·算法·c#
c238569 小时前
vector(下)
数据结构·算法
z落落9 小时前
C# 冒泡排序+选择排序 + Array.Sort 自定义排序
数据结构·算法