跳至主要內容

343, 整数拆分

Mike大约 2 分钟dynamic programmingmediummathdynamic programming

一、题目描述

给定一个正整数n,将其拆分为k正整数的和(k >= 2),并使这些整数的乘积最大化。

返回你可以获得的最大乘积

示例 1
输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。

示例 2
输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。

提示

  • 2 <= n <= 58

相关主题

  • 数学
  • 动态规划

二、题解

方法 1: 动态规划

/// 时间复杂度:O(n^2)
/// 空间复杂度:O(n)
pub fn integer_break(n: i32) -> i32 {
    let n = n as usize;
    let mut dp = vec![0; n + 1];

    for i in 2..=n {
        let mut curr_max = 0;
        for j in 1..i {
            curr_max = max(curr_max, max(j * (i - j), j * dp[i - j]));
        }
        dp[i] = curr_max;
    }

    dp[n] as i32
}

方法 2: 优化的动态规划

/// 时间复杂度:O(n)
/// 空间复杂度:O(n)
pub fn integer_break(n: i32) -> i32 {
    if n <= 3 {
        return n - 1;
    }

    let n = n as usize;
    let mut dp = vec![0; n + 1];
    dp[2] = 1;

    for i in 3..=n {
        dp[i] = max(
            max(2 * (i - 2), 2 * dp[i - 2]),
            max(3 * (i - 3), 3 * dp[i - 3]),
        )
    }

    dp[n] as i32
}

方法 3: 数学

/// 时间复杂度:O(1)
/// 空间复杂度:O(1)
pub fn integer_break(n: i32) -> i32 {
    if n <= 3 {
        return n - 1;
    }

    let (quotient, remainder) = ((n / 3) as u32, n % 3);

    match remainder {
        0 => 3_i32.pow(quotient),
        1 => 3_i32.pow(quotient - 1) * 4,
        _ => 3_i32.pow(quotient) * 2,
    }
}