东哥的算法小抄——笔记(题解整理)

第一章 数据结构

三、二叉树

4. 序列化

[297] 二叉树的序列化与反序列化
DFS:
中序的反序列化不能用,因为不能确定root是左子树和右子树中间的哪一位。前序和后序可以写,后序是反过来写,因为能发现,根节点在最后面,反过来的话,就是根、右、左。

BFS:
层级遍历用到queue,因为queue可以前出后进,序列化和反序列化都用到queue,一个逻辑,取出父节点的同时放入两子节点。
未完

5. 后序

[652] 寻找重复子树
后序遍历能复原子树模样,序列化成字符串好比较不同子树,使用一个map放所有子树字符串,一个vector放符合答案的结点。

6. 归并排序

[912] 排序数组
归并排序:两个链表里各放一个指针,比较,谁小拿出来排队,然后指针后移。
一句话总结了归并排序:先把左半边数组排好序,再把右半边数组排好序,然后把两半数组合并。

[315] 计算右侧小于当前元素的个数
和[912]题类似,唯一区别在于vector tmp使用的是vector<pair<int,int>>类型,second位置放的是每个数的初始位置,为了写答案的时候定位。使用一个vector ans传回答案。

7. 搜索树BST(特性篇)

BST的中序遍历结果是升序的。

[230] 二叉搜索树中第K小的元素
解法并不是最高效的解法,而是仅仅适用于这道题。

[538] 把二叉搜索树转换为累加树

二叉树的通用思路:思考每个节点干什么。
BST问题的思考方向:1. 利用BST左小右大的特性。2. 利用中序遍历即升序的特性。

8. 搜索树BST(基操篇)

[98] 验证二叉搜索树
如果是正常的思路,每次验证只能管自己的左右子树,管不了孙子树,所以参数设置max,min传下去,就可以约束。

[700] 二叉搜索树中的搜索
ok

[701] 二叉搜索树中的插入操作
不要用return,return还要判断是左还是右,这种直接返回在=号后侧可以直接赋值。

[450] 删除二叉搜索树中的节点
删除的三种情况,最后一种:有左子树和右子树,需要找到右子树最小的结点,value赋值过去,然后删除这个最小结点即可(左子树同理,移动最大的结点)。

//二叉搜索树的模板
void BST(TreeNode root, int target) {
    if (root.val == target)
        // 找到目标,做点什么
    if (root.val < target) 
        BST(root.right, target);//root.right=BST(root.right, target);这种也可以
    if (root.val > target)
        BST(root.left, target);
}

9. 搜索树BST(构造篇)

[96] 不同的二叉搜索树
有更简单的方法。。此方法也是老方法,除了增加一二维vector记录,防止重复计算。

[95] 不同的二叉搜索树 II
与题【96】不同之处在于如何保存每次配好的子树,反正我想了很久没想出来。

10. 快速排序的正确理解方式及运用

一句话快速排序:是先将一个元素排好序,然后再将剩下的元素排好序;是一个构造二叉搜索树的过程。
但是二叉搜索树有不平衡的风险,最极端是编程一个链表,都排到一边去了。

  1. 使用洗牌算法
  2. partition函数中随机选择数组元素作为分界点

[912] 排序数组
总共分三步,1、选择打乱方式,此处推荐两种(1.每次都随机选(这个方法) 2.洗牌算法随机打乱都可以)。2、选择low位置数值为大小分隔数。3、i在前,j在后,相对移动,移动到两者大小都不符合的时候交换。4、在分割好的两区重新上述方法。
二叉树的视角,类似于前序遍历,最后排出来一个BST。

[215] 数组中的第K个最大元素
在【912】的基础上,用if else左右筛选,再return即可。
还有二叉堆的方法,到时候再写。

11. 题目不让我做什么,我就偏要去做什么

[341] 扁平化嵌套列表迭代器
有趣的一道题,有时间不看题解自己写。有两个方法:
在递归方法中,我们在遍历时如果遇到一个嵌套的 子list,就立即处理该 子list,直到全部展开;
在迭代方法中,我们不需要全部展开,只需要把 当前list 的所有元素放入 list 中。
题中NestedInteger是多叉树的结构,考察的显然是迭代,所以考虑在next还是hasnext函数中展开时,不太懂,参考负雪明烛。
注意stack特性,逆序放进去。

12. Git原理之最近公共祖先

[236] 二叉树的最近公共祖先
几种情况,一种是q,p一左一右,一种是q就是俩人的公共祖先。框架是前序加后序这样。

[1644] 二叉树的最近公共祖先 II
使用两个bool来记录判断是否量元素都存在,而不是用nullptr来判断利用后序的原理,先判断两条子树是否存在元素,然后再判断root本身是否=目标,这样子能做到不遗漏,如果先判断root,正确就返回了,两条子树还没有查,产生了漏洞。

[235] 二叉搜索树的最近公共祖先
前面好像有几个题解标了BST,但是其实不是的,我看看。这道题很巧,只要root在两个元素之间,就是最近祖先了。

1650. 二叉树的最近公共祖先 III
单链表的内容,没写

13. 完全二叉树的节点数,你真的会算吗?

[222] 完全二叉树的节点个数
结合了普通二叉树和满二叉树,不是复杂的结合,而是判断是不是满二叉树,不是的话用普通二叉树的法子解决(每一层如此)。

四、图

1. 图论算法基础

[797] 所有可能的路径
没啥好说的,可以重新写一下看看,离开的时候要pop

2. 环检测算法及拓扑排序

。。。

五、数据结构

3. 前缀树算法模板秒杀 5 道算法题

什么叫做query本身是键的情况?

关于回溯算法框架标准多叉树框架的区别,关键在于遍历「节点」和遍历「树枝」的区别。由于 Trie 树将字符存储在「树枝」上,traverse函数是在遍历树枝上的字符,所以采用的是回溯算法框架。

回溯算法类似于深度遍历DFS,节点有值的时候,就增加结果,但是也不能放弃节点孩子的可能性,直到节点为null,然后返回上一层,再进行深入遍历。

api种,有几个和前缀相关的,有几个不和前缀相关的。
感觉hasKeyWithPatternkeysWithPattern复杂多了,因为has的话只要找到就返回,返回路径感觉复杂一些,而收集keys就简单一些。

[1804] 实现 Trie (前缀树) II-remove函数-countWordsStartingWith函数-重写
这道题不容易啊,如果是直接用labuladong的模板,就会产生冗杂,速度慢的,虽然道理是很正的,但是代码量太多了,找时间重写一遍,参考其他人答案。每个函数思路已在题中写出。

[211] 添加与搜索单词
用了两个api,一个经典insert,还有一个是通配符,稍微复杂一点

[648] 单词替换-={nullptr}-
用了trie的两个api,insert完全照搬,prefix类似查找最短prefix。可以直接在private里初始化

[208] 实现 Trie (前缀树)-this-指针数组
三个功能都很类似,主要是设置成员变量,一个指针数组和一个布尔变量,有时间复现一下labuladong的思路。

[677] 键值映射-类似1804-看1804即可

4. 啊这,一道找中位数的算法题把东哥整不会了…

[295] 数据流的中位数
数组,查找简单,插入难,搬移数据要O(N);
链表,查找难也是ON,插入容易;
平衡二叉树介于两者之间,增删改查都是logn,但是放不了重复元素;
优先级队列,有一个排序,但是只能在堆顶查找删除,在队伍中间拿不了元素。

很巧妙的一道题,比上一章节前缀树的所有api操作要好理解,将排序切割成两个优先队列,中位数在队列之间找,或者计算出来。

5. 单调栈解题模板及运用

单调栈用途不广泛,只适用于下一个更大元素这种类型

[496] 下一个更大元素 I-unordered_map-stack-hashmap[num]
找到下一个更大元素,使用单调栈(大概是唯一适配),保存元素,没有重复元素,所以应该联想到哈希表

739 题「每日温度」:
这一道题我以前写过

6. 单调队列通用模板及运用

题目写过,暂时不看这章

7. 图文详解二叉堆,实现优先级队列

二叉堆是特殊的二叉树,是通过数组构成的,分为上浮和下沉两个操作。
delmax是把头尾内容交换,删除尾节点,然后头结点下沉。insert是在尾节点插入,然后上浮。

8. 数据结构设计:用栈实现队列/用队列实现栈

队列和栈的底层都是链表和数组构成。所以两者可以互相表示,只是限于api的不同。
用两个栈实现队列,头对头,正常push,若要pop,导入到另一个栈中,再pop。

队列实现栈(无亮点):push简单,pop的话,队头的

9. 设计 Twitter:合并 k 个有序链表和面向对象设计

还没有看

第二章 动态规划

一、动态规划基本技巧

1. 动态规划解题套路框架

最重要:写出动态转移方程
斐波那契是自顶向下,动态规划是自底向上,一般脱离递归,通过迭代实现
凑零钱问题(最优子结构):子问题之间必须独立
记住重复子问题有两种方法:1、dp数组(自底向上,开头的0位可能是base case) 2、备忘录(可能就是递归,自顶向下)

思路是:

2. 最长递增子序列教你推导状态转移方程

[300] 最长递增子序列-dp数组-O(N^2)
两个for循环,dp数组里放得是,以i位数结尾的最长子序列的长度,所以,先是和前面所有位比较是否能成为末尾,其次在当末尾里,哪一队最长,记下长度,即可。
二分查找法(了解即可,所以我没看)

3. 动态规划答疑篇

都是一些基础技巧,暂时不想看。直接一边写题,不懂了再看
。。。。还有几篇

6. 对动态规划进行降维打击:空间压缩技巧

滚动变量进行优化,缩小内存。当然你也可以不做优化,因为优化会使可读性降低。

二、子序列类型问题

1. 经典动态规划:编辑距离

[72] 编辑距离-dp数组
用的dp数组,自底向上,for循环一个一个网上推。

[72] 编辑距离-自顶向下-备忘录-递归-map<pair<int,int>,int>-memo[{i,j}]
加了一个hashmap后如此不同,是什么不同,首先,return在最后return,递归的话,先是=,最后再是return,其次,键是pair的话如何写,要弄清楚。

2. 二维递增子序列:信封嵌套问题

第一个嵌套过了,第二个没过,卡在这里了,然后怎么办。

[53] 最大子数组和-vector dp(n);//一个初始化

滑动窗口:
滑动窗口算法就是专门处理子串/子数组问题的。
dp的定义:
如果是以nums[0…i] 中的「最大的子数组和」为 dp[i]。行不通。因为,最大数组和和最后一位可能不相连。
以 nums[i] 为结尾的「最大子数组和」为 dp[i]。
有后效性是指,前面的子问题包含不确定性,后面的子问题也有不确定性?
无后效性:前面的子问题计算完后结果不再改变。
分治法:
不想看分治法

3. 经典动态规划:最长公共子序列

[1143] 最长公共子序列
二维动态数组

三、背包类型问题

2. 子集背包问题

[LCR 101.分割等和子集]-二维vector压缩一维-背包问题
一道简化的背包问题,只有重量没有质量,要恰好等于sum/2为true。

dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]];//其中nums[i-1]对应位置与dp[i]中一致。

压缩为一维从后向前迭代。

3. 完全背包问题

[518. 零钱兑换 II] - 完全背包问题 - 零钱面值相同的无限量
dp[j]=dp[j]+dp[j-coins[i-1]];

4. 目标和:背包问题的变体

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Leetcode算法小抄是一份权威的算法手册,包含了Leetcode上常见的算法题目的解法和详细讲解。这个小抄对于想要提升自己算法能力的程序员来说非常有用。该小抄包括以下内容: 1.基础数据结构:包括数组、链表、栈、队列、树、哈希表等。 2.算法基础:包括排序算法、搜索算法、贪心算法、动态规划等。 3.高级算法:包括图论、字符串匹配、线性代数、计算几何等。 每个算法题目都附有详细的解析和代码实现,方便程序员进行学习和练习。此外,该小抄还提供了优秀的算法实现其他程序员的思路和解答,这对于新手来说尤为重要。 总之,Leetcode算法小抄是一份非常实用的算法手册,如果你想成为一名出色的程序员,学习和掌握其中的内容必不可少。 ### 回答2: LeetCode算法小抄是一份非常实用的算法指南,它包含了大量的算法问题和解答,而且所有的算法问题都是以LeetCode网站上的题目为蓝本的。这个小抄主要面向准备参加Google、Facebook、 Apple等知名科技公司的笔试或者面试的程序员,也适用于想要提高自己算法能力的人。这份小抄的编制者是Steven Halim和Felix Halim,也就是ACM竞赛的著名选手和教练。他们将自己多年的ACM竞赛经验倾囊相授,帮助大家提高算法能力。小抄中包含了高频出现的数据结构和算法,如树、图、排序、数组、动态规划等,每个算法都有详细的解释和代码实现。此外,小抄还包含了一些实用技巧,如测试用例设计、代码调试、复杂度分析等。总之,LeetCode算法小抄是一份非常实用、全面的算法指南,如果你想要提高自己的算法能力,相信它一定能为你带来帮助。 ### 回答3: LeetCode算法小抄是一个常用的算法学习工具,它主要是为了帮助程序员更加高效地学习和掌握LeetCode算法。LeetCode算法小抄中收录了大量经典的算法题目,并提供了详细的题解和代码示例,涵盖了各种数据结构、算法和编程技术。 LeetCode算法小抄的优点在于它的简便性和针对性。其内容结构清晰,难度逐渐增加,让读者能够逐步学习并掌握更加复杂的数据结构和算法。同时,小抄中提供了大量的代码示例和优化方法,可以帮助读者更加深入地理解和掌握算法。 另外,LeetCode算法小抄还提供了各种算法题目的分类、标签和解法推荐,让读者能够更加容易地找到自己需要的题目和解法。同时,小抄中还提供了一些常见的面试题目和解题思路,可以帮助读者更好地应对工作中和面试中的挑战。 总之,LeetCode算法小抄是一本非常实用的算法学习工具,它可以帮助程序员更加高效地学习和掌握算法知识。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值