python官方题解--剪绳子(3种解法)

剪绳子

http://www.nowcoder.com/questionTerminal/57d85990ba5b440ab888fc72b0751bf8

此题作为面试中经常考到的类型,涉及到我们熟悉的递归,动态规划,贪婪算法这三种,此文会介绍这三种解法.

  1. 递归
    我们先定义函数f(n)为把绳子剪成若干段之后的各段长度乘积的最大值.在剪第一刀的时候,我们会有n-1种可能的选择,也就是说剪出来的第一段绳子的长度可能为1,2,......n-1.因此就有了递归公式 f(n) = max(f(i)*f(n-i)),其中0<i<n.
    代码如下:

    #递归写法
    class Solution:
     def cutRope(self, number):
         # write code here
         if number < 2:
             return 0
         if number == 2:
             return 1
         if number == 3:
             return 2       
         return self.cutRopeCore(number)
    
     def cutRopeCore(self, number):
         if number < 4:
             return number
         max_ = 0
         for i in range(1, number/2+1):
             max_ = max(self.cutRopeCore(i) * self.cutRopeCore(number - i), max_)
         return max_
  1. 下面介绍动态规划的解法,接着上面的递归解法我们可以将其转换成动态规划的写法.由于这是一个从上至下的递归公式,递归会出现很多大量不必要的计算,一个很好的方法就是按照从下而上的顺序计算,即:
    我们先得到f(2),f(3),再得到f(4),f(5),直到f(n).
    我们可以得知f(2)=1, f(3)=2
    下面就可以写我们的代码啦:

    #动态规划
    class Solution:
     def cutRope(self, number):
         # write code here
         if number < 2:
             return 0
         if number == 2:
             return 1
         if number == 3:
             return 2       
         #申请辅助空间
         products = [0]*(number+1)
         #定义前几个初始变量的值
         products[0] = 0
         products[1] = 1
         products[2] = 2
         products[3] = 3
         #进行动态规划,也就是从下向上的进行求解
         for i in range(4, number+1):
             max_ = 0
             for j in range(1, i/2+1):
                 max_ = max(products[j]*products[i-j], max_)
             products[i] = max_
    
         max_ = products[number]
         return max_

3.下面介绍贪婪算法,我目前对这个不是很了解,需要一定的数学功底,只能先贴出代码,望大家谅解:

#贪婪算法
class Solution:
    def cutRope(self, number):
        # write code here
        if number < 2:
            return 0
        if number == 2:
            return 1
        if number == 3:
            return 2       
        #申请辅助空间
        timesOf3 = number / 3
        if (number - timesOf3*3) == 1:
            timesOf3 -= 1
        timesOf2 = (number - timesOf3*3) / 2
        return pow(3, timesOf3)*pow(2, timesOf2)
全部评论
贪心算法:如果target大于3,那么要求出的乘积的最大值一定是被剪裁过的(4看作2*2),要使结果积的数值最大,要避免剪裁出来1的情况,而又已知了当这个数值大于3时,要经过剪裁才能获取最大值,可以得出结论这个数值是被剪裁为2和3的,而且尽量剪裁3(如6:2*2*2与3*3,9:3*3*3,2*2*2*3)。楼主的代码的意思是如果这个数能够被3整除的话,就把这个数分解为3,也就是pow(3, timesOf3),如果余数为1,就分解出来2个2,其余为3,如果余数为2,就分解出来一个2其他为3.
4 回复 分享
发布于 2020-05-02 16:13
if number < 4: return number为什么啊
2 回复 分享
发布于 2020-05-30 10:40
问个小白问题:前几个变量为什么是初始化为0、1、2、3,而不是0、1、1、2。是因为 当长度为1,2、3、这几个值时不再分么?
1 回复 分享
发布于 2020-06-26 20:51
写的很好,谢谢
点赞 回复 分享
发布于 2020-04-12 14:58
第一种超时
点赞 回复 分享
发布于 2021-03-09 20:28

相关推荐

01-24 08:13
已编辑
合肥工业大学 Java
程序员牛肉:没啥问题。标准的流水线简历,但是学历好一点,所以应该是有约面的机会的。 这段时间可以考虑把自己的两个项目彻底的理一理。争取能够讲清楚每一个功能点
点赞 评论 收藏
分享
评论
48
2
分享

创作者周榜

更多
牛客网
牛客企业服务