以空间换时间的算法

以空间换时间的算法

大多算法考试都会有这个要求,就是在规定的时间复杂度内得到求解,这种情况下,一般多是需要复合遍历的内容,也即是时间复杂度在O(N2)和O(N3)等算法时间较高的情况下,此篇内容就是探讨一下一般的有哪些是以空间换时间的算法
LCP18.早餐组合

小扣在秋日市集选择了一家早餐摊位,一维整型数组 staple 中记录了每种主食的价格,一维整型数组 drinks 中记录了每种饮料的价格。小扣的计划选择一份主食和一款饮料,且花费不超过 x 元。请返回小扣共有多少种购买方案。
(注意:答案需要以 1e9 + 7 (1000000007) 为底取模,如:计算初始结果为:1000000008,请返回 1)
示例:
输入:staple = [10,20,5], drinks = [5,5,2], x = 15
输出:6
题目分析,显然遍历两次轻松的到题解,但复杂度为O(mn),但这题的要求就是时间复杂度降低到O(m+n),

思路一,二分查找
如果对第一个数组排序,则需要mlogm+nlogm = (m+n)logm
如果对第二个数组排序,则需要nlogn+mlogn = (m+n)logn
所以我们只需要对长度较小的数组排序即可,总的时间复杂度为(m+n)log(min(m,n))

def helper(self,v,n):
    if v[-1] <= n: return len(v)
    l,r = 0,len(v)-1
    while l < r:
        mid = (l+r) // 2
        if v[mid] <= n: l = mid+1
        else: r = mid
    return l
    
def breakfastNumber(self, staple: List[int], drinks: List[int], x: int) -> int:
    res = 0
    if len(staple) <= len(drinks):
        staple.sort()
        for n in drinks:
            res = (res+self.helper(staple,x-n)) % 1000000007
    else:
        drinks.sort()
        for n in staple:
            res = (res+self.helper(drinks,x-n)) % 1000000007
    return res

思路二,桶排序算法,时间复杂度为O(m+n)

class Solution:
    def breakfastNumber(self, staple: List[int], drinks: List[int], x: int) -> int:
        ans = 0
        arr = [0 for i in range(x+1)]
        P = 1000000007
        for sta in staple:
            if sta<x:
                arr[sta] +=1
        # 因为staple内的值必须是小于x的,这样才能算上饮料,一旦找到sta<x的情况,
        # 那么在对应的x中的位置就+1,显示其出现的次数
        for i in range(2,x):
            arr[i] +=arr[i-1]
        # arr[i] 第i个元素表示食物里面价格小于等于i的个数
        # 这一步的作用就是让1-15内的值 确定每个食物可以接受多少个小于其值的饮料的值
        for drink in drinks:
            It = x - drink
            if It<=0:
                continue
            ans +=arr[It]
        ans = ans%P
        return ans
        # 此解法分两步,找到1-15(既X内,食物价格出现的次数)
        # 第二步生成一个匹配表,这个表内的每个元素,表示食物内价格小于或的等于当前价格的个数,所以要用累加法,从小的开始向前累加。
        # 最后x-drinks得到的值 既可以直接去对照表内查找 剩余的钱可以买到的食物的个数。
        # 时间复杂度为O(m+n)最快时间复杂度

以时间换空间的算法

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值