From c835ec07b6fd76303e11ebf082df70fceb3891e3 Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Wed, 29 Mar 2023 16:44:08 +0800 Subject: [PATCH 01/58] =?UTF-8?q?Update=2024.=20=E4=B8=A4=E4=B8=A4?= =?UTF-8?q?=E4=BA=A4=E6=8D=A2=E9=93=BE=E8=A1=A8=E4=B8=AD=E7=9A=84=E8=8A=82?= =?UTF-8?q?=E7=82=B9=20about=20rust=20=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0024.两两交换链表中的节点.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 4dc051aa..12912382 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -410,7 +410,7 @@ impl Solution { // 递归 impl Solution { pub fn swap_pairs(head: Option>) -> Option> { - if head == None || head.as_ref().unwrap().next == None { + if head.is_none() || head.as_ref().unwrap().next.is_none() { return head; } From cff523c993e88c7e8de553225af7112113ae6754 Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Wed, 29 Mar 2023 19:58:07 +0800 Subject: [PATCH 02/58] =?UTF-8?q?Update=200452.=E7=94=A8=E6=9C=80=E5=B0=91?= =?UTF-8?q?=E6=95=B0=E9=87=8F=E7=9A=84=E7=AE=AD=E5=BC=95=E7=88=86=E6=B0=94?= =?UTF-8?q?=E7=90=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0452.用最少数量的箭引爆气球.md | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/problems/0452.用最少数量的箭引爆气球.md b/problems/0452.用最少数量的箭引爆气球.md index 6b018f97..3066d529 100644 --- a/problems/0452.用最少数量的箭引爆气球.md +++ b/problems/0452.用最少数量的箭引爆气球.md @@ -270,26 +270,18 @@ int findMinArrowShots(int** points, int pointsSize, int* pointsColSize){ ### Rust ```Rust -use std::cmp; impl Solution { pub fn find_min_arrow_shots(mut points: Vec>) -> i32 { - if points.is_empty() { - return 0; - } points.sort_by_key(|point| point[0]); - - let size = points.len(); - let mut count = 1; - - for i in 1..size { - if points[i][0] > points[i-1][1] { - count += 1; - } else { - points[i][1] = cmp::min(points[i][1], points[i-1][1]); + let mut result = 1; + for i in 1..points.len() { + if points[i][0] > points[i - 1][1] { + result += 1; + } else { + points[i][1] = points[i][1].min(points[i - 1][1]) } } - - return count; + result } } ``` From d1ccf8d3320eba0bfe0fb6dfdb88a4951c0729bb Mon Sep 17 00:00:00 2001 From: fw_qaq Date: Wed, 29 Mar 2023 20:00:07 +0800 Subject: [PATCH 03/58] =?UTF-8?q?Update=200452.=E7=94=A8=E6=9C=80=E5=B0=91?= =?UTF-8?q?=E6=95=B0=E9=87=8F=E7=9A=84=E7=AE=AD=E5=BC=95=E7=88=86=E6=B0=94?= =?UTF-8?q?=E7=90=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0452.用最少数量的箭引爆气球.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/problems/0452.用最少数量的箭引爆气球.md b/problems/0452.用最少数量的箭引爆气球.md index 3066d529..79f9d59a 100644 --- a/problems/0452.用最少数量的箭引爆气球.md +++ b/problems/0452.用最少数量的箭引爆气球.md @@ -272,6 +272,9 @@ int findMinArrowShots(int** points, int pointsSize, int* pointsColSize){ ```Rust impl Solution { pub fn find_min_arrow_shots(mut points: Vec>) -> i32 { + if points.is_empty() { + return 0; + } points.sort_by_key(|point| point[0]); let mut result = 1; for i in 1..points.len() { From 2d06a685ea39c988ad48b1a6025c8476cc06a640 Mon Sep 17 00:00:00 2001 From: NeedyChild <100189185+NeedyChild@users.noreply.github.com> Date: Tue, 9 May 2023 15:22:33 -0700 Subject: [PATCH 04/58] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200494.=E7=9B=AE?= =?UTF-8?q?=E6=A0=87=E5=92=8C.md=20Java=E7=89=88=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E6=95=B0=E7=BB=84=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0494.目标和.md | 79 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/problems/0494.目标和.md b/problems/0494.目标和.md index cc2bc8df..f8843d08 100644 --- a/problems/0494.目标和.md +++ b/problems/0494.目标和.md @@ -292,6 +292,85 @@ class Solution { } ``` +易于理解的二维数组版本: +```java +class Solution { + public int findTargetSumWays(int[] nums, int target) { + + // 01背包应用之“有多少种不同的填满背包最大容量的方法“ + // 易于理解的二维数组解法及详细注释 + + int sum = 0; + for(int i = 0; i < nums.length; i++) { + sum += nums[i]; + } + + // 注意nums[i] >= 0的题目条件,意味着sum也是所有nums[i]的绝对值之和 + // 这里保证了sum + target一定是大于等于零的,也就是left大于等于零(毕竟我们定义left大于right) + if(sum < Math.abs(target)){ + return 0; + } + + // 利用二元一次方程组将left用target和sum表示出来(替换掉right组合),详见代码随想录对此题的分析 + // 如果所求的left数组和为小数,则作为整数数组的nums里的任何元素自然是没有办法凑出这个小数的 + if((sum + target) % 2 != 0) { + return 0; + } + + int left = (sum + target) / 2; + + // dp[i][j]:遍历到数组第i个数时, left为j时的能装满背包的方法总数 + int[][] dp = new int[nums.length][left + 1]; + + // 初始化最上行(dp[0][j]),当nums[0] == j时(注意nums[0]和j都一定是大于等于零的,因此不需要判断等于-j时的情况),有唯一一种取法可取到j,dp[0][j]此时等于1 + // 其他情况dp[0][j] = 0 + // java整数数组默认初始值为0 + for(int j = 0; j <= left; j++) { + if(nums[0] == j) { + dp[0][j] = 1; + } + } + + // 初始化最左列(dp[i][0]) + // 当从nums数组的索引0到i的部分有n个0时(n > 0),每个0可以取+/-,因此有2的n次方中可以取到j = 0的方案 + // n = 0说明当前遍历到的数组部分没有0全为正数,因此只有一种方案可以取到j = 0(就是所有数都不取) + int numZeros = 0; + for(int i = 0; i < nums.length; i++) { + if(nums[i] == 0) { + numZeros++; + } + dp[i][0] = (int) Math.pow(2, numZeros); + + } + + // 递推公式分析: + // 当nums[i] > j时,这时候nums[i]一定不能取,所以是dp[i - 1][j]种方案数 + // nums[i] <= j时,num[i]可取可不取,因此方案数是dp[i - 1][j] + dp[i - 1][j - nums[i]] + // 由递推公式可知,先遍历i或j都可 + for(int i = 1; i < nums.length; i++) { + for(int j = 1; j <= left; j++) { + if(nums[i] > j) { + dp[i][j] = dp[i - 1][j]; + } else { + dp[i][j] = dp[i - 1][j] + dp[i - 1][j - nums[i]]; + } + } + } + + // 打印dp数组 + // for(int i = 0; i < nums.length; i++) { + // for(int j = 0; j <= left; j++) { + // System.out.print(dp[i][j] + " "); + // } + // System.out.println(""); + // } + + return dp[nums.length - 1][left]; + + } +} +``` + ### Python ```python class Solution: From ff5c98184ed3d01c1ef579d5df5c0d3906ac4f6b Mon Sep 17 00:00:00 2001 From: dd <593274462@qq.com> Date: Sun, 28 May 2023 22:42:49 +0800 Subject: [PATCH 05/58] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=201005.K?= =?UTF-8?q?=E6=AC=A1=E5=8F=96=E5=8F=8D=E5=90=8E=E6=9C=80=E5=A4=A7=E5=8C=96?= =?UTF-8?q?=E7=9A=84=E6=95=B0=E7=BB=84=E5=92=8C=20js=20=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=AE=AD=E5=A4=B4=E5=87=BD=E6=95=B0=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1005.K次取反后最大化的数组和.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/1005.K次取反后最大化的数组和.md b/problems/1005.K次取反后最大化的数组和.md index 571bc2ac..9759702a 100644 --- a/problems/1005.K次取反后最大化的数组和.md +++ b/problems/1005.K次取反后最大化的数组和.md @@ -189,9 +189,9 @@ var largestSumAfterKNegations = function(nums, k) { nums[nums.length-1] = - nums[nums.length-1] k--; } - return nums.reduce((a, b) => { - a + b - }) + + // 使用箭头函数的隐式返回值时,需使用简写省略花括号,否则要在 a + b 前加上 return + return nums.reduce((a, b) => a + b) }; // 版本二 (优化: 一次遍历) From 4a6e87f2f02c3d023c7ae2de7113abe808dd9a96 Mon Sep 17 00:00:00 2001 From: August <549392485@qq.com> Date: Sun, 28 May 2023 23:57:29 +0800 Subject: [PATCH 06/58] =?UTF-8?q?Update=200034.=E5=9C=A8=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E4=B8=AD=E6=9F=A5=E6=89=BE=E5=85=83=E7=B4=A0?= =?UTF-8?q?=E7=9A=84=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=92=8C=E6=9C=80=E5=90=8E?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E4=BD=8D=E7=BD=AE.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...序数组中查找元素的第一个和最后一个位置.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md index 7e58a870..e5266cd9 100644 --- a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md +++ b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md @@ -240,7 +240,7 @@ class Solution { while (left - 1 >= 0 && nums[left - 1] == nums[index]) { // 防止数组越界。逻辑短路,两个条件顺序不能换 left--; } - // 向左滑动,找右边界 + // 向右滑动,找右边界 while (right + 1 < nums.length && nums[right + 1] == nums[index]) { // 防止数组越界。 right++; } From b2812eb707d9e2c5382781b23d5add54e8e1db63 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Mon, 29 May 2023 19:02:51 +0800 Subject: [PATCH 07/58] =?UTF-8?q?Update=200322.=E9=9B=B6=E9=92=B1=E5=85=91?= =?UTF-8?q?=E6=8D=A2.md=20about=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0322.零钱兑换.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/problems/0322.零钱兑换.md b/problems/0322.零钱兑换.md index 0e3947da..28188349 100644 --- a/problems/0322.零钱兑换.md +++ b/problems/0322.零钱兑换.md @@ -315,18 +315,24 @@ func min(a, b int) int { Rust: ```rust -pub fn coin_change(coins: Vec, amount: i32) -> i32 { - let amount = amount as usize; - let mut dp = vec![i32::MAX; amount + 1]; - dp[0] = 0; - for i in 0..coins.len() { - for j in coins[i] as usize..=amount { - if dp[j - coins[i] as usize] != i32::MAX { - dp[j] = dp[j].min(dp[j - coins[i] as usize] + 1); +// 遍历物品 +impl Solution { + pub fn coin_change(coins: Vec, amount: i32) -> i32 { + let amount = amount as usize; + let mut dp = vec![i32::MAX; amount + 1]; + dp[0] = 0; + for coin in coins { + for i in coin as usize..=amount { + if dp[i - coin as usize] != i32::MAX { + dp[i] = dp[i].min(dp[i - coin as usize] + 1); + } } } + if dp[amount] == i32::MAX { + return -1; + } + dp[amount] } - if dp[amount] == i32::MAX { -1 } else { dp[amount] } } ``` From f45d4718c39c6d932ef32ff190c01be839a7d18d Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Mon, 29 May 2023 19:10:46 +0800 Subject: [PATCH 08/58] =?UTF-8?q?Update=200322.=E9=9B=B6=E9=92=B1=E5=85=91?= =?UTF-8?q?=E6=8D=A2.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0322.零钱兑换.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/problems/0322.零钱兑换.md b/problems/0322.零钱兑换.md index 28188349..0f910451 100644 --- a/problems/0322.零钱兑换.md +++ b/problems/0322.零钱兑换.md @@ -336,6 +336,28 @@ impl Solution { } ``` +```rust +// 遍历背包 +impl Solution { + pub fn coin_change(coins: Vec, amount: i32) -> i32 { + let amount = amount as usize; + let mut dp = vec![i32::MAX; amount + 1]; + dp[0] = 0; + for i in 0..=amount { + for &coin in &coins { + if i >= coin as usize && dp[i - coin as usize] != i32::MAX { + dp[i] = dp[i].min(dp[i - coin as usize] + 1) + } + } + } + if dp[amount] == i32::MAX { + return -1; + } + dp[amount] + } +} +``` + Javascript: ```javascript const coinChange = (coins, amount) => { From 88f03c4abaf66141a2e507c746633af2cd93c7e6 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Mon, 29 May 2023 23:26:49 +0800 Subject: [PATCH 09/58] =?UTF-8?q?Update=200322.=E9=9B=B6=E9=92=B1=E5=85=91?= =?UTF-8?q?=E6=8D=A2.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0322.零钱兑换.md | 39 +++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/problems/0322.零钱兑换.md b/problems/0322.零钱兑换.md index 0f910451..7272b194 100644 --- a/problems/0322.零钱兑换.md +++ b/problems/0322.零钱兑换.md @@ -343,7 +343,7 @@ impl Solution { let amount = amount as usize; let mut dp = vec![i32::MAX; amount + 1]; dp[0] = 0; - for i in 0..=amount { + for i in 1..=amount { for &coin in &coins { if i >= coin as usize && dp[i - coin as usize] != i32::MAX { dp[i] = dp[i].min(dp[i - coin as usize] + 1) @@ -360,6 +360,7 @@ impl Solution { Javascript: ```javascript +// 遍历物品 const coinChange = (coins, amount) => { if(!amount) { return 0; @@ -368,7 +369,7 @@ const coinChange = (coins, amount) => { let dp = Array(amount + 1).fill(Infinity); dp[0] = 0; - for(let i =0; i < coins.length; i++) { + for(let i = 0; i < coins.length; i++) { for(let j = coins[i]; j <= amount; j++) { dp[j] = Math.min(dp[j - coins[i]] + 1, dp[j]); } @@ -378,9 +379,26 @@ const coinChange = (coins, amount) => { } ``` +```javascript +// 遍历背包 +var coinChange = function(coins, amount) { + const dp = Array(amount + 1).fill(Infinity) + dp[0] = 0 + for (let i = 1; i <= amount; i++) { + for (let j = 0; j < coins.length; j++) { + if (i >= coins[j] && dp[i - coins[j]] !== Infinity) { + dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1) + } + } + } + return dp[amount] === Infinity ? -1 : dp[amount] +} +``` + TypeScript: ```typescript +// 遍历物品 function coinChange(coins: number[], amount: number): number { const dp: number[] = new Array(amount + 1).fill(Infinity); dp[0] = 0; @@ -394,6 +412,23 @@ function coinChange(coins: number[], amount: number): number { }; ``` +```typescript +// 遍历背包 +function coinChange(coins: number[], amount: number): number { + const dp: number[] = Array(amount + 1).fill(Infinity) + dp[0] = 0 + for (let i = 1; i <= amount; i++) { + for (let j = 0; j < coins.length; j++) { + if (i >= coins[j] && dp[i - coins[j]] !== Infinity) { + dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1) + } + } + } + return dp[amount] === Infinity ? -1 : dp[amount] +} +``` + +

From 2a61ec45e6366c35189ead2b08914104c1df672e Mon Sep 17 00:00:00 2001 From: Logen <47022821+Logenleedev@users.noreply.github.com> Date: Mon, 29 May 2023 17:38:31 -0500 Subject: [PATCH 10/58] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0047.全排列II.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/problems/0047.全排列II.md b/problems/0047.全排列II.md index b1908fb4..a1036b37 100644 --- a/problems/0047.全排列II.md +++ b/problems/0047.全排列II.md @@ -98,6 +98,8 @@ public: } }; +// 时间复杂度: 最差情况所有元素都是唯一的。复杂度和全排列1都是 O(n! * n) 对于 n 个元素一共有 n! 中排列方案。而对于每一个答案,我们需要 O(n) 去复制最终放到 result 数组 +// 空间复杂度: O(n) 回溯树的深度取决于我们有多少个元素 ``` ## 拓展 From 83a87ab5ad2f1dd0f81f3e779921a46c15d979f8 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Tue, 30 May 2023 16:28:09 +0800 Subject: [PATCH 11/58] =?UTF-8?q?Update=200279.=E5=AE=8C=E5=85=A8=E5=B9=B3?= =?UTF-8?q?=E6=96=B9=E6=95=B0.md=20about=20Rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0279.完全平方数.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/0279.完全平方数.md b/problems/0279.完全平方数.md index f5b23d26..d5736951 100644 --- a/problems/0279.完全平方数.md +++ b/problems/0279.完全平方数.md @@ -345,6 +345,29 @@ function numSquares(n: number): number { }; ``` +Rust: + +```rust +// 先遍历背包 +impl Solution { + pub fn num_squares(n: i32) -> i32 { + let n = n as usize; + let mut dp = vec![i32::MAX; n + 1]; + dp[0] = 0; + for i in 0..=n { + let mut j = 1; + loop { + match j * j > i { + true => break, + false => dp[i] = dp[i].min(dp[i - j * j] + 1), + } + j += 1; + } + } + dp[n] + } +} +```

From a2ff242303546243f606e717e34ff8d2965eeb9d Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Tue, 30 May 2023 18:30:14 +0800 Subject: [PATCH 12/58] =?UTF-8?q?Update=200279.=E5=AE=8C=E5=85=A8=E5=B9=B3?= =?UTF-8?q?=E6=96=B9=E6=95=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0279.完全平方数.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/problems/0279.完全平方数.md b/problems/0279.完全平方数.md index d5736951..1a0b55c0 100644 --- a/problems/0279.完全平方数.md +++ b/problems/0279.完全平方数.md @@ -369,6 +369,27 @@ impl Solution { } ``` +```rust +// 先遍历物品 +impl Solution { + pub fn num_squares(n: i32) -> i32 { + let (n, mut goods) = (n as usize, 1); + let mut dp = vec![i32::MAX; n + 1]; + dp[0] = 0; + loop { + if goods * goods > n { + break; + } + for j in goods * goods..=n { + dp[j] = dp[j].min(dp[j - goods * goods] + 1); + } + goods += 1; + } + dp[n] + } +} +``` +

From 46495a7753ebf1eb603891229375e06fc1f05a07 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Tue, 30 May 2023 21:21:02 +0800 Subject: [PATCH 13/58] =?UTF-8?q?Update=200279.=E5=AE=8C=E5=85=A8=E5=B9=B3?= =?UTF-8?q?=E6=96=B9=E6=95=B0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0279.完全平方数.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/problems/0279.完全平方数.md b/problems/0279.完全平方数.md index 1a0b55c0..71ab1906 100644 --- a/problems/0279.完全平方数.md +++ b/problems/0279.完全平方数.md @@ -331,6 +331,7 @@ var numSquares2 = function(n) { TypeScript: ```typescript +// 先遍历物品 function numSquares(n: number): number { const goodsNum: number = Math.floor(Math.sqrt(n)); const dp: number[] = new Array(n + 1).fill(Infinity); @@ -345,6 +346,20 @@ function numSquares(n: number): number { }; ``` +```rust +// 先遍历背包 +function numSquares(n: number): number { + const dp = Array(n + 1).fill(Infinity) + dp[0] = 0; + for(let i = 1; i <= n; i++){ + for(let j = 1; j * j <= i; j++){ + dp[i] = Math.min(dp[i], dp[i -j * j] + 1) + } + } + return dp[n] +}; +``` + Rust: ```rust From 3e18a30e36375046900278f7f09dc3ed53aa766f Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Tue, 30 May 2023 22:15:23 +0800 Subject: [PATCH 14/58] =?UTF-8?q?Update=200139.=E5=8D=95=E8=AF=8D=E6=8B=86?= =?UTF-8?q?=E5=88=86.md=20about=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0139.单词拆分.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/0139.单词拆分.md b/problems/0139.单词拆分.md index 230942ef..402ce132 100644 --- a/problems/0139.单词拆分.md +++ b/problems/0139.单词拆分.md @@ -464,7 +464,24 @@ function wordBreak(s: string, wordDict: string[]): boolean { }; ``` +Rust: +```rust +impl Solution { + pub fn word_break(s: String, word_dict: Vec) -> bool { + let mut dp = vec![false; s.len() + 1]; + dp[0] = true; + for i in 1..=s.len() { + for j in 0..i { + if word_dict.iter().any(|word| *word == s[j..i]) && dp[j] { + dp[i] = true; + } + } + } + dp[s.len()] + } +} +```

From 08823a26309c0bf87ecb90f680694f87255513bd Mon Sep 17 00:00:00 2001 From: rosethorn999 <24700793+rosethorn999@users.noreply.github.com> Date: Tue, 30 May 2023 12:44:16 -0700 Subject: [PATCH 15/58] chore: Missing language name --- problems/0383.赎金信.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0383.赎金信.md b/problems/0383.赎金信.md index c7469d65..e74cdf71 100644 --- a/problems/0383.赎金信.md +++ b/problems/0383.赎金信.md @@ -146,6 +146,7 @@ class Solution { ``` +Python: (版本一)使用数组 ```python class Solution: @@ -210,7 +211,6 @@ class Solution: class Solution: def canConstruct(self, ransomNote: str, magazine: str) -> bool: return all(ransomNote.count(c) <= magazine.count(c) for c in set(ransomNote)) - ``` Go: From be926a3c5b3e67023cf99f4f0311d091c01a7e08 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Wed, 31 May 2023 21:43:25 +0800 Subject: [PATCH 16/58] =?UTF-8?q?Update=200198.=E6=89=93=E5=AE=B6=E5=8A=AB?= =?UTF-8?q?=E8=88=8D.md=20about=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0198.打家劫舍.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/0198.打家劫舍.md b/problems/0198.打家劫舍.md index 6e682ec3..1ecd2eb7 100644 --- a/problems/0198.打家劫舍.md +++ b/problems/0198.打家劫舍.md @@ -250,7 +250,24 @@ function rob(nums: number[]): number { }; ``` +Rust: +```rust +impl Solution { + pub fn rob(nums: Vec) -> i32 { + if nums.len() == 1 { + return nums[0]; + } + let mut dp = vec![0; nums.len()]; + dp[0] = nums[0]; + dp[1] = nums[0].max(nums[1]); + for i in 2..nums.len() { + dp[i] = (dp[i - 2] + nums[i]).max(dp[i - 1]); + } + dp[nums.len() - 1] + } +} +```

From f22c658d365595a080ff5b516a3f2fca775e0ae6 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, 31 May 2023 22:50:48 +0800 Subject: [PATCH 17/58] =?UTF-8?q?Update=200257.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E6=89=80=E6=9C=89=E8=B7=AF=E5=BE=84.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0257.二叉树的所有路径.md | 27 ++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/problems/0257.二叉树的所有路径.md b/problems/0257.二叉树的所有路径.md index 7bd56fbd..06153507 100644 --- a/problems/0257.二叉树的所有路径.md +++ b/problems/0257.二叉树的所有路径.md @@ -390,6 +390,8 @@ public: ```Java //解法一 + +//方式一 class Solution { /** * 递归法 @@ -428,9 +430,32 @@ class Solution { } } } + +//方式二 +class Solution { + + List result = new ArrayList<>(); + + public List binaryTreePaths(TreeNode root) { + deal(root, ""); + return result; + } + + public void deal(TreeNode node, String s) { + if (node == null) + return; + if (node.left == null && node.right == null) { + result.add(new StringBuilder(s).append(node.val).toString()); + return; + } + String tmp = new StringBuilder(s).append(node.val).append("->").toString(); + deal(node.left, tmp); + deal(node.right, tmp); + } +} ``` ```java -// 解法2 +// 解法二 class Solution { /** * 迭代法 From 5b4249d4a853a77e9aed0af171204c9b8d0ee2ac Mon Sep 17 00:00:00 2001 From: liuyiwei <709224218@qq.com> Date: Thu, 1 Jun 2023 16:34:00 +0800 Subject: [PATCH 18/58] =?UTF-8?q?151.=E7=BF=BB=E8=BD=AC=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=E9=87=8C=E7=9A=84=E5=8D=95=E8=AF=8D=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E4=BD=BF=E7=94=A8=E4=BA=86=E7=A7=BB=E9=99=A4=E5=85=83?= =?UTF-8?q?=E7=B4=A0=E6=80=9D=E6=83=B3=E7=9A=84=20Go=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0151.翻转字符串里的单词.md | 50 +++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/problems/0151.翻转字符串里的单词.md b/problems/0151.翻转字符串里的单词.md index 4474f1c6..6dd3cd49 100644 --- a/problems/0151.翻转字符串里的单词.md +++ b/problems/0151.翻转字符串里的单词.md @@ -467,9 +467,57 @@ class Solution: return " ".join(words) ``` - Go: +版本一: + +```go +func reverseWords(s string) string { + b := []byte(s) + + // 移除前面、中间、后面存在的多余空格 + slow := 0 + for i := 0; i < len(b); i++ { + if b[i] != ' ' { + if slow != 0 { + b[slow] = ' ' + slow++ + } + for i < len(b) && b[i] != ' ' { // 复制逻辑 + b[slow] = b[i] + slow++ + i++ + } + } + } + b = b[0:slow] + + // 翻转整个字符串 + reverse(b) + // 翻转每个单词 + last := 0 + for i := 0; i <= len(b); i++ { + if i == len(b) || b[i] == ' ' { + reverse(b[last:i]) + last = i + 1 + } + } + return string(b) +} + +func reverse(b []byte) { + left := 0 + right := len(b) - 1 + for left < right { + b[left], b[right] = b[right], b[left] + left++ + right-- + } +} +``` + +版本二: + ```go import ( "fmt" From 32185d5f2d8b3873253da3b44cbb1fb2aaa86762 Mon Sep 17 00:00:00 2001 From: Lozakaka <102352821+Lozakaka@users.noreply.github.com> Date: Thu, 1 Jun 2023 19:44:43 -0400 Subject: [PATCH 19/58] =?UTF-8?q?=E7=B7=A8=E8=BC=AFJAVA=E8=A7=A3=E7=AD=94?= =?UTF-8?q?=E7=9A=84=E9=83=A8=E5=88=86=E5=85=A7=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 提供JAVA填充數組的函數Arrays.fill() 2. for loop中不需要if statement,並有用 // 解釋原因 --- problems/0279.完全平方数.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/problems/0279.完全平方数.md b/problems/0279.完全平方数.md index f5b23d26..82d02b30 100644 --- a/problems/0279.完全平方数.md +++ b/problems/0279.完全平方数.md @@ -177,15 +177,19 @@ class Solution { for (int j = 0; j <= n; j++) { dp[j] = max; } + //如果不想要寫for-loop填充數組的話,也可以用JAVA內建的Arrays.fill()函數。 + //Arrays.fill(dp, Integer.MAX_VALUE); + //当和为0时,组合的个数为0 dp[0] = 0; // 遍历物品 for (int i = 1; i * i <= n; i++) { // 遍历背包 for (int j = i * i; j <= n; j++) { - if (dp[j - i * i] != max) { + //if (dp[j - i * i] != max) { dp[j] = Math.min(dp[j], dp[j - i * i] + 1); - } + //} + //不需要這個if statement,因爲在完全平方數這一題不會有"湊不成"的狀況發生( 一定可以用"1"來組成任何一個n),故comment掉這個if statement。 } } return dp[n]; From 477f4595749ea6d38b22f3bac14cdc35c8aa2191 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Fri, 2 Jun 2023 22:24:44 +0800 Subject: [PATCH 20/58] =?UTF-8?q?Update=200213.=E6=89=93=E5=AE=B6=E5=8A=AB?= =?UTF-8?q?=E8=88=8DII.md=20about=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0213.打家劫舍II.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/problems/0213.打家劫舍II.md b/problems/0213.打家劫舍II.md index 6395f3a8..494ad2bd 100644 --- a/problems/0213.打家劫舍II.md +++ b/problems/0213.打家劫舍II.md @@ -248,6 +248,35 @@ function robRange(nums: number[], start: number, end: number): number { } ``` +Rust: + +```rust +impl Solution { + pub fn rob(nums: Vec) -> i32 { + match nums.len() { + 1 => nums[0], + _ => Self::rob_range(&nums, 0, nums.len() - 2).max(Self::rob_range( + &nums, + 1, + nums.len() - 1, + )), + } + } + + pub fn rob_range(nums: &Vec, start: usize, end: usize) -> i32 { + if start == end { + return nums[start]; + } + let mut dp = vec![0; nums.len()]; + dp[start] = nums[start]; + dp[start + 1] = nums[start].max(nums[start + 1]); + for i in start + 2..=end { + dp[i] = dp[i - 1].max(dp[i - 2] + nums[i]); + } + dp[end] + } +} +```

From 6bb21c8e5b18ea720651c087ecbe350ffe87a371 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sat, 3 Jun 2023 11:20:55 +0800 Subject: [PATCH 21/58] =?UTF-8?q?Update=200337.=E6=89=93=E5=AE=B6=E5=8A=AB?= =?UTF-8?q?=E8=88=8DIII.md=20about=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0337.打家劫舍III.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/problems/0337.打家劫舍III.md b/problems/0337.打家劫舍III.md index ca8cea23..1708b7a1 100644 --- a/problems/0337.打家劫舍III.md +++ b/problems/0337.打家劫舍III.md @@ -490,6 +490,33 @@ function robNode(node: TreeNode | null): MaxValueArr { } ``` +### Rust + +动态规划: + +```rust +use std::cell::RefCell; +use std::rc::Rc; +impl Solution { + pub fn rob(root: Option>>) -> i32 { + let (v1, v2) = Self::rob_tree(&root); + v1.max(v2) + } + pub fn rob_tree(cur: &Option>>) -> (i32, i32) { + match cur { + None => (0, 0), + Some(node) => { + let left = Self::rob_tree(&node.borrow_mut().left); + let right = Self::rob_tree(&node.borrow_mut().right); + ( + left.0.max(left.1) + right.0.max(right.1), // 偷左右节点 + node.borrow().val + left.0 + right.0, // 偷父节点 + ) + } + } + } +} +```

From 2d66c713f06609bfcbfa6099b4e858686ae620a2 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sat, 3 Jun 2023 13:58:57 +0800 Subject: [PATCH 22/58] =?UTF-8?q?Update=200121.=E4=B9=B0=E5=8D=96=E8=82=A1?= =?UTF-8?q?=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BA.md=20abo?= =?UTF-8?q?ut=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0121.买卖股票的最佳时机.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md index 753cb106..be8630f5 100644 --- a/problems/0121.买卖股票的最佳时机.md +++ b/problems/0121.买卖股票的最佳时机.md @@ -510,7 +510,22 @@ public class Solution } ``` +Rust: +> 贪心 + +```rust +impl Solution { + pub fn max_profit(prices: Vec) -> i32 { + let (mut low, mut res) = (i32::MAX, 0); + for p in prices { + low = p.min(low); + res = res.max(p - low); + } + res + } +} +```

From b716a8ab44c06d9ff0b144774aa43b93efd75c90 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sat, 3 Jun 2023 14:05:04 +0800 Subject: [PATCH 23/58] =?UTF-8?q?Update=200121.=E4=B9=B0=E5=8D=96=E8=82=A1?= =?UTF-8?q?=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BA.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0121.买卖股票的最佳时机.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md index be8630f5..9c8a4390 100644 --- a/problems/0121.买卖股票的最佳时机.md +++ b/problems/0121.买卖股票的最佳时机.md @@ -527,6 +527,21 @@ impl Solution { } ``` +> 动态规划 + +```rust +impl Solution { + pub fn max_profit(prices: Vec) -> i32 { + let mut dp = vec![-prices[0], 0]; + for p in prices { + dp[0] = dp[0].max(-p); + dp[1] = dp[1].max(dp[0] + p); + } + dp[1] + } +} +``` +

From 745e91e1e7043474e15ec790a89a472d0d25e279 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sat, 3 Jun 2023 14:22:19 +0800 Subject: [PATCH 24/58] =?UTF-8?q?Update=200122.=E4=B9=B0=E5=8D=96=E8=82=A1?= =?UTF-8?q?=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BAII.md=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20Rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0122.买卖股票的最佳时机II.md | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/problems/0122.买卖股票的最佳时机II.md b/problems/0122.买卖股票的最佳时机II.md index 0d8ad608..89c654fa 100644 --- a/problems/0122.买卖股票的最佳时机II.md +++ b/problems/0122.买卖股票的最佳时机II.md @@ -322,13 +322,10 @@ function maxProfit(prices: number[]): number { ```Rust impl Solution { - fn max(a: i32, b: i32) -> i32 { - if a > b { a } else { b } - } pub fn max_profit(prices: Vec) -> i32 { let mut result = 0; for i in 1..prices.len() { - result += Self::max(prices[i] - prices[i - 1], 0); + result += (prices[i] - prices[i - 1]).max(0); } result } @@ -339,18 +336,14 @@ impl Solution { ```Rust impl Solution { - fn max(a: i32, b: i32) -> i32 { - if a > b { a } else { b } - } pub fn max_profit(prices: Vec) -> i32 { - let n = prices.len(); - let mut dp = vec![vec![0; 2]; n]; - dp[0][0] -= prices[0]; - for i in 1..n { - dp[i][0] = Self::max(dp[i - 1][0], dp[i - 1][1] - prices[i]); - dp[i][1] = Self::max(dp[i - 1][1], dp[i - 1][0] + prices[i]); + let mut dp = vec![vec![0; 2]; prices.len()]; + dp[0][0] = -prices[0]; + for i in 1..prices.len() { + dp[i][0] = dp[i - 1][0].max(dp[i - 1][1] - prices[i]); + dp[i][1] = dp[i - 1][1].max(dp[i - 1][0] + prices[i]); } - Self::max(dp[n - 1][0], dp[n - 1][1]) + dp[prices.len() - 1][1] } } ``` From fd7a98b8315eb56f07caac3cc586f6b96e3d246b Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sat, 3 Jun 2023 14:40:00 +0800 Subject: [PATCH 25/58] =?UTF-8?q?Update=200122.=E4=B9=B0=E5=8D=96=E8=82=A1?= =?UTF-8?q?=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BAII?= =?UTF-8?q?=EF=BC=88=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=EF=BC=89.md=20abo?= =?UTF-8?q?ut=20rust?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...票的最佳时机II(动态规划).md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/problems/0122.买卖股票的最佳时机II(动态规划).md b/problems/0122.买卖股票的最佳时机II(动态规划).md index 146c6a4c..5976f258 100644 --- a/problems/0122.买卖股票的最佳时机II(动态规划).md +++ b/problems/0122.买卖股票的最佳时机II(动态规划).md @@ -346,7 +346,52 @@ public class Solution } ``` +Rust: +> 贪心 + +```rust +impl Solution { + pub fn max_profit(prices: Vec) -> i32 { + let mut result = 0; + for i in 1..prices.len() { + result += (prices[i] - prices[i - 1]).max(0); + } + result + } +} +``` + +>动态规划 + +```rust +impl Solution { + pub fn max_profit(prices: Vec) -> i32 { + let mut dp = vec![vec![0; 2]; prices.len()]; + dp[0][0] = -prices[0]; + for i in 1..prices.len() { + dp[i][0] = dp[i - 1][0].max(dp[i - 1][1] - prices[i]); + dp[i][1] = dp[i - 1][1].max(dp[i - 1][0] + prices[i]); + } + dp[prices.len() - 1][1] + } +} +``` + +> 优化 + +```rust +impl Solution { + pub fn max_profit(prices: Vec) -> i32 { + let mut dp = vec![-prices[0], 0]; + for i in 1..=prices.len() { + dp[0] = dp[0].max(dp[1] - prices[i - 1]); + dp[1] = dp[1].max(dp[0] + prices[i - 1]); + } + dp[1] + } +} +```

From 2719dbdd0eeeaf534acf09f0a67d3f84bae84a04 Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sat, 3 Jun 2023 14:58:09 +0800 Subject: [PATCH 26/58] =?UTF-8?q?Update=200122.=E4=B9=B0=E5=8D=96=E8=82=A1?= =?UTF-8?q?=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BAII?= =?UTF-8?q?=EF=BC=88=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=EF=BC=89.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0122.买卖股票的最佳时机II(动态规划).md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/problems/0122.买卖股票的最佳时机II(动态规划).md b/problems/0122.买卖股票的最佳时机II(动态规划).md index 5976f258..43e567c5 100644 --- a/problems/0122.买卖股票的最佳时机II(动态规划).md +++ b/problems/0122.买卖股票的最佳时机II(动态规划).md @@ -384,9 +384,10 @@ impl Solution { impl Solution { pub fn max_profit(prices: Vec) -> i32 { let mut dp = vec![-prices[0], 0]; - for i in 1..=prices.len() { - dp[0] = dp[0].max(dp[1] - prices[i - 1]); - dp[1] = dp[1].max(dp[0] + prices[i - 1]); + for p in prices { + // 可以看作 low、res + dp[0] = dp[0].max(dp[1] - p); + dp[1] = dp[1].max(dp[0] + p); } dp[1] } From 2a6a8da5e0e5d0949f92f8ef04aab26c5138770f Mon Sep 17 00:00:00 2001 From: fwqaaq Date: Sat, 3 Jun 2023 14:59:17 +0800 Subject: [PATCH 27/58] =?UTF-8?q?Update=20problems/0122.=E4=B9=B0=E5=8D=96?= =?UTF-8?q?=E8=82=A1=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BA?= =?UTF-8?q?II=EF=BC=88=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=EF=BC=89.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0122.买卖股票的最佳时机II(动态规划).md | 1 - 1 file changed, 1 deletion(-) diff --git a/problems/0122.买卖股票的最佳时机II(动态规划).md b/problems/0122.买卖股票的最佳时机II(动态规划).md index 43e567c5..24e15024 100644 --- a/problems/0122.买卖股票的最佳时机II(动态规划).md +++ b/problems/0122.买卖股票的最佳时机II(动态规划).md @@ -385,7 +385,6 @@ impl Solution { pub fn max_profit(prices: Vec) -> i32 { let mut dp = vec![-prices[0], 0]; for p in prices { - // 可以看作 low、res dp[0] = dp[0].max(dp[1] - p); dp[1] = dp[1].max(dp[0] + p); } From 22615387a5966b8930076b08abe29ae22ce8ce8a Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Tue, 6 Jun 2023 10:25:25 -0500 Subject: [PATCH 28/58] =?UTF-8?q?Update=200309.=E6=9C=80=E4=BD=B3=E4=B9=B0?= =?UTF-8?q?=E5=8D=96=E8=82=A1=E7=A5=A8=E6=97=B6=E6=9C=BA=E5=90=AB=E5=86=B7?= =?UTF-8?q?=E5=86=BB=E6=9C=9F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...09.最佳买卖股票时机含冷冻期.md | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/problems/0309.最佳买卖股票时机含冷冻期.md b/problems/0309.最佳买卖股票时机含冷冻期.md index a56d9b84..67f6d564 100644 --- a/problems/0309.最佳买卖股票时机含冷冻期.md +++ b/problems/0309.最佳买卖股票时机含冷冻期.md @@ -248,23 +248,51 @@ class Solution { ``` Python: - +版本一 ```python +from typing import List + class Solution: def maxProfit(self, prices: List[int]) -> int: n = len(prices) if n == 0: return 0 - dp = [[0] * 4 for _ in range(n)] - dp[0][0] = -prices[0] #持股票 + dp = [[0] * 4 for _ in range(n)] # 创建动态规划数组,4个状态分别表示持有股票、不持有股票且处于冷冻期、不持有股票且不处于冷冻期、不持有股票且当天卖出后处于冷冻期 + dp[0][0] = -prices[0] # 初始状态:第一天持有股票的最大利润为买入股票的价格 for i in range(1, n): - dp[i][0] = max(dp[i-1][0], max(dp[i-1][3], dp[i-1][1]) - prices[i]) - dp[i][1] = max(dp[i-1][1], dp[i-1][3]) - dp[i][2] = dp[i-1][0] + prices[i] - dp[i][3] = dp[i-1][2] - return max(dp[n-1][3], dp[n-1][1], dp[n-1][2]) -``` + dp[i][0] = max(dp[i-1][0], max(dp[i-1][3], dp[i-1][1]) - prices[i]) # 当前持有股票的最大利润等于前一天持有股票的最大利润或者前一天不持有股票且不处于冷冻期的最大利润减去当前股票的价格 + dp[i][1] = max(dp[i-1][1], dp[i-1][3]) # 当前不持有股票且处于冷冻期的最大利润等于前一天持有股票的最大利润加上当前股票的价格 + dp[i][2] = dp[i-1][0] + prices[i] # 当前不持有股票且不处于冷冻期的最大利润等于前一天不持有股票的最大利润或者前一天处于冷冻期的最大利润 + dp[i][3] = dp[i-1][2] # 当前不持有股票且当天卖出后处于冷冻期的最大利润等于前一天不持有股票且不处于冷冻期的最大利润 + return max(dp[n-1][3], dp[n-1][1], dp[n-1][2]) # 返回最后一天不持有股票的最大利润 +``` +版本二 +```python +class Solution: + def maxProfit(self, prices: List[int]) -> int: + n = len(prices) + if n < 2: + return 0 + + # 定义三种状态的动态规划数组 + dp = [[0] * 3 for _ in range(n)] + dp[0][0] = -prices[0] # 持有股票的最大利润 + dp[0][1] = 0 # 不持有股票,且处于冷冻期的最大利润 + dp[0][2] = 0 # 不持有股票,不处于冷冻期的最大利润 + + for i in range(1, n): + # 当前持有股票的最大利润等于前一天持有股票的最大利润或者前一天不持有股票且不处于冷冻期的最大利润减去当前股票的价格 + dp[i][0] = max(dp[i-1][0], dp[i-1][2] - prices[i]) + # 当前不持有股票且处于冷冻期的最大利润等于前一天持有股票的最大利润加上当前股票的价格 + dp[i][1] = dp[i-1][0] + prices[i] + # 当前不持有股票且不处于冷冻期的最大利润等于前一天不持有股票的最大利润或者前一天处于冷冻期的最大利润 + dp[i][2] = max(dp[i-1][2], dp[i-1][1]) + + # 返回最后一天不持有股票的最大利润 + return max(dp[-1][1], dp[-1][2]) + +``` Go: ```go // 最佳买卖股票时机含冷冻期 动态规划 From d3a07fa1bd7c325188a416486daa7a85e6816680 Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Tue, 6 Jun 2023 15:29:07 -0500 Subject: [PATCH 29/58] =?UTF-8?q?Update=200300.=E6=9C=80=E9=95=BF=E4=B8=8A?= =?UTF-8?q?=E5=8D=87=E5=AD=90=E5=BA=8F=E5=88=97.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0300.最长上升子序列.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/problems/0300.最长上升子序列.md b/problems/0300.最长上升子序列.md index 01d34949..98d7b14f 100644 --- a/problems/0300.最长上升子序列.md +++ b/problems/0300.最长上升子序列.md @@ -141,7 +141,7 @@ class Solution { } } ``` - +DP Python: ```python class Solution: @@ -157,7 +157,31 @@ class Solution: result = max(result, dp[i]) #取长的子序列 return result ``` +贪心 +```python +class Solution: + def lengthOfLIS(self, nums: List[int]) -> int: + if len(nums) <= 1: + return len(nums) + + tails = [nums[0]] # 存储递增子序列的尾部元素 + for num in nums[1:]: + if num > tails[-1]: + tails.append(num) # 如果当前元素大于递增子序列的最后一个元素,直接加入到子序列末尾 + else: + # 使用二分查找找到当前元素在递增子序列中的位置,并替换对应位置的元素 + left, right = 0, len(tails) - 1 + while left < right: + mid = (left + right) // 2 + if tails[mid] < num: + left = mid + 1 + else: + right = mid + tails[left] = num + + return len(tails) # 返回递增子序列的长度 +``` Go: ```go // 动态规划求解 From a7d546ca2a6c7af9df378b3928c58f373177ed54 Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Tue, 6 Jun 2023 15:29:32 -0500 Subject: [PATCH 30/58] =?UTF-8?q?Update=200300.=E6=9C=80=E9=95=BF=E4=B8=8A?= =?UTF-8?q?=E5=8D=87=E5=AD=90=E5=BA=8F=E5=88=97.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0300.最长上升子序列.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/problems/0300.最长上升子序列.md b/problems/0300.最长上升子序列.md index 98d7b14f..54249331 100644 --- a/problems/0300.最长上升子序列.md +++ b/problems/0300.最长上升子序列.md @@ -141,8 +141,10 @@ class Solution { } } ``` -DP + Python: + +DP ```python class Solution: def lengthOfLIS(self, nums: List[int]) -> int: From 4fab08d0306d82aef04379ef01b9b08aae65543a Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Tue, 6 Jun 2023 19:09:57 -0400 Subject: [PATCH 31/58] =?UTF-8?q?=E6=8F=90=E4=BE=9BJAVA=E7=9A=842*2?= =?UTF-8?q?=E6=95=B8=E7=B5=84=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原本的空間優化是直接優化成一維數組,故提供一個2*2數組的版本 --- problems/0121.买卖股票的最佳时机.md | 25 +++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md index 753cb106..794185da 100644 --- a/problems/0121.买卖股票的最佳时机.md +++ b/problems/0121.买卖股票的最佳时机.md @@ -243,8 +243,27 @@ class Solution { } } ``` +> 动态规划:版本二(使用二維數組(和卡哥思路一致),下面還有使用一維滾動數組的更優化版本) -> 动态规划:版本二 +```Java +class Solution { + public int maxProfit(int[] prices) { + int len = prices.length; + int dp[][] = new int[2][2]; + + dp[0][0] = - prices[0]; + dp[0][1] = 0; + + for (int i = 1; i < len; i++){ + dp[i % 2][0] = Math.max(dp[(i - 1) % 2][0], - prices[i]); + dp[i % 2][1] = Math.max(dp[(i - 1) % 2][1], prices[i] + dp[(i - 1) % 2][0]); + } + return dp[(len - 1) % 2][1]; + } +} +``` + +> 动态规划:版本二(使用一維數組) ``` java class Solution { @@ -271,6 +290,10 @@ class Solution { } } ``` +```Java + +``` + Python: From 9287b6be6f3dbcae30e3d5e8c636af24b41a3a7c Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Tue, 6 Jun 2023 19:25:22 -0400 Subject: [PATCH 32/58] =?UTF-8?q?=E6=96=B0=E5=A2=9EJAVA=202*2=E6=95=B8?= =?UTF-8?q?=E7=B5=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit //DP using 2*2 Array (下方還有使用一維滾動數組的更優化版本) --- ...股票的最佳时机II(动态规划).md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/0122.买卖股票的最佳时机II(动态规划).md b/problems/0122.买卖股票的最佳时机II(动态规划).md index 146c6a4c..70ab8364 100644 --- a/problems/0122.买卖股票的最佳时机II(动态规划).md +++ b/problems/0122.买卖股票的最佳时机II(动态规划).md @@ -154,7 +154,24 @@ class Solution } } ``` +```java +//DP using 2*2 Array (下方還有使用一維滾動數組的更優化版本) +class Solution { + public int maxProfit(int[] prices) { + int dp[][] = new int [2][2]; + //dp[i][0]: holding the stock + //dp[i][1]: not holding the stock + dp[0][0] = - prices[0]; + dp[0][1] = 0; + for(int i = 1; i < prices.length; i++){ + dp[i % 2][0] = Math.max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] - prices[i]); + dp[i % 2][1] = Math.max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i]); + } + return dp[(prices.length - 1) % 2][1]; + } +} +``` ```java // 优化空间 class Solution { From c652187f747a2b7546f45e0f29cc985b929a8454 Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Wed, 7 Jun 2023 03:59:52 -0500 Subject: [PATCH 33/58] =?UTF-8?q?Update=200674.=E6=9C=80=E9=95=BF=E8=BF=9E?= =?UTF-8?q?=E7=BB=AD=E9=80=92=E5=A2=9E=E5=BA=8F=E5=88=97.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0674.最长连续递增序列.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/problems/0674.最长连续递增序列.md b/problems/0674.最长连续递增序列.md index 79a8311d..0d9866a0 100644 --- a/problems/0674.最长连续递增序列.md +++ b/problems/0674.最长连续递增序列.md @@ -204,7 +204,7 @@ public static int findLengthOfLCIS(int[] nums) { Python: -> 动态规划: +DP ```python class Solution: def findLengthOfLCIS(self, nums: List[int]) -> int: @@ -219,8 +219,27 @@ class Solution: return result ``` +DP(优化版) +```python +class Solution: + def findLengthOfLCIS(self, nums: List[int]) -> int: + if not nums: + return 0 -> 贪心法: + max_length = 1 + current_length = 1 + + for i in range(1, len(nums)): + if nums[i] > nums[i - 1]: + current_length += 1 + max_length = max(max_length, current_length) + else: + current_length = 1 + + return max_length + +``` +贪心 ```python class Solution: def findLengthOfLCIS(self, nums: List[int]) -> int: From 8fb169701478cce21d5bfba761289479a0e27fbd Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Wed, 7 Jun 2023 05:26:40 -0500 Subject: [PATCH 34/58] =?UTF-8?q?Update=200718.=E6=9C=80=E9=95=BF=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E5=AD=90=E6=95=B0=E7=BB=84.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0718.最长重复子数组.md | 96 +++++++++++++++++++++----- 1 file changed, 79 insertions(+), 17 deletions(-) diff --git a/problems/0718.最长重复子数组.md b/problems/0718.最长重复子数组.md index 08be6732..78ef7ddd 100644 --- a/problems/0718.最长重复子数组.md +++ b/problems/0718.最长重复子数组.md @@ -247,37 +247,99 @@ class Solution { Python: -> 动态规划: +2维DP ```python class Solution: - def findLength(self, A: List[int], B: List[int]) -> int: - dp = [[0] * (len(B)+1) for _ in range(len(A)+1)] + def findLength(self, nums1: List[int], nums2: List[int]) -> int: + # 创建一个二维数组 dp,用于存储最长公共子数组的长度 + dp = [[0] * (len(nums2) + 1) for _ in range(len(nums1) + 1)] + # 记录最长公共子数组的长度 result = 0 - for i in range(1, len(A)+1): - for j in range(1, len(B)+1): - if A[i-1] == B[j-1]: - dp[i][j] = dp[i-1][j-1] + 1 - result = max(result, dp[i][j]) + + # 遍历数组 nums1 + for i in range(1, len(nums1) + 1): + # 遍历数组 nums2 + for j in range(1, len(nums2) + 1): + # 如果 nums1[i-1] 和 nums2[j-1] 相等 + if nums1[i - 1] == nums2[j - 1]: + # 在当前位置上的最长公共子数组长度为前一个位置上的长度加一 + dp[i][j] = dp[i - 1][j - 1] + 1 + # 更新最长公共子数组的长度 + if dp[i][j] > result: + result = dp[i][j] + + # 返回最长公共子数组的长度 return result + ``` -> 动态规划:滚动数组 +1维DP ```python class Solution: - def findLength(self, A: List[int], B: List[int]) -> int: - dp = [0] * (len(B) + 1) + def findLength(self, nums1: List[int], nums2: List[int]) -> int: + # 创建一个一维数组 dp,用于存储最长公共子数组的长度 + dp = [0] * (len(nums2) + 1) + # 记录最长公共子数组的长度 result = 0 - for i in range(1, len(A)+1): - for j in range(len(B), 0, -1): - if A[i-1] == B[j-1]: - dp[j] = dp[j-1] + 1 + + # 遍历数组 nums1 + for i in range(1, len(nums1) + 1): + # 用于保存上一个位置的值 + prev = 0 + # 遍历数组 nums2 + for j in range(1, len(nums2) + 1): + # 保存当前位置的值,因为会在后面被更新 + current = dp[j] + # 如果 nums1[i-1] 和 nums2[j-1] 相等 + if nums1[i - 1] == nums2[j - 1]: + # 在当前位置上的最长公共子数组长度为上一个位置的长度加一 + dp[j] = prev + 1 + # 更新最长公共子数组的长度 + if dp[j] > result: + result = dp[j] else: - dp[j] = 0 #注意这里不相等的时候要有赋0的操作 - result = max(result, dp[j]) + # 如果不相等,将当前位置的值置为零 + dp[j] = 0 + # 更新 prev 变量为当前位置的值,供下一次迭代使用 + prev = current + + # 返回最长公共子数组的长度 return result + ``` +2维DP 扩展 +```python +class Solution: + def findLength(self, nums1: List[int], nums2: List[int]) -> int: + # 创建一个二维数组 dp,用于存储最长公共子数组的长度 + dp = [[0] * (len(nums2) + 1) for _ in range(len(nums1) + 1)] + # 记录最长公共子数组的长度 + result = 0 + # 对第一行和第一列进行初始化 + for i in range(len(nums1)): + if nums1[i] == nums2[0]: + dp[i + 1][1] = 1 + for j in range(len(nums2)): + if nums1[0] == nums2[j]: + dp[1][j + 1] = 1 + + # 填充dp数组 + for i in range(1, len(nums1) + 1): + for j in range(1, len(nums2) + 1): + if nums1[i - 1] == nums2[j - 1]: + # 如果 nums1[i-1] 和 nums2[j-1] 相等,则当前位置的最长公共子数组长度为左上角位置的值加一 + dp[i][j] = dp[i - 1][j - 1] + 1 + if dp[i][j] > result: + # 更新最长公共子数组的长度 + result = dp[i][j] + + # 返回最长公共子数组的长度 + return result + + +``` Go: ```Go func findLength(A []int, B []int) int { From 0a742d83a49e942324163fc0e7642cd1dfd7010f Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Wed, 7 Jun 2023 05:32:55 -0500 Subject: [PATCH 35/58] =?UTF-8?q?Update=201143.=E6=9C=80=E9=95=BF=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E5=AD=90=E5=BA=8F=E5=88=97.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1143.最长公共子序列.md | 48 ++++++++++++++++++++------ 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/problems/1143.最长公共子序列.md b/problems/1143.最长公共子序列.md index 730e9ad1..4b712569 100644 --- a/problems/1143.最长公共子序列.md +++ b/problems/1143.最长公共子序列.md @@ -198,21 +198,49 @@ class Solution { ``` Python: - +2维DP ```python class Solution: def longestCommonSubsequence(self, text1: str, text2: str) -> int: - len1, len2 = len(text1)+1, len(text2)+1 - dp = [[0 for _ in range(len1)] for _ in range(len2)] # 先对dp数组做初始化操作 - for i in range(1, len2): - for j in range(1, len1): # 开始列出状态转移方程 - if text1[j-1] == text2[i-1]: - dp[i][j] = dp[i-1][j-1]+1 + # 创建一个二维数组 dp,用于存储最长公共子序列的长度 + dp = [[0] * (len(text2) + 1) for _ in range(len(text1) + 1)] + + # 遍历 text1 和 text2,填充 dp 数组 + for i in range(1, len(text1) + 1): + for j in range(1, len(text2) + 1): + if text1[i - 1] == text2[j - 1]: + # 如果 text1[i-1] 和 text2[j-1] 相等,则当前位置的最长公共子序列长度为左上角位置的值加一 + dp[i][j] = dp[i - 1][j - 1] + 1 else: - dp[i][j] = max(dp[i-1][j], dp[i][j-1]) - return dp[-1][-1] -``` + # 如果 text1[i-1] 和 text2[j-1] 不相等,则当前位置的最长公共子序列长度为上方或左方的较大值 + dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + + # 返回最长公共子序列的长度 + return dp[len(text1)][len(text2)] +``` +1维DP +```python +class Solution: + def longestCommonSubsequence(self, text1: str, text2: str) -> int: + m, n = len(text1), len(text2) + dp = [0] * (n + 1) # 初始化一维DP数组 + + for i in range(1, m + 1): + prev = 0 # 保存上一个位置的最长公共子序列长度 + for j in range(1, n + 1): + curr = dp[j] # 保存当前位置的最长公共子序列长度 + if text1[i - 1] == text2[j - 1]: + # 如果当前字符相等,则最长公共子序列长度加一 + dp[j] = prev + 1 + else: + # 如果当前字符不相等,则选择保留前一个位置的最长公共子序列长度中的较大值 + dp[j] = max(dp[j], dp[j - 1]) + prev = curr # 更新上一个位置的最长公共子序列长度 + + return dp[n] # 返回最后一个位置的最长公共子序列长度作为结果 + +``` Go: ```Go From 17a01cecefcdb2b71806a56bc6789686bcb755ac Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Thu, 8 Jun 2023 17:38:49 -0400 Subject: [PATCH 36/58] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=E8=A8=BB=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增java註解 if statement的解釋 --- problems/0070.爬楼梯完全背包版本.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/problems/0070.爬楼梯完全背包版本.md b/problems/0070.爬楼梯完全背包版本.md index 8f8bc9a6..bc5e3509 100644 --- a/problems/0070.爬楼梯完全背包版本.md +++ b/problems/0070.爬楼梯完全背包版本.md @@ -133,12 +133,13 @@ Java: class Solution { public int climbStairs(int n) { int[] dp = new int[n + 1]; - int m = 2; + int m = 2; //有兩個物品:itme1重量爲一,item2重量爲二 dp[0] = 1; for (int i = 1; i <= n; i++) { // 遍历背包 for (int j = 1; j <= m; j++) { //遍历物品 - if (i >= j) dp[i] += dp[i - j]; + if (i >= j) //當前的背包容量 大於 物品重量的時候,我們才需要記錄當前的這個裝得方法(方法數+) + dp[i] += dp[i - j]; } } From 652fa2bbb0a43799365df33544bf13638a6b8d20 Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Fri, 9 Jun 2023 18:11:29 -0400 Subject: [PATCH 37/58] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=202*2=20array=20so?= =?UTF-8?q?lution?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...佳时机含手续费(动态规划).md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md index 12789934..1443f147 100644 --- a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md +++ b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md @@ -154,6 +154,25 @@ class Solution { return dp[1]; } } +```Java +//使用 2*2 array +class Solution { + public int maxProfit(int[] prices, int fee) { + int dp[][] = new int[2][2]; + int len = prices.length; + //[i][0] = holding the stock + //[i][1] = not holding the stock + dp[0][0] = -prices[0]; + + for(int i = 1; i < len; i++){ + dp[i % 2][0] = Math.max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] - prices[i]); + dp[i % 2][1] = Math.max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][0] + prices[i] - fee); + } + + return dp[(len - 1) % 2][1]; + } +} +``` ``` Python: From 88162c3a77ad266002158c448a6dc4f934bb9dc6 Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Fri, 9 Jun 2023 18:27:21 -0400 Subject: [PATCH 38/58] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=202*4=20solution?= =?UTF-8?q?=20=E4=B8=A6=E9=99=84=E4=B8=8A=20=E5=B0=8D=E6=96=BC2-D=20array,?= =?UTF-8?q?=201-D=20array=E7=9A=84=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...09.最佳买卖股票时机含冷冻期.md | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/problems/0309.最佳买卖股票时机含冷冻期.md b/problems/0309.最佳买卖股票时机含冷冻期.md index a56d9b84..83cd448a 100644 --- a/problems/0309.最佳买卖股票时机含冷冻期.md +++ b/problems/0309.最佳买卖股票时机含冷冻期.md @@ -200,7 +200,33 @@ class Solution { } } ``` - +```java +//using 2*4 array for space optimization +//這裡稍微說一下,我在LeetCode提交的時候,2*4 2-D array的performance基本上和下面的1-D array performance差不多 +//都是time: 1ms, space: 40.X MB (其實 length*4 的 2-D array也僅僅是space:41.X MB,看起來不多) +//股票累的DP題目大致上都是這樣,就當作是一個延伸就好了。真的有人問如何優化,最起碼有東西可以講。 +class Solution { + /** + 1. [i][0] holding the stock + 2. [i][1] after cooldown but stil not buing the stock + 3. [i][2] selling the stock + 4. [i][3] cooldown + */ + public int maxProfit(int[] prices) { + int len = prices.length; + int dp[][] = new int [2][4]; + dp[0][0] = -prices[0]; + + for(int i = 1; i < len; i++){ + dp[i % 2][0] = Math.max(Math.max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] - prices[i]), dp[(i - 1) % 2][3] - prices[i]); + dp[i % 2][1] = Math.max(dp[(i - 1) % 2][1], dp[(i - 1) % 2][3]); + dp[i % 2][2] = dp[(i - 1) % 2][0] + prices[i]; + dp[i % 2][3] = dp[(i - 1) % 2][2]; + } + return Math.max(Math.max(dp[(len - 1) % 2][1], dp[(len - 1) % 2][2]), dp[(len - 1) % 2][3]); + } +} +``` ```java // 一维数组优化 class Solution { From a32bbeb71a37153276d69412526819493ffe3bd5 Mon Sep 17 00:00:00 2001 From: Feegg <1468434504@qq.com> Date: Sun, 11 Jun 2023 02:13:01 +0800 Subject: [PATCH 39/58] =?UTF-8?q?=E5=AF=B90707=E8=AE=BE=E8=AE=A1=E9=93=BE?= =?UTF-8?q?=E8=A1=A8=EF=BC=8Cgo=E7=89=88=E6=9C=AC=E5=8D=95=E9=93=BE?= =?UTF-8?q?=E8=A1=A8=E5=81=9A=E4=BA=86=E4=BF=AE=E6=94=B9=EF=BC=8C=E5=8E=9F?= =?UTF-8?q?=E6=9D=A5=E7=89=88=E6=9C=AC=E6=B2=A1=E6=9C=89=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E9=93=BE=E8=A1=A8=E6=8C=87=E5=AE=9Aindex=E4=B8=8B=E6=A0=87?= =?UTF-8?q?=E7=9A=84=E6=96=B9=E6=B3=95=EF=BC=8C=E5=B9=B6=E4=B8=94=E5=B7=B2?= =?UTF-8?q?=E6=9C=89=E7=9A=84=E5=9C=A8leetcode=E6=89=A7=E8=A1=8C=E6=9C=89?= =?UTF-8?q?=E8=AF=AF=EF=BC=8C=E5=81=9A=E4=BA=86=E4=BF=AE=E6=94=B9=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=8C=E5=9F=BA=E4=BA=8E=E5=8E=9F=E6=9D=A5=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0707.设计链表.md | 152 ++++++++++++++++++++-------------- 1 file changed, 90 insertions(+), 62 deletions(-) diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md index aa04d0e1..b9f27952 100644 --- a/problems/0707.设计链表.md +++ b/problems/0707.设计链表.md @@ -663,100 +663,128 @@ Go: //单链表实现 package main -import "fmt" - -func main() { - var list = new(SingleLinkedList) - list.Init() - list.addAtHead(100) - list.addAtTail(242) - list.addAtTail(777) - list.addAtIndex(1, 99999) - list.printLinkedList() -} - -// 单链表写法 // +import ( + "fmt" +) type SingleNode struct { - Val int - Next *SingleNode + Val int // 节点的值 + Next *SingleNode // 下一个节点的指针 } -type SingleLinkedList struct { - dummyHead *SingleNode - Size int +type MyLinkedList struct { + dummyHead *SingleNode // 虚拟头节点 + Size int // 链表大小 } -// 初始化链表 -func (list *SingleLinkedList) Init() *SingleLinkedList { - list.Size = 0 - list.dummyHead = new(SingleNode) - return list +func main() { + list := Constructor() // 初始化链表 + list.AddAtHead(100) // 在头部添加元素 + list.AddAtTail(242) // 在尾部添加元素 + list.AddAtTail(777) // 在尾部添加元素 + list.AddAtIndex(1, 99999) // 在指定位置添加元素 + list.printLinkedList() // 打印链表 } -// 获取第index个节点数值 -func (list *SingleLinkedList) get(index int) int { - if list != nil || index < 0 || index > list.Size { +/** Initialize your data structure here. */ +func Constructor() MyLinkedList { + newNode := &SingleNode{ // 创建新节点 + -999, + nil, + } + return MyLinkedList{ // 返回链表 + dummyHead: newNode, + Size: 0, + } + +} + +/** Get the value of the index-th node in the linked list. If the index is + invalid, return -1. */ +func (this *MyLinkedList) Get(index int) int { + /*if this != nil || index < 0 || index > this.Size { + return -1 + }*/ + if this == nil || index < 0 || index >= this.Size { // 如果索引无效则返回-1 return -1 } // 让cur等于真正头节点 - cur := list.dummyHead.Next - for i := 0; i < index; i++ { + cur := this.dummyHead.Next // 设置当前节点为真实头节点 + for i := 0; i < index; i++ { // 遍历到索引所在的节点 cur = cur.Next } - return cur.Val + return cur.Val // 返回节点值 } -// 在链表最前面插入一个节点 -func (list *SingleLinkedList) addAtHead(val int) { +/** Add a node of value val before the first element of the linked list. After + the insertion, the new node will be the first node of the linked list. */ +func (this *MyLinkedList) AddAtHead(val int) { // 以下两行代码可用一行代替 // newNode := new(SingleNode) // newNode.Val = val - newNode := &SingleNode{Val: val} - - newNode.Next = list.dummyHead.Next - list.dummyHead.Next = newNode - list.Size++ + newNode := &SingleNode{Val: val} // 创建新节点 + newNode.Next = this.dummyHead.Next // 新节点指向当前头节点 + this.dummyHead.Next = newNode // 新节点变为头节点 + this.Size++ // 链表大小增加1 } -// 在链表最后面插入一个节点 -func (list *SingleLinkedList) addAtTail(val int) { - newNode := &SingleNode{Val: val} - cur := list.dummyHead - for cur.Next != nil { +/** Append a node of value val to the last element of the linked list. */ +func (this *MyLinkedList) AddAtTail(val int) { + newNode := &SingleNode{Val: val} // 创建新节点 + cur := this.dummyHead // 设置当前节点为虚拟头节点 + for cur.Next != nil { // 遍历到最后一个节点 cur = cur.Next } - cur.Next = newNode - list.Size++ + cur.Next = newNode // 在尾部添加新节点 + this.Size++ // 链表大小增加1 } -// 打印链表 -func (list *SingleLinkedList) printLinkedList() { - cur := list.dummyHead - for cur.Next != nil { - fmt.Println(cur.Next.Val) - cur = cur.Next - } -} - -// 在第index个节点之前插入新节点 -func (list *SingleLinkedList) addAtIndex(index int, val int) { - if index < 0 { +/** Add a node of value val before the index-th node in the linked list. If + index equals to the length of linked list, the node will be appended to the + end of linked list. If index is greater than the length, the node will not be + inserted. */ +func (this *MyLinkedList) AddAtIndex(index int, val int) { + if index < 0 { // 如果索引小于0,设置为0 index = 0 - } else if index > list.Size { + } else if index > this.Size { // 如果索引大于链表长度,直接返回 return } - newNode := &SingleNode{Val: val} - cur := list.dummyHead //用虚拟头节点不用考虑在头部插入的情况 - for i := 0; i < index; i++ { + newNode := &SingleNode{Val: val} // 创建新节点 + cur := this.dummyHead // 设置当前节点为虚拟头节点 + for i := 0; i < index; i++ { // 遍历到指定索引的前一个节点 cur = cur.Next } - newNode.Next = cur.Next - cur.Next = newNode - list.Size++ + newNode.Next = cur.Next // 新节点指向原索引节点 + cur.Next = newNode // 原索引的前一个节点指向新节点 + this.Size++ // 链表大小增加1 } +/** Delete the index-th node in the linked list, if the index is valid. */ +func (this *MyLinkedList) DeleteAtIndex(index int) { + if index < 0 || index >= this.Size { // 如果索引无效则直接返回 + return + } + cur := this.dummyHead // 设置当前节点为虚拟头节点 + for i := 0; i < index; i++ { // 遍历到要删除节点的前一个节点 + cur = cur.Next + } + if cur.Next != nil { + cur.Next = cur.Next.Next // 当前节点直接指向下下个节点,即删除了下一个节点 + } + this.Size-- // 注意删除节点后应将链表大小减一 +} + +// 打印链表 +func (list *MyLinkedList) printLinkedList() { + cur := list.dummyHead // 设置当前节点为虚拟头节点 + for cur.Next != nil { // 遍历链表 + fmt.Println(cur.Next.Val) // 打印节点值 + cur = cur.Next // 切换到下一个节点 + } +} + + ``` ```go From 50ed10475df9c62dae9e149a867a6f083a0dde04 Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Mon, 12 Jun 2023 01:59:52 -0500 Subject: [PATCH 40/58] =?UTF-8?q?Update=200746.=E4=BD=BF=E7=94=A8=E6=9C=80?= =?UTF-8?q?=E5=B0=8F=E8=8A=B1=E8=B4=B9=E7=88=AC=E6=A5=BC=E6=A2=AF.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0746.使用最小花费爬楼梯.md | 28 ++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/problems/0746.使用最小花费爬楼梯.md b/problems/0746.使用最小花费爬楼梯.md index cd5e40e6..9eaaa4e9 100644 --- a/problems/0746.使用最小花费爬楼梯.md +++ b/problems/0746.使用最小花费爬楼梯.md @@ -282,7 +282,35 @@ class Solution: return dp1 # 返回到达楼顶的最小花费 ``` +动态规划(版本三) +```python +class Solution: + def minCostClimbingStairs(self, cost: List[int]) -> int: + dp = [0] * len(cost) + dp[0] = cost[0] # 第一步有花费 + dp[1] = cost[1] + for i in range(2, len(cost)): + dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i] + # 注意最后一步可以理解为不用花费,所以取倒数第一步,第二步的最少值 + return min(dp[-1], dp[-2]) + +``` +动态规划(版本四) + +```python +class Solution: + def minCostClimbingStairs(self, cost: List[int]) -> int: + n = len(cost) + prev_1 = cost[0] # 前一步的最小花费 + prev_2 = cost[1] # 前两步的最小花费 + for i in range(2, n): + current = min(prev_1, prev_2) + cost[i] # 当前位置的最小花费 + prev_1, prev_2 = prev_2, current # 更新前一步和前两步的最小花费 + return min(prev_1, prev_2) # 最后一步可以理解为不用花费,取倒数第一步和第二步的最少值 + + +``` ### Go ```Go func minCostClimbingStairs(cost []int) int { From 5527410f890ecfccdb017ce5aa5fc902328ab922 Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Mon, 12 Jun 2023 02:59:20 -0500 Subject: [PATCH 41/58] =?UTF-8?q?Update=200063.=E4=B8=8D=E5=90=8C=E8=B7=AF?= =?UTF-8?q?=E5=BE=84II.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0063.不同路径II.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/problems/0063.不同路径II.md b/problems/0063.不同路径II.md index 7b5b44f0..cb305b41 100644 --- a/problems/0063.不同路径II.md +++ b/problems/0063.不同路径II.md @@ -397,7 +397,39 @@ class Solution: ``` +动态规划(版本五) +```python +class Solution: + def uniquePathsWithObstacles(self, obstacleGrid): + if obstacleGrid[0][0] == 1: + return 0 + + m, n = len(obstacleGrid), len(obstacleGrid[0]) + + dp = [0] * n # 创建一个一维列表用于存储路径数 + + # 初始化第一行的路径数 + for j in range(n): + if obstacleGrid[0][j] == 1: + break + dp[j] = 1 + + # 计算其他行的路径数 + for i in range(1, m): + if obstacleGrid[i][0] == 1: + dp[0] = 0 + for j in range(1, n): + if obstacleGrid[i][j] == 1: + dp[j] = 0 + continue + + dp[j] += dp[j - 1] + + return dp[-1] # 返回最后一个元素,即终点的路径数 + + +``` ### Go ```go From 072eb2aa471f025afdb690e57a23c0932b5a4697 Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Mon, 12 Jun 2023 03:32:07 -0500 Subject: [PATCH 42/58] =?UTF-8?q?Update=200343.=E6=95=B4=E6=95=B0=E6=8B=86?= =?UTF-8?q?=E5=88=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0343.整数拆分.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/problems/0343.整数拆分.md b/problems/0343.整数拆分.md index d70641db..3ff8dedb 100644 --- a/problems/0343.整数拆分.md +++ b/problems/0343.整数拆分.md @@ -262,10 +262,11 @@ class Solution: # 计算切割点j和剩余部分(i-j)的乘积,并与之前的结果进行比较取较大值 - dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j)) + dp[i] = max(dp[i], (i - j) * j, dp[i - j] * j) return dp[n] # 返回最终的计算结果 + ``` 动态规划(版本二) ```python From b1e8b17eb1bfd4e620b49037154693d4f9188a96 Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Wed, 14 Jun 2023 18:30:56 -0400 Subject: [PATCH 43/58] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=E4=B8=80=E7=B6=AD?= =?UTF-8?q?=E6=95=B8=E7=B5=84=E8=A7=A3=E6=B3=95=EF=BC=88=E5=BE=88=E5=8D=A1?= =?UTF-8?q?=E5=93=A5=E9=82=8F=E8=BC=AF=E4=B8=80=E8=87=B4=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原本的那個版本不知道在寫什麼 --- .../0188.买卖股票的最佳时机IV.md | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/problems/0188.买卖股票的最佳时机IV.md b/problems/0188.买卖股票的最佳时机IV.md index 5bed5ecc..14f514a9 100644 --- a/problems/0188.买卖股票的最佳时机IV.md +++ b/problems/0188.买卖股票的最佳时机IV.md @@ -227,7 +227,7 @@ class Solution { } } -//版本三:一维 dp数组 +//版本三:一维 dp数组 (下面有和卡哥邏輯一致的一維數組JAVA解法) class Solution { public int maxProfit(int k, int[] prices) { if(prices.length == 0){ @@ -259,6 +259,41 @@ class Solution { } } ``` +```JAVA +class Solution { + public int maxProfit(int k, int[] prices) { + + //edge cases + if(prices.length == 0 || k == 0) + return 0; + + + int dp[] = new int [k * 2 + 1]; + + //和卡哥邏輯一致,奇數天購入股票,故初始化只初始化奇數天。 + for(int i = 1; i < 2 * k + 1; i += 2){ + dp[i] = -prices[0]; + } + + for(int i = 1; i < prices.length; i++){ //i 從 1 開始,因爲第 i = 0 天已經透過初始化完成了。 + for(int j = 1; j < 2 * k + 1; j++){ //j 從 1 開始,因爲第 j = 0 天已經透過初始化完成了。 + //奇數天購買 + if(j % 2 == 1) + dp[j] = Math.max(dp[j], dp[j - 1] - prices[i]); + //偶數天賣出 + else + dp[j] = Math.max(dp[j], dp[j - 1] + prices[i]); + } + //打印DP數組 + //for(int x : dp) + // System.out.print(x +", "); + //System.out.println(); + } + //return 第2 * k次賣出的獲利。 + return dp[2 * k]; + } +} +``` Python: From 9c1988edec9d6eeca9db1bd558ad16410f40eaf6 Mon Sep 17 00:00:00 2001 From: Binbin Date: Thu, 15 Jun 2023 19:32:34 +0800 Subject: [PATCH 44/58] =?UTF-8?q?=E9=94=99=E5=88=AB=E5=AD=97=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=EF=BC=9A=E5=B7=B2=E7=BB=8F=E5=A1=AB=E5=9C=A8=E7=9A=84?= =?UTF-8?q?=E5=AD=90=E4=B8=B2=20->=20=E5=B7=B2=E7=BB=8F=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=9A=84=E5=AD=90=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0131.分割回文串.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md index 636cf59c..92fed58a 100644 --- a/problems/0131.分割回文串.md +++ b/problems/0131.分割回文串.md @@ -118,7 +118,7 @@ for (int i = startIndex; i < s.size(); i++) { continue; } backtracking(s, i + 1); // 寻找i+1为起始位置的子串 - path.pop_back(); // 回溯过程,弹出本次已经填在的子串 + path.pop_back(); // 回溯过程,弹出本次已经添加的子串 } ``` @@ -189,7 +189,7 @@ private: continue; } backtracking(s, i + 1); // 寻找i+1为起始位置的子串 - path.pop_back(); // 回溯过程,弹出本次已经填在的子串 + path.pop_back(); // 回溯过程,弹出本次已经添加的子串 } } bool isPalindrome(const string& s, int start, int end) { @@ -245,7 +245,7 @@ private: continue; } backtracking(s, i + 1); // 寻找i+1为起始位置的子串 - path.pop_back(); // 回溯过程,弹出本次已经填在的子串 + path.pop_back(); // 回溯过程,弹出本次已经添加的子串 } } void computePalindrome(const string& s) { @@ -437,7 +437,7 @@ class Solution: substring = s[startIndex:i + 1] path.append(substring) self.backtracking(s, i + 1, path, result, isPalindrome) # 寻找i+1为起始位置的子串 - path.pop() # 回溯过程,弹出本次已经填在的子串 + path.pop() # 回溯过程,弹出本次已经添加的子串 def computePalindrome(self, s, isPalindrome): for i in range(len(s) - 1, -1, -1): # 需要倒序计算,保证在i行时,i+1行已经计算好了 @@ -497,7 +497,7 @@ func dfs(s string, start int) { if isPalindrome(str) { // 是回文子串 path = append(path, str) dfs(s, i+1) // 寻找i+1为起始位置的子串 - path = path[:len(path)-1] // 回溯过程,弹出本次已经填在的子串 + path = path[:len(path)-1] // 回溯过程,弹出本次已经添加的子串 } } } From 3becfab93f477723e4c3aee75da45989bebd0bb6 Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:58:09 -0400 Subject: [PATCH 45/58] =?UTF-8?q?=E8=AA=AA=E6=98=8EJAVA=20code=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E6=B3=A8=E6=84=8F=E7=9A=84=E5=9C=B0=E6=96=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0674.最长连续递增序列.md | 1 + 1 file changed, 1 insertion(+) diff --git a/problems/0674.最长连续递增序列.md b/problems/0674.最长连续递增序列.md index 81f02ace..8cc270ec 100644 --- a/problems/0674.最长连续递增序列.md +++ b/problems/0674.最长连续递增序列.md @@ -177,6 +177,7 @@ Java: dp[i] = 1; } int res = 1; + //可以注意到,這邊的 i 是從 0 開始,所以會出現和卡哥的C++ code有差異的地方,在一些地方會看到有 i + 1 的偏移。 for (int i = 0; i < nums.length - 1; i++) { if (nums[i + 1] > nums[i]) { dp[i + 1] = dp[i] + 1; From 018c9cb96399a5005f6ed42e0eb69ebc07f24d97 Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Thu, 15 Jun 2023 18:46:08 -0400 Subject: [PATCH 46/58] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=202-D=20array=20?= =?UTF-8?q?=E5=BB=BA=E8=AD=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1143.最长公共子序列.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/problems/1143.最长公共子序列.md b/problems/1143.最长公共子序列.md index 2b5eed3d..68269b87 100644 --- a/problems/1143.最长公共子序列.md +++ b/problems/1143.最长公共子序列.md @@ -144,6 +144,11 @@ Java: */ class Solution { public int longestCommonSubsequence(String text1, String text2) { + // char[] char1 = text1.toCharArray(); + // char[] char2 = text2.toCharArray(); + // 可以在一開始的時候就先把text1, text2 轉成char[],之後就不需要有這麼多爲了處理字串的調整 + // 就可以和卡哥的code更一致 + int[][] dp = new int[text1.length() + 1][text2.length() + 1]; // 先对dp数组做初始化操作 for (int i = 1 ; i <= text1.length() ; i++) { char char1 = text1.charAt(i - 1); From 342e7a597eb50c1570fdd713a237b761ab777bd6 Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Fri, 16 Jun 2023 20:58:06 -0400 Subject: [PATCH 47/58] =?UTF-8?q?=E5=8A=A0=E5=85=A5B=E7=AB=99=E8=A6=96?= =?UTF-8?q?=E9=A0=BB=E7=B6=B2=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0583.两个字符串的删除操作.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/problems/0583.两个字符串的删除操作.md b/problems/0583.两个字符串的删除操作.md index 561ad2f2..054f452b 100644 --- a/problems/0583.两个字符串的删除操作.md +++ b/problems/0583.两个字符串的删除操作.md @@ -14,10 +14,15 @@ * 输入: "sea", "eat" * 输出: 2 -* 解释: 第一步将"sea"变为"ea",第二步将"eat"变为"ea" +* 解释: 第一步将"sea"变为"ea",第二步将"eat"变为"ea" + + +# 算法公开课 + +**《代码随想录》算法视频公开课:[动态规划之子序列,还是为了编辑距离做铺垫 | LeetCode:583.两个字符串的删除操(https://www.bilibili.com/video/BV1we4y157wB/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 + ## 思路 - ### 动态规划一 本题和[动态规划:115.不同的子序列](https://programmercarl.com/0115.不同的子序列.html)相比,其实就是两个字符串都可以删除了,情况虽说复杂一些,但整体思路是不变的。 From c25a76587ec1028b0ab80607c2dcd14a15f18475 Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Fri, 16 Jun 2023 21:23:27 -0400 Subject: [PATCH 48/58] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=EF=BC=9A=E7=94=A8?= =?UTF-8?q?=E6=9C=80=E9=95=B7=E5=85=AC=E5=85=B1=E5=AD=90=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8F=8D=E6=8E=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增java:用最長公共子序列反推 --- .../0583.两个字符串的删除操作.md | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/problems/0583.两个字符串的删除操作.md b/problems/0583.两个字符串的删除操作.md index 561ad2f2..3e225e82 100644 --- a/problems/0583.两个字符串的删除操作.md +++ b/problems/0583.两个字符串的删除操作.md @@ -184,6 +184,31 @@ class Solution { } } ``` +```java +//DP - longest common subsequence (用最長公共子序列反推) +class Solution { + public int minDistance(String word1, String word2) { + char[] char1 = word1.toCharArray(); + char[] char2 = word2.toCharArray(); + + int len1 = char1.length; + int len2 = char2.length; + + int dp[][] = new int [len1 + 1][len2 + 1]; + + for(int i = 1; i <= len1; i++){ + for(int j = 1; j <= len2; j++){ + if(char1[i - 1] == char2[j - 1]) + dp[i][j] = dp[i - 1][j - 1] + 1; + else + dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); + } + } + + return len1 + len2 - (2 * dp[len1][len2]);//和leetcode 1143只差在這一行。 + } +} +``` Python: From 517d9def4429b836bdb8e890d5f46309b0d7c0d0 Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Sun, 18 Jun 2023 18:39:06 -0400 Subject: [PATCH 49/58] =?UTF-8?q?=E6=96=B0=E5=A2=9EB=E7=AB=99=E5=BD=B1?= =?UTF-8?q?=E7=89=87=E7=B6=B2=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增B站影片網址 --- problems/0072.编辑距离.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/problems/0072.编辑距离.md b/problems/0072.编辑距离.md index cc4ab00c..703e8913 100644 --- a/problems/0072.编辑距离.md +++ b/problems/0072.编辑距离.md @@ -40,6 +40,8 @@ exection -> execution (插入 'u') * 0 <= word1.length, word2.length <= 500 * word1 和 word2 由小写英文字母组成 +# 算法公开课 +**《代码随想录》算法视频公开课:[动态规划终极绝杀! LeetCode:72.编辑距离](https://www.bilibili.com/video/BV1we4y157wB/),相信结合视频再看本篇题解,更有助于大家对本题的理解**。 ## 思路 From 080dd35c79d0f4fe670ee0dd049c8422d67f94be Mon Sep 17 00:00:00 2001 From: Logen <47022821+Logenleedev@users.noreply.github.com> Date: Tue, 20 Jun 2023 08:15:43 +0800 Subject: [PATCH 50/58] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0047.全排列II.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0047.全排列II.md b/problems/0047.全排列II.md index 6999b732..afede33a 100644 --- a/problems/0047.全排列II.md +++ b/problems/0047.全排列II.md @@ -101,7 +101,7 @@ public: // 时间复杂度: 最差情况所有元素都是唯一的。复杂度和全排列1都是 O(n! * n) 对于 n 个元素一共有 n! 中排列方案。而对于每一个答案,我们需要 O(n) 去复制最终放到 result 数组 // 空间复杂度: O(n) 回溯树的深度取决于我们有多少个元素 ``` -* 时间复杂度: O(n) +* 时间复杂度: O(n! * n) * 空间复杂度: O(n) ## 拓展 From 346e927f6c8a98594b444233dede3bca8f6ad5eb Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Tue, 20 Jun 2023 17:51:21 -0400 Subject: [PATCH 51/58] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=E8=A7=A3=E6=B3=95?= =?UTF-8?q?=20for=20leetcode=205.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增java解法 for leetcode 5. 感覺卡哥可以提一下,其實在下一偏有提到,但是真的有關聯的這一篇沒有提到:這一題稍微改一下就能通過兩題,這一點我沒有寫在這個fork上。 --- problems/0647.回文子串.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/problems/0647.回文子串.md b/problems/0647.回文子串.md index e172de54..084b9f74 100644 --- a/problems/0647.回文子串.md +++ b/problems/0647.回文子串.md @@ -304,7 +304,38 @@ class Solution { } } ``` +LeetCode 5. Longest Palindromic Substring(LeetCode 647. 同一題的思路改一下、加一點,就能通過LeetCode 5) +```java +class Solution { + public String longestPalindrome(String s) { + //題目要求要return 最長的回文連續子串,故需要記錄當前最長的連續回文子串長度、最終起點、最終終點。 + int finalStart = 0; + int finalEnd = 0; + int finalLen = 0; + char[] chars = s.toCharArray(); + int len = chars.length; + + boolean[][] dp = new boolean[len][len]; + for (int i = len - 1; i >= 0; i--) { + for (int j = i; j < len; j++) { + if (chars[i] == chars[j] && (j - i <= 1 || dp[i + 1][j - 1])) + dp[i][j] = true; + //和LeetCode 647,差別就在這個if statement。 + //如果當前[i, j]範圍內的substring是回文子串(dp[i][j]) 且(&&) 長度大於當前要記錄的最終長度(j - i + 1 > finalLen) + //我們就更新 當前最長的連續回文子串長度、最終起點、最終終點 + if (dp[i][j] && j - i + 1 > finalLen) { + finalLen = j - i + 1; + finalStart = i; + finalEnd = j; + } + } + } + //String.substring這個method的用法是[起點, 終點),包含起點,不包含終點(左閉右開區間),故終點 + 1。 + return s.substring(finalStart, finalEnd + 1); + } +} +``` Python: From 1f31f092f1ec713a6df0f7617c39bc2107a9ba5f Mon Sep 17 00:00:00 2001 From: Ao Liu <63785048+Ao-Last@users.noreply.github.com> Date: Wed, 21 Jun 2023 17:38:00 +0800 Subject: [PATCH 52/58] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=200242.=E6=9C=89?= =?UTF-8?q?=E6=95=88=E7=9A=84=E5=AD=97=E6=AF=8D=E5=BC=82=E4=BD=8D=E8=AF=8D?= =?UTF-8?q?.md=20md=E6=A0=BC=E5=BC=8F=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0242.有效的字母异位词.md | 1 + 1 file changed, 1 insertion(+) diff --git a/problems/0242.有效的字母异位词.md b/problems/0242.有效的字母异位词.md index 101dd6f2..4ea43947 100644 --- a/problems/0242.有效的字母异位词.md +++ b/problems/0242.有效的字母异位词.md @@ -163,6 +163,7 @@ class Solution(object): a_count = Counter(s) b_count = Counter(t) return a_count == b_count +``` Go: From b92fcc936e4515fd922e4f00ecfd0e0816f275b4 Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Thu, 22 Jun 2023 03:13:04 -0400 Subject: [PATCH 53/58] =?UTF-8?q?=E8=A7=A3=E6=B1=BA=E8=B7=91=E6=9D=BF?= =?UTF-8?q?=E5=95=8F=E9=A1=8C=20+=20=E6=8F=90=E4=BE=9Bjava=E8=A7=A3?= =?UTF-8?q?=E6=B3=95(=E5=92=8C=E5=8D=A1=E5=93=A5=E9=82=8F=E8=BC=AF?= =?UTF-8?q?=E4=B8=80=E8=87=B4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 跑版: 原本的code box 結束的```不見了,所以看不到結尾圖片。 新解法和原本JAVA解法的差異: 原版的應該是自己寫的DFS,邏輯大致一致,但還是有差異,故提供用卡哥C++ code改的版本 --- problems/0200.岛屿数量.深搜版.md | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/problems/0200.岛屿数量.深搜版.md b/problems/0200.岛屿数量.深搜版.md index 6d42162a..c30ace19 100644 --- a/problems/0200.岛屿数量.深搜版.md +++ b/problems/0200.岛屿数量.深搜版.md @@ -176,6 +176,48 @@ public void dfs(char[][] grid, int i, int j){ dfs(grid,i,j + 1); dfs(grid,i,j - 1); } +``` +```java +//graph - dfs (和卡哥的代碼邏輯一致) +class Solution { + boolean[][] visited; + int dir[][] = { + {0, 1}, //right + {1, 0}, //down + {-1, 0}, //up + {0, -1} //left + }; + public int numIslands(char[][] grid) { + int count = 0; + visited = new boolean[grid.length][grid[0].length]; + + for(int i = 0; i < grid.length; i++){ + for(int j = 0; j < grid[0].length; j++){ + if(visited[i][j] == false && grid[i][j] == '1'){ + count++; + dfs(grid, i, j); + } + } + } + return count; + } + + private void dfs(char[][]grid, int x, int y){ + if(visited[x][y] == true || grid[x][y] == '0') + return; + + visited[x][y] = true; + + for(int i = 0; i < 4; i++){ + int nextX = x + dir[i][0]; + int nextY = y + dir[i][1]; + if(nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) + continue; + dfs(grid, nextX, nextY); + } + } +} +```

From 35a87bd56c87a642cd28f119be3814fe0e1bf63f Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:14:15 -0500 Subject: [PATCH 54/58] =?UTF-8?q?Update=200416.=E5=88=86=E5=89=B2=E7=AD=89?= =?UTF-8?q?=E5=92=8C=E5=AD=90=E9=9B=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0416.分割等和子集.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/problems/0416.分割等和子集.md b/problems/0416.分割等和子集.md index 1f129312..a1158d7e 100644 --- a/problems/0416.分割等和子集.md +++ b/problems/0416.分割等和子集.md @@ -324,6 +324,21 @@ class Solution: return True return False +``` + +卡哥版(简化版) +```python +class Solution: + def canPartition(self, nums: List[int]) -> bool: + if sum(nums) % 2 != 0: + return False + target = sum(nums) // 2 + dp = [0] * (target + 1) + for num in nums: + for j in range(target, num-1, -1): + dp[j] = max(dp[j], dp[j-num] + num) + return dp[-1] == target + ``` 二维DP版 ```python From 71980306bf6f653145c0c0f0313a02bd8dd1a77f Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:58:24 -0500 Subject: [PATCH 55/58] =?UTF-8?q?Update=201049.=E6=9C=80=E5=90=8E=E4=B8=80?= =?UTF-8?q?=E5=9D=97=E7=9F=B3=E5=A4=B4=E7=9A=84=E9=87=8D=E9=87=8FII.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1049.最后一块石头的重量II.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/problems/1049.最后一块石头的重量II.md b/problems/1049.最后一块石头的重量II.md index a978b802..932029ab 100644 --- a/problems/1049.最后一块石头的重量II.md +++ b/problems/1049.最后一块石头的重量II.md @@ -238,6 +238,21 @@ class Solution: return total_sum - dp[target] - dp[target] +``` + +卡哥版(简化版) +```python +class Solution: + def lastStoneWeightII(self, stones): + total_sum = sum(stones) + target = total_sum // 2 + dp = [0] * (target + 1) + for stone in stones: + for j in range(target, stone - 1, -1): + dp[j] = max(dp[j], dp[j - stone] + stone) + return total_sum - 2* dp[-1] + + ``` 二维DP版 ```python From 33eca1635693f64d0eeb6d7c477093665dded20b Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Sat, 24 Jun 2023 20:18:36 -0400 Subject: [PATCH 56/58] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 調整語言順序 2. 新增java - DFS, java - BFS解法 --- problems/0695.岛屿的最大面积.md | 162 ++++++++++++++++++++----- 1 file changed, 129 insertions(+), 33 deletions(-) diff --git a/problems/0695.岛屿的最大面积.md b/problems/0695.岛屿的最大面积.md index e5deb897..37a601bc 100644 --- a/problems/0695.岛屿的最大面积.md +++ b/problems/0695.岛屿的最大面积.md @@ -189,6 +189,135 @@ public: ``` # 其它语言版本 +## Java +### DFS +```java +// DFS +class Solution { + int[][] dir = { + {0, 1}, //right + {1, 0}, //down + {0, -1}, //left + {-1, 0} //up + }; + boolean visited[][]; + int count; + public int maxAreaOfIsland(int[][] grid) { + int res = 0; + visited = new boolean[grid.length][grid[0].length]; + for(int i = 0; i < grid.length; i++){ + for(int j = 0; j < grid[0].length; j++){ + if(visited[i][j] == false && grid[i][j] == 1){ + count = 0; + dfs(grid, i, j); + res = Math.max(res, count); + } + } + } + return res; + } + private void dfs(int[][] grid, int x, int y){ + if(visited[x][y] == true || grid[x][y] == 0) + return; + + visited[x][y] = true; + count++; + + for(int i = 0; i < 4; i++){ + int nextX = x + dir[i][0]; + int nextY = y + dir[i][1]; + + if(nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) + continue; + dfs(grid, nextX, nextY); + } + } +} + + +``` +### BFS +```java +//BFS +class Solution { + int[][] dir = { + {0, 1}, {1, 0}, {0, -1}, {-1, 0} + }; + + int count; + boolean visited[][]; + + public int maxAreaOfIsland(int[][] grid) { + int res = 0; + visited = new boolean[grid.length][grid[0].length]; + + for(int i = 0; i < grid.length; i++){ + for(int j = 0; j < grid[0].length; j++){ + if(visited[i][j] == false && grid[i][j] == 1){ + count = 0; + bfs(grid, i, j); + res = Math.max(res, count); + } + } + } + return res; + } + private void bfs(int[][] grid, int x, int y){ + Queue que = new LinkedList<>(); + que.offer(x); + que.offer(y); + visited[x][y] = true; + count++; + + while(!que.isEmpty()){ + int currX = que.poll(); + int currY = que.poll(); + + for(int i = 0; i < 4; i++){ + int nextX = currX + dir[i][0]; + int nextY = currY + dir[i][1]; + + if(nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) + continue; + if(visited[nextX][nextY] == false && grid[nextX][nextY] == 1){ + que.offer(nextX); + que.offer(nextY); + visited[nextX][nextY] = true; + count++; + } + } + } + } +} +``` +### DFS 優化(遇到島嶼後,就把他淹沒) +```java +//这里使用深度优先搜索 DFS 来完成本道题目。我们使用 DFS 计算一个岛屿的面积,同时维护计算过的最大的岛屿面积。同时,为了避免对岛屿重复计算,我们在 DFS 的时候对岛屿进行 “淹没” 操作,即将岛屿所占的地方置为 0。 +public int maxAreaOfIsland(int[][] grid) { + int res = 0; + for(int i = 0;i < grid.length;i++){ + for(int j = 0;j < grid[0].length;j++){ + //每遇到一个岛屿就计算这个岛屿的面积同时”淹没“这个岛屿 + if(grid[i][j] == 1){ + //每次计算一个岛屿的面积都要与res比较,维护最大的岛屿面积作为最后的答案 + res = Math.max(res,dfs(grid,i,j)); + } + } + } + return res; +} +public int dfs(int[][] grid,int i,int j){ + //搜索边界:i,j超过grid的范围或者当前元素为0,即当前所在的地方已经是海洋 + if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) return 0; + //淹没土地,防止后续被重复计算 + grid[i][j] = 0; + //递归的思路:要求当前土地(i,j)所在的岛屿的面积,则等于1加上下左右相邻的土地的总面积 + return 1 + dfs(grid,i - 1,j) + + dfs(grid,i + 1,j) + + dfs(grid,i,j + 1) + + dfs(grid,i,j - 1); +} +``` ## Python ### BFS @@ -261,39 +390,6 @@ class Solution: if 0 <= new_x < len(grid) and 0 <= new_y < len(grid[0]): self.dfs(grid, visited, new_x, new_y) ``` - - - -## Java - -这里使用深度优先搜索 DFS 来完成本道题目。我们使用 DFS 计算一个岛屿的面积,同时维护计算过的最大的岛屿面积。同时,为了避免对岛屿重复计算,我们在 DFS 的时候对岛屿进行 “淹没” 操作,即将岛屿所占的地方置为 0。 - -```java -public int maxAreaOfIsland(int[][] grid) { - int res = 0; - for(int i = 0;i < grid.length;i++){ - for(int j = 0;j < grid[0].length;j++){ - //每遇到一个岛屿就计算这个岛屿的面积同时”淹没“这个岛屿 - if(grid[i][j] == 1){ - //每次计算一个岛屿的面积都要与res比较,维护最大的岛屿面积作为最后的答案 - res = Math.max(res,dfs(grid,i,j)); - } - } - } - return res; -} -public int dfs(int[][] grid,int i,int j){ - //搜索边界:i,j超过grid的范围或者当前元素为0,即当前所在的地方已经是海洋 - if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == 0) return 0; - //淹没土地,防止后续被重复计算 - grid[i][j] = 0; - //递归的思路:要求当前土地(i,j)所在的岛屿的面积,则等于1加上下左右相邻的土地的总面积 - return 1 + dfs(grid,i - 1,j) + - dfs(grid,i + 1,j) + - dfs(grid,i,j + 1) + - dfs(grid,i,j - 1); -} -```

From 2b3ce4453520a16bac6d65c2b3295cc65b90f00e Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Sat, 24 Jun 2023 23:38:40 -0400 Subject: [PATCH 57/58] =?UTF-8?q?=E6=96=B0=E5=A2=9Ejava=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1020.飞地的数量.md | 126 ++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) diff --git a/problems/1020.飞地的数量.md b/problems/1020.飞地的数量.md index e92b2412..7538d774 100644 --- a/problems/1020.飞地的数量.md +++ b/problems/1020.飞地的数量.md @@ -149,7 +149,63 @@ public: ### Java -深度优先遍历版本: +深度优先遍历(没有终止条件 + 空間優化(淹沒島嶼,沒有使用visited數組)) +```java +//DFS +class Solution { + int count = 0; + int[][] dir ={ + {0, 1}, + {1, 0}, + {-1, 0}, + {0, -1} + }; + private void dfs(int[][] grid, int x, int y){ + if(grid[x][y] == 0) + return; + + grid[x][y] = 0; + count++; + + for(int i = 0; i < 4; i++){ + int nextX = x + dir[i][0]; + int nextY = y + dir[i][1]; + + if(nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) + continue; + dfs(grid, nextX, nextY); + } + + } + + public int numEnclaves(int[][] grid) { + for(int i = 0; i < grid.length; i++){ + if(grid[i][0] == 1) + dfs(grid, i, 0); + if(grid[i][grid[0].length - 1] == 1) + dfs(grid, i, grid[0].length - 1); + } + //初始化的時候,j 的上下限有調整過,必免重複操作。 + for(int j = 1; j < grid[0].length - 1; j++){ + if(grid[0][j] == 1) + dfs(grid, 0, j); + if(grid[grid.length - 1][j] == 1) + dfs(grid, grid.length - 1, j); + } + count = 0; + + for(int i = 1; i < grid.length - 1; i++){ + for(int j = 1; j < grid[0].length - 1; j++){ + if(grid[i][j] == 1) + dfs(grid, i, j); + } + } + return count; + } +} +``` + +深度优先遍历(没有终止条件) ```java class Solution { @@ -206,7 +262,7 @@ class Solution { } ``` -广度优先遍历版本: +广度优先遍历(使用visited數組) ```java class Solution { @@ -269,6 +325,72 @@ class Solution { } ``` +廣度优先遍历(空間優化(淹沒島嶼,沒有使用visited數組)) +```java +//BFS +class Solution { + int count = 0; + int[][] dir ={ + {0, 1}, + {1, 0}, + {-1, 0}, + {0, -1} + }; + private void bfs(int[][] grid, int x, int y){ + Queue que = new LinkedList<>(); + que.offer(x); + que.offer(y); + count++; + grid[x][y] = 0; + + while(!que.isEmpty()){ + int currX = que.poll(); + int currY = que.poll(); + + for(int i = 0; i < 4; i++){ + int nextX = currX + dir[i][0]; + int nextY = currY + dir[i][1]; + + if(nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) + continue; + + if(grid[nextX][nextY] == 1){ + que.offer(nextX); + que.offer(nextY); + count++; + grid[nextX][nextY] = 0; + } + } + } + } + + public int numEnclaves(int[][] grid) { + for(int i = 0; i < grid.length; i++){ + if(grid[i][0] == 1) + bfs(grid, i, 0); + if(grid[i][grid[0].length - 1] == 1) + bfs(grid, i, grid[0].length - 1); + } + for(int j = 1; j < grid[0].length; j++){ + if(grid[0][j] == 1) + bfs(grid, 0 , j); + if(grid[grid.length - 1][j] == 1) + bfs(grid, grid.length - 1, j); + } + count = 0; + for(int i = 1; i < grid.length - 1; i++){ + for(int j = 1; j < grid[0].length - 1; j++){ + if(grid[i][j] == 1) + bfs(grid,i ,j); + } + } + return count; + } +} + + +``` + ### Python 深度优先遍历 From cdc5a1e9e47690fee5c5f5b34d66f643d6e08907 Mon Sep 17 00:00:00 2001 From: Terry Liu <102352821+Lozakaka@users.noreply.github.com> Date: Mon, 26 Jun 2023 21:37:58 -0400 Subject: [PATCH 58/58] =?UTF-8?q?=E6=96=B0=E5=A2=9EJAVA=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. java的BFS解法有寫一個helper function去呼叫 2. java's DFS with 終止條件 --- problems/0130.被围绕的区域.md | 89 +++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/problems/0130.被围绕的区域.md b/problems/0130.被围绕的区域.md index abb68e19..e244873b 100644 --- a/problems/0130.被围绕的区域.md +++ b/problems/0130.被围绕的区域.md @@ -188,6 +188,54 @@ class Solution { } } ``` +```Java +//BFS(使用helper function) +class Solution { + int[][] dir ={{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; + public void solve(char[][] board) { + for(int i = 0; i < board.length; i++){ + if(board[i][0] == 'O') bfs(board, i, 0); + if(board[i][board[0].length - 1] == 'O') bfs(board, i, board[0].length - 1); + } + + for(int j = 1 ; j < board[0].length - 1; j++){ + if(board[0][j] == 'O') bfs(board, 0, j); + if(board[board.length - 1][j] == 'O') bfs(board, board.length - 1, j); + } + + for(int i = 0; i < board.length; i++){ + for(int j = 0; j < board[0].length; j++){ + if(board[i][j] == 'O') board[i][j] = 'X'; + if(board[i][j] == 'A') board[i][j] = 'O'; + } + } + } + private void bfs(char[][] board, int x, int y){ + Queue que = new LinkedList<>(); + board[x][y] = 'A'; + que.offer(x); + que.offer(y); + + while(!que.isEmpty()){ + int currX = que.poll(); + int currY = que.poll(); + + for(int i = 0; i < 4; i++){ + int nextX = currX + dir[i][0]; + int nextY = currY + dir[i][1]; + + if(nextX < 0 || nextY < 0 || nextX >= board.length || nextY >= board[0].length) + continue; + if(board[nextX][nextY] == 'X'|| board[nextX][nextY] == 'A') + continue; + bfs(board, nextX, nextY); + } + } + } +} + +``` + ```Java // 深度优先遍历 // 使用 visited 数组进行标记 @@ -296,6 +344,47 @@ class Solution { } } ``` +```java +//DFS(有終止條件) +class Solution { + int[][] dir ={{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; + public void solve(char[][] board) { + + for(int i = 0; i < board.length; i++){ + if(board[i][0] == 'O') dfs(board, i, 0); + if(board[i][board[0].length - 1] == 'O') dfs(board, i, board[0].length - 1); + } + + for(int j = 1 ; j < board[0].length - 1; j++){ + if(board[0][j] == 'O') dfs(board, 0, j); + if(board[board.length - 1][j] == 'O') dfs(board, board.length - 1, j); + } + + for(int i = 0; i < board.length; i++){ + for(int j = 0; j < board[0].length; j++){ + if(board[i][j] == 'O') board[i][j] = 'X'; + if(board[i][j] == 'A') board[i][j] = 'O'; + } + } + } + + private void dfs(char[][] board, int x, int y){ + if(board[x][y] == 'X'|| board[x][y] == 'A') + return; + board[x][y] = 'A'; + for(int i = 0; i < 4; i++){ + int nextX = x + dir[i][0]; + int nextY = y + dir[i][1]; + + if(nextX < 0 || nextY < 0 || nextX >= board.length || nextY >= board[0].length) + continue; + // if(board[nextX][nextY] == 'X'|| board[nextX][nextY] == 'A') + // continue; + dfs(board, nextX, nextY); + } + } +} +```