IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 剑指Offer 14. 剪绳子 -> 正文阅读

[数据结构与算法]剑指Offer 14. 剪绳子

题目描述:
给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],…,k[m]。请问 k [ 1 ] × . . . × k [ m ] k[1]\times...\times k[m] k[1]×...×k[m]可能的最大乘积是多少?例如,当绳子的长度是8时,把它剪成长度分别为2、3、3的三段,得到的最大乘积是18。
示例1:

输入:8
返回值:18
输入描述:输入一个数n,意义见题面。(2 <= n <= 60)
返回值描述:输出答案。

方法一:动态规划
动态规划和递归类似,有如下特点:(1)一般用于求最优解(最大值、最小值);(2)整体问题的最优解依赖于各个子问题的最优解,也就是大问题可以分解成各个子问题;(3)小问题之间还存在相互重叠的更小子问题,对于递归,则会存在重复计算,但是动态规划会把子问题的解缓存起来,从而避免重复求解子问题。(4)从上往下分析问题,从下往上求解问题。

假设把长度为 n n n的绳子剪成若干段,各段长度乘积的最大值为 f ( n ) f(n) f(n)。第一次剪后,绳子变成两段,假设第一段长为 i,则第二段长为(n - i),且 1 < = i < = n ? 1 1<=i<=n-1 1<=i<=n?1,对于长度为 i 和 (n - i) 的两段绳子可再继续剪下去,这是一个从上往下递归的过程,容易得到:
f ( n ) = m a x ( f ( i ) × f ( n ? i ) ) f(n)=max(f(i)\times f(n-i)) f(n)=max(f(i)×f(n?i))。这可以通过递归来实现,但是会存在重复计算问题,例如 f ( 7 ) f(7) f(7)分为 f ( 2 ) f(2) f(2) f ( 5 ) f(5) f(5)两个子问题, f ( 5 ) f(5) f(5)又能分为 f ( 2 ) f(2) f(2) f ( 3 ) f(3) f(3)两个子问题,这里 f ( 2 ) f(2) f(2)就会重复计算。为了避免递归的重复计算问题,可以使用动态规划来解决,从下往上求解各个子问题,并把子问题的解缓存起来,通常是缓存在一维数组或二维数组中

为了求解 f ( i ) f(i) f(i),需要求出所有可能的 f ( j ) × f ( i ? j ) f(j)\times f(i - j) f(j)×f(i?j)的值,并比较得出它们中的最大值,存放在dp数组对应位置。

public class Solution {
    public int cutRope(int target) {
        if (target == 1) return 0;
        if (target == 2) return 1;
        if (target == 3) return 2;
        int[] dp = new int[target + 1];
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
        for (int i = 4; i <= target; i++) {
            for (int j = 1; j <= i / 2; j++) {
                dp[i] = Math.max(dp[i], dp[j] * dp[i - j]);
            }
        }
        return dp[target];
    }
}

时间复杂度:双层for循环, O ( n 2 ) O(n^2) O(n2);空间复杂度:开辟了一个数组空间,用于缓存子问题结果, O ( n ) O(n) O(n)

方法二:贪心算法
剪绳子问题的贪心算法思路

public class Solution {
    public int cutRope(int target) {
        if (target == 1) return 0;
        if (target == 2) return 1;
        if (target == 3) return 2;
        int a = target / 3;
        int b = target % 3;
        if (b == 0) return (int) Math.pow(3, a); //pow()方法返回的类型是double,需要强转成int
        if (b == 1) return (int) Math.pow(3, a - 1) * 4;
        return (int) Math.pow(3, a) * 2;
    }
}

时间复杂度: O ( 1 ) O(1) O(1),空间复杂度: O ( 1 ) O(1) O(1)


结束语:如果本篇博客对您有帮助,请点赞、收藏或关注,您的鼓励是博主进步的动力,感谢支持,共同进步。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-17 12:12:08  更:2021-07-17 12:14:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 16:27:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码