diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index a15e1349..5bedd0a0 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -263,13 +263,15 @@ php ```php function twoSum(array $nums, int $target): array { - for ($i = 0; $i < count($nums);$i++) { - // 计算剩下的数 - $residue = $target - $nums[$i]; - // 匹配的index,有则返回index, 无则返回false - $match_index = array_search($residue, $nums); - if ($match_index !== false && $match_index != $i) { - return array($i, $match_index); + $map = []; + foreach($nums as $i => $num) { + if (isset($map[$target - $num])) { + return [ + $i, + $map[$target - $num] + ]; + } else { + $map[$num] = $i; } } return []; diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md index da319866..a4b6b84d 100644 --- a/problems/0015.三数之和.md +++ b/problems/0015.三数之和.md @@ -493,6 +493,9 @@ function threeSum(nums: number[]): number[][] { right: number = length - 1; let resArr: number[][] = []; for (let i = 0; i < length; i++) { + if (nums[i]>0) { + return resArr; //nums经过排序后,只要nums[i]>0, 此后的nums[i] + nums[left] + nums[right]均大于0,可以提前终止循环。 + } if (i > 0 && nums[i] === nums[i - 1]) { continue; } diff --git a/problems/0019.删除链表的倒数第N个节点.md b/problems/0019.删除链表的倒数第N个节点.md index 65a4e383..00caeea0 100644 --- a/problems/0019.删除链表的倒数第N个节点.md +++ b/problems/0019.删除链表的倒数第N个节点.md @@ -191,18 +191,20 @@ TypeScript: ```typescript function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null { let newHead: ListNode | null = new ListNode(0, head); - let slowNode: ListNode | null = newHead, - fastNode: ListNode | null = newHead; - for (let i = 0; i < n; i++) { - fastNode = fastNode.next; + //根据leetcode题目的定义可推断这里快慢指针均不需要定义为ListNode | null。 + let slowNode: ListNode = newHead; + let fastNode: ListNode = newHead; + + while(n--) { + fastNode = fastNode.next!; //由虚拟头节点前进n个节点时,fastNode.next可推断不为null。 } - while (fastNode.next) { + while(fastNode.next) { //遍历直至fastNode.next = null, 即尾部节点。 此时slowNode指向倒数第n个节点。 fastNode = fastNode.next; - slowNode = slowNode.next; + slowNode = slowNode.next!; } - slowNode.next = slowNode.next.next; - return newHead.next; -}; + slowNode.next = slowNode.next!.next; //倒数第n个节点可推断其next节点不为空。 + return newHead.next; +} ``` 版本二(计算节点总数法): diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 905a0539..10337a7f 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -337,5 +337,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; //返回翻转后的头结点 +} +``` + -----------------------
diff --git a/problems/0056.合并区间.md b/problems/0056.合并区间.md index 627ca5b1..26a8010d 100644 --- a/problems/0056.合并区间.md +++ b/problems/0056.合并区间.md @@ -329,5 +329,31 @@ object Solution { } ``` +### Rust + +```Rust +impl Solution { + fn max(a: i32, b: i32) -> i32 { + if a > b { a } else { b } + } + + pub fn merge(intervals: Vec>) -> Vec> { + let mut intervals = intervals; + let mut result = Vec::new(); + if intervals.len() == 0 { return result; } + intervals.sort_by(|a, b| a[0].cmp(&b[0])); + result.push(intervals[0].clone()); + for i in 1..intervals.len() { + if result.last_mut().unwrap()[1] >= intervals[i][0] { + result.last_mut().unwrap()[1] = Self::max(result.last_mut().unwrap()[1], intervals[i][1]); + } else { + result.push(intervals[i].clone()); + } + } + result + } +} +``` + -----------------------
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型的参数。 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 diff --git a/problems/0100.相同的树.md b/problems/0100.相同的树.md index 210418f7..4b6eb7aa 100644 --- a/problems/0100.相同的树.md +++ b/problems/0100.相同的树.md @@ -240,6 +240,20 @@ Go: JavaScript: +> 递归法 + +```javascript +var isSameTree = function (p, q) { + if (p == null && q == null) + return true; + if (p == null || q == null) + return false; + if (p.val != q.val) + return false; + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); +}; +``` + TypeScript: > 递归法-先序遍历 diff --git a/problems/0134.加油站.md b/problems/0134.加油站.md index 7e4f74f0..4e698d1b 100644 --- a/problems/0134.加油站.md +++ b/problems/0134.加油站.md @@ -405,6 +405,55 @@ function canCompleteCircuit(gas: number[], cost: number[]): number { }; ``` +### Rust + +贪心算法:方法一 + +```Rust +impl Solution { + pub fn can_complete_circuit(gas: Vec, cost: Vec) -> i32 { + let mut cur_sum = 0; + let mut min = i32::MAX; + for i in 0..gas.len() { + let rest = gas[i] - cost[i]; + cur_sum += rest; + if cur_sum < min { min = cur_sum; } + } + if cur_sum < 0 { return -1; } + if min > 0 { return 0; } + for i in (0..gas.len()).rev() { + let rest = gas[i] - cost[i]; + min += rest; + if min >= 0 { return i as i32; } + } + -1 + } +} +``` + +贪心算法:方法二 + +```Rust +impl Solution { + pub fn can_complete_circuit(gas: Vec, cost: Vec) -> i32 { + let mut cur_sum = 0; + let mut total_sum = 0; + let mut start = 0; + for i in 0..gas.len() { + cur_sum += gas[i] - cost[i]; + total_sum += gas[i] - cost[i]; + if cur_sum < 0 { + start = i + 1; + cur_sum = 0; + } + } + if total_sum < 0 { return -1; } + start as i32 + } +} +``` + + ### C 贪心算法:方法一 diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md index 6fd9b66f..5622fd1c 100644 --- a/problems/0203.移除链表元素.md +++ b/problems/0203.移除链表元素.md @@ -385,7 +385,8 @@ function removeElements(head: ListNode | null, val: number): ListNode | null { if (cur.val === val) { pre.next = cur.next; } else { - pre = pre.next; + //此处不加类型断言时:编译器会认为pre类型为ListNode, pre.next类型为ListNode | null + pre = pre.next as ListNode; } cur = cur.next; } diff --git a/problems/0337.打家劫舍III.md b/problems/0337.打家劫舍III.md index b293bf6f..20b458e9 100644 --- a/problems/0337.打家劫舍III.md +++ b/problems/0337.打家劫舍III.md @@ -190,9 +190,9 @@ public: if (cur == NULL) return vector{0, 0}; vector left = robTree(cur->left); vector right = robTree(cur->right); - // 偷cur - int val1 = cur->val + left[0] + right[0]; - // 不偷cur + // 偷cur,那么就不能偷左右节点。 + int val1 = cur->val + left[1] + right[1]; + // 不偷cur,那么可以偷也可以不偷左右节点,则取较大的情况 int val2 = max(left[0], left[1]) + max(right[0], right[1]); return {val2, val1}; } diff --git a/problems/0343.整数拆分.md b/problems/0343.整数拆分.md index a4d532fd..0a568b57 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) { @@ -299,6 +314,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 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 + } } ``` diff --git a/problems/0406.根据身高重建队列.md b/problems/0406.根据身高重建队列.md index 827b7481..75e0c40c 100644 --- a/problems/0406.根据身高重建队列.md +++ b/problems/0406.根据身高重建队列.md @@ -290,6 +290,26 @@ var reconstructQueue = function(people) { }; ``` +### Rust + +```Rust +impl Solution { + pub fn reconstruct_queue(people: Vec>) -> Vec> { + let mut people = people; + people.sort_by(|a, b| { + if a[0] == b[0] { return a[1].cmp(&b[1]); } + b[0].cmp(&a[0]) + }); + let mut que: Vec> = Vec::new(); + que.push(people[0].clone()); + for i in 1..people.len() { + let position = people[i][1]; + que.insert(position as usize, people[i].clone()); + } + que + } +} +``` ### C ```c 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: diff --git a/problems/0435.无重叠区间.md b/problems/0435.无重叠区间.md index 3aa4eeb6..6f88cad4 100644 --- a/problems/0435.无重叠区间.md +++ b/problems/0435.无重叠区间.md @@ -374,7 +374,26 @@ object Solution { } ``` +### Rust +```Rust +impl Solution { + pub fn erase_overlap_intervals(intervals: Vec>) -> i32 { + if intervals.len() == 0 { return 0; } + let mut intervals = intervals; + intervals.sort_by(|a, b| a[1].cmp(&b[1])); + let mut count = 1; + let mut end = intervals[0][1]; + for i in 1..intervals.len() { + if end <= intervals[i][0] { + end = intervals[i][1]; + count += 1; + } + } + intervals.len() as i32 - count + } +} +``` ----------------------- diff --git a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md index 6e4a86eb..c573f00d 100644 --- a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md +++ b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md @@ -221,8 +221,46 @@ function maxProfit(prices: number[], fee: number): number { }; ``` +Rust: +**贪心** +```Rust +impl Solution { + pub fn max_profit(prices: Vec, fee: i32) -> i32 { + let mut result = 0; + let mut min_price = prices[0]; + for i in 1..prices.len() { + if prices[i] < min_price { min_price = prices[i]; } + // if prices[i] >= min_price && prices[i] <= min_price + fee { continue; } + if prices[i] > min_price + fee { + result += prices[i] - min_price - fee; + min_price = prices[i] - fee; + } + } + result + } +} +``` + +**动态规划** +```Rust +impl Solution { + fn max(a: i32, b: i32) -> i32 { + if a > b { a } else { b } + } + pub fn max_profit(prices: Vec, fee: i32) -> 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] - fee); + } + Self::max(dp[n - 1][0], dp[n - 1][1]) + } +} +``` -----------------------
diff --git a/problems/0738.单调递增的数字.md b/problems/0738.单调递增的数字.md index 6b7381f3..b452d02d 100644 --- a/problems/0738.单调递增的数字.md +++ b/problems/0738.单调递增的数字.md @@ -278,5 +278,26 @@ object Solution { } ``` +### Rust + +```Rust +impl Solution { + pub fn monotone_increasing_digits(n: i32) -> i32 { + let mut str_num = n.to_string().chars().map(|x| x.to_digit(10).unwrap() as i32).collect::>(); + let mut flag = str_num.len(); + for i in (1..str_num.len()).rev() { + if str_num[i - 1] > str_num[i] { + flag = i; + str_num[i - 1] -= 1; + } + } + for i in flag..str_num.len() { + str_num[i] = 9; + } + str_num.iter().fold(0, |acc, x| acc * 10 + x) + } +} +``` + -----------------------
diff --git a/problems/0763.划分字母区间.md b/problems/0763.划分字母区间.md index ecf064d3..a6066ebc 100644 --- a/problems/0763.划分字母区间.md +++ b/problems/0763.划分字母区间.md @@ -343,6 +343,34 @@ object Solution { } ``` +### Rust + +```Rust +use std::collections::HashMap; +impl Solution { + fn max (a: usize, b: usize) -> usize { + if a > b { a } else { b } + } + pub fn partition_labels(s: String) -> Vec { + let s = s.chars().collect::>(); + let mut hash: HashMap = HashMap::new(); + for i in 0..s.len() { + hash.insert(s[i], i); + } + let mut result: Vec = Vec::new(); + let mut left: usize = 0; + let mut right: usize = 0; + for i in 0..s.len() { + right = Self::max(right, hash[&s[i]]); + if i == right { + result.push((right - left + 1) as i32); + left = i + 1; + } + } + result + } +} +``` -----------------------
diff --git a/problems/0860.柠檬水找零.md b/problems/0860.柠檬水找零.md index 42e8b19a..16b89ff7 100644 --- a/problems/0860.柠檬水找零.md +++ b/problems/0860.柠檬水找零.md @@ -251,6 +251,38 @@ var lemonadeChange = function(bills) { }; ``` + +### Rust + +```Rust +impl Solution { + pub fn lemonade_change(bills: Vec) -> bool { + let mut five = 0; + let mut ten = 0; + // let mut twenty = 0; + for bill in bills { + if bill == 5 { five += 1; } + if bill == 10 { + if five <= 0 { return false; } + ten += 1; + five -= 1; + } + if bill == 20 { + if five > 0 && ten > 0 { + five -= 1; + ten -= 1; + // twenty += 1; + } else if five >= 3 { + five -= 3; + // twenty += 1; + } else { return false; } + } + } + true + } +} +``` + ### C ```c bool lemonadeChange(int* bills, int billsSize){ 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 diff --git a/problems/链表理论基础.md b/problems/链表理论基础.md index 1a29c32a..8378f7f2 100644 --- a/problems/链表理论基础.md +++ b/problems/链表理论基础.md @@ -186,7 +186,7 @@ TypeScript: ```typescript class ListNode { public val: number; - public next: ListNode = null; + public next: ListNode|null = null; constructor(value: number) { this.val = value; this.next = null; diff --git a/problems/面试题02.07.链表相交.md b/problems/面试题02.07.链表相交.md index abf7a2f8..6d6810a3 100644 --- a/problems/面试题02.07.链表相交.md +++ b/problems/面试题02.07.链表相交.md @@ -5,7 +5,9 @@

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

-# 面试题 02.07. 链表相交 +# 面试题 02.07. 链表相交 + +同:160.链表相交 [力扣题目链接](https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/) diff --git a/添加0222.完全二叉树的节点个数Go版本.md b/添加0222.完全二叉树的节点个数Go版本.md new file mode 100644 index 00000000..6001e7b7 --- /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..3172837d --- /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 +} +``` +