From 898c42a990b57ab9824d53efd7a2b647dd2724d9 Mon Sep 17 00:00:00 2001 From: Lozakaka <102352821+Lozakaka@users.noreply.github.com> Date: Mon, 8 May 2023 18:10:28 -0400 Subject: [PATCH 1/5] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=E7=94=A8set2k?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...36\345\255\220\345\272\217\345\210\227.md" | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git "a/problems/0491.\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md" "b/problems/0491.\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md" index 436dbf01c8..2a58f55072 100644 --- "a/problems/0491.\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md" +++ "b/problems/0491.\351\200\222\345\242\236\345\255\220\345\272\217\345\210\227.md" @@ -203,6 +203,30 @@ public: ### Java +```Java +//using set, aligned with the unimproved method +class Solution { + List> result = new ArrayList<>(); + List path = new ArrayList<>(); + public List> findSubsequences(int[] nums) { + backTracking(nums, 0); + return result; + } + private void backTracking(int[] nums, int startIndex){ + if(path.size() >= 2) + result.add(new ArrayList<>(path)); + HashSet hs = new HashSet<>(); + for(int i = startIndex; i < nums.length; i++){ + if(!path.isEmpty() && path.get(path.size() -1 ) > nums[i] || hs.contains(nums[i])) + continue; + hs.add(nums[i]); + path.add(nums[i]); + backTracking(nums, i + 1); + path.remove(path.size() - 1); + } + } +} +``` ```java class Solution { From 41537211f86035ac58a7a0121e35d4838ebd61f2 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sat, 27 May 2023 16:07:52 +0800 Subject: [PATCH 2/5] =?UTF-8?q?Update=200474.=E4=B8=80=E5=92=8C=E9=9B=B6.m?= =?UTF-8?q?d=20about=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...4.\344\270\200\345\222\214\351\233\266.md" | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git "a/problems/0474.\344\270\200\345\222\214\351\233\266.md" "b/problems/0474.\344\270\200\345\222\214\351\233\266.md" index 6a178a254b..145f6ec193 100644 --- "a/problems/0474.\344\270\200\345\222\214\351\233\266.md" +++ "b/problems/0474.\344\270\200\345\222\214\351\233\266.md" @@ -491,6 +491,33 @@ object Solution { } ``` +### Rust + +```rust +impl Solution { + pub fn find_max_form(strs: Vec, m: i32, n: i32) -> i32 { + let (m, n) = (m as usize, n as usize); + let mut dp = vec![vec![0; n + 1]; m + 1]; + for s in strs { + let (mut one_num, mut zero_num) = (0, 0); + for c in s.chars() { + match c { + '0' => zero_num += 1, + '1' => one_num += 1, + _ => (), + } + } + for i in (zero_num..=m).rev() { + for j in (one_num..=n).rev() { + dp[i][j] = dp[i][j].max(dp[i - zero_num][j - one_num] + 1); + } + } + } + dp[m][n] + } +} +``` +

From 8b6e90d2e24bdec8574a213f16f81c049f7e5fb2 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sat, 27 May 2023 17:36:47 +0800 Subject: [PATCH 3/5] =?UTF-8?q?Update=20=E8=83=8C=E5=8C=85=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E7=90=86=E8=AE=BA=E5=9F=BA=E7=A1=80=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E8=83=8C=E5=8C=85.md=20about=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...14\345\205\250\350\203\214\345\214\205.md" | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git "a/problems/\350\203\214\345\214\205\351\227\256\351\242\230\347\220\206\350\256\272\345\237\272\347\241\200\345\256\214\345\205\250\350\203\214\345\214\205.md" "b/problems/\350\203\214\345\214\205\351\227\256\351\242\230\347\220\206\350\256\272\345\237\272\347\241\200\345\256\214\345\205\250\350\203\214\345\214\205.md" index e927aa2061..9a48cb71cf 100644 --- "a/problems/\350\203\214\345\214\205\351\227\256\351\242\230\347\220\206\350\256\272\345\237\272\347\241\200\345\256\214\345\205\250\350\203\214\345\214\205.md" +++ "b/problems/\350\203\214\345\214\205\351\227\256\351\242\230\347\220\206\350\256\272\345\237\272\347\241\200\345\256\214\345\205\250\350\203\214\345\214\205.md" @@ -388,6 +388,43 @@ object Solution { } ``` +Rust: + +```rust +impl Solution { + // 先遍历物品 + fn complete_pack() { + let (goods, bag_size) = (vec![(1, 15), (3, 20), (4, 30)], 4); + let mut dp = vec![0; bag_size + 1]; + for (weight, value) in goods { + for j in weight..=bag_size { + dp[j] = dp[j].max(dp[j - weight] + value); + } + } + println!("先遍历物品:{}", dp[bag_size]); + } + + // 先遍历背包 + fn complete_pack_after() { + let (goods, bag_size) = (vec![(1, 15), (3, 20), (4, 30)], 4); + let mut dp = vec![0; bag_size + 1]; + for i in 0..=bag_size { + for (weight, value) in &goods { + if i >= *weight { + dp[i] = dp[i].max(dp[i - weight] + value); + } + } + } + println!("先遍历背包:{}", dp[bag_size]); + } +} + +#[test] +fn test_complete_pack() { + Solution::complete_pack(); + Solution::complete_pack_after(); +} +```

From 4eadc742c74eb2c1b059cbac439110c13fe23b3d Mon Sep 17 00:00:00 2001 From: programmercarl <826123027@qq.com> Date: Tue, 6 Jun 2023 23:24:33 +0800 Subject: [PATCH 4/5] Update --- README.md | 2 +- ...01\350\247\204\345\210\222\357\274\211.md" | 11 ++- ...04\345\255\220\345\272\217\345\210\227.md" | 5 +- ...07\345\255\220\345\272\217\345\210\227.md" | 5 ++ ...55\345\255\220\345\272\217\345\210\227.md" | 12 ++- ...22\345\242\236\345\272\217\345\210\227.md" | 4 + ...27\344\275\231\350\277\236\346\216\245.md" | 70 ++++++++++------- ...\344\275\231\350\277\236\346\216\245II.md" | 25 +++++- ...15\345\255\220\346\225\260\347\273\204.md" | 5 ++ ...70\344\272\244\347\232\204\347\272\277.md" | 5 ++ ...61\345\255\220\345\272\217\345\210\227.md" | 23 +++--- ...30\345\234\250\350\267\257\345\276\204.md" | 78 ++++++++++--------- ...06\350\256\272\345\237\272\347\241\200.md" | 2 +- 13 files changed, 162 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index a31629607f..0172cb671b 100644 --- a/README.md +++ b/README.md @@ -492,7 +492,7 @@ 大家好,我是程序员Carl,哈工大师兄,《代码随想录》作者,先后在腾讯和百度从事后端技术研发,CSDN博客专家。对算法和C++后端技术有一定的见解,利用工作之余重新刷leetcode。 -加入「代码随想录」刷题小分队(微信群),可以扫下方二维码加我微信。 +加入「代码随想录」刷题小分队(微信群),可以扫下方二维码,加代码随想录客服微信。 如果是已工作,备注:姓名-城市-岗位-组队刷题。如果学生,备注:姓名-学校-年级-组队刷题。**备注没有自我介绍不通过哦** diff --git "a/problems/0053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214\357\274\210\345\212\250\346\200\201\350\247\204\345\210\222\357\274\211.md" "b/problems/0053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214\357\274\210\345\212\250\346\200\201\350\247\204\345\210\222\357\274\211.md" index c7d1b2fd7b..3117b1bf27 100644 --- "a/problems/0053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214\357\274\210\345\212\250\346\200\201\350\247\204\345\210\222\357\274\211.md" +++ "b/problems/0053.\346\234\200\345\244\247\345\255\220\345\272\217\345\222\214\357\274\210\345\212\250\346\200\201\350\247\204\345\210\222\357\274\211.md" @@ -11,9 +11,14 @@ 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 示例: -输入: [-2,1,-3,4,-1,2,1,-5,4] -输出: 6 -解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 +* 输入: [-2,1,-3,4,-1,2,1,-5,4] +* 输出: 6 +* 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 + +## 算法公开课 + +**《代码随想录》算法视频公开课:[看起来复杂,其实是简单动态规划 | LeetCode:53.最大子序和](https://www.bilibili.com/video/BV19V4y1F7b5),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + ## 思路 diff --git "a/problems/0115.\344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.md" "b/problems/0115.\344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.md" index 6127f19045..8c82880d58 100644 --- "a/problems/0115.\344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.md" +++ "b/problems/0115.\344\270\215\345\220\214\347\232\204\345\255\220\345\272\217\345\210\227.md" @@ -18,8 +18,9 @@ 提示: -0 <= s.length, t.length <= 1000 -s 和 t 由英文字母组成 +* 0 <= s.length, t.length <= 1000 +* s 和 t 由英文字母组成 + ## 思路 diff --git "a/problems/0300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.md" "b/problems/0300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.md" index e8cb0b5f18..e1f2bef814 100644 --- "a/problems/0300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.md" +++ "b/problems/0300.\346\234\200\351\225\277\344\270\212\345\215\207\345\255\220\345\272\217\345\210\227.md" @@ -31,6 +31,11 @@ * 1 <= nums.length <= 2500 * -10^4 <= nums[i] <= 104 +## 算法公开课 + +**《代码随想录》算法视频公开课:[动态规划之子序列问题,元素不连续!| LeetCode:300.最长递增子序列](https://www.bilibili.com/video/BV1ng411J7xP),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + + ## 思路 首先通过本题大家要明确什么是子序列,“子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序”。 diff --git "a/problems/0392.\345\210\244\346\226\255\345\255\220\345\272\217\345\210\227.md" "b/problems/0392.\345\210\244\346\226\255\345\255\220\345\272\217\345\210\227.md" index 2fa647d200..c10114c05a 100644 --- "a/problems/0392.\345\210\244\346\226\255\345\255\220\345\272\217\345\210\227.md" +++ "b/problems/0392.\345\210\244\346\226\255\345\255\220\345\272\217\345\210\227.md" @@ -14,12 +14,12 @@ 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。 示例 1: -输入:s = "abc", t = "ahbgdc" -输出:true +* 输入:s = "abc", t = "ahbgdc" +* 输出:true 示例 2: -输入:s = "axc", t = "ahbgdc" -输出:false +* 输入:s = "axc", t = "ahbgdc" +* 输出:false 提示: @@ -28,6 +28,10 @@ 两个字符串都只由小写字符组成。 +# 算法公开课 + +**《代码随想录》算法视频公开课:[动态规划,用相似思路解决复杂问题 | LeetCode:392.判断子序列](https://www.bilibili.com/video/BV1tv4y1B7ym/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + ## 思路 diff --git "a/problems/0674.\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.md" "b/problems/0674.\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.md" index 79a8311d78..9f6601e72e 100644 --- "a/problems/0674.\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.md" +++ "b/problems/0674.\346\234\200\351\225\277\350\277\236\347\273\255\351\200\222\345\242\236\345\272\217\345\210\227.md" @@ -27,6 +27,10 @@ * 0 <= nums.length <= 10^4 * -10^9 <= nums[i] <= 10^9 +## 算法公开课 + +**《代码随想录》算法视频公开课:[动态规划之子序列问题,重点在于连续!| LeetCode:674.最长连续递增序列](https://www.bilibili.com/video/BV1bD4y1778v),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + ## 思路 diff --git "a/problems/0684.\345\206\227\344\275\231\350\277\236\346\216\245.md" "b/problems/0684.\345\206\227\344\275\231\350\277\236\346\216\245.md" index e3002b65ef..97f100d042 100644 --- "a/problems/0684.\345\206\227\344\275\231\350\277\236\346\216\245.md" +++ "b/problems/0684.\345\206\227\344\275\231\350\277\236\346\216\245.md" @@ -39,8 +39,8 @@ 这里整理出我的并查集模板如下: ```CPP -int n = 1005; // 节点数量3 到 1000 -int father[1005]; +int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好 +vector father = vector (n, 0); // C++里的一种数组结构 // 并查集初始化 void init() { @@ -50,40 +50,58 @@ void init() { } // 并查集里寻根的过程 int find(int u) { - return u == father[u] ? u : father[u] = find(father[u]); -} -// 将v->u 这条边加入并查集 -void join(int u, int v) { - u = find(u); - v = find(v); - if (u == v) return ; - father[v] = u; + return u == father[u] ? u : father[u] = find(father[u]); // 路径压缩 } + // 判断 u 和 v是否找到同一个根 -bool same(int u, int v) { +bool isSame(int u, int v) { u = find(u); v = find(v); return u == v; } + +// 将v->u 这条边加入并查集 +void join(int u, int v) { + u = find(u); // 寻找u的根 + v = find(v); // 寻找v的根 + if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回 + father[v] = u; +} + ``` -以上模板汇总,只要修改 n 和father数组的大小就可以了。 +以上模板 只要修改 n 就可以了,本题 节点数量不会超过1000。 并查集主要有三个功能。 1. 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个 2. 将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上 -3. 判断两个节点是否在同一个集合,函数:same(int u, int v),就是判断两个节点是不是同一个根节点 +3. 判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点 简单介绍并查集之后,我们再来看一下这道题目。 -题目说是无向图,返回一条可以删去的边,使得结果图是一个有着N个节点的树。 +题目说是无向图,返回一条可以删去的边,使得结果图是一个有着N个节点的树(即:只有一个根节点)。 如果有多个答案,则返回二维数组中最后出现的边。 -那么我们就可以从前向后遍历每一条边,边的两个节点如果不在同一个集合,就加入集合(即:同一个根节点)。 +那么我们就可以从前向后遍历每一条边(因为优先让前面的边连上),边的两个节点如果不在同一个集合,就加入集合(即:同一个根节点)。 + +如图所示: + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230604104720.png) + +节点A 和节点 B 不在同一个集合,那么就可以将两个 节点连在一起。 -如果边的两个节点已经出现在同一个集合里,说明着边的两个节点已经连在一起了,如果再加入这条边一定就出现环了。 + +(如果题目中说:如果有多个答案,则返回二维数组中最前出现的边。 那我们就要 从后向前遍历每一条边了) + +如果边的两个节点已经出现在同一个集合里,说明着边的两个节点已经连在一起了,再加入这条边一定就出现环了。 + +如图所示: + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20230604104330.png) + +已经判断 节点A 和 节点B 在在同一个集合(同一个根),如果将 节点A 和 节点B 连在一起就一定会出现环。 这个思路清晰之后,代码就很好写了。 @@ -93,7 +111,7 @@ bool same(int u, int v) { class Solution { private: int n = 1005; // 节点数量3 到 1000 - int father[1005]; + vector father = vector (n, 0); // C++里的一种数组结构 // 并查集初始化 void init() { @@ -105,24 +123,22 @@ private: int find(int u) { return u == father[u] ? u : father[u] = find(father[u]); } - // 将v->u 这条边加入并查集 - void join(int u, int v) { - u = find(u); - v = find(v); - if (u == v) return ; - father[v] = u; - } - // 判断 u 和 v是否找到同一个根,本题用不上 - bool same(int u, int v) { + // 判断 u 和 v是否找到同一个根 + bool isSame(int u, int v) { u = find(u); v = find(v); return u == v; } + // 将v->u 这条边加入并查集 + void join(int u, int v) { + if (isSame(u, v)) return ; + father[v] = u; + } public: vector findRedundantConnection(vector>& edges) { init(); for (int i = 0; i < edges.size(); i++) { - if (same(edges[i][0], edges[i][1])) return edges[i]; + if (isSame(edges[i][0], edges[i][1])) return edges[i]; else join(edges[i][0], edges[i][1]); } return {}; diff --git "a/problems/0685.\345\206\227\344\275\231\350\277\236\346\216\245II.md" "b/problems/0685.\345\206\227\344\275\231\350\277\236\346\216\245II.md" index 5a0bd5d711..149eab0148 100644 --- "a/problems/0685.\345\206\227\344\275\231\350\277\236\346\216\245II.md" +++ "b/problems/0685.\345\206\227\344\275\231\350\277\236\346\216\245II.md" @@ -44,7 +44,6 @@ 且只有一个节点入度为2,为什么不看出度呢,出度没有意义,一棵树中随便一个父节点就有多个出度。 - 第三种情况是没有入度为2的点,那么图中一定出现了有向环(**注意这里强调是有向环!**) 如图: @@ -52,7 +51,27 @@ -首先先计算节点的入度,代码如下: +首先先计算节点的入度,这里不少录友在计算入度的时候就搞蒙了,分不清 edges[i][j] 表示的都是什么。 + +例如题目示例一给的是:edges = [[1,2],[1,3],[2,3]] + +那大家很自然就想 对应二维数组的数值是: edges[1][2] ,edges[1][3],edges[2][3],但又想不出来 edges[1][2] 数值又是什么呢? 越想约懵。 + +其实 edges = [[1,2],[1,3],[2,3]],表示的是 + +edges[0][0] = 1,edges[0][1] = 2, + +edges[1][0] = 1,edges[1][1] = 3, + +edges[2][0] = 2,edges[2][1] = 3, + +二维数组大家都学过,但是往往和图结合在一起的时候,就非常容易搞混,哪里是数组,哪里是下标了。 + +搞清楚之后,我们如何统计入度呢? + +即 edges[i][1] 表示的节点都是 箭头指向的节点,即这个几点有一个入度! (如果想统计出度,那么就是 edges[i][0])。 + +所以,统计入度的代码如下: ```cpp int inDegree[N] = {0}; // 记录节点入度 @@ -94,7 +113,7 @@ if (vec.size() > 0) { vector getRemoveEdge(const vector>& edges) ``` -此时 大家应该知道了,我们要实现两个最为关键的函数: +大家应该知道了,我们要实现两个最为关键的函数: * `isTreeAfterRemoveEdge()` 判断删一个边之后是不是树了 * `getRemoveEdge` 确定图中一定有了有向环,那么要找到需要删除的那条边 diff --git "a/problems/0718.\346\234\200\351\225\277\351\207\215\345\244\215\345\255\220\346\225\260\347\273\204.md" "b/problems/0718.\346\234\200\351\225\277\351\207\215\345\244\215\345\255\220\346\225\260\347\273\204.md" index 08be67326e..d654f2ba26 100644 --- "a/problems/0718.\346\234\200\351\225\277\351\207\215\345\244\215\345\255\220\346\225\260\347\273\204.md" +++ "b/problems/0718.\346\234\200\351\225\277\351\207\215\345\244\215\345\255\220\346\225\260\347\273\204.md" @@ -23,6 +23,11 @@ * 1 <= len(A), len(B) <= 1000 * 0 <= A[i], B[i] < 100 +## 算法公开课 + +**《代码随想录》算法视频公开课:[动态规划之子序列问题,想清楚DP数组的定义 | LeetCode:718.最长重复子数组](https://www.bilibili.com/video/BV178411H7hV),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + + ## 思路 diff --git "a/problems/1035.\344\270\215\347\233\270\344\272\244\347\232\204\347\272\277.md" "b/problems/1035.\344\270\215\347\233\270\344\272\244\347\232\204\347\272\277.md" index 7b60abdda3..7142d75c09 100644 --- "a/problems/1035.\344\270\215\347\233\270\344\272\244\347\232\204\347\272\277.md" +++ "b/problems/1035.\344\270\215\347\233\270\344\272\244\347\232\204\347\272\277.md" @@ -17,6 +17,11 @@ ![1035.不相交的线](https://code-thinking-1253855093.file.myqcloud.com/pics/2021032116363533.png) +## 算法公开课 + +**《代码随想录》算法视频公开课:[动态规划之子序列问题,换汤不换药 | LeetCode:1035.不相交的线](https://www.bilibili.com/video/BV1h84y1x7MP),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + + ## 思路 相信不少录友看到这道题目都没啥思路,我们来逐步分析一下。 diff --git "a/problems/1143.\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.md" "b/problems/1143.\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.md" index 730e9ad1f7..3799e81918 100644 --- "a/problems/1143.\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.md" +++ "b/problems/1143.\346\234\200\351\225\277\345\205\254\345\205\261\345\255\220\345\272\217\345\210\227.md" @@ -18,25 +18,30 @@ 示例 1: -输入:text1 = "abcde", text2 = "ace" -输出:3 -解释:最长公共子序列是 "ace",它的长度为 3。 +* 输入:text1 = "abcde", text2 = "ace" +* 输出:3 +* 解释:最长公共子序列是 "ace",它的长度为 3。 示例 2: -输入:text1 = "abc", text2 = "abc" -输出:3 -解释:最长公共子序列是 "abc",它的长度为 3。 +* 输入:text1 = "abc", text2 = "abc" +* 输出:3 +* 解释:最长公共子序列是 "abc",它的长度为 3。 示例 3: -输入:text1 = "abc", text2 = "def" -输出:0 -解释:两个字符串没有公共子序列,返回 0。 +* 输入:text1 = "abc", text2 = "def" +* 输出:0 +* 解释:两个字符串没有公共子序列,返回 0。 提示: * 1 <= text1.length <= 1000 * 1 <= text2.length <= 1000 输入的字符串只含有小写英文字符。 +## 算法公开课 + +**《代码随想录》算法视频公开课:[动态规划子序列问题经典题目 | LeetCode:1143.最长公共子序列](https://www.bilibili.com/video/BV1ye4y1L7CQ),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + + ## 思路 本题和[动态规划:718. 最长重复子数组](https://programmercarl.com/0718.最长重复子数组.html)区别在于这里不要求是连续的了,但要有相对顺序,即:"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。 diff --git "a/problems/1971.\345\257\273\346\211\276\345\233\276\344\270\255\346\230\257\345\220\246\345\255\230\345\234\250\350\267\257\345\276\204.md" "b/problems/1971.\345\257\273\346\211\276\345\233\276\344\270\255\346\230\257\345\220\246\345\255\230\345\234\250\350\267\257\345\276\204.md" index 3969456784..16c7cb1e85 100644 --- "a/problems/1971.\345\257\273\346\211\276\345\233\276\344\270\255\346\230\257\345\220\246\345\255\230\345\234\250\350\267\257\345\276\204.md" +++ "b/problems/1971.\345\257\273\346\211\276\345\233\276\344\270\255\346\230\257\345\220\246\345\255\230\345\234\250\350\267\257\345\276\204.md" @@ -3,6 +3,7 @@

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

+ # 1971. 寻找图中是否存在路径 [题目链接](https://leetcode.cn/problems/find-if-path-exists-in-graph/) @@ -30,7 +31,7 @@ ## 思路 -这道题目也是并查集基础题目。 +本题是并查集基础题目。 首先要知道并查集可以解决什么问题呢? @@ -39,8 +40,8 @@ 这里整理出我的并查集模板如下: ```CPP -int n = 1005; // 节点数量3 到 1000 -int father[1005]; +int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好 +vector father = vector (n, 0); // C++里的一种数组结构 // 并查集初始化 void init() { @@ -50,79 +51,86 @@ void init() { } // 并查集里寻根的过程 int find(int u) { - return u == father[u] ? u : father[u] = find(father[u]); -} -// 将v->u 这条边加入并查集 -void join(int u, int v) { - u = find(u); - v = find(v); - if (u == v) return ; - father[v] = u; + return u == father[u] ? u : father[u] = find(father[u]); // 路径压缩 } + // 判断 u 和 v是否找到同一个根 -bool same(int u, int v) { +bool isSame(int u, int v) { u = find(u); v = find(v); return u == v; } + +// 将v->u 这条边加入并查集 +void join(int u, int v) { + u = find(u); // 寻找u的根 + v = find(v); // 寻找v的根 + if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回 + father[v] = u; +} ``` -以上模板汇总,只要修改 n 和father数组的大小就可以了。 +以上模板中,只要修改 n 大小就可以,本科n不会超过2 * 10^5。 并查集主要有三个功能。 1. 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个 2. 将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上 -3. 判断两个节点是否在同一个集合,函数:same(int u, int v),就是判断两个节点是不是同一个根节点 +3. 判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点 简单介绍并查集之后,我们再来看一下这道题目。 -为什么说这道题目是并查集基础题目,因为 可以直接套用模板。 +为什么说这道题目是并查集基础题目,题目中各个点是双向图链接,那么判断 一个顶点到另一个顶点有没有有效路径其实就是看这两个顶点是否在同一个集合里。 + +如何算是同一个集合呢,有边连在一起,就算是一个集合。 + +此时我们就可以直接套用并查集模板。 使用join(int u, int v)将每条边加入到并查集。 -最后 same(int u, int v) 判断是否是同一个根 就可以里。 +最后 isSame(int u, int v) 判断是否是同一个根 就可以了。 -代码如下: +C++代码如下: -```c++ +```CPP class Solution { - private: - int n = 200005; // 节点数量 20000 - int father[200005]; + int n = 200005; // 节点数量 20000 + vector father = vector (n, 0); // C++里的一种数组结构 // 并查集初始化 void init() { - for (int i = 0; i < n; ++i) { - father[i] = i; + for (int i = 0; i < n; ++i) { father[i] = i; } } // 并查集里寻根的过程 int find(int u) { return u == father[u] ? u : father[u] = find(father[u]); } - // 将v->u 这条边加入并查集 - void join(int u, int v) { - u = find(u); - v = find(v); - if (u == v) return ; - father[v] = u; - } - // 判断 u 和 v是否找到同一个根,本题用不上 - bool same(int u, int v) { + + // 判断 u 和 v是否找到同一个根 + bool isSame(int u, int v) { u = find(u); v = find(v); return u == v; } + // 将v->u 这条边加入并查集 + void join(int u, int v) { + u = find(u); // 寻找u的根 + v = find(v); // 寻找v的根 + if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回 + father[v] = u; + } + public: bool validPath(int n, vector>& edges, int source, int destination) { - init(); + init(); for (int i = 0; i < edges.size(); i++) { - join(edges[i][0], edges[i][1]); + join(edges[i][0], edges[i][1]); } - return same(source, destination); + return isSame(source, destination); + } }; ``` diff --git "a/problems/\344\272\214\345\217\211\346\240\221\347\220\206\350\256\272\345\237\272\347\241\200.md" "b/problems/\344\272\214\345\217\211\346\240\221\347\220\206\350\256\272\345\237\272\347\241\200.md" index 3afedc8249..da139e060c 100644 --- "a/problems/\344\272\214\345\217\211\346\240\221\347\220\206\350\256\272\345\237\272\347\241\200.md" +++ "b/problems/\344\272\214\345\217\211\346\240\221\347\220\206\350\256\272\345\237\272\347\241\200.md" @@ -39,7 +39,7 @@ 什么是完全二叉树? -完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。 +完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。 **大家要自己看完全二叉树的定义,很多同学对完全二叉树其实不是真正的懂了。** From bc229e302b2ab74f4345f18bae6626543d91e0fd Mon Sep 17 00:00:00 2001 From: programmercarl <826123027@qq.com> Date: Wed, 7 Jun 2023 08:58:27 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=9B=BE=E8=AE=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 24 ++++++++++++++++++- ...75\347\232\204\350\267\257\345\276\204.md" | 4 ++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0172cb671b..65156a862f 100644 --- a/README.md +++ b/README.md @@ -387,10 +387,32 @@ 4. [单调栈:42.接雨水](./problems/0042.接雨水.md) 5. [单调栈:84.柱状图中最大的矩形](./problems/0084.柱状图中最大的矩形.md) -(持续更新中....) ## 图论 +通知:开始更新图论内容,图论部分还没有其他语言版本,欢迎录友们提交PR,成为contributor + +### 深搜广搜 + +* [图论:深度优先搜索理论基础](./problems/图论深搜理论基础.md) +* [图论:797.所有可能的路径](./problems/0797.所有可能的路径.md) +* [图论:广度优先搜索理论基础](./problems/图论广索理论基础.md) +* [图论:200.岛屿数量.深搜版](./problems/0200.岛屿数量.深搜版.md) +* [图论:200.岛屿数量.广搜版](./problems/0200.岛屿数量.广搜版.md) +* [图论:695.岛屿的最大面积](./problems/0695.岛屿的最大面积.md) +* [图论:1020.飞地的数量](./problems/1020.飞地的数量.md) +* [图论:130.被围绕的区域](./problems/0130.被围绕的区域.md) +* [图论:417.太平洋大西洋水流问题](./problems/0417.太平洋大西洋水流问题.md) +* [图论:827.最大人工岛](./problems/0827.最大人工岛.md) +* [图论:127.单词接龙](./problems/0127.单词接龙.md) +* [图论:841.钥匙和房间](./problems/0841.钥匙和房间.md) +* [图论:463.岛屿的周长](./problems/0463.岛屿的周长.md) + +### 并查集 + +(持续更新中....) + + ## 十大排序 ## 数论 diff --git "a/problems/0797.\346\211\200\346\234\211\345\217\257\350\203\275\347\232\204\350\267\257\345\276\204.md" "b/problems/0797.\346\211\200\346\234\211\345\217\257\350\203\275\347\232\204\350\267\257\345\276\204.md" index 89643e0490..2ea4ae4760 100644 --- "a/problems/0797.\346\211\200\346\234\211\345\217\257\350\203\275\347\232\204\350\267\257\345\276\204.md" +++ "b/problems/0797.\346\211\200\346\234\211\345\217\257\350\203\275\347\232\204\350\267\257\345\276\204.md" @@ -159,7 +159,7 @@ public: ## 其他语言版本 -## Java +Java ```Java // 深度优先遍历 @@ -190,7 +190,7 @@ class Solution { } ``` -## Python +Python ```python class Solution: def __init__(self):