js算法题解(第28天)----剑指 Offer 14- I. 剪绳子

160 阅读3分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

前言

每天一道算法题,死磕算法

今天我们再把上次讲的动态规划的模板拿来解今天这道题目

我们再来回忆一下我们的模板

  1. 定义新数组
  2. 找到最简单的子问题
  3. 找到父问题
  4. 找到如何把父问题化成子问题(自顶向下推理不出来,就自底向上推理试试,想办法怎么把子问题在父问题循环里面使用)

题目

给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0]k[1]...*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

示例 1:

输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1

分析

1.定义新数组

let arr = [];  

2.找到最简单的子问题 2还是可以分割的,所以不能分割的是1

arr[1] = 1;

3.找到父问题

以示例一为例,就是让求arr[8]为多少,那么你就要求出arr[1]到arr[7],基本动态规划的题目都这样

4.找到如何把父问题化成子问题

既然让求长度为8的绳子的最大乘积,他和让求长度为7的绳子的最大乘积有什么关系呢?

7+1=8

所以arr[7]*1是得出arr[8]的一个备选答案

还有一点需要注意的就是我们绳子最小可以分为两段,所以这也是备选答案

题解

1.首先定义一个数组

var cuttingRope = function(n) {
    let arr = [];
};

2.添加最简单的子问题

var cuttingRope = function(n) {
    let arr = [];
    arr[1] = [1];
};

3.遍历所有的子数组

var cuttingRope = function(n) {
    let arr = [];
    arr[1] = 1;
    // 求出所有的子数组,从第二个数字该开始,因为我们已经知道arr[1]了
    for(let i=2;i<=n;i++){
       
    }
    // 返回结果
    return arr[n];
};

4.要求一个最大值

var cuttingRope = function(n) {
    let arr = [];
    arr[1] = 1;
    // 求出所有的子数组
    for(let i=2;i<=n;i++){
        // 我们先设置最小值为-1
        let res = -1;
        for(let j=1;j<i;j++){
            // 求出分为两半的时候左半边
            let left = Math.floor(i/2);
            // arr[j]*(i-j)为根据最优子结构求值
            // left*(i-left)根据最小分成两段求解
            res = Math.max(res,arr[j]*(i-j),left*(i-left));
        }
        
        arr[i] = res;
    }
    return arr[n];
};

5.所以答案为

var cuttingRope = function(n) {
    let arr = [];
    arr[1] = 1;
    // 求出所有的子数组
    for(let i=2;i<=n;i++){
        // 我们先设置最小值为-1
        let res = -1;
        for(let j=1;j<i;j++){
            // 求出分为两半的时候左半边
            let left = Math.floor(i/2);
            // arr[j]*(i-j)为根据最优子结构求值
            // left*(i-left)根据最小分成两段求解
            res = Math.max(res,arr[j]*(i-j),left*(i-left));
        }
        
        arr[i] = res;
    }
    return arr[n];
};

总结

为什么我们第一步是定义新数组呢?

原因很简单,就是说明解动态规划第一步就是通过定义一个新数组

参考

剑指 Offer 14- I. 剪绳子