leetcode343---整数拆分

leetcode343—整数拆分原题链接


题意简述

给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明: 你可以假设 n 不小于 2 且不大于 58。


解题分析

  • 动态规划
dp[i]: 正整数i能获得的乘积最大化

分析:
	   很容易想到这个dp[i]=max(dp[i],j * dp[i-j]),
	问题是dp[2]=1,dp[3]=2,dp[4]=4,都是不符合这个规律
	的...当然,可以枚举这些特殊情况处理.
	   认真的分解几个数发现,只要i>=4,i获得乘积最大化的
	时候其一定是分解成2,3相加.所以这里就想到另一个状态转
	移方程:dp[i]=max(2*dp[i-2],3*dp[i-3])

状态转移方程:
	dp[i]=max(2*dp[i-2],3*dp[i-3])

复杂度分析:
	时间复杂度:O(n);
	空间复杂度:O(n).
	

参考代码

  • java
class Solution {
    public int integerBreak(int n) {
        if(n == 2) return 1;
        if(n == 3) return 2;
        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
        for(int i = 4; i < n + 1; i++) {
            dp[i] = Math.max(2 * dp[i - 2], 3 * dp[i - 3]);
        }
        return dp[n];
    }
}
  • go
func integerBreak(n int) int {
    if n == 2 {
        return 1
    }
    if n == 3 {
        return 2
    }
    var dp [60]int
    dp[1], dp[2], dp[3] = 1, 2, 3
    for i := 4; i <= n; i++ {
        dp[i] = max(2 * dp[i - 2],3 * dp[i - 3])
    }
    return dp[n]
}

func max(a,b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

你可能感兴趣的:(LeetCode之旅)