• [LeetCode] 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.

    Example 1:

    Input: 2
    Output: 1
    Explanation: 2 = 1 + 1, 1 × 1 = 1.

    Example 2:

    Input: 10
    Output: 36
    Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.

    Note: You may assume that n is not less than 2 and not larger than 58.

    整数拆分。题意是给一个整数n,请你把它拆分成2个或者更多个正整数,使得拆分下来的数字之间的乘积是最大的

    我简单试了几个例子,比如2,只能拆成1x1 = 1,这没什么可说的;3可以拆成1x1x1 = 1但是这毫无意义,拆成1x2 = 2的结果都比它大;4可以拆成1x3 = 3或者2x2 = 4;5可以拆成1x4 = 5或者2x3 = 6;6可以拆成1x5 = 5或者2x4 = 8;7可以拆成1x6 = 6或者2x2x3 = 12;8可以拆成1x7 = 7或者2x2x2x2 = 16。

    注意到为了要使乘积更大,首先1xN这种情况肯定不会使乘积更大,那么就试着试一些因数比1大的情形。你会发现乘积比较大的结果,因数总是往2和3上靠近,因为这样可以使得因子更多。同时发现一个数字被分解后得到的最大乘积既然最后总是往2和3靠近,那么这里面就一定有重复计算。我这里找个一张截图解释数字如何拆分,实际上这个题也是可以用动态规划做的。

    动态规划的定义是dp[i]表示数字i被拆分后能得到的最大乘积。转移方程是dp[i] = k * (i - k) 或者dp[i] = dp[k] * dp[i - k],0 < k < i

    意思是dp值有可能是一个数被拆解成两个数字(小于6的情况),或者是这个数字可以被拆解成更多个因子,只不过是后面第二种情况dp[k] * dp[i - k]事实上是对之前的答案有储存。

    时间O(n)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int integerBreak(int n) {
     3         int[] dp = new int[n + 1];
     4         for (int i = 1; i <= n; i++) {
     5             for (int j = 1; j < i; j++) {
     6                 dp[i] = Math.max(dp[i], (i - j) * j);
     7                 dp[i] = Math.max(dp[i], dp[j] * (i - j));
     8             }
     9         }
    10         return dp[n];
    11     }
    12 }

    LeetCode 题目总结

  • 相关阅读:
    线程3 线程池和文件下载服务器
    线程 2
    线程 1
    线程间操作
    编写高质量的代码-------从命名开始
    基于.NET平台常用的框架整理
    消息队列
    我是一个线程
    linux 网络命令
    css hack比较全 --- 转
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13401647.html
Copyright © 2020-2023  润新知