Merge branch 'master' of github.com:youngyangyang04/leetcode-master

This commit is contained in:
programmercarl
2022-12-23 09:52:47 +08:00
14 changed files with 348 additions and 249 deletions

View File

@ -615,6 +615,68 @@ char * longestPalindrome(char * s){
} }
``` ```
C#
動態規則:
```c#
public class Solution {
public string LongestPalindrome(string s) {
bool[,] dp = new bool[s.Length, s.Length];
int maxlenth = 0;
int left = 0;
int right = 0;
for(int i = s.Length-1 ; i>=0; i--){
for(int j = i; j <s.Length;j++){
if(s[i] == s[j]){
if(j - i <= 1){ // 情况一和情况二
dp[i, j] = true;
}else if( dp[i+1, j-1] ){ // 情况三
dp[i, j] = true;
}
}
if(dp[i, j] && j-i+1 > maxlenth){
maxlenth = j-i+1;
left = i;
right = j;
}
}
}
return s.Substring(left, maxlenth);
}
}
```
雙指針:
```C#
public class Solution {
int maxlenth = 0;
int left = 0;
int right = 0;
public string LongestPalindrome(string s) {
int result = 0;
for (int i = 0; i < s.Length; i++) {
extend(s, i, i, s.Length); // 以i為中心
extend(s, i, i + 1, s.Length); // 以i和i+1為中心
}
return s.Substring(left, maxlenth);
}
private void extend(string s, int i, int j, int n) {
while (i >= 0 && j < n && s[i] == s[j]) {
if (j - i + 1 > maxlenth) {
left = i;
right = j;
maxlenth = j - i + 1;
}
i--;
j++;
}
}
}
```
<p align="center"> <p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank"> <a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/> <img src="../pics/网站星球宣传海报.jpg" width="1000"/>

View File

@ -207,21 +207,23 @@ class Solution:
``` ```
### Go ### Go
```golang ```go
func merge(intervals [][]int) [][]int { func merge(intervals [][]int) [][]int {
//先从小到大排序
sort.Slice(intervals, func(i, j int) bool { sort.Slice(intervals, func(i, j int) bool {
return intervals[i][0] < intervals[j][0] return intervals[i][0] < intervals[j][0]
}) })
//再弄重复的 res := make([][]int, 0, len(intervals))
for i:=0;i<len(intervals)-1;i++{ left, right := intervals[0][0], intervals[0][1]
if intervals[i][1]>=intervals[i+1][0]{ for i := 1; i < len(intervals); i++ {
intervals[i][1]=max(intervals[i][1],intervals[i+1][1])//赋值最大值 if right < intervals[i][0] {
intervals=append(intervals[:i+1],intervals[i+2:]...) res = append(res, []int{left, right})
i-- left, right = intervals[i][0], intervals[i][1]
} else {
right = max(right, intervals[i][1])
} }
} }
return intervals res = append(res, []int{left, right}) // 将最后一个区间放入
return res
} }
func max(a, b int) int { func max(a, b int) int {
if a > b { if a > b {

View File

@ -69,7 +69,7 @@ dp[3],就是 元素1为头结点搜索树的数量 + 元素2为头结点搜索
**dp[i] 1到i为节点组成的二叉搜索树的个数为dp[i]** **dp[i] 1到i为节点组成的二叉搜索树的个数为dp[i]**
也可以理解是i不同元素节点组成的二叉搜索树的个数为dp[i] ,都是一样的。 也可以理解是i不同元素节点组成的二叉搜索树的个数为dp[i] ,都是一样的。
以下分析如果想不清楚就来回想一下dp[i]的定义 以下分析如果想不清楚就来回想一下dp[i]的定义

View File

@ -384,6 +384,34 @@ object Solution {
} }
``` ```
## rust
```rust
impl Solution {
pub fn lowest_common_ancestor(
root: Option<Rc<RefCell<TreeNode>>>,
p: Option<Rc<RefCell<TreeNode>>>,
q: Option<Rc<RefCell<TreeNode>>>,
) -> Option<Rc<RefCell<TreeNode>>> {
if root == p || root == q || root.is_none() {
return root;
}
let left = Self::lowest_common_ancestor(
root.as_ref().unwrap().borrow().left.clone(),
p.clone(),
q.clone(),
);
let right =
Self::lowest_common_ancestor(root.as_ref().unwrap().borrow().right.clone(), p, q);
match (&left, &right) {
(None, Some(_)) => right,
(Some(_), Some(_)) => root,
_ => left,
}
}
}
```
<p align="center"> <p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank"> <a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/> <img src="../pics/网站星球宣传海报.jpg" width="1000"/>

View File

@ -235,43 +235,6 @@ class Solution:
return dp[n] return dp[n]
``` ```
Python3:
```python
class Solution:
'''版本一,先遍历背包, 再遍历物品'''
def numSquares(self, n: int) -> int:
dp = [n] * (n + 1)
dp[0] = 0
# 遍历背包
for j in range(1, n+1):
for i in range(1, n):
num = i ** 2
if num > j: break
# 遍历物品
if j - num >= 0:
dp[j] = min(dp[j], dp[j - num] + 1)
return dp[n]
class Solution:
'''版本二, 先遍历物品, 再遍历背包'''
def numSquares(self, n: int) -> int:
# 初始化
# 组成和的完全平方数的最多个数就是只用1构成
# 因此dp[i] = i
dp = [i for i in range(n + 1)]
# dp[0] = 0 无意义,只是为了方便记录特殊情况:
# n本身就是完全平方数dp[n] = min(dp[n], dp[n - n] + 1) = 1
for i in range(1, n): # 遍历物品
if i * i > n:
break
num = i * i
for j in range(num, n + 1): # 遍历背包
dp[j] = min(dp[j], dp[j - num] + 1)
return dp[n]
```
Go Go
```go ```go
// 版本一,先遍历物品, 再遍历背包 // 版本一,先遍历物品, 再遍历背包

View File

@ -32,7 +32,7 @@
## 思路 ## 思路
这道题目初步看,如下两题几乎是一样的,大家可以用回溯法,解决如下两题 这道题目初步看,如下两题几乎是一样的,大家可以用回溯法,解决如下两题
* 698.划分为k个相等的子集 * 698.划分为k个相等的子集
* 473.火柴拼正方形 * 473.火柴拼正方形
@ -62,7 +62,7 @@
回归主题:首先,本题要求集合里能否出现总和为 sum / 2 的子集。 回归主题:首先,本题要求集合里能否出现总和为 sum / 2 的子集。
那么来一一对应一下本题,看看背包问题如来解决。 那么来一一对应一下本题,看看背包问题如来解决。
**只有确定了如下四点才能把01背包问题套到本题上来。** **只有确定了如下四点才能把01背包问题套到本题上来。**
@ -77,9 +77,9 @@
1. 确定dp数组以及下标的含义 1. 确定dp数组以及下标的含义
01背包中dp[j] 表示: 容量为j的背包所背的物品价值可以最大为dp[j]。 01背包中dp[j] 表示: 容量为j的背包所背的物品价值最大可以为dp[j]。
本题中每一个元素的数值是重量,也是价值。 本题中每一个元素的数值是重量,也是价值。
**套到本题dp[j]表示 背包总容量所能装的总重量是j放进物品后背的最大重量为dp[j]** **套到本题dp[j]表示 背包总容量所能装的总重量是j放进物品后背的最大重量为dp[j]**
@ -106,9 +106,9 @@
从dp[j]的定义来看首先dp[0]一定是0。 从dp[j]的定义来看首先dp[0]一定是0。
如果如果题目给的价值都是正整数那么非0下标都初始化为0就可以了如果题目给的价值有负数那么非0下标就要初始化为负无穷。 如果题目给的价值都是正整数那么非0下标都初始化为0就可以了如果题目给的价值有负数那么非0下标就要初始化为负无穷。
**这样才能让dp数组在递归公式的过程中取最大的价值,而不是被初始值覆盖了** **这样才能让dp数组在递的过程中取最大的价值,而不是被初始值覆盖了**
本题题目中 只包含正整数的非空数组所以非0下标的元素初始化为0就可以了。 本题题目中 只包含正整数的非空数组所以非0下标的元素初始化为0就可以了。
@ -220,6 +220,7 @@ class Solution {
} }
``` ```
二维数组版本(易于理解):
```java ```java
public class Solution { public class Solution {
public static void main(String[] args) { public static void main(String[] args) {
@ -288,46 +289,6 @@ false true false false false true true false false false false true
false true false false false true true false false false true true false true false false false true true false false false true true
``` ```
二维数组版本(易于理解):
```Java
class Solution {
public boolean canPartition(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
if (sum % 2 == 1)
return false;
int target = sum / 2;
//dp[i][j]代表可装物品为0-i背包容量为j的情况下背包内容量的最大价值
int[][] dp = new int[nums.length][target + 1];
//初始化,dp[0][j]的最大价值nums[0](if j > weight[i])
//dp[i][0]均为0不用初始化
for (int j = nums[0]; j <= target; j++) {
dp[0][j] = nums[0];
}
//遍历物品,遍历背包
//递推公式:
for (int i = 1; i < nums.length; i++) {
for (int j = 0; j <= target; j++) {
//背包容量可以容纳nums[i]
if (j >= nums[i]) {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i]);
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[nums.length - 1][target] == target;
}
}
```
### Python ### Python
```python ```python
class Solution: class Solution:
@ -341,6 +302,7 @@ class Solution:
dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]) dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
return target == dp[target] return target == dp[target]
``` ```
### Go ### Go
```go ```go
// 分割等和子集 动态规划 // 分割等和子集 动态规划
@ -369,46 +331,6 @@ func canPartition(nums []int) bool {
} }
``` ```
```go
func canPartition(nums []int) bool {
/**
动态五部曲:
1.确定dp数组和下标含义
2.确定递推公式
3.dp数组初始化
4.dp遍历顺序
5.打印
**/
//确定和
var sum int
for _,v:=range nums{
sum+=v
}
if sum%2!=0{ //如果和为奇数,则不可能分成两个相等的数组
return false
}
sum/=2
//确定dp数组和下标含义
var dp [][]bool //dp[i][j] 表示: 前i个石头是否总和不大于J
//初始化数组
dp=make([][]bool,len(nums)+1)
for i,_:=range dp{
dp[i]=make([]bool,sum+1)
dp[i][0]=true
}
for i:=1;i<=len(nums);i++{
for j:=1;j<=sum;j++{//j是固定总量
if j>=nums[i-1]{//如果容量够用则可放入背包
dp[i][j]=dp[i-1][j]||dp[i-1][j-nums[i-1]]
}else{//如果容量不够用则不拿,维持前一个状态
dp[i][j]=dp[i-1][j]
}
}
}
return dp[len(nums)][sum]
}
```
### javaScript: ### javaScript:
```js ```js

View File

@ -62,9 +62,9 @@
每次取非交叉区间的时候都是可右边界最小的来做分割点这样留给下一个区间的空间就越大所以第一条分割线就是区间1结束的位置。 每次取非交叉区间的时候都是可右边界最小的来做分割点这样留给下一个区间的空间就越大所以第一条分割线就是区间1结束的位置。
接下来就是找大于区间1结束位置的区间是从区间4开始。**那有同学问了为什么不从区间5开始别忘已经是按照右边界排序的了**。 接下来就是找大于区间1结束位置的区间是从区间4开始。**那有同学问了为什么不从区间5开始别忘已经是按照右边界排序的了**。
区间4结束之后找到区间6所以一共记录非交叉区间的个数是三个。 区间4结束之后找到区间6所以一共记录非交叉区间的个数是三个。
总共区间个数为6减去非交叉区间的个数3。移除区间的最小数量就是3。 总共区间个数为6减去非交叉区间的个数3。移除区间的最小数量就是3。
@ -184,22 +184,18 @@ public:
class Solution { class Solution {
public int eraseOverlapIntervals(int[][] intervals) { public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a,b)-> { Arrays.sort(intervals, (a,b)-> {
// 按照区间右边界升序排序 return Integer.compare(a[0],b[0]);
return a[1] - b[1];
}); });
int count = 1;
int count = 0; for(int i = 1;i < intervals.length;i++){
int edge = Integer.MIN_VALUE; if(intervals[i][0] < intervals[i-1][1]){
for (int i = 0; i < intervals.length; i++) { intervals[i][1] = Math.min(intervals[i - 1][1], intervals[i][1]);
// 若上一个区间的右边界小于当前区间的左边界,说明无交集 continue;
if (edge <= intervals[i][0]) {
edge = intervals[i][1];
}else{ }else{
count++; count++;
} }
} }
return intervals.length - count;
return count;
} }
} }
``` ```
@ -208,7 +204,6 @@ class Solution {
```java ```java
class Solution { class Solution {
public int eraseOverlapIntervals(int[][] intervals) { public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a,b)-> { Arrays.sort(intervals, (a,b)-> {
return Integer.compare(a[0],b[0]); return Integer.compare(a[0],b[0]);
}); });
@ -242,28 +237,27 @@ class Solution:
``` ```
### Go ### Go
```golang ```go
func eraseOverlapIntervals(intervals [][]int) int { func eraseOverlapIntervals(intervals [][]int) int {
var flag int
//先排序
sort.Slice(intervals, func(i, j int) bool { sort.Slice(intervals, func(i, j int) bool {
return intervals[i][0]<intervals[j][0] return intervals[i][1] < intervals[j][1]
}) })
fmt.Println(intervals) res := 1
for i := 1; i < len(intervals); i++ { for i := 1; i < len(intervals); i++ {
if intervals[i-1][1]>intervals[i][0]{ if intervals[i][0] >= intervals[i-1][1] {
flag++ res++
intervals[i][1]=min(intervals[i-1][1],intervals[i][1])//由于是先排序的,所以,第一位是递增顺序,故只需要将临近两个元素的第二个值最小值更新到该元素的第二个值即可作之后的判断 } else {
intervals[i][1] = min(intervals[i - 1][1], intervals[i][1])
} }
} }
return flag return len(intervals) - res
} }
func min(a, b int) int { func min(a, b int) int {
if a>b{ if a < b {
return b
}
return a return a
} }
return b
}
``` ```
### Javascript: ### Javascript:

View File

@ -59,7 +59,7 @@
但本题其实是01背包问题 但本题其实是01背包问题
不过这个背包有两个维度一个是m 一个是n而不同长度的字符串就是不同大小的待装物品。 不过这个背包有两个维度一个是m 一个是n而不同长度的字符串就是不同大小的待装物品。
开始动规五部曲: 开始动规五部曲:
@ -114,7 +114,7 @@ for (string str : strs) { // 遍历物品
有同学可能想那个遍历背包容量的两层for循环先后循序有没有什么讲究 有同学可能想那个遍历背包容量的两层for循环先后循序有没有什么讲究
没讲究,都是物品重量的一个维度,先遍历个都行! 没讲究,都是物品重量的一个维度,先遍历个都行!
5. 举例推导dp数组 5. 举例推导dp数组
@ -152,7 +152,7 @@ public:
## 总结 ## 总结
不少同学刷过这道,可能没有总结这究竟是什么背包。 不少同学刷过这道,可能没有总结这究竟是什么背包。
此时我们讲解了0-1背包的多种应用 此时我们讲解了0-1背包的多种应用
@ -252,53 +252,6 @@ func max(a,b int) int {
return b return b
} }
``` ```
> 传统背包,三维数组法
```golang
func findMaxForm(strs []string, m int, n int) int {
//dp的第一个index代表项目的多少第二个代表的是背包的容量
//所以本处项目的多少是lenstrs容量为m和n
dp:=make([][][]int,len(strs)+1)
for i:=0;i<=len(strs);i++{
//初始化背包容量
strDp:=make([][]int,m+1)
for j:=0;j<m+1;j++{
tmp:=make([]int,n+1)
strDp[j]=tmp
}
dp[i]=strDp
}
for k,value:=range strs{
//统计每个字符串0和1的个数
var zero,one int
for _,v:=range value{
if v=='0'{
zero++
}else{
one++
}
}
k+=1
//计算dp
for i:=0;i<=m;i++{
for j:=0;j<=n;j++{
//如果装不下
dp[k][i][j]=dp[k-1][i][j]
//如果装的下
if i>=zero&&j>=one{
dp[k][i][j]=getMax(dp[k-1][i][j],dp[k-1][i-zero][j-one]+1)
}
}
}
}
return dp[len(strs)][m][n]
}
func getMax(a,b int)int{
if a>b{
return a
}
return b
}
```
### Javascript ### Javascript
```javascript ```javascript

View File

@ -123,7 +123,7 @@ public:
x = (target + sum) / 2 x = (target + sum) / 2
**此时问题就转化为装满容量为x背包有几种方法** **此时问题就转化为装满容量为x背包,有几种方法**
这里的x就是bagSize也就是我们后面要求的背包容量。 这里的x就是bagSize也就是我们后面要求的背包容量。
@ -184,11 +184,11 @@ dp[j] += dp[j - nums[i]]
3. dp数组如何初始化 3. dp数组如何初始化
从递公式可以看出在初始化的时候dp[0] 一定要初始化为1因为dp[0]是在公式中一切递推结果的起源如果dp[0]是0的话结果将都是0。 从递公式可以看出在初始化的时候dp[0] 一定要初始化为1因为dp[0]是在公式中一切递推结果的起源如果dp[0]是0的话结果将都是0。
这里有录友可能认为从dp数组定义来说 dp[0] 应该是0也有录友认为dp[0]应该是1。 这里有录友可能认为从dp数组定义来说 dp[0] 应该是0也有录友认为dp[0]应该是1。
其实不要硬去解释它的含义,咱就把 dp[0]的情况带入本题看看就是应该等于多少。 其实不要硬去解释它的含义,咱就把 dp[0]的情况带入本题看看应该等于多少。
如果数组[0] target = 0那么 bagSize = (target + sum) / 2 = 0。 dp[0]也应该是1 也就是说给数组里的元素 0 前面无论放加法还是减法,都是 1 种方法。 如果数组[0] target = 0那么 bagSize = (target + sum) / 2 = 0。 dp[0]也应该是1 也就是说给数组里的元素 0 前面无论放加法还是减法,都是 1 种方法。
@ -198,7 +198,7 @@ dp[j] += dp[j - nums[i]]
其实 此时最终的dp[0] = 32也就是这五个零 子集的所有组合情况但此dp[0]非彼dp[0]dp[0]能算出32其基础是因为dp[0] = 1 累加起来的。 其实 此时最终的dp[0] = 32也就是这五个零 子集的所有组合情况但此dp[0]非彼dp[0]dp[0]能算出32其基础是因为dp[0] = 1 累加起来的。
dp[j]其他下标对应的数值也应该初始化为0从递公式也可以看出dp[j]要保证是0的初始值才能正确的由dp[j - nums[i]]推导出来。 dp[j]其他下标对应的数值也应该初始化为0从递公式也可以看出dp[j]要保证是0的初始值才能正确的由dp[j - nums[i]]推导出来。
4. 确定遍历顺序 4. 确定遍历顺序
@ -245,7 +245,7 @@ public:
## 总结 ## 总结
此时 大家应该不想起,我们之前讲过的[回溯算法39. 组合总和](https://programmercarl.com/0039.组合总和.html)是不是应该也可以用dp来做啊 此时 大家应该不想起,我们之前讲过的[回溯算法39. 组合总和](https://programmercarl.com/0039.组合总和.html)是不是应该也可以用dp来做啊
是的如果仅仅是求个数的话就可以用dp但[回溯算法39. 组合总和](https://programmercarl.com/0039.组合总和.html)要求的是把所有组合列出来,还是要使用回溯法爆搜的。 是的如果仅仅是求个数的话就可以用dp但[回溯算法39. 组合总和](https://programmercarl.com/0039.组合总和.html)要求的是把所有组合列出来,还是要使用回溯法爆搜的。

View File

@ -837,6 +837,93 @@ object Solution {
} }
``` ```
## rust
递归:
```rust
impl Solution {
pub fn find_mode(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
let mut count = 0;
let mut max_count = 0;
let mut res = vec![];
let mut pre = i32::MIN;
Self::search_bst(&root, &mut pre, &mut res, &mut count, &mut max_count);
res
}
pub fn search_bst(
cur: &Option<Rc<RefCell<TreeNode>>>,
mut pre: &mut i32,
res: &mut Vec<i32>,
count: &mut i32,
max_count: &mut i32,
) {
if cur.is_none() {
return;
}
let cur_node = cur.as_ref().unwrap().borrow();
Self::search_bst(&cur_node.left, pre, res, count, max_count);
if *pre == i32::MIN {
*count = 1;
} else if *pre == cur_node.val {
*count += 1;
} else {
*count = 1;
};
match count.cmp(&max_count) {
std::cmp::Ordering::Equal => res.push(cur_node.val),
std::cmp::Ordering::Greater => {
*max_count = *count;
res.clear();
res.push(cur_node.val);
}
_ => {}
};
*pre = cur_node.val;
Self::search_bst(&cur_node.right, pre, res, count, max_count);
}
}
```
迭代:
```rust
pub fn find_mode(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
let (mut cur, mut pre) = (root, i32::MIN);
let mut res = vec![];
let mut stack = vec![];
let (mut count, mut max_count) = (0, 0);
while !stack.is_empty() || cur.is_some() {
while let Some(node) = cur {
cur = node.borrow().left.clone();
stack.push(node);
}
if let Some(node) = stack.pop() {
if pre == i32::MIN {
count = 1;
} else if pre == node.borrow().val {
count += 1;
} else {
count = 1;
}
match count.cmp(&max_count) {
std::cmp::Ordering::Equal => res.push(node.borrow().val),
std::cmp::Ordering::Greater => {
max_count = count;
res.clear();
res.push(node.borrow().val);
}
_ => {}
}
pre = node.borrow().val;
cur = node.borrow().right.clone();
}
}
res
}
```
<p align="center"> <p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank"> <a href="https://programmercarl.com/other/kstar.html" target="_blank">

View File

@ -493,6 +493,93 @@ object Solution {
} }
``` ```
## rust
构建二叉树的有序数组:
```rust
use std::cell::RefCell;
use std::rc::Rc;
impl Solution {
pub fn get_minimum_difference(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
let mut vec = vec![];
Self::traversal(root, &mut vec);
let mut min = i32::MAX;
for i in 1..vec.len() {
min = min.min(vec[i] - vec[i - 1])
}
min
}
pub fn traversal(root: Option<Rc<RefCell<TreeNode>>>, v: &mut Vec<i32>) {
if root.is_none() {
return;
}
let node = root.as_ref().unwrap().borrow();
Self::traversal(node.left.clone(), v);
v.push(node.val);
Self::traversal(node.right.clone(), v);
}
}
```
递归中解决
```rust
impl Solution {
pub fn get_minimum_difference(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
let mut pre = None;
let mut min = i32::MAX;
Self::inorder(root, &mut pre, &mut min);
min
}
pub fn inorder(root: Option<Rc<RefCell<TreeNode>>>, pre: &mut Option<i32>, min: &mut i32) {
if root.is_none() {
return;
}
let node = root.as_ref().unwrap().borrow();
Self::inorder(node.left.clone(), pre, min);
if let Some(pre) = pre {
*min = (node.val - *pre).min(*min);
}
*pre = Some(node.val);
Self::inorder(node.right.clone(), pre, min);
}
}
```
迭代
```rust
impl Solution {
pub fn get_minimum_difference(mut root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
if root.is_none() {
return 0;
}
let mut stack = vec![];
let mut pre = -1;
let mut res = i32::MAX;
while root.is_some() || !stack.is_empty() {
while let Some(node) = root {
root = node.borrow().left.clone();
stack.push(node);
}
let node = stack.pop().unwrap();
if pre >= 0 {
res = res.min(node.borrow().val - pre);
}
pre = node.borrow().val;
root = node.borrow().right.clone();
}
res
}
}
```
<p align="center"> <p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank"> <a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/> <img src="../pics/网站星球宣传海报.jpg" width="1000"/>

View File

@ -341,7 +341,7 @@ class Solution {
if (node1.left == null && node2.left != null) { if (node1.left == null && node2.left != null) {
node1.left = node2.left; node1.left = node2.left;
} }
// 若node2的左节点为空,直接赋值 // 若node1的右节点为空,直接赋值
if (node1.right == null && node2.right != null) { if (node1.right == null && node2.right != null) {
node1.right = node2.right; node1.right = node2.right;
} }
@ -732,3 +732,4 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank"> <a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/> <img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a> </a>

View File

@ -217,7 +217,7 @@ class Solution: # 贪心思路
``` ```
### Go ### Go
```golang ```go
func maxProfit(prices []int, fee int) int { func maxProfit(prices []int, fee int) int {
var minBuy int = prices[0] //第一天买入 var minBuy int = prices[0] //第一天买入
var res int var res int

View File

@ -179,7 +179,7 @@ class Solution:
``` ```
### Go ### Go
```golang ```go
func monotoneIncreasingDigits(N int) int { func monotoneIncreasingDigits(N int) int {
s := strconv.Itoa(N)//将数字转为字符串,方便使用下标 s := strconv.Itoa(N)//将数字转为字符串,方便使用下标
ss := []byte(s)//将字符串转为byte数组方便更改。 ss := []byte(s)//将字符串转为byte数组方便更改。