1、想法来源:力扣题14- I. 剪绳子
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0] x k[1] x ... x 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、思路:
我们做题多了一般会想到动态规划解法,自底向上扩展绳子长度,完成题解。但是初学者可能只会想到暴力搜索,遍历所有绳子剪法,进行比较得到结果。
对于遍历通常想到for循环遍历,但对于此题,每层for循环表示什么、其范围取值是多少都较难以想到,因此for循环解法失败。但递归遍历方法则实现、理解较为简单,应谨记,在解题时较为常用
思路来源:作者:z1m,来源:力扣
方法一:暴力递归遍历
我们往往会在头脑中形成一种很直观的暴力解法,就是列举出所有的情况,找到乘积最大的那个解。
设 F(n)为长度为n的绳子可以得到的最大乘积,对于每一个F(n),可以得到如下分解:

从上图看出我们可以把求解F(n) 的问题分解成求解 F(n-1)的问题,以此类推,直到求解到 F(2)时,F(2) = 1,递推回去,问题就得到了解决。这用到的就是分治的思想。
分治思想的解决方法往往是递归,注意到我们每次将一段绳子剪成两段时,剩下的部分可以继续剪,也可以不剪, 因此我们得到了递归函数 F(n)=max(i*(n-i),i*F(n-i)), i=1,2,...,n-2
代码:

class Solution {public:int cuttingRope(int n) {if(n == 2) return 1;int res = -1;for(int i = 1;i<n;i++){res = max(res, max(i * cuttingRope(n-i),i*(n-1)) );}return res;}
};

方法二:记忆化技术(自顶向下)
上述暴力解法会超时,但是很多进阶解法往往是暴力解法的优化。注意到上述代码中超时的原因主要是因为重复计算了 F(n),为了避免重复计算可以使用 记忆化(memoization)技术。
记忆化技术的代码使用数组 f 来保存长度为 i时的最大长度 f[i],最后返回 f[n]即可。
代码:

class Solution {public:int cuttingRope(int n) {if(n == 2) return 1;if (f[n] != 0) // 如果f[n]已经计算过,直接返回避免重复计算return f[n];int res = -1;for(int i = 1;i<n;i++){res = max(res, max(i * cuttingRope(n-i),i*(n-1)) );}f[n] = res;return res;}
};

记忆化搜索也叫“备忘录法”,它从类似上边树形图结构中的 F(n)出发,逐步递归到已知值 F(2),可以理解成为自顶向上的解决办法。

动态规划解法见原博客:作者:z1m,来源:力扣

总结:

1、递归遍历实现、理解简单,比for循环好用,但时间复杂度稍高(常系数部分大)。
2、对于递归遍历通常重复计算子问题的解,因此常利用记忆法,保存子问题的解。

递归遍历与for循环遍历:递归遍历实现、理解简单相关推荐

  1. 用c语言实现二叉树的三种遍历_利用循环和递归实现二叉树的三种遍历

    一.前序遍历 遍历的过程为:首先访问根节点,再前序访问其左子树,再前序访问其右子树. 输入二叉树: 正确答案为: [1,3,4,43,3,2,2,2,42] 递归实现: void 输出:[1,3,4, ...

  2. 如何利用循环代替递归以防止栈溢出(译)

    摘要:我们经常会用到递归函数,但是如果递归深度太大时,往往导致栈溢出.而递归深度往往不太容易把握,所以比较安全一点的做法就是:用循环代替递归.文章最后的原文里面讲了如何用10步实现这个过程,相当精彩. ...

  3. js遍历树,多层嵌套for循环,递归

    js遍历树,多层嵌套for循环,递归 一.目的 源数据示例 二.如何获得数据 多层for循环嵌套遍历树数据 递归遍历树数据 一.目的 遍历获取树数据中的部分数据. 源数据示例 menuType=2的数 ...

  4. 二叉树的层序遍历和前中后序遍历代码 迭代/递归

    二叉树的层序遍历和前中后序遍历代码 迭代/递归 只记录代码.思路参考代码随想录:https://github.com/youngyangyang04/leetcode-master/blob/mast ...

  5. 剑指offer——复习1:二叉树三种遍历方式的迭代与递归实现

    剑指offer--复习1:二叉树三种遍历方式的迭代与递归实现 20180905更新:这个博客中的解法不是很好,看相应的LeetCode题目笔记~~~ 我感觉此博客中的说法更容易让人理解:https:/ ...

  6. 面试题 7 :二叉树遍历-前序遍历(DLR),中序遍历(LDR),后序遍历(LRD)-Android端非递归实现

    二叉树实体定义: /*** Author: Heynchy* Date: 2019/6/24* <p>* Introduce: 二叉树的定义*/ public class TreeNode ...

  7. 数据结构(3) 第三天 栈的应用:就近匹配/中缀表达式转后缀表达式 、树/二叉树的概念、二叉树的递归与非递归遍历(DLR LDR LRD)、递归求叶子节点数目/二叉树高度/二叉树拷贝和释放...

    01 上节课回顾 受限的线性表 栈和队列的链式存储其实就是链表 但是不能任意操作 所以叫受限的线性表 02 栈的应用_就近匹配 案例1就近匹配: #include <stdio.h> in ...

  8. 简述树的深度优先及广度优先遍历算法,并说明非递归实现?

    深度优先遍历二叉树. 1. 中序遍历(LDR)的递归算法: 若二叉树为空,则算法结束:否则: 中序遍历根结点的左子树: 访问根结点: 中序遍历根结点的右子树. 2. 前序遍历(DLR)的递归算法: 若 ...

  9. 多叉树的前序遍历_二叉树的非递归遍历的思考

    封面图来自wikipedia 1 简介 二叉树的深度优先遍历(前序遍历.中序遍历.后序遍历)是一个比较基本的操作.如果使用递归的做法,很容易写出相应的程序:而如果使用非递归的做法,虽然也能写出相应的代 ...

最新文章

  1. input js 离开事件_听说你熟练使用Vue.js,这9种Vue技术你掌握了吗?
  2. 计算机科学与技术的知识要求,0812计算机科学与技术基本要求.doc
  3. 关于LCD的duty与bias
  4. EF Core3.0+ 通过拦截器实现读写分离与SQL日志记录
  5. 调用图片文件夹中的任意图片随机显示_他来了,他来了,Mathpix拜拜了~~~文字、表格、公式图片识别神器V0.1测试版...
  6. HTML渐变背景不重复,如何停止重复自身的背景颜色渐变? (css)
  7. [配置]VUE中通过process.env判断开发,测试和生产环境,并分环境配置不同的URL HOST
  8. matlab的special函数用法
  9. 【网络文摘】编程的智慧
  10. apt-get pip3
  11. 第1章 iFIX概述
  12. JDK的发布周期缩短,JDK9,JDK10是短期版本
  13. csgo开发者控制台指令大全_csgo控制台指令大全 csgo控制台命令一览
  14. Tinder活号技术在YouTube上面居然有用模拟器和浏览器玩明白了使用谷歌下载的
  15. java毕业答辩演讲稿,2019毕业答辩演讲稿大全
  16. Java自定义组合控件
  17. tools: rm -vf !(*.sh) 删除 除了
  18. 网络中的模块化和社区结构(Modularity and community structure in networks)
  19. python读取20万数据Excel文件+拆分数据
  20. Bea公司和sun公司介绍

热门文章

  1. RStudio 手动程序包安装
  2. 另类解决android中用三星手机拍的照片存储后旋转问题。
  3. 【转载】Jupyter Lab中的plot.ly离线模式不显示图
  4. python pb与json互转
  5. 编程过程中常见的内存开辟和释放问题
  6. Vue 3 中 v-if 和 v-show 指令实现的原理(源码分析)
  7. 思摩尔推出全球首屈一指的超薄陶瓷芯烟弹解决方案FEELM Air
  8. shell 进入hadoop_hadoop的shell命令操作
  9. iphone 微信打开H5自动播放音乐问题
  10. 计算机系统英语参考文献短,计算机英文外文外文 计算机英文参考文献怎么写...