zoukankan      html  css  js  c++  java
  • 343. Integer Break

    Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.

    For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).

    Note: you may assume that n is not less than 2.

    Hint:

    1. There is a simple O(n) solution to this problem.
    2. You may check the breaking results of n ranging from 7 to 10 to discover the regularities.

    题目大意:

    给定给一个正整数n,将其分解成至少两个正整数的和,使这些整数的积最大化。返回可以得到的最大乘积。

    测试用例如题目描述。

    注意:你可以假设n不小于2.

    提示:

    1. 题目存在O(n)的解法。
    2. 你可以通过演算n为7到10的整数来寻找规律。

    解题思路:

    观察n为7到10的情形寻找规律:

    7  -> 3 * 4     -> 12
    8  -> 2 * 3 * 3 -> 18
    9  -> 3 * 3 * 3 -> 27
    10 -> 3 * 3 * 4 -> 36

    可以发现得到的拆分结果中,各元素的差值均不超过1。

    解法I 整数均摊

    将整数n均摊为m个相差不超过1的整数,m从2到n进行枚举。

    Python代码:

    class Solution(object):
        def integerBreak(self, n):
            """
            :type n: int
            :rtype: int
            """
            return max([reduce(operator.mul, self.splitInt(n, m)) for m in range(2, n + 1)])
        
        def splitInt(self, n, m):
            quotient = n / m
            remainder = n % m
            return [quotient] * (m - remainder) + [quotient + 1] * remainder
    

    上面的代码复杂度实际上是O(n ^ 2),可以将复杂度简化为O(n)。

    Python代码:

    class Solution(object):
        def integerBreak(self, n):
            """
            :type n: int
            :rtype: int
            """
            return max([self.mulSplitInt(n, m) for m in range(2, n + 1)])
        
        def mulSplitInt(self, n, m):
            quotient = n / m
            remainder = n % m
            return quotient ** (m - remainder) * (quotient + 1) ** remainder
    

    上述解法还可以进一步将时间复杂度优化为O(1),感谢网友Lost_in_补充。

    观察n从2到13时的情形:

    2  ->  1 * 1
    3  ->  2 * 1
    4  ->  2 * 2
    5  ->  3 * 2
    6  ->  3 * 3
    7  ->  3 * 2 * 2
    8  ->  3 * 3 * 2
    9  ->  3 * 3 * 3
    10 ->  3 * 3 * 2 * 2
    11 ->  3 * 3 * 3 * 2
    12 ->  3 * 3 * 3 * 3
    13 ->  3 * 3 * 3 * 2 * 2

    从上面可以找到如下规律:

    n / 3 <= 1 时,分为两个数的乘积,尽量均摊
    n / 3 > 1 时,分为若干个3和2的乘积
    n % 3 == 0 时,分为n个3的乘积
    n % 3 == 1 时,分为n-1个3和两个2的乘积
    n % 3 == 2 时,分为n个3和一个2的乘积

    Python代码:

    class Solution(object):
        def integerBreak(self, n):
            """
            :type n: int
            :rtype: int
            """
            div = n / 3
            if div <= 1:
                return (n / 2) * (n / 2 + n % 2)
            mod = n % 3
            if mod == 0:
                return 3 ** div
            elif mod == 1:
                return 3 ** (div - 1) * 4
            elif mod == 2:
                return 3 ** div * 2
    

    解法II 动态规划

    dp[i]表示整数i拆分可以得到的最大乘积,则dp[i]只与dp[i - 2], dp[i - 3]两个状态有关

    得到状态转移方程:

    dp[x] = max(3 * dp[x - 3], 2 * dp[x - 2])

    当x <= 3时,需要对结果进行特判。

    Python代码:

    class Solution(object):
        def integerBreak(self, n):
            """
            :type n: int
            :rtype: int
            """
            if n <= 3: return n - 1
            dp = [0] * (n + 1)
            dp[2], dp[3] = 2, 3
            for x in range(4, n + 1):
                dp[x] = max(3 * dp[x - 3], 2 * dp[x - 2])
            return dp[n]
    
  • 相关阅读:
    Linux 删除文件夹和文件的命令
    克隆一台liunx机器重启后和另外一台机器ip冲突,新机器设置新的ip地址
    微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用
    kafka、zookeeper相关命令
    kafka tool2 配置及链接失败解决办法
    vmware配置centos7网络
    java8 list新特性
    java分页
    移除chrome浏览器“由贵公司接管”插件
    java获取Object属性类型、属性名称、属性值
  • 原文地址:https://www.cnblogs.com/UnGeek/p/5513796.html
Copyright © 2011-2022 走看看