From 60f3ad665b005e518a6b413304bfbf26058feeb5 Mon Sep 17 00:00:00 2001 From: cezarbbb <105843128+cezarbbb@users.noreply.github.com> Date: Sun, 7 Aug 2022 19:34:04 +0800 Subject: [PATCH 01/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200343.=E6=95=B4?= =?UTF-8?q?=E6=95=B0=E6=8B=86=E5=88=86=20Rust=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0343.整数拆分 Rust版本 --- problems/0343.整数拆分.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/problems/0343.整数拆分.md b/problems/0343.整数拆分.md index a4d532fd..60676e85 100644 --- a/problems/0343.整数拆分.md +++ b/problems/0343.整数拆分.md @@ -299,6 +299,27 @@ function integerBreak(n: number): number { }; ``` +### Rust + +```Rust +impl Solution { + fn max(a: i32, b: i32) -> i32{ + if a > b { a } else { b } + } + pub fn integer_break(n: i32) -> i32 { + let n = n as usize; + let mut dp = vec![0; n + 1]; + dp[2] = 1; + for i in 3..=n { + for j in 1..i - 1 { + dp[i] = Self::max(dp[i], Self::max(((i - j) * j) as i32, dp[i - j] * j as i32)); + } + } + dp[n] + } +} +``` + ### C ```c From b58c0df620f7e5171ec4606250ad7cdd04a3646c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=9C=A1=E7=AC=94?= Date: Sun, 7 Aug 2022 20:41:01 +0800 Subject: [PATCH 02/19] =?UTF-8?q?Update=200376.=E6=91=86=E5=8A=A8=E5=BA=8F?= =?UTF-8?q?=E5=88=97.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按着讲解的原理,分别完善了Golang版本的贪心算法和动态规划算法。 --- problems/0376.摆动序列.md | 64 +++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/problems/0376.摆动序列.md b/problems/0376.摆动序列.md index a41a0f0a..d15ed2d0 100644 --- a/problems/0376.摆动序列.md +++ b/problems/0376.摆动序列.md @@ -266,22 +266,58 @@ class Solution: ### Go +**贪心** ```golang func wiggleMaxLength(nums []int) int { - var count,preDiff,curDiff int - count=1 - if len(nums)<2{ - return count - } - for i:=0;i 0 && preDiff <= 0) || (preDiff >= 0 && curDiff < 0){ - preDiff=curDiff - count++ - } - } - return count + var count, preDiff, curDiff int //初始化默认为0 + count = 1 // 初始化为1,因为最小的序列是1个数 + if len(nums) < 2 { + return count + } + for i := 0; i < len(nums)-1; i++ { + curDiff = nums[i+1] - nums[i] + if (curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0) { + count++ + } + } + return count +} +``` + +**动态规划** +```golang +func wiggleMaxLength(nums []int) int { + n := len(nums) + if n <= 1 { + return n + } + dp := make([][2]int, n) + // i 0 作为波峰的最大长度 + // i 1 作为波谷的最大长度 + dp[0][0] = 1 + dp[0][1] = 1 + for i := 0; i < n; i++ { + for j := 0; j < i; j++ { + if nums[j] > nums[i] { //nums[i]为波谷 + dp[i][1] = max(dp[i][1], dp[j][0]+1) + } + if nums[j] < nums[i] { //nums[i]为波峰 或者相等 + dp[i][0] = max(dp[i][0], dp[j][1]+1) + } + if nums[j] == nums[i] { //添加一种情况,nums[i]为相等 + dp[i][0] = max(dp[i][0], dp[j][0]) //波峰 + dp[i][1] = max(dp[i][1], dp[j][1]) //波谷 + } + } + } + return max(dp[n-1][0], dp[n-1][1]) +} +func max(a, b int) int { + if a > b { + return a + } else { + return b + } } ``` From b6027889f5d04955091933474ccd5735b53e9f75 Mon Sep 17 00:00:00 2001 From: cezarbbb <105843128+cezarbbb@users.noreply.github.com> Date: Mon, 8 Aug 2022 16:25:40 +0800 Subject: [PATCH 03/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200096.=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E7=9A=84=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91?= =?UTF-8?q?=20Rust=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0096.不同的二叉搜索树 Rust版本 --- problems/0096.不同的二叉搜索树.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/problems/0096.不同的二叉搜索树.md b/problems/0096.不同的二叉搜索树.md index 9adc0457..51de1e23 100644 --- a/problems/0096.不同的二叉搜索树.md +++ b/problems/0096.不同的二叉搜索树.md @@ -252,6 +252,24 @@ function numTrees(n: number): number { }; ``` +### Rust + +```Rust +impl Solution { + pub fn num_trees(n: i32) -> i32 { + let n = n as usize; + let mut dp = vec![0; n + 1]; + dp[0] = 1; + for i in 1..=n { + for j in 1..=i { + dp[i] += dp[j - 1] * dp[i - j]; + } + } + dp[n] + } +} +``` + ### C ```c From 8ded72e92d94a289565b964dfe8220b0c894f9d9 Mon Sep 17 00:00:00 2001 From: FancyWxx <93196934+FancyWxx@users.noreply.github.com> Date: Tue, 9 Aug 2022 14:32:20 +0800 Subject: [PATCH 04/19] =?UTF-8?q?Update=200922.=E6=8C=89=E5=A5=87=E5=81=B6?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E6=95=B0=E7=BB=84=E2=85=A1.md=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BA=86Java=E7=89=88=E6=9C=AC=E7=9A=84=E4=B8=A4?= =?UTF-8?q?=E7=A7=8D=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0922.按奇偶排序数组II.md | 53 ++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/problems/0922.按奇偶排序数组II.md b/problems/0922.按奇偶排序数组II.md index 49547a15..4e281a3c 100644 --- a/problems/0922.按奇偶排序数组II.md +++ b/problems/0922.按奇偶排序数组II.md @@ -147,6 +147,59 @@ class Solution { } ``` +### java + +```java +//方法一:采用额外的数组空间 +class Solution { + public int[] sortArrayByParityII(int[] nums) { + //定义结果数组 result + int[] result = new int[nums.length]; + int even = 0, odd = 1; + for(int i = 0; i < nums.length; i++){ + //如果为偶数 + if(nums[i] % 2 == 0){ + result[even] = nums[i]; + even += 2; + }else{ + result[odd] = nums[i]; + odd += 2; + } + } + return result; + } +} +``` +```java +//方法二:不采用额外的数组空间 +class Solution922 { + public int[] sortArrayByParityII(int[] nums) { + //定义双指针 + int oddPoint = 1, evenPoint = 0; + //开始移动并交换,最后一层必然为相互交换后再移动或者相同直接移动 + while(oddPoint < nums.length && evenPoint < nums.length){ + //进行判断 + if(nums[oddPoint] % 2 == 0 && nums[evenPoint] % 2 == 1){ //如果均不满足 + int temp = 0; + temp = nums[oddPoint]; + nums[oddPoint] = nums[evenPoint]; + nums[evenPoint] = temp; + oddPoint += 2; + evenPoint += 2; + }else if(nums[oddPoint] % 2 == 0 && nums[evenPoint] % 2 == 0){ //偶数满足 + evenPoint += 2; + }else if(nums[oddPoint] % 2 == 1 && nums[evenPoint] % 2 == 1){ //奇数满足 + oddPoint += 2; + }else{ + oddPoint += 2; + evenPoint += 2; + } + } + return nums; + } +} +``` + ### Python3 ```python From 0f9c10dda4b3446f1ac53805e3125ed42219dbab Mon Sep 17 00:00:00 2001 From: wang <472146630@qq.com> Date: Tue, 9 Aug 2022 17:34:44 +0800 Subject: [PATCH 05/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=95=B4=E6=95=B0?= =?UTF-8?q?=E6=8B=86=E5=88=86Rust=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0343.整数拆分.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/problems/0343.整数拆分.md b/problems/0343.整数拆分.md index a4d532fd..68846b13 100644 --- a/problems/0343.整数拆分.md +++ b/problems/0343.整数拆分.md @@ -192,7 +192,7 @@ public: ## 其他语言版本 -### Java +### Java ```Java class Solution { public int integerBreak(int n) { @@ -259,6 +259,21 @@ func max(a,b int) int{ } ``` +### Rust +```rust +pub fn integer_break(n: i32) -> i32 { + let n = n as usize; + let mut dp = vec![0; n + 1]; + dp[2] = 1; + for i in 3..=n { + for j in 1..i-1 { + dp[i] = dp[i].max((i - j) * j).max(dp[i - j] * j); + } + } + dp[n] as i32 +} +``` + ### Javascript ```Javascript var integerBreak = function(n) { From 0012d62724742e7492c4b06a0c55ac5305ac380f Mon Sep 17 00:00:00 2001 From: cezarbbb <105843128+cezarbbb@users.noreply.github.com> Date: Tue, 9 Aug 2022 19:20:23 +0800 Subject: [PATCH 06/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200416.=E5=88=86?= =?UTF-8?q?=E5=89=B2=E7=AD=89=E5=92=8C=E5=AD=90=E9=9B=86=20Rust=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0416.分割等和子集 Rust版本 --- problems/0416.分割等和子集.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/problems/0416.分割等和子集.md b/problems/0416.分割等和子集.md index 83b267ac..03eae8ef 100644 --- a/problems/0416.分割等和子集.md +++ b/problems/0416.分割等和子集.md @@ -417,7 +417,32 @@ var canPartition = function(nums) { ``` +### Rust +```Rust +impl Solution { + fn max(a: usize, b: usize) -> usize { + if a > b { a } else { b } + } + pub fn can_partition(nums: Vec) -> bool { + let nums = nums.iter().map(|x| *x as usize).collect::>(); + let mut sum = 0; + let mut dp: Vec = vec![0; 10001]; + for i in 0..nums.len() { + sum += nums[i]; + } + if sum % 2 == 1 { return false; } + let target = sum / 2; + for i in 0..nums.len() { + for j in (nums[i]..=target).rev() { + dp[j] = Self::max(dp[j], dp[j - nums[i]] + nums[i]); + } + } + if dp[target] == target { return true; } + false + } +} +``` ### C: From 2d6b09b66a0fea7412ab40002cdce4eb02da2854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E7=83=A8?= Date: Wed, 10 Aug 2022 11:19:58 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200024.=E4=B8=A4?= =?UTF-8?q?=E4=B8=A4=E4=BA=A4=E6=8D=A2=E9=93=BE=E8=A1=A8=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E8=8A=82=E7=82=B9=20PHP=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0024.两两交换链表中的节点.md | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 4b4b39e7..5b73fb05 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -336,5 +336,48 @@ object Solution { } ``` +PHP: +```php +//虚拟头结点 +function swapPairs($head) { + if ($head == null || $head->next == null) { + return $head; + } + + $dummyNode = new ListNode(0, $head); + $preNode = $dummyNode; //虚拟头结点 + $curNode = $head; + $nextNode = $head->next; + while($curNode && $nextNode) { + $nextNextNode = $nextNode->next; //存下一个节点 + $nextNode->next = $curNode; //交换curHead 和 nextHead + $curNode->next = $nextNextNode; + $preNode->next = $nextNode; //上一个节点的下一个指向指向nextHead + + //更新当前的几个指针 + $preNode = $preNode->next->next; + $curNode = $nextNextNode; + $nextNode = $nextNextNode->next; + } + + return $dummyNode->next; +} + +//递归版本 +function swapPairs($head) +{ + // 终止条件 + if ($head === null || $head->next === null) { + return $head; + } + + //结果要返回的头结点 + $next = $head->next; + $head->next = $this->swapPairs($next->next); //当前头结点->next指向更新 + $next->next = $head; //当前第二个节点的->next指向更新 + return $next; //返回翻转后的头结点 +} +``` + -----------------------
From 526d24743d3b451066c5ccdc884898f02a79767d Mon Sep 17 00:00:00 2001 From: GoodLiang Date: Sat, 13 Aug 2022 11:28:00 +0800 Subject: [PATCH 08/19] =?UTF-8?q?Update=200077.=E7=BB=84=E5=90=88.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改0077.组合错别字 --- problems/0077.组合.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0077.组合.md b/problems/0077.组合.md index 5a4811ba..17e4fb35 100644 --- a/problems/0077.组合.md +++ b/problems/0077.组合.md @@ -114,7 +114,7 @@ vector> result; // 存放符合条件结果的集合 vector path; // 用来存放符合条件结果 ``` -其实不定义这两个全局遍历也是可以的,把这两个变量放进递归函数的参数里,但函数里参数太多影响可读性,所以我定义全局变量了。 +其实不定义这两个全局变量也是可以的,把这两个变量放进递归函数的参数里,但函数里参数太多影响可读性,所以我定义全局变量了。 函数里一定有两个参数,既然是集合n里面取k的数,那么n和k是两个int型的参数。 From 8ec36e4309d91f67958529df3cd1a258f4d824ae Mon Sep 17 00:00:00 2001 From: easydonny Date: Sun, 14 Aug 2022 12:49:57 -0400 Subject: [PATCH 09/19] =?UTF-8?q?Update=20=E9=9D=A2=E8=AF=95=E9=A2=9802.07?= =?UTF-8?q?.=E9=93=BE=E8=A1=A8=E7=9B=B8=E4=BA=A4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit suggest changing the title from "面试题02.07." to Leetcode question number "0160", to align with all other pages. --- problems/面试题02.07.链表相交.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/面试题02.07.链表相交.md b/problems/面试题02.07.链表相交.md index abf7a2f8..8ea9c3cf 100644 --- a/problems/面试题02.07.链表相交.md +++ b/problems/面试题02.07.链表相交.md @@ -5,7 +5,7 @@

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

-# 面试题 02.07. 链表相交 +# 0160. 链表相交 [力扣题目链接](https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/) From e36dc6a5841d6aa3d719635538ee84df235c9a34 Mon Sep 17 00:00:00 2001 From: Galaxies2580 Date: Mon, 15 Aug 2022 10:22:46 +0800 Subject: [PATCH 10/19] Go --- ....完全二叉树的节点个数Go版本.md | 25 +++++++++++++++++++ 添加559.n叉树的最大深度Go版本.md | 22 ++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 添加0222.完全二叉树的节点个数Go版本.md create mode 100644 添加559.n叉树的最大深度Go版本.md diff --git a/添加0222.完全二叉树的节点个数Go版本.md b/添加0222.完全二叉树的节点个数Go版本.md new file mode 100644 index 00000000..752ace88 --- /dev/null +++ b/添加0222.完全二叉树的节点个数Go版本.md @@ -0,0 +1,25 @@ +```go +func countNodes(root *TreeNode) int { + if root == nil { + return 0 + } + q := list.New() + q.PushBack(root) + res := 0 + for q.Len() > 0 { + n := q.Len() + for i := 0; i < n; i++ { + node := q.Remove(q.Front()).(*TreeNode) + if node.Left != nil { + q.PushBack(node.Left) + } + if node.Right != nil { + q.PushBack(node.Right) + } + res++ + } + } + return res +} +``` + diff --git a/添加559.n叉树的最大深度Go版本.md b/添加559.n叉树的最大深度Go版本.md new file mode 100644 index 00000000..77ca332c --- /dev/null +++ b/添加559.n叉树的最大深度Go版本.md @@ -0,0 +1,22 @@ +```go +func maxDepth(root *Node) int { + if root == nil { + return 0 + } + q := list.New() + q.PushBack(root) + depth := 0 + for q.Len() > 0 { + n := q.Len() + for i := 0; i < n; i++ { + node := q.Remove(q.Front()).(*Node) + for j := range node.Children { + q.PushBack(node.Children[j]) + } + } + depth++ + } + return depth +} +``` + From f59621fdc5b0917f048767f64d449b6f4e7ea40b Mon Sep 17 00:00:00 2001 From: Galaxies2580 <82326525+Galaxies2580@users.noreply.github.com> Date: Mon, 15 Aug 2022 10:24:40 +0800 Subject: [PATCH 11/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A00222.=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E7=9A=84=E8=8A=82=E7=82=B9=E4=B8=AA?= =?UTF-8?q?=E6=95=B0Go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加0222.完全二叉树的节点个数Go版本 --- 添加0222.完全二叉树的节点个数Go版本.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/添加0222.完全二叉树的节点个数Go版本.md b/添加0222.完全二叉树的节点个数Go版本.md index 752ace88..6001e7b7 100644 --- a/添加0222.完全二叉树的节点个数Go版本.md +++ b/添加0222.完全二叉树的节点个数Go版本.md @@ -19,7 +19,7 @@ func countNodes(root *TreeNode) int { res++ } } - return res + return res } ``` From c50085df84471905957bb5990fba5ed4825c5f9b Mon Sep 17 00:00:00 2001 From: Galaxies2580 <82326525+Galaxies2580@users.noreply.github.com> Date: Mon, 15 Aug 2022 10:25:03 +0800 Subject: [PATCH 12/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A0559.n=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E6=9C=80=E5=A4=A7=E6=B7=B1=E5=BA=A6Go=E7=89=88?= =?UTF-8?q?=E6=9C=AC.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加559.n叉树的最大深度Go版本.md --- 添加559.n叉树的最大深度Go版本.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/添加559.n叉树的最大深度Go版本.md b/添加559.n叉树的最大深度Go版本.md index 77ca332c..3172837d 100644 --- a/添加559.n叉树的最大深度Go版本.md +++ b/添加559.n叉树的最大深度Go版本.md @@ -16,7 +16,7 @@ func maxDepth(root *Node) int { } depth++ } - return depth + return depth } ``` From 300b8f9f3e5e0233947cb08d97ea67f4840fceb3 Mon Sep 17 00:00:00 2001 From: Yuki Chen <826992207@qq.com> Date: Thu, 18 Aug 2022 10:52:42 +0800 Subject: [PATCH 13/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200035.=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E6=8F=92=E5=85=A5=E4=BD=8D=E7=BD=AE=20=E7=AC=AC?= =?UTF-8?q?=E4=BA=8C=E7=A7=8D=E4=BA=8C=E5=88=86=E6=B3=95Java=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0035.搜索插入位置.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/problems/0035.搜索插入位置.md b/problems/0035.搜索插入位置.md index f2bbb8ca..5ed3ac56 100644 --- a/problems/0035.搜索插入位置.md +++ b/problems/0035.搜索插入位置.md @@ -226,7 +226,32 @@ class Solution { } } ``` +```java +//第二种二分法:左闭右开 +public int searchInsert(int[] nums, int target) { + int left = 0; + int right = nums.length; + while (left < right) { //左闭右开 [left, right) + int middle = left + ((right - left) >> 1); + if (nums[middle] > target) { + right = middle; // target 在左区间,在[left, middle)中 + } else if (nums[middle] < target) { + left = middle + 1; // target 在右区间,在 [middle+1, right)中 + } else { // nums[middle] == target + return middle; // 数组中找到目标值的情况,直接返回下标 + } + } + // 目标值在数组所有元素之前 [0,0) + // 目标值插入数组中的位置 [left, right) ,return right 即可 + // 目标值在数组所有元素之后的情况 [left, right),因为是右开区间,所以 return right + return right; +} +``` + + + Golang: + ```golang // 第一种二分法 func searchInsert(nums []int, target int) int { From 708c3eefdf506d2e99df63e44826877980c981cf Mon Sep 17 00:00:00 2001 From: "xin.liu" Date: Thu, 18 Aug 2022 11:08:50 +0800 Subject: [PATCH 14/19] =?UTF-8?q?Update=200704.=E4=BA=8C=E5=88=86=E6=B3=95?= =?UTF-8?q?=E6=9F=A5=E6=89=BE=20JavaScript=E5=92=8CTypeScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0704.二分查找.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/problems/0704.二分查找.md b/problems/0704.二分查找.md index eec97a78..53f5331a 100644 --- a/problems/0704.二分查找.md +++ b/problems/0704.二分查找.md @@ -290,10 +290,11 @@ func search(nums []int, target int) int { */ var search = function(nums, target) { // right是数组最后一个数的下标,num[right]在查找范围内,是左闭右闭区间 - let left = 0, right = nums.length - 1; + let mid, left = 0, right = nums.length - 1; // 当left=right时,由于nums[right]在查找范围内,所以要包括此情况 while (left <= right) { - let mid = left + Math.floor((right - left)/2); + // 位运算 + 防止大数溢出 + mid = left + ((right - left) >> 1); // 如果中间数大于目标值,要把中间数排除查找范围,所以右边界更新为mid-1;如果右边界更新为mid,那中间数还在下次查找范围内 if (nums[mid] > target) { right = mid - 1; // 去左面闭区间寻找 @@ -316,10 +317,11 @@ var search = function(nums, target) { */ var search = function(nums, target) { // right是数组最后一个数的下标+1,nums[right]不在查找范围内,是左闭右开区间 - let left = 0, right = nums.length; + let mid, left = 0, right = nums.length; // 当left=right时,由于nums[right]不在查找范围,所以不必包括此情况 while (left < right) { - let mid = left + Math.floor((right - left)/2); + // 位运算 + 防止大数溢出 + mid = left + ((right - left) >> 1); // 如果中间值大于目标值,中间值不应在下次查找的范围内,但中间值的前一个值应在; // 由于right本来就不在查找范围内,所以将右边界更新为中间值,如果更新右边界为mid-1则将中间值的前一个值也踢出了下次寻找范围 if (nums[mid] > target) { @@ -340,9 +342,10 @@ var search = function(nums, target) { ```typescript function search(nums: number[], target: number): number { - let left: number = 0, right: number = nums.length - 1; + let mid: number, left: number = 0, right: number = nums.length - 1; while (left <= right) { - let mid: number = left + Math.floor((right - left) / 2); + // 位运算 + 防止大数溢出 + mid = left + ((right - left) >> 1); if (nums[mid] > target) { right = mid - 1; } else if (nums[mid] < target) { @@ -359,9 +362,10 @@ function search(nums: number[], target: number): number { ```typescript function search(nums: number[], target: number): number { - let left: number = 0, right: number = nums.length; + let mid: number, left: number = 0, right: number = nums.length; while (left < right) { - let mid: number = left + Math.floor((right - left) / 2); + // 位运算 + 防止大数溢出 + mid = left +((right - left) >> 1); if (nums[mid] > target) { right = mid; } else if (nums[mid] < target) { From 3fdf4484ef93ba60e5a7de589972c2c0edf2dc1c Mon Sep 17 00:00:00 2001 From: Yukun J Date: Wed, 17 Aug 2022 22:43:28 -0700 Subject: [PATCH 15/19] =?UTF-8?q?Update:=20=E5=A2=9E=E5=8A=A0<131.?= =?UTF-8?q?=E5=88=86=E5=89=B2=E5=9B=9E=E6=96=87=E4=B8=B2>=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0131.分割回文串.md | 59 ++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md index a54d6576..37132503 100644 --- a/problems/0131.分割回文串.md +++ b/problems/0131.分割回文串.md @@ -206,6 +206,65 @@ public: return result; } }; +``` +# 优化 + +上面的代码还存在一定的优化空间, 在于如何更高效的计算一个子字符串是否是回文字串。上述代码```isPalindrome```函数运用双指针的方法来判定对于一个字符串```s```, 给定起始下标和终止下标, 截取出的子字符串是否是回文字串。但是其中有一定的重复计算存在: + +例如给定字符串```"abcde"```, 在已知```"bcd"```不是回文字串时, 不再需要去双指针操作```"abcde"```而可以直接判定它一定不是回文字串。 + +具体来说, 给定一个字符串`s`, 长度为```n```, 它成为回文字串的充分必要条件是```s[0] == s[n-1]```且```s[1:n-1]```是回文字串。 + +大家如果熟悉动态规划这种算法的话, 我们可以高效地事先一次性计算出, 针对一个字符串```s```, 它的任何子串是否是回文字串, 然后在我们的回溯函数中直接查询即可, 省去了双指针移动判定这一步骤. + +具体参考代码如下: + +```CPP +class Solution { +private: + vector> result; + vector path; // 放已经回文的子串 + vector> isPalindrome; // 放事先计算好的是否回文子串的结果 + void backtracking (const string& s, int startIndex) { + // 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了 + if (startIndex >= s.size()) { + result.push_back(path); + return; + } + for (int i = startIndex; i < s.size(); i++) { + if (isPalindrome[startIndex][i]) { // 是回文子串 + // 获取[startIndex,i]在s中的子串 + string str = s.substr(startIndex, i - startIndex + 1); + path.push_back(str); + } else { // 不是回文,跳过 + continue; + } + backtracking(s, i + 1); // 寻找i+1为起始位置的子串 + path.pop_back(); // 回溯过程,弹出本次已经填在的子串 + } + } + void computePalindrome(const string& s) { + // isPalindrome[i][j] 代表 s[i:j](双边包括)是否是回文字串 + isPalindrome.resize(s.size(), vector(s.size(), false)); // 根据字符串s, 刷新布尔矩阵的大小 + for (int i = s.size() - 1; i >= 0; i--) { + // 需要倒序计算, 保证在i行时, i+1行已经计算好了 + for (int j = i; j < s.size(); j++) { + if (j == i) {isPalindrome[i][j] = true;} + else if (j - i == 1) {isPalindrome[i][j] = (s[i] == s[j]);} + else {isPalindrome[i][j] = (s[i] == s[j] && isPalindrome[i+1][j-1]);} + } + } + } +public: + vector> partition(string s) { + result.clear(); + path.clear(); + computePalindrome(s); + backtracking(s, 0); + return result; + } +}; + ``` # 总结 From d53246138d67e2054b54bd30b596cc4e427ee25a Mon Sep 17 00:00:00 2001 From: Yuki Chen <826992207@qq.com> Date: Sat, 20 Aug 2022 11:54:39 +0800 Subject: [PATCH 16/19] =?UTF-8?q?=E6=B7=BB=E5=8A=A00027.=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=85=83=E7=B4=A0=20=E7=9B=B8=E5=90=91=E5=8F=8C=E6=8C=87?= =?UTF-8?q?=E9=92=88=E6=B3=95Java=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0027.移除元素.md | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/problems/0027.移除元素.md b/problems/0027.移除元素.md index 12f88c75..68b1d4bd 100644 --- a/problems/0027.移除元素.md +++ b/problems/0027.移除元素.md @@ -146,7 +146,7 @@ public: }; ``` - + ## 相关题目推荐 * 26.删除排序数组中的重复项 @@ -154,10 +154,6 @@ public: * 844.比较含退格的字符串 * 977.有序数组的平方 - - - - ## 其他语言版本 @@ -180,6 +176,26 @@ class Solution { } } ``` +```java +//相向双指针法 +class Solution { + public int removeElement(int[] nums, int val) { + int left = 0; + int right = nums.length - 1; + while(right >= 0 && nums[right] == val) right--; //将right移到从右数第一个值不为val的位置 + while(left <= right) { + if(nums[left] == val) { //left位置的元素需要移除 + //将right位置的元素移到left(覆盖),right位置移除 + nums[left] = nums[right]; + right--; + } + left++; + while(right >= 0 && nums[right] == val) right--; + } + return left; + } +} +``` Python: From fef52ccea86c388881b08a0cbdf235bdf2378a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98Carl?= Date: Tue, 23 Aug 2022 09:18:21 +0800 Subject: [PATCH 17/19] =?UTF-8?q?Update=20=E9=9D=A2=E8=AF=95=E9=A2=9802.07?= =?UTF-8?q?.=E9=93=BE=E8=A1=A8=E7=9B=B8=E4=BA=A4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/面试题02.07.链表相交.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/problems/面试题02.07.链表相交.md b/problems/面试题02.07.链表相交.md index 8ea9c3cf..6d6810a3 100644 --- a/problems/面试题02.07.链表相交.md +++ b/problems/面试题02.07.链表相交.md @@ -5,7 +5,9 @@

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

-# 0160. 链表相交 +# 面试题 02.07. 链表相交 + +同:160.链表相交 [力扣题目链接](https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/) From 4de12f9810d81512b073b98d68c2b5a3126abfab Mon Sep 17 00:00:00 2001 From: programmercarl <826123027@qq.com> Date: Tue, 23 Aug 2022 17:34:20 +0800 Subject: [PATCH 18/19] Update --- problems/0347.前K个高频元素.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/problems/0347.前K个高频元素.md b/problems/0347.前K个高频元素.md index 430dcea1..d4059b9b 100644 --- a/problems/0347.前K个高频元素.md +++ b/problems/0347.前K个高频元素.md @@ -31,6 +31,14 @@ # 思路 +《代码随想录》算法视频公开课:[优先级队列正式登场!大顶堆、小顶堆该怎么用?| LeetCode:347.前 K 个高频元素](https://www.bilibili.com/video/BV1Xg41167Lz),相信结合视频在看本篇题解,更有助于大家对本题的理解。 + +

+ +

+ + + 这道题目主要涉及到如下三块内容: 1. 要统计元素出现频率 2. 对频率排序 From 59825d6700d8715eca3b980a8577598d27cc85c7 Mon Sep 17 00:00:00 2001 From: programmercarl <826123027@qq.com> Date: Tue, 23 Aug 2022 17:34:33 +0800 Subject: [PATCH 19/19] Update --- problems/0027.移除元素.md | 7 +-- problems/0150.逆波兰表达式求值.md | 2 + problems/0239.滑动窗口最大值.md | 2 + problems/0695.岛屿的最大面积.md | 63 +++++++++++++++++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) diff --git a/problems/0027.移除元素.md b/problems/0027.移除元素.md index 12f88c75..05c4394c 100644 --- a/problems/0027.移除元素.md +++ b/problems/0027.移除元素.md @@ -165,18 +165,15 @@ Java: ```java class Solution { public int removeElement(int[] nums, int val) { - // 快慢指针 - int fastIndex = 0; - int slowIndex; - for (slowIndex = 0; fastIndex < nums.length; fastIndex++) { + int slowIndex = 0; + for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) { if (nums[fastIndex] != val) { nums[slowIndex] = nums[fastIndex]; slowIndex++; } } return slowIndex; - } } ``` diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md index 21bd8593..8107e4e0 100644 --- a/problems/0150.逆波兰表达式求值.md +++ b/problems/0150.逆波兰表达式求值.md @@ -65,6 +65,8 @@ # 思路 +《代码随想录》算法视频公开课:[栈的最后表演! | LeetCode:150. 逆波兰表达式求值](https://www.bilibili.com/video/BV1kd4y1o7on),相信结合视频在看本篇题解,更有助于大家对本题的理解。 + 在上一篇文章中[1047.删除字符串中的所有相邻重复项](https://programmercarl.com/1047.删除字符串中的所有相邻重复项.html)提到了 递归就是用栈来实现的。 所以**栈与递归之间在某种程度上是可以转换的!** 这一点我们在后续讲解二叉树的时候,会更详细的讲解到。 diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md index 6ec98506..3f402f12 100644 --- a/problems/0239.滑动窗口最大值.md +++ b/problems/0239.滑动窗口最大值.md @@ -32,6 +32,8 @@ # 思路 +《代码随想录》算法视频公开课:[单调队列正式登场!| LeetCode:239. 滑动窗口最大值](https://www.bilibili.com/video/BV1XS4y1p7qj),相信结合视频在看本篇题解,更有助于大家对本题的理解。 + 这是使用单调队列的经典题目。 难点是如何求一个区间里的最大值呢? (这好像是废话),暴力一下不就得了。 diff --git a/problems/0695.岛屿的最大面积.md b/problems/0695.岛屿的最大面积.md index b0945292..3739882a 100644 --- a/problems/0695.岛屿的最大面积.md +++ b/problems/0695.岛屿的最大面积.md @@ -16,6 +16,17 @@ # 思路 +这道题目也是 dfs bfs基础类题目。 + + +## DFS + +很多同学,写dfs其实也是凭感觉来,有的时候dfs函数中写终止条件才能过,有的时候 dfs函数不写终止添加也能过! + +这里其实涉及到dfs的两种写法, + +以下代码使用dfs实现,如果对dfs不太了解的话,建议先看这篇题解:[797.所有可能的路径](https://leetcode.cn/problems/all-paths-from-source-to-target/solution/by-carlsun-2-66pf/), + 写法一,dfs只处理下一个节点 ```CPP class Solution { @@ -94,3 +105,55 @@ public: } }; ``` + +以上两种写法的区别,我在题解: [DFS,BDF 你没注意的细节都给你列出来了!LeetCode:200. 岛屿数量](https://leetcode.cn/problems/number-of-islands/solution/by-carlsun-2-n72a/)做了详细介绍。 + +## BFS + +```CPP +class Solution { +private: + int count; + int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 四个方向 + void bfs(vector>& grid, vector>& visited, int x, int y) { + queue que; + que.push(x); + que.push(y); + visited[x][y] = true; // 加入队列就意味节点是陆地可到达的点 + count++; + while(!que.empty()) { + int xx = que.front();que.pop(); + int yy = que.front();que.pop(); + for (int i = 0 ;i < 4; i++) { + int nextx = xx + dir[i][0]; + int nexty = yy + dir[i][1]; + if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue; // 越界 + if (!visited[nextx][nexty] && grid[nextx][nexty] == 1) { // 节点没有被访问过且是陆地 + visited[nextx][nexty] = true; + count++; + que.push(nextx); + que.push(nexty); + } + } + } + } + +public: + int maxAreaOfIsland(vector>& grid) { + int n = grid.size(), m = grid[0].size(); + vector> visited = vector>(n, vector(m, false)); + int result = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (!visited[i][j] && grid[i][j] == 1) { + count = 0; + bfs(grid, visited, i, j); // 将与其链接的陆地都标记上 true + result = max(result, count); + } + } + } + return result; + } +}; + +```