zoukankan      html  css  js  c++  java
  • 剑指Offer_#14-1_剪绳子

    剑指Offer_#14-1_剪绳子

    Contents

    题目

    给你一根长度为 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

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

    提示:
    2 <= n <= 58

    思路分析

    动态规划

    设要求的最大的绳子长度乘积为f(n)
    这是一个动态规划问题。动态规划问题包含四个特点:

    1. 目标是求一个问题的最优解
    2. 整体问题的最优解依赖于各个子问题的最优解
    3. 大问题分解若干个小问题,这些小问题之间包含重叠的子问题,例如
      • f(10)分解为f(4)和f(6)
      • f(4)分解为f(2)和f(2)
      • f(6)分解为f(4)和f(2)
        这当中f(2)既是f(4)的子问题,也是f(6)的子问题,所以我们说f(2)是一个重叠的子问题,所以为了减少复杂度,我们可以将f(2)记录下来。这样以后计算f(4)和f(6)时就不需要进行重复计算。
    4. 从上往下分析问题,从下往上求解问题
      • 从上往下分析问题。也就是说,我们都是从大问题出发,将其分解为一个个小问题,这是从上而下。但是由于上面所写的特点2,大问题的解决是依赖于小问题的,所以没办法从上往下的求解。例如:我们要求解问题f(8),是依赖于f(1),f(2)...,f(7)的,要从f(1)开始算起,算到f(7),而不可能从f(7)算起,算到f(1)。这是依赖关系导致的。
      • 从下往上求解问题。也就是先计算最小,最容易问题的最优解,再利用小问题最优解,解决大问题最优解。

    解题思路

    使用数组products[]记录f(n)的结果,下标对应着长度n(长度最小为2,索引0和1的元素仅仅是凑数的,目的是使得长度和下标可以相同)。
    对于n<3的情况,可以直接得出:

    • 长度为2时,只能剪成1+1,f(2)=1
    • 长度为3时,只能剪成1+2,f(3)=2
      所以可以归结为f(n)=n-1(n<=3)。

    当输入n>3时,就需要通过循环,计算出所有f(n),返回最后一个元素即可。

    解答1

    class Solution {
        public int cuttingRope(int n) {
            if (n <= 3) return n-1;//长度为2或3时,其实不切最好,但是题目要求必须至少切一刀,所以乘积反而减1
            int[] products = new int[n + 1];//products[i]是长度为i时问题的解。长度是n+1,最后一个元素索引为n。
            //如果n>3,最后剩下的长度小于3,应该选择不切
            products[0] = 0;
            products[1] = 1;
            products[2] = 2;
            products[3] = 3;
            //继续计算长度超过4的最大乘积,要依赖于0~3的结果(准确说是1~3的结果,0是凑数的)
            for(int i = 4;i <= n;i++){
                int max = 0;
                for(int j = 1;j <= i/2;j++){
                    int product = products[j] * products[i - j];//从j的位置开始切割,计算最大乘积
                    if(product > max) max = product;
                }
                products[i] = max;
            }
            return products[n];
        }
    }

    复杂度分析

    空间复杂度

    • 使用一个数组来保存结果,

    时间复杂度

    • 二层循环,
  • 相关阅读:
    python中获取python版本号的方法
    Unity3D 的大场景内存优化
    Unity中的内存泄漏
    HDR和bloom效果的区别和关系
    用TexturePacker打图集用于UGUI中
    Lua的闭包详解(终于搞懂了)
    深入浅出!从语义角度分析隐藏在Unity协程背后的原理
    Unity3D导入3DMax模型缩放单位问题深入分析
    Unite 2017 | 从《闹闹天宫》看MOBA游戏里的网络同步技术
    Unity声音-音源组件
  • 原文地址:https://www.cnblogs.com/Howfars/p/13158983.html
Copyright © 2011-2022 走看看