剑指Offer 14- I. 剪绳子(Medium)/ 剪绳子 II(Medium)/ 343. 整数拆分(Medium)

剑指Offer 14- II. 剪绳子 II(Medium)
343. 整数拆分(Medium)
在这里插入图片描述
【题目连接】

题解

  1. 剪绳子(数学推导 / 贪心思想,清晰图解)
  2. 图解【暴力递归】【记忆化技术】【动态规划】【动态规划优化解法】

思路

  1. 数学方法【均值不等式 + 函数求极值】
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  2. 记忆化递归
    在这里插入图片描述

在这里插入图片描述
3. 动态规划
在这里插入图片描述
在这里插入图片描述
4. 动态规划空间优化
在这里插入图片描述
说明:
函数cuttingRope(n)的目标是返回能够获得的最大可能的差值。
函数的主要部分是一个循环,从3到n(包括n),计算并存储每个长度下的最大可能的差值。
循环中的dp[i%3]表示当绳子长度为i时的最大差值。这里使用模运算%来确保索引始终在0, 1, 2的范围内,因为当i大于3时,我们只需要考虑最近的三段绳子(即长度为i-1, i-2, i-3的绳子)
在循环中,我们考虑三种可能的剪断位置:
在位置i-1处剪断,得到两段长度为i-1和1的绳子。差值为i-1。
在位置i-2处剪断,得到两段长度为i-2和2的绳子。差值为i-2。
在位置i-3处剪断,得到两段长度为i-3和3的绳子。差值为i-3。
我们选择上述三种可能中的最大差值作为当前长度下的最大差值。
最后,函数返回dp[n%3],即当绳子长度为n时的最大差值。
这个方法利用了动态规划的思想,通过存储并复用之前计算的结果,避免了重复计算,从而提高了效率。

代码

class Solution(object):
    ### 0909 记忆化递归(20 ms,12.7 MB)
    def cuttingRope(self, n):
        """
        :type n: int
        :rtype: int
        """
        def memorize(n):
            ## 递归终止条件
            if n == 2:
                return 1
            ## 若当前子问题已计算,则直接返回其结果
            if f[n] != 0:
                return f[n]
            
            ## 临时变量res用于暂存剩余的绳子(数组)
            res = -1
            ## i表示需要剪掉多长的绳子,其长度从1到n
            for i in range(1, n+1):
                ## 判断是否需要剪掉?
                ## res:表示不继续剪掉
                ## i*(n-i):表示n剪掉i之后,不再剪了,直接和i相乘
                ## i*memorize(n-i):表示n剪掉i之后,继续剪(得到子问题),计算完成后再和i相乘
                res = max(res, max(i*(n-i), i*memorize(n-i)))
                
            ## 当前f数组的最后一位用于存放前面(子)问题的最大值(最优结果)
            f[n] = res
            return f[n]

        ## 初始化f数组(0),其长度为n+1,最后一位用于存放前面(子)问题的最大值(最优结果)
        f = [0] * (n+1)
        return memorize(n)

    ### 0909 动态规划(24 ms,12.9 MB)
    def cuttingRope(self, n):
        dp = [0] * (n+1)
        dp[2] = 1
        ## i从3到n
        for i in range(3, n+1):
            for j in range(1, i):
                ## 判断是否需要剪掉?
                dp[i] = max(dp[i], max(j*(i-j), j*dp[i-j]))
        ## 返回数组的最后一个元素
        return dp[n]

    ### 0909 数学方法【均值不等式 + 求极值】(4 ms,12.8 MB)
    import math
    def cuttingRope(self, n):
        if n <= 3:
            return n - 1
        a, b = n // 3, n % 3

        ## 若整除,则直接计算
        if b == 0:
            return int(math.pow(3, a))
        ## 若余1,则拆分一个3,将1和3转换为2*2
        elif b == 1:
            return int(math.pow(3, a-1)) * 2 * 2
        ## 若余2,则不拆分,直接计算
        else:
            return int(math.pow(3, a)) * 2        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值