From 533b9fb5e1af1bc4aa2ad9065a59a7b1baf2c8fc Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Mon, 18 Oct 2021 15:59:42 +0800 Subject: [PATCH 01/50] update dd --- 4 Tree/README.md | 3 +-- 8 Algorithms Analysis/动态规划.md | 2 +- 9 Algorithms Job Interview/5.2 数列-nsum问题.md | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/4 Tree/README.md b/4 Tree/README.md index 7837139..04434dc 100644 --- a/4 Tree/README.md +++ b/4 Tree/README.md @@ -21,11 +21,10 @@ 快速排序就是个二叉树的前序遍历,归并排序就是个二叉树的后序遍历 - - ## [AVL树](3-平衡树AVL/README.md) + ## [字典树trie](4-字典树Trie/README.md) 字典树也叫前缀树,单词查找树 diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index 5e43aba..70e2728 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -10,7 +10,7 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 使用动态规划算法的问题的特征是`子问题的重叠性`,否则动态规划算法不具备优势 -动态规划的核心思想就是穷举求最值; 动态规划问题的一般形式就是求最值,动态规划其实是运筹学的一种最优化方法,只不过在计算机问题上应用比较多,比如说让你求最长递增子序列呀,最小编辑距离呀等等。 +动态规划的核心思想就是穷举求最值; 动态规划问题的一般形式就是`求最值`,动态规划其实是运筹学的一种最优化方法,只不过在计算机问题上应用比较多,比如说让你求最长递增子序列呀,最小编辑距离呀等等。 diff --git a/9 Algorithms Job Interview/5.2 数列-nsum问题.md b/9 Algorithms Job Interview/5.2 数列-nsum问题.md index 65ea410..895026f 100644 --- a/9 Algorithms Job Interview/5.2 数列-nsum问题.md +++ b/9 Algorithms Job Interview/5.2 数列-nsum问题.md @@ -91,7 +91,7 @@ int findaddends(int *data,int length,int sum,int *a,int *b); 例如输入的数组为`1, -2, 3, 10, -4, 7, 2, -5` ,和最大的子数组为`3, 10, -4, 7, 2` ,因此输出为该子数组的和18。 1. 蛮力法 fmax(i,j) 找出最大的值,3重循环 ,复杂度 0(n^3) -2. maxendindhere保存当前累加的和,如果<0,就把maxendinghere清零 , max保存最终的最大和 +2. maxendindhere保存当前累加的和,如果<0,就把maxendinghere清零 , max保存最终的最大和; 如果都是负数 ``` int maxSumOfVector(int *data,int length){ From 840b6ebf7aeec877e3d4a6686a21cf1a9ddf7d70 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Mon, 25 Oct 2021 16:39:57 +0800 Subject: [PATCH 02/50] update algo analysis --- 8 Algorithms Analysis/分治算法.md | 3 +- 8 Algorithms Analysis/动态规划.md | 50 ++++++++++++++++------------- 8 Algorithms Analysis/穷举搜索法.md | 4 +-- 8 Algorithms Analysis/贪心算法.md | 4 +-- 8 Algorithms Analysis/迭代法.md | 3 +- 8 Algorithms Analysis/递归.md | 15 +++++---- 6 files changed, 41 insertions(+), 38 deletions(-) diff --git a/8 Algorithms Analysis/分治算法.md b/8 Algorithms Analysis/分治算法.md index 832f8b1..92f5fe1 100644 --- a/8 Algorithms Analysis/分治算法.md +++ b/8 Algorithms Analysis/分治算法.md @@ -1,5 +1,4 @@ - -### 分治算法 +# 分治算法 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,各个击破,分而治之。 diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index 70e2728..fcd1ce0 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -7,22 +7,45 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 动态规划算法的关键在于解决冗余,以空间换时间的技术,需要存储过程中的各种状态。可以看着是`分治算法`+`解决冗余` -使用动态规划算法的问题的特征是`子问题的重叠性`,否则动态规划算法不具备优势 +使用动态规划算法的问题的特征是`子问题的重叠性`,`最优子结构` ,否则动态规划算法不具备优势 + +动态规划算法也可以说是 `记住求过的解来节省时间` + +【初始状态】→【决策1】→【决策2】→…→【决策n】→【结束状态】 -动态规划的核心思想就是穷举求最值; 动态规划问题的一般形式就是`求最值`,动态规划其实是运筹学的一种最优化方法,只不过在计算机问题上应用比较多,比如说让你求最长递增子序列呀,最小编辑距离呀等等。 +### DP 应用场景 + +动态规划的核心思想就是穷举求最值; 动态规划问题的一般形式就是`求最值`,动态规划其实是运筹学的一种最优化方法,只不过在计算机问题上应用比较多,比如说: + +* 最长递增子序列 (LIS Longest Increasing Subsequence) +* 最小编辑距离 +* 0-1 背包问题 +* 凑零钱问题 +* 股票问题 +* 接雨水问题 +* Fibonacci数列 +* 青蛙跳阶问题: 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。 + + +### DP VS 分治法 + +与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。 +## DP 解题模板 + + +####基本步骤 + +* 划分问题 * 状态 * 状态转移方程, 这一步最为困难 * 状态压缩 -### DP 解题模板 - - ``` # 初始化 base case dp[0][0][...] = base @@ -35,23 +58,6 @@ for 状态1 in 状态1的所有取值: ``` -####基本步骤 - -1. 划分问题 -2. 选择状态 -3. 确定决策并写出状态转移方程 -4. 写出规划方程 - - -#### 最长递增子序列 - -最长递增子序列(LIS Longest Increasing Subsequence) - - -#### 其它案例 - -* 最短路径 -* 0-1 背包问题 diff --git a/8 Algorithms Analysis/穷举搜索法.md b/8 Algorithms Analysis/穷举搜索法.md index 783a715..2da99f3 100644 --- a/8 Algorithms Analysis/穷举搜索法.md +++ b/8 Algorithms Analysis/穷举搜索法.md @@ -1,6 +1,4 @@ - - -## 穷举搜索法 +# 穷举搜索法 或者叫蛮力法。对可能的解的众多候选按照某种顺序逐一枚举和检验。典型的问题如选择排序和冒泡排序。 diff --git a/8 Algorithms Analysis/贪心算法.md b/8 Algorithms Analysis/贪心算法.md index da6d18a..f5ac09d 100644 --- a/8 Algorithms Analysis/贪心算法.md +++ b/8 Algorithms Analysis/贪心算法.md @@ -1,6 +1,4 @@ - - -## 贪心算法 +# 贪心算法 不追求最优解,只找到满意解。 diff --git a/8 Algorithms Analysis/迭代法.md b/8 Algorithms Analysis/迭代法.md index 8352728..41b808d 100644 --- a/8 Algorithms Analysis/迭代法.md +++ b/8 Algorithms Analysis/迭代法.md @@ -1,5 +1,4 @@ - -## 迭代法 +# 迭代法 是一种不断用旧值递推新值的过程,分精确迭代和近视迭代。是用来求方程和方程组近似根的方法。 diff --git a/8 Algorithms Analysis/递归.md b/8 Algorithms Analysis/递归.md index 4834141..c6a8d10 100644 --- a/8 Algorithms Analysis/递归.md +++ b/8 Algorithms Analysis/递归.md @@ -14,6 +14,13 @@ 递归运行效率较低,因为有函数调用的开销,递归多次也可能造成栈溢出。 +### 其它案例 + +* 阶乘计算 +* 梵塔问题 (三根针1,2,3表示,1号从小到大n个盘子,先要都移到3号上,不能出现大盘压小盘,找出移动次数最少的方案) +* 快速排序 + + ## 斐波那契数列 @@ -76,6 +83,7 @@ int fib(int n) { 递归解法 +``` public static LinkedNode mergeSeqLink2(LinkedNode l1, LinkedNode l2){ if(l1 == null){ @@ -96,6 +104,7 @@ public static LinkedNode mergeSeqLink2(LinkedNode l1, LinkedNode l2){ ``` 非递归解法 + ``` public static LinkedNode mergeSeqLink(LinkedNode l1, LinkedNode l2){ if (l1 == null) return l2; @@ -131,12 +140,6 @@ public static LinkedNode mergeSeqLink(LinkedNode l1, LinkedNode l2){ -#### 其它案例 - -阶乘计算 -梵塔问题 (三根针1,2,3表示,1号从小到大n个盘子,先要都移到3号上,不能出现大盘压小盘,找出移动次数最少的方案) -快速排序 - From 1c152c6afe4fcf1c8bd6557613b4d584703012c5 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Thu, 28 Oct 2021 23:53:15 +0800 Subject: [PATCH 03/50] update dp --- 8 Algorithms Analysis/动态规划.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index fcd1ce0..d8936a5 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -7,7 +7,6 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 动态规划算法的关键在于解决冗余,以空间换时间的技术,需要存储过程中的各种状态。可以看着是`分治算法`+`解决冗余` -使用动态规划算法的问题的特征是`子问题的重叠性`,`最优子结构` ,否则动态规划算法不具备优势 动态规划算法也可以说是 `记住求过的解来节省时间` @@ -16,6 +15,10 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 ### DP 应用场景 +如果一个问题,可以把所有可能的答案穷举出来,并且穷举出来后,发现存在重叠子问题,就可以考虑使用动态规划。 + +使用动态规划算法的问题的特征是`子问题的重叠性`,`最优子结构` ,否则动态规划算法不具备优势。 + 动态规划的核心思想就是穷举求最值; 动态规划问题的一般形式就是`求最值`,动态规划其实是运筹学的一种最优化方法,只不过在计算机问题上应用比较多,比如说: * 最长递增子序列 (LIS Longest Increasing Subsequence) @@ -28,6 +31,22 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 * 青蛙跳阶问题: 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。 +``` +# 青蛙跳阶问题 +想跳到第10级台阶,要么是先跳到第9级,然后再跳1级台阶上去;要么是先跳到第8级,然后一次迈2级台阶上去。 +同理,要想跳到第9级台阶,要么是先跳到第8级,然后再跳1级台阶上去;要么是先跳到第7级,然后一次迈2级台阶上去。 +要想跳到第8级台阶,要么是先跳到第7级,然后再跳1级台阶上去;要么是先跳到第6级,然后一次迈2级台阶上去 + +即通用公式为: f(n) = f(n-1) + f(n-2) + +那f(2) 或者 f(1) 等于多少呢? + +当只有2级台阶时,有两种跳法,第一种是直接跳两级,第二种是先跳一级,然后再跳一级。即f(2) = 2; +当只有1级台阶时,只有一种跳法,即f(1)= 1; + +``` + + ### DP VS 分治法 与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。 From 4da038278b464127252d6070a2d3fd7871655675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Fri, 5 Nov 2021 10:34:02 +0800 Subject: [PATCH 04/50] =?UTF-8?q?Update=20=E9=80=92=E5=BD=92.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 8 Algorithms Analysis/递归.md | 1 + 1 file changed, 1 insertion(+) diff --git a/8 Algorithms Analysis/递归.md b/8 Algorithms Analysis/递归.md index c6a8d10..45e7ee3 100644 --- a/8 Algorithms Analysis/递归.md +++ b/8 Algorithms Analysis/递归.md @@ -19,6 +19,7 @@ * 阶乘计算 * 梵塔问题 (三根针1,2,3表示,1号从小到大n个盘子,先要都移到3号上,不能出现大盘压小盘,找出移动次数最少的方案) * 快速排序 +* 很多树算法都是递归思想实现 From bd814e6691d982dd16b0c64dfa796e48934d65d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Fri, 5 Nov 2021 10:37:09 +0800 Subject: [PATCH 05/50] =?UTF-8?q?Update=20=E5=8A=A8=E6=80=81=E8=A7=84?= =?UTF-8?q?=E5=88=92.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 8 Algorithms Analysis/动态规划.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index d8936a5..70ff74d 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -56,7 +56,7 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 ## DP 解题模板 -####基本步骤 +#### 基本步骤 * 划分问题 * 状态 From 8fe17aae46e7fe75181ec856a95a2b489f658133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Fri, 5 Nov 2021 10:44:02 +0800 Subject: [PATCH 06/50] Update README.md --- 6 Sort/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/6 Sort/README.md b/6 Sort/README.md index 2099a69..ac51c25 100644 --- a/6 Sort/README.md +++ b/6 Sort/README.md @@ -5,9 +5,9 @@ **交换排序算法** -* 冒泡排序 +* 冒泡排序 :没轮确定一个最大的数排后面 * 插入排序 -* 选择排序 +* 选择排序 :每轮选择最小的数排前面 * 希尔排序 * 快排 : 选最后一个作为pivot(基数), 将数据分为 左边小于 pivot, 右边大于 pivot * 归并排序 : From 4b5e2d8b8098f7ae02248515a124390265c3823c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Fri, 5 Nov 2021 13:12:46 +0800 Subject: [PATCH 07/50] Update README.md --- 9 Algorithms Job Interview/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index 6fa298e..08a9ad1 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -15,6 +15,7 @@ * 子串 +数组,字符串问题常用解题套路:二分查找、 快慢指针、 左右指针、 滑动窗口、 前缀和数组、 差分数组。 ## [链表](2%20链表.md) @@ -60,12 +61,13 @@ ## [二叉树](7%20二叉树.md) +常见问题 * 遍历 * 翻转 * 子树 - +解题思路:递归 ## [图](8%20图.md) From 6c74856e627c74bea2f5e11f1d2cda6fdb5b89b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Sat, 6 Nov 2021 11:13:37 +0800 Subject: [PATCH 08/50] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0f91d4d..405f548 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,7 @@ * Hash * 快速排序 -* 快递选择SELECT +* 快速选择SELECT * BFS/DFS (广度/深度优先遍历) * 红黑树 (一种自平衡的`二叉查找树`) * KMP 字符串匹配算法 From ad152b7814b845af2b7839e8868c80228a9c349c Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Sat, 6 Nov 2021 22:03:15 +0800 Subject: [PATCH 09/50] update readme --- 1 String/KMP.md | 7 ++ 2 List/README.md | 7 ++ 4 Tree/9-红黑树 R-B tree/红黑树.md | 7 ++ 4 Tree/README.md | 6 +- 5 Graph/DFS 和 BFS.md | 10 ++- 5 Graph/README.md | 15 ++-- 5 Graph/最短路径.md | 9 +- 6 Sort/README.md | 140 +++++++++++++++++------------ 94 15-Classic-Algorithms/README.md | 9 +- README.md | 18 ++-- 10 files changed, 147 insertions(+), 81 deletions(-) create mode 100644 1 String/KMP.md diff --git a/1 String/KMP.md b/1 String/KMP.md new file mode 100644 index 0000000..03d0bd1 --- /dev/null +++ b/1 String/KMP.md @@ -0,0 +1,7 @@ +# 字符串匹配算法 KMP + +KMP于1977年被提出,全称 Knuth–Morris–Pratt 算法; 名字分别是:Donald Knuth(K), James H. Morris(M), Vaughan Pratt(P). + +KMP算法是一种字符串匹配算法,可以在 O(n+m) 的时间复杂度内实现两个字符串的匹配。 + + diff --git a/2 List/README.md b/2 List/README.md index 458996f..1e0460f 100644 --- a/2 List/README.md +++ b/2 List/README.md @@ -23,6 +23,13 @@ java 中扩容,每次扩容新增原先容量的 1/2 这个就不介绍了。重点说下双向链表。 +### 链表 VS 数组 + + +* 查询: 数组 O(1), 内存连续, 有序时可以用二分查找;有界 +* 删除: 链表只需要移动指针 O(1) ,数组的话删除元素需要移动后续的元素 O(N) + + ## 双向链表 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。 diff --git a/4 Tree/9-红黑树 R-B tree/红黑树.md b/4 Tree/9-红黑树 R-B tree/红黑树.md index a33a927..ff83a6d 100644 --- a/4 Tree/9-红黑树 R-B tree/红黑树.md +++ b/4 Tree/9-红黑树 R-B tree/红黑树.md @@ -49,3 +49,10 @@ + + + + + + + diff --git a/4 Tree/README.md b/4 Tree/README.md index 78c138a..1b16e27 100644 --- a/4 Tree/README.md +++ b/4 Tree/README.md @@ -23,10 +23,12 @@ ## [AVL树](3-平衡树AVL/README.md) +绝对的平衡二叉树; ## [红黑树](9-红黑树%20R-B%20tree/红黑树.md) +弱平衡二叉树;使用广泛 ## [字典树trie](4-字典树Trie/README.md) @@ -50,10 +52,6 @@ -## 赫夫曼编码 Huffman - - - diff --git a/5 Graph/DFS 和 BFS.md b/5 Graph/DFS 和 BFS.md index cbfbc4a..ecd990f 100644 --- a/5 Graph/DFS 和 BFS.md +++ b/5 Graph/DFS 和 BFS.md @@ -1,4 +1,12 @@ -# DFS 和 BFS +# DFS 和 BFS 搜索算法 + + +> DFS用递归的形式,用到了栈结构,先进后出; BFS选取状态用队列的形式,先进先出。 + + + + + diff --git a/5 Graph/README.md b/5 Graph/README.md index 7fe21e1..a4d7452 100644 --- a/5 Graph/README.md +++ b/5 Graph/README.md @@ -9,12 +9,12 @@ ### 应用场景 -工业界有哪些应用场景 +工业界有哪些应用场景? * 匹配,如打车中司乘匹配引擎,如何做到效率最优 -* 并行任务调度,一组任务,任务有优先级,如何合理安排任务调度,在最短时间内完成 -* 导航路径规划,在使用导航软件时,用户在选择一个开始地点和目的地之后导航软件会给出各种如路程最短,不走高速,时长最短等方案 -* 社区发现,在好友关系中,根据社区之间联系或紧密,利用图 louvain 算法或者其他算法对用户进行分群从而达到精准营销,个性化服务等 +* 并行任务调度: 一组任务,任务有优先级,如何合理安排任务调度,在最短时间内完成 +* 导航路径规划:在使用导航软件时,用户在选择一个开始地点和目的地之后导航软件会给出各种如路程最短,不走高速,时长最短等方案 +* 社区发现: 在好友关系中,根据社区之间联系或紧密,利用图 louvain 算法或者其他算法对用户进行分群从而达到精准营销,个性化服务等 * 金融贷后催收:利用图算法找出符合条件的失联人的联系人,从而提高催收失联修复的覆盖率、有效联系率,助力不良资产的回收 * 套汇 @@ -45,8 +45,8 @@ #### 遍历 -* 广度优先 -* 深度优先 +* 广度优先 BFS +* 深度优先 DFS Dijkstra A* @@ -67,3 +67,6 @@ https://www.jiqizhixin.com/articles/2019-05-16-14 + + + diff --git a/5 Graph/最短路径.md b/5 Graph/最短路径.md index 38713e8..0b952ad 100644 --- a/5 Graph/最短路径.md +++ b/5 Graph/最短路径.md @@ -1 +1,8 @@ -# 最短路径 \ No newline at end of file +# 最短路径 + + +Dijkstra(迪杰斯特拉) + + + + diff --git a/6 Sort/README.md b/6 Sort/README.md index ac51c25..9cfae22 100644 --- a/6 Sort/README.md +++ b/6 Sort/README.md @@ -3,21 +3,32 @@ **排序的稳定性** 是指对于相等的元素,排序之后,任然保存2个元素的位置没有变,就是稳定的排序,反之就是不稳定排序。 -**交换排序算法** +* 交换排序算法 +* 桶排序 + +### 交换排序算法 * 冒泡排序 :没轮确定一个最大的数排后面 -* 插入排序 * 选择排序 :每轮选择最小的数排前面 -* 希尔排序 -* 快排 : 选最后一个作为pivot(基数), 将数据分为 左边小于 pivot, 右边大于 pivot -* 归并排序 : -* 堆排序 +* 快排 : 选最后一个作为pivot(基数), 将数据分为 左边小于 pivot, 右边大于 pivot; 分治递归, 二叉树的前序遍历思路 +* 归并排序 : 将无序的数组,分成2个子数组分别排序,然后再merge ; 分治递归, 二叉树的后续遍历思路 +* 插入排序 : +* 希尔排序 : +* 堆排序 : -**线性排序算法** + +### 线性排序算法 * 桶排序 +### 小结 + +常见的排序算法都是比较排序,比较排序的时间复杂度通常为 O(n^2) 或 O(nlogn) +但是如果带排序的数字有一些特俗性时,我们可以根据这来设计更加优化的排序算法。 + + + # 交换排序算法 排序算法的复杂度由 `比较的次数` 和 `交换的次数` 一起决定。 @@ -31,6 +42,8 @@ 在a【i,n】中最小的元素和 a[i]交换位置。空间复杂度O(1),时间复杂度 O(n^2) +![](./selectsort.gif) + ### 冒泡排序 @@ -40,50 +53,41 @@ 这样,即使是排好序的拿冒泡排序排序,比较的时间复杂度O(n^2) - - - -### 插入排序 - -1. 第一个元素算作已经排好 -2. 取下一个元素,从已经排好的序列元素中,从后向前扫描 -3. 如果排好序的元素大于 新元素,排好序的元素移到下一个位置 -4. 重复3,直到直到最后的插入位置 -5. 重复2 - -类似插入扑克牌的效果 - -最坏的情况: 待排序的是一个逆序排放的数组,这样导致每一轮都要移动元素;此时复杂度是是0(n^2) -最好的情况: 待排序的是一已经顺序排放的数字,此时只需要做一轮比较就够了 0(n)。因此可以看到,**对大部分数据已经有序这样的数组排序,使用`插入排序`非常有优势** - -空间复杂度O(1) - - -### 希尔排序 - -递减增量排序算法,对`插入排序`的改进,实质是分组插入排序,又叫`缩小增量排序` - -1. 先将待排数列分割成若干子序列(增量为m) -2. 对每个子序列使用`插入排序` -3. 减小增量,再排序 -4. 对全体元素做一次`插入排序` - -`希尔排序`提升排序的奥秘就在于`数据元素越有序,使用插入排序效率越高` - +![](./bubblesort.gif) ### 快速排序 +时间复杂度 平均复杂度 O(n * logn) , 最坏 O(n^2) +空间复杂度 +快速排序是对冒泡排序的改进,划分交换排序。 + + 递归一次,pivot 左边都比它小,右边都比它大。这是递归,分治的思想。 -> 快速排序就是个二叉树的前序遍历,归并排序就是个二叉树的后序遍历 +> 快速排序就是个二叉树的前序遍历思路,归并排序就是个二叉树的后序遍历思路 + + +代码框架如下 + +``` +void quicksort(int *a, int left, int right){ + if (left Date: Sat, 6 Nov 2021 23:10:14 +0800 Subject: [PATCH 10/50] update readme --- 5 Graph/最短路径.md | 27 +++++++++++++++++++++++++-- README.md | 16 +++++++--------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/5 Graph/最短路径.md b/5 Graph/最短路径.md index 0b952ad..d933843 100644 --- a/5 Graph/最短路径.md +++ b/5 Graph/最短路径.md @@ -1,7 +1,30 @@ -# 最短路径 +# 最短路径算法 -Dijkstra(迪杰斯特拉) +最短路径问题: 寻找图(由结点和路径组成的)中两结点之间的最短路径 + + +实现算法 + +* A* 算法 +* Floyd +* Dijkstra(迪杰斯特拉) +* bellman-ford +* spfa + + +## A* 算法 + +`A*(A-Star)`算法是一种静态路网中求解最短路径最有效的直接搜索方法; 算法中的距离估算值与实际值越接近,最终搜索速度越快。 + + + +## Dijkstra:最短路径算法 + +Dijkstra 解决图中一点到其余各点到最短路径的问题 + +Dijkstra是荷兰的计算机科学家,提出”信号量和PV原语“,"解决哲学家就餐问题",”死锁“也是它提出来的) + diff --git a/README.md b/README.md index 6f14128..125f83f 100644 --- a/README.md +++ b/README.md @@ -164,24 +164,22 @@ ## 15个经典基础算法 +* [KMP 字符串匹配算法](1%20String/KMP.md) * [Hash](3%20Hash%20Table/README.md) * [快速排序](6%20Sort/README.md) * 快速选择SELECT -* BFS/DFS (广度/深度优先遍历) * [红黑树 (一种弱/自平衡的`二叉查找树`)](4%20Tree/9-红黑树%20R-B%20tree/红黑树.md) -* [DP (动态规划 dynamic programming)](8%20Algorithms%20Analysis/动态规划.md) -* [KMP 字符串匹配算法](1%20String/KMP.md) -* A*寻路算法: 求解最短路径 -* Dijkstra:最短路径算法 (八卦下:Dijkstra是荷兰的计算机科学家,提出”信号量和PV原语“,"解决哲学家就餐问题",”死锁“也是它提出来的) -* `SPFA(shortest path faster algorithm)` 单元最短路径算法 +* [BFS/DFS (广度/深度优先遍历)](5%20Graph/DFS%20和%20BFS.md) +* [`A*`寻路算法: 求解最短路径](5%20Graph/最短路径.md) +* Dijkstra:最短路径算法 +* `SPFA(Shortest Path Faster Algorithm)` 单元最短路径算法 * 启发式搜索 * 遗传算法 `GA` -* 图像特征提取之`SIFT` 算法 +* [DP (动态规划 dynamic programming)](8%20Algorithms%20Analysis/动态规划.md) +* 图像特征提取之`SIFT` 算法 , 广泛的应用于图像识别,图像检索,3D重建等CV的各种领域 * 傅立叶变换 - - ## 推荐阅读 ### 刷题必备 From 3a88447c9d3a2386dc64d11b87f8834223a69f93 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Sat, 6 Nov 2021 23:46:45 +0800 Subject: [PATCH 11/50] update readme --- 3 Hash Table/README.md | 1 + 5 Graph/DFS 和 BFS.md | 5 +++++ 6 Sort/外排序.md | 5 +++++ .../{bloomfilter => }/Bitmap.md | 12 ++++++------ ...loom filter(布隆过滤器).md => Bloomfilter.md} | 1 - .../{mapreduce => }/Hash映射,分而治之.md | 0 .../Inverted Index/倒排索引(Inverted Index).md | 3 +-- .../Inverted Index/数据库索引.md | 3 +-- 91 Algorithms In Big Data/README.md | 16 ++++++++-------- .../{simhash => }/simhash算法.md | 0 91 Algorithms In Big Data/双层桶划分.md | 4 +--- 92 Algorithms In DB/README.md | 3 +-- 12 files changed, 29 insertions(+), 24 deletions(-) create mode 100644 6 Sort/外排序.md rename 91 Algorithms In Big Data/{bloomfilter => }/Bitmap.md (78%) rename 91 Algorithms In Big Data/{bloomfilter/Bloom filter(布隆过滤器).md => Bloomfilter.md} (99%) rename 91 Algorithms In Big Data/{mapreduce => }/Hash映射,分而治之.md (100%) rename 91 Algorithms In Big Data/{simhash => }/simhash算法.md (100%) diff --git a/3 Hash Table/README.md b/3 Hash Table/README.md index 409a780..0bf1d4f 100644 --- a/3 Hash Table/README.md +++ b/3 Hash Table/README.md @@ -63,6 +63,7 @@ Hash hashCode(char *key){ 当然,还有其他的散列函数,如`平方取中法`, `随机数法`等。 + ## 碰撞解决 diff --git a/5 Graph/DFS 和 BFS.md b/5 Graph/DFS 和 BFS.md index ecd990f..ed7d73c 100644 --- a/5 Graph/DFS 和 BFS.md +++ b/5 Graph/DFS 和 BFS.md @@ -1,5 +1,10 @@ # DFS 和 BFS 搜索算法 +DFS: 深度优先搜索,以深度为准则,先一条路走到底,直到达到目标; 没有达到目标又无路可走了,那么则退回到上一步的状态,走其他路。这便是回溯上来。 + +BFS:广度优先搜素,在面临一个路口时,把所有的岔路口都记下来,然后选择其中一个进入,然后将它的分路情况记录下来,然后再返回来进入另外一个岔路,并重复这样的操作。 + + > DFS用递归的形式,用到了栈结构,先进后出; BFS选取状态用队列的形式,先进先出。 diff --git a/6 Sort/外排序.md b/6 Sort/外排序.md new file mode 100644 index 0000000..6c426c6 --- /dev/null +++ b/6 Sort/外排序.md @@ -0,0 +1,5 @@ +# 外排序 + + + + diff --git a/91 Algorithms In Big Data/bloomfilter/Bitmap.md b/91 Algorithms In Big Data/Bitmap.md similarity index 78% rename from 91 Algorithms In Big Data/bloomfilter/Bitmap.md rename to 91 Algorithms In Big Data/Bitmap.md index d2ce2d3..94ac1f4 100644 --- a/91 Algorithms In Big Data/bloomfilter/Bitmap.md +++ b/91 Algorithms In Big Data/Bitmap.md @@ -1,16 +1,16 @@ - - -## Bitmap +# Bitmap 也就是用1个(或几个)bit位来标记某个元素对应的value(如果是1bitmap,就只能是元素是否存在;如果是x-bitmap,还可以是元素出现的次数等信息)。使用bit位来存储信息,在需要的存储空间方面可以大大节省。应用场景有: -1. 排序(如果是1-bitmap,就只能对无重复的数排序) -2. 判断某个元素是否存在 +1. 判断某个元素是否存在 +2. 排序(如果是1-bitmap,就只能对无重复的数排序) + 比如,某文件中有若干8位数字的电话号码,要求统计一共有多少个不同的电话号码? -分析:8位最多99 999 999, 如果1Byte表示1个号码是否存在,需要95MB空间,但是如果1bit表示1个号码是否存在,则只需要 95/8=12MB 的空间。这时,数字k(0~99 999 999)与bit位的对应关系是: +分析:8位最多99 999 999, 如果1Byte表示1个号码是否存在,需要95MB空间,但是如果1bit表示1个号码是否存在,则只需要 95/8=12MB 的空间。这时,数字 `k(0~99 999 999)`与bit位的对应关系是: + ``` #define SIZE 15*1024*1024 diff --git a/91 Algorithms In Big Data/bloomfilter/Bloom filter(布隆过滤器).md b/91 Algorithms In Big Data/Bloomfilter.md similarity index 99% rename from 91 Algorithms In Big Data/bloomfilter/Bloom filter(布隆过滤器).md rename to 91 Algorithms In Big Data/Bloomfilter.md index fcd6520..c0075aa 100644 --- a/91 Algorithms In Big Data/bloomfilter/Bloom filter(布隆过滤器).md +++ b/91 Algorithms In Big Data/Bloomfilter.md @@ -1,4 +1,3 @@ - # Bloom filter(布隆过滤器) Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法。通常应用在海量数据处理中,一些需要快速判断某个元素是否属于集合,但是并不严格要求100%正确的场合(容忍错误的场景)。 diff --git a/91 Algorithms In Big Data/mapreduce/Hash映射,分而治之.md b/91 Algorithms In Big Data/Hash映射,分而治之.md similarity index 100% rename from 91 Algorithms In Big Data/mapreduce/Hash映射,分而治之.md rename to 91 Algorithms In Big Data/Hash映射,分而治之.md diff --git a/91 Algorithms In Big Data/Inverted Index/倒排索引(Inverted Index).md b/91 Algorithms In Big Data/Inverted Index/倒排索引(Inverted Index).md index aed743c..b203143 100644 --- a/91 Algorithms In Big Data/Inverted Index/倒排索引(Inverted Index).md +++ b/91 Algorithms In Big Data/Inverted Index/倒排索引(Inverted Index).md @@ -1,5 +1,4 @@ - -## 倒排索引(Inverted Index) +# 倒排索引(Inverted Index) 常规的索引是文档到关键词的映射,就是每个文档指向一个它所包含的索引项的序列,也就是文档文档指向了它包含的索引项序列,也就是文档指向它包含的哪些单词。 diff --git a/91 Algorithms In Big Data/Inverted Index/数据库索引.md b/91 Algorithms In Big Data/Inverted Index/数据库索引.md index 48048f7..96b8cf0 100644 --- a/91 Algorithms In Big Data/Inverted Index/数据库索引.md +++ b/91 Algorithms In Big Data/Inverted Index/数据库索引.md @@ -1,5 +1,4 @@ - -## 数据库索引 +# 数据库索引 索引使用的数据结构多是B树或B+树。B树和B+树广泛应用于文件存储系统和数据库系统中,mysql使用的是B+树,oracle使用的是B树,Mysql也支持多种索引类型,如b-tree 索引,哈希索引,全文索引等。 diff --git a/91 Algorithms In Big Data/README.md b/91 Algorithms In Big Data/README.md index 9a34953..b45e6b5 100644 --- a/91 Algorithms In Big Data/README.md +++ b/91 Algorithms In Big Data/README.md @@ -6,15 +6,15 @@ 针对空间,就一个办法,大而化小,分而治之。常采用hash映射 -* Hash映射/分而治之 -* Bitmap -* Bloom filter(布隆过滤器) -* 双层桶划分 -* Trie树 -* 数据库索引 +* [Hash映射,分而治之](Hash映射,分而治之.md) +* [Bitmap](Bitmap.md) +* [Bloom filter(布隆过滤器)](Bloomfilter.md) +* [双层桶划分](双层桶划分.md) +* [Trie树](../4%20Tree/4-字典树Trie/README.md) +* [数据库索引](Inverted%20Index/数据库索引.md) * 倒排索引(Inverted Index) -* 外排序 -* simhash算法 +* [外排序](../6%20Sort/外排序.md) +* [simhash算法](simhash算法.md) * 分布处理之Mapreduce diff --git a/91 Algorithms In Big Data/simhash/simhash算法.md b/91 Algorithms In Big Data/simhash算法.md similarity index 100% rename from 91 Algorithms In Big Data/simhash/simhash算法.md rename to 91 Algorithms In Big Data/simhash算法.md diff --git a/91 Algorithms In Big Data/双层桶划分.md b/91 Algorithms In Big Data/双层桶划分.md index 01d77be..c4adf7d 100644 --- a/91 Algorithms In Big Data/双层桶划分.md +++ b/91 Algorithms In Big Data/双层桶划分.md @@ -1,6 +1,4 @@ - - -## 双层桶划分 +# 双层桶划分 双层桶不是一种数据结构,只是一种算法思维。分而治之思想。 diff --git a/92 Algorithms In DB/README.md b/92 Algorithms In DB/README.md index 4095714..f818b84 100644 --- a/92 Algorithms In DB/README.md +++ b/92 Algorithms In DB/README.md @@ -1,5 +1,4 @@ - -## 数据库系统中的算法 +# 数据库系统中的算法 最近开始读《数据库系统实现》这本书,所以就想到把数据库里面用到的数据结构和算法做一个梳理。就有了这些文字。 From 00136b91f9dbb2bc78d3d866d95ed25b561668c8 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Sun, 7 Nov 2021 00:16:03 +0800 Subject: [PATCH 12/50] update readme.md --- 6 Sort/README.md | 33 +++++++++++++++++-- 8 Algorithms Analysis/README.md | 12 +++---- 8 Algorithms Analysis/分治算法.md | 15 +++++---- 8 Algorithms Analysis/动态规划.md | 3 +- 8 Algorithms Analysis/递归.md | 2 +- .../mapreduce/Hash映射,分而治之.md | 20 +++++++++++ 6 files changed, 68 insertions(+), 17 deletions(-) create mode 100644 91 Algorithms In Big Data/mapreduce/Hash映射,分而治之.md diff --git a/6 Sort/README.md b/6 Sort/README.md index 9cfae22..0e4508a 100644 --- a/6 Sort/README.md +++ b/6 Sort/README.md @@ -149,7 +149,7 @@ void quicksort(int *a, int left, int right){ ### 归并排序merge -分治算法(divide-and-conquer),必然用到递归 ; +分治算法(divide-and-conquer),必然用到递归 ; 2个有序数组的合并操作是O(n)的复杂度 因此我们可以将无序的数组,分成2个子数组分别排序,然后再merge,依次类推 @@ -161,7 +161,7 @@ void quicksort(int *a, int left, int right){ 3. 合并 -归并排序的代码框架如下: +归并排序的代码框架,套用二叉树的后续遍历思路,如下: ``` void sort(int[] nums, int lo, int hi) { @@ -174,6 +174,35 @@ void sort(int[] nums, int lo, int hi) { merge(nums, lo, mid, hi); /************************/ } + +//合并连个有序数组; 从后往前merge +public void merge(int[] arr,int low,int mid,int high,int[] tmp){ + int i = 0; + int j = low,k = mid+1; //左边序列和右边序列起始索引 + + while(j <= mid && k <= high){ + if(arr[j] < arr[k]){ + tmp[i++] = arr[j++]; + }else{ + tmp[i++] = arr[k++]; + } + } + + //若左边序列还有剩余,则将其全部拷贝进tmp[]中 + while(j <= mid){ + tmp[i++] = arr[j++]; + } + + while(k <= high){ + tmp[i++] = arr[k++]; + } + + for(int t=0;t 自顶向下的递归,自底向上是迭代 diff --git a/91 Algorithms In Big Data/mapreduce/Hash映射,分而治之.md b/91 Algorithms In Big Data/mapreduce/Hash映射,分而治之.md new file mode 100644 index 0000000..a964710 --- /dev/null +++ b/91 Algorithms In Big Data/mapreduce/Hash映射,分而治之.md @@ -0,0 +1,20 @@ +# Hash映射,分而治之 + +这里的`Hash映射`是指通过一种映射散列的方式,将海量数据均匀分布在对应的内存或更小的文件中 + +使用hash映射有个最重要的特点是: `hash值相同的两个串不一定一样,但是两个一样的字符串hash值一定相等`。哈希函数如下: + +``` +int hash = 0; +for (int i=0;i Date: Sun, 7 Nov 2021 01:15:35 +0800 Subject: [PATCH 13/50] update readme --- 2 List/README.md | 10 +++++- 4 Tree/8-堆/堆.md | 42 ++++++++++++++++++++++ 4 Tree/README.md | 4 +++ 5 Graph/README.md | 9 ++++- 6 Sort/README.md | 33 +++--------------- 9 Algorithms Job Interview/README.md | 52 +++++++++++++++++++++++++--- README.md | 2 ++ 7 files changed, 118 insertions(+), 34 deletions(-) diff --git a/2 List/README.md b/2 List/README.md index 1e0460f..a8a29af 100644 --- a/2 List/README.md +++ b/2 List/README.md @@ -25,11 +25,19 @@ java 中扩容,每次扩容新增原先容量的 1/2 ### 链表 VS 数组 +特点 -* 查询: 数组 O(1), 内存连续, 有序时可以用二分查找;有界 +* 数组 : 内存连续, 更好利用局部性原理;内存空间必须一次性分配够,所以说数组如果要扩容,需要重新分配一块更大的空间,再把数据全部复制过去,有界 +* 链表 : 不存在数组的扩容问题, 空间不连续,你无法根据一个索引算出对应元素的地址,所以不能随机访问; 需要前后元素位置的指针,会消耗相对更多的储存空间 + +优缺点: + +* 查询: 数组 O(1), 有序时可以用二分查找; * 删除: 链表只需要移动指针 O(1) ,数组的话删除元素需要移动后续的元素 O(N) + + ## 双向链表 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。 diff --git a/4 Tree/8-堆/堆.md b/4 Tree/8-堆/堆.md index 16bb213..73f9773 100644 --- a/4 Tree/8-堆/堆.md +++ b/4 Tree/8-堆/堆.md @@ -1,5 +1,47 @@ # 大顶堆 和 小顶堆 +先来了解下 `堆` 结构; 堆也被称为`优先队列` ; + +特点 + +* 堆总是一颗完全二叉树树, 使用数组作为其存储结构; +* 任一节点小于(或大于)其所有的孩子节点; + + +堆分小根堆和大根堆; 如果是大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。 + + + +### 应用场景 + +* 优先队列 如iOS中的NSOperationQueue 就是维护一个优先队列 +* 堆排序 +* top-K 大(小) + + + +# 堆存储结构 + + +`堆用数组来存储`,因为是一颗完全二叉树,i节点的父节点索引就是(i-1)/2, 左右子节点小标是 2i+1,2i+2。 + +堆的操作有: + +* 建堆 +* 插入:都是插入到数组最后,然后再调整满足堆次序 +* 删除:删除总是发生在 A[0]处,也就是只删除根节点 + +这样难怪`堆`被称为 `优先队列`。 插入和删除分别在 数组尾部和头部,只是需要再次调整以满足堆次序。 + + + + + + + + + + diff --git a/4 Tree/README.md b/4 Tree/README.md index 1b16e27..b163486 100644 --- a/4 Tree/README.md +++ b/4 Tree/README.md @@ -16,6 +16,10 @@ * 赫夫曼编码 Huffman +## 二叉树 + + + ## [二叉查找树](2-二叉查找树/二叉查找树.md) 快速排序就是个二叉树的前序遍历,归并排序就是个二叉树的后序遍历 diff --git a/5 Graph/README.md b/5 Graph/README.md index a4d7452..0774d79 100644 --- a/5 Graph/README.md +++ b/5 Graph/README.md @@ -37,10 +37,17 @@ # 图的存储结构 * 对象和指针 -* 矩阵 +* 邻接矩阵 (二维数组) * 邻接表 +图数据结构表示: + +``` + +``` + + ## 图的操作 #### 遍历 diff --git a/6 Sort/README.md b/6 Sort/README.md index 0e4508a..20636e4 100644 --- a/6 Sort/README.md +++ b/6 Sort/README.md @@ -246,40 +246,17 @@ public void merge(int[] arr,int low,int mid,int high,int[] tmp){ 利用堆这种数据结构设计的一种排序算法 -先来了解下 `堆` 结构 - -堆分小根堆和大根堆 - -堆: 任一节点小于(或大于)其所有的孩子节点,如果是大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。 - -堆也被称为`优先队列` -堆总是一颗完全树 - -`堆用数组来存储`,i节点的父节点就是(i-1)/2,左右子节点小标是 2i+1,2i+2。 - -堆的操作有: - -建堆 -插入:都是插入到数组最后,然后再调整满足堆次序 -删除:删除总是发生在 A[0]处,也就是只删除根节点 - -这样难怪`堆`被称为 `优先队列`。插入和删除分别在 数组尾部和头部,只是需要再次调整以满足堆次序。 - -`堆`的应用场景有: -优先队列 如iOS中的NSOperationQueue 就是维护一个优先队列 -堆排序 - - +[堆结构参考这里](../4%20Tree/8-堆/堆.md) 我们来看看如何使用`堆` 来做排序? -1.将待排序数列看做一颗完全二叉树的存储结构 -2.`堆化数组`,结束后,根a[0]变成了最小的值(小根堆) -3.取a[0]值,然后对`堆`做删除操作,此时,`堆`会重新 `堆化数组`,a[0]又是下一个最小的值。 +1. 将待排序数列看做一颗完全二叉树的存储结构 +2. `堆化数组`,结束后,根a[0]变成了最小的值(小根堆) +3. 取a[0]值,然后对`堆`做删除操作,此时,`堆`会重新 `堆化数组`,a[0]又是下一个最小的值。 删除操作通常是先把数组最后的元素提到a[0]位置,然后从根节点开始进行一次从上向下的调整;调整时,先从左右孩子中找最小的交换。如果父节点比每个节点都小就不用调整。(因此,在`堆排序`是可以直接让 a[0]和数组最后一个元素互换,但要先保存好a[0],或者a[n-1],这样导致了使用`堆排序`时,递增排序使用大根堆,递减排序使用小根堆。) 4. 循环3,就可以按从小到大的顺序取出所有数组元素。 -堆排序主要时间花在建堆期间和`堆化数组`,找数列中最大树只需要O(1)时间复杂度 +堆排序主要时间花在建堆期间和`堆化数组`,找数列中最大数只需要O(1)时间复杂度 void heap_sort(int *a, int length){ diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index 08a9ad1..c39960f 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -79,20 +79,64 @@ +# 刷题框架套路 + +遍历 + +``` +# 数组遍历框架 +void traverse(int[] arr) { + for (int i = 0; i < arr.length; i++) { + // 迭代访问 arr[i] + } +} + +# 链表遍历框架 +void traverse(ListNode head) { + for (ListNode p = head; p != null; p = p.next) { + // 迭代访问 p.val + } +} + +``` -## [《剑指offer》](剑指offer/README.md) +递归 -《剑指offer》里面给出了50到高质量的算法问题,很有学习的必要。 +``` +# 链表递归 +void traverse(ListNode head) { + // 递归访问 head.val + traverse(head.next); +} -## [《编程之美》](编程之美/README.md) +# 二叉树递归 +void traverse(TreeNode root) { + traverse(root.left); + traverse(root.right); +} + +# 多叉树递归 +void traverse(TreeNode root) { + for (TreeNode child : root.children) + traverse(child); +} + +# 图的递归:,用个布尔数组 visited 做标记就行了 +``` + + + +# 参考 [九度OJ](http://ac.jobdu.com/index.php) [leetcode 题目](https://leetcode.com/) - +[labuladong 的算法小抄](https://labuladong.gitee.io/algo/1/2/) +[《剑指offer》](剑指offer/README.md) 《剑指offer》里面给出了50到高质量的算法问题,很有学习的必要。 +[《编程之美》](编程之美/README.md) diff --git a/README.md b/README.md index 125f83f..ebc3c05 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,8 @@ * 链表 * 双向链表 +数组和链表结构是基础结构,散列表、栈、队列、堆、树、图等等各种数据结构都基于数组和链表结构实现。 + ### [队列](2%20Queue/README.md) * 队列 From 881539862f84da7d8df35580d0f23c87722a2863 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Sun, 7 Nov 2021 13:28:51 +0800 Subject: [PATCH 14/50] update tree --- 4 Tree/2-二叉查找树/二叉查找树.md | 2 +- 4 Tree/5-伸展树/伸展树.md | 3 +-- 4 Tree/91-反向索引/反向索引.md | 12 ------------ 4 Tree/huffman tree/赫夫曼编码.md | 4 ++-- 8 Algorithms Analysis/动态规划.md | 4 +++- .../Inverted Index/倒排索引(Inverted Index).md | 9 +++++++++ 6 files changed, 16 insertions(+), 18 deletions(-) delete mode 100644 4 Tree/91-反向索引/反向索引.md diff --git a/4 Tree/2-二叉查找树/二叉查找树.md b/4 Tree/2-二叉查找树/二叉查找树.md index 965a982..0a47375 100644 --- a/4 Tree/2-二叉查找树/二叉查找树.md +++ b/4 Tree/2-二叉查找树/二叉查找树.md @@ -1,4 +1,4 @@ -# 二叉查找树 +# 二叉查找树BST 二叉查找树(Binary search tree),也叫`有序二叉树(Ordered binary tree)`,`排序二叉树(Sorted binary tree)`。是指一个空树或者具有下列性质的二叉树: diff --git a/4 Tree/5-伸展树/伸展树.md b/4 Tree/5-伸展树/伸展树.md index 1a9e070..eaa5d51 100644 --- a/4 Tree/5-伸展树/伸展树.md +++ b/4 Tree/5-伸展树/伸展树.md @@ -1,5 +1,4 @@ - -## 伸展树 (splay tree) +# 伸展树 (splay tree) 伸展树是一种自平衡的二叉排序树。为什么需要这些自平衡的二叉排序树? diff --git a/4 Tree/91-反向索引/反向索引.md b/4 Tree/91-反向索引/反向索引.md deleted file mode 100644 index bcb9b23..0000000 --- a/4 Tree/91-反向索引/反向索引.md +++ /dev/null @@ -1,12 +0,0 @@ -# 反向索引 - -正排索引如 mysql中的索引实现 ,通常使用 B+ 树实现。 反向索引如何来实现呢? - -### 应用场景 - -* ES -* 推荐内容召回 - - - - diff --git a/4 Tree/huffman tree/赫夫曼编码.md b/4 Tree/huffman tree/赫夫曼编码.md index 8e641a6..274e410 100644 --- a/4 Tree/huffman tree/赫夫曼编码.md +++ b/4 Tree/huffman tree/赫夫曼编码.md @@ -1,5 +1,4 @@ - -## 赫夫曼编码 Huffman +# 赫夫曼编码 Huffman 这是一个经典的压缩算法。通过`字符出现的频率`,`优先级`,`二叉树`进行的压缩算法。 @@ -42,6 +41,7 @@ struct node{ 被编码的文本长度 unsigned int size 字符频率表 unsigned char freqs[NUM_CHARS] + ###解压缩 1. 读取文件头 diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index 21fb2f1..e5797cf 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -29,6 +29,8 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 * 接雨水问题 * Fibonacci数列 * 青蛙跳阶问题: 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。 +* 二叉树的最近公共祖先 +* 链表翻转 ``` @@ -57,7 +59,7 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 ## DP 解题模板 -#### 基本步骤 +基本步骤 * 划分问题 * 状态 diff --git a/91 Algorithms In Big Data/Inverted Index/倒排索引(Inverted Index).md b/91 Algorithms In Big Data/Inverted Index/倒排索引(Inverted Index).md index b203143..3c83445 100644 --- a/91 Algorithms In Big Data/Inverted Index/倒排索引(Inverted Index).md +++ b/91 Algorithms In Big Data/Inverted Index/倒排索引(Inverted Index).md @@ -34,6 +34,15 @@ T2 = "it is a banana" - 在加入新文章时,我们需要为新文章中的关键词索引和之前的合并 +### 应用场景 + +* mysql中的索引实现,使用 B+ 树实现 +* ES +* 推荐内容召回 + + + + ### 参考 From 103347ed161d23b0c34654734f01b1ca9b75ec3f Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Tue, 9 Nov 2021 01:26:42 +0800 Subject: [PATCH 15/50] update tree --- 4 Tree/4-字典树Trie/README.md | 10 ++++++---- 4 Tree/huffman tree/赫夫曼编码.md | 4 +++- 8 Algorithms Analysis/动态规划.md | 5 +++++ 8 Algorithms Analysis/回溯法.md | 12 ++++++++---- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/4 Tree/4-字典树Trie/README.md b/4 Tree/4-字典树Trie/README.md index cda44ef..6968f78 100644 --- a/4 Tree/4-字典树Trie/README.md +++ b/4 Tree/4-字典树Trie/README.md @@ -1,6 +1,5 @@ # 字典树trie -## trie基本 `字典树`,英文名`Trie树`,Trie一词来自retrieve,发音为/tri:/ “tree”,也有人读为/traɪ/ “try”, 又称`单词查找树` 或 `前缀树`,Trie树,是一种树形结构(多叉树)。 @@ -81,9 +80,12 @@ trie树把每个关键字保存在一条路径上,而不是一个节点中 ## trie树存储结构和基本操作 -最简单实现 ---- 26个字母表 a-z (没有考虑数字,大小写,其他字符如=-*/) -子树用数组存储,浪费空间;如果系统中存在大量字符串,且这些字符串基本没有公共前缀,trie树将消耗大量内存 -如果用链表存储,查询时需要遍历链表,查询效率有所降低 +最简单实现 ---- 26个字母表 `a-z` (没有考虑数字,大小写,其他字符如 `=-*/`) + +trie 树存储结构 + +* 用数组存储,浪费空间;如果系统中存在大量字符串,且这些字符串基本没有公共前缀,trie树将消耗大量内存 +* 用链表存储,查询时需要遍历链表,查询效率有所降低 diff --git a/4 Tree/huffman tree/赫夫曼编码.md b/4 Tree/huffman tree/赫夫曼编码.md index 274e410..624b6a5 100644 --- a/4 Tree/huffman tree/赫夫曼编码.md +++ b/4 Tree/huffman tree/赫夫曼编码.md @@ -1,6 +1,8 @@ # 赫夫曼编码 Huffman -这是一个经典的压缩算法。通过`字符出现的频率`,`优先级`,`二叉树`进行的压缩算法。 +Huffman在1952年根据香农(Shannon)在1948年和范若(Fano)在1949年阐述的这种编码思想提出了一种不定长编码的方法,也称霍夫曼(Huffman)编码。 + +这是一个经典的压缩算法。通过`字符出现的频率`,`优先级`,`二叉树` 进行的压缩算法。 对一个字符串,计算每个字符出现的次数,把这些字符放到优先队列(priority queue) 这这个priority queue转出二叉树 diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index e5797cf..b7d41f0 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -55,6 +55,11 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。 +### DP VS 回溯法 + + +动态规划的暴力求解阶段就是回溯算法。只是有的问题具有重叠子问题性质,可以用 dp table 或者备忘录优化,将递归树大幅剪枝,这就变成了动态规划;而有些问题没有重叠子问题,也就是[回溯算法](回溯法.md)问题了,复杂度非常高是不可避免的 + ## DP 解题模板 diff --git a/8 Algorithms Analysis/回溯法.md b/8 Algorithms Analysis/回溯法.md index 9599935..f4a12fd 100644 --- a/8 Algorithms Analysis/回溯法.md +++ b/8 Algorithms Analysis/回溯法.md @@ -13,6 +13,14 @@ 回溯法求解问题时,一般是一边建树,一边遍历该树;且采用非递归方法。 +#### 案例 + +* 迷宫问题 +* 全排列 + + + + ## 代码框架 ``` @@ -48,9 +56,5 @@ def backtrack(路径, 选择列表): -#### 其它案例 - -* 迷宫问题 -* 全排列 From 1023845d74a518ec84a22ade5279f53aa0f4f5a7 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Tue, 9 Nov 2021 14:21:46 +0800 Subject: [PATCH 16/50] top-k --- 4 Tree/8-堆/Top-K 问题.md | 20 +++++++++ 4 Tree/8-堆/堆.md | 80 ++++++++++++++++++++++++++++++--- 8 Algorithms Analysis/回溯法.md | 2 +- 3 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 4 Tree/8-堆/Top-K 问题.md diff --git a/4 Tree/8-堆/Top-K 问题.md b/4 Tree/8-堆/Top-K 问题.md new file mode 100644 index 0000000..326ca38 --- /dev/null +++ b/4 Tree/8-堆/Top-K 问题.md @@ -0,0 +1,20 @@ +# Top-K 问题 + + +问题描述:从arr[1, n]这n个数中,找出最大的k个数,这就是经典的TopK问题 + + +思路 + +1. 排序,全局都排序了,这也是这个方法复杂度非常高的原因 ; [排序算法参考这里](../../6%20Sort/REAME.md) +2. 冒泡排序,局部排序徐,只对最大的k个数排序 +3. [堆排序](./堆.md), 只找最大的k个数,这k个数不需要排序; top-k大 问题就是用 小根堆, 小根堆 固定为 k 个元素大小 , 遍历 k-N (N为所有数据的个数),插入小根堆并调整堆,以保证堆内的k个元素,总是当前最大的k个元素。 + + + + + + + + + diff --git a/4 Tree/8-堆/堆.md b/4 Tree/8-堆/堆.md index 73f9773..8877e6f 100644 --- a/4 Tree/8-堆/堆.md +++ b/4 Tree/8-堆/堆.md @@ -1,40 +1,106 @@ # 大顶堆 和 小顶堆 -先来了解下 `堆` 结构; 堆也被称为`优先队列` ; +先来了解下 `堆` 结构; 堆也被称为`优先队列`,`二叉堆` ; 特点 -* 堆总是一颗完全二叉树树, 使用数组作为其存储结构; +* 堆总是一颗完全二叉树树, 使用数组作为其存储结构,因此也叫 `二叉堆`; 用链表存的就叫二叉树了 * 任一节点小于(或大于)其所有的孩子节点; -堆分小根堆和大根堆; 如果是大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。 +堆分小根堆和大根堆; 如果根节点大于所有孩子节点,这就是一颗大根堆,也就是根节点是堆上的最大值;如果节点小于所有的子节点,这就是一颗小跟堆,也即是根节点是堆上所有节点的最小值。 +`堆用数组来存储`,因为是一颗完全二叉树,i节点的父节点索引就是(i-1)/2, 左右子节点小标是 2i+1,2i+2。 + +比如大根堆存储示例 + +``` +10, 7, 6 , 3, 4, 1, 5 +``` ### 应用场景 -* 优先队列 如iOS中的NSOperationQueue 就是维护一个优先队列 +* 优先队列 如iOS中的 NSOperationQueue 就是维护一个优先队列 * 堆排序 -* top-K 大(小) +* top-K 大(小) , top-k大 问题就是用 小根堆, 小根堆 固定为 k 个元素大小 , 遍历 k-N (N为所有数据的个数),插入小根堆并调整堆,以保证堆内的k个元素,总是当前最大的k个元素。 # 堆存储结构 -`堆用数组来存储`,因为是一颗完全二叉树,i节点的父节点索引就是(i-1)/2, 左右子节点小标是 2i+1,2i+2。 - 堆的操作有: * 建堆 * 插入:都是插入到数组最后,然后再调整满足堆次序 * 删除:删除总是发生在 A[0]处,也就是只删除根节点 + 这样难怪`堆`被称为 `优先队列`。 插入和删除分别在 数组尾部和头部,只是需要再次调整以满足堆次序。 +优先级队列的代码实现 + + +```java +public class MaxPQ + > { + // 存储元素的数组 + private Key[] pq; + // 当前 Priority Queue 中的元素个数 + private int N = 0; + + public MaxPQ(int cap) { + // 索引 0 不用,所以多分配一个空间 + pq = (Key[]) new Comparable[cap + 1]; + } + + /* 返回当前队列中最大元素 */ + public Key max() { + return pq[1]; + } + + /* 插入元素 e */ + public void insert(Key e) {...} + + /* 删除并返回当前队列中最大元素 */ + public Key delMax() {...} + + /* 上浮第 k 个元素,以维护最大堆性质 */ + private void swim(int k) {...} + + /* 下沉第 k 个元素,以维护最大堆性质 */ + private void sink(int k) {...} + + /* 交换数组的两个元素 */ + private void exch(int i, int j) { + Key temp = pq[i]; + pq[i] = pq[j]; + pq[j] = temp; + } + + /* pq[i] 是否比 pq[j] 小? */ + private boolean less(int i, int j) { + return pq[i].compareTo(pq[j]) < 0; + } + + /* 还有 left, right, parent 三个方法 */ +} + +``` + + + + + + + + + + + diff --git a/8 Algorithms Analysis/回溯法.md b/8 Algorithms Analysis/回溯法.md index f4a12fd..9275b8a 100644 --- a/8 Algorithms Analysis/回溯法.md +++ b/8 Algorithms Analysis/回溯法.md @@ -23,7 +23,7 @@ ## 代码框架 -``` +```python result = [] def backtrack(路径, 选择列表): if 满足结束条件: From 990a0b3da50b92ccd447b1f94f1100c192014d0a Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Tue, 9 Nov 2021 14:25:36 +0800 Subject: [PATCH 17/50] update sort --- 6 Sort/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/6 Sort/README.md b/6 Sort/README.md index 20636e4..c598f11 100644 --- a/6 Sort/README.md +++ b/6 Sort/README.md @@ -252,10 +252,10 @@ public void merge(int[] arr,int low,int mid,int high,int[] tmp){ 1. 将待排序数列看做一颗完全二叉树的存储结构 2. `堆化数组`,结束后,根a[0]变成了最小的值(小根堆) -3. 取a[0]值,然后对`堆`做删除操作,此时,`堆`会重新 `堆化数组`,a[0]又是下一个最小的值。 -删除操作通常是先把数组最后的元素提到a[0]位置,然后从根节点开始进行一次从上向下的调整;调整时,先从左右孩子中找最小的交换。如果父节点比每个节点都小就不用调整。(因此,在`堆排序`是可以直接让 a[0]和数组最后一个元素互换,但要先保存好a[0],或者a[n-1],这样导致了使用`堆排序`时,递增排序使用大根堆,递减排序使用小根堆。) +3. 取a[0]值,然后对`堆`做删除操作,此时,`堆`会重新 `堆化数组`,a[0]又是下一个最小的值。删除操作通常是先把数组最后的元素提到a[0]位置,然后从根节点开始进行一次从上向下的调整;调整时,先从左右孩子中找最小的交换。如果父节点比每个节点都小就不用调整。因此,在`堆排序`是可以直接让 a[0]和数组最后一个元素互换,但要先保存好a[0],或者a[n-1],这样导致了使用`堆排序`时,递增排序使用大根堆,递减排序使用小根堆。 4. 循环3,就可以按从小到大的顺序取出所有数组元素。 + 堆排序主要时间花在建堆期间和`堆化数组`,找数列中最大数只需要O(1)时间复杂度 From 5e159f210b87fb3d963683bdc7590d0d7feaf873 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Tue, 9 Nov 2021 14:48:48 +0800 Subject: [PATCH 18/50] update heap --- 4 Tree/8-堆/堆.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/4 Tree/8-堆/堆.md b/4 Tree/8-堆/堆.md index 8877e6f..114c01e 100644 --- a/4 Tree/8-堆/堆.md +++ b/4 Tree/8-堆/堆.md @@ -41,6 +41,14 @@ 这样难怪`堆`被称为 `优先队列`。 插入和删除分别在 数组尾部和头部,只是需要再次调整以满足堆次序。 +### 堆调整 + +插入或删除元素以后, 如何进行堆调整, 已满足堆次序? + + + + + 优先级队列的代码实现 From b3672ec2f0887961cd69ce90327c44204e836357 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Tue, 9 Nov 2021 14:55:28 +0800 Subject: [PATCH 19/50] update 9 --- 4 Tree/6-后缀树/后缀树.md | 3 +-- 4 Tree/8-堆/堆.md | 2 +- 9 Algorithms Job Interview/README.md | 8 ++++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/4 Tree/6-后缀树/后缀树.md b/4 Tree/6-后缀树/后缀树.md index 47e8368..43c5a72 100644 --- a/4 Tree/6-后缀树/后缀树.md +++ b/4 Tree/6-后缀树/后缀树.md @@ -1,5 +1,4 @@ - -## 后缀树(suffix tree) +# 后缀树(suffix tree) ###后缀树的应用 diff --git a/4 Tree/8-堆/堆.md b/4 Tree/8-堆/堆.md index 114c01e..74111ad 100644 --- a/4 Tree/8-堆/堆.md +++ b/4 Tree/8-堆/堆.md @@ -24,7 +24,7 @@ * 优先队列 如iOS中的 NSOperationQueue 就是维护一个优先队列 * 堆排序 -* top-K 大(小) , top-k大 问题就是用 小根堆, 小根堆 固定为 k 个元素大小 , 遍历 k-N (N为所有数据的个数),插入小根堆并调整堆,以保证堆内的k个元素,总是当前最大的k个元素。 +* [top-K 大(小)](Top-K%20问题.md) , top-k大 问题就是用 小根堆, 小根堆 固定为 k 个元素大小 , 遍历 k-N (N为所有数据的个数),插入小根堆并调整堆,以保证堆内的k个元素,总是当前最大的k个元素。 diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index c39960f..fee673c 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -2,6 +2,12 @@ 这部分内容是算法问题合集,题目大多来自网络和书籍。我做了下简单的整理,很多题做了一些思路标记。 +常用解题套路工具 + +* 数组,字符串问题:二分查找、 快慢指针、 左右指针、 滑动窗口、 前缀和数组、 差分数组。 +* 二叉树问题:递归 +* [动态规划问题](../8%20Algorithms%20Analysis/动态规划.md) + ## [字符串](1%20字符串.md) @@ -14,8 +20,6 @@ * 字符串比较 * 子串 - -数组,字符串问题常用解题套路:二分查找、 快慢指针、 左右指针、 滑动窗口、 前缀和数组、 差分数组。 ## [链表](2%20链表.md) From a45c4567591780d31e90cda2190f8b78adb258a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Wed, 10 Nov 2021 09:53:44 +0800 Subject: [PATCH 20/50] =?UTF-8?q?Update=20=E9=80=92=E5=BD=92.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 8 Algorithms Analysis/递归.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/8 Algorithms Analysis/递归.md b/8 Algorithms Analysis/递归.md index 2b3f933..f751283 100644 --- a/8 Algorithms Analysis/递归.md +++ b/8 Algorithms Analysis/递归.md @@ -1,6 +1,8 @@ # 递归 -递归是一种设计和描述算法的有力工具。 递归算法执行过程分 `递推` 和 `回归` 两个阶段 +递归是一种设计和描述算法的有力工具。 也是回溯法和动态规划的基础。 + +递归算法执行过程分 `递推` 和 `回归` 两个阶段 在 `递推` 阶段,将大的问题分解成小的问题 在 `回归` 阶段,获得最简单问题的解后,逐级返回,依次得到稍微复杂情况的解,知道获得最终的结果 @@ -13,6 +15,9 @@ 递归运行效率较低,因为有函数调用的开销,递归多次也可能造成栈溢出。 +画递归树,可以很方便地看到是否存在重叠子问题,如果有的话,就可以采用动态规划。 + + ### 其它案例 From af658eb2e67bfe66f96c09b3f96c264a3b9073c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Wed, 10 Nov 2021 09:55:22 +0800 Subject: [PATCH 21/50] =?UTF-8?q?Update=20=E9=80=92=E5=BD=92.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 8 Algorithms Analysis/递归.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/8 Algorithms Analysis/递归.md b/8 Algorithms Analysis/递归.md index f751283..3a8cd69 100644 --- a/8 Algorithms Analysis/递归.md +++ b/8 Algorithms Analysis/递归.md @@ -15,6 +15,9 @@ 递归运行效率较低,因为有函数调用的开销,递归多次也可能造成栈溢出。 + +### 递归树 + 画递归树,可以很方便地看到是否存在重叠子问题,如果有的话,就可以采用动态规划。 From 9ce6414f7bcf02ac2f5b671e1c6db868ee471860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Wed, 10 Nov 2021 09:57:16 +0800 Subject: [PATCH 22/50] =?UTF-8?q?Update=20=E9=80=92=E5=BD=92.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 8 Algorithms Analysis/递归.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/8 Algorithms Analysis/递归.md b/8 Algorithms Analysis/递归.md index 3a8cd69..04e9ca1 100644 --- a/8 Algorithms Analysis/递归.md +++ b/8 Algorithms Analysis/递归.md @@ -15,6 +15,18 @@ 递归运行效率较低,因为有函数调用的开销,递归多次也可能造成栈溢出。 +### 递归公式 + +快排 + +归并排 + + +二叉树 + + + + ### 递归树 From 5a0d23faa858ca7259dc5d17dcda80e328b32894 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Wed, 10 Nov 2021 14:27:03 +0800 Subject: [PATCH 23/50] update dp --- 3 Hash Table/LinkedHashMap.md | 58 +++++++++++++++++++++++++++++++ 8 Algorithms Analysis/动态规划.md | 1 + 8 Algorithms Analysis/回溯法.md | 28 ++++++++++++++- 8 Algorithms Analysis/递归.md | 2 +- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/3 Hash Table/LinkedHashMap.md b/3 Hash Table/LinkedHashMap.md index 515225a..4a3db88 100644 --- a/3 Hash Table/LinkedHashMap.md +++ b/3 Hash Table/LinkedHashMap.md @@ -100,6 +100,64 @@ protected boolean removeEldestEntry(Map.Entry eldest) { ``` +基于 LinkedHashMap实现的 LRU Cache + + +```Java +class LRUCache { + int cap; + LinkedHashMap cache = new LinkedHashMap<>(); + public LRUCache(int capacity) { + this.cap = capacity; + } + + //访问元素 + public int get(int key) { + if (!cache.containsKey(key)) { + return -1; + } + // 将 key 变为最近使用 + makeRecently(key); + return cache.get(key); + } + + //添加元素到cache + public void put(int key, int val) { + if (cache.containsKey(key)) { + // 修改 key 的值 + cache.put(key, val); + // 将 key 变为最近使用 + makeRecently(key); + return; + } + + if (cache.size() >= this.cap) { + // 链表头部就是最久未使用的 key + int oldestKey = cache.keySet().iterator().next(); + cache.remove(oldestKey); + } + // 将新的 key 添加链表尾部 + cache.put(key, val); + } + + private void makeRecently(int key) { + int val = cache.get(key); + // 删除 key,重新插入到队尾 + cache.remove(key); + cache.put(key, val); + } +} + +``` + + + + + + + + + diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index b7d41f0..01a2222 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -57,6 +57,7 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 ### DP VS 回溯法 +DP 和 回溯法 都会用到递归 动态规划的暴力求解阶段就是回溯算法。只是有的问题具有重叠子问题性质,可以用 dp table 或者备忘录优化,将递归树大幅剪枝,这就变成了动态规划;而有些问题没有重叠子问题,也就是[回溯算法](回溯法.md)问题了,复杂度非常高是不可避免的 diff --git a/8 Algorithms Analysis/回溯法.md b/8 Algorithms Analysis/回溯法.md index 9275b8a..1a7fd91 100644 --- a/8 Algorithms Analysis/回溯法.md +++ b/8 Algorithms Analysis/回溯法.md @@ -20,7 +20,6 @@ - ## 代码框架 ```python @@ -43,6 +42,33 @@ def backtrack(路径, 选择列表): > n 个不重复的数,全排列共有 n! 个 +```Java + // 路径:记录在 track 中 + // 选择列表:nums 中不存在于 track 的那些元素 + // 结束条件:nums 中的元素全都在 track 中出现 + void backtrack(int[] nums, LinkedList track) { + // 触发结束条件 + if (track.size() == nums.length) { + res.add(new LinkedList(track)); + return; + } + + for (int i = 0; i < nums.length; i++) { + // 排除不合法的选择 + if (track.contains(nums[i])) + continue; + + // 做选择 + track.add(nums[i]); + + // 进入下一层决策树 + backtrack(nums, track); + // 取消选择 + track.removeLast(); + } + } +``` + ## 八皇后问题 diff --git a/8 Algorithms Analysis/递归.md b/8 Algorithms Analysis/递归.md index 2b3f933..0d36733 100644 --- a/8 Algorithms Analysis/递归.md +++ b/8 Algorithms Analysis/递归.md @@ -6,7 +6,7 @@ 在 `回归` 阶段,获得最简单问题的解后,逐级返回,依次得到稍微复杂情况的解,知道获得最终的结果 1) 确定递归公式 , 比如 斐波那契数列 问题中的 `fib(n)=fib(n-1)+fib(n-2)` -2) 确定边界条件 +2) 确定边界条件 bad case > 自顶向下的递归,自底向上是迭代 From 0b2ae012d04a56ac2c7a82314f107944d87901da Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Wed, 10 Nov 2021 16:27:32 +0800 Subject: [PATCH 24/50] update recursion --- 8 Algorithms Analysis/递归.md | 38 +++++++++++++++++++++++++- 9 Algorithms Job Interview/7 二叉树.md | 15 ++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/8 Algorithms Analysis/递归.md b/8 Algorithms Analysis/递归.md index 112256d..94f9d3f 100644 --- a/8 Algorithms Analysis/递归.md +++ b/8 Algorithms Analysis/递归.md @@ -17,14 +17,50 @@ ### 递归公式 -快排 +[快排](../6%20Sort/README.md) + +```Java + void quicksort(int *a, int left, int right){ + if (left Date: Wed, 10 Nov 2021 16:35:20 +0800 Subject: [PATCH 25/50] update readme --- 1 String/java String.md | 4 ---- 4 Tree/README.md | 5 +++-- 8 Algorithms Analysis/README.md | 8 +------- 8 Algorithms Analysis/分治算法.md | 2 +- 9 Algorithms Job Interview/README.md | 2 +- 5 files changed, 6 insertions(+), 15 deletions(-) diff --git a/1 String/java String.md b/1 String/java String.md index a837aad..bcf2e29 100644 --- a/1 String/java String.md +++ b/1 String/java String.md @@ -3,7 +3,3 @@ Java 中 String 实现。 -``` - -``` - diff --git a/4 Tree/README.md b/4 Tree/README.md index b163486..6b16a06 100644 --- a/4 Tree/README.md +++ b/4 Tree/README.md @@ -19,11 +19,12 @@ ## 二叉树 +[快速排序](../6%20Sort/README.md)就是个二叉树的前序遍历,归并排序就是个二叉树的后序遍历 -## [二叉查找树](2-二叉查找树/二叉查找树.md) -快速排序就是个二叉树的前序遍历,归并排序就是个二叉树的后序遍历 +## [二叉查找树BST](2-二叉查找树/二叉查找树.md) +有序的二叉树,中序遍历结果是递增的 ## [AVL树](3-平衡树AVL/README.md) diff --git a/8 Algorithms Analysis/README.md b/8 Algorithms Analysis/README.md index 4678500..007526c 100644 --- a/8 Algorithms Analysis/README.md +++ b/8 Algorithms Analysis/README.md @@ -16,13 +16,7 @@ ### 总结 -贪心法、分治法、动态规划都是将问题归纳为根小的、相似的子问题,通过求解子问题产生全局最优解。 - -`贪心法` - -`分治法` - -`动态规划` +`贪心法`、`分治法`、`动态规划` 都是将问题归纳为根小的、相似的子问题,通过求解子问题产生全局最优解。 diff --git a/8 Algorithms Analysis/分治算法.md b/8 Algorithms Analysis/分治算法.md index 3e6328e..be1eb73 100644 --- a/8 Algorithms Analysis/分治算法.md +++ b/8 Algorithms Analysis/分治算法.md @@ -3,7 +3,7 @@ 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,各个击破,分而治之。 -分治算法常用`递归`实现 +分治算法常用[递归](./递归.md) 实现 1)问题缩小的小规模可以很容易解决 2)问题可以分解为规模较小相同问题 diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index fee673c..bef2121 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -79,7 +79,7 @@ -## 智力思维训练 +## [智力思维训练](9%20智力思维训练.md) From e819afafb996a0bb5a66ef86fb440521b59bf1ec Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Wed, 10 Nov 2021 16:50:22 +0800 Subject: [PATCH 26/50] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ebc3c05..1304c07 100644 --- a/README.md +++ b/README.md @@ -255,7 +255,7 @@ http://www.cs.usfca.edu/~galles/visualization/Algorithms.html [OI Wiki](https://github.com/24OI/OI-wiki/) 主要内容是 OI / ACM-ICPC 相关的知识整理。 - +[labuladong 的算法小抄](https://labuladong.gitee.io/algo/) 作者整理了很多的解题套路框架,看完获益良多 ## 联系 From 3b1001135d67314649a6c22586ca7eb8ccf41506 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Wed, 10 Nov 2021 17:05:04 +0800 Subject: [PATCH 27/50] update readme --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1304c07..c21d73b 100644 --- a/README.md +++ b/README.md @@ -246,14 +246,18 @@ http://www.cs.usfca.edu/~galles/visualization/Algorithms.html * [九度OJ](http://ac.jobdu.com/index.php) * 这有个[ACM训练方案](http://www.java3z.com/cwbwebhome/article/article19/res041.html) -### 其它 + +### 网课 [高级数据结构和算法](https://www.coursera.org/learn/gaoji-shuju-jiegou/) 北大教授张铭老师在coursera上的课程。完成这门课之时,你将掌握多维数组、广义表、Trie树、AVL树、伸展树等高级数据结构,并结合内排序、外排序、检索、索引有关的算法,高效地解决现实生活中一些比较复杂的应用问题。当然coursera上也还有很多其它算法方面的视频课程。 [算法设计与分析 Design and Analysis of Algorithms](https://class.coursera.org/algorithms-001/lecture) 由北大教授Wanling Qu在coursera讲授的一门算法课程。首先介绍一些与算法有关的基础知识,然后阐述经典的算法设计思想和分析技术,主要涉及的算法设计技术是:分治策略、动态规划、贪心法、回溯与分支限界等。每个视频都配有相应的讲义(pdf文件)以便阅读和复习。 -[OI Wiki](https://github.com/24OI/OI-wiki/) 主要内容是 OI / ACM-ICPC 相关的知识整理。 + +### 其它 + +[OI Wiki](https://github.com/24OI/OI-wiki/) 主要内容是 OI/ACM-ICPC 编程竞赛 (competitive programming) 相关的知识整理, 包括基础知识、常见题型、解题思路以及常用工具等内容。 [labuladong 的算法小抄](https://labuladong.gitee.io/algo/) 作者整理了很多的解题套路框架,看完获益良多 From c6f0c16806ffe79935acc2b0464775cdd219d69a Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Wed, 10 Nov 2021 17:07:31 +0800 Subject: [PATCH 28/50] add topcode --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c21d73b..e3d6f0f 100644 --- a/README.md +++ b/README.md @@ -241,7 +241,8 @@ http://www.cs.usfca.edu/~galles/visualization/Algorithms.html ### 编程网站 -* [leetcode](http://leetcode.com/) +* [leetcode](http://leetcode.com/) +* [codetop](https://codetop.cc/home) 企业高频面试题库,刷题必备 * [openjudge](http://openjudge.cn/) 开放在线程序评测平台,可以创建自己的OJ小组   * [九度OJ](http://ac.jobdu.com/index.php) * 这有个[ACM训练方案](http://www.java3z.com/cwbwebhome/article/article19/res041.html) From 99ca1198c0dff38da5074cbee1584aa3fad97eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Thu, 11 Nov 2021 10:06:07 +0800 Subject: [PATCH 29/50] Update README.md --- 9 Algorithms Job Interview/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index bef2121..b7bb001 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -2,6 +2,15 @@ 这部分内容是算法问题合集,题目大多来自网络和书籍。我做了下简单的整理,很多题做了一些思路标记。 +如何更好的写算法题 + +ide 工具 & 文本框 +语言基础语法:各常用集合的api,要能够默写 +题型,熟悉各种题目,避免在题目理解上花太多时间跟面试官拉齐 +编程思路和框架,拿到题目以后能快速套思路和代码框架 +编程细节:多练习,总结 + + 常用解题套路工具 * 数组,字符串问题:二分查找、 快慢指针、 左右指针、 滑动窗口、 前缀和数组、 差分数组。 From 892359e28b46ac1e5ab29387cc9922f28c08062f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Thu, 11 Nov 2021 10:08:06 +0800 Subject: [PATCH 30/50] Update README.md --- 9 Algorithms Job Interview/README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index b7bb001..de5b372 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -2,13 +2,15 @@ 这部分内容是算法问题合集,题目大多来自网络和书籍。我做了下简单的整理,很多题做了一些思路标记。 +## 小结 + 如何更好的写算法题 -ide 工具 & 文本框 -语言基础语法:各常用集合的api,要能够默写 -题型,熟悉各种题目,避免在题目理解上花太多时间跟面试官拉齐 -编程思路和框架,拿到题目以后能快速套思路和代码框架 -编程细节:多练习,总结 +* ide 工具 & 文本框 +* 语言基础语法:各常用集合的api,要能够默写 +* 题目:熟悉各种题目,避免在题目理解上花太多时间跟面试官拉齐 +* 编程思路和框架:拿到题目以后能快速套思路和代码框架 +* 编程细节:多练习,总结 常用解题套路工具 From 215f3f8c05713de54c763ada5a5cd9f7a874578b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Thu, 11 Nov 2021 19:53:02 +0800 Subject: [PATCH 31/50] Update README.md --- 9 Algorithms Job Interview/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index de5b372..93556c0 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -4,9 +4,9 @@ ## 小结 -如何更好的写算法题 +面试中如何更好的写算法题 -* ide 工具 & 文本框 +* ide 工具 & 文本框 ;文本框环境写算法是通常没有智能提示,有些基础数据结构可能要自己定义 * 语言基础语法:各常用集合的api,要能够默写 * 题目:熟悉各种题目,避免在题目理解上花太多时间跟面试官拉齐 * 编程思路和框架:拿到题目以后能快速套思路和代码框架 From 9f03183eecc62502635280e35b53b8227c4ca47a Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Thu, 11 Nov 2021 20:00:08 +0800 Subject: [PATCH 32/50] update readme --- 9 Algorithms Job Interview/7.2 二叉树-建树.md | 8 ++------ 9 Algorithms Job Interview/README.md | 14 +++++++------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/9 Algorithms Job Interview/7.2 二叉树-建树.md b/9 Algorithms Job Interview/7.2 二叉树-建树.md index 47ed4c6..905810c 100644 --- a/9 Algorithms Job Interview/7.2 二叉树-建树.md +++ b/9 Algorithms Job Interview/7.2 二叉树-建树.md @@ -1,16 +1,12 @@ # 二叉树-建树 - - ## 把一个有序整数数组放到二叉树中? 分析:本题考察二叉搜索树的建树方法,简单的递归结构。 -关于树的算法设计一定要联想到递归,因为树本身就是递归的定义。 -而,学会把递归改称非递归也是一种必要的技术。 -毕竟,递归会造成栈溢出,关于系统底层的程序中不到非不得以最好不要用。 -但是对某些数学问题,就一定要学会用递归去解决。 +关于树的算法设计一定要联想到递归,因为树本身就是递归的定义。而,学会把递归改称非递归也是一种必要的技术。 +毕竟,递归会造成栈溢出,关于系统底层的程序中不到非不得以最好不要用。但是对某些数学问题,就一定要学会用递归去解决。 diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index de5b372..a4948af 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -146,12 +146,12 @@ void traverse(TreeNode root) { # 参考 - -[九度OJ](http://ac.jobdu.com/index.php) -[leetcode 题目](https://leetcode.com/) -[labuladong 的算法小抄](https://labuladong.gitee.io/algo/1/2/) -[《剑指offer》](剑指offer/README.md) 《剑指offer》里面给出了50到高质量的算法问题,很有学习的必要。 -[《编程之美》](编程之美/README.md) - + +[九度OJ](http://ac.jobdu.com/index.php) +[leetcode 题目](https://leetcode.com/) +[labuladong 的算法小抄](https://labuladong.gitee.io/algo/1/2/) +[《剑指offer》](剑指offer/README.md) 《剑指offer》里面给出了50到高质量的算法问题,很有学习的必要。 +[《编程之美》](编程之美/README.md) + From 4d67d29412d30ce75f9e78462d8c6d479ea05abc Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Sun, 14 Nov 2021 22:42:14 +0800 Subject: [PATCH 33/50] update dp --- 4 Tree/2-二叉查找树/二叉查找树.md | 14 ++++-- 8 Algorithms Analysis/动态规划.md | 43 ++++++++++++++----- 9 Algorithms Job Interview/4.2 数值-指数.md | 41 ++++++++++++++---- 9 Algorithms Job Interview/5.4 数列-查找.md | 31 +++++++++++++ 9 Algorithms Job Interview/7 二叉树.md | 6 ++- 9 Algorithms Job Interview/7.1 二叉树-遍历.md | 25 ++++++++++- 9 Algorithms Job Interview/7.5 二叉搜索树.md | 27 ++++++++++++ 7 files changed, 161 insertions(+), 26 deletions(-) create mode 100644 9 Algorithms Job Interview/7.5 二叉搜索树.md diff --git a/4 Tree/2-二叉查找树/二叉查找树.md b/4 Tree/2-二叉查找树/二叉查找树.md index 0a47375..3ce4c39 100644 --- a/4 Tree/2-二叉查找树/二叉查找树.md +++ b/4 Tree/2-二叉查找树/二叉查找树.md @@ -1,12 +1,15 @@ # 二叉查找树BST -二叉查找树(Binary search tree),也叫`有序二叉树(Ordered binary tree)`,`排序二叉树(Sorted binary tree)`。是指一个空树或者具有下列性质的二叉树: +二叉查找树(Binary search tree),也叫`有序二叉树(Ordered binary tree)`,`排序二叉树(Sorted binary tree)`。 + +是指一个空树或者具有下列性质的二叉树: 1. 若任意节点的左子树不为空,则左子树上所有的节点值小于它的根节点值 2. 若任意节点的右子树不为空,则右子树上所有节点的值均大于它的根节点的值 3. 任意节点左右子树也为二叉查找树 4. 没有键值(key)相等的节点 + 有序的二叉查找树,中序遍历结果是递增的。 @@ -23,12 +26,15 @@ ``` +### 删除节点 + 删除节点,需要重建排序树 1) 删除节点是叶子节点(分支为0),结构不破坏 2)删除节点只有一个分支(分支为1),结构也不破坏 - 3)删除节点有2个分支,此时删除节点 + 3)删除节点有2个分支,此时删除节点 ; 需要重建树 + 思路一: 选左子树的最大节点,或右子树最小节点替换 ``` @@ -55,6 +61,7 @@ int bisearch_tree_delete(BiSearchTree **tree,ElemType node){ printf("树为空,或想要删除的节点不存在\n"); return -1; } + //该节点为叶子节点,直接删除 if (!target->rChild && !target->lChild) { @@ -86,7 +93,8 @@ int bisearch_tree_delete(BiSearchTree **tree,ElemType node){ target->rChild=target->rChild->rChild; free(del); - } + } + else{ //左右子树均不空,p,t 2个指针一前以后,将左子树最大的节点(肯定是一个最右的节点)替换到删除的节点后,还需要处理左子树最大节点的左子树 BiSearchTree *p=target,*t=target->lChild; diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index 01a2222..c2ff383 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -8,7 +8,7 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 动态规划算法的关键在于解决冗余,以空间换时间的技术,需要存储过程中的各种状态。可以看着是`分治算法`+`解决冗余` -动态规划算法也可以说是 `记住求过的解来节省时间` +动态规划算法也可以说是 `记住求过的解来节省时间` ; 比如 Fibonacci数列 中,先直接从最小,最简单的 f(1) , f(2) 开始,自低向上一直到 f(20) , 这就是动态规划的思路 【初始状态】→【决策1】→【决策2】→…→【决策n】→【结束状态】 @@ -21,16 +21,20 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 动态规划的核心思想就是穷举求最值; 动态规划问题的一般形式就是`求最值`,动态规划其实是运筹学的一种最优化方法,只不过在计算机问题上应用比较多,比如说: -* 最长递增子序列 (LIS Longest Increasing Subsequence) -* 最小编辑距离 -* 0-1 背包问题 -* 凑零钱问题 -* 股票问题 -* 接雨水问题 -* Fibonacci数列 +* Fibonacci数列 [代码参考这里 递归](./递归.md) +* 凑零钱问题 +* 股票问题 [代码参考这里](https://github.com/nonstriater/deep-in-java/blob/master/src/main/java/com/nonstriater/deepinjava/algo/list/stock/BestChance.java) +* 二叉树的最近公共祖先 [代码参考这里](https://github.com/nonstriater/deep-in-java/blob/master/src/main/java/com/nonstriater/deepinjava/algo/tree/CommonParent.java) +* 链表翻转 [代码参考这里](https://github.com/nonstriater/deep-in-java/blob/master/src/main/java/com/nonstriater/deepinjava/algo/link/ReverseLink.java) +* 接雨水问题 * 青蛙跳阶问题: 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。 -* 二叉树的最近公共祖先 -* 链表翻转 +* 最小编辑距离 +* 最长递增子序列 (LIS Longest Increasing Subsequence) +* 0-1 背包问题 + + + +[更多动态规划案例代码实现参考deep-in-java])(https://github.com/nonstriater/deep-in-java/tree/master/src/main/java/com/nonstriater/deepinjava/algo/framework/dynamic) ``` @@ -69,7 +73,7 @@ DP 和 回溯法 都会用到递归 * 划分问题 * 状态 -* 状态转移方程, 这一步最为困难 +* 状态转移方程, 这一步最为困难 ; 暴力解法就是状态转移方程 * 状态压缩 @@ -87,6 +91,23 @@ for 状态1 in 状态1的所有取值: +## 凑零钱问题 + +凑零钱问题[视频解读参考这里]() + +如果使用贪心策略,并不能得到最优解。 + + + +```Java + +``` + + + + + + diff --git a/9 Algorithms Job Interview/4.2 数值-指数.md b/9 Algorithms Job Interview/4.2 数值-指数.md index 371b804..247983c 100644 --- a/9 Algorithms Job Interview/4.2 数值-指数.md +++ b/9 Algorithms Job Interview/4.2 数值-指数.md @@ -11,6 +11,19 @@ 不需要考虑溢出。 + +用例: + +``` +2^3 = 8 +0^3 = 0 +2^0 = 1 +2^-3 = 1/(2^3) = 0.125 +0^-3 +``` + + + 分析:这是一道看起来很简单的问题。可能有不少的人在看到题目后30秒写出如下的代码: ``` double Power(double base, int exponent) @@ -35,15 +48,6 @@ double Power(double base, int exponent) 2^1 = 2 ``` -用例: - -``` -2 3 = 8 -0 3 = 0 -2 0 = 1 -2 -3 = 1/(2^3) = 0.125 -0 -3 -``` 使用递归实现的代码示例: @@ -62,6 +66,25 @@ double Power(double base, unsigned int exponent) ``` +## Sqrt(x) + +给你一个非负整数 x ,计算并返回 x 的 算术平方根 。由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 + + +示例 1: +``` +输入:x = 4 +输出:2 +``` +示例 2: +``` +输入:x = 8 +输出:2 +解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。 +``` + + + ## 求根号2的值 并且按照我的需要列出指定小数位,比如根号2是1.141 我要列出1位小数就是1.1 2位就是1.14, 1000位就是1.141...... 等。。 diff --git a/9 Algorithms Job Interview/5.4 数列-查找.md b/9 Algorithms Job Interview/5.4 数列-查找.md index f1763fa..48bd250 100644 --- a/9 Algorithms Job Interview/5.4 数列-查找.md +++ b/9 Algorithms Job Interview/5.4 数列-查找.md @@ -141,4 +141,35 @@ int one_appear_count(int n); +## 搜索旋转排序数组 + + +整数数组 nums 按升序排列,数组中的值 互不相同 。 + +在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。 + +给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。 + + +示例 1: + +``` +输入:nums = [4,5,6,7,0,1,2], target = 0 +输出:4 +``` + +示例 2: +``` +输入:nums = [4,5,6,7,0,1,2], target = 3 +输出:-1 +``` + + + + + + + + + diff --git a/9 Algorithms Job Interview/7 二叉树.md b/9 Algorithms Job Interview/7 二叉树.md index 1bc6d32..58bac03 100644 --- a/9 Algorithms Job Interview/7 二叉树.md +++ b/9 Algorithms Job Interview/7 二叉树.md @@ -107,8 +107,7 @@ TreeNode invertTree(TreeNode root) { - -## 二叉树两个结点的最低共同父结点 +## 二叉树两个结点的最低共同父结点 (最近公共祖先) 设计一个算法,找出二叉树上任意两个结点的最近共同父结点。复杂度如果是O(n2)则不得分 @@ -119,6 +118,9 @@ TreeNode invertTree(TreeNode root) { + + + ## 求一个二叉树中任意两个节点间的最大距离 两个节点的距离的定义是 这两个节点间边的个数,比如某个孩子节点和父节点间的距离是1,和相邻兄弟节点间的距离是2,优化时间空间复杂度。 diff --git a/9 Algorithms Job Interview/7.1 二叉树-遍历.md b/9 Algorithms Job Interview/7.1 二叉树-遍历.md index f072186..c98ae50 100644 --- a/9 Algorithms Job Interview/7.1 二叉树-遍历.md +++ b/9 Algorithms Job Interview/7.1 二叉树-遍历.md @@ -49,13 +49,30 @@ 分析:这道题本质上还是考查二元树的遍历。对于一颗完全二叉树,要求给所有节点加上一个pNext指针,指向同一层的相邻节点;如果当前节点已经是该层的最后一个节点,则将pNext指针指向NULL;给出程序实现,并分析时间复杂度和空间复杂度。 +## 二元树的最小深度 + + +例如:输入二元树: +``` + + 10 + / \ + 6 14 + / \ + 12 16 +``` + +输出该树的最小深度2。 + + ## 判断整数序列是不是二元查找树的后序遍历结果 题目:输入一个整数数组,判断该数组是不是某二元查找树的后序遍历的结果。 如果是返回true,否则返回false。 -例如输入5、7、6、9、11、10、8,由于这一整数序列是如下树的后序遍历结果: + +例如输入`5、7、6、9、11、10、8`,由于这一整数序列是如下树的后序遍历结果: ``` 8 / \ @@ -66,3 +83,9 @@ 因此返回true。如果输入7、4、6、5,没有哪棵树的后序遍历的结果是这个序列,因此返回false。 + + + + + + diff --git a/9 Algorithms Job Interview/7.5 二叉搜索树.md b/9 Algorithms Job Interview/7.5 二叉搜索树.md new file mode 100644 index 0000000..31b323c --- /dev/null +++ b/9 Algorithms Job Interview/7.5 二叉搜索树.md @@ -0,0 +1,27 @@ +# 二叉搜索树 + +关于二叉查找树特性[参考这里](../4%20Tree/2-二叉查找树/二叉查找树.md) + +## 验证二叉搜索树 + + +## 二叉搜索树中的节点搜索 + + +## 二叉搜索树中的插入操作 + + +## 删除二叉搜索树中的节点 + + + + + + + + + + + + + From 363cf82d546f0c1037394a86c68ff4c1f9c8d3da Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Mon, 15 Nov 2021 01:20:46 +0800 Subject: [PATCH 34/50] update dp and tree --- 4 Tree/2-二叉查找树/二叉查找树.md | 2 +- 8 Algorithms Analysis/动态规划.md | 19 +++++--- 8 Algorithms Analysis/贪心算法.md | 16 ++++--- 8 Algorithms Analysis/递归.md | 48 +++++++++++++++++-- 9 Algorithms Job Interview/5 数组数列问题.md | 2 - 9 Algorithms Job Interview/7.1 二叉树-遍历.md | 6 +++ 6 files changed, 73 insertions(+), 20 deletions(-) diff --git a/4 Tree/2-二叉查找树/二叉查找树.md b/4 Tree/2-二叉查找树/二叉查找树.md index 3ce4c39..6e5ce4f 100644 --- a/4 Tree/2-二叉查找树/二叉查找树.md +++ b/4 Tree/2-二叉查找树/二叉查找树.md @@ -10,7 +10,7 @@ 4. 没有键值(key)相等的节点 -有序的二叉查找树,中序遍历结果是递增的。 +有序的二叉查找树,中序遍历结果是递增的。 `左小右大` ``` diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index c2ff383..eaeef85 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -24,21 +24,22 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 * Fibonacci数列 [代码参考这里 递归](./递归.md) * 凑零钱问题 * 股票问题 [代码参考这里](https://github.com/nonstriater/deep-in-java/blob/master/src/main/java/com/nonstriater/deepinjava/algo/list/stock/BestChance.java) -* 二叉树的最近公共祖先 [代码参考这里](https://github.com/nonstriater/deep-in-java/blob/master/src/main/java/com/nonstriater/deepinjava/algo/tree/CommonParent.java) -* 链表翻转 [代码参考这里](https://github.com/nonstriater/deep-in-java/blob/master/src/main/java/com/nonstriater/deepinjava/algo/link/ReverseLink.java) -* 接雨水问题 +* 打家劫舍问题 : num[i] 代表第i个房子中的现金数目,从房子中取钱的最大数目,约束是相邻房子的钱不能同时取出 +* 接雨水问题 : * 青蛙跳阶问题: 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。 * 最小编辑距离 -* 最长递增子序列 (LIS Longest Increasing Subsequence) +* 最长递增子序列 (LIS Longest Increasing Subsequence),如`【5,6,7,3,2,8】` 最长子序列 `【5,6,7,8】`, 输出4 +* 最大子数组和 +* 最长公共子序列 (LIS Longest public Subsequence) +* 最长回文子序列 (LIS Longest public Subsequence) * 0-1 背包问题 - [更多动态规划案例代码实现参考deep-in-java])(https://github.com/nonstriater/deep-in-java/tree/master/src/main/java/com/nonstriater/deepinjava/algo/framework/dynamic) +青蛙跳阶问题 ``` -# 青蛙跳阶问题 想跳到第10级台阶,要么是先跳到第9级,然后再跳1级台阶上去;要么是先跳到第8级,然后一次迈2级台阶上去。 同理,要想跳到第9级台阶,要么是先跳到第8级,然后再跳1级台阶上去;要么是先跳到第7级,然后一次迈2级台阶上去。 要想跳到第8级台阶,要么是先跳到第7级,然后再跳1级台阶上去;要么是先跳到第6级,然后一次迈2级台阶上去 @@ -53,6 +54,10 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 ``` + + + + ### DP VS 分治法 与[分治法](分治算法.md)不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。 @@ -93,7 +98,7 @@ for 状态1 in 状态1的所有取值: ## 凑零钱问题 -凑零钱问题[视频解读参考这里]() +凑零钱问题[视频解读参考这里](https://www.ixigua.com/6881883015832666635?wid_try=1) 如果使用贪心策略,并不能得到最优解。 diff --git a/8 Algorithms Analysis/贪心算法.md b/8 Algorithms Analysis/贪心算法.md index f5ac09d..400c5dd 100644 --- a/8 Algorithms Analysis/贪心算法.md +++ b/8 Algorithms Analysis/贪心算法.md @@ -3,13 +3,17 @@ 不追求最优解,只找到满意解。 -#### 赫夫曼编码 - - - #### 其它案例 -找回零钱问题 -装箱问题 +* 跳跃游戏 +* 射击气球 +* 装箱问题 + +## 赫夫曼编码 + + + + + diff --git a/8 Algorithms Analysis/递归.md b/8 Algorithms Analysis/递归.md index 94f9d3f..7f6b53f 100644 --- a/8 Algorithms Analysis/递归.md +++ b/8 Algorithms Analysis/递归.md @@ -15,6 +15,7 @@ 递归运行效率较低,因为有函数调用的开销,递归多次也可能造成栈溢出。 + ### 递归公式 [快排](../6%20Sort/README.md) @@ -72,11 +73,12 @@ void traverse(TreeNode root) { ### 其它案例 +* 斐波那契数列 * 阶乘计算 -* 梵塔问题 (三根针1,2,3表示,1号从小到大n个盘子,先要都移到3号上,不能出现大盘压小盘,找出移动次数最少的方案) -* 快速排序 -* 很多树算法都是递归思想实现 - +* 快速排序 +* 链表翻转 +* 很多树算法都是递归思想实现, 如 二叉树的最近公共祖先 +* 梵塔问题 (三根针1,2,3表示,1号从小到大n个盘子,先要都移到3号上,不能出现大盘压小盘,找出移动次数最少的方案) ## 斐波那契数列 @@ -196,6 +198,44 @@ public static LinkedNode mergeSeqLink(LinkedNode l1, LinkedNode l2){ +## 链表翻转 + + +链表翻转 [代码参考这里](https://github.com/nonstriater/deep-in-java/blob/master/src/main/java/com/nonstriater/deepinjava/algo/link/ReverseLink.java) + + +```Java +//翻转链表前n个节点 + static LinkedNode tmp;//需要一个外部的临时变量 + public static LinkedNode reverseN(LinkedNode head, int n){ + //LinkedNode tmp = null; + if (n == 1) { + tmp = head.next; + return head; + } + + LinkedNode tail = reverseN(head.next, n-1); + + head.next.next = head; //后n-1个节点 与 第 1 个节点 指向 翻转 + head.next = tmp; + + return tail; + } + +``` + + + +## 二叉树的最近公共祖先 + +二叉树的最近公共祖先 [代码参考这里](https://github.com/nonstriater/deep-in-java/blob/master/src/main/java/com/nonstriater/deepinjava/algo/tree/CommonParent.java) + + +```Java + +``` + + diff --git a/9 Algorithms Job Interview/5 数组数列问题.md b/9 Algorithms Job Interview/5 数组数列问题.md index 65b823d..e2b4756 100644 --- a/9 Algorithms Job Interview/5 数组数列问题.md +++ b/9 Algorithms Job Interview/5 数组数列问题.md @@ -80,8 +80,6 @@ int fib(int n) { - - ## 递减数列左移后的数组中找数 一个数组是由一个递减数列左移若干位形成的,比如{4,3,2,1,6,5} diff --git a/9 Algorithms Job Interview/7.1 二叉树-遍历.md b/9 Algorithms Job Interview/7.1 二叉树-遍历.md index c98ae50..d4d513d 100644 --- a/9 Algorithms Job Interview/7.1 二叉树-遍历.md +++ b/9 Algorithms Job Interview/7.1 二叉树-遍历.md @@ -66,6 +66,12 @@ +## 完全二叉树的节点个数 + + + + + ## 判断整数序列是不是二元查找树的后序遍历结果 From 4a31531cf6ff7f938f785ce010b5a449edc91227 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Mon, 15 Nov 2021 01:22:38 +0800 Subject: [PATCH 35/50] =?UTF-8?q?Update=20=E9=80=92=E5=BD=92.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 8 Algorithms Analysis/递归.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/8 Algorithms Analysis/递归.md b/8 Algorithms Analysis/递归.md index 7f6b53f..0374c7f 100644 --- a/8 Algorithms Analysis/递归.md +++ b/8 Algorithms Analysis/递归.md @@ -233,6 +233,24 @@ public static LinkedNode mergeSeqLink(LinkedNode l1, LinkedNode l2){ ```Java +TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + // base case + if (root == null) return null; + if (root == p || root == q) return root; + + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + // 情况 1 + if (left != null && right != null) { + return root; + } + // 情况 2 + if (left == null && right == null) { + return null; + } + // 情况 3 + return left == null ? right : left; +} ``` From ec09f22df47b904bbd38c3e8e9ba234acc679f2c Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Mon, 15 Nov 2021 01:29:08 +0800 Subject: [PATCH 36/50] update tree --- 8 Algorithms Analysis/递归.md | 31 +++++++++++++------------- 9 Algorithms Job Interview/7 二叉树.md | 20 +++++++++++++++++ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/8 Algorithms Analysis/递归.md b/8 Algorithms Analysis/递归.md index 0374c7f..761ed1e 100644 --- a/8 Algorithms Analysis/递归.md +++ b/8 Algorithms Analysis/递归.md @@ -232,25 +232,24 @@ public static LinkedNode mergeSeqLink(LinkedNode l1, LinkedNode l2){ ```Java - TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { - // base case - if (root == null) return null; - if (root == p || root == q) return root; + // base case + if (root == null) return null; + if (root == p || root == q) return root; - TreeNode left = lowestCommonAncestor(root.left, p, q); - TreeNode right = lowestCommonAncestor(root.right, p, q); - // 情况 1 - if (left != null && right != null) { - return root; + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + // 情况 1 :p, q 在 root 为根的树中 + if (left != null && right != null) { + return root; + } + // 情况 2 :p, q 不在 在 root 为根的树中 + if (left == null && right == null) { + return null; + } + // 情况 3 : p, q 只有1个在root 为根的树中 + return left == null ? right : left; } - // 情况 2 - if (left == null && right == null) { - return null; - } - // 情况 3 - return left == null ? right : left; -} ``` diff --git a/9 Algorithms Job Interview/7 二叉树.md b/9 Algorithms Job Interview/7 二叉树.md index 58bac03..28bcff2 100644 --- a/9 Algorithms Job Interview/7 二叉树.md +++ b/9 Algorithms Job Interview/7 二叉树.md @@ -117,6 +117,26 @@ TreeNode invertTree(TreeNode root) { 分析:求数中两个结点的最低共同结点是面试中经常出现的一个问题。这个问题至少有两个变种。 +``` +TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + // base case + if (root == null) return null; + if (root == p || root == q) return root; + + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + // 情况 1 :p, q 在 root 为根的树中 + if (left != null && right != null) { + return root; + } + // 情况 2 :p, q 不在 在 root 为根的树中 + if (left == null && right == null) { + return null; + } + // 情况 3 : p, q 只有1个在root 为根的树中 + return left == null ? right : left; + } +``` From 81e6ec3f533d1f8626c3d5995436c6a8931601a2 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Mon, 15 Nov 2021 01:44:14 +0800 Subject: [PATCH 37/50] update dp --- 8 Algorithms Analysis/动态规划.md | 27 +++++++++++++-- 9 Algorithms Job Interview/1.1 字符串-查找.md | 33 ++++++++++++++++++- .../5.2 数列-nsum问题.md | 3 +- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index eaeef85..a034b8b 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -25,7 +25,7 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 * 凑零钱问题 * 股票问题 [代码参考这里](https://github.com/nonstriater/deep-in-java/blob/master/src/main/java/com/nonstriater/deepinjava/algo/list/stock/BestChance.java) * 打家劫舍问题 : num[i] 代表第i个房子中的现金数目,从房子中取钱的最大数目,约束是相邻房子的钱不能同时取出 -* 接雨水问题 : +* 接雨水问题 :num[i]表示柱子高度,计算下雨之后能接多少雨水 * 青蛙跳阶问题: 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。 * 最小编辑距离 * 最长递增子序列 (LIS Longest Increasing Subsequence),如`【5,6,7,3,2,8】` 最长子序列 `【5,6,7,8】`, 输出4 @@ -56,8 +56,6 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 - - ### DP VS 分治法 与[分治法](分治算法.md)不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。 @@ -105,6 +103,29 @@ for 状态1 in 状态1的所有取值: ```Java +//递归解法,处理重叠子问题, 使用 dp[amount+1] 备忘录 + int coinChange2(int[] coins, int amount) { + int[] dp = new int[amount + 1]; + + // 数组大小为 amount + 1,初始值也为 amount + 1 + // 为啥 dp 数组初始化为 amount + 1 呢,因为凑成 amount 金额的硬币数最多只可能等于 amount(全用 1 元面值的硬币),所以初始化为 amount + 1 就相当于初始化为正无穷 + Arrays.fill(dp, amount + 1); + + // base case + dp[0] = 0; + // 外层 for 循环在遍历所有状态的所有取值 + for (int i = 0; i < dp.length; i++) { + // 内层 for 循环在求所有选择的最小值 + for (int coin : coins) { + // 子问题无解,跳过 + if (i - coin < 0) { + continue; + } + dp[i] = Math.min(dp[i], 1 + dp[i - coin]); + } + } + return (dp[amount] == amount + 1) ? -1 : dp[amount]; + } ``` diff --git a/9 Algorithms Job Interview/1.1 字符串-查找.md b/9 Algorithms Job Interview/1.1 字符串-查找.md index c7b6aa9..18e9d22 100644 --- a/9 Algorithms Job Interview/1.1 字符串-查找.md +++ b/9 Algorithms Job Interview/1.1 字符串-查找.md @@ -193,7 +193,7 @@ int longest_common_subsequence(const char *s1,const char *s2, char *common){ ``` -## 对称子字符串的最大长度 +## 对称子字符串的最大长度 (最长回文子串) 题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。 @@ -215,6 +215,37 @@ int max_symmetrical_char_length(const char *scr){ ``` +```Java + public String longestPalindrome(String s) { + String res = ""; + for (int i = 0; i < s.length(); i++) { + // 以 s[i] 为中心的最长回文子串 + String s1 = palindrome(s, i, i); + + // 以 s[i] 和 s[i+1] 为中心的最长回文子串 + String s2 = palindrome(s, i, i + 1); + + // res = longest(res, s1, s2) + res = res.length() > s1.length() ? res : s1; + res = res.length() > s2.length() ? res : s2; + } + return res; + } + + //实现一个函数来寻找最长回文串 + String palindrome(String s, int l, int r) { + // 防止索引越界 + while (l >= 0 && r < s.length() + && s.charAt(l) == s.charAt(r)) { + // 向两边展开 + l--; r++; + } + // 返回以 s[l] 和 s[r] 为中心的最长回文串 + return s.substring(l + 1, r); + } +``` + + ## 子串匹配的个数 diff --git a/9 Algorithms Job Interview/5.2 数列-nsum问题.md b/9 Algorithms Job Interview/5.2 数列-nsum问题.md index 895026f..d76c014 100644 --- a/9 Algorithms Job Interview/5.2 数列-nsum问题.md +++ b/9 Algorithms Job Interview/5.2 数列-nsum问题.md @@ -81,7 +81,6 @@ int findaddends(int *data,int length,int sum,int *a,int *b); - ## 求子数组的最大和(最大字段和) 输入一个整形数组,数组里有正数也有负数。 @@ -91,7 +90,7 @@ int findaddends(int *data,int length,int sum,int *a,int *b); 例如输入的数组为`1, -2, 3, 10, -4, 7, 2, -5` ,和最大的子数组为`3, 10, -4, 7, 2` ,因此输出为该子数组的和18。 1. 蛮力法 fmax(i,j) 找出最大的值,3重循环 ,复杂度 0(n^3) -2. maxendindhere保存当前累加的和,如果<0,就把maxendinghere清零 , max保存最终的最大和; 如果都是负数 +2. `动态规划` maxendindhere保存当前累加的和,如果<0, 就把maxendinghere清零 , max保存最终的最大和; 如果都是负数 ``` int maxSumOfVector(int *data,int length){ From 067187ee33a91fc38e760dd50a6aac8f0a5d5cc0 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Mon, 15 Nov 2021 01:46:49 +0800 Subject: [PATCH 38/50] update readme --- 9 Algorithms Job Interview/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index 457416a..3dbf57b 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -18,6 +18,7 @@ * 数组,字符串问题:二分查找、 快慢指针、 左右指针、 滑动窗口、 前缀和数组、 差分数组。 * 二叉树问题:递归 * [动态规划问题](../8%20Algorithms%20Analysis/动态规划.md) +* [常见算法题目Java实现](https://github.com/nonstriater/deep-in-java/tree/master/src/main/java/com/nonstriater/deepinjava/algo) ## [字符串](1%20字符串.md) From 15d5934f07f29af622d43dd2d05c937f2d640b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Wed, 17 Nov 2021 01:32:45 +0800 Subject: [PATCH 39/50] Update README.md --- 1 String/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1 String/README.md b/1 String/README.md index 07353c5..620f262 100644 --- a/1 String/README.md +++ b/1 String/README.md @@ -25,7 +25,7 @@ ## 滑动窗口 -使用滑动窗口解决字符串问题,代码框架 +使用滑动窗口解决字符串子串问题,代码框架 ``` int left = 0, right = 0; From 10184a3450059869a45c36b81b13836468e5d059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=BC=80=E5=8F=91=E5=B0=8F=E5=86=89?= <510495266@qq.com> Date: Wed, 17 Nov 2021 01:33:09 +0800 Subject: [PATCH 40/50] Create README.md From b0c67229b3ee7afaab7d983d1ee8ae2e240171fb Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Sat, 27 Nov 2021 02:15:19 +0800 Subject: [PATCH 41/50] add link --- 2 List/README.md | 33 ++++-- 4 Tree/9-红黑树 R-B tree/红黑树.md | 2 +- 9 Algorithms Job Interview/1 字符串.md | 8 +- 9 Algorithms Job Interview/1.1 字符串-查找.md | 39 ++++--- 9 Algorithms Job Interview/2 链表.md | 13 ++- 9 Algorithms Job Interview/5.1 数列-排序.md | 2 - 9 Algorithms Job Interview/5.4 数列-查找.md | 27 ++++- 9 Algorithms Job Interview/README.md | 105 +++++++++--------- README.md | 33 +++--- 9 files changed, 160 insertions(+), 102 deletions(-) diff --git a/2 List/README.md b/2 List/README.md index a8a29af..796ae89 100644 --- a/2 List/README.md +++ b/2 List/README.md @@ -4,6 +4,7 @@ * 双向链表 * 双向循环链表 + ## 链表 ### 应用场景 @@ -11,18 +12,6 @@ * [redis slowlog](Redis%20slowlog.md) -### 扩缩容 - -简单说下编程语言 java, golang中 LinkList的扩缩容的策略。 - -java 中扩容,每次扩容新增原先容量的 1/2 -``` - int newCapacity = oldCapacity + (oldCapacity >> 1); -``` - -这个就不介绍了。重点说下双向链表。 - - ### 链表 VS 数组 特点 @@ -38,12 +27,27 @@ java 中扩容,每次扩容新增原先容量的 1/2 +### 扩缩容 + +简单说下编程语言 java, golang中 LinkList的扩缩容的策略。 + +java 中扩容,每次扩容新增原先容量的 1/2 +``` + int newCapacity = oldCapacity + (oldCapacity >> 1); +``` + +这个就不介绍了。重点说下双向链表。 + + + ## 双向链表 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。 双向链表克服了单链表中访问某个节点前驱节点(插入,删除操作时),只能从头遍历的问题。 +缺点是: 多了1倍的额外的指针空间大小。 + ``` typedef int Value typedef struct Entry{ @@ -53,6 +57,11 @@ typedef struct Entry{ ``` +应用场景 + +* mysql B+树 叶子节点就使用 双向链表,方便 `age<10` 类似条件查询,或者 倒序查询 如 `order by desc` ,从后向前遍历数据 + + ## 循环链表 最后一个节点指针指向头节点的链表 diff --git a/4 Tree/9-红黑树 R-B tree/红黑树.md b/4 Tree/9-红黑树 R-B tree/红黑树.md index ff83a6d..48aa007 100644 --- a/4 Tree/9-红黑树 R-B tree/红黑树.md +++ b/4 Tree/9-红黑树 R-B tree/红黑树.md @@ -1,6 +1,6 @@ # 红黑树 (red-black tree) -红黑树(Red Black Tree) 是一种自平衡二叉查找树。一种特化的AVL树,在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。 它可以在O(log n)时间内做查找,插入和删除。 +红黑树(Red Black Tree) 是一种自平衡二叉查找树。一种特化的[AVL树](../3-平衡树AVL/README.md),在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。 它可以在O(log n)时间内做查找,插入和删除。 它的每个结点都被“着色”为红色或者黑色,这些结点的颜色被用来检测树的平衡性。 diff --git a/9 Algorithms Job Interview/1 字符串.md b/9 Algorithms Job Interview/1 字符串.md index 1f67dc4..47565ce 100644 --- a/9 Algorithms Job Interview/1 字符串.md +++ b/9 Algorithms Job Interview/1 字符串.md @@ -4,11 +4,13 @@ * 回文判断 * 字符(串)统计 +* [子串查找](1.1%20字符串-查找.md) +* [字符串修改](1.3%20字符串-修改.md) 如单词反转/移动等 +* [字符删除](1.2%20字符串-删除.md) * 字符串的压缩 * 字符串的排列和组合 -* [子串查找](1.1%20字符串-查找.md) -* [字符删除](1.2%20字符串-删除.md) -* [字符串修改](1.3%20字符串-修改.md) 如单词反转/移动等 + + ## 判断字符串是否是回文 diff --git a/9 Algorithms Job Interview/1.1 字符串-查找.md b/9 Algorithms Job Interview/1.1 字符串-查找.md index 18e9d22..7618a01 100644 --- a/9 Algorithms Job Interview/1.1 字符串-查找.md +++ b/9 Algorithms Job Interview/1.1 字符串-查找.md @@ -45,19 +45,6 @@ char char_first_appear_once(const unsigned char *source){ 题目扩展:这里的字符换成整数,整数数量几十TB,海量数据处理,显然hash方法不可能,没有那么大得内容 -## 请编写能直接实现strstr()函数功能的代码。 - -> strstr(str1,str2) 判断str2是否是str1的子串。 - -``` -/* -@ret 有就返回第一次出现子串的地址,否则返回NULL -*/ -char *strstr(const char *source, const char *target){ - -} -``` - ### 字符串中找出连续最长的数字子串 @@ -164,11 +151,6 @@ int lengthOfLongestSubstring(string s) { -## 求最大连续递增数字子串 - -如“ads3sl456789DF3456ld345AA”中的“456789”就是所求。这道题在上一道题目的基础上增加了数字要递增的条件。思路跟上面差不多,碰到不递增的数字就相当于第二个数字串了。 - - ## 最长公共子串问题 @@ -247,6 +229,27 @@ int max_symmetrical_char_length(const char *scr){ + +## 求最大连续递增数字子串 + +如“ads3sl456789DF3456ld345AA”中的“456789”就是所求。这道题在上一道题目的基础上增加了数字要递增的条件。思路跟上面差不多,碰到不递增的数字就相当于第二个数字串了。 + + +## 请编写能直接实现strstr()函数功能的代码。 + +> strstr(str1,str2) 判断str2是否是str1的子串。 + +``` +/* +@ret 有就返回第一次出现子串的地址,否则返回NULL +*/ +char *strstr(const char *source, const char *target){ + +} +``` + + + ## 子串匹配的个数 已知一个字符串,比如asderwsde,寻找其中的一个子字符串比如sde的个数,如果没有返回0,有的话返回子字符串的个数。 diff --git a/9 Algorithms Job Interview/2 链表.md b/9 Algorithms Job Interview/2 链表.md index 4cf7da9..e1fe717 100644 --- a/9 Algorithms Job Interview/2 链表.md +++ b/9 Algorithms Job Interview/2 链表.md @@ -10,12 +10,14 @@ * 链表中是否有环 -链表结点定义如下: +链表结点定义如下: +``` struct ListNode { int m_nKey; ListNode* m_pNext; }; +``` @@ -110,6 +112,15 @@ struct ComplexNode 请完成函数`ComplexNode* Clone(ComplexNode* pHead)`,以复制一个复杂链表。 +这个题目难点在于: + + + + + + + + diff --git a/9 Algorithms Job Interview/5.1 数列-排序.md b/9 Algorithms Job Interview/5.1 数列-排序.md index c4d2950..b01a548 100644 --- a/9 Algorithms Job Interview/5.1 数列-排序.md +++ b/9 Algorithms Job Interview/5.1 数列-排序.md @@ -25,8 +25,6 @@ void sort(int * a, int length) `动态规划` - - ## 扑克牌的顺子 diff --git a/9 Algorithms Job Interview/5.4 数列-查找.md b/9 Algorithms Job Interview/5.4 数列-查找.md index 48bd250..ac9bd9b 100644 --- a/9 Algorithms Job Interview/5.4 数列-查找.md +++ b/9 Algorithms Job Interview/5.4 数列-查找.md @@ -87,13 +87,38 @@ topMaxK(int *a,int length, int k); ## 找第k大的数 -比如 1,2,3,4,5,6,7和8这8个数字,低3大的数字是 6 +比如 `1,2,3,4,5,6,7,8 `这 8个数字,第3大的数字是 6 ``` int topK(int * a, int length, int k) ``` +```Java +//冒泡实现 + public int findK(int[] nums, int k){ + //base case + if (nums== null || nums.length < k) { + return -1; + } + + for(int i=1; i<=k; i++){ + for(int j=0; j nums[next]){ + int tmp = nums[j]; + nums[j] = nums[next]; + nums[next] = tmp; + } + } + } + + return nums[nums.length-k]; + } +``` + + + ## 最长公共子序列 (动态规划的经典题目) diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index 3dbf57b..99db4ec 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -13,7 +13,7 @@ * 编程细节:多练习,总结 -常用解题套路工具 +## 常用解题套路工具 * 数组,字符串问题:二分查找、 快慢指针、 左右指针、 滑动窗口、 前缀和数组、 差分数组。 * 二叉树问题:递归 @@ -21,6 +21,59 @@ * [常见算法题目Java实现](https://github.com/nonstriater/deep-in-java/tree/master/src/main/java/com/nonstriater/deepinjava/algo) +## 刷题框架套路 + + +遍历 + +``` +# 数组遍历框架 +void traverse(int[] arr) { + for (int i = 0; i < arr.length; i++) { + // 迭代访问 arr[i] + } +} + +# 链表遍历框架 +void traverse(ListNode head) { + for (ListNode p = head; p != null; p = p.next) { + // 迭代访问 p.val + } +} + +``` + + +递归 + +``` +# 链表递归 +void traverse(ListNode head) { + // 递归访问 head.val + traverse(head.next); +} + + +# 二叉树递归 +void traverse(TreeNode root) { + traverse(root.left); + traverse(root.right); +} + +# 多叉树递归 +void traverse(TreeNode root) { + for (TreeNode child : root.children) + traverse(child); +} + +# 图的递归:,用个布尔数组 visited 做标记就行了 + +``` + + + + + ## [字符串](1%20字符串.md) 计算机处理的数据除了数值,就是字符。字符处理的常见问题包括: @@ -95,56 +148,6 @@ -# 刷题框架套路 - -遍历 - -``` -# 数组遍历框架 -void traverse(int[] arr) { - for (int i = 0; i < arr.length; i++) { - // 迭代访问 arr[i] - } -} - -# 链表遍历框架 -void traverse(ListNode head) { - for (ListNode p = head; p != null; p = p.next) { - // 迭代访问 p.val - } -} - -``` - - -递归 - -``` -# 链表递归 -void traverse(ListNode head) { - // 递归访问 head.val - traverse(head.next); -} - - -# 二叉树递归 -void traverse(TreeNode root) { - traverse(root.left); - traverse(root.right); -} - -# 多叉树递归 -void traverse(TreeNode root) { - for (TreeNode child : root.children) - traverse(child); -} - -# 图的递归:,用个布尔数组 visited 做标记就行了 - - -``` - - # 参考 diff --git a/README.md b/README.md index e3d6f0f..ce25ff7 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ * 链表 * 双向链表 +### [数组](2%20List/README.md) + +* [数组数列问题](%20Algorithms%20Job%20Interview/5%20数组数列问题.md) + 数组和链表结构是基础结构,散列表、栈、队列、堆、树、图等等各种数据结构都基于数组和链表结构实现。 ### [队列](2%20Queue/README.md) @@ -36,13 +40,13 @@ ### [字符串算法](1%20String/README.md) -* 排序 -* 查找 +* 子串查找 [字符串常见题目参考这里](%20Algorithms%20Job%20Interview/1%20字符串.md) * BF算法 * KMP算法 * BM算法 * 正则表达式 * 数据压缩 +* 排序 ### [树](4%20Tree/README.md) @@ -92,22 +96,25 @@ ### [查找算法](7%20Search/README.md) -* 顺序表查找:顺序查找 -* 有序表查找:二分查找 + +* 哈希表: O(1) [hashtable实现参考这里](../3%20Hash%20Table/README.md) +* 有序表查找:二分查找 +* 顺序表查找:顺序查找, 复杂度O(N) * 分块查找: 块内无序,块之间有序;可以先二分查找定位到块,然后再到`块`中顺序查找 * 动态查找: 二叉排序树,AVL树,B- ,B+(这里之所以叫 `动态查找表`,是因为表结构是查找的过程中动态生成的) -* 哈希表: O(1) + ## [算法设计思想](8%20Algorithms%20Analysis/README.md) - -* 迭代法 -* 穷举搜索法 -* 递推法 -* 动态规划 -* 贪心算法 -* 回溯 -* 分治算法 + + +* [递归](8%20Algorithms%20Analysis/递归.md) +* [分治算法](8%20Algorithms%20Analysis/分治算法.md) +* [动态规划](8%20Algorithms%20Analysis/动态规划.md) +* [回溯法](8%20Algorithms%20Analysis/回溯法.md) +* [迭代法](8%20Algorithms%20Analysis/迭代法.md) +* [穷举搜索法](8%20Algorithms%20Analysis/穷举搜索法.md) +* [贪心算法](8%20Algorithms%20Analysis/贪心算法.md) From 0b2fb94f5ad0c813fd8d51cf27f8963dad95a317 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Sat, 27 Nov 2021 02:32:30 +0800 Subject: [PATCH 42/50] add link --- 9 Algorithms Job Interview/README.md | 67 ++++++++++++++++++++++++++-- README.md | 25 +++++------ 2 files changed, 75 insertions(+), 17 deletions(-) diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index 99db4ec..779c80f 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -24,7 +24,7 @@ ## 刷题框架套路 -遍历 +### 遍历 ``` # 数组遍历框架 @@ -41,12 +41,21 @@ void traverse(ListNode head) { } } -``` +void traverse(ListNode head) { - -递归 + ListNode p = head; + while(p.next != null) + ... + p = p.next + +} ``` + + +### 递归 + +```Java # 链表递归 void traverse(ListNode head) { // 递归访问 head.val @@ -71,6 +80,56 @@ void traverse(TreeNode root) { ``` +### 二分查找 + +```Java +public int bsearch(int[] nums, int target){ + + if(nums == null) { + return -1; + } + + int low = 0; + int high = nums.length; + + while(low < high){ + middle = (high + low ) / 2; + if(nums[middle] < target){ + low = middle; + } else if (nums[middle] == target) { + high = middle;// + } else { + high = middle; + } + } + + return low; + } +``` + +### 滑动窗口 + +```Java + + +``` + + +### 排序算法 + +[排序算法](../6%20Sort/README.md) + +```Java + +#快排 quickSort + + + +#归并排序 mergeSort + + + +``` diff --git a/README.md b/README.md index ce25ff7..a8e561b 100644 --- a/README.md +++ b/README.md @@ -51,20 +51,19 @@ ### [树](4%20Tree/README.md) -* 二叉树 -* 二叉查找树 -* 伸展树(splay tree 分裂树) -* 平衡二叉树AVL -* 红黑树 -* B树,B+,B* -* R树 -* Trie树(前缀树) -* 后缀树 -* 最优二叉树(赫夫曼树) -* 二叉堆 (大根堆,小根堆) -* 二项树 -* 二项堆 +* 二叉树 [快速排序](6%20Sort/README.md)就是个二叉树的前序遍历,归并排序就是个二叉树的后序遍历 +* [二叉查找树BST](4%20Tree/2-二叉查找树/二叉查找树.md) 有序的二叉树,中序遍历结果是递增的 +* [平衡二叉树 AVL树](4%20Tree/3-平衡树AVL/README.md) 绝对平衡二叉树; +* [红黑树](4%20Tree/9-红黑树%20R-B%20tree/红黑树.md) 弱平衡二叉树;使用广泛 +* [B树](4%20Tree/7-B树/B树.md) +* [B+树](4%20Tree/7-B树/B+树.md) mysql 索引使用 B+树 的数据结构 +* [字典树trie](4%20Tree/4-字典树Trie/README.md) 字典树也叫前缀树,单词查找树 +* [二叉堆](4%20Tree/8-堆/堆.md) +* [伸展树](4%20Tree/5-伸展树/伸展树.md) +* [后缀树](4%20Tree/6-后缀树/后缀树.md) * 斐波那契堆(Fibonacci Heap) +* 最优二叉树(赫夫曼树) + ### [图的算法](5%20Graph/README.md) From d97d7c491c19db264030b1f72d6d2d7f066e2875 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Sat, 27 Nov 2021 02:39:27 +0800 Subject: [PATCH 43/50] add algo frm --- 6 Sort/README.md | 15 ++++++++------- 9 Algorithms Job Interview/README.md | 22 ++++++++++++++++++++-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/6 Sort/README.md b/6 Sort/README.md index c598f11..8878542 100644 --- a/6 Sort/README.md +++ b/6 Sort/README.md @@ -14,7 +14,7 @@ * 归并排序 : 将无序的数组,分成2个子数组分别排序,然后再merge ; 分治递归, 二叉树的后续遍历思路 * 插入排序 : * 希尔排序 : -* 堆排序 : +* [堆排序](../4%20Tree/8-堆/堆.md) : ### 线性排序算法 @@ -71,7 +71,7 @@ 代码框架如下 -``` +```C void quicksort(int *a, int left, int right){ if (left Date: Mon, 29 Nov 2021 01:13:02 +0800 Subject: [PATCH 44/50] add frm --- 2 List/README.md | 5 ++ 9 Algorithms Job Interview/README.md | 102 +++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 12 deletions(-) diff --git a/2 List/README.md b/2 List/README.md index 796ae89..2ff036e 100644 --- a/2 List/README.md +++ b/2 List/README.md @@ -60,6 +60,7 @@ typedef struct Entry{ 应用场景 * mysql B+树 叶子节点就使用 双向链表,方便 `age<10` 类似条件查询,或者 倒序查询 如 `order by desc` ,从后向前遍历数据 +* Java AQS 中的等待队列, 是一个双端 双向链表 的结构 (FIFO 结构) ## 循环链表 @@ -78,3 +79,7 @@ typedef struct Entry{ + + + + diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index ab373fb..d703c67 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -35,12 +35,6 @@ void traverse(int[] arr) { } # 链表遍历框架 -void traverse(ListNode head) { - for (ListNode p = head; p != null; p = p.next) { - // 迭代访问 p.val - } -} - void traverse(ListNode head) { ListNode p = head; @@ -49,10 +43,10 @@ void traverse(ListNode head) { p = p.next } - ``` + ### 递归 ```Java @@ -79,10 +73,36 @@ void traverse(TreeNode root) { ``` +比如,二叉树的最近公共祖先 + +```Java +TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + // base case + if (root == null) return null; + if (root == p || root == q) return root; + + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + // 情况 1 :p, q 在 root 为根的树中 + if (left != null && right != null) { + return root; + } + // 情况 2 :p, q 不在 在 root 为根的树中 + if (left == null && right == null) { + return null; + } + // 情况 3 : p, q 只有1个在root 为根的树中 + return left == null ? right : left; + } +``` + ### 二分查找 +[查找算法](../7%20Search/README.md) + ```Java +// 1, 2, 2, 2, 2, 3 public int bsearch(int[] nums, int target){ if(nums == null) { @@ -90,16 +110,16 @@ public int bsearch(int[] nums, int target){ } int low = 0; - int high = nums.length; + int high = nums.length;// 注意 while(low < high){ middle = (high + low ) / 2; if(nums[middle] < target){ - low = middle; + low = middle + 1; } else if (nums[middle] == target) { - high = middle;// + high = middle;//继续向左早 } else { - high = middle; + high = middle; // 注意 , 这里没有 -1 } } @@ -107,11 +127,69 @@ public int bsearch(int[] nums, int target){ } ``` + +### 快慢指针 + +如下判断链表是否有环 + +``` +public static boolean hasCycle(LinkNode head) { + if(head == null) { + return false; + } + + LinkNode p = head, q = head; + while(p.next != null && p.next.next != null && q.next != null) { + p = p.next.next; + q = q.next; + if(p == q) { + return true; + } + } + return false; + } +``` + + +### 左右指针 + +``` + +``` + + ### 滑动窗口 +滑动窗口: 无重复字符的最长子串 + ```Java +public static int longestSubString(char[] s){ + int left = 0, right = 0; + int res = 0; // 记录最长结果 + Map window = new HashMap(); + while (right < s.length) { + Character c = s[right]; + + //窗口变大 + right++; + window.put(c, window.getOrDefault(c, 0) + 1); //java写的麻烦,不一定记得这个api + + if (window.get(c) > 1) { + //判断左侧窗口是否要收缩 + char d = s[left]; + + left ++; + window.put(d, window.get(d)-1); + } + + // 在这里更新答案 + res = res > (right-left) ? res: (right-left); + + } + return res; +} ``` @@ -126,7 +204,7 @@ void quicksort(int[] nums, int left, int right){ if (left Date: Mon, 29 Nov 2021 01:30:30 +0800 Subject: [PATCH 45/50] update string --- 1 String/java String.md | 3 +++ 9 Algorithms Job Interview/README.md | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/1 String/java String.md b/1 String/java String.md index bcf2e29..e84a90e 100644 --- a/1 String/java String.md +++ b/1 String/java String.md @@ -3,3 +3,6 @@ Java 中 String 实现。 + + + diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index d703c67..b2ce9c5 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -163,7 +163,7 @@ public static boolean hasCycle(LinkNode head) { 滑动窗口: 无重复字符的最长子串 ```Java - +//如 ”abcabbcbb“ 输出 3 public static int longestSubString(char[] s){ int left = 0, right = 0; int res = 0; // 记录最长结果 From 0de0504b9dcbd9ef61ad1c1f09a68ef1afe9dfa4 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Tue, 30 Nov 2021 23:50:23 +0800 Subject: [PATCH 46/50] add quicksort --- 6 Sort/README.md | 38 +++++++++++++++++++++++++++++++ 8 Algorithms Analysis/动态规划.md | 33 ++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/6 Sort/README.md b/6 Sort/README.md index 8878542..1ad64c2 100644 --- a/6 Sort/README.md +++ b/6 Sort/README.md @@ -143,6 +143,44 @@ void quicksort(int *a, int left, int right){ ``` +```Java +// pivot 选择 尾部节点, 代码写起来更加简单; 移动元素更方便 +static int partition(int[] nums, int left, int right){ + + int pivot = nums[right];//选尾部节点作为 pivot + int end = right; + + right--; + while (left < right) { + + if (nums[left] <= pivot) { + left ++ ; + continue; + } + + //元素比 pivot 大,右边窗口变小 + //swap left & right + swap(nums, left, right); + right--; + + } + + // 跟 pivot 元素置换 + int i = 0; + if (nums[left] <= pivot) { + //swap left+1 & pivot + i = left +1; + } else {//swap left & pivot + i = left ; + } + + swap(nums, i, end); + + return i; + } +``` + + ![](./qsort.gif) diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index a034b8b..66d3522 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -97,6 +97,7 @@ for 状态1 in 状态1的所有取值: ## 凑零钱问题 凑零钱问题[视频解读参考这里](https://www.ixigua.com/6881883015832666635?wid_try=1) +[实现代码这里](https://github.com/nonstriater/deep-in-java/tree/master/src/main/java/com/nonstriater/deepinjava/algo/list) 如果使用贪心策略,并不能得到最优解。 @@ -104,11 +105,12 @@ for 状态1 in 状态1的所有取值: ```Java //递归解法,处理重叠子问题, 使用 dp[amount+1] 备忘录 - int coinChange2(int[] coins, int amount) { + int coinChange2(int[] coins, int amount) { int[] dp = new int[amount + 1]; // 数组大小为 amount + 1,初始值也为 amount + 1 - // 为啥 dp 数组初始化为 amount + 1 呢,因为凑成 amount 金额的硬币数最多只可能等于 amount(全用 1 元面值的硬币),所以初始化为 amount + 1 就相当于初始化为正无穷 + // 为啥 dp 数组初始化为 amount + 1 呢? + // 因为凑成 amount 金额的硬币数最多只可能等于 amount(全用 1 元面值的硬币),所以初始化为 amount + 1 就相当于初始化为正无穷 Arrays.fill(dp, amount + 1); // base case @@ -125,11 +127,36 @@ for 状态1 in 状态1的所有取值: } } return (dp[amount] == amount + 1) ? -1 : dp[amount]; - } + } ``` +## 股票问题 + + +``` +``` + + +## 接雨水问题 + +num[i]表示柱子高度,计算下雨之后最多能接多少雨水 + + +``` +``` + + + + + + + + + + + From 21dfcedd7fab585e56d705a2a2b308d6c6562190 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Wed, 8 Dec 2021 03:49:19 +0800 Subject: [PATCH 47/50] update readme --- 2 List/数组.md | 15 ++++ 4 Tree/huffman tree/赫夫曼编码.md | 8 +- 6 Sort/README.md | 5 +- 8 Algorithms Analysis/动态规划.md | 115 ++++++++++++++++++++++++++- 9 Algorithms Job Interview/README.md | 42 +++++++++- README.md | 6 +- 6 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 2 List/数组.md diff --git a/2 List/数组.md b/2 List/数组.md new file mode 100644 index 0000000..f69c0b3 --- /dev/null +++ b/2 List/数组.md @@ -0,0 +1,15 @@ +# 数组 + +数据与链表差异 [参考这里](README.md) + + +## 循环数组 + + + + + + + + + diff --git a/4 Tree/huffman tree/赫夫曼编码.md b/4 Tree/huffman tree/赫夫曼编码.md index 624b6a5..c35c115 100644 --- a/4 Tree/huffman tree/赫夫曼编码.md +++ b/4 Tree/huffman tree/赫夫曼编码.md @@ -4,17 +4,21 @@ Huffman在1952年根据香农(Shannon)在1948年和范若(Fano)在1949 这是一个经典的压缩算法。通过`字符出现的频率`,`优先级`,`二叉树` 进行的压缩算法。 -对一个字符串,计算每个字符出现的次数,把这些字符放到优先队列(priority queue) -这这个priority queue转出二叉树 +对一个字符串,计算每个字符出现的次数, 把这些字符放到优先队列(priority queue); 这个priority queue转出二叉树 需要一个字符编码表来解码,通过二叉树建立huffman编码和解码的字典表 + +举一个例子: + 原始串: 二级制编码: huffman编码: + + ### 存储结构和基本操作 ``` diff --git a/6 Sort/README.md b/6 Sort/README.md index 1ad64c2..fd0ff97 100644 --- a/6 Sort/README.md +++ b/6 Sort/README.md @@ -145,6 +145,7 @@ void quicksort(int *a, int left, int right){ ```Java // pivot 选择 尾部节点, 代码写起来更加简单; 移动元素更方便 +// 左右指针技巧 static int partition(int[] nums, int left, int right){ int pivot = nums[right];//选尾部节点作为 pivot @@ -154,11 +155,11 @@ static int partition(int[] nums, int left, int right){ while (left < right) { if (nums[left] <= pivot) { - left ++ ; + left ++ ; //左边指针 窗口变小 continue; } - //元素比 pivot 大,右边窗口变小 + //元素比 pivot 大,右边指针 窗口变小 //swap left & right swap(nums, left, right); right--; diff --git a/8 Algorithms Analysis/动态规划.md b/8 Algorithms Analysis/动态规划.md index 66d3522..d9d708e 100644 --- a/8 Algorithms Analysis/动态规划.md +++ b/8 Algorithms Analysis/动态规划.md @@ -22,6 +22,7 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 动态规划的核心思想就是穷举求最值; 动态规划问题的一般形式就是`求最值`,动态规划其实是运筹学的一种最优化方法,只不过在计算机问题上应用比较多,比如说: * Fibonacci数列 [代码参考这里 递归](./递归.md) +* 最大子数组和 * 凑零钱问题 * 股票问题 [代码参考这里](https://github.com/nonstriater/deep-in-java/blob/master/src/main/java/com/nonstriater/deepinjava/algo/list/stock/BestChance.java) * 打家劫舍问题 : num[i] 代表第i个房子中的现金数目,从房子中取钱的最大数目,约束是相邻房子的钱不能同时取出 @@ -29,7 +30,7 @@ DP通常基于一个递推公式及一个(或多个)初始状态,当前子问 * 青蛙跳阶问题: 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 10 级的台阶总共有多少种跳法。 * 最小编辑距离 * 最长递增子序列 (LIS Longest Increasing Subsequence),如`【5,6,7,3,2,8】` 最长子序列 `【5,6,7,8】`, 输出4 -* 最大子数组和 + * 最长公共子序列 (LIS Longest public Subsequence) * 最长回文子序列 (LIS Longest public Subsequence) * 0-1 背包问题 @@ -75,7 +76,7 @@ DP 和 回溯法 都会用到递归 基本步骤 * 划分问题 -* 状态 +* 状态定义, 穷举「状态」, bad case * 状态转移方程, 这一步最为困难 ; 暴力解法就是状态转移方程 * 状态压缩 @@ -94,13 +95,96 @@ for 状态1 in 状态1的所有取值: +## 最大子数组和 + +示例: 输入:nums = [-2,1,-3,4,-1,2,1,-5,4],连续子数组 [4,-1,2,1] 的和最大, 输出:6 + + +dp[i] 表示 nums[i] 为结尾的「最大子数组和」; dp[n-1] 就是 nums 的「最大子数组和」 +状态转移 : `dp[i] = Math.max(nums[i], nums[i] + dp[i - 1]);` +状态压缩:注意到 dp[i] 仅仅和 dp[i-1] 的状态有关 + + +```Java +public static int largestSubSequenceSum2(int[] nums){ + + int n = nums.length; + if (n == 0) return 0; + + // base case + int dp_0 = nums[0]; + int dp_1 = 0; + int res = dp_0; + + for (int i = 1; i < n; i++) { + // dp[i] = max(nums[i], nums[i] + dp[i-1]) + dp_1 = Math.max(nums[i], nums[i] + dp_0); + dp_0 = dp_1; + + // 顺便计算最大的结果, 保存到 res + res = Math.max(res, dp_1); + } + + return res; + + } +``` + + ## 凑零钱问题 凑零钱问题[视频解读参考这里](https://www.ixigua.com/6881883015832666635?wid_try=1) -[实现代码这里](https://github.com/nonstriater/deep-in-java/tree/master/src/main/java/com/nonstriater/deepinjava/algo/list) +[实现代码这里](https://github.com/nonstriater/deep-in-java/tree/master/src/main/java/com/nonstriater/deepinjava/algo/framework/dynamic) 如果使用贪心策略,并不能得到最优解。 +比如:给定一个面值list : 1,2,4,5,7,10; 给定一个 target : 14, 求 凑齐 target=14 , 最少的零钱数量 + +思路: + +如想求 amount = 14 时的最少硬币数, + 如果你知道凑出 amount = 13 的最少硬币数(子问题), 再加 1 个 1元面值 即可 + 如果你知道凑出 amount = 12 的最少硬币数(子问题), 再加 1 个 2元面值 即可 + 如果你知道凑出 amount = 10 的最少硬币数(子问题), 再加 1 个 4元面值 即可 + 如果你知道凑出 amount = 9 的最少硬币数(子问题), 再加 1 个 5元面值 即可 + + +```Java +for (int coin : coins) { + // 计算子问题的结果 + int subProblem = dp(coins, amount - coin); + // 子问题无解则跳过 + if (subProblem == -1) continue; + + // 在子问题中选择最优解,然后加一 + res = Math.min(res, subProblem + 1); + } +``` + +通过备忘录消除子问题(不用递归了), dp 数组的定义:当目标金额为 i 时,至少需要 dp[i] 枚硬币凑出 +如想求 amount = 14 时的最少硬币数, dp[14] + dp[0] = 0 + dp[1] = 1 + dp[2] = 1个2元的,dp[1] + 1个1元 + ... + dp[9] = dp[8] + 1个1元, dp[7] + 1个2元, dp[5] + 1个4元, dp[4] + 1个5元,dp[2] + 1个7元 + 1 + dp[i-coin] 从这些可选项里选择最小的 + + +```Java +//对于 dp[i], 遍历可选项, 选择最小的 +for(int coin : coins) { + if (i < coin) { + continue; + } + + //dp[i] 保留最小的 + dp[i] = Math.min(dp[i],dp[i-coin] + 1 ) +} + +``` + +完整代码如下: ```Java @@ -134,8 +218,22 @@ for 状态1 in 状态1的所有取值: ## 股票问题 +num[i] 表示第 i 天的股票价格, 设计一个算法(交易策略) ,计算你能获得的最大收益,你最多可以完成 k 笔交易; + +比如: [3,2,6,5,1,3] +k=1 , 第2天买入 2块钱, 第3天卖出 6块,利润 6-2 = 4块 是最大利润 +k= 2 (可以交易2次) , [2,6] + [1,3] 是最大利润 + +动态规划思路如下: + + +* 状态定义: +* 状态转移: +* 状态压缩: + ``` + ``` @@ -144,6 +242,17 @@ for 状态1 in 状态1的所有取值: num[i]表示柱子高度,计算下雨之后最多能接多少雨水 +位置i能装多少? +位置 i 能达到的水柱高度和其左边的最高柱子、右边的最高柱子有关,我们分别称这两个柱子高度为 l_max 和 r_max;位置 i 最大的水柱高度就是 `min(l_max, r_max)` + + +思路: + +* 暴力解法 +* 备忘录解法 +* 双指针解法 + + ``` ``` diff --git a/9 Algorithms Job Interview/README.md b/9 Algorithms Job Interview/README.md index b2ce9c5..75d7a54 100644 --- a/9 Algorithms Job Interview/README.md +++ b/9 Algorithms Job Interview/README.md @@ -153,8 +153,44 @@ public static boolean hasCycle(LinkNode head) { ### 左右指针 -``` +快排中 挖坑(pivot) 排序 +```Java +// pivot 选择 尾部节点, 代码写起来更加简单; 移动元素更方便 +// 左右指针技巧 +static int partition(int[] nums, int left, int right){ + + int pivot = nums[right];//选尾部节点作为 pivot + int end = right; + + right--; + while (left < right) { + + if (nums[left] <= pivot) { + left ++ ; //左边指针 窗口变小 + continue; + } + + //元素比 pivot 大,右边指针 窗口变小 + //swap left & right + swap(nums, left, right); + right--; + + } + + // 跟 pivot 元素置换 + int i = 0; + if (nums[left] <= pivot) { + //swap left+1 & pivot + i = left +1; + } else {//swap left & pivot + i = left ; + } + + swap(nums, i, end); + + return i; + } ``` @@ -227,6 +263,10 @@ void mergeSort(int[] nums, int left, int right){ ``` +### 动态规划 DP + + + ## [字符串](1%20字符串.md) diff --git a/README.md b/README.md index a8e561b..6663323 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ * 链表 * 双向链表 -### [数组](2%20List/README.md) +### [数组](2%20List/数组.md) -* [数组数列问题](%20Algorithms%20Job%20Interview/5%20数组数列问题.md) +* [数组数列问题](9%20Algorithms%20Job%20Interview/5%20数组数列问题.md) 数组和链表结构是基础结构,散列表、栈、队列、堆、树、图等等各种数据结构都基于数组和链表结构实现。 @@ -40,7 +40,7 @@ ### [字符串算法](1%20String/README.md) -* 子串查找 [字符串常见题目参考这里](%20Algorithms%20Job%20Interview/1%20字符串.md) +* 子串查找 [字符串常见题目参考这里](9%20Algorithms%20Job%20Interview/1%20字符串.md) * BF算法 * KMP算法 * BM算法 From 3cc2b2da1284a6c2dd6f1b693617143e8ddd60e9 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Wed, 8 Dec 2021 03:57:51 +0800 Subject: [PATCH 48/50] circle array --- 2 List/数组.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/2 List/数组.md b/2 List/数组.md index f69c0b3..2be85e1 100644 --- a/2 List/数组.md +++ b/2 List/数组.md @@ -6,10 +6,24 @@ ## 循环数组 +特点 + +* 长度固定,下表不会越界,使用2个指针标识 头尾 下标; 默认都是 0 +* 方便用来实现 栈,队列;比如 队列实现时,新增元素,头下表+1; 删除元素,尾下标+1 + +比如Java的 ArrayBlockingQueue 就是一个 带有 takeIndex 和 putIndex 的环形数组。 + + +缺点:头尾之间的元素不好维护,从中间删除了某个元素,会出现数组空隙。 +数据结构 + +``` +``` + From 667624355cc6a5b7270604dbbb68d994bf6a1dee Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Wed, 22 Dec 2021 17:12:08 +0800 Subject: [PATCH 49/50] update list&tree --- 2 List/QPS Counter.md | 32 ++++++ 2 List/数组.md | 1 - 4 Tree/8-堆/pq-1.png | Bin 0 -> 107467 bytes 4 Tree/8-堆/堆.md | 98 ++++++++++++++++-- 9 Algorithms Job Interview/1 字符串.md | 8 ++ 9 Algorithms Job Interview/1.1 字符串-查找.md | 61 ++++++----- 9 Algorithms Job Interview/1.3 字符串-修改.md | 33 +++--- 9 Algorithms Job Interview/1.4 字符串-排序.md | 1 - 9 Algorithms Job Interview/5.4 数列-查找.md | 26 +++++ 9 Algorithms Job Interview/README.md | 3 + 10 files changed, 212 insertions(+), 51 deletions(-) create mode 100644 4 Tree/8-堆/pq-1.png diff --git a/2 List/QPS Counter.md b/2 List/QPS Counter.md index 3411dea..570c2c4 100644 --- a/2 List/QPS Counter.md +++ b/2 List/QPS Counter.md @@ -5,3 +5,35 @@ + +```Java + static AtomicInteger qpsCount = 100; //线程安全 + static volatile long lastSenconds = System.currentTimeMillis()/1000; + + //1 计数器 + public static boolean tryAcquire() { + + long current = System.currentTimeMillis()/1000; + if(current == lastSenconds){ + + if (qpsCount-- > 0) {//CAS api + return true; + } else { + //限流 + return false; + } + + } else{//下一个时间窗口 + lastSenconds = current; + qpsCount = 100; + return true; + } + } +``` + + + + + + + diff --git a/2 List/数组.md b/2 List/数组.md index 2be85e1..dc02027 100644 --- a/2 List/数组.md +++ b/2 List/数组.md @@ -18,7 +18,6 @@ - 数据结构 ``` diff --git a/4 Tree/8-堆/pq-1.png b/4 Tree/8-堆/pq-1.png new file mode 100644 index 0000000000000000000000000000000000000000..78202ff57b2f97364198df85aaa15a6138319285 GIT binary patch literal 107467 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 pq = new PriorityQueue(); + pq.add(new Employee(1L, "AAA", LocalDate.now())); + pq.add(new Employee(4L, "BBB", LocalDate.now())); + pq.add(new Employee(3L, "DDD", LocalDate.now())); + pq.add(new Employee(7L, "GGG", LocalDate.now())); + pq.add(new Employee(2L, "CCC", LocalDate.now())); + + while (true) { + Employee head = pq.poll(); + System.out.println(head); + if (head == null) { + return; + } + } + } + +``` + +输出 + +``` +Employee [id=1, name=AAA, dob=2021-12-22] +Employee [id=2, name=CCC, dob=2021-12-22] +Employee [id=3, name=DDD, dob=2021-12-22] +Employee [id=4, name=BBB, dob=2021-12-22] +Employee [id=7, name=GGG, dob=2021-12-22] +``` + + +如下,使用 PriorityQueue实现的 top-K 大问题,实现如下: + +```Java +/** + * 小根堆实现 + */ + public static int findMaxK(int[] nums, int k) { + PriorityQueue pq = new PriorityQueue<>(k, (a, b) -> (a-b) ); + + for (int i = 0; i +``` ## 判断字符串是否是回文 diff --git a/9 Algorithms Job Interview/1.1 字符串-查找.md b/9 Algorithms Job Interview/1.1 字符串-查找.md index 7618a01..dc80de2 100644 --- a/9 Algorithms Job Interview/1.1 字符串-查找.md +++ b/9 Algorithms Job Interview/1.1 字符串-查找.md @@ -27,11 +27,14 @@ char char_first_appear_once(const unsigned char *source){ int hash[256]={0}; char *tmp = source; if (tmp == NULL) return '\0'; + + //第一次建立hash表 key为字符,value为出现次数 while(*tmp != '\0'){ hash[*tmp]++; tmp++; } + //第二次扫描找到第一个value为1的key tmp = source; while(*tmp != '\0'){ if (hash[*tmp] == 1) return *tmp; @@ -151,30 +154,6 @@ int lengthOfLongestSubstring(string s) { - -## 最长公共子串问题 - -请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。 - -例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串,则输出它们的长度4,并打印任意一个子串。 - -``` -int longest_common_subsequence(const char *s1,const char *s2, char *common) -``` - -分析:求最长公共子串(Longest Common Subsequence,LCS)是一道非常经典的动态规划题,因此一些重视算法的公司像MicroStrategy都把它当作面试题。如"abccade","dgcadde"的最大子串为"cad" - - - -实例代码: - -``` -int longest_common_subsequence(const char *s1,const char *s2, char *common){ - -} -``` - - ## 对称子字符串的最大长度 (最长回文子串) 题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。 @@ -228,6 +207,40 @@ int max_symmetrical_char_length(const char *scr){ ``` +## 最小覆盖子串 + +(难度 hard) `滑动窗口` + +给定 字符串 s, t ; 在字符串 s 里找出 包含 t 所有字母的最小子串 +eg: s = "ADOBECODEBANC" t = "ABC" 输出: "BANC" + + + + + + +## 最长公共子串问题 + +请编写一个函数,输入两个字符串,求它们的最长公共子串,并打印出最长公共子串。 + +例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子串,则输出它们的长度4,并打印任意一个子串。 + +``` +int longest_common_subsequence(const char *s1,const char *s2, char *common) +``` + +分析:求最长公共子串(Longest Common Subsequence,LCS)是一道非常经典的动态规划题,因此一些重视算法的公司像MicroStrategy都把它当作面试题。如"abccade","dgcadde"的最大子串为"cad" + + + +实例代码: + +``` +int longest_common_subsequence(const char *s1,const char *s2, char *common){ + +} +``` + ## 求最大连续递增数字子串 diff --git a/9 Algorithms Job Interview/1.3 字符串-修改.md b/9 Algorithms Job Interview/1.3 字符串-修改.md index 4b18a11..0fcf775 100644 --- a/9 Algorithms Job Interview/1.3 字符串-修改.md +++ b/9 Algorithms Job Interview/1.3 字符串-修改.md @@ -79,22 +79,6 @@ char *revert_by_word(char *source){ 用C语言实现一个revert函数,它的功能是将输入的字符串在原串上倒序后返回。 -## 左旋转字符串 - ->字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。 - -如把`字符串abcdef`左旋转2位得到`字符串cdefab` 。请实现字符串左旋转的函数。要求时间对长度为n的字符串操作的复杂度为O(n),辅助内存为O(1)。 - -``` -char *left_rotate(char *str,int offset){ - -} -``` - -思路: 我们可以abcdef分成两部分,ab和cdef,内部逆序以后,整体再次逆序,就可以得到想要的结果了。 -也就是跟上面的问题是同样的问题。 - - ## 替换空格 @@ -138,6 +122,23 @@ char *replace_blank(char *source){ ``` +## 左旋转字符串 + +>字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。 + +如把`字符串abcdef`左旋转2位得到`字符串cdefab` 。请实现字符串左旋转的函数。要求时间对长度为n的字符串操作的复杂度为O(n),辅助内存为O(1)。 + +``` +char *left_rotate(char *str,int offset){ + +} +``` + +思路: 我们可以abcdef分成两部分,ab和cdef,内部逆序以后,整体再次逆序,就可以得到想要的结果了。 +也就是跟上面的问题是同样的问题。 + + + ## 字符串原地压缩 diff --git a/9 Algorithms Job Interview/1.4 字符串-排序.md b/9 Algorithms Job Interview/1.4 字符串-排序.md index 9dd1338..9bc9900 100644 --- a/9 Algorithms Job Interview/1.4 字符串-排序.md +++ b/9 Algorithms Job Interview/1.4 字符串-排序.md @@ -2,7 +2,6 @@ - ## 小写字母排在大写字母的前面 有一个由大小写组成的字符串,现在需要对他进行修改,将其中的所有小写字母排在大写字母的前面(大写或小写字母之间不要求保持原来次序),如有可能尽量选择时间和空间效率高的算法 c语言函数原型: diff --git a/9 Algorithms Job Interview/5.4 数列-查找.md b/9 Algorithms Job Interview/5.4 数列-查找.md index ac9bd9b..24cf68b 100644 --- a/9 Algorithms Job Interview/5.4 数列-查找.md +++ b/9 Algorithms Job Interview/5.4 数列-查找.md @@ -119,6 +119,32 @@ int topK(int * a, int length, int k) +```Java +/** + * 小根堆实现 + */ + public static int findMaxK(int[] nums, int k) { + PriorityQueue pq = new PriorityQueue<>(k, (a, b) -> (a-b) ); + + for (int i = 0; i window = new HashMap(); + while (right < s.length) { Character c = s[right]; From f19caf3ac6bb76bc67c9d2447fdc9f21ad11bf98 Mon Sep 17 00:00:00 2001 From: ranwenjie Date: Thu, 23 Dec 2021 11:59:12 +0800 Subject: [PATCH 50/50] priorityqueue update --- 4 Tree/8-堆/pq-1.jpg | Bin 0 -> 128833 bytes 4 Tree/8-堆/堆.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 4 Tree/8-堆/pq-1.jpg diff --git a/4 Tree/8-堆/pq-1.jpg b/4 Tree/8-堆/pq-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e8b9cebd45c2b7647e8e36b97a20c3c9c7d0ecdb GIT binary patch literal 128833 zcmeFZcT`i~w=cSBQl$w}B`6>Y0!mduLXjq76qPDO1*C&WixLv)od_z}AksucKp=qB zNLP`LAVDBSMFk`QiCa>5`};fRojcxrW4v+R9dF!!-fty4StD6{?LF68vwh}Vd;8Ni z8IU|>>tGA;@BqLy=ml(3fNUF7AXIa50<-`C5CQ~vqyavt#sj?o9z{UlUv&UD#iR6J zb!VOf|JjBY0MY^h{{L*_0e$~dp#J_j`#-<=p7Q*U9-s35pRM^{J>~nax&_o4*j@#W zo(%|(3Xcp3zpiSadl)!s<>18sPw!CqS6$;@RmrJ6*|RvHf&a&C;Rh?A6=wSlASJ|a z!T*YnXCJ^T#lt7Xv)u>4pt}&@`B(YZY0w7`FCV|a4nZMd5mBf?lO({)!^g+V&nF=8 z&t-Vxq5lDXDFNxdM=W>jI(J2IUxbW)LSBiGnpJ(btn)Zs-QentL}8KLa`Fm_8v8X5 z9Mm#2GB!DS?6~zw8(TYjhg0V-Ty$}DbNBG^^}FUD5Ev906&(|cx_K)pIVCkMJtH&! z?!Eg3g%2J+DlIFocvktm>P15%p{cp$b!%HsZ(skw;M;faCnl#pPS1RrB~hrfFJHec zegE;3vA*$pllceyyY&xU(0Kj_SIt~wE8(<4$Z37u)J=k@v?~6={rfp!{(Mte`+y>|wC|B-n5|+!`zYX+_Zv#Sw zDcJ8jE4KmiAtc)=O6IH}{D1xt_J2KT#?t2BJ^g!}{=EwR%`JWZmIeQonZUnS!M`;p zWK8^97W`Wl{C~X)u-jvt&vZOHv(1E)w2J-hJY#uj8%W*;zFZt9uE2t~fzpCD5#T^+ z=Kp_=X9{YrZV&I7CSG*-k}_bwhmnV`F~2Qxp!9#~fNzig?;K%m#^W>FKw=g8A|pJ@ z>>MRL72fF5PV=ESS$QhW61=Wb*M>w7)t_81S2XN$E&9@Wb`Z4ZC(o=5WAhIV5}x!ywycl!I6Jr!)MVZV5ma1KWKc-8z`_gl;(0zvv)O`R&w~Y$ zXT;*iGdruL{c`k|0@R{`w&;CVK73XVT{n>;2g^w+pW(PM=ia1H1$X#b78b+ z3*F*O^7M9K9whwrI#igOGXv3*B{%8e59@Y`09Oe^D5gVYFG)m^7!@9L;d#OA9 zUN(LHVX{^E>CoW)4C0ty*1M5Ef4_e2h$7Ft!zh7C&|U54yf9O%1R*cYZyQMA%7Nyd z_LEK>3>jhLnp(qC(w@^QXll-3gSG()iENlS4_Nx_)h0X=M4aFX3s$B`h_} z^p;Tpjv-Cbd~E+Q>g)QdQBM8 zWx8Wa7yoiuuDWh;PfpSDyt_wyUUo3^wcn>X-#dH?Rt{h2hk3S&kaBthc#;s8ltVuY zYG5hnbCg!g`jN9He_8&sC%X{Lw8u=?CUO6$UTnzHqrbJJKU|Ufi~&=4#)8NcdoR7L z=TTPw%}UfYu3_u6`sAfF1mT@g%1`x)zQ`Op`H2ip_EX)eFar$@#Tg{?=5fdi_heA& zR(Z@6`q zgGlikTT@GXr@Ox(LNYE-XTVof?dZAn+k&!NI&>Tbwz^DNOm8!8VnouKanw+ypJ16&le($MI&X?h#W7*O;$_utX!?jOu4o+>*ZKbxaVnR(F zi@)4VoFMn_>Hj=d{flIU5R=TqX&FU%O8_c0(Gc^&!Ai;y9CTpEv2;*>Ea>?O>TMrV z$>rB+=2v$8Xr?FR+WvT>)`>~Pj1mczJqS{G_uv3l#3;PkCTvKSlhSijZVNr4uhyER z8F*QI#(BI;d@w{guD$eBj&kN6Wm&%~cPz{U3ZWs*b#QTW+nVX&t; z=FhFuFpcuimzPdF?#s&-a0_=fy$4)1iqA@Z`&44_k@kij6XcYb>#=3Q8kQLtOerRE za-M-peJ#f^M2SzUx?QuOd#3LzK3jgEfqGS_pWSz^D`aVJ#8#k%fb8Ew)&cGqUXH7Q z`GhA3_7IgIrAjiFqucx*`)&;LAtbE?v@}==7Kup>>q=RCs9hp@2NO6A+dv3Xk}WyY zafFT_SEiLQ()t&bX)JB0$NNbm^Ydk%S+{ExLVx8-#g=LftlR&rN(DGTDRG|>LKIrW z$PS&-A=)NmG@-*WGEkxYZuc}(^4I+fVTWxFylU~ks~jrl_~eRLt^reSC75*~U>j({ z_29tMv{&4IhIn2S37Kw~*xxl2ub4Wo5OOT_;@-R0-xs}gIN$(mO=q%)I62q=1cZUf z5`!d2rj!{RB$HMV5-8C=gHPbC(Uq8jZQyE)lkJuO!dOVH;F674@I$Y;uOl}c;I^1K zxU^XyJ&Wnd_|q4j_6WyBq!T<%-9y67(!vawfrsdgt2f6fM7 z!!kx+o-$gTh4sLdFnY@eHF{BgO`UNU^W~pf+!0oPSco)G01{iAtQ;UEAEBOi6cF?XbPleK}7(;6`ysc8vwBQFaNx z8_l~7$aE=!ILhZ+3ni2R#tytu`bWc7v-bA$2L`~o$;MjSFB&%t^8VhZ;7EncD$av0 zBhZulXO+;Vmu_Z4tLiV#pv8;t4Ofm0`I+E~QW=DKY|RpS0^_ydJ8DP##=0VA~x z4PNQQzOk--(CTMQsuz95iVgGYp!N&#jxO~c-ghGT8NeF2ZAN2WpxdnqQgF$I+rZ9k zATZ}tuXp>TZf#VNrc1-?ykDC;WnG6dgIiRk40x@Y(en>B;3!d({>3J{m43P_Gm5TT zL|YR4llYb9&9(Te7lo#zMHmBZHI&35Dt8gm&z+a0|GyKTt>_td%;%Byj z#;&4hmPLP!7yG1773W33`Tm9hi{f*^8-cA2N3$-QB4C3f0en7W{K`ix>qc+`I7yM& zVDAMlmMwHXnSjXzsi-nEerF}R*zfPiS8{e0hl=hGK|x1cCEVtrZ;de*w!t zsMJmj2TEjSJM9}f+@L`iXYOh~B5%fEqrVYd;pAdPTsE9C-z7E0))YHlmqD9kpWAPljucevLf+(JjkdG0`1PUA!9vyqt_xJo>#8~5tA6MX&B4MC)j|gbuqy($4mE^UzMdmA&k4eTI{W-+k@qqMY=soHRz{_HNXiQ4&{PlknkRC85h zLr09W{bjfQP$_ufW$T$U?GS+PgiM3e5n0%|f$-TZtMCLltO$jUB2M+c0IQ;tUfd)G zVNE}<6b(($A6B|YKKnlc*3h0Wxr@azoaby&mVpDy%Kg$PEp#`_&FM1Az~N-m?sK18 zv*-T$zD2Hln*XM25_NQG0qsM_b43IxFrnpQZ7eAg(dH%R)IN2Z@697;1)G;n2Q3zj z=jS4xDEpVxWp}B~VLtaVIiM3PU6(5d%gCX`yM5R9(5-_kz^zYzT^CRt;`pGA=D+P` zuUt(H7P{KNLVrl3n!?1*T+lZ0bQ?lRX%IYYcW@o2oWvEp2W24c?m!G6T3!cFxu?XQ$+I9E@e=I;^f;+?o@kYqN2gDE!H9D`M-Wd z4fgaiFbg$2olAE}pO4iOR5Jn>S-aTU^x6dKHXs}bT~O!6D5Wk_Q3RFL!#y}|6zV-e z`uH0)w|e&H!QdP9LR6`{YHh1&T7#1BSVRjDR_VYBmk$`{x9j_lJ~*;+gNLIuBgc>%Tu=nv$xd-plWbj^XE~HP z;Z4zZN9VuxR5Yuqhvkh($yFZ{Ic5aXSSPq2#@MGhrCrBRYHnZ&!-#D{Z+9D8Ay~sQ zHT9hiF%TN0d4sa@cHayOk*eE$ikpjb8@+hK;J`MZjPfVX+~&#!VKl)j72Y1f-Wn*Q zI42dj+Fdbq*x}V1m#P7=0DHk&Z1)MaE6a*~k&ejV9z_Rz^jFl(jn1fJ z@1^|k!6{yQ*vXA5y!@bd|HZwoSB-7H@vuHmo8Y#A03@l}lT&AA$1-5=XawVB6a`aO z&Fp82b(1dWGTx8b?Gvnj-5vTzV$)L?6D1yCT zKwR}Oozx?mqwjQM(Nfam;Y;^g^YKWT=U;sz~>*7-@<53e2LyXWIwcwAhm1 zWAb$CK-8@@JwBkuEWAWOCZMYaKBsQ>u2LWwt{N>r$0TqW-8BgD!(hJ-U?8yG-HEOS*_#^*P88qf4Z z%sNF&Ja~BWwVasGvF`b#iQA^c+t{YjJ|`F%*;}K|<^{{ByZk68q(3k3o-Sy#eEwji zhC(1qe zeDHo*_KQN*Ftwu!bxmEuC{Nl<%H?UhLFAqv7~_1(>fGtOPUDmIyVDcc6jfKO!Oa7f znqNur0eth9j@Syt)C&sMO86j)Ad8p}GLuTPRCM8ip;C`$xROO?+kgi0E7F!7&%m$l zB7+2DkcYm8024IkKIgdWZKfOMUCT>nC*~MP7<|xC-D^2V@K;z`ssp`X^mBS!CU6NX zCD7kOkbO`BJP^)NuFZhJyAvta@Hg84c;K<^NjRZ7T?x8Ujv4mw;`@$T>>QFg)C>-X z(|M7%A4xKrrn95LmspB+@<0@QP2uk7?3big`B0tq-22N&dK;Wviu@ghQP~E1CPr?X zvnN!ibO?{NL%qLvBW=Q^y)J19^-aFuQBMGPteejOZ$`9fqu>F-K^+9yWMz~JlSFx} zd%|}I=g)mt*%OQjGhal5Izrv%zAnp$vTkGi_&Q@2dDu5uXHo5*A8Rlt(0Y?-zGriD zwp-D|xvk;VMpIwujE0`Rrx(6RKUKN^_dZJ%196AgHW0KX2C@d>igj$K>Yv3h@Nr#W zo6r9CSQ(dB9u+Ug<;%paj&}^FUQ)gsBg4azp!+y6rt|2JdlX~)IJQon{o?^l>|Egu zEp3PAhNouuq+UFewmK`h!$PnIZNR9bY4(ZMfd@=_un7yIj0+@K>hF2+r9Sh+8R|JY zzxH0cUz&=>9U3=spLkG2xspjmZkenf7q#GpV+iigNAEwy)(}yMDm|1jAZabFd~@M^cAL)lVNx<1#gnE^mZKEgu# z25}c;sLa-p{omkoAwT|G1s&J3+gzdbBS!PbD{qH@iMxgomq_~BH}jA7CJ8Gktv&eJ@L&A6BiXm)bBh~?$d+nIv1#mbT)+jevmxWcq24i!AuhblZ ztgH?x!&|zAK{}y~{V$6ziPPtW*gw>K!XvbIt`Ix3vv~~$y|#h(-YdkF`z>5t{%!ch z;CEd8phfxL;lll~bW_U-GaKrzIBAE#nuQZNFJ|vYswZ9$i>>D8iFm6y(WL|?u+E^} zI7QgdISD~_XlL_X@?u}R{UNpvR<>=fw;b7L^{Uw0{lW15+1XEZh3fh_nYl^7*KfnM z%(XGo_~y#)&e%5#N(@{N#C)QQ>9D44aN0-h101Sv@u0ysA1RcKf z=G-N&)C3~8&IfuAL6TdBF_Uesgc1tm{9pO~y&AgMo5*(ak!^phrGIZ7H1Qoa!v6{XEJI2{*(mh!OTv zw*}cv+5S36A5^ddr}b`M+v%>u3|P-!0)IzBlRaS`=90>EJWLyLQwg5+aX;m|*H24a zU#M<)R1B>S+K_SCkTXFhf*A}5N+rU~4E(C*QE8_>66!^77AzaqUqa|ql1^SJQ95@r zN#r)Z5cd>*ZPlNumkilJkV|aN1L2R7=!-Nx5mb10!K0L9%zmQhY{9qhKW-3`2W5`@ zLK5s>Scx6%e)r{e{9l&EPmgCgbUEsox{~?f%AYRgk~3i;zg9o@8+G;>8<;r{{Iu3C zyZ!#n7fGQyWlloJc`9C!`xY+_UBSy^!)v-p$@E>=rs&^d>bDqH^!uut$_1g%Wo;1v z&zS2&?i5xO8_25TLAx-FA2Z&Q2D?`&oEtyP4x^R)OluO|Pfd7W10LVM_fS&*?}GQ& z`8(p;U)E-CuxNVS_)nwVFoHz7x$#^eUd-&6k8T+}iAa%Y$d9W=tvy4oeBZQtz0ol@ zi;Yz-_C8mxd?nICYxS88k1OBi zUw&|Y-19leBGME*W&0@tWD(spdAR#_(IYh1pTTT+T=- z9X(`ID%I2syuGl##cS{#-#7|Q6y6n2K&%S*G4^2ry`-0$Cxp>5(K;>*O1oQ7VZ)1` z)Pqyp&!e(FXbmT|932L*7W&I=rvh7U5n|7M_H-LmZ!{CvAno&7F?YT>H=<4PQsRo7 zW0|3{5I7e)_c1O0%)r$i)5ma8f7RH%-u~1x<{^*%+j@h0R&U-uy^Ypm`C-O9u(%F8G7bl8 zEXPV2u4N!4YR%fc%r|;(y}ad8R(XlIbyDB<-B-0&NAIw^qTFrOU)o?O^d+{84+R4F z(|*q_N~7R|B=4FN<xHmjY!W0+WKk9l=78(ukxH{Qy2s%F^mbI-Kg-H!n)rohO(P zwI&VbgyGM$Oh;+g8145oy&2}Wcj=RXDCKMJ(7Oxfo-OD7T@l!z0qM`HIkfM=T-4WwtdlY~YLm5)S$d!U%Q!#4J2P(PUK!BL|vN>@vLH z!%TbIj8+M|#r^kIyl%_gZ_gXxf}^O*S% zFU~Ps)R!_`Nme-345>FD^quI@5HV$X+Q{Z-yj@{3od5sPY@c9h(@ z=U@`0C3$nzJDh<0>7nxYX0-7~g#OLdvV2=o!iBJFngC!5Db_fem=z4%$4S()CXWiW zP`3(-2mj9e#CGHUsx1g?1NFg>OFUu!oNwa!|BDdo_Qe0zkmBDIP7d53kpYKsb{`e+Fm+R>F=iXs%*p9k+PYQueiYPnU72T; zkr92k+(+9$KT>=fxbg`#xLROu^s@$nG3f(tPe;iait?)ApU4jPF9VILVL5qs5a1!-!*krX z9`T)RhtAnhR}V@_3S7L{+yNyN1LA<})*uoOqdTu9K&lKI0GpkjdxIAuAXis!z@^=g zO?9Nz5Jsq&$$_qd#-fyI?S3@q&fUg$B!Hi7fnOpoerw9}QNKQXz&9A={7TNmhSten2M z$GJrZ_%b1TW7x6Ej;^Q%ijTYvg7xop`q`)2SM*%2#| ztau5dFh2d(?vMG0LsY5ILHXHiS2)WCElyutRielCA%)QA)I2?xuj|dOshwSSU$CHh z#-%vhuIXNM9?I)9*>7dT( zgZ{8(nLRTXrXk(fslRnZr)e>>PW6$of`oEiW%WU(YMyrv>j?KfTm|jNviZ!NMK;Sf z)H6;?8WGdXj`;0E?0%4=bTa#!NrAfk)!6kiY5Q*uith49|F*4x2MSj<8A-HSBHiT= z#XEu1B9YwTV8ng37(yVhbQ<4X>t;lo?LVE4Pw#Enb4&r?m;gKpZ)Cx@`1MB$@Rc*$ zz~{?#vu*4lI;-|ZZs1RE+c<$yK#UF<4F9BiCGZM5 zJ2c=o#q5QIm_M!)Q^B1y7oZpR;b&P?!K9AJ2-$+HxToIlBI6FfcUN*7?u+%sP7>;0 zF49HVInd19!lN@v5|K0_yd?t0a%YFCUxu%4DS1ScMp@jGG#xpAw7&wFpWty9!_kzputaIF+t(0uV z=7x!Pbtw4RsMLwgrOO-X**VI3V(St|O7rcrozVOrP$1aS|8vOeU7kpcu& z_(Kcx?4{E}F7~whWiIM_ihXk*zY+=|b08>ye}z*(DB3X{PMRCw9%%yeAZstZU@fYx zznak8e0JXW2Q8=kLgbAPU6=aGF)ow5rMLUvn9XrT9!u}go&F6&0RyLx#9Lj%mGI0U+aOA%d~;eb zCn17*|NcvxO6H-R5b#-2#P02)$)EPY*w;P(CwR2j03X245@~Dw!@*S9@;@Fsnxri& zP?_J>Cjy%?q*CwWI1!W~wkGeEm!=Mhi6xd3OZ=m9>}Ml*KHJ zkWj(!^^-AMMTFBMd8YUM+~q#x2|jps%qLPgSyu>vkdb5)t_U<+){8w7EXH%}dP58R z^60EJ4ZA|2E@m!3il!P2K37OJ+AMfhkGc_DnW_EyYi9xZ!7m-10(GA#UjF$WGL6st zW+3Yv6l--@(K&B1jlHJrIUg-p@Q2yf5%FV9m4-TJ_*SMEOIuReWFl62V_D~ex?t0r zqom>?>+z=G!1oZHjvF z+1xmTtVZ3Dz+`>@eWrbZY!UyrZN5x{MJ?wp(># z8F8o0_i~`I^~3HYfoqnGFY2hQ-u%;fPRbK9fw|N9#-SUw`!n6L8VuU>L%z1+NPG}@ z2+ip<=QPbzNzU8C*@3boxal@8kVEp?t5f+H1ht) zw8c)m{OAh^3GLp!`epo2#%OX>`r@@n=1n8dsMkN{-s<5)X4F`FK}W8LK?KVLwVOsx z%f{?>1NVEG+fCGL%7-g5H3GjH=yc-{d15`0``M=G*>6N!qW@^3Nes4rG=|K8qzWHniS+Iq-GzZ|| zL2Q4xV4KkgIw`0{PpKdeT)OY8_Nz1JA2x(F^_`mVkd z^~Gwuu=}9F!Ic2MQQ}pJ-Q1}*{}r3iXKYh2o>COvVl<7;pVa#V7^l z7?(uVsMm$d)EIqek<%B-;~Um2Iw-Q^`rL&BZveU;cra~iahAq?&rD*Iy1sy$bpKum zDd<5+qcs?pMg8kM49{Ik7H7uVThDzS5LQ6>UA(Su0$iXwVGx*cqCDH36?O^qKhL?3 zQ3>|erw?{7%8i!1!;NLk4pILR!C&sW3$?9PgCn!U_JNCJQLPS1P}VJRMSjj z2n=NUH875<pV(Fw9Q_i&ofo9 zs_rF503FE5GnYr3(PO*A`Pp9d;umc?MYT9zc=OAJpG=J0KEpeA)z|Cy%D^7JGCeE! z5o6SvIojQ}Io~ZRqv-b~7hzE)nvdO!Ovlm@ohHmp7?kLeRtYM^(wi5%Cl`L=e7m%q zF8#b_8LM^X5@~Om|D&2lLDO3s$arY&TXByEF76;gwv|+%OT$C7D{aWV;|OKm99I03 zx^xb)&t1)CNQ&QC?k)e#RKuUkcpuKaF6mLa0h9$H(KGb*0&(0h9nuxD_F8Qzb4DLO zIUi4mFubh-*>3C<5Esn4ft&k7G4xjL0531@QtH{NAM+!4d9rvy(A8^Z-hv3i-#PSr zvD;kH!!@KA+7aTz#3#5k6>alcns=Z;P5}>WB?CuB+0^ zpQs#Gd{(ftPcOqTb}HN$Foe>umv zsOEaZgV7H~hxgvEK+!L@nS2jt@6w;9*>F-YiaXtRKGWHJ+;HtLw2ZvBP+v6aQv!-E zsXVqnp-m&s)eS5Pv*j2*cATeB7C>g5-r#fRxs#3bk#yI-n63V@qsaQvP^pL@rI?j4 zrO|^5_c8#%28li35-ly8Z4L1}i!qa+V=mWyll(B+w9~P>Z9QmbrJLFKz@3m#^8;^Q zU%U8FU$lR(g21{C8bdcp!TPl0XGftRYpQA-atB(g<8gQKzC1PEEff$-hvh$$rpkW>BB7AYO5*a4qiIx`+}4xPSI;CeN* zlwVkU<;5Y>h7$Gs!Bqi9e)wF=zz|CbGa`2lO7jeCX$5m=aemTnq#w+Q41tRBa{EpfryKsLr`8ttxpBik%S`oq=cY}~J$ zeEpaMzqfvaOXoCU&wkojMVCCYe9I%Z-v|fK znl)d%R98@m`Fb@u0tT7;fhX*kCud#~ePN_;Hsdu>sQ$_XbPVI~ar3$|>vhk;NY%eO zUlWW=u9>j-h7Oa95OZuE)cDknN|DaTu=e&WA5{UycuXYo|XyO2jZg-w zU9ArLACg>--N+P|5th9Cz%C~lOX-E(7+uD@b};mc9|upKKOEG;*ik%y zFn4?87W1adyN8v#XUyjbE*eas){&N-=%Ir+^J8oqI${Odcq!y9zjW7X(w|{mBS*Sq zo97rAWj>_Tc=#;CQk8$n9IuIjF$tU}zoDSbV79qVkP7@&xDXO;NEi>@eCK>ccBEv_ zNb#@=zh~0@j8E*R*8}(>xgtEQi|-f)P>8iMagMy$j}sRCYna5TqhfdN$5(j%RV;e> zx|r;B>g>D5tLU_-?COCV@T(XV?Artip2hbG`#rhtE#ztzuo zQk_DdUe&pGCQa*Iu=?GHB2Q?e1s9cNZPbhyYb%i~7gR8LpooE_;8NM9)!-khU3!-` zn7?5|uTA4w)TwuLOX=^Ql-M^tWfr1n{rb6czj304ARes`nG#ZHVTN2kJ{j9=oEEyf zj%>P79iZ4hT~cMK+e)cs$7g$X2S+N7MoRUx^*tO~T^fo}nP;hUhp>(QtH*+=SSWp) z32nPgwtk}%E63hj_~#L`p^#KjJE5NMWE*>lQo1;wSML#HVou?))%RKw0FOns?nEWm`)zt7Z&qQYDLQr zah3A~LQ=4)5E5G1^T|w*{A#znwRg}~=fc$MDP1O)`Hix50J!36>SG~jRu6zID9!g? zTL7HtpbkNhbC14tX|O}VL6#hMIueDW>9)sHu?cY5+OpIUuAcx}`&N>$NO{oiqqIu} zB0R;g1@?xGYN&%zye1UlOKkrB=eWjdSBV%*_)D(4j-PuTY&EiZ+E<+~?R?T~+Vi?G zd^S-CEytLnG`G-O2B+~s6GrWkyY$IU;ri_HOICe*8m-93m8J3$Me>CN%RS~jk)GCZ zeulBT|46;8cibhIYyWwNiwl3M3%{ggw=5XS67j~&Omii{CwPFcm{wT42fnMrDomZ> zH(d!u@zz((-embJ*9Q(oA(rCg+`n7 zMt9`G`HP6O&XAeTfKjbJIVW9TibUaX@a<`=8y zQTr#9=b*Xx_|uywo0IKAgNha{Q zg1h1LS{fohI7_MKM1P-a!`q>+-qvEt0{735+s|AVw;Wu_*lT%B70`G1E&yP>FpCB? zGXt<$m9MhneqdSUQFp1b>x#kpd}_e^-q)&nTy){OQU-)T$C8W%yU)8qVc)N2ESrll?M_5#S@OdkK9A} zVIWjM9o4luVrqNqcip&~`7X9m6POjjxUtyl5rWZgtM@Vv4ZM5~#eC79C^v{Ew=DRH zl;6Jy@V(y#eDSk$cAP@4;CHO(ii&BC4Igs3a6D1qSM?2N9SJDM=E=-k zIqZ62yBO8%cDw?WUkZ0B?Hhj0xaxc77cFV-AEj*Qdq6~^KH0M>!&LV>i zGzKanL&KHNdk-rfa!~*ELebUj<5`1ztJ{LSx8cVBiqx*VLQ;;U?cvJ3M{)l*{kq23hY!*z!$gpid9x7ZA9n5fL@9mQ6G|pcP8j9H2k;loTnwHy> zqVg2xDI$_;2L2)@S8v0QqOD|!!F8Xa=#gY2j^W_G&RB{jyJC=r<=o}yZ38ynn>Ji; zqtzH?%u+B-Zg6q7|GYhYrW+xsmt-y%B?65$>Uw7X z1*XKOYAQ0Z!-wUHn(T)us(v&RW!VNDH&juXMjK$pZORsVeG7;`6t6yDQ?xZo?Z*w* zd9!`f-@y*>Y@K7-W8by2A^fIZuMfTzUQFDB5rML}U03(APGE*%JZvOG@N67s-#6O% zsSb&fH{sOIjIdvq_FSwP>r8xcy+#fI8hQqq#*=IQq&84BuO@vkaV9KOUN&EC~q2Knk zgkwz?>{ml;PcBQgG`*I5k(PdWMeIoS>QNfpABMx%pWZGbQ*Q^&CpuXqtSju(ses{ zQq+S@rRDVBPAb6)*9s9?A6`qjo9$kAFwhdXwEq&BH<*gR!3lONcUg|$4lEBFL5KC3 z4!Q2sxc>zsLG+wI{v}&@^_o=kptA3cTys|!XPfvndMuQw=gRoG(`AX0S`quazx17$ zYffy%Vql6Q`Itp@e0bRCot*sJ35yB}^$b&H0;oa1_TFs?0CBsFq{-P48it}liMozH~Q+mJZ)W&{m*PJ=((@|6` zJ<9t^>7L5#@A2B7(0&Xe4aSx^qT3~j`LJbNMv+J^{56d^2xh&s3SD3hnfenZOGZ40 zFI9^bUY_$?mu&v^n3~4k^$eRjTE=$aq;5X!5M+q|LiX}nQ8av~noy`x+ ztmA4Hf5bLZbVI+zrOXO$z1t^Up7K_ySu7J+gI|uziVOcVO40s&Do^|S^?`~{2lUh@ zw4RSTf3V=I(&QzYa}7YpL2P4X4{;7LNR&Qwbux;WrPyCnm;A)5+u*0@bElhpSC1Ag z7~AiczJEtMbm!pv2&M{-b(jm$)PP8hLMpOPPy2V`y1Op4nb**Yu6d68=+sNwaqzyU zJO;Jk!-{irH%sbUG-WreG_&C3^2J@NU3=%h|7mkw`9uF$TW2U5{5?Ao)#8<*;2bGT zd76=W>@)ALthJ#7*?gK5*A(+ZmH#fk1#+zQBjJTP5 zCH`ξ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�qN|GJI+bRyZaJHTM!>a2c-R9 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 Rm(3IX-zvecpZoL3{{z)7>`wpy literal 0 HcmV?d00001 diff --git a/4 Tree/8-堆/堆.md b/4 Tree/8-堆/堆.md index c490690..c6e8d6e 100644 --- a/4 Tree/8-堆/堆.md +++ b/4 Tree/8-堆/堆.md @@ -16,7 +16,7 @@ 比如小根堆存储示例 -![小根堆](./pq-1.png) +![小根堆](./pq-1.jpg)