leetcode:1498

问题

满足所给数字和的数字子串:

  • 给你一个整数数组 nums 和一个整数 target 。
  • 请你统计并返回 nums 中能满足其最小元素与最大元素的 和 小于或等于 target 的 非空 子序列的数目。
  • 由于答案可能很大,请将结果对 10^9 + 7 取余后返回。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路
  • 首先肯定对原数组进行排序
  • 当排序后数组的一个子数组 n u m s [ l e f t : r i g h t ] nums[left:right] nums[left:right] 存在 n u m s [ l e f t ] + n u m s [ r i g h t ] < t a r g e t nums[left]+nums[right]<target nums[left]+nums[right]<target , 那么这个数组下的,所有包含 n u m s [ l e f t ] nums[left] nums[left] 的子数组都满足条件,总个数为:
    r e s + = 2 r i g h t − l e f t − 1 res+=2^{right-left-1} res+=2rightleft1
  • left 从 0 开始,right 从len-1 开始
  • n u m s [ l e f t ] + n u m s [ r i g h t ] < = t a r g e t nums[left]+nums[right]<=target nums[left]+nums[right]<=target 时,更新 res。
    • 此时以left为起点的所有满足子数组已经算完,因此:
      l e f t + + left++ left++
  • n u m s [ l e f t ] + n u m s [ r i g h t ] > t a r g e t nums[left]+nums[right]>target nums[left]+nums[right]>target 时,
    • 当前数组中,可能包含存在left的符合条件的子数组(只需要加一个不那么大的数即可)
    • 当前数组中,绝不会存在包含right的符合条件的子数组,因为left已经是最小的了,right没法再加一个更小的。因此,
      r i g h t − − right-- right
class Solution(object):
    def numSubseq(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        x = 1000000007
        max_len = 1000000
        powarr=[1]
        for _ in range(1,max_len):
            powarr.append((powarr[-1]*2%x))        
        nums = sorted(nums)
        # print(nums)
        left = 0
        right = len(nums)-1
        res = 0
        while(left<=right):
            if nums[left]+nums[right]<=target:
                res=(res+ powarr[right-left])%x
                # print(left,right,res)
                left+=1
            else:
                right-=1
        return res
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值