diff --git a/problems/0053.最大子序和.md b/problems/0053.最大子序和.md index d0680a3b..73cac244 100644 --- a/problems/0053.最大子序和.md +++ b/problems/0053.最大子序和.md @@ -140,7 +140,7 @@ public: ## 其他语言版本 -### Java +### Java ```java class Solution { public int maxSubArray(int[] nums) { @@ -180,7 +180,7 @@ class Solution { } ``` -### Python +### Python ```python class Solution: def maxSubArray(self, nums: List[int]) -> int: @@ -195,7 +195,7 @@ class Solution: return result ``` -### Go +### Go ```go func maxSubArray(nums []int) int { @@ -212,6 +212,20 @@ func maxSubArray(nums []int) int { } ``` +### Rust +```rust +pub fn max_sub_array(nums: Vec) -> i32 { + let mut max_sum = i32::MIN; + let mut curr = 0; + for n in nums.iter() { + curr += n; + max_sum = max_sum.max(curr); + curr = curr.max(0); + } + max_sum +} +``` + ### Javascript: ```Javascript var maxSubArray = function(nums) { diff --git a/problems/0135.分发糖果.md b/problems/0135.分发糖果.md index 72f3dd56..3456a04c 100644 --- a/problems/0135.分发糖果.md +++ b/problems/0135.分发糖果.md @@ -126,11 +126,11 @@ public: ## 其他语言版本 -### Java +### Java ```java class Solution { - /** - 分两个阶段 + /** + 分两个阶段 1、起点下标1 从左往右,只要 右边 比 左边 大,右边的糖果=左边 + 1 2、起点下标 ratings.length - 2 从右往左, 只要左边 比 右边 大,此时 左边的糖果应该 取本身的糖果数(符合比它左边大) 和 右边糖果数 + 1 二者的最大值,这样才符合 它比它左边的大,也比它右边大 */ @@ -160,7 +160,7 @@ class Solution { } ``` -### Python +### Python ```python class Solution: def candy(self, ratings: List[int]) -> int: @@ -213,6 +213,25 @@ func findMax(num1 int ,num2 int) int{ } ``` +### Rust +```rust +pub fn candy(ratings: Vec) -> i32 { + let mut candies = vec![1i32; ratings.len()]; + for i in 1..ratings.len() { + if ratings[i - 1] < ratings[i] { + candies[i] = candies[i - 1] + 1; + } + } + + for i in (0..ratings.len()-1).rev() { + if ratings[i] > ratings[i + 1] { + candies[i] = candies[i].max(candies[i + 1] + 1); + } + } + candies.iter().sum() +} +``` + ### Javascript: ```Javascript var candy = function(ratings) { @@ -229,7 +248,7 @@ var candy = function(ratings) { candys[i] = Math.max(candys[i], candys[i + 1] + 1) } } - + let count = candys.reduce((a, b) => { return a + b }) diff --git a/problems/0300.最长上升子序列.md b/problems/0300.最长上升子序列.md index f68edb5a..cfa8ae12 100644 --- a/problems/0300.最长上升子序列.md +++ b/problems/0300.最长上升子序列.md @@ -201,6 +201,23 @@ func max(x, y int) int { } ``` +Rust: +```rust +pub fn length_of_lis(nums: Vec) -> i32 { + let mut dp = vec![1; nums.len() + 1]; + let mut result = 1; + for i in 1..nums.len() { + for j in 0..i { + if nums[j] < nums[i] { + dp[i] = dp[i].max(dp[j] + 1); + } + result = result.max(dp[i]); + } + } + result +} +``` + Javascript ```javascript const lengthOfLIS = (nums) => { diff --git a/problems/0322.零钱兑换.md b/problems/0322.零钱兑换.md index 3a8d0662..43c735be 100644 --- a/problems/0322.零钱兑换.md +++ b/problems/0322.零钱兑换.md @@ -220,7 +220,7 @@ class Solution: for j in range(coin, amount + 1): dp[j] = min(dp[j], dp[j - coin] + 1) return dp[amount] if dp[amount] < amount + 1 else -1 - + def coinChange1(self, coins: List[int], amount: int) -> int: '''版本二''' # 初始化 @@ -302,6 +302,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); + } + } + } + if dp[amount] == i32::MAX { -1 } else { dp[amount] } +} +``` + Javascript: ```javascript const coinChange = (coins, amount) => { diff --git a/problems/0455.分发饼干.md b/problems/0455.分发饼干.md index d95a407a..17db4a85 100644 --- a/problems/0455.分发饼干.md +++ b/problems/0455.分发饼干.md @@ -106,7 +106,7 @@ public: ## 其他语言版本 -### Java +### Java ```java class Solution { // 思路1:优先考虑饼干,小饼干先喂饱小胃口 @@ -145,7 +145,7 @@ class Solution { } ``` -### Python +### Python ```python class Solution: # 思路1:优先考虑胃饼干 @@ -166,13 +166,13 @@ class Solution: s.sort() start, count = len(s) - 1, 0 for index in range(len(g) - 1, -1, -1): # 先喂饱大胃口 - if start >= 0 and g[index] <= s[start]: + if start >= 0 and g[index] <= s[start]: start -= 1 count += 1 return count ``` -### Go +### Go ```golang //排序后,局部最优 func findContentChildren(g []int, s []int) int { @@ -191,7 +191,27 @@ func findContentChildren(g []int, s []int) int { } ``` -### Javascript +### Rust +```rust +pub fn find_content_children(children: Vec, cookie: Vec) -> i32 { + let mut children = children; + let mut cookies = cookie; + children.sort(); + cookies.sort(); + + let (mut child, mut cookie) = (0usize, 0usize); + while child < children.len() && cookie < cookies.len() { + // 优先选择最小饼干喂饱孩子 + if children[child] <= cookies[cookie] { + child += 1; + } + cookie += 1 + } + child as i32 +} +``` + +### Javascript ```js var findContentChildren = function(g, s) { g = g.sort((a, b) => a - b) @@ -203,7 +223,7 @@ var findContentChildren = function(g, s) { result++ index-- } - } + } return result }; @@ -251,7 +271,7 @@ function findContentChildren(g: number[], s: number[]): number { }; ``` -### C +### C ```c int cmp(int* a, int* b) { @@ -261,7 +281,7 @@ int cmp(int* a, int* b) { int findContentChildren(int* g, int gSize, int* s, int sSize){ if(sSize == 0) return 0; - + //将两个数组排序为升序 qsort(g, gSize, sizeof(int), cmp); qsort(s, sSize, sizeof(int), cmp); diff --git a/problems/0518.零钱兑换II.md b/problems/0518.零钱兑换II.md index e72c5f85..0e4a3987 100644 --- a/problems/0518.零钱兑换II.md +++ b/problems/0518.零钱兑换II.md @@ -242,6 +242,22 @@ func change(amount int, coins []int) int { } ``` +Rust: +```rust +pub fn change(amount: i32, coins: Vec) -> i32 { + let amount = amount as usize; + let coins = coins.iter().map(|&c|c as usize).collect::>(); + let mut dp = vec![0usize; amount + 1]; + dp[0] = 1; + for i in 0..coins.len() { + for j in coins[i]..=amount { + dp[j] += dp[j - coins[i]]; + } + } + dp[amount] as i32 +} +``` + Javascript: ```javascript const change = (amount, coins) => { diff --git a/problems/0674.最长连续递增序列.md b/problems/0674.最长连续递增序列.md index 56e95d97..4f571d09 100644 --- a/problems/0674.最长连续递增序列.md +++ b/problems/0674.最长连续递增序列.md @@ -218,6 +218,7 @@ class Solution: return result ``` + > 贪心法: ```python class Solution: @@ -276,6 +277,24 @@ func findLengthOfLCIS(nums []int) int { } ``` +Rust: +```rust +pub fn find_length_of_lcis(nums: Vec) -> i32 { + if nums.is_empty() { + return 0; + } + let mut result = 1; + let mut dp = vec![1; nums.len()]; + for i in 1..nums.len() { + if nums[i - 1] < nums[i] { + dp[i] = dp[i - 1] + 1; + result = result.max(dp[i]); + } + } + result +} +``` + Javascript: > 动态规划: diff --git a/problems/1035.不相交的线.md b/problems/1035.不相交的线.md index 0602e111..279ed816 100644 --- a/problems/1035.不相交的线.md +++ b/problems/1035.不相交的线.md @@ -111,7 +111,6 @@ class Solution: Golang: ```go - func maxUncrossedLines(A []int, B []int) int { m, n := len(A), len(B) dp := make([][]int, m+1) @@ -140,7 +139,26 @@ func max(a, b int) int { } ``` +Rust: +```rust +pub fn max_uncrossed_lines(nums1: Vec, nums2: Vec) -> i32 { + let (n, m) = (nums1.len(), nums2.len()); + let mut last = vec![0; m + 1]; // 记录滚动数组 + let mut dp = vec![0; m + 1]; + for i in 1..=n { + dp.swap_with_slice(&mut last); + for j in 1..=m { + if nums1[i - 1] == nums2[j - 1] { + dp[j] = last[j - 1] + 1; + } else { + dp[j] = last[j].max(dp[j - 1]); + } + } + } + dp[m] +} +``` JavaScript: diff --git a/problems/1143.最长公共子序列.md b/problems/1143.最长公共子序列.md index fdcc7619..ecedf89b 100644 --- a/problems/1143.最长公共子序列.md +++ b/problems/1143.最长公共子序列.md @@ -4,40 +4,40 @@

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

-## 1143.最长公共子序列 +## 1143.最长公共子序列 [力扣题目链接](https://leetcode-cn.com/problems/longest-common-subsequence/) -给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。 +给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。 -一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。 +一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。 -例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。 +例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。 -若这两个字符串没有公共子序列,则返回 0。 +若这两个字符串没有公共子序列,则返回 0。 -示例 1: +示例 1: -输入:text1 = "abcde", text2 = "ace" -输出:3 -解释:最长公共子序列是 "ace",它的长度为 3。 +输入:text1 = "abcde", text2 = "ace" +输出:3 +解释:最长公共子序列是 "ace",它的长度为 3。 -示例 2: -输入:text1 = "abc", text2 = "abc" -输出:3 -解释:最长公共子序列是 "abc",它的长度为 3。 +示例 2: +输入:text1 = "abc", text2 = "abc" +输出:3 +解释:最长公共子序列是 "abc",它的长度为 3。 -示例 3: -输入:text1 = "abc", text2 = "def" -输出:0 -解释:两个字符串没有公共子序列,返回 0。 +示例 3: +输入:text1 = "abc", text2 = "def" +输出:0 +解释:两个字符串没有公共子序列,返回 0。 -提示: +提示: * 1 <= text1.length <= 1000 * 1 <= text2.length <= 1000 输入的字符串只含有小写英文字符。 -## 思路 +## 思路 本题和[动态规划:718. 最长重复子数组](https://programmercarl.com/0718.最长重复子数组.html)区别在于这里不要求是连续的了,但要有相对顺序,即:"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。 @@ -45,21 +45,21 @@ 1. 确定dp数组(dp table)以及下标的含义 -dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j] +dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j] -有同学会问:为什么要定义长度为[0, i - 1]的字符串text1,定义为长度为[0, i]的字符串text1不香么? +有同学会问:为什么要定义长度为[0, i - 1]的字符串text1,定义为长度为[0, i]的字符串text1不香么? 这样定义是为了后面代码实现方便,如果非要定义为为长度为[0, i]的字符串text1也可以,大家可以试一试! 2. 确定递推公式 -主要就是两大情况: text1[i - 1] 与 text2[j - 1]相同,text1[i - 1] 与 text2[j - 1]不相同 +主要就是两大情况: text1[i - 1] 与 text2[j - 1]相同,text1[i - 1] 与 text2[j - 1]不相同 -如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1; +如果text1[i - 1] 与 text2[j - 1]相同,那么找到了一个公共元素,所以dp[i][j] = dp[i - 1][j - 1] + 1; 如果text1[i - 1] 与 text2[j - 1]不相同,那就看看text1[0, i - 2]与text2[0, j - 1]的最长公共子序列 和 text1[0, i - 1]与text2[0, j - 2]的最长公共子序列,取最大的。 -即:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); +即:dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 代码如下: @@ -71,9 +71,9 @@ if (text1[i - 1] == text2[j - 1]) { } ``` -3. dp数组如何初始化 +3. dp数组如何初始化 -先看看dp[i][0]应该是多少呢? +先看看dp[i][0]应该是多少呢? test1[0, i-1]和空串的最长公共子序列自然是0,所以dp[i][0] = 0; @@ -101,7 +101,7 @@ vector> dp(text1.size() + 1, vector(text2.size() + 1, 0)); ![1143.最长公共子序列1](https://img-blog.csdnimg.cn/20210210150215918.jpg) -最后红框dp[text1.size()][text2.size()]为最终结果 +最后红框dp[text1.size()][text2.size()]为最终结果 以上分析完毕,C++代码如下: @@ -158,7 +158,7 @@ class Solution: 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[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] @@ -189,10 +189,32 @@ func longestCommonSubsequence(text1 string, text2 string) int { func max(a,b int)int { if a>b{ - return a + return a } return b } + +``` + +Rust: +```rust +pub fn longest_common_subsequence(text1: String, text2: String) -> i32 { + let (n, m) = (text1.len(), text2.len()); + let (s1, s2) = (text1.as_bytes(), text2.as_bytes()); + let mut dp = vec![0; m + 1]; + let mut last = vec![0; m + 1]; + for i in 1..=n { + dp.swap_with_slice(&mut last); + for j in 1..=m { + dp[j] = if s1[i - 1] == s2[j - 1] { + last[j - 1] + 1 + } else { + last[j].max(dp[j - 1]) + }; + } + } + dp[m] +} ``` Javascript: