递归代码模板


# Python def recursion(level, param1, param2, ...):     # recursion terminator     终止条件判断if level > MAX_LEVEL:        # process_result        return     # process logic in current level     当前递归逻辑处理process(level, data...)     # drill down       递归调用self.recursion(level + 1, p1, ...)    # reverse the current level status if needed     处理一些状态

实战题目
爬楼梯
括号问题22
二叉树翻转226
二叉搜索树校验98 搜索树是不允许相等的元素存在的
二叉树最大深度104
二叉树最小深度111
二叉树的序列化反序列化297
每日一课
如何优雅地计算斐波那契数列

课后作业
二叉树两个节点的公共祖先236
前序遍历与中序遍历构造二叉树105
n个数中所有可能结合77
没有重复 数字的序列,返回其所有可能的全排列46
可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列47

小结 01

一天做了10个左右的题,头晕脑胀,感觉相似的题目却又不同,所以有些题目做的很费劲,没有很好的处理,做完了效果也不是很好,并不像之前做完一个,都会有一些思路去处理,一些注意事项等等,现在感觉做完了就全凭感觉的样子,还需要冷静思考总结才行。
而且,虽然知道了这些题目都是针对递归的训练题目,但是并不是仅仅这样就够了,还需要注意的是有些题目是比较复杂的,是有逻辑需要抽象处理的,并不是知道用递归就行了,还要注意问题处理的过程,边界等。比如括号的问题,还是要了解有效括号的特性,知道如何迭代才行。
什么是有效的二叉搜索树,二叉搜索树的中序遍历特点是否可以用上等,有很多都是需要画图才能够真正解决的。但是这里条件有限,所以也别太心急,多做几遍就好了,加油。每个题都去思考对应的逻辑,处理逻辑,而不是总想一次带走,有些需要更多的逻辑处理来支撑,分析问题,找到问题的核心逻辑,找到重复点,才有助于解决问题。

同时,通过对下面的二叉树公共祖先的学习,进一步认识到了
状态空间和结果空间的区别
状态空间,是指问题本身可能有哪些情况,比如下面的分析
结果空间则是问题通过当前的解答方式可以得到的答案有哪些,比如括号组合的题,最后需要在解空间中进行过滤,得到全部合法的解,还有就是最大矩形面积,如果按照每个bar的高作为矩形的高进行枚举,则也是构建了一个解空间,在这个解空间中最终搜索只会得到一个最优解

有些问题需要对状态空间更好的划分,才更好得到解空间
而有些问题则不是构建解空间,而是直接求解得到唯一解,并不涉及最优概念,而是一个对错型的题,只有一个解,比如矩形面积,是多个解找最大的(数据线构建解空间再求解的情况),共同父节点则是直接得到最终解(没有解空间的概念)

小结02 二叉树两个节点的公共祖先

/*** 这个问题的分析,从网上看的思路,感觉有些很好,这里应该怎样分析* 首先是问题的状态空间* 1. 两个节点是父子关系*      1. 找到的时候肯定是先找到parent,直接返回parent即可** 2. 两个节点不是父子关系* 在某个子树中没有找到,只需要返回null**      1. 在某个节点的左子树和右子树中都找到了,说明当前节点为target,逐层返回之**      2. 在某个节点的其中一个子树中找到某一个节点(或则两个),返回chiled返回的节点,即代表找到了至少一个节点,* 如果在其他层级的遍历中无法找到节点,则说明这个子树中有两个这个节点,这个返回的非null糅合了多种情况,隐含了树中必然有两个节点的条件****/

可以得到这个精简的代码

public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root == p || root == q || root == null){return root;}TreeNode left = lowestCommonAncestor(root.left,p,q);TreeNode right = lowestCommonAncestor(root.right,p,q);if((left != null)&&(right != null)){return root;}if (left != null) {return left;} else {return right;}}

小结03 可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列47

非常开心,这个题通过自己的探索得到了一个新的解法,而且效率也算中规中矩,60%以上
这个是根据不重复的全排推出来的,在每个迭代中增加了一个map,如果有重复的就不交换位置了

 class Solution {List<List<Integer>> res = new LinkedList<>();public List<List<Integer>> permuteUnique(int[] nums) {List<Integer> numList = new LinkedList<>();for (int i : nums) {numList.add(i);}unique(numList, 0, nums.length);return res;}private void unique(List<Integer> numList, int cur, int len) {if (cur == len - 1) {res.add(new ArrayList<>(numList));return;}// 这里增加了一个map用来判断,就是没法重复用,有点可惜Map<Integer, Boolean> dic = new HashMap<>();for (int i = cur; i < len; i++) {if (dic.get(numList.get(i)) != null) {continue;}Collections.swap(numList, i, cur);unique(numList, cur + 1, len);Collections.swap(numList, i, cur);dic.put(numList.get(i), Boolean.TRUE);}}}

更好的答案应该是体统了更好的时间复杂度,节约了不少时间,但是思路不太一样

class Solution {boolean[] vis;public List<List<Integer>> permuteUnique(int[] nums) {List<List<Integer>> ans = new ArrayList<List<Integer>>();List<Integer> perm = new ArrayList<Integer>();vis = new boolean[nums.length];Arrays.sort(nums);backtrack(nums, ans, 0, perm);return ans;}public void backtrack(int[] nums, List<List<Integer>> ans, int idx, List<Integer> perm) {if (idx == nums.length) {ans.add(new ArrayList<Integer>(perm));return;}for (int i = 0; i < nums.length; ++i) {if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {continue;}perm.add(nums[i]);vis[i] = true;backtrack(nums, ans, idx + 1, perm);vis[i] = false;perm.remove(idx);}}
}

算法训练营07-递归使用练习相关推荐

  1. 算法训练营 day20 二叉树 最大二叉树 合并二叉树 二叉搜索树中的搜索 验证二叉树

    算法训练营 day20 二叉树 最大二叉树 合并二叉树 二叉搜索树中的搜索 验证二叉树 最大二叉树 654. 最大二叉树 - 力扣(LeetCode) 给定一个不重复的整数数组 nums . 最大二叉 ...

  2. 算法训练营 重编码_完成编码训练营后的第一年,我学到了教训。

    算法训练营 重编码 by Mario Hoyos 通过马里奥·霍约斯(Mario Hoyos) 完成编码训练营后的第一年,我学到了教训. (Lessons I learned the first ye ...

  3. [经验分享] 覃超算法训练营学习笔记

    本文为覃超算法训练营的课程笔记 推荐学习网站 学习数据结构的动画演示网站 B站 覃超大魔王 Snailclimb/JavaGuide 工欲善其事,必先利其器 simple collaborative ...

  4. 极客时间 算法训练营 毕业总结

    不知不觉8周的算法训练营也接近尾声,这期间训练营对自己的影响有三方面 一方面是收获了刻意练习,终身成长这些可以产生长远影响的思想,这里推荐三本书 卡罗尔·德韦克的<终身成长>.安德斯·艾利 ...

  5. 代码随想录算法训练营第二天|LeetCode977.有序数组的平方、LeetCode209.长度最小的子数组、LeetCode59.螺旋矩阵Ⅱ

    算法训练营打卡第二天,今天的前两道题目重点练习了双指针的用法,最后一道题目将边界条件的限定作为关键点,额外锻炼了逻辑能力. LeetCode977.有序数组的平方 题目链接 https://leetc ...

  6. _32LeetCode代码随想录算法训练营第三十二天-贪心算法 | 738.单调递增的数字 、714.买卖股票的最佳时机含手续费、968.监控二叉树

    _32LeetCode代码随想录算法训练营第三十二天-贪心算法 | 738.单调递增的数字 .714.买卖股票的最佳时机含手续费.968.监控二叉树 题目列表 738.单调递增的数字 714.买卖股票 ...

  7. 代码随想录算法训练营第30天| 332.重新安排行程 、51. N皇后 、 37. 解数独

    代码随想录算法训练营第30天| 332.重新安排行程 .51. N皇后 . 37. 解数独 332.重新安排行程 开始想的是将行程进行全排列之后,然后选出一个字典排序最小的.就也是使用的回溯的思路. ...

  8. 代码随想录算法训练营Day12 栈与队列

    #代码随想录算法训练营 代码随想录算法训练营Day12 栈与队列| 239. 滑动窗口最大值 347.前 K 个高频元素 总结 239. 滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑 ...

  9. 算法训练营学习笔记1

    算法训练营学习笔记 贪心算法 心算法总是做出当前最好的选择,期望通过局部最优选择得到全局最优的解决方案.从问题的初始解开始,一步歩地做出当前最好的选择,逐步逼近问题的目标,尽可能得到最优解: 贪心本质 ...

  10. 代码随想录算法训练营第十五天 | 层序遍历 10,226.翻转二叉树,101.对称二叉树 2

    代码随想录算法训练营第十五天 | 层序遍历 10,226.翻转二叉树,101.对称二叉树 2 1.1 层序遍历 10 1.1.1 102.二叉树的层序遍历 思路: 通过队列实现 class Solut ...

最新文章

  1. matlab水印剪切攻击程序,可以运行的水印matlab程序(嵌入,提取,攻击测试等).doc
  2. 解决opencv在pycharm中无代码自动提示的bug
  3. java hashmap读,java – ConcurrentHashmap – 读取和删除
  4. 简说设计模式——策略模式
  5. java中什么是数组_JAVA中关于数组的定义
  6. JAVA获取图片的宽、高和大小
  7. Java 算法 阿尔法乘积
  8. NAPI 方式的实现
  9. IntelliJ IDEA Maven配置 MAC系统
  10. Markdown常用字体 大小 颜色和背景设置
  11. 重发布直连路由到 OSPF
  12. 怎么注册自定义域名Email.cn邮箱?
  13. 面试面经 | 2021大疆嵌入式软件工程师笔试题B卷
  14. OSPF报文与LSA
  15. 计算机保研er去清华计算法学怎么样?
  16. echo命令详细解析(linux中超级详细,图文展示)
  17. dice系数 交叉熵_ACL2020 | 香侬科技提出用Dice Loss缓解数据集数据不平衡问题
  18. 物联网深度融入生活场景 爆发条件成熟
  19. 【STM32Cube】基于H743的SPI配置
  20. 用友nc登陆提示java_用友NC软件无法进入登陆界面,提示“网页上有错误”等现象   问题现象...

热门文章

  1. interface接口实例
  2. cocos2d-x初探学习笔记(16)--LayerColor
  3. Python 多进程pool.map()方法的使用
  4. 哦豁?这个程序员…… 有、东西!
  5. 意犹未尽 —— GPM 的状态流转(十)
  6. 【今晚7点】:圆桌PI回归 继续聊聊开源的故事
  7. HEVC支持苹果HLS的几个关键问题
  8. ffplay.c学习-7-以音频同步为基准
  9. php中使用hash_hmac函数实现HMAC-SHA1签名算法的来龙去脉
  10. EasyRTMP实现的rtmp推流的基本协议流程