From 499b9efdb413f2e4094f80ba40a90ddb8c5e71ed Mon Sep 17 00:00:00 2001 From: robot Date: Sat, 7 Jan 2023 21:07:45 +0800 Subject: [PATCH] go --- 91/season2.md | 2 +- 91/two-pointers.md | 4 +- README.md | 2 +- ...76\345\275\251\351\242\204\345\221\212.md" | 2 +- daily/2019-08-13.md | 58 +++--- introduction.md | 2 +- ...acity-to-ship-packages-within-d-days-en.md | 63 +++---- ...t-sorted-array-to-binary-search-tree.en.md | 32 ++-- ...vert-sorted-array-to-binary-search-tree.md | 3 +- problems/1260.shift-2d-grid.en.md | 13 +- ...-elements-in-a-contaminated-binary-tree.md | 2 +- problems/1310.xor-queries-of-a-subarray.md | 4 +- .../1332.remove-palindromic-sequences.en.md | 9 +- ...nts-on-subarrays-to-form-a-target-array.md | 10 +- problems/19.removeNthNodeFromEndofList.md | 4 +- problems/20.valid-parents.en.md | 31 ++-- problems/437.path-sum-iii.en.md | 53 +++--- problems/525.contiguous-array.md | 2 +- problems/53.maximum-sum-subarray-cn.en.md | 171 ++++++++---------- problems/binode-lcci.en.md | 12 +- selected/atMostK.md | 2 +- thinkings/DFS.en.md | 9 +- thinkings/GCD.en.md | 23 +-- thinkings/README.en.md | 26 +-- thinkings/backtrack.en.md | 6 +- thinkings/basic-data-structure.en.md | 108 +++++------ thinkings/binary-search-1.en.md | 27 ++- thinkings/binary-search-2.en.md | 88 +++------ thinkings/bit.en.md | 4 +- thinkings/dynamic-programming.en.md | 14 +- thinkings/graph.en.md | 28 ++- thinkings/greedy.en.md | 10 +- thinkings/heap-2.en.md | 33 ++-- thinkings/heap.en.md | 46 ++--- thinkings/island.en.md | 13 +- thinkings/linked-list.en.md | 40 ++-- thinkings/monotone-stack.en.md | 41 ++--- thinkings/prefix.en.md | 102 +++++------ thinkings/prefix.md | 2 +- thinkings/reservoid-sampling.en.md | 4 +- ...run-length-encode-and-huffman-encode.en.md | 34 ++-- thinkings/search.en.md | 12 +- thinkings/tree.en.md | 10 +- thinkings/union-find.en.md | 6 +- 44 files changed, 487 insertions(+), 680 deletions(-) diff --git a/91/season2.md b/91/season2.md index 5ac5a88e8..28bdc7bfd 100644 --- a/91/season2.md +++ b/91/season2.md @@ -2,7 +2,7 @@ 力扣加加,一个努力做西湖区最好的算法题解的团队。就在今天它给大家带来了《91 天学算法》,帮助大家摆脱困境,征服算法。 - + ## 初衷 diff --git a/91/two-pointers.md b/91/two-pointers.md index 4dc0bb733..3fde7a8d0 100644 --- a/91/two-pointers.md +++ b/91/two-pointers.md @@ -1,8 +1,8 @@ -# 【91算法-基础篇】05.双指针 +# 【91 算法-基础篇】05.双指针 力扣加加,一个努力做西湖区最好的算法题解的团队。就在今天它给大家带来了《91 天学算法》,帮助大家摆脱困境,征服算法。 - + ## 什么是双指针 diff --git a/README.md b/README.md index 0de01cae4..4b102a010 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ 可以去我的公众号《力扣加加》后台回复电子书获取! - + > epub 还是有动图的 diff --git "a/backlog/\347\262\276\345\275\251\351\242\204\345\221\212.md" "b/backlog/\347\262\276\345\275\251\351\242\204\345\221\212.md" index ca9d9d757..b422a0048 100644 --- "a/backlog/\347\262\276\345\275\251\351\242\204\345\221\212.md" +++ "b/backlog/\347\262\276\345\275\251\351\242\204\345\221\212.md" @@ -2,7 +2,7 @@ [0042.trapping-rain-water](./problems/42.trapping-rain-water.md): - +![](https://p.ipic.vip/9twl4j.jpg) [0547.friend-circles](./problems/547.friend-circles-en.md): diff --git a/daily/2019-08-13.md b/daily/2019-08-13.md index 1baf1d433..794ae344b 100644 --- a/daily/2019-08-13.md +++ b/daily/2019-08-13.md @@ -1,10 +1,12 @@ -# 毎日一题 - 417. 太平洋大西洋水流问题 +# 毎日一题 - 417. 太平洋大西洋水流问题 ## 信息卡片 -* 时间:2019-08-13 -* 题目链接:https://leetcode-cn.com/problems/pacific-atlantic-water-flow -- tag:`Backtracking` `DFS` +- 时间:2019-08-13 +- 题目链接:https://leetcode-cn.com/problems/pacific-atlantic-water-flow + +* tag:`Backtracking` `DFS` + ## 题目描述 给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度。“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界。 @@ -15,15 +17,14 @@ 提示: -输出坐标的顺序不重要 -m 和 n 都小于150 +输出坐标的顺序不重要 m 和 n 都小于 150 示例: ``` 给定下面的 5x5 矩阵: - 太平洋 ~ ~ ~ ~ ~ + 太平洋 ~ ~ ~ ~ ~ ~ 1 2 2 3 (5) * ~ 3 2 3 (4) (4) * ~ 2 4 (5) 3 1 * @@ -33,25 +34,18 @@ m 和 n 都小于150 返回: -[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (上图中带括号的单元). +[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]](上图中带括号的单元). ``` - - ## 参考答案 -- 方法1:直接采用回溯法 超时 +- 方法 1:直接采用回溯法 超时 -直接判断 水流既可以流动到“太平洋”,又能流动到“大西洋”的陆地单元的坐标 -采用方法是 -回溯法(英语:backtracking)是暴力搜索法中的一种。 -在最坏的情况下,回溯法会导致一次复杂度为指数时间的计算。 -在这个题目中,这个题目中正好就是如此。 -因为需要等到上下左右全部计算完毕才有确定答案。 +直接判断 水流既可以流动到“太平洋”,又能流动到“大西洋”的陆地单元的坐标采用方法是回溯法(英语:backtracking)是暴力搜索法中的一种。在最坏的情况下,回溯法会导致一次复杂度为指数时间的计算。在这个题目中,这个题目中正好就是如此。因为需要等到上下左右全部计算完毕才有确定答案。 m 和 n =150,肯定超时。 -- 方法2:动态规划+回溯法 +- 方法 2:动态规划+回溯法 思路: @@ -61,8 +55,7 @@ m 和 n =150,肯定超时。 最后将探测结果进行合并即可。合并的条件就是当前单元既能流入太平洋又能流入大西洋。 -![集合](https://p.ipic.vip/r02fm7.jpg) -扩展: +![集合](https://p.ipic.vip/r02fm7.jpg) 扩展: 如果题目改为能够流入大西洋或者太平洋,我们只需要最后合并的时候,条件改为求或即可 @@ -124,7 +117,6 @@ var pacificAtlantic = function(matrix) { }; ``` - - C++ Code ```c++ @@ -139,12 +131,12 @@ var pacificAtlantic = function(matrix) { int col = matrix[0].size(); if ( 0 == col ) return(out); - + /* 能流动到“太平洋"的陆地 */ vector > dp1( row, vector( col, false ) ); /* 能流动到“大西洋"的陆地 */ vector > dp2( row, vector( col, false ) ); - + /* 从第一行/最后一行出发寻找连同节点,不变的x坐标 */ for ( int j = 0; j < col; j++ ) { @@ -157,7 +149,7 @@ var pacificAtlantic = function(matrix) { dfs( i, 0, INT_MIN, matrix, dp1 ); dfs( i, col - 1, INT_MIN, matrix, dp2 ); } - + vector temp( 2 ); for ( int i = 0; i < row; i++ ) { @@ -174,9 +166,9 @@ var pacificAtlantic = function(matrix) { } return(out); } - - - void dfs( int row, int col, int height, + + + void dfs( int row, int col, int height, vector > & matrix, vector > & visited ) { if ( row < 0 || row >= matrix.size() || @@ -185,19 +177,19 @@ var pacificAtlantic = function(matrix) { { return; } - + if ( visited[row][col] == true ) { return; } - + if ( height > matrix[row][col] ) { return; } - + visited[row][col] = true; - + dfs( row + 1, col, matrix[row][col], matrix, visited ); dfs( row - 1, col, matrix[row][col], matrix, visited ); dfs( row, col + 1, matrix[row][col], matrix, visited ); @@ -206,10 +198,6 @@ var pacificAtlantic = function(matrix) { }; ``` - - - - ## 其他优秀解答 > ##### 暂缺 diff --git a/introduction.md b/introduction.md index a71a19f1a..ba2b6a566 100644 --- a/introduction.md +++ b/introduction.md @@ -30,7 +30,7 @@ 有些动图,在做成电子书(比如 pdf)的时候自然就变没了,如果需要看动图的, 可以去我的公众号《力扣加加》或者我的 leetcode 题解仓库看。 - + > epub 还是有动图的 diff --git a/problems/1011.capacity-to-ship-packages-within-d-days-en.md b/problems/1011.capacity-to-ship-packages-within-d-days-en.md index a313d6ef5..c4848ca15 100644 --- a/problems/1011.capacity-to-ship-packages-within-d-days-en.md +++ b/problems/1011.capacity-to-ship-packages-within-d-days-en.md @@ -6,7 +6,7 @@ https://leetcode-cn.com/problems/capacity-to-ship-packages-within-d-days A conveyor belt has packages that must be shipped from one port to another within D days. -The i-th package on the conveyor belt has a weight of weights[i]. Each day, we load the ship with packages on the conveyor belt (in the order given by weights). We may not load more weight than the maximum weight capacity of the ship. +The i-th package on the conveyor belt has a weight of weights[i]. Each day, we load the ship with packages on the conveyor belt (in the order given by weights). We may not load more weight than the maximum weight capacity of the ship. Return the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within D days. @@ -15,7 +15,7 @@ Return the least weight capacity of the ship that will result in all the package ``` Input: weights = [1,2,3,4,5,6,7,8,9,10], D = 5 Output: 15 -Explanation: +Explanation: A ship capacity of 15 is the minimum to ship all the packages in 5 days like this: 1st day: 1, 2, 3, 4, 5 2nd day: 6, 7 @@ -23,7 +23,7 @@ A ship capacity of 15 is the minimum to ship all the packages in 5 days like thi 4th day: 9 5th day: 10 -Note that the cargo must be shipped in the order given, so using a ship of capacity 14 and splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed. +Note that the cargo must be shipped in the order given, so using a ship of capacity 14 and splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed. ``` **Example 2:** @@ -31,7 +31,7 @@ Note that the cargo must be shipped in the order given, so using a ship of capac ``` Input: weights = [3,2,2,4,1,4], D = 3 Output: 6 -Explanation: +Explanation: A ship capacity of 6 is the minimum to ship all the packages in 3 days like this: 1st day: 3, 2 2nd day: 2, 4 @@ -43,49 +43,42 @@ A ship capacity of 6 is the minimum to ship all the packages in 3 days like this ``` Input: weights = [1,2,3,1,1], D = 4 Output: 3 -Explanation: +Explanation: 1st day: 1 2nd day: 2 3rd day: 3 4th day: 1, 1 ``` - - - **Note:** +**Note:** 1. `1 <= D <= weights.length <= 50000` 2. `1 <= weights[i] <= 500` - - ## Solution -The problem is same as [**LeetCode 875 koko-eating-bananas**] (https://github.com/azl397985856/leetcode/blob/master/problems/875.koko-eating-bananas-en.md) practically. +The problem is same as [**LeetCode 875 koko-eating-bananas**](https://github.com/azl397985856/leetcode/blob/master/problems/875.koko-eating-bananas-en.md) practically. -It is easy to solve this kind of problems if you take a closer look into it. +It is easy to solve this kind of problems if you take a closer look into it. - -The essence is to search a given number in finite discrete data like [ 1,2,3,4, ... , total ]. +The essence is to search a given number in finite discrete data like [ 1,2,3,4, ... , total ]. However, We should find the cargo that can be shipped in D days rather than look for the target directly. - Consider the following questions: - Can it be shipped if the capacity is 1? - Can it be shipped if the capacity is 2? - Can it be shipped if the capacity is 3? - ... -- Can it be shipped if the capacity is total ? ( Yeap we can, D is greater than or equal to 1) +- Can it be shipped if the capacity is total ? ( Yeap we can, D is greater than or equal to 1) -During the process, we directly `return` if the answer is *yes*. +During the process, we directly `return` if the answer is _yes_. -If the answer is *no*, just keep asking. +If the answer is _no_, just keep asking. This is a typical binary search problem, the only difference is the judgement condition: - ```python def canShip(opacity): # Whether the capacity of the specified ship can be shipped in D days @@ -146,38 +139,38 @@ class Solution: * @param {number} D * @return {number} */ -var shipWithinDays = function(weights, D) { - let high = weights.reduce((acc, cur) => acc + cur) - let low = 0 +var shipWithinDays = function (weights, D) { + let high = weights.reduce((acc, cur) => acc + cur); + let low = 0; - while(low < high) { - let mid = Math.floor((high + low) / 2) + while (low < high) { + let mid = Math.floor((high + low) / 2); if (canShip(mid)) { - high = mid + high = mid; } else { - low = mid + 1 + low = mid + 1; } } - return low + return low; function canShip(opacity) { - let remain = opacity - let count = 1 + let remain = opacity; + let count = 1; for (let weight of weights) { if (weight > opacity) { - return false + return false; } - remain -= weight + remain -= weight; if (remain < 0) { - count++ - remain = opacity - weight + count++; + remain = opacity - weight; } if (count > D) { - return false + return false; } } - return count <= D + return count <= D; } }; ``` diff --git a/problems/108.convert-sorted-array-to-binary-search-tree.en.md b/problems/108.convert-sorted-array-to-binary-search-tree.en.md index 79760e648..6e9a355ae 100644 --- a/problems/108.convert-sorted-array-to-binary-search-tree.en.md +++ b/problems/108.convert-sorted-array-to-binary-search-tree.en.md @@ -29,10 +29,7 @@ One possible answer is: [0,-3, 9,-10, null,5], which can represent the following ## Company --Ali --Tencent --Baidu --Byte +-Ali -Tencent -Baidu -Byte - airbnb @@ -58,15 +55,15 @@ JS Code: ```js var sortedArrayToBST = function (nums) { - // Since the array is sorted, one idea is to divide the array into two halves, one half is the left subtree and the other half is the right subtree - // Then use the “recursive nature of the tree” to complete the operation recursively. - if (nums.length === 0) return null; - const mid = nums.length >> 1; - const root = new TreeNode(nums[mid]); - - root.left = sortedArrayToBST(nums.slice(0, mid)); - root.right = sortedArrayToBST(nums.slice(mid + 1)); - return root; + // Since the array is sorted, one idea is to divide the array into two halves, one half is the left subtree and the other half is the right subtree + // Then use the “recursive nature of the tree” to complete the operation recursively. + if (nums.length === 0) return null; + const mid = nums.length >> 1; + const root = new TreeNode(nums[mid]); + + root.left = sortedArrayToBST(nums.slice(0, mid)); + root.right = sortedArrayToBST(nums.slice(mid + 1)); + return root; }; ``` @@ -85,8 +82,7 @@ return root **Complexity analysis** --Time complexity:$O(N)$ --Spatial complexity: Each recursion copies the space of N, so the spatial complexity is $O(N^2)$ +-Time complexity:$O(N)$ -Spatial complexity: Each recursion copies the space of N, so the spatial complexity is $O(N^2)$ However, there is actually no need to open up new space: @@ -169,12 +165,10 @@ return root **Complexity analysis** --Time complexity:$O(N)$ --Spatial complexity: Since it is a balanced binary tree, the overhead of the implicit call stack is $O(logN)$ +-Time complexity:$O(N)$ -Spatial complexity: Since it is a balanced binary tree, the overhead of the implicit call stack is $O(logN)$ For more questions, please visit my LeetCode questions warehouse:https://github.com/azl397985856/leetcode . There are already 37K stars. -Public account 【[Force Buckle plus] (https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg )】 -Zhihu Column 【[Lucifer-Zhihu] (https://www.zhihu.com/people/lu-xiao-13-70 )】 +Public account 【[Force Buckle plus](https://p.ipic.vip/n8gbxo.jpg)】 Zhihu Column 【[Lucifer-Zhihu](https://www.zhihu.com/people/lu-xiao-13-70)】 Pay attention, don't get lost! diff --git a/problems/108.convert-sorted-array-to-binary-search-tree.md b/problems/108.convert-sorted-array-to-binary-search-tree.md index a570097ef..ce75fcb12 100644 --- a/problems/108.convert-sorted-array-to-binary-search-tree.md +++ b/problems/108.convert-sorted-array-to-binary-search-tree.md @@ -175,7 +175,6 @@ class Solution(object): 更多题解可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。 -公众号【 [力扣加加](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg)】 -知乎专栏【 [Lucifer - 知乎](https://www.zhihu.com/people/lu-xiao-13-70)】 +公众号【 [力扣加加](https://p.ipic.vip/n8gbxo.jpg)】知乎专栏【 [Lucifer - 知乎](https://www.zhihu.com/people/lu-xiao-13-70)】 点关注,不迷路! diff --git a/problems/1260.shift-2d-grid.en.md b/problems/1260.shift-2d-grid.en.md index 0090dd44c..97d5147d3 100644 --- a/problems/1260.shift-2d-grid.en.md +++ b/problems/1260.shift-2d-grid.en.md @@ -47,8 +47,7 @@ prompt: ## Pre-knowledge --[array](https://github.com/azl397985856/leetcode/blob/master/thinkings/basic-data-structure.md) --Mathematics +-[array](https://github.com/azl397985856/leetcode/blob/master/thinkings/basic-data-structure.md) -Mathematics ## Company @@ -88,10 +87,9 @@ Since it is easy, the above approach is barely acceptable, so we will consider o ### Idea -If we look closely at the matrix, we will find that in fact, such matrix migration is regular. As shown in the figure: -![image](https://p.ipic.vip/6w6n0m.jpg) +If we look closely at the matrix, we will find that in fact, such matrix migration is regular. As shown in the figure: ![image](https://p.ipic.vip/6w6n0m.jpg) -Therefore, this problem has been transformed into our one-dimensional matrix transfer problem. LeetCode also has the original title [189. Rotating array](https://leetcode-cn.com/problems/rotate-array /), at the same time, I also wrote an article [Cyclic shift algorithm that liberal arts students can understand] (https://lucifer.ren/blog/2019/12/11/rotate-list /) To discuss this specifically, in the end we used the cubic rotation method. The relevant mathematical proofs are also written. They are very detailed and will not be repeated here. +Therefore, this problem has been transformed into our one-dimensional matrix transfer problem. LeetCode also has the original title [189. Rotating array](https://leetcode-cn.com/problems/rotate-array /), at the same time, I also wrote an article [Cyclic shift algorithm that liberal arts students can understand](https://lucifer.ren/blog/2019/12/11/rotate-list /) To discuss this specifically, in the end we used the cubic rotation method. The relevant mathematical proofs are also written. They are very detailed and will not be repeated here. LeetCode really likes to change the soup without changing the medicine. @@ -148,8 +146,7 @@ return res **Complexity analysis** --Time complexity:$O(N)$ --Spatial complexity:$O(1)$ +-Time complexity:$O(N)$ -Spatial complexity:$O(1)$ ## Related topics @@ -157,7 +154,7 @@ return res ## Reference --[Cyclic shift algorithm that liberal arts students can understand] (https://lucifer . ren/blog/2019/12/11/rotate-list/) +-[Cyclic shift algorithm that liberal arts students can understand](https://lucifer . ren/blog/2019/12/11/rotate-list/) For more questions, please visit my LeetCode questions warehouse:https://github.com/azl397985856/leetcode . There are already 37K stars. diff --git a/problems/1261.find-elements-in-a-contaminated-binary-tree.md b/problems/1261.find-elements-in-a-contaminated-binary-tree.md index 4239003db..eaedeed9f 100644 --- a/problems/1261.find-elements-in-a-contaminated-binary-tree.md +++ b/problems/1261.find-elements-in-a-contaminated-binary-tree.md @@ -271,4 +271,4 @@ class FindElements: 关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。 -![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg) +![](https://p.ipic.vip/n8gbxo.jpg) diff --git a/problems/1310.xor-queries-of-a-subarray.md b/problems/1310.xor-queries-of-a-subarray.md index a7d1bc41d..969f97dc7 100644 --- a/problems/1310.xor-queries-of-a-subarray.md +++ b/problems/1310.xor-queries-of-a-subarray.md @@ -204,6 +204,4 @@ public: - [1186.删除一次得到子数组最大和](https://lucifer.ren/blog/2019/12/11/leetcode-1186/) -大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。 -大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。 -![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg) +大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。 ![](https://p.ipic.vip/n8gbxo.jpg) diff --git a/problems/1332.remove-palindromic-sequences.en.md b/problems/1332.remove-palindromic-sequences.en.md index b0de4c69a..05aa87b55 100644 --- a/problems/1332.remove-palindromic-sequences.en.md +++ b/problems/1332.remove-palindromic-sequences.en.md @@ -55,15 +55,13 @@ Have you encountered this question in a real interview? ## Idea -This is another ”shaking clever" topic. Similar topics are [1297. maximum-number-of-occurrences-of-a-substrate] (https://github.com/azl397985856/leetcode/blob/77db8fa47c7ee0a14b320f7c2d22f7c61ae53c35/problems/1297.maximum-number-of-occurrences-of-a-substring.md ) +This is another ”shaking clever" topic. Similar topics are [1297. maximum-number-of-occurrences-of-a-substrate](https://github.com/azl397985856/leetcode/blob/77db8fa47c7ee0a14b320f7c2d22f7c61ae53c35/problems/1297.maximum-number-of-occurrences-of-a-substring.md) Since there are only two characters a and B. In fact, the most number of eliminations is 2. This is because we can eliminate a sub-sequence each time, instead of eliminating a sub-string. In this way, we can eliminate all 1s first and then all 2s (the same is true for eliminating 2s first), so that it only takes two times to complete. Is it possible to do it 0 times or 1 time? Yes. For example, in the case of one elimination given in the title, the example given in the title is “ababa”. We found that it is actually a palindrome string in itself, so it can be eliminated all at once. Then there is an idea: --If s is a palindrome, then we need to eliminate it once --Otherwise it takes two times --Be sure to pay attention to special circumstances, for empty strings, we need 0 times +-If s is a palindrome, then we need to eliminate it once -Otherwise it takes two times -Be sure to pay attention to special circumstances, for empty strings, we need 0 times If you interpret a palindrome, you only need two pointers to force it. For specific ideas, please refer to [125. Verify palindrome string](./125.valid-palindrome.md) @@ -126,8 +124,7 @@ return 2; **Complexity analysis** --Time complexity:$O(N)$ --Spatial complexity:$O(1)$ +-Time complexity:$O(N)$ -Spatial complexity:$O(1)$ For more questions, please visit my LeetCode questions warehouse:https://github.com/azl397985856/leetcode . There are already 37K stars. diff --git a/problems/1526.minimum-number-of-increments-on-subarrays-to-form-a-target-array.md b/problems/1526.minimum-number-of-increments-on-subarrays-to-form-a-target-array.md index 1b1d3a29c..fe7e576d0 100644 --- a/problems/1526.minimum-number-of-increments-on-subarrays-to-form-a-target-array.md +++ b/problems/1526.minimum-number-of-increments-on-subarrays-to-form-a-target-array.md @@ -27,13 +27,13 @@ https://leetcode-cn.com/problems/minimum-number-of-increments-on-subarrays-to-fo 输入:target = [3,1,1,2] 输出:4 -解释:(initial)[0,0,0,0] -> [1,1,1,1] -> [1,1,1,2] -> [2,1,1,2] -> [3,1,1,2] (target) 。 +解释:(initial)[0,0,0,0] -> [1,1,1,1] -> [1,1,1,2] -> [2,1,1,2] -> [3,1,1,2](target) 。 示例 3: 输入:target = [3,1,5,4,2] 输出:7 解释:(initial)[0,0,0,0,0] -> [1,1,1,1,1] -> [2,1,1,1,1] -> [3,1,1,1,1] - -> [3,1,2,2,2] -> [3,1,3,3,2] -> [3,1,4,4,2] -> [3,1,5,4,2] (target)。 + -> [3,1,2,2,2] -> [3,1,3,3,2] -> [3,1,4,4,2] -> [3,1,5,4,2](target)。 示例 4: 输入:target = [1,1,1,1] @@ -102,8 +102,7 @@ class Solution: return ans ``` -**复杂度分析** -令 N 为数组长度。 +**复杂度分析** 令 N 为数组长度。 - 时间复杂度:$O(N)$ - 空间复杂度:$O(N)$ @@ -128,8 +127,7 @@ class Solution: return ans ``` -**复杂度分析** -令 N 为数组长度。 +**复杂度分析** 令 N 为数组长度。 - 时间复杂度:$O(N)$ - 空间复杂度:$O(1)$ diff --git a/problems/19.removeNthNodeFromEndofList.md b/problems/19.removeNthNodeFromEndofList.md index a10762cd5..1b7f81dd6 100644 --- a/problems/19.removeNthNodeFromEndofList.md +++ b/problems/19.removeNthNodeFromEndofList.md @@ -165,6 +165,4 @@ public: - 时间复杂度:$O(N)$ - 空间复杂度:$O(1)$ -大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。 -大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。 -![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg) +大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 37K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。 ![](https://p.ipic.vip/n8gbxo.jpg) diff --git a/problems/20.valid-parents.en.md b/problems/20.valid-parents.en.md index 628230a92..cfd35679e 100644 --- a/problems/20.valid-parents.en.md +++ b/problems/20.valid-parents.en.md @@ -42,10 +42,7 @@ Output: true ## Company --Ali --Baidu --Tencent --Byte +-Ali -Baidu -Tencent -Byte - airbnb - amazon @@ -60,7 +57,7 @@ Output: true ### Idea -Regarding the idea of this question, Deng Junhui spoke very well. Students who have not seen it can take a look at it. [Video address] (http://www.xuetangx.com/courses/course-v1:TsinghuaX +30240184+sp/courseware/ad1a23c053df4501a3facd66ef6ccfa9/8d6f450e7f7a445098ae1d507fda80f6/). +Regarding the idea of this question, Deng Junhui spoke very well. Students who have not seen it can take a look at it. [Video address](http://www.xuetangx.com/courses/course-v1:TsinghuaX +30240184+sp/courseware/ad1a23c053df4501a3facd66ef6ccfa9/8d6f450e7f7a445098ae1d507fda80f6/). Use the stack to traverse the input string @@ -85,7 +82,7 @@ It is worth noting that if the topic requires only one type of bracket, then we 1. Basic characteristics and operation of the stack 2. You can use arrays to simulate stacks -For example, in: push out: pop is the stack. In: push out shift is the queue. However, the queue implemented by this algorithm has a relatively high time complexity when deleting elements in the header. For details, you can refer to [double-ended queue deque] (https://zh.wikipedia.org/wiki/%E5%8F%8C%E7%AB%AF%E9%98%9F%E5%88%97 ). +For example, in: push out: pop is the stack. In: push out shift is the queue. However, the queue implemented by this algorithm has a relatively high time complexity when deleting elements in the header. For details, you can refer to [double-ended queue deque](https://zh.wikipedia.org/wiki/%E5%8F%8C%E7%AB%AF%E9%98%9F%E5%88%97). ### Code @@ -153,8 +150,7 @@ return len(stack) == 0 **Complexity analysis** --Time complexity:$O(N)$ --Spatial complexity:$O(N)$ +-Time complexity:$O(N)$ -Spatial complexity:$O(N)$ ##O(1) space @@ -198,8 +194,7 @@ return false; **Complexity analysis** --Time complexity:$O(N)$ --Spatial complexity:$O(1)$ +-Time complexity:$O(N)$ -Spatial complexity:$O(1)$ ## Regular matching @@ -226,18 +221,17 @@ JavaScript: ```js var isValid = function (s) { - while (s.includes("[]") || s.includes("()") || s.includes("{}")) { - s = s.replace("[]", "").replace("()", "").replace("{}", ""); - } - s = s.replace("[]", "").replace("()", "").replace("{}", ""); - return s.length === 0; + while (s.includes("[]") || s.includes("()") || s.includes("{}")) { + s = s.replace("[]", "").replace("()", "").replace("{}", ""); + } + s = s.replace("[]", "").replace("()", "").replace("{}", ""); + return s.length === 0; }; ``` **Complexity analysis** --Time complexity: depends on the implementation of the regularization engine --Spatial complexity: depends on the implementation of the regularization engine +-Time complexity: depends on the implementation of the regularization engine -Spatial complexity: depends on the implementation of the regularization engine ## Related topics @@ -245,8 +239,7 @@ var isValid = function (s) { ## Extension --If you are asked to check whether the XML tag is closed, how to check, and further, if you want to implement a simple XML parser, how should you implement it? --In fact, this kind of problem can be further extended. We can parse tag syntax like HTML, such as `

` +-If you are asked to check whether the XML tag is closed, how to check, and further, if you want to implement a simple XML parser, how should you implement it? -In fact, this kind of problem can be further extended. We can parse tag syntax like HTML, such as `

` For more questions, please visit my LeetCode questions warehouse:https://github.com/azl397985856/leetcode . There are already 37K stars. diff --git a/problems/437.path-sum-iii.en.md b/problems/437.path-sum-iii.en.md index c78ca09c7..85ac5f57b 100644 --- a/problems/437.path-sum-iii.en.md +++ b/problems/437.path-sum-iii.en.md @@ -39,18 +39,13 @@ Return 3. Paths with sum equal to 8 have: ## Company --Ali --Tencent --Baidu --Byte +-Ali -Tencent -Baidu -Byte ## Idea -This question requires us to solve the path from any node to the descendant nodes and return it to the specified value. -Note that here, it does not necessarily start from the root node, nor does it necessarily end at the leaf node. +This question requires us to solve the path from any node to the descendant nodes and return it to the specified value. Note that here, it does not necessarily start from the root node, nor does it necessarily end at the leaf node. -A simple idea is to solve it directly recursively. The spatial complexity O(n) and time complexity are between O(nlogn) and O(N^2)., -Specific code: +A simple idea is to solve it directly recursively. The spatial complexity O(n) and time complexity are between O(nlogn) and O(N^2)., Specific code: ```js /** @@ -62,11 +57,11 @@ Specific code: */ // the number of the paths starting from self function helper(root, sum) { - if (root === null) return 0; - const l = helper(root.left, sum - root.val); - const r = helper(root.right, sum - root.val); + if (root === null) return 0; + const l = helper(root.left, sum - root.val); + const r = helper(root.right, sum - root.val); - return l + r + (root.val === sum ? 1 : 0); + return l + r + (root.val === sum ? 1 : 0); } /** * @param {TreeNode} root @@ -74,25 +69,23 @@ function helper(root, sum) { * @return {number} */ var pathSum = function (root, sum) { - // Spatial complexity O(n) Time complexity is between O(nlogn) and O(N^2) - // tag: dfs tree - if (root === null) return 0; - // the number of the paths starting from self - const self = helper(root, sum); - // we don't know the answer, so we just pass it down - const l = pathSum(root.left, sum); - // we don't know the answer, so we just pass it down - const r = pathSum(root.right, sum); - - return self + l + r; + // Spatial complexity O(n) Time complexity is between O(nlogn) and O(N^2) + // tag: dfs tree + if (root === null) return 0; + // the number of the paths starting from self + const self = helper(root, sum); + // we don't know the answer, so we just pass it down + const l = pathSum(root.left, sum); + // we don't know the answer, so we just pass it down + const r = pathSum(root.right, sum); + + return self + l + r; }; ``` -However, there is also an algorithm with better spatial complexity, which uses hashmaps to avoid double calculations. The time complexity and spatial complexity are both O(n). -This idea is an upgraded version of'subarray-sum-equals-k`. If you can solve that question O(n), this question will not be very difficult., -Just replaced the array with a binary tree. For specific ideas, you can see [This topic] (. /560.subarray-sum-equals-k.md ) +However, there is also an algorithm with better spatial complexity, which uses hashmaps to avoid double calculations. The time complexity and spatial complexity are both O(n). This idea is an upgraded version of'subarray-sum-equals-k`. If you can solve that question O(n), this question will not be very difficult., Just replaced the array with a binary tree. For specific ideas, you can see [This topic](. /560.subarray-sum-equals-k.md ) -There is a difference here. Let me explain why there is a 'hashmap[acc] = hashmap[acc] - 1;`, The reason is very simple, that is, when we use DFS, when we go back from the bottom, the value of map should also go back. If you are more familiar with the backtracking method, It should be easy to understand. If you are not familiar with it, you can refer to [this topic] (./46.permutations.md ), this question is through'templist. pop()` is done. +There is a difference here. Let me explain why there is a 'hashmap[acc] = hashmap[acc] - 1;`, The reason is very simple, that is, when we use DFS, when we go back from the bottom, the value of map should also go back. If you are more familiar with the backtracking method, It should be easy to understand. If you are not familiar with it, you can refer to [this topic](./46.permutations.md ), this question is through'templist. pop()` is done. In addition, I drew a picture, I believe you will understand after reading it. @@ -110,8 +103,7 @@ See the code area below for specific implementation. ## Analysis of key points --Exchange space for time through hashmap --For this kind of continuous element summation problem, there is a common idea. You can refer to [This topic] (./560.subarray-sum-equals-k.md ) +-Exchange space for time through hashmap -For this kind of continuous element summation problem, there is a common idea. You can refer to [This topic](./560.subarray-sum-equals-k.md) ## Code @@ -164,8 +156,7 @@ return helper(root, 0, sum, hashmap); **Complexity analysis** --Time complexity:$O(N)$ --Spatial complexity:$O(N)$ +-Time complexity:$O(N)$ -Spatial complexity:$O(N)$ For more questions, please visit my LeetCode questions warehouse:https://github.com/azl397985856/leetcode . There are already 37K stars. diff --git a/problems/525.contiguous-array.md b/problems/525.contiguous-array.md index 3bfb8cae3..80351a054 100644 --- a/problems/525.contiguous-array.md +++ b/problems/525.contiguous-array.md @@ -19,7 +19,7 @@ https://leetcode-cn.com/problems/contiguous-array/ 输入: nums = [0,1,0] 输出: 2 -说明: [0, 1] (或 [1, 0]) 是具有相同数量0和1的最长连续子数组。 +说明: [0, 1](或 [1, 0]) 是具有相同数量0和1的最长连续子数组。   diff --git a/problems/53.maximum-sum-subarray-cn.en.md b/problems/53.maximum-sum-subarray-cn.en.md index 74687e69f..2853e3f92 100644 --- a/problems/53.maximum-sum-subarray-cn.en.md +++ b/problems/53.maximum-sum-subarray-cn.en.md @@ -24,10 +24,7 @@ If you have implemented a solution with a complexity of O(n), try to solve it us ## Company --Ali --Baidu --Byte --Tencent +-Ali -Baidu -Byte -Tencent - bloomberg - linkedin @@ -43,52 +40,43 @@ Under normal circumstances, start with the violent solution analysis, and then c **Original violent solution:**(timeout) -To find the sum of the sub-sequence, then we need to know the position of the beginning and end of the sub-sequence, and then calculate the sum of the sequence between the beginning and the end. Use 2 for loops to enumerate the beginning and end positions of all sub-sequences. -Then use a for loop to solve the sequence sum. The time complexity here is too high,`O(n^3)`. +To find the sum of the sub-sequence, then we need to know the position of the beginning and end of the sub-sequence, and then calculate the sum of the sequence between the beginning and the end. Use 2 for loops to enumerate the beginning and end positions of all sub-sequences. Then use a for loop to solve the sequence sum. The time complexity here is too high,`O(n^3)`. **Complexity analysis** --Time complexity:$O(N^3)$, where N is the length of the array --Spatial complexity:$O(1)$ +-Time complexity:$O(N^3)$, where N is the length of the array -Spatial complexity:$O(1)$ #### Solution 2-Prefix and + Violent solution **Optimized violent solution:** (shocked, actually AC) -On the basis of the violent solution, we can optimize the violent solution`O(n^2)` with the prefix sum, where space is exchanged for time. -Here you can use the original array to represent`PrefixSum`, saving space. +On the basis of the violent solution, we can optimize the violent solution`O(n^2)` with the prefix sum, where space is exchanged for time. Here you can use the original array to represent`PrefixSum`, saving space. -Finding the sequence sum can be optimized with the prefix sum (`PrefixSum`), given the beginning and end positions of the sub-sequence`(l, r),` -Then the sequence and'subarraysum=PrefixSum[r]-PrefixSum[l-1];` Use a global variable'maxSum` to compare the sum of the sub-sequences solved each time,`maxSum = max(maxSum, subarraySum)'. +Finding the sequence sum can be optimized with the prefix sum (`PrefixSum`), given the beginning and end positions of the sub-sequence`(l, r),` Then the sequence and'subarraysum=PrefixSum[r]-PrefixSum[l-1];` Use a global variable'maxSum` to compare the sum of the sub-sequences solved each time,`maxSum = max(maxSum, subarraySum)'. **Complexity analysis** --Time complexity:$O(N^2)$, where N is the length of the array --Spatial complexity:$O(N)$ +-Time complexity:$O(N^2)$, where N is the length of the array -Spatial complexity:$O(N)$ > If you change the original array to represent prefixes and arrays, the spatial complexity is reduced to `O(1)` However, the time complexity is still too high, and can it be more optimized? The answer is yes, the prefix sum can also be optimized to`O(n)`. -####Solution 3-Optimize the prefix and -from [**@lucifer**] (https://github.com/azl397985856 ) +####Solution 3-Optimize the prefix and -from [**@lucifer**](https://github.com/azl397985856) We define the function's(i)`, its function is to calculate the value starting from `0(including 0)` and adding to`i(including i)`. Then's(j)-S(i-1)`is equal to the value from`i`(including i) to`j` (including j). -We further analyze, in fact, we only need to traverse once to calculate all's(i)`, where'i= 0,1,2,. . . . ,n-1. ` -Then we subtract the previous's(k)`, where'k= 0,1,2,. . . , i-1`, the minimum value can be. So we need -Use a variable to maintain this minimum value, and also need a variable to maintain the maximum value. +We further analyze, in fact, we only need to traverse once to calculate all's(i)`, where'i= 0,1,2,. . . . ,n-1. ` Then we subtract the previous's(k)`, where'k= 0,1,2,. . . , i-1`, the minimum value can be. So we need Use a variable to maintain this minimum value, and also need a variable to maintain the maximum value. **Complexity analysis** --Time complexity:$O(N)$, where N is the length of the array --Spatial complexity:$O(1)$ +-Time complexity:$O(N)$, where N is the length of the array -Spatial complexity:$O(1)$ -#### Solution 4-[Partition Method] (https://www.wikiwand.com/zh-hans/%E5%88%86%E6%B2%BB%E6%B3%95 ) +#### Solution 4-[Partition Method](https://www.wikiwand.com/zh-hans/%E5%88%86%E6%B2%BB%E6%B3%95) -We divide the array "nums" into two parts: left ("left") and right ("right") at the middle position ("m"). Then there is, -`left = nums[0]. . . nums[m-1]` and'return = nums[m + 1]. . . nums[n-1]` +We divide the array "nums" into two parts: left ("left") and right ("right") at the middle position ("m"). Then there is, `left = nums[0]. . . nums[m-1]` and'return = nums[m + 1]. . . nums[n-1]` There are three situations where the position of the largest sub-sequence sum is as follows: @@ -98,22 +86,19 @@ There are three situations where the position of the largest sub-sequence sum is The sum of the largest sub-sequences in the three cases is obtained separately, and the largest value of the three is the sum of the largest sub-sequences. -For example, as shown in the figure below: -![](https://p.ipic.vip/8i530l.jpg) +For example, as shown in the figure below: ![](https://p.ipic.vip/8i530l.jpg) **Complexity analysis** --Time complexity:$O(NlogN)$, where N is the length of the array --Spatial complexity:$O(logN)$ +-Time complexity:$O(NlogN)$, where N is the length of the array -Spatial complexity:$O(logN)$ -####Solution 5-[Dynamic Planning] (https://www.wikiwand.com/zh-hans/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92 ) +####Solution 5-[Dynamic Planning](https://www.wikiwand.com/zh-hans/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92) The difficulty of dynamic programming is to find the state transition equation, 'dp[i]-represents the maximum sub-sequence sum to the current position i` -The state transition equation is: -`dp[i] = max(dp[i - 1] + nums[i], nums[i])` +The state transition equation is: `dp[i] = max(dp[i - 1] + nums[i], nums[i])` Initialization:`dp[0] = nums[0]` @@ -126,13 +111,11 @@ From the state transition equation, we only focus on the value of the previous s - `currMaxSum = max(currMaxSum + nums[i], nums[i])` - `maxSum = max(currMaxSum, maxSum)` -As shown in the figure: -![](https://p.ipic.vip/1l599b.jpg) +As shown in the figure: ![](https://p.ipic.vip/1l599b.jpg) **Complexity analysis** --Time complexity:$O(N)$, where N is the length of the array --Spatial complexity:$O(1)$ +-Time complexity:$O(N)$, where N is the length of the array -Spatial complexity:$O(1)$ ## Analysis of key Points @@ -186,20 +169,20 @@ _Javascript code_ from [**@lucifer**](https://github.com/azl397985856) ```javascript function LSS(list) { - const len = list.length; - let max = -Number.MAX_VALUE; - let sum = 0; - for (let i = 0; i < len; i++) { - sum = 0; - for (let j = i; j < len; j++) { - sum += list[j]; - if (sum > max) { - max = sum; - } - } - } - - return max; + const len = list.length; + let max = -Number.MAX_VALUE; + let sum = 0; + for (let i = 0; i < len; i++) { + sum = 0; + for (let j = i; j < len; j++) { + sum += list[j]; + if (sum > max) { + max = sum; + } + } + } + + return max; } ``` @@ -246,19 +229,19 @@ _Javascript code_ from [**@lucifer**](https://github.com/azl397985856) ```javascript function LSS(list) { - const len = list.length; - let max = list[0]; - let min = 0; - let sum = 0; - for (let i = 0; i < len; i++) { - sum += list[i]; - if (sum - min > max) max = sum - min; - if (sum < min) { - min = sum; - } - } - - return max; + const len = list.length; + let max = list[0]; + let min = 0; + let sum = 0; + for (let i = 0; i < len; i++) { + sum += list[i]; + if (sum - min > max) max = sum - min; + if (sum < min) { + min = sum; + } + } + + return max; } ``` @@ -327,30 +310,30 @@ _Javascript code_ from [**@lucifer**](https://github.com/azl397985856) ```javascript function helper(list, m, n) { - if (m === n) return list[m]; - let sum = 0; - let lmax = -Number.MAX_VALUE; - let rmax = -Number.MAX_VALUE; - const mid = ((n - m) >> 1) + m; - const l = helper(list, m, mid); - const r = helper(list, mid + 1, n); - for (let i = mid; i >= m; i--) { - sum += list[i]; - if (sum > lmax) lmax = sum; - } - - sum = 0; - - for (let i = mid + 1; i <= n; i++) { - sum += list[i]; - if (sum > rmax) rmax = sum; - } - - return Math.max(l, r, lmax + rmax); + if (m === n) return list[m]; + let sum = 0; + let lmax = -Number.MAX_VALUE; + let rmax = -Number.MAX_VALUE; + const mid = ((n - m) >> 1) + m; + const l = helper(list, m, mid); + const r = helper(list, mid + 1, n); + for (let i = mid; i >= m; i--) { + sum += list[i]; + if (sum > lmax) lmax = sum; + } + + sum = 0; + + for (let i = mid + 1; i <= n; i++) { + sum += list[i]; + if (sum > rmax) rmax = sum; + } + + return Math.max(l, r, lmax + rmax); } function LSS(list) { - return helper(list, 0, list.length - 1); + return helper(list, 0, list.length - 1); } ``` @@ -390,28 +373,26 @@ _Javascript code_ from [**@lucifer**](https://github.com/azl397985856) ```javascript function LSS(list) { - const len = list.length; - let max = list[0]; - for (let i = 1; i < len; i++) { - list[i] = Math.max(0, list[i - 1]) + list[i]; - if (list[i] > max) max = list[i]; - } - - return max; + const len = list.length; + let max = list[0]; + for (let i = 1; i < len; i++) { + list[i] = Math.max(0, list[i - 1]) + list[i]; + if (list[i] > max) max = list[i]; + } + + return max; } ``` ## Extension --If the array is a two-dimensional array, find the sum of the largest subarrays? --If the product of the largest sub-sequence is required? +-If the array is a two-dimensional array, find the sum of the largest subarrays? -If the product of the largest sub-sequence is required? ## Similar questions - [Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/) - [Longest Turbulent Subarray](https://leetcode.com/problems/longest-turbulent-subarray/) -If you have any comments on this, please leave me a message. I will check the answers one by one when I have time. For more algorithm routines, you can visit my LeetCode problem solving warehouse:https://github.com/azl397985856/leetcode . There are already 37K stars. -You can also pay attention to my public account "Force Buckle Plus" to take you to chew off the hard bone of the algorithm. +If you have any comments on this, please leave me a message. I will check the answers one by one when I have time. For more algorithm routines, you can visit my LeetCode problem solving warehouse:https://github.com/azl397985856/leetcode . There are already 37K stars. You can also pay attention to my public account "Force Buckle Plus" to take you to chew off the hard bone of the algorithm. -![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg) +![](https://p.ipic.vip/n8gbxo.jpg) diff --git a/problems/binode-lcci.en.md b/problems/binode-lcci.en.md index 20eb520e0..07c5d157d 100644 --- a/problems/binode-lcci.en.md +++ b/problems/binode-lcci.en.md @@ -24,8 +24,7 @@ The number of nodes will not exceed 100,000. ## Pre-knowledge --Binary search tree --Recursion -[Binary tree traversal] (../thinkings/binary-tree-traversal.md) +-Binary search tree -Recursion -[Binary tree traversal](../thinkings/binary-tree-traversal.md) ## Company @@ -100,8 +99,7 @@ dfs(root. right) ## Key points --Pointer operation --Processing of return values +-Pointer operation -Processing of return values ## Code @@ -124,8 +122,7 @@ return self. ans **Complexity analysis** --Time complexity:$O(N)$, where N is the total number of nodes in the tree. --Spatial complexity:$O(h)$, where h is the height of the tree. +-Time complexity:$O(N)$, where N is the total number of nodes in the tree. -Spatial complexity:$O(h)$, where h is the height of the tree. ## Related topics @@ -133,7 +130,6 @@ return self. ans - [92.reverse-linked-list-ii](./92.reverse-linked-list-ii.md) - [25.reverse-nodes-in-k-groups-cn](./25.reverse-nodes-in-k-groups.md) -If you have any comments on this, please leave me a message. I will check the answers one by one when I have time. For more algorithm routines, you can visit my LeetCode problem solving warehouse:https://github.com/azl397985856/leetcode . There are already 37K stars. -You can also pay attention to my public account "Force Buckle Plus" to take you to chew off the hard bone of the algorithm. +If you have any comments on this, please leave me a message. I will check the answers one by one when I have time. For more algorithm routines, you can visit my LeetCode problem solving warehouse:https://github.com/azl397985856/leetcode . There are already 37K stars. You can also pay attention to my public account "Force Buckle Plus" to take you to chew off the hard bone of the algorithm. ![](https://p.ipic.vip/70qh9q.jpg) diff --git a/selected/atMostK.md b/selected/atMostK.md index d057e999c..d27a0be5d 100644 --- a/selected/atMostK.md +++ b/selected/atMostK.md @@ -623,4 +623,4 @@ class Solution: 大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。 -![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg) +![](https://p.ipic.vip/n8gbxo.jpg) diff --git a/thinkings/DFS.en.md b/thinkings/DFS.en.md index f04e4a56b..fae69df54 100644 --- a/thinkings/DFS.en.md +++ b/thinkings/DFS.en.md @@ -19,8 +19,7 @@ The concept of DFS comes from graph theory, but there are still some differences 1. First put the root node in the **stack**. 2. Take the first node from _stack_ and verify whether it is the target. If the target is found, the search ends and the result is returned. Otherwise, add one of its direct child nodes that have not been tested to the stack. 3. Repeat Step 2. -4. If there is no direct child node that has not been detected. Add the previous node to the **stack**. - Repeat Step 2. +4. If there is no direct child node that has not been detected. Add the previous node to the **stack**. Repeat Step 2. 5. Repeat step 4. 6. If **stack** is empty, it means that the entire picture has been checked-that is, there are no targets to search for in the picture. End the search and return “Target not found". @@ -48,7 +47,7 @@ dfs(j) These are a few DFS topics that I recently summarized, and will continue to be updated in the future~ -- [200. Number of islands] (https://leetcode-cn.com/problems/number-of-islands/solution/mo-ban-ti-dao-yu-dfspython3-by-fe-lucifer-2 /) Medium +- [200. Number of islands](https://leetcode-cn.com/problems/number-of-islands/solution/mo-ban-ti-dao-yu-dfspython3-by-fe-lucifer-2 /) Medium -- [695. The largest area of the island] (https://leetcode-cn.com/problems/max-area-of-island/solution/mo-ban-ti-dao-yu-dfspython3-by-fe-lucifer /) Medium -- [979. Allocate coins in a binary tree] (https://leetcode-cn.com/problems/distribute-coins-in-binary-tree/solution/tu-jie-dfspython3-by-fe-lucifer /) Medium +- [695. The largest area of the island](https://leetcode-cn.com/problems/max-area-of-island/solution/mo-ban-ti-dao-yu-dfspython3-by-fe-lucifer /) Medium +- [979. Allocate coins in a binary tree](https://leetcode-cn.com/problems/distribute-coins-in-binary-tree/solution/tu-jie-dfspython3-by-fe-lucifer /) Medium diff --git a/thinkings/GCD.en.md b/thinkings/GCD.en.md index 7c8835cc1..bb2eb291b 100644 --- a/thinkings/GCD.en.md +++ b/thinkings/GCD.en.md @@ -4,9 +4,9 @@ There is a special study on the greatest common divisor. Although in LeetCode, t For example: -- [914. Card grouping] (https://leetcode-cn.com/problems/x-of-a-kind-in-a-deck-of-cards/solution/python3-zui-da-gong-yue-shu-914-qia-pai-fen-zu-by -/ "914. Card grouping") +- [914. Card grouping](https://leetcode-cn.com/problems/x-of-a-kind-in-a-deck-of-cards/solution/python3-zui-da-gong-yue-shu-914-qia-pai-fen-zu-by -/ "914. Card grouping") - [365. Kettle problem) (https://leetcode-cn.com/problems/water-and-jug-problem/solution/bfszui-da-gong-yue-shu-by-fe-lucifer /"365. Kettle problem") -- [1071. The greatest common factor of a string] (https://leetcode-cn.com/problems/greatest-common-divisor-of-strings/solution/1071-zi-fu-chuan-de-zui-da-gong-yin-zi-zui-da-gong / "1071. The greatest common factor of the string") +- [1071. The greatest common factor of a string](https://leetcode-cn.com/problems/greatest-common-divisor-of-strings/solution/1071-zi-fu-chuan-de-zui-da-gong-yin-zi-zui-da-gong / "1071. The greatest common factor of the string") Therefore, how to solve the greatest common divisor is important. @@ -25,8 +25,7 @@ smaller -= 1 **Complexity analysis** --Time complexity: The best case scenario is to execute a loop body, and the worst case scenario is to loop to a smaller of 1, so the total time complexity is $O(N)$, where N is the smaller number in a and B. --Spatial complexity:$O(1)$. +-Time complexity: The best case scenario is to execute a loop body, and the worst case scenario is to loop to a smaller of 1, so the total time complexity is $O(N)$, where N is the smaller number in a and B. -Spatial complexity:$O(1)$. ### Tossing and dividing @@ -39,8 +38,7 @@ return a if b == 0 else GCD(b, a % b) **Complexity analysis** --Time complexity:$O(log(max(a,b)))$ --Spatial complexity: Spatial complexity depends on the depth of recursion, so the spatial complexity is $O(log(max(a, b)))$ +-Time complexity:$O(log(max(a,b)))$ -Spatial complexity: Spatial complexity depends on the depth of recursion, so the spatial complexity is $O(log(max(a, b)))$ ### More phase derogation technique @@ -99,7 +97,7 @@ Note: We agree that the first of the ordered sequence will always be 1. ### Idea -You can go through [this website] (https://binarysearch.com/problems/Divisible-Numbers "binary search") Online verification. +You can go through [this website](https://binarysearch.com/problems/Divisible-Numbers "binary search") Online verification. A simple idea is to use a heap to do it. The only thing to pay attention to is the deletions. We can use a hash table to record the numbers that have appeared in order to achieve the purpose of deletions. @@ -138,9 +136,7 @@ In order to solve this problem, we can use the knowledge of set theory. Gather a little bit of knowledge: --If the set of values in the ordered sequence that are less than or equal to x can be divisible by x and are multiples of A is SA, the size of the set is A --If the set of values in the ordered sequence that are less than or equal to x can be divisible by x and are multiples of B is SB, the size of the set is B --If the set of values in an ordered sequence that are less than or equal to x that can be divisible by x and are multiples of C is SC, the size of the set is C +-If the set of values in the ordered sequence that are less than or equal to x can be divisible by x and are multiples of A is SA, the size of the set is A -If the set of values in the ordered sequence that are less than or equal to x can be divisible by x and are multiples of B is SB, the size of the set is B -If the set of values in an ordered sequence that are less than or equal to x that can be divisible by x and are multiples of C is SC, the size of the set is C Then the final answer is the number of numbers in the large set (which needs to be duplicated) composed of SA, SB, and SC, that is,: @@ -160,7 +156,7 @@ return x * y // gcd(x, y) ``` -The next step is the two-part routine. If you can't understand the two-part part, please take a look at my [two-part topic] (https://github.com/azl397985856/leetcode/blob/master/91/binary-search.md "Two-part special"). +The next step is the two-part routine. If you can't understand the two-part part, please take a look at my [two-part topic](https://github.com/azl397985856/leetcode/blob/master/91/binary-search.md "Two-part special"). ### Code (Python3) @@ -191,11 +187,10 @@ return l **Complexity analysis** --Time complexity:$logn$. --Spatial complexity: The depth of the recursive tree of gcd and lcm is basically negligible. +-Time complexity:$logn$. -Spatial complexity: The depth of the recursive tree of gcd and lcm is basically negligible. ## Summary -Through this article, we not only understand the concept of the greatest common divisor and the method of finding it. It also visually perceives the **principle** of the calculation of the greatest common divisor. The greatest common divisor and the least common multiple are two similar concepts. There are not many questions about the greatest common divisor and the least common multiple in Li Buckle. You can find these questions through the Mathematics tab. For more information about mathematics knowledge in algorithms, you can refer to this article [Summary of mathematics test points necessary for brushing algorithm questions] (https://mp.weixin.qq.com/s?__biz=MzI4MzUxNjI3OA==&mid=2247485590&idx=1&sn=e3f13aa02fed4d4132146e193eb17cdb&chksm=eb88c48fdcff4d99b44d537459396589b8987f89a8c21085a945ca8d5e2b0b140c13aef81d91&token=1223087516&lang=zh_CN#rd "Summary of math test points necessary for brushing algorithm questions") +Through this article, we not only understand the concept of the greatest common divisor and the method of finding it. It also visually perceives the **principle** of the calculation of the greatest common divisor. The greatest common divisor and the least common multiple are two similar concepts. There are not many questions about the greatest common divisor and the least common multiple in Li Buckle. You can find these questions through the Mathematics tab. For more information about mathematics knowledge in algorithms, you can refer to this article [Summary of mathematics test points necessary for brushing algorithm questions](https://mp.weixin.qq.com/s?__biz=MzI4MzUxNjI3OA==&mid=2247485590&idx=1&sn=e3f13aa02fed4d4132146e193eb17cdb&chksm=eb88c48fdcff4d99b44d537459396589b8987f89a8c21085a945ca8d5e2b0b140c13aef81d91&token=1223087516&lang=zh_CN#rd "Summary of math test points necessary for brushing algorithm questions") > The second part of this article will also be released soon. diff --git a/thinkings/README.en.md b/thinkings/README.en.md index 60359010a..91c34b668 100644 --- a/thinkings/README.en.md +++ b/thinkings/README.en.md @@ -1,6 +1,6 @@ # Algorithm Topic -The following are some types of questions that I have summarized. Understanding these things in advance is very helpful for future questions. It is strongly recommended to master them first. In addition, my 91-day learning algorithm has also organized the topic at a more granular level. For example, [91-day Learning Algorithm] (. . /91/Readme. md) +The following are some types of questions that I have summarized. Understanding these things in advance is very helpful for future questions. It is strongly recommended to master them first. In addition, my 91-day learning algorithm has also organized the topic at a more granular level. For example, [91-day Learning Algorithm](. . /91/Readme. md) First of all, everyone must master the basic data structure, and secondly, the violent method. Brute force is also an algorithm, but what we are pursuing is definitely an algorithm with better performance. Therefore, it is important to understand the algorithm bottleneck of brute force and the characteristics of various data structures, so that you can use this knowledge to approach the optimal solution step by step. @@ -10,26 +10,4 @@ There is also the violent optimization method that must be mastered. Like search If you study around this idea, it won't be too bad. I won't say much about the others. Everyone will slowly appreciate it. --[Data cable](basic-data-structure.en.md) --[acyl](linked-list.en.md) --[Tree topic](tree.en.md) --[Top(top)](heap.en.md) --[Next)](heap-2.en.md) --[Abne four points (wish)](binary-search-1.en.md) --[Twenty-four points (Part 2)](binary-search-2.en.md) --[Supernova](binary-tree-traversal.en.md) --[Dynamic](dynamic-programming.en.md) --[backtracking](backtrack.en.md) -(Occupation)run-length-encode-and-huffman-encode.en.md) --[bloom filter](bloom filter. md) --[Prefix tree(trie. md) --[My vocational class](https://lucifer.ren/blog/2020/02/03/leetcode-%E6%88%91%E7%9A%84%E6%97%A5%E7%A8%8B%E5%AE%89%E6%8E%92%E8%A1%A8%E7%B3%BB%E5%88%97/) --[Structure 2]([https://lucifer . . . Ren/Blog/2020/02/08/ %E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%93%E9%A2%98/](https://lucifer.ren/blog/2020/02/08/%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%93%E9%A2%98/)) --[Stressful pressure (pressure + pressure)](slide-window.en.md) --[Recruitment position](bit.en.md) --[Island problem] (island. md) --[Journey of Wisdom](GCD.en.md) --[Union](union-find.en.md) --[Second](balanced-tree.en.md) --[One pumping](reservoid-sampling.en.md) --[single](monotone-stack.en.md) \ No newline at end of file +-[Data cable](basic-data-structure.en.md) -[acyl](linked-list.en.md) -[Tree topic](tree.en.md) -[Top(top)](heap.en.md) -[Next)](heap-2.en.md) -[Abne four points (wish)](binary-search-1.en.md) -[Twenty-four points (Part 2)](binary-search-2.en.md) -[Supernova](binary-tree-traversal.en.md) -[Dynamic](dynamic-programming.en.md) -[backtracking](backtrack.en.md) (Occupation)run-length-encode-and-huffman-encode.en.md) -[bloom filter](bloom filter. md) -[Prefix tree(trie. md) -[My vocational class](https://lucifer.ren/blog/2020/02/03/leetcode-%E6%88%91%E7%9A%84%E6%97%A5%E7%A8%8B%E5%AE%89%E6%8E%92%E8%A1%A8%E7%B3%BB%E5%88%97/) -[Structure 2]([https://lucifer . . . Ren/Blog/2020/02/08/ %E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%93%E9%A2%98/](https://lucifer.ren/blog/2020/02/08/%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%93%E9%A2%98/)) -[Stressful pressure (pressure + pressure)](slide-window.en.md) -[Recruitment position](bit.en.md) -[Island problem](island. md) -[Journey of Wisdom](GCD.en.md) -[Union](union-find.en.md) -[Second](balanced-tree.en.md) -[One pumping](reservoid-sampling.en.md) -[single](monotone-stack.en.md) diff --git a/thinkings/backtrack.en.md b/thinkings/backtrack.en.md index efcd25df7..8578c7da4 100644 --- a/thinkings/backtrack.en.md +++ b/thinkings/backtrack.en.md @@ -1,6 +1,6 @@ # Backtracking -Backtracking is a technique in DFS. The backtracking method adopts [trial and error] (https://zh.wikipedia.org/wiki/%E8%AF%95%E9%94%99 ) The thought, it tries to solve a problem step by step. In the process of step-by-step problem solving, when it finds that the existing step-by-step answers cannot be effectively answered correctly by trying, it will cancel the previous step or even the calculation of the previous few steps, and then try again to find the answer to the question through other possible step-by-step answers. +Backtracking is a technique in DFS. The backtracking method adopts [trial and error](https://zh.wikipedia.org/wiki/%E8%AF%95%E9%94%99) The thought, it tries to solve a problem step by step. In the process of step-by-step problem solving, when it finds that the existing step-by-step answers cannot be effectively answered correctly by trying, it will cancel the previous step or even the calculation of the previous few steps, and then try again to find the answer to the question through other possible step-by-step answers. In layman's terms, backtracking is an algorithm that turns back if you can't get there. @@ -67,7 +67,7 @@ Another test point for backtracking questions is pruning. By pruning properly, t The skills of pruning in each question are different, but a simple principle is to avoid recursion that cannot be the answer at all. -For example: [842. Split the array into a Fibonacci sequence] (https://leetcode-cn.com/problems/split-array-into-fibonacci-sequence /) +For example: [842. Split the array into a Fibonacci sequence](https://leetcode-cn.com/problems/split-array-into-fibonacci-sequence /) Title description: @@ -167,7 +167,7 @@ Reference title: - [140. Word Split II](https://github.com/azl397985856/leetcode/blob/master/problems/140.word-break-ii.md) - [401. Binary watch](../problems/401.binary-watch.md) -- [816. Fuzzy coordinates] (https://github.com/azl397985856/leetcode/blob/master/problems/816.ambiguous-coordinates.md ) +- [816. Fuzzy coordinates](https://github.com/azl397985856/leetcode/blob/master/problems/816.ambiguous-coordinates.md) This kind of problem is different from subsets and permutations. The combination is regular. We can use the Cartesian product formula to combine two or more subsets. diff --git a/thinkings/basic-data-structure.en.md b/thinkings/basic-data-structure.en.md index 6da214272..4b59115d4 100644 --- a/thinkings/basic-data-structure.en.md +++ b/thinkings/basic-data-structure.en.md @@ -28,23 +28,23 @@ So why do hooks use arrays? We can explain from another perspective, what would ```js function Form() { - // 1. Use the name state variable - const [name, setName] = useState("Mary"); + // 1. Use the name state variable + const [name, setName] = useState("Mary"); - // 2. Use an effect for persisting the form - useEffect(function persistForm() { - localStorage.setItem("formData", name); - }); + // 2. Use an effect for persisting the form + useEffect(function persistForm() { + localStorage.setItem("formData", name); + }); - // 3. Use the surname state variable - const [surname, setSurname] = useState("Poppins"); + // 3. Use the surname state variable + const [surname, setSurname] = useState("Poppins"); - // 4. Use an effect for updating the title - useEffect(function updateTitle() { - document.title = name + " " + surname; - }); + // 4. Use an effect for updating the title + useEffect(function updateTitle() { + document.title = name + " " + surname; + }); - // . . . + // . . . } ``` @@ -63,7 +63,7 @@ If you don't use arrays to implement, such as objects, the hooks of Form are } ``` -So the question is how to take key1, key2, key3, and key4? This is a problem. For more research on the nature of React hooks, please check [React hooks: not magic, just arrays] (https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e ) +So the question is how to take key1, key2, key3, and key4? This is a problem. For more research on the nature of React hooks, please check [React hooks: not magic, just arrays](https://medium.com/@ryardley/react-hooks-not-magic-just-arrays-cd4f1857236e) However, there is also a problem with using arrays. That is, React has left the task of `how to ensure the correspondence between the states saved by Hooks inside the component'to the developer to ensure, that is, you must ensure that the order of hooks is strictly consistent. For details, please refer to React's official website in the Hooks Rule section. @@ -79,8 +79,7 @@ In computer science, a queue is a special type of abstract data type or collecti There are two basic queue operations: --Add an entity to the backend location of the queue, which is called queuing --Removing an entity from the front end of the queue is called dequeue. +-Add an entity to the backend location of the queue, which is called queuing -Removing an entity from the front end of the queue is called dequeue. Schematic diagram of FIFO (first in, first out) for elements in the queue: @@ -122,7 +121,7 @@ The frame transmission method can divide the data of the request and response in `Multiplexing` is used to replace the original sequence and congestion mechanism. In 'HTTP/1.1`, multiple TCP links are required for multiple simultaneous requests, and a single domain name has a limit of 6-8 TCP link requests (this limit is restricted by the browser, and different browsers may not be the same). In 'HTTP/2`, all communications under the same domain name are completed on a single link, occupying only one TCP link, and requests and responses can be made in parallel on this link without interfering with each other. -> [This website] (https://http2.akamai.com/demo ) You can intuitively feel the performance comparison between 'HTTP/1.1' and`HTTP/2'. +> [This website](https://http2.akamai.com/demo) You can intuitively feel the performance comparison between 'HTTP/1.1' and`HTTP/2'. ### Stack @@ -130,8 +129,7 @@ The stack is also a kind of restricted sequence. When it is restricted, it is li In computer science, a stack is an abstract data type that is used to represent a collection of elements and has two main operations.: --push, add elements to the top (end) of the stack --pop, remove the element at the top (end) of the stack +-push, add elements to the top (end) of the stack -pop, remove the element at the top (end) of the stack The above two operations can be simply summarized as ** last in, first out (LIFO =last in, first out)**. @@ -147,20 +145,19 @@ Schematic diagram of the push and pop operations of the stack: #### Stack application (non-front-end caution) -Stacks have applications in many places. For example, familiar browsers have many stacks. In fact, the execution stack of the browser is a basic stack structure. From the data structure point of view, it is a stack. -This also explains that our recursive solution is essentially the same as the loop +stack solution. +Stacks have applications in many places. For example, familiar browsers have many stacks. In fact, the execution stack of the browser is a basic stack structure. From the data structure point of view, it is a stack. This also explains that our recursive solution is essentially the same as the loop +stack solution. For example, the following JS code: ```js function bar() { - const a = 1; - const b = 2; - console.log(a, b); + const a = 1; + const b = 2; + console.log(a, b); } function foo() { - const a = 1; - bar(); + const a = 1; + bar(); } foo(); @@ -208,38 +205,35 @@ React must re-implement the algorithm for traversing the tree, from relying on a > Andrew said this: If you only rely on the [built-in] call stack, it will continue to work until the stack is empty. -Wouldn't it be great if we could interrupt the call stack at will and manipulate the stack frame manually? -This is the purpose of React Fiber. `Fiber is a re-implementation of the stack, dedicated to React components`. You can think of a single Fiber as a `virtual stack frame`. +Wouldn't it be great if we could interrupt the call stack at will and manipulate the stack frame manually? This is the purpose of React Fiber. `Fiber is a re-implementation of the stack, dedicated to React components`. You can think of a single Fiber as a `virtual stack frame`. react fiber is probably like this: ```js let fiber = { - tag: HOST_COMPONENT, - type: "div", - return: parentFiber, - children: childFiber, - sibling: childFiber, - alternate: currentFiber, - stateNode: document.createElement("div"), - props: { children: [], className: "foo" }, - partialState: null, - effectTag: PLACEMENT, - effects: [], + tag: HOST_COMPONENT, + type: "div", + return: parentFiber, + children: childFiber, + sibling: childFiber, + alternate: currentFiber, + stateNode: document.createElement("div"), + props: { children: [], className: "foo" }, + partialState: null, + effectTag: PLACEMENT, + effects: [], }; ``` -It can be seen from this that fiber is essentially an object. Use the parent, child, and sibling attributes to build a fiber tree to represent the structure tree of the component., -Return, children, sibling are also all fibers, so fiber looks like a linked list. +It can be seen from this that fiber is essentially an object. Use the parent, child, and sibling attributes to build a fiber tree to represent the structure tree of the component., Return, children, sibling are also all fibers, so fiber looks like a linked list. -> Attentive friends may have discovered that alternate is also a fiber, so what is it used for? -> Its principle is actually a bit like git, which can be used to perform operations such as git revert, git commit, etc. This part is very interesting. I will explain it in my "Developing git from Scratch". +> Attentive friends may have discovered that alternate is also a fiber, so what is it used for? Its principle is actually a bit like git, which can be used to perform operations such as git revert, git commit, etc. This part is very interesting. I will explain it in my "Developing git from Scratch". -Friends who want to know more can read [this article] (https://github.com/dawn-plex/translate/blob/master/articles/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-to-walk-the-components-tree.md ) +Friends who want to know more can read [this article](https://github.com/dawn-plex/translate/blob/master/articles/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-to-walk-the-components-tree.md) -If you can go over the wall, you can read [original English] (https://medium.com/react-in-depth/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-67f1014d0eb7 ) +If you can go over the wall, you can read [original English](https://medium.com/react-in-depth/the-how-and-why-on-reacts-usage-of-linked-list-in-fiber-67f1014d0eb7) -[This article] (https://engineering.hexacta.com/didact-fiber-incremental-reconciliation-b2fe028dcaec ) It is also an excellent early article on fiber architecture +[This article](https://engineering.hexacta.com/didact-fiber-incremental-reconciliation-b2fe028dcaec) It is also an excellent early article on fiber architecture I am also currently writing about the fiber architecture part of the "react Series of Tutorials for Developing react from Scratch". If you are interested in the specific implementation, please pay attention. @@ -253,8 +247,7 @@ The application of trees is also very extensive. They can be expressed as tree s A tree is actually a special kind of `graph', which is a kind of acutely connected graph, a maximal acutely connected graph, and a minimally connected graph. -From another perspective, a tree is a recursive data structure. Moreover, different representation methods of trees, such as the less commonly used "eldest son + brother" method, are for -Your understanding of the data structure of trees is of great use, and it is not an exaggeration to say that it is a deeper understanding of the nature of trees. +From another perspective, a tree is a recursive data structure. Moreover, different representation methods of trees, such as the less commonly used "eldest son + brother" method, are for Your understanding of the data structure of trees is of great use, and it is not an exaggeration to say that it is a deeper understanding of the nature of trees. The basic algorithms of the tree include front, middle and back sequence traversal and hierarchical traversal. Some students are relatively vague about the access order of the three specific manifestations of the front, middle and back. In fact, I was the same at the beginning. I learned a little later. You just need to remember: `The so-called front, middle and back refer to the position of the root node, and the other positions can be arranged according to the first left and then right`. For example, the pre-sequence traversal is `root left and right", the middle sequence is `left root right", and the post-sequence is `left and right root`, isn't it simple? @@ -266,18 +259,15 @@ However, the performance of recursion in computers has always been problematic, The important nature of the tree: --If the tree has n nodes, then it has n-1 edges, which shows that the number of nodes and edges of the tree are of the same order. --There is a `unique` path from any node to the root node, the length of the path is the depth of the node +-If the tree has n nodes, then it has n-1 edges, which shows that the number of nodes and edges of the tree are of the same order. -There is a `unique` path from any node to the root node, the length of the path is the depth of the node The actual tree used may be more complicated. For example, a quadtree or octree may be used for collision detection in games. And the k-dimensional tree structure`k-d tree` and so on. -![](https://p.ipic.vip/2kuyc2.jpg) -(Picture from https://zh.wikipedia.org/wiki/K-d%E6%A0%91 ) +![](https://p.ipic.vip/2kuyc2.jpg) (Picture from https://zh.wikipedia.org/wiki/K-d%E6%A0%91 ) ### Binary tree -A binary tree is a tree with no more than two nodes, and it is a special subset of trees. Interestingly, the restricted tree structure of a binary tree can represent and realize all trees., -The principle behind it is the "eldest son + brother" method. In Teacher Deng's words, "A binary tree is a special case of a multi-pronged tree, but when it has roots and is orderly, its descriptive ability is sufficient to cover the latter." +A binary tree is a tree with no more than two nodes, and it is a special subset of trees. Interestingly, the restricted tree structure of a binary tree can represent and realize all trees., The principle behind it is the "eldest son + brother" method. In Teacher Deng's words, "A binary tree is a special case of a multi-pronged tree, but when it has roots and is orderly, its descriptive ability is sufficient to cover the latter." > In fact, while you use the "eldest son + brother" method to represent the tree, you can rotate it at an angle of 45 degrees. @@ -302,7 +292,7 @@ Related concepts: -True binary tree (the degree of all nodes can only be even, that is, it can only be 0 or 2) -In addition, I also specially opened [traversal of binary trees] (./binary-tree-traversal.md ) Chapters, specific details and algorithms can be viewed there. +In addition, I also specially opened [traversal of binary trees](./binary-tree-traversal.md) Chapters, specific details and algorithms can be viewed there. #### Heap @@ -312,8 +302,7 @@ A typical implementation of heaps is binary heaps. Characteristics of binary stacks: --In a min heap, if P is a parent node of C, then the key (or value) of P should be less than or equal to the corresponding value of C. -Because of this, the top element of the heap must be the smallest. We will use this feature to find the minimum value or the kth smallest value. +-In a min heap, if P is a parent node of C, then the key (or value) of P should be less than or equal to the corresponding value of C. Because of this, the top element of the heap must be the smallest. We will use this feature to find the minimum value or the kth smallest value. ![min-heap](https://p.ipic.vip/shen88.jpg) @@ -333,9 +322,6 @@ Binary Sort Tree (Binary Sort Tree), also known as Binary Search Tree (Binary Se Binary lookup tree A binary tree with the following properties: --If the left subtree is not empty, the value of all nodes on the left subtree is less than the value of its root node; --If the right subtree is not empty, the value of all nodes on the right subtree is greater than the value of its root node; --The left and right subtrees are also binary sorting trees; --There are no nodes with equal key values. +-If the left subtree is not empty, the value of all nodes on the left subtree is less than the value of its root node; -If the right subtree is not empty, the value of all nodes on the right subtree is greater than the value of its root node; -The left and right subtrees are also binary sorting trees; -There are no nodes with equal key values. For a binary lookup tree, the conventional operations are to insert, find, delete, find the parent node, find the maximum value, and find the minimum value. diff --git a/thinkings/binary-search-1.en.md b/thinkings/binary-search-1.en.md index 451aa6c91..661c6378b 100644 --- a/thinkings/binary-search-1.en.md +++ b/thinkings/binary-search-1.en.md @@ -2,7 +2,7 @@ ## Foreword -![](https://p.ipic.vip/6zfu8a.jpg) +![](https://p.ipic.vip/6roqnw.jpg) Hello everyone, this is lucifer. What I bring to you today is the topic of "Two Points". Let's start with the outline of this article. This is a brain map drawn by me with mindmap. After that, I will continue to improve it and gradually improve other topics. @@ -10,9 +10,7 @@ Hello everyone, this is lucifer. What I bring to you today is the topic of "Two This series contains the following topics: --[I have almost finished swiping all the linked topics of Lixu, and I found these things. 。 。 ](https://lucifer. ren/blog/2020/11/08/linked-list/) -[After almost brushing all the tree questions of Li Buckle, I found these things. 。 。 ](https://lucifer. ren/blog/2020/11/23/tree/) --[After almost brushing all the piles of questions, I found these things. 。 。 (Part 1))(https://lucifer . ren/blog/2020/12/26/heap/) --[After almost brushing all the piles of questions, I found these things. 。 。 (Part 2))(https://lucifer . ren/blog/2021/01/19/heap-2/) +-[I have almost finished swiping all the linked topics of Lixu, and I found these things. 。 。 ](https://lucifer. ren/blog/2020/11/08/linked-list/) -[After almost brushing all the tree questions of Li Buckle, I found these things. 。 。 ](https://lucifer. ren/blog/2020/11/23/tree/) -[After almost brushing all the piles of questions, I found these things. 。 。 (Part 1))(https://lucifer . ren/blog/2020/12/26/heap/) -[After almost brushing all the piles of questions, I found these things. 。 。 (Part 2))(https://lucifer . ren/blog/2021/01/19/heap-2/) @@ -20,7 +18,7 @@ This topic is expected to be divided into two parts. The first part mainly talks The content of this article has been synchronized to the RoadMap of my question-brushing plug-in. Combined with the question-brushing plug-in, it tastes better to eat~ The way to obtain the plug-in can be viewed by replying to the plug-in on my public account. -![Swipe question plug-in] (https://tva1.sinaimg.cn/large/008eGmZEly1godsvaj344j30rw0qo433.jpg ) +![Swipe question plug-in](https://p.ipic.vip/d62pjf.jpg) > If you find the article useful, please like and leave a message to forward it, so that I can continue to do it. @@ -30,13 +28,13 @@ In order to prepare for this topic, I not only finished all the binary questions Binary search is also known as the `half-fold search algorithm`. In a narrow sense, binary search is a search algorithm for finding a specific element in an ordered array. This is also a saying that most people know. In fact, the broad binary search is to reduce the scale of the problem to half of the original one. Similarly, the three-point method is to reduce the scale of the problem to 1/3 of the original. -The content that this article brings to you is `binary search in a narrow sense". If you want to understand other binary search in a broad sense, you can check out a blog post I wrote earlier [looking at the binary method from the problem of mouse drug testing] (https://lucifer . ren/blog/2019/12/11/ laoshushidu/ "The binary method from the perspective of drug testing in mice") +The content that this article brings to you is `binary search in a narrow sense". If you want to understand other binary search in a broad sense, you can check out a blog post I wrote earlier [looking at the binary method from the problem of mouse drug testing](https://lucifer . ren/blog/2019/12/11/ laoshushidu/ "The binary method from the perspective of drug testing in mice") > Although the basic idea of binary search is relatively simple, the details can be overwhelming. . . —Gartner When Jon Bentley assigned binary search questions to students in professional programming classes, 90% of the students were still unable to give correct answers after spending several hours, mainly because these erroneous programs could not run when facing boundary values, or returned incorrect results. A study conducted in 1988 showed that only 5 out of 20 textbooks correctly implemented binary search. Not only that, Bentley's own binary search algorithm in the book "Programming Zhuji" published in 1986 has the problem of integer overflow, which has not been discovered for more than 20 years. The same overflow problem in the binary search algorithm implemented by the Java language library has existed for more than nine years before it was fixed. -It can be seen that binary search is not simple. This article will try to take you closer to ta, understand the underlying logic of ta, and provide templates to help you write bug-free binary search codes. After reading the lecture notes, it is recommended that you combine [LeetCode Book two-way search] (https://leetcode-cn.com/leetbook/read/binary-search "LeetCode Book Binary Search") Practice it. +It can be seen that binary search is not simple. This article will try to take you closer to ta, understand the underlying logic of ta, and provide templates to help you write bug-free binary search codes. After reading the lecture notes, it is recommended that you combine [LeetCode Book two-way search](https://leetcode-cn.com/leetbook/read/binary-search "LeetCode Book Binary Search") Practice it. ## Basic Concept @@ -54,7 +52,7 @@ Obviously, the solution space is the interval [-1, n-1], where n is the length o It should be noted that the solution space of the above topic can only be an integer between the intervals [-1, n-1]. And decimals such as 1.2 cannot exist. This is actually the case for most people. However, there are also a small number of problems whose solution space includes decimals. If the solution space includes decimals, it may involve accuracy issues, which everyone needs to pay attention to. -For example, if you ask for the square root of a number x, the answer error is considered correct to the power of $10^-6$. It is easy to know here that the size of the solution space can be defined as [1,x] (of course, it can be defined more precisely, we will discuss this issue later), where the solution space should include all real numbers in the interval, not just integers. At this time, the problem-solving ideas and code have not changed much, the only thing that needs to be changed is: +For example, if you ask for the square root of a number x, the answer error is considered correct to the power of $10^-6$. It is easy to know here that the size of the solution space can be defined as [1,x](of course, it can be defined more precisely, we will discuss this issue later), where the solution space should include all real numbers in the interval, not just integers. At this time, the problem-solving ideas and code have not changed much, the only thing that needs to be changed is: 1. Update the step size of the answer. For example, the previous update was `l=mid+1`, but now **may**will not work, so this **may**will miss the correct solution, for example, the correct solution happens to be a certain decimal within the interval [mid, mid+1]. 2. Errors need to be considered when judging conditions. Due to the problem of accuracy, the end condition of the judgment may have to become ** The error with the answer is within a certain range**. @@ -73,8 +71,7 @@ I am talking about sequences here, not arrays, linked lists, etc. In other words Although the binary method does not mean that the sequence needs to be ordered, most binary topics have the distinctive feature of being ordered. It's just: --Some topics directly limit the order. This kind of topic is usually not difficult, and it is easy to think of using two points. --Some require you to construct an ordered sequence by yourself. This type of topic is usually not difficult, and requires everyone to have a certain ability to observe. +-Some topics directly limit the order. This kind of topic is usually not difficult, and it is easy to think of using two points. -Some require you to construct an ordered sequence by yourself. This type of topic is usually not difficult, and requires everyone to have a certain ability to observe. For example, [Triple Inversion](https://binarysearch.com/problems/Triple-Inversion "Triple Inversion"). The title description is as follows: @@ -111,9 +108,9 @@ It doesn't matter if you don't understand the code for the time being. Let's lea ### Extreme value -Similar to me in [Heap topic] (https://lucifer . ren/blog/2020/12/26/ heap/ "heap topic") The extreme value mentioned. It's just that the extremes here are **static**, not dynamic. The extreme value here usually refers to the k-th largest (or k-th smallest) number. \*\* +Similar to me in [Heap topic](https://lucifer . ren/blog/2020/12/26/ heap/ "heap topic") The extreme value mentioned. It's just that the extremes here are **static**, not dynamic. The extreme value here usually refers to the k-th largest (or k-th smallest) number. \*\* -A very important use of heaps is to find the k-th largest number, and the binary method can also find the k-th largest number, but the ideas of the two are completely different. I have explained in detail the idea of using heaps to find the kth largest heap in the heaps topic mentioned earlier. What about the two points? Here we use an example to feel it: This question is [Kth Pair Distance] (https://binarysearch.com/problems/Kth-Pair-Distance "Kth Pair Distance"), the title description is as follows: +A very important use of heaps is to find the k-th largest number, and the binary method can also find the k-th largest number, but the ideas of the two are completely different. I have explained in detail the idea of using heaps to find the kth largest heap in the heaps topic mentioned earlier. What about the two points? Here we use an example to feel it: This question is [Kth Pair Distance](https://binarysearch.com/problems/Kth-Pair-Distance "Kth Pair Distance"), the title description is as follows: ``` Given a list of integers nums and an integer k, return the k-th (0-indexed) smallest abs(x - y) for every pair of elements (x, y) in nums. Note that (x, y) and (y, x) are considered the same pair. @@ -143,9 +140,7 @@ In simple terms, the title is to give an array of nums, which allows you to find For this question, the solution space is the difference from 0 to the maximum and minimum values in the array nums, which is expressed in intervals as [0, max(nums)-min(nums)]. After we have a clear understanding of the space, we need to divide the solution space. For this question, you can choose the intermediate value mid of the current solution space, and then calculate the absolute value of the difference between any two numbers that are less than or equal to this intermediate value. There are several. We might as well make this number X. --If x is greater than k, then the number greater than or equal to mid in the solution space cannot be the answer, so it can be discarded. --If x is less than k, then the numbers in the solution space that are less than or equal to mid cannot be the answer, so they can be discarded. --If x is equal to k, then mid is the answer. +-If x is greater than k, then the number greater than or equal to mid in the solution space cannot be the answer, so it can be discarded. -If x is less than k, then the numbers in the solution space that are less than or equal to mid cannot be the answer, so they can be discarded. -If x is equal to k, then mid is the answer. Based on this, we can use two points to solve it. This kind of question type, I summarize it as **Counting two points**. I will focus on the four major application parts later. @@ -182,7 +177,7 @@ Everyone must remember the center of the dichotomy. Others (such as orderly sequ The concept of space has been clearly understood by everyone earlier. And the halving here is actually the halving of the solution space. -For example, at the beginning, the solution space is [1, n] (n is an integer greater than n). By **Some way**, we are sure that the [1, m] interval** cannot be the answer**. Then the solution space becomes (m, n), and the solution space becomes trivial (directly solvable) after continuing this process. +For example, at the beginning, the solution space is [1, n](n is an integer greater than n). By **Some way**, we are sure that the [1, m] interval** cannot be the answer**. Then the solution space becomes (m, n), and the solution space becomes trivial (directly solvable) after continuing this process. > Note that the left side of the interval (m,n] is open, which means that m is impossible to get. diff --git a/thinkings/binary-search-2.en.md b/thinkings/binary-search-2.en.md index b58996b95..d49b1b3d7 100644 --- a/thinkings/binary-search-2.en.md +++ b/thinkings/binary-search-2.en.md @@ -6,14 +6,11 @@ Hello everyone, this is lucifer. What I bring to you today is the topic of "Two > You can also use vscode blink-mind to open the source file to view. There are some notes in it that you can click to view. The source file can be obtained by replying to the brain map on my official account "Force Buckle Plus", and the brain map will continue to be updated with more content in the future. vscode plug-in address:https://marketplace.visualstudio.com/items?itemName=awehook.vscode-blink-mind -![](https://p.ipic.vip/7b946x.jpg) +![](https://p.ipic.vip/wir7q1.jpg) This series contains the following topics: --[I have almost finished swiping all the linked topics of Lixu, and I found these things. 。 。 ](https://lucifer. ren/blog/2020/11/08/linked-list/) -[After almost brushing all the tree questions of Li Buckle, I found these things. 。 。 ](https://lucifer. ren/blog/2020/11/23/tree/) --[After almost brushing all the piles of questions, I found these things. 。 。 (Part 1))(https://lucifer . ren/blog/2020/12/26/heap/) --[After almost brushing all the piles of questions, I found these things. 。 。 (Part 2))(https://lucifer . ren/blog/2021/01/19/heap-2/) --[After almost brushing all the two-point questions of Li Buckle, I found these things. 。 。 (Part 1))(https://lucifer . ren/blog/2021/03/08/binary-search-1/) +-[I have almost finished swiping all the linked topics of Lixu, and I found these things. 。 。 ](https://lucifer. ren/blog/2020/11/08/linked-list/) -[After almost brushing all the tree questions of Li Buckle, I found these things. 。 。 ](https://lucifer. ren/blog/2020/11/23/tree/) -[After almost brushing all the piles of questions, I found these things. 。 。 (Part 1))(https://lucifer . ren/blog/2020/12/26/heap/) -[After almost brushing all the piles of questions, I found these things. 。 。 (Part 2))(https://lucifer . ren/blog/2021/01/19/heap-2/) -[After almost brushing all the two-point questions of Li Buckle, I found these things. 。 。 (Part 1))(https://lucifer . ren/blog/2021/03/08/binary-search-1/) @@ -45,11 +42,7 @@ This is the simplest form of binary lookup. Of course, binary search also has ma Common variants are: --If there are multiple elements that meet the condition, return the index of the leftmost element that meets the condition. --If there are multiple elements that meet the condition, return the index of the rightmost element that meets the condition. --The array is not ordered as a whole. For example, ascending order first and then descending order, or descending order first and then ascending order. --Turn a one-dimensional array into a two-dimensional array. --. 。 。 +-If there are multiple elements that meet the condition, return the index of the leftmost element that meets the condition. -If there are multiple elements that meet the condition, return the index of the rightmost element that meets the condition. -The array is not ordered as a whole. For example, ascending order first and then descending order, or descending order first and then ascending order. -Turn a one-dimensional array into a two-dimensional array. -. 。 。 Next, we will check it one by one. @@ -65,12 +58,9 @@ For the convenience of describing the problem later, it is necessary to introduc Terms used in binary search: --target-- the value to be found --index--current location --l and r-left and right pointers --mid--the midpoint of the left and right pointers, which is used to determine the index we should look to the left or the right (in fact, it is to shrink the solution space) +-target-- the value to be found -index--current location -l and r-left and right pointers -mid--the midpoint of the left and right pointers, which is used to determine the index we should look to the left or the right (in fact, it is to shrink the solution space) -![Term illustration](https://p.ipic.vip/6zhzd0.jpg) +![Term illustration](https://p.ipic.vip/6qylgw.jpg) It is worth noting that, except that the target is fixed, everything else changes dynamically. Where l and r refer to the upper and lower boundaries of the solution space, mid is the intermediate value of the upper and lower boundaries, and index is the traversal pointer, which is used to control the traversal process. @@ -82,22 +72,17 @@ In order to better understand the next content, we solve the simplest type -** t Algorithm description: --Start with the intermediate element of the array. If the intermediate element happens to be the element to be found, the search process ends.; --If the target element is greater than the intermediate element, then the values in the array that are smaller than the intermediate element can be excluded (since the array is ordered, it is equivalent to excluding all values on the left side of the array), and the solution space can be shrunk to [mid+1, r]. --If the target element is less than the intermediate element, then the values in the array that are greater than the intermediate element can be excluded (since the array is ordered, it is equivalent to excluding all values on the right side of the array), and the solution space can be shrunk to [l, mid-1]. --If the solution space is empty at a certain step, it means that it cannot be found. +-Start with the intermediate element of the array. If the intermediate element happens to be the element to be found, the search process ends.; -If the target element is greater than the intermediate element, then the values in the array that are smaller than the intermediate element can be excluded (since the array is ordered, it is equivalent to excluding all values on the left side of the array), and the solution space can be shrunk to [mid+1, r]. -If the target element is less than the intermediate element, then the values in the array that are greater than the intermediate element can be excluded (since the array is ordered, it is equivalent to excluding all values on the right side of the array), and the solution space can be shrunk to [l, mid-1]. -If the solution space is empty at a certain step, it means that it cannot be found. Give a specific example to facilitate everyone to increase their sense of substitution. Suppose nums is`[1,3,4,6,7,8,10,13,14]' and the target is 4·. --The element in the middle of the array at the beginning is 7 --7> 4, since the numbers on the right side of 7 are all greater than 7, it is impossible to be the answer. We have shortened the range to the left side of 7. +-The element in the middle of the array at the beginning is 7 -7> 4, since the numbers on the right side of 7 are all greater than 7, it is impossible to be the answer. We have shortened the range to the left side of 7. -![Adjust solution space] (https://tva1.sinaimg.cn/large/008eGmZEly1gosrelnzhuj30c905bweq.jpg ) +![Adjust solution space](https://p.ipic.vip/nfci5c.jpg) --The solution space becomes [1,3,4,6], at which time the intermediate element is 3. --3 < 4, since the numbers on the left of 3 are all less than 3, it is impossible to be the answer. We have shortened the range to the right side of 3. +-The solution space becomes [1,3,4,6], at which time the intermediate element is 3. -3 < 4, since the numbers on the left of 3 are all less than 3, it is impossible to be the answer. We have shortened the range to the right side of 3. -![Adjust the solution space again] (https://tva1.sinaimg.cn/large/008eGmZEly1gosrg6phvzj305b033glk.jpg ) +![Adjust the solution space again](https://p.ipic.vip/vxm7rh.jpg) -The solution space becomes [4,6]. At this time, the intermediate element is 4, which is exactly what we are looking for. Just return its index 2. @@ -105,11 +90,7 @@ Give a specific example to facilitate everyone to increase their sense of substi Since this search algorithm reduces the search scope by half every time it is compared, it is a typical binary search. --Average time complexity: $O(logN)$ --Worst time complexity: $O(logN)$ --Spatial complexity --Iteration: $O(1)$ --Recursion: $O(logN)$(elimination of tailless calls) +-Average time complexity: $O(logN)$ -Worst time complexity: $O(logN)$ -Spatial complexity -Iteration: $O(1)$ -Recursion: $O(logN)$(elimination of tailless calls) > The complexity of the latter is similar, and I will not repeat them. @@ -127,10 +108,7 @@ Don't underestimate such an algorithm. Even if it is such a simple and unpretent > It's easy to understand for an example. For example, for the interval [4,4], it contains an element 4, so the solution space is not empty and we need to continue searching (imagine that 4 happens to be the target we are looking for. If we don't continue searching, we will miss the correct answer). And when the solution space is [left, right), also for [4,4], the solution space is empty at this time, because there are no numbers· in such an interval. --In the cycle, we constantly calculate the mid and compare nums[mid] with the target value. --If nums[mid] is equal to the target value, mid is returned in advance (only need to find one that meets the conditions) --If nums[mid] is less than the target value, it means that the target value is on the right side of mid. At this time, the solution space can be reduced to [mid + 1, right] (mid and the numbers on the left side of mid are excluded by us) --If nums[mid] is greater than the target value, it means that the target value is on the left side of mid. At this time, the solution space can be reduced to [left, mid-1] (mid and the numbers on the right side of mid are excluded by us) +-In the cycle, we constantly calculate the mid and compare nums[mid] with the target value. -If nums[mid] is equal to the target value, mid is returned in advance (only need to find one that meets the conditions) -If nums[mid] is less than the target value, it means that the target value is on the right side of mid. At this time, the solution space can be reduced to [mid + 1, right](mid and the numbers on the left side of mid are excluded by us) -If nums[mid] is greater than the target value, it means that the target value is on the left side of mid. At this time, the solution space can be reduced to [left, mid-1](mid and the numbers on the right side of mid are excluded by us) - If it is not found at the end of the loop, it means that it is not found, and a return of -1 means that it is not found. @@ -180,19 +158,19 @@ return -1 ```js function binarySearch(nums, target) { - let left = 0; - let right = nums.length - 1; - while (left <= right) { - const mid = Math.floor(left + (right - left) / 2); - if (nums[mid] == target) return mid; - if (nums[mid] < target) - // Solution space becomes [mid+1, right] - left = mid + 1; - if (nums[mid] > target) - //Solution space becomes [left, mid-1] - right = mid - 1; - } - return -1; + let left = 0; + let right = nums.length - 1; + while (left <= right) { + const mid = Math.floor(left + (right - left) / 2); + if (nums[mid] == target) return mid; + if (nums[mid] < target) + // Solution space becomes [mid+1, right] + left = mid + 1; + if (nums[mid] > target) + //Solution space becomes [left, mid-1] + right = mid - 1; + } + return -1; } ``` @@ -236,9 +214,7 @@ Specific algorithm: -Since the solution space we define is [left,right], when left <=right, the solution space is not empty. In other words, our termination search condition is left <=right. --When A[mid]>=x, it means that a spare tire is found. We make r=mid-1 to exclude mid from the solution space, and continue to see if there is a better spare tire. --When A[mid] < x, it means that mid is not the answer at all. Directly update l = mid+ 1 to exclude mid from the solution space. --Finally, the l that solves the space is the best spare tire, and the spare tire turns positive. +-When A[mid]>=x, it means that a spare tire is found. We make r=mid-1 to exclude mid from the solution space, and continue to see if there is a better spare tire. -When A[mid] < x, it means that mid is not the answer at all. Directly update l = mid+ 1 to exclude mid from the solution space. -Finally, the l that solves the space is the best spare tire, and the spare tire turns positive. #### Code template @@ -269,9 +245,7 @@ Specific algorithm: -Since the solution space we define is [left,right], when left <=right, the solution space is not empty. In other words, our termination search condition is left <=right. --When A[mid]> x, it means that a spare tire is found. We make r= mid-1 to exclude mid from the solution space, and continue to see if there is a better spare tire. --When A[mid]<= x, it means that mid is not the answer at all. Directly update l= mid+ 1 to exclude mid from the solution space. --Finally, the l that solves the space is the best spare tire, and the spare tire turns positive. +-When A[mid]> x, it means that a spare tire is found. We make r= mid-1 to exclude mid from the solution space, and continue to see if there is a better spare tire. -When A[mid]<= x, it means that mid is not the answer at all. Directly update l= mid+ 1 to exclude mid from the solution space. -Finally, the l that solves the space is the best spare tire, and the spare tire turns positive. #### Code template @@ -320,8 +294,7 @@ The basic knowledge is almost ready. Next, we start with dry goods skills. What to talk about next: --Ability detection and counting binary are similar in nature, and they are both generalizations of ordinary binary. --The essence of prefixing and sorting and inserting sorting and sorting is to build an ordered sequence. +-Ability detection and counting binary are similar in nature, and they are both generalizations of ordinary binary. -The essence of prefixing and sorting and inserting sorting and sorting is to build an ordered sequence. Then let's get started. @@ -408,12 +381,11 @@ It has been observed that the solution space that needs to be detected is an ord The key to the two-way solution is: --Clear solution space. For this question, the solution space is [1, max(piles)]. --How to shrink the solution space. The key point is that **If the speed k cannot finish eating all bananas, then all solutions that are less than or equal to k can be ruled out. ** +-Clear solution space. For this question, the solution space is [1, max(piles)]. -How to shrink the solution space. The key point is that **If the speed k cannot finish eating all bananas, then all solutions that are less than or equal to k can be ruled out. ** In summary, we can use the leftmost boundary, that is, the right boundary is constantly shrinking. -![](https://p.ipic.vip/77n5hj.jpg) +![](https://p.ipic.vip/d69a7p.jpg) > The upper limit of the number of bananas in the banana pile is 10^9. Keke is too edible, right? diff --git a/thinkings/bit.en.md b/thinkings/bit.en.md index bc9a38095..ab682bcc7 100644 --- a/thinkings/bit.en.md +++ b/thinkings/bit.en.md @@ -183,10 +183,10 @@ return [a, b] ## Related topics -- [190. Reverse binary bits] (https://leetcode-cn.com/problems/reverse-bits /) (simple) +- [190. Reverse binary bits](https://leetcode-cn.com/problems/reverse-bits /) (simple) - [191. The number of digits 1](https://leetcode-cn.com/problems/number-of-1-bits /) (simple) - [338. Bit count](https://leetcode-cn.com/problems/counting-bits /) (medium) -- [1072. Flip by column to get the maximum value and other rows] (https://leetcode-cn.com/problems/flip-columns-for-maximum-number-of-equal-rows /) (medium) +- [1072. Flip by column to get the maximum value and other rows](https://leetcode-cn.com/problems/flip-columns-for-maximum-number-of-equal-rows /) (medium) For more questions, please visit my LeetCode questions warehouse:https://github.com/azl397985856/leetcode . There are already 38K stars. diff --git a/thinkings/dynamic-programming.en.md b/thinkings/dynamic-programming.en.md index 4d4852087..523d246cf 100644 --- a/thinkings/dynamic-programming.en.md +++ b/thinkings/dynamic-programming.en.md @@ -11,7 +11,7 @@ The task to be solved by dynamic programming is usually to accomplish a specific Each stage is abstract as a state (represented by a circle), and transitions may occur between states (represented by arrows). You can draw a picture similar to the following: -! [State transition diagram] (https://tva1.sinaimg.cn/large/008eGmZEly1gpoaanln73j31ak0p0dpd.jpg ) +![State transition diagram](https://p.ipic.vip/9bx82f.jpg) Then what kind of decision sequence should we make to make the result optimal? In other words, it is how each state should be selected to the next specific state and finally reach the target state. This is the problem of dynamic programming research. @@ -113,7 +113,7 @@ Every dynamic programming problem can actually be abstract as a mathematical fun Solving the dynamic programming problem can be seen as filling the black box of functions so that the numbers in the defined domain are correctly mapped to the value range. -![Mathematical functions vs Dynamic programming] (https://tva1.sinaimg.cn/large/008eGmZEly1gplrxy60mpj30pt0daacn.jpg ) +![Mathematical functions vs Dynamic programming](https://p.ipic.vip/ga40ge.jpg) Recursion is not an algorithm, it is a programming method corresponding to iteration. It's just that we usually use recursion to decompose problems. For example, we define a recursive function f(n) and use f(n) to describe the problem. It is the same as using ordinary dynamic programming f[n] to describe the problem. Here f is a dp array. @@ -139,7 +139,7 @@ function climbStairs(n) { We use a recursive tree to intuitively feel the following (each circle represents a sub-problem): -![Overlapping sub-issues] (https://tva1.sinaimg.cn/large/007S8ZIlly1ghluhw6pf2j30mz0b2dgk.jpg ) +![Overlapping sub-issues](https://p.ipic.vip/5ipuui.jpg) Red indicates repeated calculations. That is, both Fib(N-2) and Fib(N-3) have been calculated twice, in fact, one calculation is enough. For example, if the value of Fib(N-2) is calculated for the first time, then the next time you need to calculate Fib(N-2) again, you can directly return the result of the last calculation. The reason why this can be done is precisely as mentioned earlier. Our recursive function is a function in mathematics, that is to say, if the parameter is certain, then the return value must not change. Therefore, if we encounter the same parameter next time, we can return the value calculated last time directly without having to recalculate. The time saved in this way is equivalent to the number of overlapping sub-problems. @@ -163,7 +163,7 @@ climbStairs(10) Here I use a hash table named ** memo to store the return value of the recursive function, where key is the parameter and value is the return value of the recursive function. ** -![Hash indicates intent](https://p.ipic.vip/h4suhr.jpg) +![Hash indicates intent](https://p.ipic.vip/gdpa5k.jpg) > The form of key is (x, y), which represents an ancestor. Usually there are multiple parameters for dynamic programming, so we can use the ancestor method to memorize them. Or it can take the form of a multidimensional array. For the figure above, a two-dimensional array can be used to represent it. @@ -247,9 +247,9 @@ To be honest, I can only practice more and summarize the routines during the pra **Two examples** -Regarding the definition of state, it is so important that I list it as the core of dynamic programming. Therefore, I think it is necessary to give a few examples to illustrate. I am directly from Li Buckle's [dynamic programming topic] (https://leetcode-cn.com/tag/dynamic-programming/problemset / "dynamic programming Topics") The first two questions are selected to tell you about them. +Regarding the definition of state, it is so important that I list it as the core of dynamic programming. Therefore, I think it is necessary to give a few examples to illustrate. I am directly from Li Buckle's [dynamic programming topic](https://leetcode-cn.com/tag/dynamic-programming/problemset / "dynamic programming Topics") The first two questions are selected to tell you about them. -! [Topic of dynamic programming of Force Buckle] (https://tva1.sinaimg.cn/large/008eGmZEly1gpmtitey5hj315k0lsjxk.jpg ) +![Topic of dynamic programming of Force Buckle](https://p.ipic.vip/r7b7xv.jpg) The first question: "5. The Longest Palindrome Strand" Medium difficulty @@ -374,7 +374,7 @@ This question is very similar to the stair climbing above, but it has changed fr In this question, I define the state as f(i,j), which represents the total number of paths for the robot to reach the point (i,j). Then the total number of states is the Cartesian product of the values of i and j, which is m\*N. -![Two-dimensional stair climbing] (https://tva1.sinaimg.cn/large/008eGmZEly1gpn6m7knnij30u00v1di1.jpg ) +![Two-dimensional stair climbing](https://p.ipic.vip/yz1l42.jpg) In general, the spatial and time complexity of dynamic programming is based on the number of states, and the number of states is usually the Cartesian product of parameters, which is determined by the non-backward nature of dynamic programming. diff --git a/thinkings/graph.en.md b/thinkings/graph.en.md index 8a8d22cd9..c6ce4e5b4 100644 --- a/thinkings/graph.en.md +++ b/thinkings/graph.en.md @@ -4,7 +4,7 @@ Graph Theory is a branch of mathematics. It takes pictures as the research objec The following is a logical diagram structure: -! [Logical diagram structure] (https://tva1.sinaimg.cn/large/008i3skNly1guanati4zlj61800u075p02.jpg ) +![Logical diagram structure](https://p.ipic.vip/ygw8ii.jpg) Graphs are one of the most complex data structures. The data structures mentioned earlier can be regarded as special cases of graphs. Then why don't you just use diagrams for all of them, and divide them into so many data structures? @@ -34,16 +34,15 @@ How many edges point to node A, then the degree of entry of node A is what. Simi Still take the figure above as an example. The entry and exit degrees of all nodes in this figure are 1. -![](https://p.ipic.vip/zgyf24.jpg) +![](https://p.ipic.vip/w21lsl.jpg) ### Path & Ring [Path: Path] --Cyclic Graph [Cyclic Graph] The graph above is a cyclic graph, because we trigger from a certain point in the graph and we can go back to the starting point. This is the same as the ring in reality. --Acircular Graph〔Acyclic Graph〕 +-Cyclic Graph [Cyclic Graph] The graph above is a cyclic graph, because we trigger from a certain point in the graph and we can go back to the starting point. This is the same as the ring in reality. -Acircular Graph〔Acyclic Graph〕 I can transform the figure above into a loop-free diagram with a little modification. At this time, there is no loop. -![](https://p.ipic.vip/r7h4zu.jpg) +![](https://p.ipic.vip/b0gk9e.jpg) ### Connectedness Diagram & Strong Connectedness Diagram @@ -73,7 +72,7 @@ Use an n\*n matrix to describe the graph graph, which is a two-dimensional matri Generally speaking, for all graphs, I use graph[i][j]=1 to indicate that there is an edge between vertex i and vertex j, and the direction of the edge is from i to J. Use graph[i][j]= 0 to indicate that there is no edge between vertex i and vertex J. For this graph, we can store other numbers, which represent weights. -![](https://p.ipic.vip/0f39q4.jpg) +![](https://p.ipic.vip/0fmltq.jpg) It can be seen that the picture above is diagonally symmetrical, so we only need to look at half of it, which causes half of the space to be wasted. @@ -141,14 +140,13 @@ For each point, a linked list is stored, which is used to point to all points di For example, in an undirected graph: -![graph-1](https://p.ipic.vip/41khvw.jpg) -(Picture from https://zhuanlan.zhihu.com/p/25498681 ) +![graph-1](https://p.ipic.vip/j7nlpi.jpg) (Picture from https://zhuanlan.zhihu.com/p/25498681 ) It can be seen that in an undirected graph, the adjacency matrix is symmetrical about the diagonal, and the adjacency list always has two symmetrical edges. And in a directed graph: -![graph-2](https://p.ipic.vip/rfxn5j.jpg) +![graph-2](https://p.ipic.vip/o6jq46.jpg) (Picture from https://zhuanlan.zhihu.com/p/25498681 ) @@ -170,7 +168,7 @@ Here, take a directed graph as an example, and a directed graph is similar. I wi The depth-first method of traversing the graph is to start from a certain vertex v in the graph and continue to visit the neighbors, and the neighbors of the neighbors until the access is complete. -![](https://p.ipic.vip/odnpw3.jpg) +![](https://p.ipic.vip/oso066.jpg) As shown in the figure above, IF we use DFS and start from node A, **A possible** access order is: **A->C-> B-> D-> F->G->E**, Of course, it may also be **A->D->C->B->F->G->E**, etc., Depending on your code, but THEY are all depth-first. @@ -178,7 +176,7 @@ As shown in the figure above, IF we use DFS and start from node A, **A possible* Breadth-first search can be vividly described as "shallow and endless". It also requires a queue to maintain the order of the traversed apex so that the adjacent apex of these apex can be accessed in the order of dequeue. -![](https://p.ipic.vip/r0h2f4.jpg) +![](https://p.ipic.vip/54jwlt.jpg) As shown in the figure above, IF we use BFS and start from node A, ** A possible** access order is: ** A->B-> C-> F-> E->G-> D**, Of course, it may also be **A->B->F->E->C->G->D**, etc., Depending on your code, but they are all breadth-first. @@ -191,17 +189,13 @@ The algorithm of the title of the figure is more suitable for a set of templates Here are several common board questions. The main ones are: - Dijkstra -- Floyd-Warshall - -Minimum spanning tree (Kruskal & Prim) This subsection has been deleted at present. I feel that what I wrote is not detailed enough. After the supplement is completed, it will be opened again. - -A star pathfinding algorithm - -Two-dimensional diagram (dyeing method) [Bipartitie] - -Topological Sort〔 Topological Sort〕 +- Floyd-Warshall -Minimum spanning tree (Kruskal & Prim) This subsection has been deleted at present. I feel that what I wrote is not detailed enough. After the supplement is completed, it will be opened again. -A star pathfinding algorithm -Two-dimensional diagram (dyeing method) [Bipartitie] -Topological Sort〔 Topological Sort〕 The templates for common algorithms are listed below. > All the templates below are based on adjacency matrix modeling. -It is strongly recommended that you learn the following classic algorithm after you have finished the search for special articles. You can test a few ordinary search questions, and if you can make them, you can learn more. Recommended topic: [Maximize the value of the path in a picture] (https://leetcode-cn.com/problems/maximum-path-quality-of-a-graph / "Maximize the value of the path in a picture") +It is strongly recommended that you learn the following classic algorithm after you have finished the search for special articles. You can test a few ordinary search questions, and if you can make them, you can learn more. Recommended topic: [Maximize the value of the path in a picture](https://leetcode-cn.com/problems/maximum-path-quality-of-a-graph / "Maximize the value of the path in a picture") ### Shortest distance, shortest path diff --git a/thinkings/greedy.en.md b/thinkings/greedy.en.md index 24e467a06..316158f32 100644 --- a/thinkings/greedy.en.md +++ b/thinkings/greedy.en.md @@ -11,8 +11,8 @@ There are 73 questions on greedy strategies on LeetCode. We will divide it into We have selected three questions to explain. In addition to using the greedy method, you can also try dynamic planning to solve these three questions. - [45. Jumping Game II](https://leetcode-cn.com/problems/jump-game-ii /), difficult -- [1024. Video stitching] (https://leetcode-cn.com/problems/video-stitching /), medium -- [1326. Minimum number of taps for irrigating the garden] (https://leetcode-cn.com/problems/minimum-number-of-taps-to-open-to-water-a-garden /), difficult +- [1024. Video stitching](https://leetcode-cn.com/problems/video-stitching /), medium +- [1326. Minimum number of taps for irrigating the garden](https://leetcode-cn.com/problems/minimum-number-of-taps-to-open-to-water-a-garden /), difficult A major feature of the coverage problem, we can abstract it as `a large interval I on a given number axis and n small cells i[0], i[1],. . . , i[n-1], ask how many cells to choose at least, so that the union of these cells can cover the entire large area. ` @@ -187,7 +187,7 @@ There is a one-dimensional garden on the x-axis. The length of the garden is n, There are a total of n +1 taps in the garden, which are located at [0, 1,. . . , n]. -Give you an integer n and an array of integer ranges of length n +1, where ranges[i] (the index starts from 0) means: if you turn on the faucet at point i, the area that can be irrigated is [i-ranges[i], i + ranges[i]]. +Give you an integer n and an array of integer ranges of length n +1, where ranges[i](the index starts from 0) means: if you turn on the faucet at point i, the area that can be irrigated is [i-ranges[i], i + ranges[i]]. Please return the minimum number of taps that can irrigate the entire garden. If there is always a place in the garden that cannot be irrigated, please return to -1. @@ -240,9 +240,7 @@ I won't explain much here. Let's take a look at the specific algorithms, and let algorithm: --Use further[i] to record the rightmost land that can be covered by each tap I. There are a total of n +1 taps, and we traverse n + 1 times. --Calculate and update the left and right boundaries of the faucet every time [i-ranges[i], i+ ranges[i]] The furthest of the faucet within the range of [i-ranges[i], i+ ranges[i]] --Finally, start from land 0 and traverse all the way to land n, recording the number of taps, similar to a jumping game. +-Use further[i] to record the rightmost land that can be covered by each tap I. There are a total of n +1 taps, and we traverse n + 1 times. -Calculate and update the left and right boundaries of the faucet every time [i-ranges[i], i+ ranges[i]] The furthest of the faucet within the range of [i-ranges[i], i+ ranges[i]] -Finally, start from land 0 and traverse all the way to land n, recording the number of taps, similar to a jumping game. Is it almost exactly the same as the question above? diff --git a/thinkings/heap-2.en.md b/thinkings/heap-2.en.md index 272cff73f..4517dc79d 100644 --- a/thinkings/heap-2.en.md +++ b/thinkings/heap-2.en.md @@ -4,11 +4,11 @@ Last time I did a small survey for everyone on my public account, "Vote for the programming language you want to solve~". The following are the results of the survey: -![Voting results](https://p.ipic.vip/0ambnc.jpg) +![Voting results](https://p.ipic.vip/j4yrg2.jpg) Regarding others, most of them are in the Go language. -![What did the other people who voted for write?](https://p.ipic.vip/deg4hc.jpg) +![What did the other people who voted for write?](https://p.ipic.vip/fe8utj.jpg) Since the proportion of Java and Python has exceeded 60%, this time I will try to write in both Java and Python. Thank you @ CaptainZ for providing the Java code. At the same time, in order to prevent the article from being stinky and long, I put all the code (Java and Python) of this article in Java on the official website of Likujiajia\*\*, website address:https://leetcode-solution.cn/solution-code @@ -16,7 +16,7 @@ Since the proportion of Java and Python has exceeded 60%, this time I will try t ## Body -![](https://p.ipic.vip/j81nlc.jpg) +![](https://p.ipic.vip/4r5oeh.jpg) Hello everyone, this is lucifer. What I bring to you today is the topic of "Heap". Let's start with the outline of this article. This is a brain map drawn by me with mindmap. After that, I will continue to improve it and gradually improve other topics. @@ -58,7 +58,7 @@ heapq. heappop() #Pop up(4,5,6) Using a diagram to represent the heap structure is as follows: -! [Use a small top heap of tuples] (https://tva1.sinaimg.cn/large/0081Kckwly1gmbn0faqqaj30jy0lkq4n.jpg ) +![Use a small top heap of tuples](https://p.ipic.vip/wioiow.jpg) Briefly explain the execution result of the above code. @@ -98,7 +98,7 @@ heapq. heappush(h, -a) It is shown in the figure as follows: -! [Small top pile simulates big top pile] (https://tva1.sinaimg.cn/large/0081Kckwly1gmbn35fzhyj30k20mk75z.jpg ) +![Small top pile simulates big top pile](https://p.ipic.vip/226haf.jpg) That's it for laying the groundwork, and then we will get to the point. @@ -112,9 +112,9 @@ A typical application of a fixed heap is to find the k-th smallest number. In fa However, we don't need to put them all into the heap first, but build a large top heap (note that it is not the small top heap above), and maintain the size of the heap at k. If the size of the heap is greater than k after the new number is added to the heap, you need to compare the number at the top of the heap with the new number, and remove the larger number. This guarantees that the number in the heap is the smallest k of all numbers, and the largest of the smallest k (that is, the top of the heap) is not the kth smallest? This is the reason for choosing to build a large top stack instead of a small top stack. -! [Fix the 5th smallest number on the big top stack] (https://tva1.sinaimg.cn/large/0081Kckwly1gmbgz93840j30zk0u0jv7.jpg ) +![Fix the 5th smallest number on the big top stack](https://p.ipic.vip/okcn10.jpg) -The summary in a simple sentence is that \*\* Fixing a large top heap of size k can quickly find the k-th smallest number, on the contrary, fixing a small top heap of size k can quickly find the k-th largest number. For example, the third question of the weekly competition on 2020-02-24 [5663. Find the kth largest XOR coordinate value] (https://leetcode-cn.com/problems/find-kth-largest-xor-coordinate-value /"5663. Find out the kth largest XOR coordinate value") You can use the fixed small top heap technique to achieve it (this question allows you to find the kth largest number). +The summary in a simple sentence is that \*\* Fixing a large top heap of size k can quickly find the k-th smallest number, on the contrary, fixing a small top heap of size k can quickly find the k-th largest number. For example, the third question of the weekly competition on 2020-02-24 [5663. Find the kth largest XOR coordinate value](https://leetcode-cn.com/problems/find-kth-largest-xor-coordinate-value /"5663. Find out the kth largest XOR coordinate value") You can use the fixed small top heap technique to achieve it (this question allows you to find the kth largest number). So maybe your feelings are not strong. Next, I will give you two examples to help you deepen your impression. @@ -152,20 +152,17 @@ If 99% of the integers in the data stream are in the range of 0 to 100, how woul This question can actually be seen as a special case of finding the k-th smallest number. --If the length of the list is odd, then k is (n + 1) / 2, and the median is the kth number. For example, n is 5 and k is (5 + 1)/ 2 = 3。 --If the length of the list is even, then k is (n +1) / 2 and (n +1) / 2 + 1, and the median is the average of these two numbers. For example, n is 6, and k is (6 +1)/2 = 3 and (6 + 1) / 2 + 1 = 4。 +-If the length of the list is odd, then k is (n + 1) / 2, and the median is the kth number. For example, n is 5 and k is (5 + 1)/ 2 = 3。 -If the length of the list is even, then k is (n +1) / 2 and (n +1) / 2 + 1, and the median is the average of these two numbers. For example, n is 6, and k is (6 +1)/2 = 3 and (6 + 1) / 2 + 1 = 4。 Thus we can maintain two fixed heap, fixed stack size is $(n + 1) \div 2$ and $n - (n + 1)\div2$, that is, both the size of the heap**up**a difference of 1, and more specifically that $ 0 <= (n + 1) \div 2 - (n - (n + 1) \div 2) <= 1$。 Based on the knowledge mentioned above, we can: --Build a large top heap and store the smallest number of $(n +1) \div 2$, so that the number at the top of the heap is the smallest number of $(n +1) \div 2$, which is the median in odd cases. --Build a small top heap and store the largest number of n- $(n +1) \div 2$, so that the number at the top of the heap is the largest number of n- $(n +1) \div 2$, combined with the large top heap above, the median of even cases can be obtained. +-Build a large top heap and store the smallest number of $(n +1) \div 2$, so that the number at the top of the heap is the smallest number of $(n +1) \div 2$, which is the median in odd cases. -Build a small top heap and store the largest number of n- $(n +1) \div 2$, so that the number at the top of the heap is the largest number of n- $(n +1) \div 2$, combined with the large top heap above, the median of even cases can be obtained. With such knowledge, all that remains is how to maintain the size of the two heaps. --If the number of large top piles is smaller than that of small top piles, then transfer the smallest of the small top piles to the large top piles. And since the small top stack maintains the largest number of k, and the large top stack maintains the smallest number of k, the top of the small top stack must be greater than or equal to the top of the large top stack, and the two top stacks are the median of **\***. --If the number of large top piles is 2 more than the number of small top piles, then the largest of the large top piles will be transferred to the small top piles. The reason is the same as above. +-If the number of large top piles is smaller than that of small top piles, then transfer the smallest of the small top piles to the large top piles. And since the small top stack maintains the largest number of k, and the large top stack maintains the smallest number of k, the top of the small top stack must be greater than or equal to the top of the large top stack, and the two top stacks are the median of **\***. -If the number of large top piles is 2 more than the number of small top piles, then the largest of the large top piles will be transferred to the small top piles. The reason is the same as above. At this point, you may have understood why two heaps are built separately, and you need a large top heaps and a small top heaps. The reason for this is as described above. @@ -301,8 +298,7 @@ This technique was actually mentioned earlier when talking about super ugly numb In fact, this technique may be more appropriate to be called multi-pointer optimization, but the name is too simple and easy to confuse with double pointers, so I gave ta a chic name-Multi-channel merge. --Multiple routes are reflected in: there are multiple candidate routes. In the code, we can use multiple pointers to represent it. --The merger is reflected in: the result may be the longest or shortest of multiple candidate routes, or it may be the kth, etc. Therefore, we need to compare the results of multiple routes, and discard or select one or more routes according to the topic description. +-Multiple routes are reflected in: there are multiple candidate routes. In the code, we can use multiple pointers to represent it. -The merger is reflected in: the result may be the longest or shortest of multiple candidate routes, or it may be the kth, etc. Therefore, we need to compare the results of multiple routes, and discard or select one or more routes according to the topic description. This description is more abstract. Next, let's deepen everyone's understanding through a few examples. @@ -356,16 +352,13 @@ mat[i] is a non-decreasing array In fact, this question is to give you m one-dimensional arrays of the same length. Let us select a number from these m arrays, that is, select a total of m numbers, and find that the sum of these m numbers is The kth smallest among all selection possibilities. -![](https://p.ipic.vip/pypsm9.jpg) +![](https://p.ipic.vip/xi03t7.jpg) A simple idea is to use multiple pointers to solve. For this question, it is to use m pointers to point to m one-dimensional arrays. The position of the pointers indicates that the first few in the one-dimensional array are currently selected. Take the'mat in the title = [[1,3,11],[2,4,6]], Take k = 5` as an example. --First initialize two pointers p1 and p2, which point to the beginning of two one-dimensional arrays. The code indicates that they are all initialized to 0. --At this time, the sum of the numbers pointed to by the two pointers is 1 + 2 = 3, which is the first smallest sum. --Next, we move one of the pointers. At this time, we can move p1 or p2. --Then the second smallest value must be the smaller value of the two cases of moving p1 and moving p2. And here moving p1 and p2 will actually get 5, which means that the sum of the second and third small ones is 5. +-First initialize two pointers p1 and p2, which point to the beginning of two one-dimensional arrays. The code indicates that they are all initialized to 0. -At this time, the sum of the numbers pointed to by the two pointers is 1 + 2 = 3, which is the first smallest sum. -Next, we move one of the pointers. At this time, we can move p1 or p2. -Then the second smallest value must be the smaller value of the two cases of moving p1 and moving p2. And here moving p1 and p2 will actually get 5, which means that the sum of the second and third small ones is 5. It has been forked here, and two situations have occurred (pay attention to the bold position, the bold indicates the position of the pointer): diff --git a/thinkings/heap.en.md b/thinkings/heap.en.md index 058bc6fd5..3912967cf 100644 --- a/thinkings/heap.en.md +++ b/thinkings/heap.en.md @@ -1,6 +1,6 @@ # 堆专题 -![](https://p.ipic.vip/kznqh4.jpg) +![](https://p.ipic.vip/dns3hz.jpg) 大家好,我是 lucifer。今天给大家带来的是《堆》专题。先上下本文的提纲,这个是我用 mindmap 画的一个脑图,之后我会继续完善,将其他专题逐步完善起来。 @@ -18,7 +18,7 @@ [堆标签](https://leetcode-cn.com/tag/tree/ "堆标签")在 leetcode 一共有 **42 道题**。 为了准备这个专题,我将 leetcode 几乎所有的堆题目都刷了一遍。 -![](https://p.ipic.vip/iubecr.jpg) +![](https://p.ipic.vip/qx5cws.jpg) 可以看出,除了 3 个上锁的,其他我都刷了一遍。通过集中刷这些题,我发现了一些有趣的信息,今天就分享给大家。 @@ -64,7 +64,7 @@ 如果不同的客户使用不同的窗口。那么我们可以设计三个队列,分别存放正在排队的三种人。这种设计满足了题目要求,也足够简单。 -![](https://p.ipic.vip/oylgd6.jpg) +![](https://p.ipic.vip/noqe15.jpg) 如果我们**只有一个窗口**,所有的病人需要使用同一个队列,并且同样的客户类型按照上面讲的**先到先服务原则**,但是不同客户类型之间可能会插队。 @@ -78,7 +78,7 @@ 因此我们就可以继续使用刚才的三个队列的方式,只不过队列存储的不是真实时间,而是虚拟时间。每次开始叫号的时候,我们使用虚拟时间比较,虚拟时间较小的先服务即可。 -![](https://p.ipic.vip/ccyo6b.jpg) +![](https://p.ipic.vip/clq91x.jpg) > 不难看出,队列内部的时间都是有序。 @@ -95,10 +95,10 @@ 如下图是插入一个 1:30 开始排队的普通客户的情况。 -![](https://p.ipic.vip/epfmkj.jpg) +![](https://p.ipic.vip/q22wm2.jpg) (查找插入位置) -![](https://p.ipic.vip/od3eg0.jpg) +![](https://p.ipic.vip/uhftpi.jpg) (将其插入) 如果队列使用数组实现, 上面插队过程的时间复杂度为 $O(N)$,其中 $N$ 为被插队的队伍长度。如果队伍很长,那么调整的次数明显增加。 @@ -107,11 +107,11 @@ 上面说了链表的实现核心在于查找也需要 $O(N)$,我们可以优化这个过程吗?实际上这就是优先级队列的链表实现,由于是有序的,我们可以用跳表加速查找,时间复杂度可以优化到 $O(logN)$。 -![](https://p.ipic.vip/ao1pua.jpg) +![](https://p.ipic.vip/t6l1jp.jpg) 其实算法界有很多类似的问题。比如建立数据库索引的算法,如果给某一个有序的列添加索引,不能每次插入一条数据都去调整所有的数据吧(上面的数组实现)?因此我们可以用平衡树来实现,这样每次插入可以最多调整 $(O(logN))$。优先队列的另外一种实现 - 二叉堆就是这个思想,时间复杂度也可以优化到 $O(logN)$ -![](https://p.ipic.vip/vycxgm.jpg) +![](https://p.ipic.vip/0au6fq.jpg) 本文只讲解常见的二叉堆实现,对于跳表和红黑树不再这里讲。 关于优先队列的二叉堆实现,我们会在后面给大家详细介绍。这里大家只有明白优先队列解决的问题是什么就可以了。 @@ -500,13 +500,13 @@ class Solution { 我们知道,不借助额外空间的情况下,在链表中查找一个值,需要按照顺序一个个查找,时间复杂度为 $O(N)$,其中 N 为链表长度。 -![](https://p.ipic.vip/g6tg2n.jpg) +![](https://p.ipic.vip/7k87vh.jpg) (单链表) 当链表长度很大的时候, 这种时间是很难接受的。 一种常见的的优化方式是**建立哈希表,将所有节点都放到哈希表中,以空间换时间的方式减少时间复杂度**,这种做法时间复杂度为 $O(1)$,但是空间复杂度为 $O(N)$。 -![](https://p.ipic.vip/da1rok.jpg) +![](https://p.ipic.vip/e3aci5.jpg) (单链表 + 哈希表) @@ -518,7 +518,7 @@ class Solution { > 注意这个算法要求链表是有序的。 -![](https://p.ipic.vip/is3071.jpg) +![](https://p.ipic.vip/oziotf.jpg) (建立一级索引) @@ -529,7 +529,7 @@ class Solution { 这个例子看不出性能提升。但是如果元素继续增大, 继续增加索引的层数,建立二级,三级。。。索引,使得链表能够实现二分查找,从而获得更好的效率。但是相应地,我们需要付出额外空间的代价。 -![](https://p.ipic.vip/dky40x.jpg) +![](https://p.ipic.vip/5av4uh.jpg) (增加索引层数) @@ -572,7 +572,7 @@ h.heappop() # 3 本质上来说,二叉堆就是一颗特殊的完全二叉树。它的特殊性只体现在一点,那就是**父节点的权值不大于儿子的权值(小顶堆)**。 -![](https://p.ipic.vip/v24509.jpg) +![](https://p.ipic.vip/v32zmq.jpg) (一个小顶堆) 上面这句话需要大家记住,一切的一切都源于上面这句话。 @@ -587,24 +587,24 @@ h.heappop() # 3 如果仅仅是删除,那么一个堆就会变成两个堆了,问题变复杂了。 -![](https://p.ipic.vip/5hp8ip.jpg) +![](https://p.ipic.vip/ypzpn9.jpg) (上图出堆之后会生成两个新的堆) 一个常见的操作是,把根结点和最后一个结点交换。但是新的根结点可能不满足 **父节点的权值不大于儿子的权值(小顶堆)**。 如下图,我们将根节点的 2 和尾部的数字进行交换后,这个时候是不满足堆性质的。 -![](https://p.ipic.vip/140g5w.jpg) +![](https://p.ipic.vip/gi2ofs.jpg) 这个时候,其实只需要将新的根节点下沉到正确位置即可。这里的**正确位置**,指的还是那句话**父节点的权值不大于儿子的权值(小顶堆)**。如果不满足这一点,我们就继续下沉,直到满足。 我们知道根节点往下下沉的过程,其实有两个方向可供选择,是下沉到左子节点?还是下沉到右子节点?以小顶堆来说,答案应该是下沉到较小的子节点处,否则会错失正确答案。以上面的堆为例,如果下沉到右子节点 4,那么就无法得到正确的堆顶 3。因此我们需要下沉到左子节点。 -![](https://p.ipic.vip/ilhzim.jpg) +![](https://p.ipic.vip/gqm5d9.jpg) 下沉到如图位置,还是不满足 **父节点的权值不大于儿子的权值(小顶堆)**,于是我们继续执行同样的操作。 -![](https://p.ipic.vip/0emyhf.jpg) +![](https://p.ipic.vip/ar3ty6.jpg) 有的同学可能有疑问。弹出根节点前堆满足堆的性质,但是弹出之后经过你上面讲的下沉操作,一定还满足么? @@ -623,7 +623,7 @@ h.heappop() # 3 > 之所以这么做的其中一个原因是时间复杂度更低,因为我们是用数组进行模拟的,而在数组尾部添加元素的时间复杂度为 $O(1)$。 -![](https://p.ipic.vip/jxt7ki.jpg) +![](https://p.ipic.vip/usffec.jpg) 这次我们发现,不满足堆的节点目前是刚刚被插入节点的尾部节点,因此不能进行下沉操作了。这一次我们需要执行**上浮操作**。 @@ -631,10 +631,10 @@ h.heappop() # 3 和上面基本类似,如果不满足堆的性质,我们将其和父节点交换(上浮),继续这个过程,直到满足堆的性质。 -![](https://p.ipic.vip/0suv9m.jpg) +![](https://p.ipic.vip/r0vogx.jpg) (第一次上浮,仍然不满足堆特性,继续上浮) -![](https://p.ipic.vip/op82y6.jpg) +![](https://p.ipic.vip/arunjx.jpg) (满足了堆特性,上浮过程完毕) 经过这样的操作,其还是一个满足堆性质的堆。证明过程和上面类似,不再赘述。 @@ -652,12 +652,12 @@ h.heappop() # 3 如图所示是一个完全二叉树和树的数组表示法。 -![](https://p.ipic.vip/c2et7m.jpg) +![](https://p.ipic.vip/npka2q.jpg) (注意数组索引的对应关系) 形象点来看,我们可以可以画出如下的对应关系图: -![](https://p.ipic.vip/nl4hlg.jpg) +![](https://p.ipic.vip/an63qu.jpg) 这样一来,是不是和上面的树差不多一致了?有没有容易理解一点呢? @@ -831,4 +831,4 @@ public class Heap { 大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。目前已经 37K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。 -![二维码](https://p.ipic.vip/0ss8wk.jpg) +![二维码](https://p.ipic.vip/e910pi.jpg) diff --git a/thinkings/island.en.md b/thinkings/island.en.md index 28266d45e..10423834d 100644 --- a/thinkings/island.en.md +++ b/thinkings/island.en.md @@ -65,19 +65,16 @@ dfs(i, j) ## Related topics -- [200. Number of islands] (https://github.com/azl397985856/leetcode/blob/master/problems/200.number-of-islands.md ) -- [695. The largest area of the island] (https://leetcode-cn.com/problems/max-area-of-island/solution/695-dao-yu-de-zui-da-mian-ji-dfspython3-by-fe-luci /) (Original title of Byte beating) -- [1162. Map analysis] (https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/python-tu-jie-chao-jian-dan-de-bfs1162-di-tu-fen-x /) +- [200. Number of islands](https://github.com/azl397985856/leetcode/blob/master/problems/200.number-of-islands.md) +- [695. The largest area of the island](https://leetcode-cn.com/problems/max-area-of-island/solution/695-dao-yu-de-zui-da-mian-ji-dfspython3-by-fe-luci /) (Original title of Byte beating) +- [1162. Map analysis](https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/python-tu-jie-chao-jian-dan-de-bfs1162-di-tu-fen-x /) - 463. The circumference of the island The above four questions can be done using regular DFS. And the direction of recursion is in four directions: up, down, left and right. What's more interesting is that you can use the method of in-situ modification to reduce the space opened up for visits. Among them, 463 questions are just when doing DFS, it is necessary to note that the adjacent side lengths may be calculated repeatedly, so they need to be subtracted. My idea here is: --Add 4 when encountering land --Continue to determine whether it is land on the left and above --If yes, there will be a double calculation. At this time, the double calculation is 2, so you can subtract 2. --If not, the calculation will not be repeated, and you can ignore it. +-Add 4 when encountering land -Continue to determine whether it is land on the left and above -If yes, there will be a double calculation. At this time, the double calculation is 2, so you can subtract 2. -If not, the calculation will not be repeated, and you can ignore it. Note that the ones on the right and below do not need to be counted, otherwise the calculation will still be repeated. @@ -135,7 +132,7 @@ If you encounter a small island topic next time, or a topic that can be abstract ## Extension -In fact, many questions have the shadow of small island questions. The core of the so-called small island questions is to seek connectivity areas. If you can transform the problem into a connectivity area, then you can use the ideas in this section to do so. For example, [959. Area divided by slashes] (https://leetcode-cn.com/problems/regions-cut-by-slashes / "959. Divide the area by a slash") +In fact, many questions have the shadow of small island questions. The core of the so-called small island questions is to seek connectivity areas. If you can transform the problem into a connectivity area, then you can use the ideas in this section to do so. For example, [959. Area divided by slashes](https://leetcode-cn.com/problems/regions-cut-by-slashes / "959. Divide the area by a slash") Title description: diff --git a/thinkings/linked-list.en.md b/thinkings/linked-list.en.md index 63c8fe512..1a82c9c57 100644 --- a/thinkings/linked-list.en.md +++ b/thinkings/linked-list.en.md @@ -8,7 +8,7 @@ Let's start with the outline of this article. This is a brain map drawn by me wi Hello everyone, this is lucifer. The topic that I bring to you today is "Linked List". Many people find this to be a difficult topic. In fact, as long as you master the trick, it is not that difficult. Next, let's talk about it. -[Linked List Tag] (https://leetcode-cn.com/tag/linked-list /"Linked list tag") There are a total of ** 54 questions** in leetcode. In order to prepare for this topic, I spent a few days brushing almost all the linked list topics of leetcode. +[Linked List Tag](https://leetcode-cn.com/tag/linked-list /"Linked list tag") There are a total of ** 54 questions** in leetcode. In order to prepare for this topic, I spent a few days brushing almost all the linked list topics of leetcode. ![](https://p.ipic.vip/fdv0l4.jpg) @@ -38,8 +38,8 @@ Arrays are contiguous memory spaces, and usually the size of each unit is fixed, ```ts interface ListNode { - data: T; - next: ListNode; + data: T; + next: ListNode; } ``` @@ -152,8 +152,7 @@ Is it very similar? **It can be seen that the logic of the two is the same, but the subtle operations are different. **For example: --The array is an index ++ --The linked list is cur = cur. next +-The array is an index ++ -The linked list is cur = cur. next What if we need to traverse in reverse order? @@ -242,8 +241,7 @@ It doesn't matter if the painting looks good or not, just be able to see it clea I did the linked list of force buttons all over. An interesting phenomenon was found, that is, there are very single test centers in the United States. Except for design questions, there are no two points in the test center.: --Pointer modification --Splicing of linked lists +-Pointer modification -Splicing of linked lists ### Pointer modification @@ -253,14 +251,14 @@ For arrays, a data structure that supports random access, inversion is easy, as ```js function reverseArray(arr) { - let left = 0; - let right = arr.length - 1; - while (left < right) { - const temp = arr[left]; - arr[left++] = arr[right]; - arr[right--] = temp; - } - return arr; + let left = 0; + let right = arr.length - 1; + while (left < right) { + const temp = arr[left]; + arr[left++] = arr[right]; + arr[right--] = temp; + } + return arr; } ``` @@ -375,9 +373,7 @@ Therefore, there are many splicing operations on the linked list. If you know th The most error-prone place of linked lists is where we should pay attention. 90% of the most common errors in linked lists are concentrated in the following three situations: --A ring appeared, causing an endless loop. --The boundary cannot be distinguished, resulting in an error in the boundary condition. --Don't understand what to do recursively +-A ring appeared, causing an endless loop. -The boundary cannot be distinguished, resulting in an error in the boundary condition. -Don't understand what to do recursively Next, let's take a look one by one. @@ -385,8 +381,7 @@ Next, let's take a look one by one. There are two test centers in the ring: --The topic may have a ring, allowing you to judge whether there is a ring and the location of the ring. --The list of topics has no ring, but the ring has been rounded out by your operation pointer. +-The topic may have a ring, allowing you to judge whether there is a ring and the location of the ring. -The list of topics has no ring, but the ring has been rounded out by your operation pointer. Here we will only discuss the second one, and the first one can use the \*\*speed pointer algorithm we mentioned later. @@ -398,8 +393,7 @@ But the list is so long, it is impossible for me to draw it all. In fact, it is What many people are wrong is that they do not consider boundaries. One technique for considering boundaries is to look at the topic information. --If the head node of the topic may be removed, then consider using a virtual node, so that the head node becomes an intermediate node, and there is no need to make special judgments for the head node. --The title asks you to return not the original head node, but the tail node or other intermediate nodes. At this time, pay attention to the pointer changes. +-If the head node of the topic may be removed, then consider using a virtual node, so that the head node becomes an intermediate node, and there is no need to make special judgments for the head node. -The title asks you to return not the original head node, but the tail node or other intermediate nodes. At this time, pay attention to the pointer changes. The specific content of the above two parts, we will explain in the virtual head part that we will talk about later. As an old rule, everyone can leave an impression. @@ -407,7 +401,7 @@ The specific content of the above two parts, we will explain in the virtual head Ok, it's time to fill the pit. As mentioned above, the linked list structure is inherently recursive, so using recursive solutions or recursive thinking will help us solve problems. -In [binary tree traversal] (https://github.com/azl397985856/leetcode/blob/master/thinkings/binary-tree-traversal.md ) In the part, I talked about the three popular traversal methods of binary trees, namely pre-sequence traversal, middle-sequence traversal, and post-sequence traversal. +In [binary tree traversal](https://github.com/azl397985856/leetcode/blob/master/thinkings/binary-tree-traversal.md) In the part, I talked about the three popular traversal methods of binary trees, namely pre-sequence traversal, middle-sequence traversal, and post-sequence traversal. The front, middle and back order actually refers to the processing order of the current node relative to the child nodes. If the current node is processed first and then the child nodes are processed, then it is the preamble. If you process the left node first, then the current node, and finally the right node, it is a middle-order traversal. The subsequent traversal is naturally the final processing of the current node. diff --git a/thinkings/monotone-stack.en.md b/thinkings/monotone-stack.en.md index c068c8403..aa4d94888 100644 --- a/thinkings/monotone-stack.en.md +++ b/thinkings/monotone-stack.en.md @@ -32,16 +32,13 @@ Since the stack only operates at the end, if we use arrays for simulation, the t ### Application --Function call stack --Browser forward and backward --Matching brackets --The monotonic stack is used to find the next larger (smaller) element +-Function call stack -Browser forward and backward -Matching brackets -The monotonic stack is used to find the next larger (smaller) element ### Topic recommendation - [394. String decoding](https://leetcode-cn.com/problems/decode-string /) - [946. Verify stack sequence](https://leetcode-cn.com/problems/validate-stack-sequences /) -- [1381. Design a stack that supports incremental operations] (https://leetcode-cn.com/problems/design-a-stack-with-increment-operation /) +- [1381. Design a stack that supports incremental operations](https://leetcode-cn.com/problems/design-a-stack-with-increment-operation /) ## What is the monotonic stack? @@ -90,8 +87,7 @@ If ans is used to denote the first position after arr[i] that is less than itsel Step 8, we are starting to pop again. At this time, 9 pops up, so the first index less than 9 after 9 is 6. -The process of this algorithm is summed up in one sentence, **If the monotonicity can still be maintained after pressing the stack, then directly press. Otherwise, the elements of the stack will pop up first, and the monotonicity will be maintained until they are pressed in. ** -The principle of this algorithm is summed up in one sentence, **The elements that are popped up are all larger than the current element, and since the stack is monotonically increasing, the nearest one that is smaller than itself after it is the current element.** +The process of this algorithm is summed up in one sentence, **If the monotonicity can still be maintained after pressing the stack, then directly press. Otherwise, the elements of the stack will pop up first, and the monotonicity will be maintained until they are pressed in. ** The principle of this algorithm is summed up in one sentence, **The elements that are popped up are all larger than the current element, and since the stack is monotonically increasing, the nearest one that is smaller than itself after it is the current element.** Let's recommend a few questions for everyone. While the knowledge is still in your mind, hurry up and brush it up~ @@ -116,8 +112,7 @@ return ans **Complexity analysis** --Time complexity: Since the elements of arr will only enter the stack and exit the stack once at most, the time complexity is still $O(N)$, where N is the length of the array. --Spatial complexity: Since the stack is used, and the maximum length of the stack is consistent with the length of arr, the spatial complexity is $O(N)$, where N is the length of the array. +-Time complexity: Since the elements of arr will only enter the stack and exit the stack once at most, the time complexity is still $O(N)$, where N is the length of the array. -Spatial complexity: Since the stack is used, and the maximum length of the stack is consistent with the length of arr, the spatial complexity is $O(N)$, where N is the length of the array. ### Code @@ -142,17 +137,17 @@ JS: ```js var monostoneStack = function (T) { - let stack = []; - let result = []; - for (let i = 0; i < T.length; i++) { - result[i] = 0; - while (stack.length > 0 && T[stack[stack.length - 1]] < T[i]) { - let peek = stack.pop(); - result[peek] = i - peek; - } - stack.push(i); - } - return result; + let stack = []; + let result = []; + for (let i = 0; i < T.length; i++) { + result[i] = 0; + while (stack.length > 0 && T[stack[stack.length - 1]] < T[i]) { + let peek = stack.pop(); + result[peek] = i - peek; + } + stack.push(i); + } + return result; }; ``` @@ -160,9 +155,9 @@ var monostoneStack = function (T) { The following questions will help you understand the monotonic stack and let you understand when you can use the monotonic stack for algorithm optimization. -- [42. Pick up the rain] (https://github.com/azl397985856/leetcode/blob/master/problems/42.trapping-rain-water.md "42. Pick up the rain") -- [84. The largest rectangle in the histogram] (https://github.com/azl397985856/leetcode/blob/master/problems/84.largest-rectangle-in-histogram.md "84. The largest rectangle in the histogram") -- [739.Daily temperature] (https://github.com/azl397985856/leetcode/blob/master/daily/2019-06-06.md "739. Daily temperature") +- [42. Pick up the rain](https://github.com/azl397985856/leetcode/blob/master/problems/42.trapping-rain-water.md "42. Pick up the rain") +- [84. The largest rectangle in the histogram](https://github.com/azl397985856/leetcode/blob/master/problems/84.largest-rectangle-in-histogram.md "84. The largest rectangle in the histogram") +- [739.Daily temperature](https://github.com/azl397985856/leetcode/blob/master/daily/2019-06-06.md "739. Daily temperature") - 316. Remove duplicate letters - 402. Remove K digits diff --git a/thinkings/prefix.en.md b/thinkings/prefix.en.md index feab711c1..5b54ec55a 100644 --- a/thinkings/prefix.en.md +++ b/thinkings/prefix.en.md @@ -2,11 +2,11 @@ It took me a few days to select five topics with the same idea from the link to help you solve the problem. If you think the article is useful to you, remember to like and share, so that I can see your approval and have the motivation to continue doing it. -- [467. Surround the unique sub-string in the string] (https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string /"467. Surround the unique sub-string in the string") (medium) -- [795. Number of interval subarrays] (https://leetcode-cn.com/problems/number-of-subarrays-with-bounded-maximum /"795. Number of interval subarrays") (medium) -- [904. Fruit basket] (https://leetcode-cn.com/problems/fruit-into-baskets / "904. Fruit basket") (medium) +- [467. Surround the unique sub-string in the string](https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string /"467. Surround the unique sub-string in the string") (medium) +- [795. Number of interval subarrays](https://leetcode-cn.com/problems/number-of-subarrays-with-bounded-maximum /"795. Number of interval subarrays") (medium) +- [904. Fruit basket](https://leetcode-cn.com/problems/fruit-into-baskets / "904. Fruit basket") (medium) - [992. Subarrays of K different integers](https://leetcode-cn.com/problems/subarrays-with-k-different-integers /"992. Subarrays of K different integers") (difficult) -- [1109. Flight booking statistics] (https://leetcode-cn.com/problems/corporate-flight-bookings /"1109. Flight Booking Statistics") (medium) +- [1109. Flight booking statistics](https://leetcode-cn.com/problems/corporate-flight-bookings /"1109. Flight Booking Statistics") (medium) The first four questions are all subtypes of sliding windows. We know that sliding windows are suitable for use when the topic requirements are continuous, and [prefix and](https://oi-wiki.org/basic/prefix-sum / "Prefix and") the same is true. In the continuous problem, the two are of great significance for optimizing the time complexity. Therefore, if you can solve a problem with violence, and the problem happens to have continuous restrictions, then techniques such as sliding windows and prefixing sums should be thought of. @@ -26,7 +26,7 @@ This problem can be solved using the prefix sum. Prefix sum is an important kind For [1,2,3,4,5,6], the prefix sum can be pre=[1,3,6,10,15,21]. We can use the formula pre[𝑖]=pre[𝑖-1]+nums[num] to get the value of each prefix sum, and then calculate and solve the problem accordingly through the prefix sum. In fact, the concept of prefix sum is very simple, but the difficulty is how to use prefix sum in the problem and how to use the relationship between prefix and sum to solve the problem. -Title recommendation: [1480. Dynamic sum of one-dimensional arrays] (https://leetcode-cn.com/problems/running-sum-of-1d-array /) +Title recommendation: [1480. Dynamic sum of one-dimensional arrays](https://leetcode-cn.com/problems/running-sum-of-1d-array /) ### 母题 1 @@ -42,20 +42,19 @@ Reference code (JS): ```js function countSubArray(nums) { - let ans = 0; - let pre = 0; - for (_ in nums) { - pre += 1; - ans += pre; - } - return ans; + let ans = 0; + let pre = 0; + for (_ in nums) { + pre += 1; + ans += pre; + } + return ans; } ``` **Complexity analysis** --Time complexity:$O(N)$, where N is the length of the array. --Spatial complexity:$O(1)$ +-Time complexity:$O(N)$, where N is the length of the array. -Spatial complexity:$O(1)$ And since the number of subarrays ending in index i is i +1, this question can directly use the arithmetic sequence summation formula`(1 +n) * n / 2`, where n is the length of the array. @@ -69,25 +68,24 @@ Reference code (JS): ```js function countSubArray(nums) { - let ans = 1; - let pre = 1; - for (let i = 1; i < nums.length; i++) { - if (nums[i] - nums[i - 1] == 1) { - pre += 1; - } else { - pre = 0; - } - - ans += pre; - } - return ans; + let ans = 1; + let pre = 1; + for (let i = 1; i < nums.length; i++) { + if (nums[i] - nums[i - 1] == 1) { + pre += 1; + } else { + pre = 0; + } + + ans += pre; + } + return ans; } ``` **Complexity analysis** --Time complexity:$O(N)$, where N is the length of the array. --Spatial complexity:$O(1)$ +-Time complexity:$O(N)$, where N is the length of the array. -Spatial complexity:$O(1)$ What if the difference between my values is greater than 1? In fact, just change the symbol. Isn't this just to find the number of ascending sub-sequences? I won't continue to repeat them here, you can try it yourself. @@ -101,25 +99,24 @@ Reference code (JS): ```js function countSubArray(k, nums) { - let ans = 0; - let pre = 0; - for (let i = 0; i < nums.length; i++) { - if (nums[i] <= k) { - pre += 1; - } else { - pre = 0; - } - - ans += pre; - } - return ans; + let ans = 0; + let pre = 0; + for (let i = 0; i < nums.length; i++) { + if (nums[i] <= k) { + pre += 1; + } else { + pre = 0; + } + + ans += pre; + } + return ans; } ``` **Complexity analysis** --Time complexity:$O(N)$, where N is the length of the array. --Spatial complexity:$O(1)$ +-Time complexity:$O(N)$, where N is the length of the array. -Spatial complexity:$O(1)$ ### 母题 4 @@ -233,9 +230,7 @@ b: 1 The meaning is: --The maximum length of a sub-string ending in b is 1, which is B. --The maximum length of a sub-string ending in c is 3, which is abc. --The maximum length of a sub-string ending in d is 4, which is abcd. +-The maximum length of a sub-string ending in b is 1, which is B. -The maximum length of a sub-string ending in c is 3, which is abc. -The maximum length of a sub-string ending in d is 4, which is abcd. As for c, there is no need to save it. We can figure it out by way of theme 2. @@ -245,8 +240,7 @@ Specific algorithm: > Keywords are: longest --Use a variable w to record the length of consecutive sub-strings, and the traversal process updates len_mapper according to the value of w --Returns the sum of all values in len_mapper. +-Use a variable w to record the length of consecutive sub-strings, and the traversal process updates len_mapper according to the value of w -Returns the sum of all values in len_mapper. For example: abc, len_mapper at this time is: @@ -271,7 +265,7 @@ z: 1 } ``` -This achieves the purpose of deleveraging. This algorithm is not heavy or leaky, because the longest continuous sub-string must contain a continuous sub-string shorter than it. This idea is the same as [1297. Maximum number of occurrences of a sub-string] (https://github.com/azl397985856/leetcode/issues/266 "1297. The maximum number of occurrences of a strand") The method of pruning is different and the same. +This achieves the purpose of deleveraging. This algorithm is not heavy or leaky, because the longest continuous sub-string must contain a continuous sub-string shorter than it. This idea is the same as [1297. Maximum number of occurrences of a sub-string](https://github.com/azl397985856/leetcode/issues/266 "1297. The maximum number of occurrences of a strand") The method of pruning is different and the same. ### Code (Python) @@ -292,8 +286,7 @@ return sum(len_mapper. values()) **Complexity analysis** --Time complexity:$O(N)$, where $N$ is the length of the string P. --Spatial complexity: Since up to 26 letters are stored, the space is actually constant, so the spatial complexity is $O(1)$. +-Time complexity:$O(N)$, where $N$ is the length of the string P. -Spatial complexity: Since up to 26 letters are stored, the space is actually constant, so the spatial complexity is $O(1)$. ## 795. Number of interval subarrays (medium) @@ -351,8 +344,7 @@ return notGreater(R) - notGreater(L - 1) **_Complexity analysis_** --Time complexity:$O(N)$, where $N$ is the length of the array. --Spatial complexity:$O(1)$. +-Time complexity:$O(N)$, where $N$ is the length of the array. -Spatial complexity:$O(1)$. ## 904. Fruit basket (medium) @@ -439,8 +431,7 @@ return atMostK(2, tree) **Complexity analysis** --Time complexity:$O(N)$, where $N$ is the length of the array. --Spatial complexity:$O(k)$. +-Time complexity:$O(N)$, where $N$ is the length of the array. -Spatial complexity:$O(k)$. ## 992. Subarrays of K different integers (difficult) @@ -512,8 +503,7 @@ return res **Complexity analysis** --Time complexity:$O(N)$, where $N$ is the length of the array. --Spatial complexity:$O(k)$. +-Time complexity:$O(N)$, where $N$ is the length of the array. -Spatial complexity:$O(k)$. ## 1109. Flight booking statistics (medium) diff --git a/thinkings/prefix.md b/thinkings/prefix.md index ba97f2063..60f10c22d 100644 --- a/thinkings/prefix.md +++ b/thinkings/prefix.md @@ -621,4 +621,4 @@ class Solution: 大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。 -![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg) +![](https://p.ipic.vip/n8gbxo.jpg) diff --git a/thinkings/reservoid-sampling.en.md b/thinkings/reservoid-sampling.en.md index a7da921df..0068e5e52 100644 --- a/thinkings/reservoid-sampling.en.md +++ b/thinkings/reservoid-sampling.en.md @@ -46,9 +46,9 @@ In short, no matter which number it is, the probability of being selected is $\f ## Related topics -- [382. Random nodes in the linked list] (https://leetcode-cn.com/problems/linked-list-random-node /"382. "Random nodes") +- [382. Random nodes in the linked list](https://leetcode-cn.com/problems/linked-list-random-node /"382. "Random nodes") - [398. Random Number Index)(https://leetcode-cn.com/problems/random-pick-index /"398. Random number index") -- [497. Random points in non-overlapping rectangles] (https://leetcode-cn.com/problems/random-point-in-non-overlapping-rectangles /"497. Random points in non-overlapping rectangles") +- [497. Random points in non-overlapping rectangles](https://leetcode-cn.com/problems/random-point-in-non-overlapping-rectangles /"497. Random points in non-overlapping rectangles") ## Summary diff --git a/thinkings/run-length-encode-and-huffman-encode.en.md b/thinkings/run-length-encode-and-huffman-encode.en.md index a514f4541..88a347d1b 100644 --- a/thinkings/run-length-encode-and-huffman-encode.en.md +++ b/thinkings/run-length-encode-and-huffman-encode.en.md @@ -2,17 +2,15 @@ ## Hu Hucode (哈 Hucode) -The basic idea of Huffman encoding is to use short encoding to represent characters with high frequency of occurrence, and long encoding to represent characters with low frequency of occurrence. This reduces the average length of the encoded string and the expected value of the length, so as to achieve the purpose of compression. -Therefore, Huffman coding is widely used in the field of lossless compression. It can be seen that Huffman encoding is a variable encoding, not a fixed-length encoding. +The basic idea of Huffman encoding is to use short encoding to represent characters with high frequency of occurrence, and long encoding to represent characters with low frequency of occurrence. This reduces the average length of the encoded string and the expected value of the length, so as to achieve the purpose of compression. Therefore, Huffman coding is widely used in the field of lossless compression. It can be seen that Huffman encoding is a variable encoding, not a fixed-length encoding. The Huffman coding process consists of two main parts: --Build a Huffman tree based on input characters --Traverse the Huffman tree and assign the nodes of the tree to characters +-Build a Huffman tree based on input characters -Traverse the Huffman tree and assign the nodes of the tree to characters As mentioned above, his basic principle is to 'use short encodings to represent characters with high frequency of occurrence, and long encodings to represent characters with low frequency of occurrence`. Therefore, the first thing to do is to count the frequency of occurrence of characters, and then build a Huffman tree (also known as an optimal binary tree) based on the statistical frequency. -! [Huffman-tree](. . /assets/thinkings/huffman-tree. webp) +![Huffman-tree](. . /assets/thinkings/huffman-tree. webp) As shown in the figure, the **Huffman tree is a binary tree**. Among them, the path of the left child node of the node is represented by 0, and the right child node is represented by 1. The value of the node represents its weight. The greater the weight, the smaller the depth. The depth is actually the length of the code. Usually we use the frequency of occurrence of characters as the weight. When encoding is actually performed, it is similar to a dictionary tree. Nodes are not used for encoding, and the paths of nodes are used for encoding. @@ -24,12 +22,12 @@ For example, the result of our frequency statistics for a string is as follows | character | frequency | | :-------: | :-------: | -| a | 5 | -| b | 9 | -| c | 12 | -| d | 13 | -| e | 16 | -| f | 45 | +| a | 5 | +| b | 9 | +| c | 12 | +| d | 13 | +| e | 16 | +| f | 45 | -Construct each element into a node, that is, a tree with only one element. And build a minimum heap that contains all the nodes. The algorithm uses the minimum heap as the priority queue. @@ -41,12 +39,12 @@ The result is like this: | character | frequency | encoding | | :-------: | :-------: | :------: | -| a | 5 | 1100 | -| b | 9 | 1101 | -| c | 12 | 100 | -| d | 13 | 101 | -| e | 16 | 111 | -| f | 45 | 0 | +| a | 5 | 1100 | +| b | 9 | 1101 | +| c | 12 | 100 | +| d | 13 | 101 | +| e | 16 | 111 | +| f | 45 | 0 | ##run-length encode (run-length encoding) @@ -84,4 +82,4 @@ In fact, the principle of video compression is similar, except that video compre ## Related topics -[900.rle-iterator](../problems/900.rle-iterator.md) \ No newline at end of file +[900.rle-iterator](../problems/900.rle-iterator.md) diff --git a/thinkings/search.en.md b/thinkings/search.en.md index cf6260864..efeffd52b 100644 --- a/thinkings/search.en.md +++ b/thinkings/search.en.md @@ -61,7 +61,7 @@ Based on this, you can draw the following decision tree. Animated demonstration of the decision-making process: -! [Search-decision tree. svg](https://pic. stackoverflow. wiki/uploadImages/115/238/39/106/2021/05/27/18/33/b97ee92b-a516-48e1-83d9-b29c1eaf2eff. svg) +![Search-decision tree. svg](https://pic. stackoverflow. wiki/uploadImages/115/238/39/106/2021/05/27/18/33/b97ee92b-a516-48e1-83d9-b29c1eaf2eff. svg) **Some search algorithms are based on this simple idea, and the essence is to simulate this decision tree. There are actually many interesting details in it, which we will explain in more detail later. And now everyone only needs to have a little idea of what the solution space is and how to traverse the solution space. ** I will continue to deepen this concept later. @@ -128,7 +128,7 @@ For example, the depth of the calculation tree to be discussed below. Since the For example, we will talk about calculating the number of child nodes of the tree below. Since the recursive formula for the child nodes of the tree is: $f(x)= sum_{i=0}^{n}{f(a_i)}$ where x is a node in the tree, and$a_i$ is the child node of the node in the tree. The base case does not have any child nodes (that is, leaf nodes), at this time $f(x) = 1$. Therefore, we can use the back-order traversal to complete the statistics of the number of child nodes from the bottom up. -Regarding the traversal method used for the analysis of recursive relationships, I described this in detail in the sub-topic "Simulation, Enumeration and Recursion" in the basic article of "91 Days Learning Algorithm". 91 Students can view it directly. Regarding the various traversal methods of trees, I am in [Tree topic] (https://leetcode-solution.cn/solutionDetail?url=https%3A%2F%2Fapi.github.com%2Frepos%2Fazl397985856%2Fleetcode%2Fcontents%2Fthinkings%2Ftree.md&type=1 ) is introduced in detail. +Regarding the traversal method used for the analysis of recursive relationships, I described this in detail in the sub-topic "Simulation, Enumeration and Recursion" in the basic article of "91 Days Learning Algorithm". 91 Students can view it directly. Regarding the various traversal methods of trees, I am in [Tree topic](https://leetcode-solution.cn/solutionDetail?url=https%3A%2F%2Fapi.github.com%2Frepos%2Fazl397985856%2Fleetcode%2Fcontents%2Fthinkings%2Ftree.md&type=1) is introduced in detail. ##### Iterative deepening @@ -215,7 +215,7 @@ Back to the topic. We can use a binary bit to represent a subset of the original > Here 40% off is 20. -> If you are not familiar with state compression, you can take a look at my article [What is state compression DP? This question will get you started] (https://mp.weixin.qq.com/s?__biz=MzI4MzUxNjI3OA==&mid=2247486874&idx=1&sn=0f27ddd51ad5b92ef0ddcc4fb19a3f5e&chksm=eb88c183dcff4895209c4dc4d005e3bb143cc852805594b407dbf3f4718c60261f09c2849f70&token=1227596150&lang=zh_CN#rd ) +> If you are not familiar with state compression, you can take a look at my article [What is state compression DP? This question will get you started](https://mp.weixin.qq.com/s?__biz=MzI4MzUxNjI3OA==&mid=2247486874&idx=1&sn=0f27ddd51ad5b92ef0ddcc4fb19a3f5e&chksm=eb88c183dcff4895209c4dc4d005e3bb143cc852805594b407dbf3f4718c60261f09c2849f70&token=1227596150&lang=zh_CN#rd) Next, we use dynamic programming to find the sum of all subsets. @@ -322,9 +322,9 @@ Let n be the length of the array and m be $\frac{n}{2}$. Related topics recommended: -- [16. The sum of the three closest numbers] (https://leetcode-cn.com/problems/3sum-closest /) -- [1049. The weight of the last stone II] (https://leetcode-cn.com/problems/last-stone-weight-ii /) -- [1774. The cost of dessert closest to the target price] (https://leetcode-cn.com/problems/closest-dessert-cost /) +- [16. The sum of the three closest numbers](https://leetcode-cn.com/problems/3sum-closest /) +- [1049. The weight of the last stone II](https://leetcode-cn.com/problems/last-stone-weight-ii /) +- [1774. The cost of dessert closest to the target price](https://leetcode-cn.com/problems/closest-dessert-cost /) What does this question have to do with two-way search? diff --git a/thinkings/tree.en.md b/thinkings/tree.en.md index c1499f02a..5676680b0 100644 --- a/thinkings/tree.en.md +++ b/thinkings/tree.en.md @@ -16,7 +16,7 @@ First light up the protagonist of this article-tree (my makeup technique is okay ![](https://p.ipic.vip/5lkkd6.jpg) -[Tree Tag] (https://leetcode-cn.com/tag/tree /"Tree tag") There are a total of 175 questions in leetcode. In order to prepare for this topic, I spent a few days brushing almost all the tree topics of leetcode. +[Tree Tag](https://leetcode-cn.com/tag/tree /"Tree tag") There are a total of 175 questions in leetcode. In order to prepare for this topic, I spent a few days brushing almost all the tree topics of leetcode. ![](https://p.ipic.vip/bdo0jv.jpg) @@ -24,7 +24,7 @@ Except for 35 locked ones, 1 question that cannot be done (1628 questions, I don ## Edible Guide -Hello everyone, this is lucifer. What I bring to you today is the topic "Tree". In addition, in order to keep the focus and practicality of the chapters, some content is omitted, such as Huffman trees, prefix trees, balanced binary trees (red and black trees, etc.), and binary piles. These contents are relatively not that practical. If you are also interested in these contents, you can pay attention to my warehouse [leetcode algorithm problem solving] (https://github.com/azl397985856/leetcode "leetcode algorithm problem solving"), if you have any content you want to see, you can also leave a message to tell me~ +Hello everyone, this is lucifer. What I bring to you today is the topic "Tree". In addition, in order to keep the focus and practicality of the chapters, some content is omitted, such as Huffman trees, prefix trees, balanced binary trees (red and black trees, etc.), and binary piles. These contents are relatively not that practical. If you are also interested in these contents, you can pay attention to my warehouse [leetcode algorithm problem solving](https://github.com/azl397985856/leetcode "leetcode algorithm problem solving"), if you have any content you want to see, you can also leave a message to tell me~ In addition, it is important to inform everyone in advance that many of the contents of this article depend on recursion. Regarding the recursion exercise, I recommend that you draw the recursion process on paper and manually substitute it several times. After the brain is familiar with recursion, it doesn't have to work so hard. Students who are really too lazy to draw pictures can also find a visual recursion website, such as https://recursion.now.sh /. After you have a certain understanding of recursion, take a closer look at the various traversal methods of the tree, then finish reading this article, and finally do the topic at the end of the article. It's not a big problem to fix recursion. @@ -72,7 +72,7 @@ Taking the calculation of 5's fibbonacci as an example, the process is probably **This is actually the subsequent traversal of a tree. **, do you think the tree (logical tree) is very important? We will talk about the post-sequence traversal later, now everyone knows that this is the case. -You can also go to [this website] (https://recursion.now.sh / "Recursive Visualization Website") View the single-step execution effect of the above algorithm. Of course, there are more animated demonstrations of algorithms on this website. +You can also go to [this website](https://recursion.now.sh / "Recursive Visualization Website") View the single-step execution effect of the above algorithm. Of course, there are more animated demonstrations of algorithms on this website. > The arrow directions in the figure above are for your convenience. In fact, the direction of the arrow becomes downward, which is the real tree structure. @@ -205,7 +205,7 @@ Some students may say that every node here will enter and exit the stack twice, > Morris traversal is an algorithm that can complete the traversal of a tree with a constant spatial complexity. -I think that in most cases, people don't need to pay too much attention to such small differences. In addition, if this traversal method is fully mastered, it is not difficult to write an iteration into the stack based on the idea of recursion. It's nothing more than entering the stack when the function is called, and exiting the stack when the function returns. For more information about binary tree traversal, you can also visit the topic I wrote earlier ["Binary tree Traversal"] (https://github.com/azl397985856/leetcode/blob/master/thinkings/binary-tree-traversal.md "Traversal of binary trees"). +I think that in most cases, people don't need to pay too much attention to such small differences. In addition, if this traversal method is fully mastered, it is not difficult to write an iteration into the stack based on the idea of recursion. It's nothing more than entering the stack when the function is called, and exiting the stack when the function returns. For more information about binary tree traversal, you can also visit the topic I wrote earlier ["Binary tree Traversal"](https://github.com/azl397985856/leetcode/blob/master/thinkings/binary-tree-traversal.md "Traversal of binary trees"). ### Summary @@ -278,7 +278,7 @@ dfs(j) } ``` -The visited above is to prevent endless loops caused by the presence of rings. And we know that trees do not have rings, so most of the topics of the tree do not need to be visited, unless you modify the structure of the tree, for example, the left pointer of the left subtree points to itself, and there will be a ring at this time. Another example is [138. Copy the linked list with random pointers] (https://leetcode-cn.com/problems/copy-list-with-random-pointer /) This question needs to record the nodes that have been copied. There are very few questions for trees that need to record visited information. +The visited above is to prevent endless loops caused by the presence of rings. And we know that trees do not have rings, so most of the topics of the tree do not need to be visited, unless you modify the structure of the tree, for example, the left pointer of the left subtree points to itself, and there will be a ring at this time. Another example is [138. Copy the linked list with random pointers](https://leetcode-cn.com/problems/copy-list-with-random-pointer /) This question needs to record the nodes that have been copied. There are very few questions for trees that need to record visited information. Therefore, the DFS of a tree is more: diff --git a/thinkings/union-find.en.md b/thinkings/union-find.en.md index 0443ac492..92b0dbb9c 100644 --- a/thinkings/union-find.en.md +++ b/thinkings/union-find.en.md @@ -303,10 +303,10 @@ There are many topics about parallel collection. The official data is 30 questio I have summarized a few questions here and checked the topics: - [547. Circle of friends](../problems/547.friend-circles.md) -- [721. Account consolidation] (https://leetcode-cn.com/problems/accounts-merge/solution/mo-ban-ti-bing-cha-ji-python3-by-fe-lucifer-3 /) -- [990. Satisfiability of equation equation] (https://github.com/azl397985856/leetcode/issues/304 ) +- [721. Account consolidation](https://leetcode-cn.com/problems/accounts-merge/solution/mo-ban-ti-bing-cha-ji-python3-by-fe-lucifer-3 /) +- [990. Satisfiability of equation equation](https://github.com/azl397985856/leetcode/issues/304) - [1202. Exchange elements in a string](https://leetcode-cn.com/problems/smallest-string-with-swaps /) -- [1697. Check whether the path with the edge length limit exists] (https://leetcode-cn.com/problems/checking-existence-of-edge-length-limited-paths /) +- [1697. Check whether the path with the edge length limit exists](https://leetcode-cn.com/problems/checking-existence-of-edge-length-limited-paths /) The first four questions of the above questions are all about the connectivity of the weighted graph, and the fifth question is about the connectivity of the weighted graph. Everyone must know both types. The keywords of the above topics are **Connectivity**, and the codes are all sets of templates. After reading the content here, it is recommended to practice with the above topics and test the learning results.