From dc65f95f7beecb1f6b2ecf49665b4f3a89c6c904 Mon Sep 17 00:00:00 2001 From: wisuky <48423733+wisuky@users.noreply.github.com> Date: Sat, 5 Aug 2023 17:05:35 +0800 Subject: [PATCH 01/23] =?UTF-8?q?Update=200001.=E4=B8=A4=E6=95=B0=E4=B9=8B?= =?UTF-8?q?=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改错别字 --- problems/0001.两数之和.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index 712bc3f0..4e44d0c3 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -37,20 +37,20 @@ [242. 有效的字母异位词](https://www.programmercarl.com/0242.有效的字母异位词.html) 这道题目是用数组作为哈希表来解决哈希问题,[349. 两个数组的交集](https://www.programmercarl.com/0349.两个数组的交集.html)这道题目是通过set作为哈希表来解决哈希问题。 -首先我在强调一下 **什么时候使用哈希法**,当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。 +首先我再强调一下 **什么时候使用哈希法**,当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。 本题呢,我就需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是 是否出现在这个集合。 那么我们就应该想到使用哈希法了。 -因为本地,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,**需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适**。 +因为本题,我们不仅要知道元素有没有遍历过,还要知道这个元素对应的下标,**需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适**。 再来看一下使用数组和set来做哈希法的局限。 * 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。 * set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。 -此时就要选择另一种数据结构:map ,map是一种key value的存储结构,可以用key保存数值,用value在保存数值所在的下标。 +此时就要选择另一种数据结构:map ,map是一种key value的存储结构,可以用key保存数值,用value再保存数值所在的下标。 C++中map,有三种类型: From d4810327aed53170c21c23f06e1fb6c54a184337 Mon Sep 17 00:00:00 2001 From: Liu Yongliang <41845017+tlylt@users.noreply.github.com> Date: Sun, 6 Aug 2023 10:25:37 +0800 Subject: [PATCH 02/23] =?UTF-8?q?Update=200459.=E9=87=8D=E5=A4=8D=E7=9A=84?= =?UTF-8?q?=E5=AD=90=E5=AD=97=E7=AC=A6=E4=B8=B2.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0459.重复的子字符串.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0459.重复的子字符串.md b/problems/0459.重复的子字符串.md index f99102ab..177c3878 100644 --- a/problems/0459.重复的子字符串.md +++ b/problems/0459.重复的子字符串.md @@ -52,7 +52,7 @@ 也就是由前后相同的子串组成。 -那么既然前面有相同的子串,后面有相同的子串,用 s + s,这样组成的字符串中,后面的子串做前串,前后的子串做后串,就一定还能组成一个s,如图: +那么既然前面有相同的子串,后面有相同的子串,用 s + s,这样组成的字符串中,后面的子串做前串,前面的子串做后串,就一定还能组成一个s,如图: ![图二](https://code-thinking-1253855093.file.myqcloud.com/pics/20220728104931.png) From 692647b03a1e14d895bbb24b5b98286c17100c73 Mon Sep 17 00:00:00 2001 From: wisuky <48423733+wisuky@users.noreply.github.com> Date: Sun, 6 Aug 2023 21:27:09 +0800 Subject: [PATCH 03/23] =?UTF-8?q?Update=200454.=E5=9B=9B=E6=95=B0=E7=9B=B8?= =?UTF-8?q?=E5=8A=A0II.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0454.四数相加II.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0454.四数相加II.md b/problems/0454.四数相加II.md index 90c37334..1c262c87 100644 --- a/problems/0454.四数相加II.md +++ b/problems/0454.四数相加II.md @@ -41,7 +41,7 @@ ## 思路 -本题咋眼一看好像和[0015.三数之和](https://programmercarl.com/0015.三数之和.html),[0018.四数之和](https://programmercarl.com/0018.四数之和.html)差不多,其实差很多。 +本题乍眼一看好像和[0015.三数之和](https://programmercarl.com/0015.三数之和.html),[0018.四数之和](https://programmercarl.com/0018.四数之和.html)差不多,其实差很多。 **本题是使用哈希法的经典题目,而[0015.三数之和](https://programmercarl.com/0015.三数之和.html),[0018.四数之和](https://programmercarl.com/0018.四数之和.html)并不合适使用哈希法**,因为三数之和和四数之和这两道题目使用哈希法在不超时的情况下做到对结果去重是很困难的,很有多细节需要处理。 From 1f9f9c224cafb201ae71668a330a82a01105cfd5 Mon Sep 17 00:00:00 2001 From: wisuky <48423733+wisuky@users.noreply.github.com> Date: Tue, 8 Aug 2023 13:43:15 +0800 Subject: [PATCH 04/23] =?UTF-8?q?Update=200015.=E4=B8=89=E6=95=B0=E4=B9=8B?= =?UTF-8?q?=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0015.三数之和.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md index 4951c90c..91fc9d68 100644 --- a/problems/0015.三数之和.md +++ b/problems/0015.三数之和.md @@ -171,7 +171,7 @@ public: #### a的去重 -说道去重,其实主要考虑三个数的去重。 a, b ,c, 对应的就是 nums[i],nums[left],nums[right] +说到去重,其实主要考虑三个数的去重。 a, b ,c, 对应的就是 nums[i],nums[left],nums[right] a 如果重复了怎么办,a是nums里遍历的元素,那么应该直接跳过去。 @@ -181,7 +181,7 @@ a 如果重复了怎么办,a是nums里遍历的元素,那么应该直接跳 其实不一样! -都是和 nums[i]进行比较,是比较它的前一个,还是比较他的后一个。 +都是和 nums[i]进行比较,是比较它的前一个,还是比较它的后一个。 如果我们的写法是 这样: @@ -191,7 +191,7 @@ if (nums[i] == nums[i + 1]) { // 去重操作 } ``` -那就我们就把 三元组中出现重复元素的情况直接pass掉了。 例如{-1, -1 ,2} 这组数据,当遍历到第一个-1 的时候,判断 下一个也是-1,那这组数据就pass了。 +那我们就把 三元组中出现重复元素的情况直接pass掉了。 例如{-1, -1 ,2} 这组数据,当遍历到第一个-1 的时候,判断 下一个也是-1,那这组数据就pass了。 **我们要做的是 不能有重复的三元组,但三元组内的元素是可以重复的!** From d3eb234491ba63256ab8451ca16fd1084d24b8ff Mon Sep 17 00:00:00 2001 From: Jining Jiang <58833386+jjnnzb@users.noreply.github.com> Date: Tue, 8 Aug 2023 23:51:25 +0800 Subject: [PATCH 05/23] =?UTF-8?q?fix:=20=E8=A1=A8=E8=BF=B0=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 应该是“其他”,而不是“其其他” --- problems/背包理论基础01背包-1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/背包理论基础01背包-1.md b/problems/背包理论基础01背包-1.md index 7511ac87..79ad26a8 100644 --- a/problems/背包理论基础01背包-1.md +++ b/problems/背包理论基础01背包-1.md @@ -28,7 +28,7 @@ ![416.分割等和子集1](https://code-thinking-1253855093.file.myqcloud.com/pics/20210117171307407.png) -至于背包九讲其其他背包,面试几乎不会问,都是竞赛级别的了,leetcode上连多重背包的题目都没有,所以题库也告诉我们,01背包和完全背包就够用了。 +至于背包九讲其他背包,面试几乎不会问,都是竞赛级别的了,leetcode上连多重背包的题目都没有,所以题库也告诉我们,01背包和完全背包就够用了。 而完全背包又是也是01背包稍作变化而来,即:完全背包的物品数量是无限的。 From 6167408cd29d884bb8b74cc73b05ce7b6aac87ed Mon Sep 17 00:00:00 2001 From: han Date: Wed, 9 Aug 2023 12:06:32 +0800 Subject: [PATCH 06/23] =?UTF-8?q?=E6=B7=BB=E5=8A=A00018.=E5=9B=9B=E6=95=B0?= =?UTF-8?q?=E4=B9=8B=E5=92=8C=20Ruby=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0018.四数之和.md | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md index 28c20b7a..17715b2e 100644 --- a/problems/0018.四数之和.md +++ b/problems/0018.四数之和.md @@ -649,6 +649,54 @@ object Solution { } } ``` +### Ruby: + +```ruby +def four_sum(nums, target) + #结果集 + result = [] + nums = nums.sort! + + for i in 0..nums.size - 1 + return result if i > 0 && nums[i] > target && nums[i] >= 0 + #对a进行去重 + next if i > 0 && nums[i] == nums[i - 1] + + for j in i + 1..nums.size - 1 + break if nums[i] + nums[j] > target && nums[i] + nums[j] >= 0 + #对b进行去重 + next if j > i + 1 && nums[j] == nums[j - 1] + left = j + 1 + right = nums.size - 1 + while left < right + sum = nums[i] + nums[j] + nums[left] + nums[right] + if sum > target + right -= 1 + elsif sum < target + left += 1 + else + result << [nums[i], nums[j], nums[left], nums[right]] + + #对c进行去重 + while left < right && nums[left] == nums[left + 1] + left += 1 + end + + #对d进行去重 + while left < right && nums[right] == nums[right - 1] + right -= 1 + end + + right -= 1 + left += 1 + end + end + end + end + + return result +end +```

From 7ae878753b3d700d14a3bfd0c55194c618b62a03 Mon Sep 17 00:00:00 2001 From: han Date: Thu, 10 Aug 2023 10:21:29 +0800 Subject: [PATCH 07/23] =?UTF-8?q?=E6=B7=BB=E5=8A=A01047.=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E4=B8=AD=E7=9A=84=E6=89=80=E6=9C=89?= =?UTF-8?q?=E7=9B=B8=E9=82=BB=E9=87=8D=E5=A4=8D=E9=A1=B9=20Ruby=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...除字符串中的所有相邻重复项.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index ad54f0f8..ffe13530 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -475,6 +475,26 @@ impl Solution { } ``` +### Ruby + +```ruby +def remove_duplicates(s) + #数组模拟栈 + stack = [] + s.each_char do |chr| + if stack.empty? + stack.push chr + else + head = stack.pop + #重新进栈 + stack.push head, chr if head != chr + end + end + + return stack.join +end +``` +

From 86f2dcb46bbd7e243bee746c37f7cdeb448f004c Mon Sep 17 00:00:00 2001 From: TonySu Date: Thu, 10 Aug 2023 17:24:51 +0800 Subject: [PATCH 08/23] =?UTF-8?q?Update=200130.=E8=A2=AB=E5=9B=B4=E7=BB=95?= =?UTF-8?q?=E7=9A=84=E5=8C=BA=E5=9F=9F.md,=20=E5=A2=9E=E5=8A=A0Python3=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=9A=84DFS=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加Python3 版本的DFS解法,在leetcode上测试通过。 --- problems/0130.被围绕的区域.md | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/problems/0130.被围绕的区域.md b/problems/0130.被围绕的区域.md index e244873b..e8a1f02f 100644 --- a/problems/0130.被围绕的区域.md +++ b/problems/0130.被围绕的区域.md @@ -385,6 +385,55 @@ class Solution { } } ``` +### Python3 + +```Python +// 深度优先遍历 +class Solution: + dir_list = [(0, 1), (0, -1), (1, 0), (-1, 0)] + def solve(self, board: List[List[str]]) -> None: + """ + Do not return anything, modify board in-place instead. + """ + row_size = len(board) + column_size = len(board[0]) + visited = [[False] * column_size for _ in range(row_size)] + # 从边缘开始,将边缘相连的O改成A。然后遍历所有,将A改成O,O改成X + # 第一行和最后一行 + for i in range(column_size): + if board[0][i] == "O" and not visited[0][i]: + self.dfs(board, 0, i, visited) + if board[row_size-1][i] == "O" and not visited[row_size-1][i]: + self.dfs(board, row_size-1, i, visited) + + # 第一列和最后一列 + for i in range(1, row_size-1): + if board[i][0] == "O" and not visited[i][0]: + self.dfs(board, i, 0, visited) + if board[i][column_size-1] == "O" and not visited[i][column_size-1]: + self.dfs(board, i, column_size-1, visited) + + for i in range(row_size): + for j in range(column_size): + if board[i][j] == "A": + board[i][j] = "O" + elif board[i][j] == "O": + board[i][j] = "X" + + + def dfs(self, board, x, y, visited): + if visited[x][y] or board[x][y] == "X": + return + visited[x][y] = True + board[x][y] = "A" + for i in range(4): + new_x = x + self.dir_list[i][0] + new_y = y + self.dir_list[i][1] + if new_x >= len(board) or new_y >= len(board[0]) or new_x < 0 or new_y < 0: + continue + self.dfs(board, new_x, new_y, visited) + +```

From 92051fac670c4c1e776d0afad4adadbc9c6dacfd Mon Sep 17 00:00:00 2001 From: Liu Yongliang <41845017+tlylt@users.noreply.github.com> Date: Sun, 13 Aug 2023 13:59:49 +0800 Subject: [PATCH 09/23] =?UTF-8?q?Update=200225.=E7=94=A8=E9=98=9F=E5=88=97?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=A0=88.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0225.用队列实现栈.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md index 13b742f8..3de300c7 100644 --- a/problems/0225.用队列实现栈.md +++ b/problems/0225.用队列实现栈.md @@ -111,7 +111,7 @@ public: } }; ``` -* 时间复杂度: push为O(n),其他为O(1) +* 时间复杂度: pop为O(n),其他为O(1) * 空间复杂度: O(n) ## 优化 @@ -158,7 +158,7 @@ public: } }; ``` -* 时间复杂度: push为O(n),其他为O(1) +* 时间复杂度: pop为O(n),其他为O(1) * 空间复杂度: O(n) From 0f458de25416863e592d419a35f535405610f9bf Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Sun, 13 Aug 2023 22:59:49 -0400 Subject: [PATCH 10/23] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=E8=A7=A3=E6=B3=95?= =?UTF-8?q?=EF=BC=88hashArray=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增java解法(hashArray) --- problems/0349.两个数组的交集.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/problems/0349.两个数组的交集.md b/problems/0349.两个数组的交集.md index 26a9286d..138067e3 100644 --- a/problems/0349.两个数组的交集.md +++ b/problems/0349.两个数组的交集.md @@ -121,7 +121,7 @@ public: ## 其他语言版本 ### Java: - +版本一:使用HashSet ```Java import java.util.HashSet; import java.util.Set; @@ -159,7 +159,28 @@ class Solution { } } ``` - +版本二:使用Hash數組 +```java +class Solution { + public int[] intersection(int[] nums1, int[] nums2) { + int[] hash1 = new int[1002]; + int[] hash2 = new int[1002]; + for(int i : nums1) + hash1[i]++; + for(int i : nums2) + hash2[i]++; + List resList = new ArrayList<>(); + for(int i = 0; i < 1002; i++) + if(hash1[i] > 0 && hash2[i] > 0) + resList.add(i); + int index = 0; + int res[] = new int[resList.size()]; + for(int i : resList) + res[index++] = i; + return res; + } +} +``` ### Python3: (版本一) 使用字典和集合 From 6a2f01055c784d54059568f970b44d650be04e87 Mon Sep 17 00:00:00 2001 From: programmercarl <826123027@qq.com> Date: Tue, 15 Aug 2023 10:09:47 +0800 Subject: [PATCH 11/23] Update --- problems/0332.重新安排行程.md | 7 +-- problems/qita/acm.md | 89 +++++++++++++++++++++++++++++ problems/二叉树理论基础.md | 2 +- 3 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 problems/qita/acm.md diff --git a/problems/0332.重新安排行程.md b/problems/0332.重新安排行程.md index 3798b48d..794a67fa 100644 --- a/problems/0332.重新安排行程.md +++ b/problems/0332.重新安排行程.md @@ -237,13 +237,10 @@ public: ```cpp for (pair& target : targets[result[result.size() - 1]]) ``` -pair里要有const,因为map中的key是不可修改的,所以是`pair`。 -如果不加const,也可以复制一份pair,例如这么写: +一定要加上引用即 `& target`,因为后面有对 target.second 做减减操作,如果没有引用,单纯复制,这个结果就没记录下来,那最后的结果就不对了。 -```cpp -for (pairtarget : targets[result[result.size() - 1]]) -``` +加上引用之后,就必须在 string 前面加上 const,因为map中的key 是不可修改了,这就是语法规定了。 ## 总结 diff --git a/problems/qita/acm.md b/problems/qita/acm.md new file mode 100644 index 00000000..1be0e924 --- /dev/null +++ b/problems/qita/acm.md @@ -0,0 +1,89 @@ + +# 如何练习ACM模式输入输入模式 | 如何准备笔试 | 卡码网 + +卡码网地址:[https://kamacoder.com](https://kamacoder.com) + +## 为什么卡码网 + +录友们在求职的时候会发现,很多公司的笔试题和面试题都是ACM模式, 而大家习惯去力扣刷题,力扣是核心代码模式。 + +当大家在做ACM模式的算法题的时候,需要自己处理数据的输入输出,**如果没有接触过的话,还是挺难的**。 + +[知识星球](https://programmercarl.com/other/kstar.html)里很多录友的日常打卡中,都表示被 ACM模式折磨过: + +

+ +
+ +
+ +
+ +
+ +所以我正式推出:**卡码网**([https://kamacoder.com](https://kamacoder.com)),**专门帮助大家练习ACM模式**。 + +那么之前大家去哪里练习ACM模式呢? + +去牛客做笔试真题,结果发现 ACM模式没练出来,题目倒是巨难,一点思路都没有,代码更没有写,ACM模式无从练起。 + +去洛谷,POJ上练习? 结果发现 题目超多,不知道从哪里开始刷,也没有一个循序渐进的刷题顺序。 + +**而卡码网上有我精选+制作的25道题目**!我还把25题的后台测试数据制作了一遍,保证大家练习的效果。 + +为什么题目不多,只有25道? + +因为大家练习ACM模式不需要那么多题目,有一个循序渐进的练习过程就好了。 + +这25道题目包含了数组、链表、哈希表、字符串、二叉树、动态规划以及图的的题目,常见的输入输出方式都覆盖了。 + +**这是最精华的25道题目**!。 + +## 卡码网长什么样 + +来看看这极简的界面,没有烂七八糟的功能,只有刷题! + +
+ +在「状态」这里可以看到 大家提交的代码和判题记录,目前卡码网([https://kamacoder.com](https://kamacoder.com))几乎无时无刻都有卡友在提交代码。 +看看大家周六晚上都在做什么,刷哪些题目。 + +
+ + +提交代码的界面是这样的,**目前支持所有主流刷题语言**。 + +
+ +## 题解 + +基本大家来卡码网([https://kamacoder.com](https://kamacoder.com))练习ACM模式,都是对输入输出不够了解的,所以想看现成的题解,看看究竟是怎么处理的。 + +所以我用C++把卡码网上25道题目的题解都写了,并发布到Github上: + +[https://github.com/youngyangyang04/kamacoder-solutions](https://github.com/youngyangyang04/kamacoder-solutions) + +
+ +**欢迎去Github上star,欢迎fork,也欢迎来Github仓库贡献其他语言版本,成为contributor**。 + +如果不懂如何和开源项目提交代码,[可以看这里](https://www.programmercarl.com/qita/join.html) + +目前已经有两位录友贡献C和Java版本了。 + +
+ +期待在Github(https://github.com/youngyangyang04/kamacoder-solutions) 的contributors上也出现你的头像。 + +目前题解只有C++代码吗? + +当然不是,大多数题目已经有了 Java、python、C版本。 **其他语言版本,就给录友们成为contributor的机会了**。 + +## 最后 + +卡码网地址:[https://kamacoder.com](https://kamacoder.com) + +快去体验吧,笔试之前最好 把卡码网25道题目都刷完。 + +期待录友们成为最早一批把卡码网刷爆的coder! + diff --git a/problems/二叉树理论基础.md b/problems/二叉树理论基础.md index 184dba60..e2c6d83c 100644 --- a/problems/二叉树理论基础.md +++ b/problems/二叉树理论基础.md @@ -150,7 +150,7 @@ 最后再说一说二叉树中深度优先和广度优先遍历实现方式,我们做二叉树相关题目,经常会使用递归的方式来实现深度优先遍历,也就是实现前中后序遍历,使用递归是比较方便的。 -**之前我们讲栈与队列的时候,就说过栈其实就是递归的一种实现结构**,也就说前中后序遍历的逻辑其实都是可以借助栈使用非递归的方式来实现的。 +**之前我们讲栈与队列的时候,就说过栈其实就是递归的一种实现结构**,也就说前中后序遍历的逻辑其实都是可以借助栈使用递归的方式来实现的。 而广度优先遍历的实现一般使用队列来实现,这也是队列先进先出的特点所决定的,因为需要先进先出的结构,才能一层一层的来遍历二叉树。 From 77f448ec961c4547fb2e2a70356020e760ed7c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=93=88=E5=93=88=E5=93=88?= <76643786+Projecthappy@users.noreply.github.com> Date: Wed, 16 Aug 2023 14:38:49 +0800 Subject: [PATCH 12/23] =?UTF-8?q?0332.=E9=87=8D=E6=96=B0=E5=AE=89=E6=8E=92?= =?UTF-8?q?=E8=A1=8C=E7=A8=8B=EF=BC=8C=E6=B7=BB=E5=8A=A0java=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0332.重新安排行程.md | 78 +++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/problems/0332.重新安排行程.md b/problems/0332.重新安排行程.md index fcdeae7b..2498fbfe 100644 --- a/problems/0332.重新安排行程.md +++ b/problems/0332.重新安排行程.md @@ -261,6 +261,84 @@ for (pair& target : targets[result[result.size() - 1]]) ### Java +```java +/* 首先遍历所有机票,将机票转换成map,其中起点作为key,终点按照字典顺序插入到终点的列表中 + 然后进入递归,递归中首先在result中加入当前位置,如果票用完了就说明这条路走通了 + 递归中遍历从当前位置出发的终点(也就是map中key为当前位置的列表),因为列表是有序的,因此只要出现能走通的路径,这条路径就是字典排序最低的 + 在遍历中,首先从map中移除当前的机票,将遍历到的终点作为起点进入下一层的递归中,如果发现当前机票往后走走不通,再把当前的机票加到map中*/ +class Solution { + //key为起点,value是有序的终点的列表 + Map> ticketMap = new HashMap<>(); + LinkedList result = new LinkedList<>(); + + public List findItinerary(List> tickets) { + //遍历tickets,存入ticketMap中 + for (List ticket : tickets) { + addNew(ticket.get(0), ticket.get(1)); + } + deal("JFK"); + return result; + } + + boolean deal(String currentLocation) { + result.add(currentLocation); + //机票全部用完,找到最小字符路径 + if (ticketMap.isEmpty()) { + return true; + } + //当前位置的终点列表 + LinkedList targetLocations = ticketMap.get(currentLocation); + //机票没用完,但是没有从当前位置出发的机票了,说明这条路走不通 + if (targetLocations == null) { + return false; + } + //终点列表中遍历到的终点 + String targetLocation; + //遍历从当前位置出发的机票 + for (int i = 0; i < targetLocations.size(); i++) { + targetLocation = targetLocations.get(i); + //删除map中的机票,如果当前位置只有一个终点,直接删除k,v,有多个终点则删除终点列表中当前的终点 + if (targetLocations.size() == 1) { + ticketMap.remove(currentLocation); + } else { + targetLocations.remove(i); + } + //递归 + if (deal(targetLocation)) { + return true; + } else { + //路线走不通,将机票重新加到map中 + addNew(currentLocation, targetLocation); + result.removeLast(); + } + } + return false; + } + + /** + * 在map中添加新元素 + * + * @param start 起点 + * @param end 终点 + */ + void addNew(String start, String end) { + LinkedList startAllEnd = ticketMap.get(start); + if (startAllEnd != null) { + for (int i = 0; i < startAllEnd.size() + 1; i++) { + if (i == startAllEnd.size() || end.compareTo(startAllEnd.get(i)) < 0) { + startAllEnd.add(i, end); + break; + } + } + } else { + LinkedList ends = new LinkedList<>(); + ends.add(end); + ticketMap.put(start, ends); + } + } +} +``` + ```java class Solution { private LinkedList res; From 00f2aa679318c12921ce974168ad3b7728bc0ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=93=88=E5=93=88=E5=93=88?= <76643786+Projecthappy@users.noreply.github.com> Date: Wed, 16 Aug 2023 15:28:28 +0800 Subject: [PATCH 13/23] =?UTF-8?q?0051.N=E7=9A=87=E5=90=8E=EF=BC=8Cjava?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B0=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0051.N皇后.md | 52 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/problems/0051.N皇后.md b/problems/0051.N皇后.md index 6bc4fa78..71c40238 100644 --- a/problems/0051.N皇后.md +++ b/problems/0051.N皇后.md @@ -345,6 +345,58 @@ class Solution { } } ``` +```java +//该方法主要特点在于用一个一维数组暂存皇后的位置,数组下标代表行,数组下标的值代表列,并初始化一个长度为n-1,值全为'.'的模板字符串 +//在找到合法方案时,遍历数组,在模板字符串下标为数组值的位置插入Q +class Solution { + //结果 + List> result = new ArrayList<>(); + //储存皇后的位置,下标为行,值为列 + int[] queenIndex; + //棋盘中一行的字符串模板 + String template; + int size; + + public List> solveNQueens(int n) { + size = n; + template = ".".repeat(n - 1); + queenIndex = new int[n]; + deal(0); + return result; + } + + void deal(int index) { + //遍历当前行的所有位置(尝试在这行每个位置放置皇后) + for (int i = 0; i < size; i++) { + queenIndex[index] = i; + //检查在当前位置放置皇后是否合法 + if (check(index, i)) { + //如果当前的行是最后一行,就说明当前皇后的摆放已经是完整并且合法的,在结果集中加入当前的摆放方案 + if (index == size - 1) { + List tmp = new ArrayList<>(size); + //遍历当前的皇后位置,在模板字符串对应的位置加入Q,再加入到结果集中 + for (Integer integer : queenIndex) { + tmp.add(new StringBuilder(template).insert(integer, "Q").toString()); + } + result.add(tmp); + return; + } + //如果当前不是最后一行,还需要进入下一行 + deal(index + 1); + } + } + } + + boolean check(int rowIndex, int columnIndex) { + for (int i = 0; i < rowIndex; i++) { + if (queenIndex[i] == columnIndex || (Math.abs(queenIndex[i] - columnIndex) == Math.abs(i - rowIndex))) { + return false; + } + } + return true; + } +} +``` ### Python From b66eb1c7fddaafdf28e510bbfe59fdb5107c67b3 Mon Sep 17 00:00:00 2001 From: programmercarl <826123027@qq.com> Date: Fri, 18 Aug 2023 09:35:21 +0800 Subject: [PATCH 14/23] Update --- problems/0102.二叉树的层序遍历.md | 2 +- problems/0236.二叉树的最近公共祖先.md | 2 +- problems/0977.有序数组的平方.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index ce9a247c..51d030e7 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -18,7 +18,7 @@ * [102.二叉树的层序遍历](https://leetcode.cn/problems/binary-tree-level-order-traversal/) * [107.二叉树的层次遍历II](https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/) * [199.二叉树的右视图](https://leetcode.cn/problems/binary-tree-right-side-view/) -* [637.二叉树的层平均值](https://leetcode.cn/problems/binary-tree-right-side-view/) +* [637.二叉树的层平均值](https://leetcode.cn/problems/average-of-levels-in-binary-tree/) * [429.N叉树的层序遍历](https://leetcode.cn/problems/n-ary-tree-level-order-traversal/) * [515.在每个树行中找最大值](https://leetcode.cn/problems/find-largest-value-in-each-tree-row/) * [116.填充每个节点的下一个右侧节点指针](https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/) diff --git a/problems/0236.二叉树的最近公共祖先.md b/problems/0236.二叉树的最近公共祖先.md index 9db7409e..edb5ea3e 100644 --- a/problems/0236.二叉树的最近公共祖先.md +++ b/problems/0236.二叉树的最近公共祖先.md @@ -133,7 +133,7 @@ left与right的逻辑处理; // 中 ![236.二叉树的最近公共祖先](https://code-thinking-1253855093.file.myqcloud.com/pics/2021020415105872.png) -就像图中一样直接返回7,多美滋滋。 +就像图中一样直接返回7。 但事实上还要遍历根节点右子树(即使此时已经找到了目标节点了),也就是图中的节点4、15、20。 diff --git a/problems/0977.有序数组的平方.md b/problems/0977.有序数组的平方.md index 4bee585b..5bdbcbc7 100644 --- a/problems/0977.有序数组的平方.md +++ b/problems/0977.有序数组的平方.md @@ -30,7 +30,7 @@ ### 暴力排序 -最直观的想法,莫过于:每个数平方之后,排个序,美滋滋,代码如下: +最直观的想法,莫过于:每个数平方之后,排个序,代码如下: ```CPP class Solution { From 4bd8f3ea32bb189de5919745e531a964b5fcd008 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Mon, 21 Aug 2023 16:07:53 +0800 Subject: [PATCH 15/23] =?UTF-8?q?Update=200496.=E4=B8=8B=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=9B=B4=E5=A4=A7=E5=85=83=E7=B4=A0I.md=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0496.下一个更大元素I.md | 32 +++++++++++++++---------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/problems/0496.下一个更大元素I.md b/problems/0496.下一个更大元素I.md index 6bcafafb..e02cfbd1 100644 --- a/problems/0496.下一个更大元素I.md +++ b/problems/0496.下一个更大元素I.md @@ -392,25 +392,33 @@ function nextGreaterElement(nums1: number[], nums2: number[]): number[] { ### Rust ```rust +use std::collections::HashMap; impl Solution { pub fn next_greater_element(nums1: Vec, nums2: Vec) -> Vec { - let mut ans = vec![-1; nums1.len()]; - use std::collections::HashMap; - let mut map = HashMap::new(); - for (idx, &i) in nums1.iter().enumerate() { - map.insert(i, idx); + let (mut res, mut map) = (vec![-1; nums1.len()], HashMap::new()); + if nums1.is_empty() { + return res; } + + nums1.into_iter().enumerate().for_each(|(v, k)| { + map.insert(k, v); + }); + let mut stack = vec![]; - for (idx, &i) in nums2.iter().enumerate() { - while !stack.is_empty() && nums2[*stack.last().unwrap()] < i { - let pos = stack.pop().unwrap(); - if let Some(&jdx) = map.get(&nums2[pos]) { - ans[jdx] = i; + for (i, &value) in nums2.iter().enumerate() { + while let Some(&top) = stack.last() { + if value <= nums2[top] { + break; + } + let stacked_index = stack.pop().unwrap(); + if let Some(&mapped_index) = map.get(&nums2[stacked_index]) { + res[mapped_index] = value; } } - stack.push(idx); + stack.push(i); } - ans + + res } } ``` From 7aae4f81bd83749333400144fa474c918addb7f4 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Mon, 21 Aug 2023 16:29:16 +0800 Subject: [PATCH 16/23] =?UTF-8?q?Update=200503.=E4=B8=8B=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=9B=B4=E5=A4=A7=E5=85=83=E7=B4=A0II.md=20about=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0503.下一个更大元素II.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/problems/0503.下一个更大元素II.md b/problems/0503.下一个更大元素II.md index d211a680..e732b820 100644 --- a/problems/0503.下一个更大元素II.md +++ b/problems/0503.下一个更大元素II.md @@ -289,6 +289,28 @@ impl Solution { } ``` +> 版本二: + +```rust +impl Solution { + pub fn next_greater_elements(nums: Vec) -> Vec { + let (mut stack, mut res) = (vec![], vec![-1; nums.len()]); + + for i in 0..nums.len() * 2 { + while let Some(&top) = stack.last() { + if nums[i % nums.len()] <= nums[top] { + break; + } + let saved_index = stack.pop().unwrap(); + res[saved_index] = nums[i % nums.len()]; + } + stack.push(i % nums.len()); + } + + res + } +} +```

From 264b72f3c63c937e27262b7e92fba027eed6e93c Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Mon, 21 Aug 2023 18:10:48 +0800 Subject: [PATCH 17/23] =?UTF-8?q?Update=200797.=E6=89=80=E6=9C=89=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E7=9A=84=E8=B7=AF=E5=BE=84.md=20about=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0797.所有可能的路径.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/problems/0797.所有可能的路径.md b/problems/0797.所有可能的路径.md index ec8288c6..9d14bd7c 100644 --- a/problems/0797.所有可能的路径.md +++ b/problems/0797.所有可能的路径.md @@ -217,7 +217,29 @@ class Solution: self.path.pop() # 回溯 ``` +### Rust +```rust +impl Solution { + pub fn all_paths_source_target(graph: Vec>) -> Vec> { + let (mut res, mut path) = (vec![], vec![0]); + Self::dfs(&graph, &mut path, &mut res, 0); + res + } + + pub fn dfs(graph: &Vec>, path: &mut Vec, res: &mut Vec>, node: usize) { + if node == graph.len() - 1 { + res.push(path.clone()); + return; + } + for &v in &graph[node] { + path.push(v); + Self::dfs(graph, path, res, v as usize); + path.pop(); + } + } +} +```

From 0f1505600e2c0ab505db9111923bad63ab4e41c1 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Mon, 21 Aug 2023 19:26:18 +0800 Subject: [PATCH 18/23] =?UTF-8?q?Update=200200.=E5=B2=9B=E5=B1=BF=E6=95=B0?= =?UTF-8?q?=E9=87=8F.=E5=B9=BF=E6=90=9C=E7=89=88.md=20about=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0200.岛屿数量.广搜版.md | 41 +++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/problems/0200.岛屿数量.广搜版.md b/problems/0200.岛屿数量.广搜版.md index 5b9d90aa..8bbedb59 100644 --- a/problems/0200.岛屿数量.广搜版.md +++ b/problems/0200.岛屿数量.广搜版.md @@ -240,6 +240,47 @@ class Solution: ``` +### Rust + +```rust + +use std::collections::VecDeque; +impl Solution { + const DIRECTIONS: [(i32, i32); 4] = [(0, 1), (1, 0), (-1, 0), (0, -1)]; + pub fn num_islands(grid: Vec>) -> i32 { + let mut visited = vec![vec![false; grid[0].len()]; grid.len()]; + let mut res = 0; + for (i, chars) in grid.iter().enumerate() { + for (j, &c) in chars.iter().enumerate() { + if !visited[i][j] && c == '1' { + res += 1; + Self::bfs(&grid, &mut visited, (i as i32, j as i32)); + } + } + } + res + } + + pub fn bfs(grid: &Vec>, visited: &mut Vec>, (x, y): (i32, i32)) { + let mut queue = VecDeque::new(); + queue.push_back((x, y)); + visited[x as usize][y as usize] = true; + while let Some((cur_x, cur_y)) = queue.pop_front() { + for (dx, dy) in Self::DIRECTIONS { + let (nx, ny) = (cur_x + dx, cur_y + dy); + if nx < 0 || nx >= grid.len() as i32 || ny < 0 || ny >= grid[0].len() as i32 { + continue; + } + let (nx, ny) = (nx as usize, ny as usize); + if grid[nx][ny] == '1' && !visited[nx][ny] { + visited[nx][ny] = true; + queue.push_back((nx as i32, ny as i32)); + } + } + } + } +} +```

From 660d7bcdc436c758e6094e178c8193eda7120418 Mon Sep 17 00:00:00 2001 From: jinbudaily <18336218010@163.com> Date: Wed, 23 Aug 2023 15:12:47 +0800 Subject: [PATCH 19/23] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E9=9A=8F=E6=83=B3=E5=BD=95=E7=AE=97=E6=B3=95?= =?UTF-8?q?=E5=85=AC=E5=BC=80=E8=AF=BE=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0027.移除元素.md | 1 - problems/0028.实现strStr.md | 11 ++++++----- problems/0042.接雨水.md | 5 ++++- problems/0045.跳跃游戏II.md | 1 - problems/0059.螺旋矩阵II.md | 1 - problems/0062.不同路径.md | 1 + problems/0063.不同路径II.md | 1 + problems/0084.柱状图中最大的矩形.md | 4 ++++ problems/0115.不同的子序列.md | 3 +++ problems/0209.长度最小的子数组.md | 1 - problems/0416.分割等和子集.md | 2 ++ problems/0496.下一个更大元素I.md | 4 ++++ problems/0503.下一个更大元素II.md | 5 +++++ problems/0516.最长回文子序列.md | 4 ++++ problems/0647.回文子串.md | 5 ++++- problems/0701.二叉搜索树中的插入操作.md | 1 - problems/0739.每日温度.md | 4 ++++ problems/二叉树总结篇.md | 1 - problems/字符串总结.md | 1 - problems/贪心算法理论基础.md | 3 +++ problems/面试题02.07.链表相交.md | 1 - 21 files changed, 45 insertions(+), 15 deletions(-) diff --git a/problems/0027.移除元素.md b/problems/0027.移除元素.md index 40ee3a2e..3337d42e 100644 --- a/problems/0027.移除元素.md +++ b/problems/0027.移除元素.md @@ -444,4 +444,3 @@ public class Solution { - diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md index 53b57fd5..207a047d 100644 --- a/problems/0028.实现strStr.md +++ b/problems/0028.实现strStr.md @@ -27,16 +27,16 @@ 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。 +## 算法公开课 -## 思路 - -本题是KMP 经典题目。 - -以下文字如果看不进去,可以看我的B站视频: +本题是KMP 经典题目。以下文字如果看不进去,可以看[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html),相信结合视频再看本篇题解,更有助于大家对本题的理解。 * [帮你把KMP算法学个通透!B站(理论篇)](https://www.bilibili.com/video/BV1PD4y1o7nd/) * [帮你把KMP算法学个通透!(求next数组代码篇)](https://www.bilibili.com/video/BV1M5411j7Xx) + +## 思路 + KMP的经典思想就是:**当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。** 本篇将以如下顺序来讲解KMP, @@ -1362,3 +1362,4 @@ impl Solution { + diff --git a/problems/0042.接雨水.md b/problems/0042.接雨水.md index 1f1a543b..760ebc34 100644 --- a/problems/0042.接雨水.md +++ b/problems/0042.接雨水.md @@ -28,6 +28,10 @@ * 输入:height = [4,2,0,3,2,5] * 输出:9 +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[单调栈,经典来袭!LeetCode:42.接雨水](https://www.bilibili.com/video/BV1uD4y1u75P/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 @@ -1029,4 +1033,3 @@ impl Solution { - diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index 02c8e486..fbd84866 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -469,4 +469,3 @@ impl Solution { - diff --git a/problems/0059.螺旋矩阵II.md b/problems/0059.螺旋矩阵II.md index 78d9385a..515c4fb5 100644 --- a/problems/0059.螺旋矩阵II.md +++ b/problems/0059.螺旋矩阵II.md @@ -744,4 +744,3 @@ end - diff --git a/problems/0062.不同路径.md b/problems/0062.不同路径.md index 985c7575..b7ce542e 100644 --- a/problems/0062.不同路径.md +++ b/problems/0062.不同路径.md @@ -559,3 +559,4 @@ public class Solution + diff --git a/problems/0063.不同路径II.md b/problems/0063.不同路径II.md index 3d243a7a..8b842858 100644 --- a/problems/0063.不同路径II.md +++ b/problems/0063.不同路径II.md @@ -739,3 +739,4 @@ object Solution { + diff --git a/problems/0084.柱状图中最大的矩形.md b/problems/0084.柱状图中最大的矩形.md index 9b76229a..47ed0f33 100644 --- a/problems/0084.柱状图中最大的矩形.md +++ b/problems/0084.柱状图中最大的矩形.md @@ -20,6 +20,10 @@ * 1 <= heights.length <=10^5 * 0 <= heights[i] <= 10^4 +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[单调栈,又一次经典来袭! LeetCode:84.柱状图中最大的矩形](https://www.bilibili.com/video/BV1Ns4y1o7uB/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + ## 思路 本题和[42. 接雨水](https://programmercarl.com/0042.接雨水.html),是遥相呼应的两道题目,建议都要仔细做一做,原理上有很多相同的地方,但细节上又有差异,更可以加深对单调栈的理解! diff --git a/problems/0115.不同的子序列.md b/problems/0115.不同的子序列.md index d925c5de..b1de0ceb 100644 --- a/problems/0115.不同的子序列.md +++ b/problems/0115.不同的子序列.md @@ -21,6 +21,9 @@ * 0 <= s.length, t.length <= 1000 * s 和 t 由英文字母组成 +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划之子序列,为了编辑距离做铺垫 | LeetCode:115.不同的子序列](https://www.bilibili.com/video/BV1fG4y1m75Q/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 ## 思路 diff --git a/problems/0209.长度最小的子数组.md b/problems/0209.长度最小的子数组.md index 4b1d0e96..afce2646 100644 --- a/problems/0209.长度最小的子数组.md +++ b/problems/0209.长度最小的子数组.md @@ -563,4 +563,3 @@ public class Solution { - diff --git a/problems/0416.分割等和子集.md b/problems/0416.分割等和子集.md index 2b2be103..81eb4c80 100644 --- a/problems/0416.分割等和子集.md +++ b/problems/0416.分割等和子集.md @@ -4,6 +4,7 @@

参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

+ # 416. 分割等和子集 [力扣题目链接](https://leetcode.cn/problems/partition-equal-subset-sum/) @@ -730,3 +731,4 @@ object Solution { + diff --git a/problems/0496.下一个更大元素I.md b/problems/0496.下一个更大元素I.md index 6bcafafb..f01d8333 100644 --- a/problems/0496.下一个更大元素I.md +++ b/problems/0496.下一个更大元素I.md @@ -37,6 +37,10 @@ nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位 * nums1和nums2中所有整数 互不相同 * nums1 中的所有整数同样出现在 nums2 中 +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[单调栈,套上一个壳子就有点绕了| LeetCode:496.下一个更大元素](https://www.bilibili.com/video/BV1jA411m7dX/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 做本题之前,建议先做一下[739. 每日温度](https://programmercarl.com/0739.每日温度.html) diff --git a/problems/0503.下一个更大元素II.md b/problems/0503.下一个更大元素II.md index d211a680..3bddd298 100644 --- a/problems/0503.下一个更大元素II.md +++ b/problems/0503.下一个更大元素II.md @@ -21,6 +21,10 @@ * 1 <= nums.length <= 10^4 * -10^9 <= nums[i] <= 10^9 +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[单调栈,成环了可怎么办?LeetCode:503.下一个更大元素II](https://www.bilibili.com/video/BV15y4y1o7Dw/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 @@ -294,3 +298,4 @@ impl Solution { + diff --git a/problems/0516.最长回文子序列.md b/problems/0516.最长回文子序列.md index 80927583..7df2aa3d 100644 --- a/problems/0516.最长回文子序列.md +++ b/problems/0516.最长回文子序列.md @@ -27,6 +27,10 @@ * 1 <= s.length <= 1000 * s 只包含小写英文字母 +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划再显神通,LeetCode:516.最长回文子序列](https://www.bilibili.com/video/BV1d8411K7W6/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + ## 思路 diff --git a/problems/0647.回文子串.md b/problems/0647.回文子串.md index fdf83736..0ed49bc1 100644 --- a/problems/0647.回文子串.md +++ b/problems/0647.回文子串.md @@ -26,6 +26,10 @@ 提示:输入的字符串长度不会超过 1000 。 +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[动态规划,字符串性质决定了DP数组的定义 | LeetCode:647.回文子串](https://www.bilibili.com/video/BV17G4y1y7z9/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 ### 暴力解法 @@ -528,4 +532,3 @@ function expandRange(s: string, left: number, right: number): number { - diff --git a/problems/0701.二叉搜索树中的插入操作.md b/problems/0701.二叉搜索树中的插入操作.md index 511d161c..1042b5a7 100644 --- a/problems/0701.二叉搜索树中的插入操作.md +++ b/problems/0701.二叉搜索树中的插入操作.md @@ -697,4 +697,3 @@ impl Solution { - diff --git a/problems/0739.每日温度.md b/problems/0739.每日温度.md index fc1a8063..fdb11c63 100644 --- a/problems/0739.每日温度.md +++ b/problems/0739.每日温度.md @@ -17,6 +17,10 @@ 提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。 +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[单调栈,你该了解的,这里都讲了!LeetCode:739.每日温度](https://www.bilibili.com/video/BV1my4y1Z7jj/),相信结合视频在看本篇题解,更有助于大家对本题的理解**。 + ## 思路 diff --git a/problems/二叉树总结篇.md b/problems/二叉树总结篇.md index 82949543..739184bb 100644 --- a/problems/二叉树总结篇.md +++ b/problems/二叉树总结篇.md @@ -163,4 +163,3 @@ - diff --git a/problems/字符串总结.md b/problems/字符串总结.md index 5c2f0164..df4db787 100644 --- a/problems/字符串总结.md +++ b/problems/字符串总结.md @@ -128,4 +128,3 @@ KMP算法是字符串查找最重要的算法,但彻底理解KMP并不容易 - diff --git a/problems/贪心算法理论基础.md b/problems/贪心算法理论基础.md index 0b90da6a..cac29292 100644 --- a/problems/贪心算法理论基础.md +++ b/problems/贪心算法理论基础.md @@ -11,6 +11,9 @@ 贪心算法大纲 +## 算法公开课 + +**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html):[贪心算法理论基础!](https://www.bilibili.com/video/BV1WK4y1R71x/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 ## 什么是贪心 diff --git a/problems/面试题02.07.链表相交.md b/problems/面试题02.07.链表相交.md index 833eadca..5de9da5c 100644 --- a/problems/面试题02.07.链表相交.md +++ b/problems/面试题02.07.链表相交.md @@ -508,4 +508,3 @@ object Solution { - From a01c3f78cf18a0eed0e236bdb48369c662e10b12 Mon Sep 17 00:00:00 2001 From: programmercarl <826123027@qq.com> Date: Mon, 28 Aug 2023 15:25:11 +0800 Subject: [PATCH 20/23] Update --- problems/0059.螺旋矩阵II.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/problems/0059.螺旋矩阵II.md b/problems/0059.螺旋矩阵II.md index 78d9385a..cab955b6 100644 --- a/problems/0059.螺旋矩阵II.md +++ b/problems/0059.螺旋矩阵II.md @@ -211,10 +211,6 @@ class Solution: ```javascript -/** - * @param {number} n - * @return {number[][]} - */ var generateMatrix = function(n) { let startX = startY = 0; // 起始位置 let loop = Math.floor(n/2); // 旋转圈数 @@ -226,11 +222,11 @@ var generateMatrix = function(n) { while (loop--) { let row = startX, col = startY; // 上行从左到右(左闭右开) - for (; col < startY + n - offset; col++) { + for (; col < n - offset; col++) { res[row][col] = count++; } // 右列从上到下(左闭右开) - for (; row < startX + n - offset; row++) { + for (; row < n - offset; row++) { res[row][col] = count++; } // 下行从右到左(左闭右开) @@ -247,7 +243,7 @@ var generateMatrix = function(n) { startY++; // 更新offset - offset += 2; + offset += 1; } // 如果n为奇数的话,需要单独给矩阵最中间的位置赋值 if (n % 2 === 1) { @@ -255,6 +251,7 @@ var generateMatrix = function(n) { } return res; }; + ``` From 99eb035fee885decbd4438145c3f48d28e981e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=93=88=E5=93=88=E5=93=88?= <76643786+Projecthappy@users.noreply.github.com> Date: Tue, 29 Aug 2023 11:12:04 +0800 Subject: [PATCH 21/23] =?UTF-8?q?Update=200051.N=E7=9A=87=E5=90=8E.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0051.N皇后.md | 52 ---------------------------------------- 1 file changed, 52 deletions(-) diff --git a/problems/0051.N皇后.md b/problems/0051.N皇后.md index 71c40238..6bc4fa78 100644 --- a/problems/0051.N皇后.md +++ b/problems/0051.N皇后.md @@ -345,58 +345,6 @@ class Solution { } } ``` -```java -//该方法主要特点在于用一个一维数组暂存皇后的位置,数组下标代表行,数组下标的值代表列,并初始化一个长度为n-1,值全为'.'的模板字符串 -//在找到合法方案时,遍历数组,在模板字符串下标为数组值的位置插入Q -class Solution { - //结果 - List> result = new ArrayList<>(); - //储存皇后的位置,下标为行,值为列 - int[] queenIndex; - //棋盘中一行的字符串模板 - String template; - int size; - - public List> solveNQueens(int n) { - size = n; - template = ".".repeat(n - 1); - queenIndex = new int[n]; - deal(0); - return result; - } - - void deal(int index) { - //遍历当前行的所有位置(尝试在这行每个位置放置皇后) - for (int i = 0; i < size; i++) { - queenIndex[index] = i; - //检查在当前位置放置皇后是否合法 - if (check(index, i)) { - //如果当前的行是最后一行,就说明当前皇后的摆放已经是完整并且合法的,在结果集中加入当前的摆放方案 - if (index == size - 1) { - List tmp = new ArrayList<>(size); - //遍历当前的皇后位置,在模板字符串对应的位置加入Q,再加入到结果集中 - for (Integer integer : queenIndex) { - tmp.add(new StringBuilder(template).insert(integer, "Q").toString()); - } - result.add(tmp); - return; - } - //如果当前不是最后一行,还需要进入下一行 - deal(index + 1); - } - } - } - - boolean check(int rowIndex, int columnIndex) { - for (int i = 0; i < rowIndex; i++) { - if (queenIndex[i] == columnIndex || (Math.abs(queenIndex[i] - columnIndex) == Math.abs(i - rowIndex))) { - return false; - } - } - return true; - } -} -``` ### Python From 7d770507c3217eb69bd0b15ec4a8eb6bfad56010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=93=88=E5=93=88=E5=93=88?= <76643786+Projecthappy@users.noreply.github.com> Date: Tue, 29 Aug 2023 11:23:38 +0800 Subject: [PATCH 22/23] =?UTF-8?q?=E5=AE=8C=E5=96=84java=E6=96=B0=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0332.重新安排行程.md | 151 ++++++++++++++-------------- 1 file changed, 73 insertions(+), 78 deletions(-) diff --git a/problems/0332.重新安排行程.md b/problems/0332.重新安排行程.md index 2498fbfe..ab144f43 100644 --- a/problems/0332.重新安排行程.md +++ b/problems/0332.重新安排行程.md @@ -261,84 +261,6 @@ for (pair& target : targets[result[result.size() - 1]]) ### Java -```java -/* 首先遍历所有机票,将机票转换成map,其中起点作为key,终点按照字典顺序插入到终点的列表中 - 然后进入递归,递归中首先在result中加入当前位置,如果票用完了就说明这条路走通了 - 递归中遍历从当前位置出发的终点(也就是map中key为当前位置的列表),因为列表是有序的,因此只要出现能走通的路径,这条路径就是字典排序最低的 - 在遍历中,首先从map中移除当前的机票,将遍历到的终点作为起点进入下一层的递归中,如果发现当前机票往后走走不通,再把当前的机票加到map中*/ -class Solution { - //key为起点,value是有序的终点的列表 - Map> ticketMap = new HashMap<>(); - LinkedList result = new LinkedList<>(); - - public List findItinerary(List> tickets) { - //遍历tickets,存入ticketMap中 - for (List ticket : tickets) { - addNew(ticket.get(0), ticket.get(1)); - } - deal("JFK"); - return result; - } - - boolean deal(String currentLocation) { - result.add(currentLocation); - //机票全部用完,找到最小字符路径 - if (ticketMap.isEmpty()) { - return true; - } - //当前位置的终点列表 - LinkedList targetLocations = ticketMap.get(currentLocation); - //机票没用完,但是没有从当前位置出发的机票了,说明这条路走不通 - if (targetLocations == null) { - return false; - } - //终点列表中遍历到的终点 - String targetLocation; - //遍历从当前位置出发的机票 - for (int i = 0; i < targetLocations.size(); i++) { - targetLocation = targetLocations.get(i); - //删除map中的机票,如果当前位置只有一个终点,直接删除k,v,有多个终点则删除终点列表中当前的终点 - if (targetLocations.size() == 1) { - ticketMap.remove(currentLocation); - } else { - targetLocations.remove(i); - } - //递归 - if (deal(targetLocation)) { - return true; - } else { - //路线走不通,将机票重新加到map中 - addNew(currentLocation, targetLocation); - result.removeLast(); - } - } - return false; - } - - /** - * 在map中添加新元素 - * - * @param start 起点 - * @param end 终点 - */ - void addNew(String start, String end) { - LinkedList startAllEnd = ticketMap.get(start); - if (startAllEnd != null) { - for (int i = 0; i < startAllEnd.size() + 1; i++) { - if (i == startAllEnd.size() || end.compareTo(startAllEnd.get(i)) < 0) { - startAllEnd.add(i, end); - break; - } - } - } else { - LinkedList ends = new LinkedList<>(); - ends.add(end); - ticketMap.put(start, ends); - } - } -} -``` - ```java class Solution { private LinkedList res; @@ -423,6 +345,79 @@ class Solution { } ``` +```java +/* 该方法是对第二个方法的改进,主要变化在于将某点的所有终点变更为链表的形式,优点在于 + 1.添加终点时直接在对应位置添加节点,避免了TreeMap增元素时的频繁调整 + 2.同时每次对终点进行增加删除查找时直接通过下标操作,避免hashMap反复计算hash*/ +class Solution { + //key为起点,value是有序的终点的列表 + Map> ticketMap = new HashMap<>(); + LinkedList result = new LinkedList<>(); + int total; + + public List findItinerary(List> tickets) { + total = tickets.size() + 1; + //遍历tickets,存入ticketMap中 + for (List ticket : tickets) { + addNew(ticket.get(0), ticket.get(1)); + } + deal("JFK"); + return result; + } + + boolean deal(String currentLocation) { + result.add(currentLocation); + //机票全部用完,找到最小字符路径 + if (result.size() == total) { + return true; + } + //当前位置的终点列表 + LinkedList targetLocations = ticketMap.get(currentLocation); + //没有从当前位置出发的机票了,说明这条路走不通 + if (targetLocations != null && !targetLocations.isEmpty()) { + //终点列表中遍历到的终点 + String targetLocation; + //遍历从当前位置出发的机票 + for (int i = 0; i < targetLocations.size(); i++) { + targetLocation = targetLocations.get(i); + //删除终点列表中当前的终点 + targetLocations.remove(i); + //递归 + if (deal(targetLocation)) { + return true; + } + //路线走不通,将机票重新加回去 + targetLocations.add(i, targetLocation); + result.removeLast(); + } + } + return false; + } + + /** + * 在map中按照字典顺序添加新元素 + * + * @param start 起点 + * @param end 终点 + */ + void addNew(String start, String end) { + LinkedList startAllEnd = ticketMap.getOrDefault(start, new LinkedList<>()); + if (!startAllEnd.isEmpty()) { + for (int i = 0; i < startAllEnd.size(); i++) { + if (end.compareTo(startAllEnd.get(i)) < 0) { + startAllEnd.add(i, end); + return; + } + } + startAllEnd.add(startAllEnd.size(), end); + } else { + startAllEnd.add(end); + ticketMap.put(start, startAllEnd); + } + } +} +``` + ### Python 回溯 使用used数组 From 4d532348fc1714de1cb07c0e28710b1228188aab Mon Sep 17 00:00:00 2001 From: programmercarl <826123027@qq.com> Date: Tue, 29 Aug 2023 19:12:30 +0800 Subject: [PATCH 23/23] Update --- problems/0463.岛屿的周长.md | 31 +++++++++++++++++++++++++ problems/图论并查集理论基础.md | 2 -- problems/图论广搜理论基础.md | 1 - 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/problems/0463.岛屿的周长.md b/problems/0463.岛屿的周长.md index 48e64d0b..2e954e30 100644 --- a/problems/0463.岛屿的周长.md +++ b/problems/0463.岛屿的周长.md @@ -10,6 +10,37 @@ [力扣题目链接](https://leetcode.cn/problems/island-perimeter/) +给定一个 row x col 的二维网格地图 grid ,其中:grid[i][j] = 1 表示陆地, grid[i][j] = 0 表示水域。 + +网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。 + +岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。 + + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230829180848.png) + +* 输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]] +* 输出:16 +* 解释:它的周长是上面图片中的 16 个黄色的边 + + +示例 2: + +* 输入:grid = [[1]] +* 输出:4 + +示例 3: + +* 输入:grid = [[1,0]] +* 输出:4 + +提示: + +* row == grid.length +* col == grid[i].length +* 1 <= row, col <= 100 +* grid[i][j] 为 0 或 1 + ## 思路 岛屿问题最容易让人想到BFS或者DFS,但是这道题还真的没有必要,别把简单问题搞复杂了。 diff --git a/problems/图论并查集理论基础.md b/problems/图论并查集理论基础.md index 5cd753e9..bc520e8e 100644 --- a/problems/图论并查集理论基础.md +++ b/problems/图论并查集理论基础.md @@ -1,8 +1,6 @@ # 并查集理论基础 -图论中,关于深搜和广搜我们在这里:[钥匙和房间](https://mp.weixin.qq.com/s/E9NlJy9PW1oJuD8N2EURoQ) 已经更新完毕了。 - 接下来我们来讲一下并查集,首先当然是并查集理论基础。 ## 背景 diff --git a/problems/图论广搜理论基础.md b/problems/图论广搜理论基础.md index 1f3a1372..64ca181b 100644 --- a/problems/图论广搜理论基础.md +++ b/problems/图论广搜理论基础.md @@ -6,7 +6,6 @@ # 广度优先搜索理论基础 -> 号外!!代码随想录图论内容已经计划开更了! 在[深度优先搜索](https://programmercarl.com/图论深搜理论基础.html)的讲解中,我们就讲过深度优先搜索和广度优先搜索的区别。