merge PRs
This commit is contained in:
commit
408d01dc4b
62
README.md
62
README.md
|
|
@ -3,7 +3,8 @@
|
|||
> 1. **介绍**:本项目是一套完整的刷题计划,旨在帮助大家少走弯路,循序渐进学算法,[关注作者](#关于作者)
|
||||
> 2. **PDF版本** : [「代码随想录」算法精讲 PDF 版本](https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ) 。
|
||||
> 3. **学习社区** : 一起学习打卡/面试技巧/如何选择offer/大厂内推/职场规则/简历修改/技术分享/程序人生。欢迎加入[「代码随想录」学习社区](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) 。
|
||||
> 4. **转载须知** :以下所有文章皆为我([程序员Carl](https://github.com/youngyangyang04))的原创。引用本项目文章请注明出处,发现恶意抄袭或搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!
|
||||
> 4. **提交代码**:本项目统一使用C++语言进行讲解,但已经有Java、Python、Go、JavaScript等等多语言版本,感谢[这里的每一位贡献者](https://github.com/youngyangyang04/leetcode-master/graphs/contributors),如果你也想贡献代码点亮你的头像,[点击这里](https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A)了解提交代码的方式。
|
||||
> 5. **转载须知** :以下所有文章皆为我([程序员Carl](https://github.com/youngyangyang04))的原创。引用本项目文章请注明出处,发现恶意抄袭或搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/youngyangyang04/leetcode-master" target="_blank">
|
||||
|
|
@ -11,11 +12,16 @@
|
|||
</a>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ" target="_blank">
|
||||
<img src="./pics/知识星球.png" width="600"/>
|
||||
</a>
|
||||
|
||||
|
||||
# LeetCode 刷题攻略
|
||||
|
||||
|
|
@ -111,14 +117,24 @@
|
|||
|
||||
(持续更新中.....)
|
||||
|
||||
## 备战秋招
|
||||
|
||||
1. [选择方向的时候,我也迷茫了](https://mp.weixin.qq.com/s/ZCzFiAHZHLqHPLJQXNm75g)
|
||||
2. [刷题就用库函数了,怎么了?](https://mp.weixin.qq.com/s/6K3_OSaudnHGq2Ey8vqYfg)
|
||||
3. [关于实习,大家可能有点迷茫!](https://mp.weixin.qq.com/s/xcxzi7c78kQGjvZ8hh7taA)
|
||||
4. [马上秋招了,慌得很!](https://mp.weixin.qq.com/s/7q7W8Cb2-a5U5atZdOnOFA)
|
||||
5. [Carl看了上百份简历,总结了这些!](https://mp.weixin.qq.com/s/sJa87MZD28piCOVMFkIbwQ)
|
||||
6. [面试中遇到了发散性问题.....](https://mp.weixin.qq.com/s/SSonDxi2pjkSVwHNzZswng)
|
||||
|
||||
## 数组
|
||||
|
||||
1. [数组过于简单,但你该了解这些!](./problems/数组理论基础.md)
|
||||
2. [数组:每次遇到二分法,都是一看就会,一写就废](./problems/0704.二分查找.md)
|
||||
3. [数组:就移除个元素很难么?](./problems/0027.移除元素.md)
|
||||
4. [数组:滑动窗口拯救了你](./problems/0209.长度最小的子数组.md)
|
||||
5. [数组:这个循环可以转懵很多人!](./problems/0059.螺旋矩阵II.md)
|
||||
6. [数组:总结篇](./problems/数组总结篇.md)
|
||||
4. [数组:有序数组的平方,还有序么?](./problems/0977.有序数组的平方.md)
|
||||
5. [数组:滑动窗口拯救了你](./problems/0209.长度最小的子数组.md)
|
||||
6. [数组:这个循环可以转懵很多人!](./problems/0059.螺旋矩阵II.md)
|
||||
7. [数组:总结篇](./problems/数组总结篇.md)
|
||||
|
||||
## 链表
|
||||
|
||||
|
|
@ -169,10 +185,9 @@
|
|||
6. [链表:删除链表的倒数第 N 个结点](./problems/0019.删除链表的倒数第N个节点.md)
|
||||
7. [链表:链表相交](./problems/面试题02.07.链表相交.md)
|
||||
8. [链表:环找到了,那入口呢?](./problems/0142.环形链表II.md)
|
||||
9. [链表:删除链表的倒数第 N 个结点](./problems/0019.删除链表的倒数第N个节点.md)
|
||||
10. [哈希表:解决了两数之和,那么能解决三数之和么?](./problems/0015.三数之和.md)
|
||||
11. [双指针法:一样的道理,能解决四数之和](./problems/0018.四数之和.md)
|
||||
12. [双指针法:总结篇!](./problems/双指针总结.md)
|
||||
9. [哈希表:解决了两数之和,那么能解决三数之和么?](./problems/0015.三数之和.md)
|
||||
10. [双指针法:一样的道理,能解决四数之和](./problems/0018.四数之和.md)
|
||||
11. [双指针法:总结篇!](./problems/双指针总结.md)
|
||||
|
||||
## 栈与队列
|
||||
|
||||
|
|
@ -292,6 +307,7 @@
|
|||
|
||||
动态规划专题已经开始啦,来不及解释了,小伙伴们上车别掉队!
|
||||
|
||||
<img src='https://code-thinking.cdn.bcebos.com/pics/动态规划-总结大纲1.jpg' width=500> </img></div>
|
||||
1. [关于动态规划,你该了解这些!](./problems/动态规划理论基础.md)
|
||||
2. [动态规划:斐波那契数](./problems/0509.斐波那契数.md)
|
||||
3. [动态规划:爬楼梯](./problems/0070.爬楼梯.md)
|
||||
|
|
@ -305,7 +321,8 @@
|
|||
|
||||
背包问题系列:
|
||||
|
||||
<img src='https://img-blog.csdnimg.cn/202102261550480.png' width=500 alt='背包问题大纲'> </img></div>
|
||||
<img src='https://code-thinking.cdn.bcebos.com/pics/动态规划-背包问题总结.png' width=500 alt='背包问题大纲'> </img></div>
|
||||
|
||||
|
||||
11. [动态规划:关于01背包问题,你该了解这些!](./problems/背包理论基础01背包-1.md)
|
||||
12. [动态规划:关于01背包问题,你该了解这些!(滚动数组)](./problems/背包理论基础01背包-2.md)
|
||||
|
|
@ -334,7 +351,8 @@
|
|||
|
||||
股票系列:
|
||||
|
||||
<img src='https://code-thinking.cdn.bcebos.com/pics/%E8%82%A1%E7%A5%A8%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93.jpg' width=500 alt='股票问题总结'> </img></div>
|
||||
<img src='https://code-thinking.cdn.bcebos.com/pics/股票问题总结.jpg' width=500 alt='股票问题总结'> </img></div>
|
||||
|
||||
|
||||
32. [动态规划:买卖股票的最佳时机](./problems/0121.买卖股票的最佳时机.md)
|
||||
33. [动态规划:本周我们都讲了这些(系列六)](./problems/周总结/20210225动规周末总结.md)
|
||||
|
|
@ -348,6 +366,9 @@
|
|||
|
||||
子序列系列:
|
||||
|
||||
<img src='https://code-thinking.cdn.bcebos.com/pics/动态规划-子序列问题总结.jpg' width=500 alt=''> </img></div>
|
||||
|
||||
|
||||
40. [动态规划:最长递增子序列](./problems/0300.最长上升子序列.md)
|
||||
41. [动态规划:最长连续递增序列](./problems/0674.最长连续递增序列.md)
|
||||
42. [动态规划:最长重复子数组](./problems/0718.最长重复子数组.md)
|
||||
|
|
@ -361,10 +382,14 @@
|
|||
52. [为了绝杀编辑距离,Carl做了三步铺垫,你都知道么?](./problems/为了绝杀编辑距离,卡尔做了三步铺垫.md)
|
||||
53. [动态规划:回文子串](./problems/0647.回文子串.md)
|
||||
54. [动态规划:最长回文子序列](./problems/0516.最长回文子序列.md)
|
||||
|
||||
55. [动态规划总结篇](./problems/动态规划总结篇.md)
|
||||
|
||||
(持续更新中....)
|
||||
|
||||
## 单调栈
|
||||
|
||||
1. [每日温度](./problems/0739.每日温度.md)
|
||||
|
||||
## 图论
|
||||
|
||||
## 十大排序
|
||||
|
|
@ -385,12 +410,7 @@
|
|||
|
||||
[各类基础算法模板](https://github.com/youngyangyang04/leetcode/blob/master/problems/算法模板.md)
|
||||
|
||||
# 备战秋招
|
||||
|
||||
1. [技术比较弱,也对技术不感兴趣,如何选择方向?](https://mp.weixin.qq.com/s/ZCzFiAHZHLqHPLJQXNm75g)
|
||||
2. [刷题就用库函数了,怎么了?](https://mp.weixin.qq.com/s/6K3_OSaudnHGq2Ey8vqYfg)
|
||||
3. [关于实习,大家可能有点迷茫!](https://mp.weixin.qq.com/s/xcxzi7c78kQGjvZ8hh7taA)
|
||||
4. [马上秋招了,慌得很!](https://mp.weixin.qq.com/s/7q7W8Cb2-a5U5atZdOnOFA)
|
||||
|
||||
# B站算法视频讲解
|
||||
|
||||
|
|
@ -409,6 +429,10 @@
|
|||
|
||||
(持续更新中....)
|
||||
|
||||
# 贡献者
|
||||
|
||||
你可以[点此链接](https://github.com/youngyangyang04/leetcode-master/graphs/contributors)查看LeetCode-Master的所有贡献者。感谢你们补充了LeetCode-Master的其他语言版本,让更多的读者收益于此项目。
|
||||
|
||||
# 关于作者
|
||||
|
||||
大家好,我是程序员Carl,哈工大师兄,ACM 校赛、黑龙江省赛、东北四省赛金牌、亚洲区域赛铜牌获得者,先后在腾讯和百度从事后端技术研发,CSDN博客专家。对算法和C++后端技术有一定的见解,利用工作之余重新刷leetcode。
|
||||
|
|
@ -420,7 +444,7 @@
|
|||
<a name="微信"></a>
|
||||
<img src="https://img-blog.csdnimg.cn/20200814140330894.png" data-img="1" width="175" height="175">
|
||||
|
||||
# 我的公众号
|
||||
# 公众号
|
||||
|
||||
更多精彩文章持续更新,微信搜索:「代码随想录」第一时间围观,关注后回复:「666」可以获得所有算法专题原创PDF。
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 1. 两数之和
|
||||
|
|
@ -29,10 +29,10 @@ https://leetcode-cn.com/problems/two-sum/
|
|||
很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2)。
|
||||
|
||||
建议大家做这道题目之前,先做一下这两道
|
||||
* [242. 有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)
|
||||
* [349. 两个数组的交集](https://mp.weixin.qq.com/s/N9iqAchXreSVW7zXUS4BVA)
|
||||
* [242. 有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA)
|
||||
* [349. 两个数组的交集](https://mp.weixin.qq.com/s/aMSA5zrp3jJcLjuSB0Es2Q)
|
||||
|
||||
[242. 有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig) 这道题目是用数组作为哈希表来解决哈希问题,[349. 两个数组的交集](https://mp.weixin.qq.com/s/N9iqAchXreSVW7zXUS4BVA)这道题目是通过set作为哈希表来解决哈希问题。
|
||||
[242. 有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA) 这道题目是用数组作为哈希表来解决哈希问题,[349. 两个数组的交集](https://mp.weixin.qq.com/s/aMSA5zrp3jJcLjuSB0Es2Q)这道题目是通过set作为哈希表来解决哈希问题。
|
||||
|
||||
本题呢,则要使用map,那么来看一下使用数组和set来做哈希法的局限。
|
||||
|
||||
|
|
@ -51,13 +51,14 @@ C++中map,有三种类型:
|
|||
|
||||
std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。
|
||||
|
||||
同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。 更多哈希表的理论知识请看[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA)。
|
||||
同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。 更多哈希表的理论知识请看[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg)。
|
||||
|
||||
**这道题目中并不需要key有序,选择std::unordered_map 效率更高!**
|
||||
|
||||
解题思路动画如下:
|
||||
|
||||
<video src='https://code-thinking.cdn.bcebos.com/gifs/1.%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C.mp4' controls='controls' width='640' height='320' autoplay='autoplay'> Your browser does not support the video tag.</video></div>
|
||||

|
||||
|
||||
|
||||
C++代码:
|
||||
|
||||
|
|
@ -134,6 +135,21 @@ func twoSum(nums []int, target int) []int {
|
|||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// 使用map方式解题,降低时间复杂度
|
||||
func twoSum(nums []int, target int) []int {
|
||||
m := make(map[int]int)
|
||||
for index, val := range nums {
|
||||
if preIndex, ok := m[target-val]; ok {
|
||||
return []int{preIndex, index}
|
||||
} else {
|
||||
m[val] = index
|
||||
}
|
||||
}
|
||||
return []int{}
|
||||
}
|
||||
```
|
||||
|
||||
Rust
|
||||
|
||||
```rust
|
||||
|
|
@ -156,6 +172,21 @@ impl Solution {
|
|||
}
|
||||
```
|
||||
|
||||
Javascript
|
||||
|
||||
```javascript
|
||||
var twoSum = function (nums, target) {
|
||||
let hash = {};
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
if (hash[target - nums[i]] !== undefined) {
|
||||
return [i, hash[target - nums[i]]];
|
||||
}
|
||||
hash[nums[i]] = i;
|
||||
}
|
||||
return [];
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -105,8 +105,7 @@ public:
|
|||
|
||||
时间复杂度:O(n^2)。
|
||||
|
||||
|
||||
## 双指针法C++代码
|
||||
C++代码代码如下:
|
||||
|
||||
```C++
|
||||
class Solution {
|
||||
|
|
@ -163,13 +162,14 @@ public:
|
|||
|
||||
# 思考题
|
||||
|
||||
既然三数之和可以使用双指针法,我们之前讲过的[两数之和](https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ),可不可以使用双指针法呢?
|
||||
|
||||
既然三数之和可以使用双指针法,我们之前讲过的[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ),可不可以使用双指针法呢?
|
||||
|
||||
如果不能,题意如何更改就可以使用双指针法呢? **大家留言说出自己的想法吧!**
|
||||
|
||||
两数之和 就不能使用双指针法,因为[两数之和](https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ)要求返回的是索引下表, 而双指针法一定要排序,一旦排序之后原数组的索引就被改变了。
|
||||
两数之和 就不能使用双指针法,因为[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ)要求返回的是索引下表, 而双指针法一定要排序,一旦排序之后原数组的索引就被改变了。
|
||||
|
||||
如果[两数之和](https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ)要求返回的是数值的话,就可以使用双指针法了。
|
||||
如果[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ)要求返回的是数值的话,就可以使用双指针法了。
|
||||
|
||||
|
||||
|
||||
|
|
@ -218,8 +218,33 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```Python
|
||||
class Solution:
|
||||
def threeSum(self, nums):
|
||||
ans = []
|
||||
n = len(nums)
|
||||
nums.sort()
|
||||
for i in range(n):
|
||||
left = i + 1
|
||||
right = n - 1
|
||||
if nums[i] > 0:
|
||||
break
|
||||
if i >= 1 and nums[i] == nums[i - 1]:
|
||||
continue
|
||||
while left < right:
|
||||
total = nums[i] + nums[left] + nums[right]
|
||||
if total > 0:
|
||||
right -= 1
|
||||
elif total < 0:
|
||||
left += 1
|
||||
else:
|
||||
ans.append([nums[i], nums[left], nums[right]])
|
||||
while left != right and nums[left] == nums[left + 1]: left += 1
|
||||
while left != right and nums[right] == nums[right - 1]: right -= 1
|
||||
left += 1
|
||||
right -= 1
|
||||
return ans
|
||||
```
|
||||
Go:
|
||||
```Go
|
||||
func threeSum(nums []int)[][]int{
|
||||
|
|
@ -256,8 +281,78 @@ func threeSum(nums []int)[][]int{
|
|||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {number[]} nums
|
||||
* @return {number[][]}
|
||||
*/
|
||||
|
||||
// 循环内不考虑去重
|
||||
var threeSum = function(nums) {
|
||||
const len = nums.length;
|
||||
if(len < 3) return [];
|
||||
nums.sort((a, b) => a - b);
|
||||
const resSet = new Set();
|
||||
for(let i = 0; i < len - 2; i++) {
|
||||
if(nums[i] > 0) break;
|
||||
let l = i + 1, r = len - 1;
|
||||
while(l < r) {
|
||||
const sum = nums[i] + nums[l] + nums[r];
|
||||
if(sum < 0) { l++; continue };
|
||||
if(sum > 0) { r--; continue };
|
||||
resSet.add(`${nums[i]},${nums[l]},${nums[r]}`);
|
||||
l++;
|
||||
r--;
|
||||
}
|
||||
}
|
||||
return Array.from(resSet).map(i => i.split(","));
|
||||
};
|
||||
|
||||
// 去重优化
|
||||
var threeSum = function(nums) {
|
||||
const len = nums.length;
|
||||
if(len < 3) return [];
|
||||
nums.sort((a, b) => a - b);
|
||||
const res = [];
|
||||
for(let i = 0; i < len - 2; i++) {
|
||||
if(nums[i] > 0) break;
|
||||
// a去重
|
||||
if(i > 0 && nums[i] === nums[i - 1]) continue;
|
||||
let l = i + 1, r = len - 1;
|
||||
while(l < r) {
|
||||
const sum = nums[i] + nums[l] + nums[r];
|
||||
if(sum < 0) { l++; continue };
|
||||
if(sum > 0) { r--; continue };
|
||||
res.push([nums[i], nums[l], nums[r]])
|
||||
// b c 去重
|
||||
while(l < r && nums[l] === nums[++l]);
|
||||
while(l < r && nums[r] === nums[--r]);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
ruby:
|
||||
```ruby
|
||||
def is_valid(strs)
|
||||
symbol_map = {')' => '(', '}' => '{', ']' => '['}
|
||||
stack = []
|
||||
strs.size.times {|i|
|
||||
c = strs[i]
|
||||
if symbol_map.has_key?(c)
|
||||
top_e = stack.shift
|
||||
return false if symbol_map[c] != top_e
|
||||
else
|
||||
stack.unshift(c)
|
||||
end
|
||||
}
|
||||
stack.empty?
|
||||
end
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
# 17.电话号码的字母组合
|
||||
|
|
@ -137,7 +137,7 @@ for (int i = 0; i < letters.size(); i++) {
|
|||
关键地方都讲完了,按照[关于回溯算法,你该了解这些!](https://mp.weixin.qq.com/s/gjSgJbNbd1eAA5WkA-HeWw)中的回溯法模板,不难写出如下C++代码:
|
||||
|
||||
|
||||
```
|
||||
```c++
|
||||
// 版本一
|
||||
class Solution {
|
||||
private:
|
||||
|
|
@ -183,7 +183,7 @@ public:
|
|||
|
||||
一些写法,是把回溯的过程放在递归函数里了,例如如下代码,我可以写成这样:(注意注释中不一样的地方)
|
||||
|
||||
```
|
||||
```c++
|
||||
// 版本二
|
||||
class Solution {
|
||||
private:
|
||||
|
|
@ -272,7 +272,7 @@ class Solution {
|
|||
String str = numString[digits.charAt(num) - '0'];
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
temp.append(str.charAt(i));
|
||||
//回溯
|
||||
//c
|
||||
backTracking(digits, numString, num + 1);
|
||||
//剔除末尾的继续尝试
|
||||
temp.deleteCharAt(temp.length() - 1);
|
||||
|
|
@ -283,9 +283,92 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
```Python
|
||||
class Solution:
|
||||
ans = []
|
||||
s = ''
|
||||
letterMap = {
|
||||
'2': 'abc',
|
||||
'3': 'def',
|
||||
'4': 'ghi',
|
||||
'5': 'jkl',
|
||||
'6': 'mno',
|
||||
'7': 'pqrs',
|
||||
'8': 'tuv',
|
||||
'9': 'wxyz'
|
||||
}
|
||||
|
||||
def letterCombinations(self, digits):
|
||||
self.ans.clear()
|
||||
if digits == '':
|
||||
return self.ans
|
||||
self.backtracking(digits, 0)
|
||||
return self.ans
|
||||
|
||||
def backtracking(self, digits, index):
|
||||
if index == len(digits):
|
||||
self.ans.append(self.s)
|
||||
return
|
||||
else:
|
||||
letters = self.letterMap[digits[index]] # 取出数字对应的字符集
|
||||
for letter in letters:
|
||||
self.s = self.s + letter # 处理
|
||||
self.backtracking(digits, index + 1)
|
||||
self.s = self.s[:-1] # 回溯
|
||||
```
|
||||
|
||||
python3:
|
||||
|
||||
```py
|
||||
class Solution:
|
||||
def letterCombinations(self, digits: str) -> List[str]:
|
||||
self.s = ""
|
||||
res = []
|
||||
letterMap = ["","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]
|
||||
if len(digits) == 0: return res
|
||||
def backtrack(digits,index):
|
||||
if index == len(digits):
|
||||
return res.append(self.s)
|
||||
digit = int(digits[index]) #将index指向的数字转为int
|
||||
letters = letterMap[digit] #取数字对应的字符集
|
||||
for i in range(len(letters)):
|
||||
self.s += letters[i]
|
||||
backtrack(digits,index + 1) #递归,注意index+1,一下层要处理下一个数字
|
||||
self.s = self.s[:-1] #回溯
|
||||
backtrack(digits,0)
|
||||
return res
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
var letterCombinations = function(digits) {
|
||||
const k = digits.length;
|
||||
const map = ["","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"];
|
||||
if(!k) return [];
|
||||
if(k === 1) return map[digits].split("");
|
||||
|
||||
const res = [], path = [];
|
||||
backtracking(digits, k, 0);
|
||||
return res;
|
||||
|
||||
function backtracking(n, k, a) {
|
||||
if(path.length === k) {
|
||||
res.push(path.join(""));
|
||||
return;
|
||||
}
|
||||
for(const v of map[n[a]]) {
|
||||
path.push(v);
|
||||
backtracking(n, k, a + 1);
|
||||
path.pop();
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 一样的道理,能解决四数之和
|
||||
|
|
@ -31,38 +31,39 @@ https://leetcode-cn.com/problems/4sum/
|
|||
|
||||
# 思路
|
||||
|
||||
四数之和,和[三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)是一个思路,都是使用双指针法, 基本解法就是在[三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A) 的基础上再套一层for循环。
|
||||
四数之和,和[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)是一个思路,都是使用双指针法, 基本解法就是在[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg) 的基础上再套一层for循环。
|
||||
|
||||
但是有一些细节需要注意,例如: 不要判断`nums[k] > target` 就返回了,三数之和 可以通过 `nums[i] > 0` 就返回了,因为 0 已经是确定的数了,四数之和这道题目 target是任意值。(大家亲自写代码就能感受出来)
|
||||
|
||||
[三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)的双指针解法是一层for循环num[i]为确定值,然后循环内有left和right下表作为双指针,找到nums[i] + nums[left] + nums[right] == 0。
|
||||
[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)的双指针解法是一层for循环num[i]为确定值,然后循环内有left和right下表作为双指针,找到nums[i] + nums[left] + nums[right] == 0。
|
||||
|
||||
四数之和的双指针解法是两层for循环nums[k] + nums[i]为确定值,依然是循环内有left和right下表作为双指针,找出nums[k] + nums[i] + nums[left] + nums[right] == target的情况,三数之和的时间复杂度是O(n^2),四数之和的时间复杂度是O(n^3) 。
|
||||
|
||||
那么一样的道理,五数之和、六数之和等等都采用这种解法。
|
||||
|
||||
对于[三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)双指针法就是将原本暴力O(n^3)的解法,降为O(n^2)的解法,四数之和的双指针解法就是将原本暴力O(n^4)的解法,降为O(n^3)的解法。
|
||||
对于[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)双指针法就是将原本暴力O(n^3)的解法,降为O(n^2)的解法,四数之和的双指针解法就是将原本暴力O(n^4)的解法,降为O(n^3)的解法。
|
||||
|
||||
之前我们讲过哈希表的经典题目:[四数相加II](https://mp.weixin.qq.com/s/Ue8pKKU5hw_m-jPgwlHcbA),相对于本题简单很多,因为本题是要求在一个集合中找出四个数相加等于target,同时四元组不能重复。
|
||||
之前我们讲过哈希表的经典题目:[454.四数相加II](https://mp.weixin.qq.com/s/12g_w6RzHuEpFts1pT6BWw),相对于本题简单很多,因为本题是要求在一个集合中找出四个数相加等于target,同时四元组不能重复。
|
||||
|
||||
而[四数相加II](https://mp.weixin.qq.com/s/Ue8pKKU5hw_m-jPgwlHcbA)是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于本题还是简单了不少!
|
||||
而[454.四数相加II](https://mp.weixin.qq.com/s/12g_w6RzHuEpFts1pT6BWw)是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于本题还是简单了不少!
|
||||
|
||||
我们来回顾一下,几道题目使用了双指针法。
|
||||
|
||||
双指针法将时间复杂度O(n^2)的解法优化为 O(n)的解法。也就是降一个数量级,题目如下:
|
||||
* [0027.移除元素](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA)
|
||||
* [15.三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)
|
||||
|
||||
* [27.移除元素](https://mp.weixin.qq.com/s/RMkulE4NIb6XsSX83ra-Ww)
|
||||
* [15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)
|
||||
* [18.四数之和](https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g)
|
||||
|
||||
双指针来记录前后指针实现链表反转:
|
||||
|
||||
* [206.反转链表](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg)
|
||||
操作链表:
|
||||
|
||||
使用双指针来确定有环:
|
||||
* [206.反转链表](https://mp.weixin.qq.com/s/ckEvIVGcNLfrz6OLOMoT0A)
|
||||
* [19.删除链表的倒数第N个节点](https://mp.weixin.qq.com/s/gxu65X1343xW_sBrkTz0Eg)
|
||||
* [面试题 02.07. 链表相交](https://mp.weixin.qq.com/s/BhfFfaGvt9Zs7UmH4YehZw)
|
||||
* [142题.环形链表II](https://mp.weixin.qq.com/s/gt_VH3hQTqNxyWcl1ECSbQ)
|
||||
|
||||
* [142题.环形链表II](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA)
|
||||
|
||||
双指针法在数组和链表中还有很多应用,后面还会介绍到。
|
||||
双指针法在字符串题目中还有很多应用,后面还会介绍到。
|
||||
|
||||
C++代码
|
||||
|
||||
|
|
@ -165,11 +166,75 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
```python
|
||||
|
||||
class Solution(object):
|
||||
def fourSum(self, nums, target):
|
||||
"""
|
||||
:type nums: List[int]
|
||||
:type target: int
|
||||
:rtype: List[List[int]]
|
||||
"""
|
||||
# use a dict to store value:showtimes
|
||||
hashmap = dict()
|
||||
for n in nums:
|
||||
if n in hashmap:
|
||||
hashmap[n] += 1
|
||||
else:
|
||||
hashmap[n] = 1
|
||||
|
||||
# good thing about using python is you can use set to drop duplicates.
|
||||
ans = set()
|
||||
for i in range(len(nums)):
|
||||
for j in range(i + 1, len(nums)):
|
||||
for k in range(j + 1, len(nums)):
|
||||
val = target - (nums[i] + nums[j] + nums[k])
|
||||
if val in hashmap:
|
||||
# make sure no duplicates.
|
||||
count = (nums[i] == val) + (nums[j] == val) + (nums[k] == val)
|
||||
if hashmap[val] > count:
|
||||
ans.add(tuple(sorted([nums[i], nums[j], nums[k], val])))
|
||||
else:
|
||||
continue
|
||||
return ans
|
||||
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {number[]} nums
|
||||
* @param {number} target
|
||||
* @return {number[][]}
|
||||
*/
|
||||
var fourSum = function(nums, target) {
|
||||
const len = nums.length;
|
||||
if(len < 4) return [];
|
||||
nums.sort((a, b) => a - b);
|
||||
const res = [];
|
||||
for(let i = 0; i < len - 3; i++) {
|
||||
// 去重i
|
||||
if(i > 0 && nums[i] === nums[i - 1]) continue;
|
||||
for(let j = i + 1; j < len - 2; j++) {
|
||||
// 去重j
|
||||
if(j > i + 1 && nums[j] === nums[j - 1]) continue;
|
||||
let l = j + 1, r = len - 1;
|
||||
while(l < r) {
|
||||
const sum = nums[i] + nums[j] + nums[l] + nums[r];
|
||||
if(sum < target) { l++; continue}
|
||||
if(sum > target) { r--; continue}
|
||||
res.push([nums[i], nums[j], nums[l], nums[r]]);
|
||||
while(l < r && nums[l] === nums[++l]);
|
||||
while(l < r && nums[r] === nums[--r]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -112,29 +112,79 @@ class Solution {
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
```python
|
||||
# Definition for singly-linked list.
|
||||
# class ListNode:
|
||||
# def __init__(self, val=0, next=None):
|
||||
# self.val = val
|
||||
# self.next = next
|
||||
class Solution:
|
||||
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
|
||||
head_dummy = ListNode()
|
||||
head_dummy.next = head
|
||||
|
||||
slow, fast = head_dummy, head_dummy
|
||||
while(n!=0): #fast先往前走n步
|
||||
fast = fast.next
|
||||
n -= 1
|
||||
while(fast.next!=None):
|
||||
slow = slow.next
|
||||
fast = fast.next
|
||||
#fast 走到结尾后,slow的下一个节点为倒数第N个节点
|
||||
slow.next = slow.next.next #删除
|
||||
return head_dummy.next
|
||||
```
|
||||
Go:
|
||||
```Go
|
||||
/**
|
||||
* Definition for singly-linked list.
|
||||
* type ListNode struct {
|
||||
* Val int
|
||||
* Next *ListNode
|
||||
* }
|
||||
*/
|
||||
func removeNthFromEnd(head *ListNode, n int) *ListNode {
|
||||
result:=&ListNode{}
|
||||
result.Next=head
|
||||
var pre *ListNode
|
||||
cur:=result
|
||||
|
||||
i:=1
|
||||
for head!=nil{
|
||||
if i>=n{
|
||||
pre=cur
|
||||
cur=cur.Next
|
||||
dummyHead := &ListNode{}
|
||||
dummyHead.Next = head
|
||||
cur := head
|
||||
prev := dummyHead
|
||||
i := 1
|
||||
for cur != nil {
|
||||
cur = cur.Next
|
||||
if i > n {
|
||||
prev = prev.Next
|
||||
}
|
||||
head=head.Next
|
||||
i++
|
||||
}
|
||||
pre.Next=pre.Next.Next
|
||||
return result.Next
|
||||
|
||||
prev.Next = prev.Next.Next
|
||||
return dummyHead.Next
|
||||
}
|
||||
```
|
||||
|
||||
JavaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {ListNode} head
|
||||
* @param {number} n
|
||||
* @return {ListNode}
|
||||
*/
|
||||
var removeNthFromEnd = function(head, n) {
|
||||
let ret = new ListNode(0, head),
|
||||
slow = fast = ret;
|
||||
while(n--) fast = fast.next;
|
||||
if(!fast) return ret.next;
|
||||
while (fast.next) {
|
||||
fast = fast.next;
|
||||
slow = slow.next
|
||||
};
|
||||
slow.next = slow.next.next;
|
||||
return ret.next;
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -162,6 +162,33 @@ class Solution {
|
|||
return deque.isEmpty();
|
||||
}
|
||||
}
|
||||
// 方法2
|
||||
class Solution {
|
||||
public boolean isValid(String s) {
|
||||
|
||||
Stack<Character> stack = new Stack<>();
|
||||
Map<Character, Character> map = new HashMap<Character, Character>() {
|
||||
{
|
||||
put('}', '{');
|
||||
put(']', '[');
|
||||
put(')', '(');
|
||||
}
|
||||
};
|
||||
|
||||
for (Character c : s.toCharArray()) { // 顺序读取字符
|
||||
if (!stack.isEmpty() && map.containsKey(c)) { // 是右括号 && 栈不为空
|
||||
if (stack.peek() == map.get(c)) { // 取其对应的左括号直接和栈顶比
|
||||
stack.pop(); // 相同则抵消,出栈
|
||||
} else {
|
||||
return false; // 不同则直接返回
|
||||
}
|
||||
} else {
|
||||
stack.push(c); // 左括号,直接入栈
|
||||
}
|
||||
}
|
||||
return stack.isEmpty(); // 看左右是否抵消完
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
|
@ -220,6 +247,49 @@ def is_valid(strs)
|
|||
end
|
||||
```
|
||||
|
||||
Javascript:
|
||||
```javascript
|
||||
var isValid = function (s) {
|
||||
const stack = [];
|
||||
for (let i = 0; i < s.length; i++) {
|
||||
let c = s[i];
|
||||
switch (c) {
|
||||
case '(':
|
||||
stack.push(')');
|
||||
break;
|
||||
case '[':
|
||||
stack.push(']');
|
||||
break;
|
||||
case '{':
|
||||
stack.push('}');
|
||||
break;
|
||||
default:
|
||||
if (c !== stack.pop()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack.length === 0;
|
||||
};
|
||||
// 简化版本
|
||||
var isValid = function(s) {
|
||||
const stack = [],
|
||||
map = {
|
||||
"(":")",
|
||||
"{":"}",
|
||||
"[":"]"
|
||||
};
|
||||
for(const x of s) {
|
||||
if(x in map) {
|
||||
stack.push(x);
|
||||
continue;
|
||||
};
|
||||
if(map[stack.pop()] !== x) return false;
|
||||
}
|
||||
return !stack.length;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 24. 两两交换链表中的节点
|
||||
|
||||
|
|
@ -87,10 +87,116 @@ public:
|
|||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
// 递归版本
|
||||
class Solution {
|
||||
public ListNode swapPairs(ListNode head) {
|
||||
// base case 退出提交
|
||||
if(head == null || head.next == null) return head;
|
||||
// 获取当前节点的下一个节点
|
||||
ListNode next = head.next;
|
||||
// 进行递归
|
||||
ListNode newNode = swapPairs(next.next);
|
||||
// 这里进行交换
|
||||
next.next = head;
|
||||
head.next = newNode;
|
||||
|
||||
return next;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
// 虚拟头结点
|
||||
class Solution {
|
||||
public ListNode swapPairs(ListNode head) {
|
||||
|
||||
ListNode dummyNode = new ListNode(0);
|
||||
dummyNode.next = head;
|
||||
ListNode prev = dummyNode;
|
||||
|
||||
while (prev.next != null && prev.next.next != null) {
|
||||
ListNode temp = head.next.next; // 缓存 next
|
||||
prev.next = head.next; // 将 prev 的 next 改为 head 的 next
|
||||
head.next.next = head; // 将 head.next(prev.next) 的next,指向 head
|
||||
head.next = temp; // 将head 的 next 接上缓存的temp
|
||||
prev = head; // 步进1位
|
||||
head = head.next; // 步进1位
|
||||
}
|
||||
return dummyNode.next;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
```python
|
||||
class Solution:
|
||||
def swapPairs(self, head: ListNode) -> ListNode:
|
||||
dummy = ListNode(0) #设置一个虚拟头结点
|
||||
dummy.next = head
|
||||
cur = dummy
|
||||
while cur.next and cur.next.next:
|
||||
tmp = cur.next #记录临时节点
|
||||
tmp1 = cur.next.next.next #记录临时节点
|
||||
|
||||
cur.next = cur.next.next #步骤一
|
||||
cur.next.next = tmp #步骤二
|
||||
cur.next.next.next = tmp1 #步骤三
|
||||
|
||||
cur = cur.next.next #cur移动两位,准备下一轮交换
|
||||
return dummy.next
|
||||
```
|
||||
|
||||
Go:
|
||||
```go
|
||||
func swapPairs(head *ListNode) *ListNode {
|
||||
dummy := &ListNode{
|
||||
Next: head,
|
||||
}
|
||||
//head=list[i]
|
||||
//pre=list[i-1]
|
||||
pre := dummy
|
||||
for head != nil && head.Next != nil {
|
||||
pre.Next = head.Next
|
||||
next := head.Next.Next
|
||||
head.Next.Next = head
|
||||
head.Next = next
|
||||
//pre=list[(i+2)-1]
|
||||
pre = head
|
||||
//head=list[(i+2)]
|
||||
head = next
|
||||
}
|
||||
return dummy.Next
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// 递归版本
|
||||
func swapPairs(head *ListNode) *ListNode {
|
||||
if head == nil || head.Next == nil {
|
||||
return head
|
||||
}
|
||||
next := head.Next
|
||||
head.Next = swapPairs(next.Next)
|
||||
next.Next = head
|
||||
return next
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
```javascript
|
||||
var swapPairs = function (head) {
|
||||
let ret = new ListNode(0, head), temp = ret;
|
||||
while (temp.next && temp.next.next) {
|
||||
let cur = temp.next.next, pre = temp.next;
|
||||
pre.next = cur.next;
|
||||
cur.next = pre;
|
||||
temp.next = cur;
|
||||
temp = pre;
|
||||
}
|
||||
return ret.next;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 27. 移除元素
|
||||
|
|
@ -186,6 +186,36 @@ var removeElement = (nums, val) => {
|
|||
};
|
||||
```
|
||||
|
||||
Ruby:
|
||||
```ruby
|
||||
def remove_element(nums, val)
|
||||
i = 0
|
||||
nums.each_index do |j|
|
||||
if nums[j] != val
|
||||
nums[i] = nums[j]
|
||||
i+=1
|
||||
end
|
||||
end
|
||||
i
|
||||
end
|
||||
```
|
||||
Rust:
|
||||
```rust
|
||||
pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> &mut Vec<i32> {
|
||||
let mut start: usize = 0;
|
||||
while start < nums.len() {
|
||||
if nums[start] == val {
|
||||
nums.remove(start);
|
||||
}
|
||||
start += 1;
|
||||
}
|
||||
nums
|
||||
}
|
||||
fn main() {
|
||||
let mut nums = vec![5,1,3,5,2,3,4,1];
|
||||
println!("{:?}",remove_element(&mut nums, 5));
|
||||
}
|
||||
```
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 在一个串中查找是否出现过另一个串,这是KMP的看家本领。
|
||||
|
|
@ -61,11 +61,6 @@ KMP的经典思想就是:**当出现字符串不匹配时,可以记录一部
|
|||
|
||||
读完本篇可以顺便,把leetcode上28.实现strStr()题目做了。
|
||||
|
||||
如果文字实在看不下去,就看我在B站上的视频吧,如下:
|
||||
|
||||
* [帮你把KMP算法学个通透!(理论篇)B站](https://www.bilibili.com/video/BV1PD4y1o7nd/)
|
||||
* [帮你把KMP算法学个通透!(求next数组代码篇)B站](https://www.bilibili.com/video/BV1M5411j7Xx/)
|
||||
|
||||
|
||||
# 什么是KMP
|
||||
|
||||
|
|
@ -726,6 +721,94 @@ class Solution:
|
|||
|
||||
Go:
|
||||
|
||||
```go
|
||||
// 方法一:前缀表使用减1实现
|
||||
|
||||
// getNext 构造前缀表next
|
||||
// params:
|
||||
// next 前缀表数组
|
||||
// s 模式串
|
||||
func getNext(next []int, s string) {
|
||||
j := -1 // j表示 最长相等前后缀长度
|
||||
next[0] = j
|
||||
|
||||
for i := 1; i < len(s); i++ {
|
||||
for j >= 0 && s[i] != s[j+1] {
|
||||
j = next[j] // 回退前一位
|
||||
}
|
||||
if s[i] == s[j+1] {
|
||||
j++
|
||||
}
|
||||
next[i] = j // next[i]是i(包括i)之前的最长相等前后缀长度
|
||||
}
|
||||
}
|
||||
func strStr(haystack string, needle string) int {
|
||||
if len(needle) == 0 {
|
||||
return 0
|
||||
}
|
||||
next := make([]int, len(needle))
|
||||
getNext(next, needle)
|
||||
j := -1 // 模式串的起始位置 next为-1 因此也为-1
|
||||
for i := 0; i < len(haystack); i++ {
|
||||
for j >= 0 && haystack[i] != needle[j+1] {
|
||||
j = next[j] // 寻找下一个匹配点
|
||||
}
|
||||
if haystack[i] == needle[j+1] {
|
||||
j++
|
||||
}
|
||||
if j == len(needle)-1 { // j指向了模式串的末尾
|
||||
return i - len(needle) + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
// 方法二: 前缀表无减一或者右移
|
||||
|
||||
// getNext 构造前缀表next
|
||||
// params:
|
||||
// next 前缀表数组
|
||||
// s 模式串
|
||||
func getNext(next []int, s string) {
|
||||
j := 0
|
||||
next[0] = j
|
||||
for i := 1; i < len(s); i++ {
|
||||
for j > 0 && s[i] != s[j] {
|
||||
j = next[j-1]
|
||||
}
|
||||
if s[i] == s[j] {
|
||||
j++
|
||||
}
|
||||
next[i] = j
|
||||
}
|
||||
}
|
||||
func strStr(haystack string, needle string) int {
|
||||
n := len(needle)
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
j := 0
|
||||
next := make([]int, n)
|
||||
getNext(next, needle)
|
||||
for i := 0; i < len(haystack); i++ {
|
||||
for j > 0 && haystack[i] != needle[j] {
|
||||
j = next[j-1] // 回退到j的前一位
|
||||
}
|
||||
if haystack[i] == needle[j] {
|
||||
j++
|
||||
}
|
||||
if j == n {
|
||||
return i - n + 1
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -116,7 +116,7 @@ public:
|
|||
|
||||
**大家要仔细看注释,思考为什么要写while(left <= right), 为什么要写right = middle - 1**。
|
||||
|
||||
```
|
||||
```C++
|
||||
class Solution {
|
||||
public:
|
||||
int searchInsert(vector<int>& nums, int target) {
|
||||
|
|
@ -257,7 +257,25 @@ class Solution:
|
|||
|
||||
Go:
|
||||
|
||||
JavaScript:
|
||||
```js
|
||||
var searchInsert = function (nums, target) {
|
||||
let l = 0, r = nums.length - 1, ans = nums.length;
|
||||
|
||||
while (l <= r) {
|
||||
const mid = l + Math.floor((r - l) >> 1);
|
||||
|
||||
if (target > nums[mid]) {
|
||||
l = mid + 1;
|
||||
} else {
|
||||
ans = mid;
|
||||
r = mid - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return ans;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
如果对回溯法理论还不清楚的同学,可以先看这个视频[视频来了!!带你学透回溯算法(理论篇)](https://mp.weixin.qq.com/s/wDd5azGIYWjbU0fdua_qBg)
|
||||
|
|
@ -287,11 +287,97 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def solveSudoku(self, board: List[List[str]]) -> None:
|
||||
"""
|
||||
Do not return anything, modify board in-place instead.
|
||||
"""
|
||||
def backtrack(board):
|
||||
for i in range(len(board)): #遍历行
|
||||
for j in range(len(board[0])): #遍历列
|
||||
if board[i][j] != ".": continue
|
||||
for k in range(1,10): #(i, j) 这个位置放k是否合适
|
||||
if isValid(i,j,k,board):
|
||||
board[i][j] = str(k) #放置k
|
||||
if backtrack(board): return True #如果找到合适一组立刻返回
|
||||
board[i][j] = "." #回溯,撤销k
|
||||
return False #9个数都试完了,都不行,那么就返回false
|
||||
return True #遍历完没有返回false,说明找到了合适棋盘位置了
|
||||
def isValid(row,col,val,board):
|
||||
for i in range(9): #判断行里是否重复
|
||||
if board[row][i] == str(val):
|
||||
return False
|
||||
for j in range(9): #判断列里是否重复
|
||||
if board[j][col] == str(val):
|
||||
return False
|
||||
startRow = (row // 3) * 3
|
||||
startcol = (col // 3) * 3
|
||||
for i in range(startRow,startRow + 3): #判断9方格里是否重复
|
||||
for j in range(startcol,startcol + 3):
|
||||
if board[i][j] == str(val):
|
||||
return False
|
||||
return True
|
||||
backtrack(board)
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
var solveSudoku = function(board) {
|
||||
function isValid(row, col, val, board) {
|
||||
let len = board.length
|
||||
// 行不能重复
|
||||
for(let i = 0; i < len; i++) {
|
||||
if(board[row][i] === val) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// 列不能重复
|
||||
for(let i = 0; i < len; i++) {
|
||||
if(board[i][col] === val) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
let startRow = Math.floor(row / 3) * 3
|
||||
let startCol = Math.floor(col / 3) * 3
|
||||
|
||||
for(let i = startRow; i < startRow + 3; i++) {
|
||||
for(let j = startCol; j < startCol + 3; j++) {
|
||||
if(board[i][j] === val) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
function backTracking() {
|
||||
for(let i = 0; i < board.length; i++) {
|
||||
for(let j = 0; j < board[0].length; j++) {
|
||||
if(board[i][j] !== '.') continue
|
||||
for(let val = 1; val <= 9; val++) {
|
||||
if(isValid(i, j, `${val}`, board)) {
|
||||
board[i][j] = `${val}`
|
||||
if (backTracking()) {
|
||||
return true
|
||||
}
|
||||
|
||||
board[i][j] = `.`
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
backTracking(board)
|
||||
return board
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 39. 组合总和
|
||||
|
|
@ -237,45 +237,81 @@ public:
|
|||
|
||||
Java:
|
||||
```Java
|
||||
// 剪枝优化
|
||||
class Solution {
|
||||
List<List<Integer>> lists = new ArrayList<>();
|
||||
Deque<Integer> deque = new LinkedList<>();
|
||||
|
||||
public List<List<Integer>> combinationSum3(int k, int n) {
|
||||
int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
backTracking(arr, n, k, 0);
|
||||
return lists;
|
||||
public List<List<Integer>> combinationSum(int[] candidates, int target) {
|
||||
List<List<Integer>> res = new ArrayList<>();
|
||||
Arrays.sort(candidates); // 先进行排序
|
||||
backtracking(res, new ArrayList<>(), candidates, target, 0, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
public void backTracking(int[] arr, int n, int k, int startIndex) {
|
||||
//如果 n 小于0,没必要继续本次递归,已经不符合要求了
|
||||
if (n < 0) {
|
||||
public void backtracking(List<List<Integer>> res, List<Integer> path, int[] candidates, int target, int sum, int idx) {
|
||||
// 找到了数字和为 target 的组合
|
||||
if (sum == target) {
|
||||
res.add(new ArrayList<>(path));
|
||||
return;
|
||||
}
|
||||
if (deque.size() == k) {
|
||||
if (n == 0) {
|
||||
lists.add(new ArrayList(deque));
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (int i = startIndex; i < arr.length - (k - deque.size()) + 1; i++) {
|
||||
deque.push(arr[i]);
|
||||
//减去当前元素
|
||||
n -= arr[i];
|
||||
backTracking(arr, n, k, i + 1);
|
||||
//恢复n
|
||||
n += deque.pop();
|
||||
|
||||
for (int i = idx; i < candidates.length; i++) {
|
||||
// 如果 sum + candidates[i] > target 就终止遍历
|
||||
if (sum + candidates[i] > target) break;
|
||||
path.add(candidates[i]);
|
||||
backtracking(res, path, candidates, target, sum + candidates[i], i);
|
||||
path.remove(path.size() - 1); // 回溯,移除路径 path 最后一个元素
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
|
||||
res = []
|
||||
path = []
|
||||
def backtrack(candidates,target,sum,startIndex):
|
||||
if sum > target: return
|
||||
if sum == target: return res.append(path[:])
|
||||
for i in range(startIndex,len(candidates)):
|
||||
if sum + candidates[i] >target: return #如果 sum + candidates[i] > target 就终止遍历
|
||||
sum += candidates[i]
|
||||
path.append(candidates[i])
|
||||
backtrack(candidates,target,sum,i) #startIndex = i:表示可以重复读取当前的数
|
||||
sum -= candidates[i] #回溯
|
||||
path.pop() #回溯
|
||||
candidates = sorted(candidates) #需要排序
|
||||
backtrack(candidates,target,0,0)
|
||||
return res
|
||||
```
|
||||
Go:
|
||||
|
||||
JavaScript:
|
||||
|
||||
```js
|
||||
var combinationSum = function(candidates, target) {
|
||||
const res = [], path = [];
|
||||
candidates.sort(); // 排序
|
||||
backtracking(0, 0);
|
||||
return res;
|
||||
function backtracking(j, sum) {
|
||||
if (sum > target) return;
|
||||
if (sum === target) {
|
||||
res.push(Array.from(path));
|
||||
return;
|
||||
}
|
||||
for(let i = j; i < candidates.length; i++ ) {
|
||||
const n = candidates[i];
|
||||
if(n > target - sum) continue;
|
||||
path.push(n);
|
||||
sum += n;
|
||||
backtracking(i, sum);
|
||||
path.pop();
|
||||
sum -= n;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 这篇可以说是全网把组合问题如何去重,讲的最清晰的了!
|
||||
|
|
@ -292,13 +292,61 @@ class Solution {
|
|||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```py
|
||||
class Solution:
|
||||
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
|
||||
res = []
|
||||
path = []
|
||||
def backtrack(candidates,target,sum,startIndex):
|
||||
if sum == target: res.append(path[:])
|
||||
for i in range(startIndex,len(candidates)): #要对同一树层使用过的元素进行跳过
|
||||
if sum + candidates[i] > target: return
|
||||
if i > startIndex and candidates[i] == candidates[i-1]: continue #直接用startIndex来去重,要对同一树层使用过的元素进行跳过
|
||||
sum += candidates[i]
|
||||
path.append(candidates[i])
|
||||
backtrack(candidates,target,sum,i+1) #i+1:每个数字在每个组合中只能使用一次
|
||||
sum -= candidates[i] #回溯
|
||||
path.pop() #回溯
|
||||
candidates = sorted(candidates) #首先把给candidates排序,让其相同的元素都挨在一起。
|
||||
backtrack(candidates,target,0,0)
|
||||
return res
|
||||
```
|
||||
Go:
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {number[]} candidates
|
||||
* @param {number} target
|
||||
* @return {number[][]}
|
||||
*/
|
||||
var combinationSum2 = function(candidates, target) {
|
||||
const res = []; path = [], len = candidates.length;
|
||||
candidates.sort();
|
||||
backtracking(0, 0);
|
||||
return res;
|
||||
function backtracking(sum, i) {
|
||||
if (sum > target) return;
|
||||
if (sum === target) {
|
||||
res.push(Array.from(path));
|
||||
return;
|
||||
}
|
||||
let f = -1;
|
||||
for(let j = i; j < len; j++) {
|
||||
const n = candidates[j];
|
||||
if(n > target - sum || n === f) continue;
|
||||
path.push(n);
|
||||
sum += n;
|
||||
f = n;
|
||||
backtracking(sum, j + 1);
|
||||
path.pop();
|
||||
sum -= n;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 相对于[贪心算法:跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)难了不少,做好心里准备!
|
||||
|
|
@ -175,9 +175,64 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def jump(self, nums: List[int]) -> int:
|
||||
if len(nums) == 1: return 0
|
||||
ans = 0
|
||||
curDistance = 0
|
||||
nextDistance = 0
|
||||
for i in range(len(nums)):
|
||||
nextDistance = max(i + nums[i], nextDistance)
|
||||
if i == curDistance:
|
||||
if curDistance != len(nums) - 1:
|
||||
ans += 1
|
||||
curDistance = nextDistance
|
||||
if nextDistance >= len(nums) - 1: break
|
||||
return ans
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func jump(nums []int) int {
|
||||
dp:=make([]int ,len(nums))
|
||||
dp[0]=0
|
||||
|
||||
for i:=1;i<len(nums);i++{
|
||||
dp[i]=i
|
||||
for j:=0;j<i;j++{
|
||||
if nums[j]+j>i{
|
||||
dp[i]=min(dp[j]+1,dp[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[len(nums)-1]
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
var jump = function(nums) {
|
||||
let curIndex = 0
|
||||
let nextIndex = 0
|
||||
let steps = 0
|
||||
for(let i = 0; i < nums.length - 1; i++) {
|
||||
nextIndex = Math.max(nums[i] + i, nextIndex)
|
||||
if(i === curIndex) {
|
||||
curIndex = nextIndex
|
||||
steps++
|
||||
}
|
||||
}
|
||||
|
||||
return steps
|
||||
};
|
||||
```
|
||||
|
||||
/*
|
||||
dp[i]表示从起点到当前位置的最小跳跃次数
|
||||
dp[i]=min(dp[j]+1,dp[i]) 表示从j位置用一步跳跃到当前位置,这个j位置可能有很多个,却最小一个就可以
|
||||
*/
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 46.全排列
|
||||
|
|
@ -149,6 +149,7 @@ public:
|
|||
Java:
|
||||
```java
|
||||
class Solution {
|
||||
|
||||
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
|
||||
LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
|
||||
boolean[] used;
|
||||
|
|
@ -167,9 +168,6 @@ class Solution {
|
|||
return;
|
||||
}
|
||||
for (int i = 0; i < nums.length; i++){
|
||||
// if (path.contains(nums[i])){
|
||||
// continue;
|
||||
// }
|
||||
if (used[i]){
|
||||
continue;
|
||||
}
|
||||
|
|
@ -184,7 +182,45 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
```python3
|
||||
class Solution:
|
||||
def permute(self, nums: List[int]) -> List[List[int]]:
|
||||
res = [] #存放符合条件结果的集合
|
||||
path = [] #用来存放符合条件的结果
|
||||
used = [] #用来存放已经用过的数字
|
||||
def backtrack(nums,used):
|
||||
if len(path) == len(nums):
|
||||
return res.append(path[:]) #此时说明找到了一组
|
||||
for i in range(0,len(nums)):
|
||||
if nums[i] in used:
|
||||
continue #used里已经收录的元素,直接跳过
|
||||
path.append(nums[i])
|
||||
used.append(nums[i])
|
||||
backtrack(nums,used)
|
||||
used.pop()
|
||||
path.pop()
|
||||
backtrack(nums,used)
|
||||
return res
|
||||
```
|
||||
|
||||
Python(优化,不用used数组):
|
||||
```python3
|
||||
class Solution:
|
||||
def permute(self, nums: List[int]) -> List[List[int]]:
|
||||
res = [] #存放符合条件结果的集合
|
||||
path = [] #用来存放符合条件的结果
|
||||
def backtrack(nums):
|
||||
if len(path) == len(nums):
|
||||
return res.append(path[:]) #此时说明找到了一组
|
||||
for i in range(0,len(nums)):
|
||||
if nums[i] in path: #path里已经收录的元素,直接跳过
|
||||
continue
|
||||
path.append(nums[i])
|
||||
backtrack(nums) #递归
|
||||
path.pop() #回溯
|
||||
backtrack(nums)
|
||||
return res
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
|
|
@ -208,14 +244,33 @@ func backtrack(nums,pathNums []int,used []bool){
|
|||
}
|
||||
}
|
||||
|
||||
func permute(nums []int) [][]int {
|
||||
//var pathNums []int
|
||||
pathNums:=make([]int,0)
|
||||
var used=make([]bool,len(nums))
|
||||
result=[][]int{}
|
||||
backtrack(nums,pathNums,used)
|
||||
Javascript:
|
||||
|
||||
```javascript
|
||||
|
||||
var permute = function(nums) {
|
||||
let result = []
|
||||
let path = []
|
||||
function backtracing(used) {
|
||||
if(path.length === nums.length) {
|
||||
result.push(path.slice(0))
|
||||
return
|
||||
}
|
||||
for(let i = 0; i < nums.length; i++) {
|
||||
if(used[nums[i]]) {
|
||||
continue
|
||||
}
|
||||
used[nums[i]] = true
|
||||
path.push(nums[i])
|
||||
backtracing(used)
|
||||
path.pop()
|
||||
used[nums[i]] = false
|
||||
}
|
||||
}
|
||||
backtracing([])
|
||||
return result
|
||||
}
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 排列问题(二)
|
||||
|
||||
## 47.全排列 II
|
||||
|
|
@ -85,7 +85,7 @@ public:
|
|||
path.clear();
|
||||
sort(nums.begin(), nums.end()); // 排序
|
||||
vector<bool> used(nums.size(), false);
|
||||
backtracking(nums, vec, used);
|
||||
backtracking(nums, used);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
|
@ -220,6 +220,43 @@ class Solution:
|
|||
return res
|
||||
```
|
||||
|
||||
Javascript:
|
||||
|
||||
```javascript
|
||||
|
||||
var permuteUnique = function (nums) {
|
||||
nums.sort((a, b) => {
|
||||
return a - b
|
||||
})
|
||||
let result = []
|
||||
let path = []
|
||||
|
||||
function backtracing( used) {
|
||||
if (path.length === nums.length) {
|
||||
result.push(path.slice())
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
if (i > 0 && nums[i] === nums[i - 1] && !used[i - 1]) {
|
||||
continue
|
||||
}
|
||||
if (!used[i]) {
|
||||
used[i] = true
|
||||
path.push(nums[i])
|
||||
backtracing(used)
|
||||
path.pop()
|
||||
used[i] = false
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
backtracing([])
|
||||
return result
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 第51题. N皇后
|
||||
|
|
@ -430,6 +430,65 @@ func solveNQueens(n int) [][]string {
|
|||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
var solveNQueens = function(n) {
|
||||
function isValid(row, col, chessBoard, n) {
|
||||
|
||||
for(let i = 0; i < row; i++) {
|
||||
if(chessBoard[i][col] === 'Q') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for(let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
|
||||
if(chessBoard[i][j] === 'Q') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for(let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
|
||||
if(chessBoard[i][j] === 'Q') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function transformChessBoard(chessBoard) {
|
||||
let chessBoardBack = []
|
||||
chessBoard.forEach(row => {
|
||||
let rowStr = ''
|
||||
row.forEach(value => {
|
||||
rowStr += value
|
||||
})
|
||||
chessBoardBack.push(rowStr)
|
||||
})
|
||||
|
||||
return chessBoardBack
|
||||
}
|
||||
|
||||
let result = []
|
||||
function backtracing(row,chessBoard) {
|
||||
if(row === n) {
|
||||
result.push(transformChessBoard(chessBoard))
|
||||
return
|
||||
}
|
||||
for(let col = 0; col < n; col++) {
|
||||
if(isValid(row, col, chessBoard, n)) {
|
||||
chessBoard[row][col] = 'Q'
|
||||
backtracing(row + 1,chessBoard)
|
||||
chessBoard[row][col] = '.'
|
||||
}
|
||||
}
|
||||
}
|
||||
let chessBoard = new Array(n).fill([]).map(() => new Array(n).fill('.'))
|
||||
backtracing(0,chessBoard)
|
||||
return result
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 53. 最大子序和
|
||||
|
|
@ -175,29 +175,39 @@ class Solution:
|
|||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func maxSubArray(nums []int) int {
|
||||
if len(nums)<1{
|
||||
return 0
|
||||
}
|
||||
dp:=make([]int,len(nums))
|
||||
result:=nums[0]
|
||||
dp[0]=nums[0]
|
||||
for i:=1;i<len(nums);i++{
|
||||
dp[i]=max(dp[i-1]+nums[i],nums[i])
|
||||
result=max(dp[i],result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func max(a,b int)int{
|
||||
if a>b{
|
||||
return a
|
||||
}else{
|
||||
return b
|
||||
```go
|
||||
func maxSubArray(nums []int) int {
|
||||
maxSum := nums[0]
|
||||
for i := 1; i < len(nums); i++ {
|
||||
if nums[i] + nums[i-1] > nums[i] {
|
||||
nums[i] += nums[i-1]
|
||||
}
|
||||
if nums[i] > maxSum {
|
||||
maxSum = nums[i]
|
||||
}
|
||||
}
|
||||
return maxSum
|
||||
}
|
||||
```
|
||||
Javascript:
|
||||
```Javascript
|
||||
var maxSubArray = function(nums) {
|
||||
let result = -Infinity
|
||||
let count = 0
|
||||
for(let i = 0; i < nums.length; i++) {
|
||||
count += nums[i]
|
||||
if(count > result) {
|
||||
result = count
|
||||
}
|
||||
if(count < 0) {
|
||||
count = 0
|
||||
}
|
||||
}
|
||||
return result
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 53. 最大子序和
|
||||
|
||||
|
|
@ -95,10 +95,47 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
```java
|
||||
/**
|
||||
* 1.dp[i]代表当前下标对应的最大值
|
||||
* 2.递推公式 dp[i] = max (dp[i-1]+nums[i],nums[i]) res = max(res,dp[i])
|
||||
* 3.初始化 都为 0
|
||||
* 4.遍历方向,从前往后
|
||||
* 5.举例推导结果。。。
|
||||
*
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public static int maxSubArray(int[] nums) {
|
||||
if (nums.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int res = nums[0];
|
||||
int[] dp = new int[nums.length];
|
||||
dp[0] = nums[0];
|
||||
for (int i = 1; i < nums.length; i++) {
|
||||
dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
|
||||
res = res > dp[i] ? res : dp[i];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def maxSubArray(self, nums: List[int]) -> int:
|
||||
if len(nums) == 0:
|
||||
return 0
|
||||
dp = [0] * len(nums)
|
||||
dp[0] = nums[0]
|
||||
result = dp[0]
|
||||
for i in range(1, len(nums)):
|
||||
dp[i] = max(dp[i-1] + nums[i], nums[i]) #状态转移公式
|
||||
result = max(result, dp[i]) #result 保存dp[i]的最大值
|
||||
return result
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 55. 跳跃游戏
|
||||
|
|
@ -122,8 +122,39 @@ class Solution:
|
|||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func canJUmp(nums []int) bool {
|
||||
if len(nums)<=1{
|
||||
return true
|
||||
}
|
||||
dp:=make([]bool,len(nums))
|
||||
dp[0]=true
|
||||
for i:=1;i<len(nums);i++{
|
||||
for j:=i-1;j>=0;j--{
|
||||
if dp[j]&&nums[j]+j>=i{
|
||||
dp[i]=true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[len(nums)-1]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
var canJump = function(nums) {
|
||||
if(nums.length === 1) return true
|
||||
let cover = 0
|
||||
for(let i = 0; i <= cover; i++) {
|
||||
cover = Math.max(cover, i + nums[i])
|
||||
if(cover >= nums.length - 1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 56. 合并区间
|
||||
|
|
@ -141,16 +141,7 @@ Java:
|
|||
class Solution {
|
||||
public int[][] merge(int[][] intervals) {
|
||||
List<int[]> res = new LinkedList<>();
|
||||
Arrays.sort(intervals, new Comparator<int[]>() {
|
||||
@Override
|
||||
public int compare(int[] o1, int[] o2) {
|
||||
if (o1[0] != o2[0]) {
|
||||
return Integer.compare(o1[0],o2[0]);
|
||||
} else {
|
||||
return Integer.compare(o1[1],o2[1]);
|
||||
}
|
||||
}
|
||||
});
|
||||
Arrays.sort(intervals, (o1, o2) -> Integer.compare(o1[0], o2[0]));
|
||||
|
||||
int start = intervals[0][0];
|
||||
for (int i = 1; i < intervals.length; i++) {
|
||||
|
|
@ -168,10 +159,69 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
|
||||
if len(intervals) == 0: return intervals
|
||||
intervals.sort(key=lambda x: x[0])
|
||||
result = []
|
||||
result.append(intervals[0])
|
||||
for i in range(1, len(intervals)):
|
||||
last = result[-1]
|
||||
if last[1] >= intervals[i][0]:
|
||||
result[-1] = [last[0], max(last[1], intervals[i][1])]
|
||||
else:
|
||||
result.append(intervals[i])
|
||||
return result
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func merge(intervals [][]int) [][]int {
|
||||
sort.Slice(intervals, func(i, j int) bool {
|
||||
return intervals[i][0]<intervals[j][0]
|
||||
})
|
||||
|
||||
res:=[][]int{}
|
||||
prev:=intervals[0]
|
||||
|
||||
for i:=1;i<len(intervals);i++{
|
||||
cur :=intervals[i]
|
||||
if prev[1]<cur[0]{
|
||||
res=append(res,prev)
|
||||
prev=cur
|
||||
}else {
|
||||
prev[1]=max(prev[1],cur[1])
|
||||
}
|
||||
}
|
||||
res=append(res,prev)
|
||||
return res
|
||||
}
|
||||
func max(a, b int) int {
|
||||
if a > b { return a }
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
```javascript
|
||||
var merge = function (intervals) {
|
||||
intervals.sort((a, b) => a[0] - b[0]);
|
||||
let prev = intervals[0]
|
||||
let result = []
|
||||
for(let i =0; i<intervals.length; i++){
|
||||
let cur = intervals[i]
|
||||
if(cur[0] > prev[1]){
|
||||
result.push(prev)
|
||||
prev = cur
|
||||
}else{
|
||||
prev[1] = Math.max(cur[1],prev[1])
|
||||
}
|
||||
}
|
||||
result.push(prev)
|
||||
return result
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -224,6 +224,88 @@ class Solution:
|
|||
return matrix
|
||||
```
|
||||
|
||||
javaScript
|
||||
|
||||
```js
|
||||
|
||||
/**
|
||||
* @param {number} n
|
||||
* @return {number[][]}
|
||||
*/
|
||||
var generateMatrix = function(n) {
|
||||
// new Array(n).fill(new Array(n))
|
||||
// 使用fill --> 填充的是同一个数组地址
|
||||
const res = Array.from({length: n}).map(() => new Array(n));
|
||||
let loop = n >> 1, i = 0, //循环次数
|
||||
count = 1,
|
||||
startX = startY = 0; // 起始位置
|
||||
while(++i <= loop) {
|
||||
// 定义行列
|
||||
let row = startX, column = startY;
|
||||
// [ startY, n - i)
|
||||
while(column < n - i) {
|
||||
res[row][column++] = count++;
|
||||
}
|
||||
// [ startX, n - i)
|
||||
while(row < n - i) {
|
||||
res[row++][column] = count++;
|
||||
}
|
||||
// [n - i , startY)
|
||||
while(column > startY) {
|
||||
res[row][column--] = count++;
|
||||
}
|
||||
// [n - i , startX)
|
||||
while(row > startX) {
|
||||
res[row--][column] = count++;
|
||||
}
|
||||
startX = ++startY;
|
||||
}
|
||||
if(n & 1) {
|
||||
res[startX][startY] = count;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
func generateMatrix(n int) [][]int {
|
||||
top, bottom := 0, n-1
|
||||
left, right := 0, n-1
|
||||
num := 1
|
||||
tar := n * n
|
||||
matrix := make([][]int, n)
|
||||
for i := 0; i < n; i++ {
|
||||
matrix[i] = make([]int, n)
|
||||
}
|
||||
for num <= tar {
|
||||
for i := left; i <= right; i++ {
|
||||
matrix[top][i] = num
|
||||
num++
|
||||
}
|
||||
top++
|
||||
for i := top; i <= bottom; i++ {
|
||||
matrix[i][right] = num
|
||||
num++
|
||||
}
|
||||
right--
|
||||
for i := right; i >= left; i-- {
|
||||
matrix[bottom][i] = num
|
||||
num++
|
||||
}
|
||||
bottom--
|
||||
for i := bottom; i >= top; i-- {
|
||||
matrix[i][left] = num
|
||||
num++
|
||||
}
|
||||
left++
|
||||
}
|
||||
return matrix
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 62.不同路径
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ public:
|
|||
|
||||
### 动态规划
|
||||
|
||||
机器人从(0 , 0) 位置触发,到(m - 1, n - 1)终点。
|
||||
机器人从(0 , 0) 位置出发,到(m - 1, n - 1)终点。
|
||||
|
||||
按照动规五部曲来分析:
|
||||
|
||||
|
|
@ -243,14 +243,92 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
```java
|
||||
/**
|
||||
* 1. 确定dp数组下表含义 dp[i][j] 到每一个坐标可能的路径种类
|
||||
* 2. 递推公式 dp[i][j] = dp[i-1][j] dp[i][j-1]
|
||||
* 3. 初始化 dp[i][0]=1 dp[0][i]=1 初始化横竖就可
|
||||
* 4. 遍历顺序 一行一行遍历
|
||||
* 5. 推导结果 。。。。。。。。
|
||||
*
|
||||
* @param m
|
||||
* @param n
|
||||
* @return
|
||||
*/
|
||||
public static int uniquePaths(int m, int n) {
|
||||
int[][] dp = new int[m][n];
|
||||
//初始化
|
||||
for (int i = 0; i < m; i++) {
|
||||
dp[i][0] = 1;
|
||||
}
|
||||
for (int i = 0; i < n; i++) {
|
||||
dp[0][i] = 1;
|
||||
}
|
||||
|
||||
for (int i = 1; i < m; i++) {
|
||||
for (int j = 1; j < n; j++) {
|
||||
dp[i][j] = dp[i-1][j]+dp[i][j-1];
|
||||
}
|
||||
}
|
||||
return dp[m-1][n-1];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution: # 动态规划
|
||||
def uniquePaths(self, m: int, n: int) -> int:
|
||||
dp = [[0 for i in range(n)] for j in range(m)]
|
||||
for i in range(m): dp[i][0] = 1
|
||||
for j in range(n): dp[0][j] = 1
|
||||
for i in range(1, m):
|
||||
for j in range(1, n):
|
||||
dp[i][j] = dp[i][j - 1] + dp[i - 1][j]
|
||||
return dp[m - 1][n - 1]
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func uniquePaths(m int, n int) int {
|
||||
dp := make([][]int, m)
|
||||
for i := range dp {
|
||||
dp[i] = make([]int, n)
|
||||
dp[i][0] = 1
|
||||
}
|
||||
for j := 0; j < n; j++ {
|
||||
dp[0][j] = 1
|
||||
}
|
||||
for i := 1; i < m; i++ {
|
||||
for j := 1; j < n; j++ {
|
||||
dp[i][j] = dp[i-1][j] + dp[i][j-1]
|
||||
}
|
||||
}
|
||||
return dp[m-1][n-1]
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
var uniquePaths = function(m, n) {
|
||||
const dp = Array(m).fill().map(item => Array(n))
|
||||
|
||||
for (let i = 0; i < m; ++i) {
|
||||
dp[i][0] = 1
|
||||
}
|
||||
|
||||
for (let i = 0; i < n; ++i) {
|
||||
dp[0][i] = 1
|
||||
}
|
||||
|
||||
for (let i = 1; i < m; ++i) {
|
||||
for (let j = 1; j < n; ++j) {
|
||||
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
|
||||
}
|
||||
}
|
||||
return dp[m - 1][n - 1]
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 63. 不同路径 II
|
||||
|
||||
|
|
@ -157,8 +157,6 @@ public:
|
|||
* 时间复杂度O(n * m) n m 分别为obstacleGrid 长度和宽度
|
||||
* 空间复杂度O(n * m)
|
||||
|
||||
至于能不能优化空间降为一维dp数组,我感觉不太行,因为要考虑障碍,如果把这些障碍压缩到一行,结果一定就不一样了。
|
||||
|
||||
## 总结
|
||||
|
||||
本题是[62.不同路径](https://mp.weixin.qq.com/s/MGgGIt4QCpFMROE9X9he_A)的障碍版,整体思路大体一致。
|
||||
|
|
@ -237,7 +235,74 @@ class Solution:
|
|||
|
||||
Go:
|
||||
|
||||
```go
|
||||
func uniquePathsWithObstacles(obstacleGrid [][]int) int {
|
||||
m,n:= len(obstacleGrid),len(obstacleGrid[0])
|
||||
// 定义一个dp数组
|
||||
dp := make([][]int,m)
|
||||
for i,_ := range dp {
|
||||
dp[i] = make([]int,n)
|
||||
}
|
||||
// 初始化
|
||||
for i:=0;i<m;i++ {
|
||||
// 如果是障碍物, 后面的就都是0, 不用循环了
|
||||
if obstacleGrid[i][0] == 1 {
|
||||
break
|
||||
}
|
||||
dp[i][0]=1
|
||||
}
|
||||
for i:=0;i<n;i++ {
|
||||
if obstacleGrid[0][i] == 1 {
|
||||
break
|
||||
}
|
||||
dp[0][i]=1
|
||||
}
|
||||
// dp数组推导过程
|
||||
for i:=1;i<m;i++ {
|
||||
for j:=1;j<n;j++ {
|
||||
// 如果obstacleGrid[i][j]这个点是障碍物, 那么我们的dp[i][j]保持为0
|
||||
if obstacleGrid[i][j] != 1 {
|
||||
// 否则我们需要计算当前点可以到达的路径数
|
||||
dp[i][j] = dp[i-1][j]+dp[i][j-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
// debug遍历dp
|
||||
//for i,_ := range dp {
|
||||
// for j,_ := range dp[i] {
|
||||
// fmt.Printf("%.2v,",dp[i][j])
|
||||
// }
|
||||
// fmt.Println()
|
||||
//}
|
||||
return dp[m-1][n-1]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Javascript
|
||||
``` Javascript
|
||||
var uniquePathsWithObstacles = function(obstacleGrid) {
|
||||
const m = obstacleGrid.length
|
||||
const n = obstacleGrid[0].length
|
||||
const dp = Array(m).fill().map(item => Array(n).fill(0))
|
||||
|
||||
for (let i = 0; i < m && obstacleGrid[i][0] === 0; ++i) {
|
||||
dp[i][0] = 1
|
||||
}
|
||||
|
||||
for (let i = 0; i < n && obstacleGrid[0][i] === 0; ++i) {
|
||||
dp[0][i] = 1
|
||||
}
|
||||
|
||||
for (let i = 1; i < m; ++i) {
|
||||
for (let j = 1; j < n; ++j) {
|
||||
dp[i][j] = obstacleGrid[i][j] === 1 ? 0 : dp[i - 1][j] + dp[i][j - 1]
|
||||
}
|
||||
}
|
||||
|
||||
return dp[m - 1][n - 1]
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 70. 爬楼梯
|
||||
题目地址:https://leetcode-cn.com/problems/climbing-stairs/
|
||||
|
||||
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
|
||||
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
|
||||
|
||||
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
|
||||
|
||||
|
|
@ -212,7 +213,45 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public int climbStairs(int n) {
|
||||
// 跟斐波那契数列一样
|
||||
if(n <= 2) return n;
|
||||
int a = 1, b = 2, sum = 0;
|
||||
|
||||
for(int i = 3; i <= n; i++){
|
||||
sum = a + b;
|
||||
a = b;
|
||||
b = sum;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
// 常规方式
|
||||
public int climbStairs(int n) {
|
||||
int[] dp = new int[n + 1];
|
||||
dp[0] = 1;
|
||||
dp[1] = 1;
|
||||
for (int i = 2; i <= n; i++) {
|
||||
dp[i] = dp[i - 1] + dp[i - 2];
|
||||
}
|
||||
return dp[n];
|
||||
}
|
||||
// 用变量记录代替数组
|
||||
public int climbStairs(int n) {
|
||||
int a = 0, b = 1, c = 0; // 默认需要1次
|
||||
for (int i = 1; i <= n; i++) {
|
||||
c = a + b; // f(i - 1) + f(n - 2)
|
||||
a = b; // 记录上一轮的值
|
||||
b = c; // 向后步进1个数
|
||||
}
|
||||
return c;
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 动态规划:以前我没得选,现在我选择再爬一次!
|
||||
|
||||
之前讲这道题目的时候,因为还没有讲背包问题,所以就只是讲了一下爬楼梯最直接的动规方法(斐波那契)。
|
||||
|
|
@ -149,9 +149,44 @@ class Solution {
|
|||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
```python3
|
||||
class Solution:
|
||||
def climbStairs(self, n: int) -> int:
|
||||
dp = [0]*(n + 1)
|
||||
dp[0] = 1
|
||||
m = 2
|
||||
# 遍历背包
|
||||
for j in range(n + 1):
|
||||
# 遍历物品
|
||||
for step in range(1, m + 1):
|
||||
if j >= step:
|
||||
dp[j] += dp[j - step]
|
||||
return dp[n]
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
```go
|
||||
func climbStairs(n int) int {
|
||||
//定义
|
||||
dp := make([]int, n+1)
|
||||
//初始化
|
||||
dp[0] = 1
|
||||
// 本题物品只有两个1,2
|
||||
m := 2
|
||||
// 遍历顺序
|
||||
for j := 1; j <= n; j++ { //先遍历背包
|
||||
for i := 1; i <= m; i++ { //再遍历物品
|
||||
if j >= i {
|
||||
dp[j] += dp[j-i]
|
||||
}
|
||||
//fmt.Println(dp)
|
||||
}
|
||||
}
|
||||
return dp[n]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 72. 编辑距离
|
||||
|
||||
https://leetcode-cn.com/problems/edit-distance/
|
||||
|
||||
给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。
|
||||
|
||||
你可以对一个单词进行如下三种操作:
|
||||
|
|
@ -198,10 +200,50 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
public int minDistance(String word1, String word2) {
|
||||
int m = word1.length();
|
||||
int n = word2.length();
|
||||
int[][] dp = new int[m + 1][n + 1];
|
||||
// 初始化
|
||||
for (int i = 1; i <= m; i++) {
|
||||
dp[i][0] = i;
|
||||
}
|
||||
for (int j = 1; j <= n; j++) {
|
||||
dp[0][j] = j;
|
||||
}
|
||||
for (int i = 1; i <= m; i++) {
|
||||
for (int j = 1; j <= n; j++) {
|
||||
// 因为dp数组有效位从1开始
|
||||
// 所以当前遍历到的字符串的位置为i-1 | j-1
|
||||
if (word1.charAt(i - 1) == word2.charAt(j - 1)) {
|
||||
dp[i][j] = dp[i - 1][j - 1];
|
||||
} else {
|
||||
dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1], dp[i][j - 1]), dp[i - 1][j]) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[m][n];
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def minDistance(self, word1: str, word2: str) -> int:
|
||||
dp = [[0] * (len(word2)+1) for _ in range(len(word1)+1)]
|
||||
for i in range(len(word1)+1):
|
||||
dp[i][0] = i
|
||||
for j in range(len(word2)+1):
|
||||
dp[0][j] = j
|
||||
for i in range(1, len(word1)+1):
|
||||
for j in range(1, len(word2)+1):
|
||||
if word1[i-1] == word2[j-1]:
|
||||
dp[i][j] = dp[i-1][j-1]
|
||||
else:
|
||||
dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1
|
||||
return dp[-1][-1]
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -370,11 +370,70 @@ class Solution {
|
|||
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def combine(self, n: int, k: int) -> List[List[int]]:
|
||||
res=[] #存放符合条件结果的集合
|
||||
path=[] #用来存放符合条件结果
|
||||
def backtrack(n,k,startIndex):
|
||||
if len(path) == k:
|
||||
res.append(path[:])
|
||||
return
|
||||
for i in range(startIndex,n+1):
|
||||
path.append(i) #处理节点
|
||||
backtrack(n,k,i+1) #递归
|
||||
path.pop() #回溯,撤销处理的节点
|
||||
backtrack(n,k,1)
|
||||
return res
|
||||
```
|
||||
javascript
|
||||
```javascript
|
||||
let result = []
|
||||
let path = []
|
||||
var combine = function(n, k) {
|
||||
result = []
|
||||
combineHelper(n, k, 1)
|
||||
return result
|
||||
};
|
||||
const combineHelper = (n, k, startIndex) => {
|
||||
if (path.length === k) {
|
||||
result.push([...path])
|
||||
return
|
||||
}
|
||||
for (let i = startIndex; i <= n - (k - path.length) + 1; ++i) {
|
||||
path.push(i)
|
||||
combineHelper(n, k, i + 1)
|
||||
path.pop()
|
||||
}
|
||||
}
|
||||
```
|
||||
Go:
|
||||
|
||||
|
||||
```Go
|
||||
var res [][]int
|
||||
func combine(n int, k int) [][]int {
|
||||
res=[][]int{}
|
||||
if n <= 0 || k <= 0 || k > n {
|
||||
return res
|
||||
}
|
||||
backtrack(n, k, 1, []int{})
|
||||
return res
|
||||
}
|
||||
func backtrack(n,k,start int,track []int){
|
||||
if len(track)==k{
|
||||
temp:=make([]int,k)
|
||||
copy(temp,track)
|
||||
res=append(res,temp)
|
||||
}
|
||||
if len(track)+n-start+1 < k {
|
||||
return
|
||||
}
|
||||
for i:=start;i<=n;i++{
|
||||
track=append(track,i)
|
||||
backtrack(n,k,i+1,track)
|
||||
track=track[:len(track)-1]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
```
|
||||
```java
|
||||
class Solution {
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
LinkedList<Integer> path = new LinkedList<>();
|
||||
|
|
@ -176,9 +176,71 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def combine(self, n: int, k: int) -> List[List[int]]:
|
||||
res=[] #存放符合条件结果的集合
|
||||
path=[] #用来存放符合条件结果
|
||||
def backtrack(n,k,startIndex):
|
||||
if len(path) == k:
|
||||
res.append(path[:])
|
||||
return
|
||||
for i in range(startIndex,n-(k-len(path))+2): #优化的地方
|
||||
path.append(i) #处理节点
|
||||
backtrack(n,k,i+1) #递归
|
||||
path.pop() #回溯,撤销处理的节点
|
||||
backtrack(n,k,1)
|
||||
return res
|
||||
```
|
||||
Go:
|
||||
```Go
|
||||
var res [][]int
|
||||
func combine(n int, k int) [][]int {
|
||||
res=[][]int{}
|
||||
if n <= 0 || k <= 0 || k > n {
|
||||
return res
|
||||
}
|
||||
backtrack(n, k, 1, []int{})
|
||||
return res
|
||||
}
|
||||
func backtrack(n,k,start int,track []int){
|
||||
if len(track)==k{
|
||||
temp:=make([]int,k)
|
||||
copy(temp,track)
|
||||
res=append(res,temp)
|
||||
}
|
||||
if len(track)+n-start+1 < k {
|
||||
return
|
||||
}
|
||||
for i:=start;i<=n;i++{
|
||||
track=append(track,i)
|
||||
backtrack(n,k,i+1,track)
|
||||
track=track[:len(track)-1]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
var combine = function(n, k) {
|
||||
const res = [], path = [];
|
||||
backtracking(n, k, 1);
|
||||
return res;
|
||||
function backtracking (n, k, i){
|
||||
const len = path.length;
|
||||
if(len === k) {
|
||||
res.push(Array.from(path));
|
||||
return;
|
||||
}
|
||||
for(let a = i; a <= n + len - k + 1; a++) {
|
||||
path.push(a);
|
||||
backtracking(n, k, a + 1);
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 第78题. 子集
|
||||
|
|
@ -186,7 +186,6 @@ class Solution {
|
|||
result.add(new ArrayList<>());
|
||||
return result;
|
||||
}
|
||||
Arrays.sort(nums);
|
||||
subsetsHelper(nums, 0);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -206,7 +205,20 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def subsets(self, nums: List[int]) -> List[List[int]]:
|
||||
res = []
|
||||
path = []
|
||||
def backtrack(nums,startIndex):
|
||||
res.append(path[:]) #收集子集,要放在终止添加的上面,否则会漏掉自己
|
||||
for i in range(startIndex,len(nums)): #当startIndex已经大于数组的长度了,就终止了,for循环本来也结束了,所以不需要终止条件
|
||||
path.append(nums[i])
|
||||
backtrack(nums,i+1) #递归
|
||||
path.pop() #回溯
|
||||
backtrack(nums,0)
|
||||
return res
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 第90题.子集II
|
||||
|
|
@ -208,7 +208,23 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
|
||||
res = [] #存放符合条件结果的集合
|
||||
path = [] #用来存放符合条件结果
|
||||
def backtrack(nums,startIndex):
|
||||
res.append(path[:])
|
||||
for i in range(startIndex,len(nums)):
|
||||
if i > startIndex and nums[i] == nums[i - 1]: #我们要对同一树层使用过的元素进行跳过
|
||||
continue
|
||||
path.append(nums[i])
|
||||
backtrack(nums,i+1) #递归
|
||||
path.pop() #回溯
|
||||
nums = sorted(nums) #去重需要排序
|
||||
backtrack(nums,0)
|
||||
return res
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -338,6 +338,35 @@ class Solution(object):
|
|||
return ans```
|
||||
```
|
||||
|
||||
JavaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {string} s
|
||||
* @return {string[]}
|
||||
*/
|
||||
var restoreIpAddresses = function(s) {
|
||||
const res = [], path = [];
|
||||
backtracking(0, 0)
|
||||
return res;
|
||||
function backtracking(i) {
|
||||
const len = path.length;
|
||||
if(len > 4) return;
|
||||
if(len === 4 && i === s.length) {
|
||||
res.push(path.join("."));
|
||||
return;
|
||||
}
|
||||
for(let j = i; j < s.length; j++) {
|
||||
const str = s.substr(i, j - i + 1);
|
||||
if(str.length > 3 || +str > 255) break;
|
||||
if(str.length > 1 && str[0] === "0") break;
|
||||
path.push(str);
|
||||
backtracking(j + 1);
|
||||
path.pop()
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 96.不同的二叉搜索树
|
||||
|
||||
|
|
@ -186,10 +186,30 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def numTrees(self, n: int) -> int:
|
||||
dp = [0] * (n + 1)
|
||||
dp[0], dp[1] = 1, 1
|
||||
for i in range(2, n + 1):
|
||||
for j in range(1, i + 1):
|
||||
dp[i] += dp[j - 1] * dp[i - j]
|
||||
return dp[-1]
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
```Go
|
||||
func numTrees(n int)int{
|
||||
dp:=make([]int,n+1)
|
||||
dp[0]=1
|
||||
for i:=1;i<=n;i++{
|
||||
for j:=1;j<=i;j++{
|
||||
dp[i]+=dp[j-1]*dp[i-j]
|
||||
}
|
||||
}
|
||||
return dp[n]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 98.验证二叉搜索树
|
||||
|
|
@ -304,11 +304,58 @@ class Solution {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 简洁实现·递归解法
|
||||
class Solution {
|
||||
public boolean isValidBST(TreeNode root) {
|
||||
return validBST(Long.MIN_VALUE, Long.MAX_VALUE, root);
|
||||
}
|
||||
boolean validBST(long lower, long upper, TreeNode root) {
|
||||
if (root == null) return true;
|
||||
if (root.val <= lower || root.val >= upper) return false;
|
||||
return validBST(lower, root.val, root.left) && validBST(root.val, upper, root.right);
|
||||
}
|
||||
}
|
||||
// 简洁实现·中序遍历
|
||||
class Solution {
|
||||
private long prev = Long.MIN_VALUE;
|
||||
public boolean isValidBST(TreeNode root) {
|
||||
if (root == null) {
|
||||
return true;
|
||||
}
|
||||
if (!isValidBST(root.left)) {
|
||||
return false;
|
||||
}
|
||||
if (root.val <= prev) { // 不满足二叉搜索树条件
|
||||
return false;
|
||||
}
|
||||
prev = root.val;
|
||||
return isValidBST(root.right);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
//递归法
|
||||
class Solution:
|
||||
def isValidBST(self, root: TreeNode) -> bool:
|
||||
res = [] //把二叉搜索树按中序遍历写成list
|
||||
def buildalist(root):
|
||||
if not root: return
|
||||
buildalist(root.left) //左
|
||||
res.append(root.val) //中
|
||||
buildalist(root.right) //右
|
||||
return res
|
||||
buildalist(root)
|
||||
return res == sorted(res) and len(set(res)) == len(res) //检查list里的数有没有重复元素,以及是否按从小到大排列
|
||||
```
|
||||
Go:
|
||||
```Go
|
||||
import "math"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 101. 对称二叉树
|
||||
|
|
@ -360,9 +360,129 @@ Java:
|
|||
|
||||
Python:
|
||||
|
||||
> 递归法
|
||||
```python
|
||||
class Solution:
|
||||
def isSymmetric(self, root: TreeNode) -> bool:
|
||||
if not root:
|
||||
return True
|
||||
return self.compare(root.left, root.right)
|
||||
|
||||
def compare(self, left, right):
|
||||
#首先排除空节点的情况
|
||||
if left == None and right != None: return False
|
||||
elif left != None and right == None: return False
|
||||
elif left == None and right == None: return True
|
||||
#排除了空节点,再排除数值不相同的情况
|
||||
elif left.val != right.val: return False
|
||||
|
||||
#此时就是:左右节点都不为空,且数值相同的情况
|
||||
#此时才做递归,做下一层的判断
|
||||
outside = self.compare(left.left, right.right) #左子树:左、 右子树:右
|
||||
inside = self.compare(left.right, right.left) #左子树:右、 右子树:左
|
||||
isSame = outside and inside #左子树:中、 右子树:中 (逻辑处理)
|
||||
return isSame
|
||||
```
|
||||
|
||||
> 迭代法: 使用队列
|
||||
```python
|
||||
import collections
|
||||
class Solution:
|
||||
def isSymmetric(self, root: TreeNode) -> bool:
|
||||
if not root:
|
||||
return True
|
||||
queue = collections.deque()
|
||||
queue.append(root.left) #将左子树头结点加入队列
|
||||
queue.append(root.right) #将右子树头结点加入队列
|
||||
while queue: #接下来就要判断这这两个树是否相互翻转
|
||||
leftNode = queue.popleft()
|
||||
rightNode = queue.popleft()
|
||||
if not leftNode and not rightNode: #左节点为空、右节点为空,此时说明是对称的
|
||||
continue
|
||||
|
||||
#左右一个节点不为空,或者都不为空但数值不相同,返回false
|
||||
if not leftNode or not rightNode or leftNode.val != rightNode.val:
|
||||
return False
|
||||
queue.append(leftNode.left) #加入左节点左孩子
|
||||
queue.append(rightNode.right) #加入右节点右孩子
|
||||
queue.append(leftNode.right) #加入左节点右孩子
|
||||
queue.append(rightNode.left) #加入右节点左孩子
|
||||
return True
|
||||
```
|
||||
|
||||
> 迭代法:使用栈
|
||||
```python
|
||||
class Solution:
|
||||
def isSymmetric(self, root: TreeNode) -> bool:
|
||||
if not root:
|
||||
return True
|
||||
st = [] #这里改成了栈
|
||||
st.append(root.left)
|
||||
st.append(root.right)
|
||||
while st:
|
||||
leftNode = st.pop()
|
||||
rightNode = st.pop()
|
||||
if not leftNode and not rightNode:
|
||||
continue
|
||||
if not leftNode or not rightNode or leftNode.val != rightNode.val:
|
||||
return False
|
||||
st.append(leftNode.left)
|
||||
st.append(rightNode.right)
|
||||
st.append(leftNode.right)
|
||||
st.append(rightNode.left)
|
||||
return True
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
// 递归
|
||||
func defs(left *TreeNode, right *TreeNode) bool {
|
||||
if left == nil && right == nil {
|
||||
return true;
|
||||
};
|
||||
if left == nil || right == nil {
|
||||
return false;
|
||||
};
|
||||
if left.Val != right.Val {
|
||||
return false;
|
||||
}
|
||||
return defs(left.Left, right.Right) && defs(right.Left, left.Right);
|
||||
}
|
||||
func isSymmetric(root *TreeNode) bool {
|
||||
return defs(root.Left, root.Right);
|
||||
}
|
||||
|
||||
// 迭代
|
||||
func isSymmetric(root *TreeNode) bool {
|
||||
var queue []*TreeNode;
|
||||
if root != nil {
|
||||
queue = append(queue, root.Left, root.Right);
|
||||
}
|
||||
for len(queue) > 0 {
|
||||
left := queue[0];
|
||||
right := queue[1];
|
||||
queue = queue[2:];
|
||||
if left == nil && right == nil {
|
||||
continue;
|
||||
}
|
||||
if left == nil || right == nil || left.Val != right.Val {
|
||||
return false;
|
||||
};
|
||||
queue = append(queue, left.Left, right.Right, right.Left, left.Right);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
JavaScript
|
||||
```javascript
|
||||
|
|
@ -379,6 +499,90 @@ const check = (leftPtr, rightPtr) => {
|
|||
return leftPtr.val === rightPtr.val && check(leftPtr.left, rightPtr.right) && check(leftPtr.right, rightPtr.left)
|
||||
}
|
||||
```
|
||||
JavaScript:
|
||||
|
||||
递归判断是否为对称二叉树:
|
||||
```javascript
|
||||
var isSymmetric = function(root) {
|
||||
//使用递归遍历左右子树 递归三部曲
|
||||
// 1. 确定递归的参数 root.left root.right和返回值true false
|
||||
const compareNode=function(left,right){
|
||||
//2. 确定终止条件 空的情况
|
||||
if(left===null&&right!==null||left!==null&&right===null){
|
||||
return false;
|
||||
}else if(left===null&&right===null){
|
||||
return true;
|
||||
}else if(left.val!==right.val){
|
||||
return false;
|
||||
}
|
||||
//3. 确定单层递归逻辑
|
||||
let outSide=compareNode(left.left,right.right);
|
||||
let inSide=compareNode(left.right,right.left);
|
||||
return outSide&&inSide;
|
||||
}
|
||||
if(root===null){
|
||||
return true;
|
||||
}
|
||||
return compareNode(root.left,root.right);
|
||||
};
|
||||
```
|
||||
队列实现迭代判断是否为对称二叉树:
|
||||
```javascript
|
||||
var isSymmetric = function(root) {
|
||||
//迭代方法判断是否是对称二叉树
|
||||
//首先判断root是否为空
|
||||
if(root===null){
|
||||
return true;
|
||||
}
|
||||
let queue=[];
|
||||
queue.push(root.left);
|
||||
queue.push(root.right);
|
||||
while(queue.length){
|
||||
let leftNode=queue.shift();//左节点
|
||||
let rightNode=queue.shift();//右节点
|
||||
if(leftNode===null&&rightNode===null){
|
||||
continue;
|
||||
}
|
||||
if(leftNode===null||rightNode===null||leftNode.val!==rightNode.val){
|
||||
return false;
|
||||
}
|
||||
queue.push(leftNode.left);//左节点左孩子入队
|
||||
queue.push(rightNode.right);//右节点右孩子入队
|
||||
queue.push(leftNode.right);//左节点右孩子入队
|
||||
queue.push(rightNode.left);//右节点左孩子入队
|
||||
}
|
||||
return true;
|
||||
};
|
||||
```
|
||||
栈实现迭代判断是否为对称二叉树:
|
||||
```javascript
|
||||
var isSymmetric = function(root) {
|
||||
//迭代方法判断是否是对称二叉树
|
||||
//首先判断root是否为空
|
||||
if(root===null){
|
||||
return true;
|
||||
}
|
||||
let stack=[];
|
||||
stack.push(root.left);
|
||||
stack.push(root.right);
|
||||
while(stack.length){
|
||||
let rightNode=stack.pop();//左节点
|
||||
let leftNode=stack.pop();//右节点
|
||||
if(leftNode===null&&rightNode===null){
|
||||
continue;
|
||||
}
|
||||
if(leftNode===null||rightNode===null||leftNode.val!==rightNode.val){
|
||||
return false;
|
||||
}
|
||||
stack.push(leftNode.left);//左节点左孩子入队
|
||||
stack.push(rightNode.right);//右节点右孩子入队
|
||||
stack.push(leftNode.right);//左节点右孩子入队
|
||||
stack.push(rightNode.left);//右节点左孩子入队
|
||||
}
|
||||
return true;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
# 二叉树的层序遍历
|
||||
|
||||
|
|
@ -79,6 +79,67 @@ public:
|
|||
return result;
|
||||
}
|
||||
};
|
||||
```
|
||||
python代码:
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
class Solution:
|
||||
def levelOrder(self, root: TreeNode) -> List[List[int]]:
|
||||
if not root:
|
||||
return []
|
||||
|
||||
quene = [root]
|
||||
out_list = []
|
||||
|
||||
while quene:
|
||||
length = len(queue) # 这里一定要先求出队列的长度,不能用range(len(queue)),因为queue长度是变化的
|
||||
in_list = []
|
||||
for _ in range(length):
|
||||
curnode = queue.pop(0) # (默认移除列表最后一个元素)这里需要移除队列最头上的那个
|
||||
in_list.append(curnode.val)
|
||||
if curnode.left: queue.append(curnode.left)
|
||||
if curnode.right: queue.append(curnode.right)
|
||||
out_list.append(in_list)
|
||||
|
||||
return out_list
|
||||
```
|
||||
|
||||
|
||||
|
||||
javascript代码:
|
||||
|
||||
```javascript
|
||||
var levelOrder = function(root) {
|
||||
//二叉树的层序遍历
|
||||
let res=[],queue=[];
|
||||
queue.push(root);
|
||||
if(root===null){
|
||||
return res;
|
||||
}
|
||||
while(queue.length!==0){
|
||||
// 记录当前层级节点数
|
||||
let length=queue.length;
|
||||
//存放每一层的节点
|
||||
let curLevel=[];
|
||||
for(let i=0;i<length;i++){
|
||||
let node=queue.shift();
|
||||
curLevel.push(node.val);
|
||||
// 存放当前层下一层的节点
|
||||
node.left&&queue.push(node.left);
|
||||
node.right&&queue.push(node.right);
|
||||
}
|
||||
//把每一层的结果放到结果数组
|
||||
res.push(curLevel);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
**此时我们就掌握了二叉树的层序遍历了,那么如下五道leetcode上的题目,只需要修改模板的一两行代码(不能再多了),便可打倒!**
|
||||
|
|
@ -122,6 +183,67 @@ public:
|
|||
}
|
||||
};
|
||||
```
|
||||
python代码:
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
class Solution:
|
||||
def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
|
||||
if not root:
|
||||
return []
|
||||
quene = [root]
|
||||
out_list = []
|
||||
|
||||
while quene:
|
||||
in_list = []
|
||||
for _ in range(len(quene)):
|
||||
node = quene.pop(0)
|
||||
in_list.append(node.val)
|
||||
if node.left:
|
||||
quene.append(node.left)
|
||||
if node.right:
|
||||
quene.append(node.right)
|
||||
|
||||
out_list.append(in_list)
|
||||
|
||||
out_list.reverse()
|
||||
return out_list
|
||||
|
||||
# 执行用时:36 ms, 在所有 Python3 提交中击败了92.00%的用户
|
||||
# 内存消耗:15.2 MB, 在所有 Python3 提交中击败了63.76%的用户
|
||||
```
|
||||
|
||||
|
||||
|
||||
javascript代码
|
||||
|
||||
```javascript
|
||||
var levelOrderBottom = function(root) {
|
||||
let res=[],queue=[];
|
||||
queue.push(root);
|
||||
while(queue.length&&root!==null){
|
||||
// 存放当前层级节点数组
|
||||
let curLevel=[];
|
||||
// 计算当前层级节点数量
|
||||
let length=queue.length;
|
||||
while(length--){
|
||||
let node=queue.shift();
|
||||
// 把当前层节点存入curLevel数组
|
||||
curLevel.push(node.val);
|
||||
// 把下一层级的左右节点存入queue队列
|
||||
node.left&&queue.push(node.left);
|
||||
node.right&&queue.push(node.right);
|
||||
}
|
||||
res.push(curLevel);
|
||||
}
|
||||
return res.reverse();
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
## 199.二叉树的右视图
|
||||
|
|
@ -159,6 +281,73 @@ public:
|
|||
}
|
||||
};
|
||||
```
|
||||
python代码:
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
class Solution:
|
||||
def rightSideView(self, root: TreeNode) -> List[int]:
|
||||
if not root:
|
||||
return []
|
||||
|
||||
# deque来自collections模块,不在力扣平台时,需要手动写入
|
||||
# 'from collections import deque' 导入
|
||||
# deque相比list的好处是,list的pop(0)是O(n)复杂度,deque的popleft()是O(1)复杂度
|
||||
|
||||
quene = deque([root])
|
||||
out_list = []
|
||||
|
||||
while quene:
|
||||
# 每次都取最后一个node就可以了
|
||||
node = quene[-1]
|
||||
out_list.append(node.val)
|
||||
|
||||
# 执行这个遍历的目的是获取下一层所有的node
|
||||
for _ in range(len(quene)):
|
||||
node = quene.popleft()
|
||||
if node.left:
|
||||
quene.append(node.left)
|
||||
if node.right:
|
||||
quene.append(node.right)
|
||||
|
||||
return out_list
|
||||
|
||||
# 执行用时:36 ms, 在所有 Python3 提交中击败了89.47%的用户
|
||||
# 内存消耗:14.6 MB, 在所有 Python3 提交中击败了96.65%的用户
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
javascript代码:
|
||||
|
||||
```javascript
|
||||
var rightSideView = function(root) {
|
||||
//二叉树右视图 只需要把每一层最后一个节点存储到res数组
|
||||
let res=[],queue=[];
|
||||
queue.push(root);
|
||||
while(queue.length&&root!==null){
|
||||
// 记录当前层级节点个数
|
||||
let length=queue.length;
|
||||
while(length--){
|
||||
let node=queue.shift();
|
||||
//length长度为0的时候表明到了层级最后一个节点
|
||||
if(!length){
|
||||
res.push(node.val);
|
||||
}
|
||||
node.left&&queue.push(node.left);
|
||||
node.right&&queue.push(node.right);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
```
|
||||
|
||||
## 637.二叉树的层平均值
|
||||
|
||||
|
|
@ -199,6 +388,71 @@ public:
|
|||
|
||||
```
|
||||
|
||||
python代码:
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
class Solution:
|
||||
def averageOfLevels(self, root: TreeNode) -> List[float]:
|
||||
if not root:
|
||||
return []
|
||||
|
||||
quene = deque([root])
|
||||
out_list = []
|
||||
|
||||
while quene:
|
||||
in_list = []
|
||||
|
||||
for _ in range(len(quene)):
|
||||
node = quene.popleft()
|
||||
in_list.append(node.val)
|
||||
if node.left:
|
||||
quene.append(node.left)
|
||||
if node.right:
|
||||
quene.append(node.right)
|
||||
|
||||
out_list.append(in_list)
|
||||
|
||||
out_list = map(lambda x: sum(x) / len(x), out_list)
|
||||
|
||||
return out_list
|
||||
|
||||
# 执行用时:56 ms, 在所有 Python3 提交中击败了81.48%的用户
|
||||
# 内存消耗:17 MB, 在所有 Python3 提交中击败了89.68%的用户
|
||||
```
|
||||
|
||||
|
||||
|
||||
javascript代码:
|
||||
|
||||
```javascript
|
||||
var averageOfLevels = function(root) {
|
||||
//层级平均值
|
||||
let res=[],queue=[];
|
||||
queue.push(root);
|
||||
while(queue.length&&root!==null){
|
||||
//每一层节点个数
|
||||
let length=queue.length;
|
||||
//sum记录每一层的和
|
||||
let sum=0;
|
||||
for(let i=0;i<length;i++){
|
||||
let node=queue.shift();
|
||||
sum+=node.val;
|
||||
node.left&&queue.push(node.left);
|
||||
node.right&&queue.push(node.right);
|
||||
}
|
||||
//每一层的平均值存入数组res
|
||||
res.push(sum/length);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
```
|
||||
|
||||
## 429.N叉树的层序遍历
|
||||
|
||||
题目链接:https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/
|
||||
|
|
@ -250,6 +504,92 @@ public:
|
|||
};
|
||||
```
|
||||
|
||||
python代码:
|
||||
|
||||
```python
|
||||
"""
|
||||
# Definition for a Node.
|
||||
class Node:
|
||||
def __init__(self, val=None, children=None):
|
||||
self.val = val
|
||||
self.children = children
|
||||
"""
|
||||
|
||||
class Solution:
|
||||
def levelOrder(self, root: 'Node') -> List[List[int]]:
|
||||
if not root:
|
||||
return []
|
||||
|
||||
quene = deque([root])
|
||||
out_list = []
|
||||
|
||||
while quene:
|
||||
in_list = []
|
||||
|
||||
for _ in range(len(quene)):
|
||||
node = quene.popleft()
|
||||
in_list.append(node.val)
|
||||
if node.children:
|
||||
# 这个地方要用extend而不是append,我们看下面的例子:
|
||||
# In [18]: alist=[]
|
||||
# In [19]: alist.append([1,2,3])
|
||||
# In [20]: alist
|
||||
# Out[20]: [[1, 2, 3]]
|
||||
# In [21]: alist.extend([4,5,6])
|
||||
# In [22]: alist
|
||||
# Out[22]: [[1, 2, 3], 4, 5, 6]
|
||||
# 可以看到extend对要添加的list进行了一个解包操作
|
||||
# print(root.children),可以得到children是一个包含
|
||||
# 孩子节点地址的list,我们使用for遍历quene的时候,
|
||||
# 希望quene是一个单层list,所以要用extend
|
||||
# 使用extend的情况,如果print(quene),结果是
|
||||
# deque([<__main__.Node object at 0x7f60763ae0a0>])
|
||||
# deque([<__main__.Node object at 0x7f607636e6d0>, <__main__.Node object at 0x7f607636e130>, <__main__.Node object at 0x7f607636e310>])
|
||||
# deque([<__main__.Node object at 0x7f607636e880>, <__main__.Node object at 0x7f607636ef10>])
|
||||
# 可以看到是单层list
|
||||
# 如果使用append,print(quene)的结果是
|
||||
# deque([<__main__.Node object at 0x7f18907530a0>])
|
||||
# deque([[<__main__.Node object at 0x7f18907136d0>, <__main__.Node object at 0x7f1890713130>, <__main__.Node object at 0x7f1890713310>]])
|
||||
# 可以看到是两层list,这样for的遍历就会报错
|
||||
|
||||
quene.extend(node.children)
|
||||
|
||||
out_list.append(in_list)
|
||||
|
||||
return out_list
|
||||
|
||||
# 执行用时:60 ms, 在所有 Python3 提交中击败了76.99%的用户
|
||||
# 内存消耗:16.5 MB, 在所有 Python3 提交中击败了89.19%的用户
|
||||
```
|
||||
|
||||
|
||||
|
||||
JavaScript代码:
|
||||
|
||||
```JavaScript
|
||||
var levelOrder = function(root) {
|
||||
//每一层可能有2个以上,所以不再使用node.left node.right
|
||||
let res=[],queue=[];
|
||||
queue.push(root);
|
||||
while(queue.length&&root!==null){
|
||||
//记录每一层节点个数还是和二叉树一致
|
||||
let length=queue.length;
|
||||
//存放每层节点 也和二叉树一致
|
||||
let curLevel=[];
|
||||
while(length--){
|
||||
let node = queue.shift();
|
||||
curLevel.push(node.val);
|
||||
//这里不再是 ndoe.left node.right 而是循坏node.children
|
||||
for(let item of node.children){
|
||||
item&&queue.push(item);
|
||||
}
|
||||
}
|
||||
res.push(curLevel);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
```
|
||||
|
||||
## 515.在每个树行中找最大值
|
||||
|
||||
题目链接:https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/
|
||||
|
|
@ -287,6 +627,29 @@ public:
|
|||
}
|
||||
};
|
||||
```
|
||||
javascript代码:
|
||||
|
||||
```javascript
|
||||
var largestValues = function(root) {
|
||||
//使用层序遍历
|
||||
let res=[],queue=[];
|
||||
queue.push(root);
|
||||
while(root!==null&&queue.length){
|
||||
//设置max初始值就是队列的第一个元素
|
||||
let max=queue[0];
|
||||
let length=queue.length;
|
||||
while(length--){
|
||||
let node = queue.shift();
|
||||
max=max>node.val?max:node.val;
|
||||
node.left&&queue.push(node.left);
|
||||
node.right&&queue.push(node.right);
|
||||
}
|
||||
//把每一层的最大值放到res数组
|
||||
res.push(max);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
```
|
||||
|
||||
## 116.填充每个节点的下一个右侧节点指针
|
||||
|
||||
|
|
@ -657,8 +1020,569 @@ Python:
|
|||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func levelOrder(root *TreeNode) [][]int {
|
||||
result:=make([][]int,0)
|
||||
if root==nil{
|
||||
return result
|
||||
}
|
||||
|
||||
queue:=make([]*TreeNode,0)
|
||||
queue=append(queue,root)
|
||||
|
||||
for len(queue)>0{
|
||||
list:=make([]int,0)
|
||||
l:=len(queue)
|
||||
|
||||
for i:=0;i<l;i++{
|
||||
level:=queue[0]
|
||||
queue=queue[1:]
|
||||
list=append(list,level.Val)
|
||||
if level.Left!=nil{
|
||||
queue=append(queue,level.Left)
|
||||
}
|
||||
if level.Right!=nil{
|
||||
queue=append(queue,level.Right)
|
||||
}
|
||||
}
|
||||
result=append(result,list)
|
||||
}
|
||||
return result
|
||||
}
|
||||
```
|
||||
> 二叉树的层序遍历(GO语言完全版)
|
||||
|
||||
```go
|
||||
/**
|
||||
102. 二叉树的层序遍历
|
||||
*/
|
||||
func levelOrder(root *TreeNode) [][]int {
|
||||
res:=[][]int{}
|
||||
if root==nil{//防止为空
|
||||
return res
|
||||
}
|
||||
queue:=list.New()
|
||||
queue.PushBack(root)
|
||||
var tmpArr []int
|
||||
for queue.Len()>0 {
|
||||
length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数)
|
||||
for i:=0;i<length;i++{
|
||||
node:=queue.Remove(queue.Front()).(*TreeNode)//出队列
|
||||
if node.Left!=nil{
|
||||
queue.PushBack(node.Left)
|
||||
}
|
||||
if node.Right!=nil{
|
||||
queue.PushBack(node.Right)
|
||||
}
|
||||
tmpArr=append(tmpArr,node.Val)//将值加入本层切片中
|
||||
}
|
||||
res=append(res,tmpArr)//放入结果集
|
||||
tmpArr=[]int{}//清空层的数据
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
107. 二叉树的层序遍历 II
|
||||
*/
|
||||
func levelOrderBottom(root *TreeNode) [][]int {
|
||||
queue:=list.New()
|
||||
res:=[][]int{}
|
||||
if root==nil{
|
||||
return res
|
||||
}
|
||||
queue.PushBack(root)
|
||||
for queue.Len()>0{
|
||||
length:=queue.Len()
|
||||
tmp:=[]int{}
|
||||
for i:=0;i<length;i++{
|
||||
node:=queue.Remove(queue.Front()).(*TreeNode)
|
||||
if node.Left!=nil{
|
||||
queue.PushBack(node.Left)
|
||||
}
|
||||
if node.Right!=nil{
|
||||
queue.PushBack(node.Right)
|
||||
}
|
||||
tmp=append(tmp,node.Val)
|
||||
}
|
||||
res=append(res,tmp)
|
||||
}
|
||||
//反转结果集
|
||||
for i:=0;i<len(res)/2;i++{
|
||||
res[i],res[len(res)-i-1]=res[len(res)-i-1],res[i]
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
199. 二叉树的右视图
|
||||
*/
|
||||
func rightSideView(root *TreeNode) []int {
|
||||
queue:=list.New()
|
||||
res:=[][]int{}
|
||||
var finaRes []int
|
||||
if root==nil{
|
||||
return finaRes
|
||||
}
|
||||
queue.PushBack(root)
|
||||
for queue.Len()>0{
|
||||
length:=queue.Len()
|
||||
tmp:=[]int{}
|
||||
for i:=0;i<length;i++{
|
||||
node:=queue.Remove(queue.Front()).(*TreeNode)
|
||||
if node.Left!=nil{
|
||||
queue.PushBack(node.Left)
|
||||
}
|
||||
if node.Right!=nil{
|
||||
queue.PushBack(node.Right)
|
||||
}
|
||||
tmp=append(tmp,node.Val)
|
||||
}
|
||||
res=append(res,tmp)
|
||||
}
|
||||
//取每一层的最后一个元素
|
||||
for i:=0;i<len(res);i++{
|
||||
finaRes=append(finaRes,res[i][len(res[i])-1])
|
||||
}
|
||||
return finaRes
|
||||
}
|
||||
|
||||
/**
|
||||
637. 二叉树的层平均值
|
||||
*/
|
||||
func averageOfLevels(root *TreeNode) []float64 {
|
||||
res:=[][]int{}
|
||||
var finRes []float64
|
||||
if root==nil{//防止为空
|
||||
return finRes
|
||||
}
|
||||
queue:=list.New()
|
||||
queue.PushBack(root)
|
||||
var tmpArr []int
|
||||
for queue.Len()>0 {
|
||||
length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数)
|
||||
for i:=0;i<length;i++{
|
||||
node:=queue.Remove(queue.Front()).(*TreeNode)//出队列
|
||||
if node.Left!=nil{
|
||||
queue.PushBack(node.Left)
|
||||
}
|
||||
if node.Right!=nil{
|
||||
queue.PushBack(node.Right)
|
||||
}
|
||||
tmpArr=append(tmpArr,node.Val)//将值加入本层切片中
|
||||
}
|
||||
res=append(res,tmpArr)//放入结果集
|
||||
tmpArr=[]int{}//清空层的数据
|
||||
}
|
||||
//计算每层的平均值
|
||||
length:=len(res)
|
||||
for i:=0;i<length;i++{
|
||||
var sum int
|
||||
for j:=0;j<len(res[i]);j++{
|
||||
sum+=res[i][j]
|
||||
}
|
||||
tmp:=float64(sum)/float64(len(res[i]))
|
||||
finRes=append(finRes,tmp)//将平均值放入结果集合
|
||||
}
|
||||
return finRes
|
||||
}
|
||||
|
||||
/**
|
||||
429. N 叉树的层序遍历
|
||||
*/
|
||||
|
||||
func levelOrder(root *Node) [][]int {
|
||||
queue:=list.New()
|
||||
res:=[][]int{}//结果集
|
||||
if root==nil{
|
||||
return res
|
||||
}
|
||||
queue.PushBack(root)
|
||||
for queue.Len()>0{
|
||||
length:=queue.Len()//记录当前层的数量
|
||||
var tmp []int
|
||||
for T:=0;T<length;T++{//该层的每个元素:一添加到该层的结果集中;二找到该元素的下层元素加入到队列中,方便下次使用
|
||||
myNode:=queue.Remove(queue.Front()).(*Node)
|
||||
tmp=append(tmp,myNode.Val)
|
||||
for i:=0;i<len(myNode.Children);i++{
|
||||
queue.PushBack(myNode.Children[i])
|
||||
}
|
||||
}
|
||||
res=append(res,tmp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
/**
|
||||
515. 在每个树行中找最大值
|
||||
*/
|
||||
func largestValues(root *TreeNode) []int {
|
||||
res:=[][]int{}
|
||||
var finRes []int
|
||||
if root==nil{//防止为空
|
||||
return finRes
|
||||
}
|
||||
queue:=list.New()
|
||||
queue.PushBack(root)
|
||||
var tmpArr []int
|
||||
//层次遍历
|
||||
for queue.Len()>0 {
|
||||
length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数)
|
||||
for i:=0;i<length;i++{
|
||||
node:=queue.Remove(queue.Front()).(*TreeNode)//出队列
|
||||
if node.Left!=nil{
|
||||
queue.PushBack(node.Left)
|
||||
}
|
||||
if node.Right!=nil{
|
||||
queue.PushBack(node.Right)
|
||||
}
|
||||
tmpArr=append(tmpArr,node.Val)//将值加入本层切片中
|
||||
}
|
||||
res=append(res,tmpArr)//放入结果集
|
||||
tmpArr=[]int{}//清空层的数据
|
||||
}
|
||||
//找到每层的最大值
|
||||
for i:=0;i<len(res);i++{
|
||||
finRes=append(finRes,max(res[i]...))
|
||||
}
|
||||
return finRes
|
||||
}
|
||||
func max(vals...int) int {
|
||||
max:=int(math.Inf(-1))//负无穷
|
||||
for _, val := range vals {
|
||||
if val > max {
|
||||
max = val
|
||||
}
|
||||
}
|
||||
return max
|
||||
}
|
||||
/**
|
||||
116. 填充每个节点的下一个右侧节点指针
|
||||
117. 填充每个节点的下一个右侧节点指针 II
|
||||
*/
|
||||
|
||||
func connect(root *Node) *Node {
|
||||
res:=[][]*Node{}
|
||||
if root==nil{//防止为空
|
||||
return root
|
||||
}
|
||||
queue:=list.New()
|
||||
queue.PushBack(root)
|
||||
var tmpArr []*Node
|
||||
for queue.Len()>0 {
|
||||
length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数)
|
||||
for i:=0;i<length;i++{
|
||||
node:=queue.Remove(queue.Front()).(*Node)//出队列
|
||||
if node.Left!=nil{
|
||||
queue.PushBack(node.Left)
|
||||
}
|
||||
if node.Right!=nil{
|
||||
queue.PushBack(node.Right)
|
||||
}
|
||||
tmpArr=append(tmpArr,node)//将值加入本层切片中
|
||||
}
|
||||
res=append(res,tmpArr)//放入结果集
|
||||
tmpArr=[]*Node{}//清空层的数据
|
||||
}
|
||||
//遍历每层元素,指定next
|
||||
for i:=0;i<len(res);i++{
|
||||
for j:=0;j<len(res[i])-1;j++{
|
||||
res[i][j].Next=res[i][j+1]
|
||||
}
|
||||
}
|
||||
return root
|
||||
}
|
||||
```
|
||||
Javascript:
|
||||
```javascript
|
||||
var levelOrder = function (root) {
|
||||
let ans = [];
|
||||
if (!root) return ans;
|
||||
let queue = [root];
|
||||
while (queue.length) {
|
||||
let size = queue.length;
|
||||
let temp = [];
|
||||
while (size--) {
|
||||
let n = queue.shift();
|
||||
temp.push(n.val);
|
||||
if (n.left) queue.push(n.left);
|
||||
if (n.right) queue.push(n.right);
|
||||
}
|
||||
ans.push(temp);
|
||||
}
|
||||
return ans;
|
||||
};
|
||||
```
|
||||
|
||||
> 二叉树的层序遍历(Javascript语言完全版) (迭代 + 递归)
|
||||
|
||||
```js
|
||||
/**
|
||||
* 102. 二叉树的层序遍历
|
||||
* @param {TreeNode} root
|
||||
* @return {number[][]}
|
||||
*/
|
||||
|
||||
// 迭代
|
||||
|
||||
var levelOrder = function(root) {
|
||||
const queue = [], res = [];
|
||||
root && queue.push(root);
|
||||
while(len = queue.length) {
|
||||
const val = [];
|
||||
while(len--) {
|
||||
const node = queue.shift();
|
||||
val.push(node.val);
|
||||
node.left && queue.push(node.left);
|
||||
node.right && queue.push(node.right);
|
||||
}
|
||||
res.push(val);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
// 递归
|
||||
var levelOrder = function(root) {
|
||||
const res = [];
|
||||
function defs (root, i) {
|
||||
if(!root) return;
|
||||
if(!res[i]) res[i] = [];
|
||||
res[i].push(root.val)
|
||||
root.left && defs(root.left, i + 1);
|
||||
root.right && defs(root.right, i + 1);
|
||||
}
|
||||
defs(root, 0);
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 107. 二叉树的层序遍历 II
|
||||
* @param {TreeNode} root
|
||||
* @return {number[][]}
|
||||
*/
|
||||
|
||||
// 迭代
|
||||
|
||||
var levelOrderBottom = function(root) {
|
||||
const queue = [], res = [];
|
||||
root && queue.push(root);
|
||||
while(len = queue.length) {
|
||||
const val = [];
|
||||
while(len--) {
|
||||
const node = queue.shift();
|
||||
val.push(node.val);
|
||||
node.left && queue.push(node.left);
|
||||
node.right && queue.push(node.right);
|
||||
}
|
||||
res.push(val);
|
||||
}
|
||||
return res.reverse()
|
||||
};
|
||||
|
||||
// 递归
|
||||
|
||||
var levelOrderBottom = function(root) {
|
||||
const res = [];
|
||||
function defs (root, i) {
|
||||
if(!root) return;
|
||||
if(!res[i]) res[i] = [];
|
||||
res[i].push(root.val);
|
||||
root.left && defs(root.left, i + 1);
|
||||
root.right && defs(root.right, i + 1);
|
||||
}
|
||||
defs(root, 0);
|
||||
return res.reverse();
|
||||
};
|
||||
|
||||
/**
|
||||
* 199. 二叉树的右视图
|
||||
* @param {TreeNode} root
|
||||
* @return {number[]}
|
||||
*/
|
||||
|
||||
// 迭代
|
||||
|
||||
var rightSideView = function(root) {
|
||||
const res = [], queue = [];
|
||||
root && queue.push(root);
|
||||
while(l = queue.length) {
|
||||
while (l--) {
|
||||
const {val, left, right} = queue.shift();
|
||||
!l && res.push(val);
|
||||
left && queue.push(left);
|
||||
right && queue.push(right);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
// 递归
|
||||
var rightSideView = function(root) {
|
||||
const res = [];
|
||||
function defs(root, i) {
|
||||
if(!root) return;
|
||||
res[i] = root.val;
|
||||
root.left && defs(root.left, i + 1);
|
||||
root.right && defs(root.right, i + 1);
|
||||
}
|
||||
defs(root, 0);
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* 637. 二叉树的层平均值
|
||||
* @param {TreeNode} root
|
||||
* @return {number[]}
|
||||
*/
|
||||
|
||||
// 迭代
|
||||
var averageOfLevels = function(root) {
|
||||
const queue = [], res = [];
|
||||
root && queue.push(root);
|
||||
while(len = queue.length) {
|
||||
let sum = 0, l = len;
|
||||
while(l--) {
|
||||
const {val, left, right} = queue.shift();
|
||||
sum += val;
|
||||
left && queue.push(left);
|
||||
right && queue.push(right);
|
||||
}
|
||||
res.push(sum/len);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
// 递归
|
||||
var averageOfLevels = function(root) {
|
||||
const resCount = [], res = [];
|
||||
function defs(root, i) {
|
||||
if(!root) return;
|
||||
if(isNaN(res[i])) resCount[i] = res[i] = 0;
|
||||
res[i] += root.val;
|
||||
resCount[i]++;
|
||||
root.left && defs(root.left, i + 1);
|
||||
root.right && defs(root.right, i + 1);
|
||||
}
|
||||
defs(root, 0);
|
||||
return res.map((val, i) => val / resCount[i]);
|
||||
};
|
||||
|
||||
/**
|
||||
* 515. 在每个树行中找最大值
|
||||
* @param {TreeNode} root
|
||||
* @return {number[]}
|
||||
*/
|
||||
|
||||
// 迭代
|
||||
const MIN_G = Number.MIN_SAFE_INTEGER;
|
||||
var largestValues = function(root) {
|
||||
const queue = [], res = [];
|
||||
root && queue.push(root);
|
||||
while(len = queue.length) {
|
||||
let max = MIN_G;
|
||||
while(len--) {
|
||||
const {val, left, right} = queue.shift();
|
||||
max = max > val ? max : val;
|
||||
left && queue.push(left);
|
||||
right && queue.push(right);
|
||||
}
|
||||
res.push(max);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
// 递归
|
||||
var largestValues = function(root) {
|
||||
const res = [];
|
||||
function defs (root, i) {
|
||||
if(!root) return;
|
||||
if(isNaN(res[i])) res[i] = root.val;
|
||||
res[i] = res[i] > root.val ? res[i] : root.val;
|
||||
root.left && defs(root.left, i + 1);
|
||||
root.right && defs(root.right, i + 1);
|
||||
}
|
||||
defs(root, 0);
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* 429. N 叉树的层序遍历
|
||||
* @param {Node|null} root
|
||||
* @return {number[][]}
|
||||
*/
|
||||
|
||||
// 迭代
|
||||
var levelOrder = function(root) {
|
||||
const queue = [], res = [];
|
||||
root && queue.push(root);
|
||||
while(len = queue.length) {
|
||||
const vals = [];
|
||||
while(len--) {
|
||||
const {val, children} = queue.shift();
|
||||
vals.push(val);
|
||||
for(const e of children) {
|
||||
queue.push(e);
|
||||
}
|
||||
}
|
||||
res.push(vals);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
// 递归
|
||||
|
||||
var levelOrder = function(root) {
|
||||
const res = [];
|
||||
function defs (root, i) {
|
||||
if(!root) return;
|
||||
if(!res[i]) res[i] = [];
|
||||
res[i].push(root.val);
|
||||
for(const e of root.children) {
|
||||
defs(e, i + 1);
|
||||
}
|
||||
}
|
||||
defs(root, 0);
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* 116. 填充每个节点的下一个右侧节点指针
|
||||
* 117. 填充每个节点的下一个右侧节点指针 II
|
||||
* @param {Node} root
|
||||
* @return {Node}
|
||||
*/
|
||||
|
||||
// 迭代
|
||||
var connect = function(root) {
|
||||
const queue = [];
|
||||
root && queue.push(root);
|
||||
while(len = queue.length) {
|
||||
while(len--) {
|
||||
const node1 = queue.shift(),
|
||||
node2 = len ? queue[0] : null;
|
||||
node1.next = node2;
|
||||
node1.left && queue.push(node1.left);
|
||||
node1.right && queue.push(node1.right);
|
||||
}
|
||||
}
|
||||
return root;
|
||||
};
|
||||
|
||||
// 递归
|
||||
var connect = function(root) {
|
||||
const res = [];
|
||||
function defs (root, i) {
|
||||
if(!root) return;
|
||||
if(res[i]) res[i].next = root;
|
||||
res[i] = root;
|
||||
root.left && defs(root.left, i + 1);
|
||||
root.right && defs(root.right, i + 1);
|
||||
}
|
||||
defs(root, 0);
|
||||
return root;
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
看完本篇可以一起做了如下两道题目:
|
||||
|
|
@ -193,40 +193,6 @@ public:
|
|||
};
|
||||
```
|
||||
|
||||
使用栈来模拟后序遍历依然可以
|
||||
|
||||
```C++
|
||||
class Solution {
|
||||
public:
|
||||
int maxDepth(TreeNode* root) {
|
||||
stack<TreeNode*> st;
|
||||
if (root != NULL) st.push(root);
|
||||
int depth = 0;
|
||||
int result = 0;
|
||||
while (!st.empty()) {
|
||||
TreeNode* node = st.top();
|
||||
if (node != NULL) {
|
||||
st.pop();
|
||||
st.push(node); // 中
|
||||
st.push(NULL);
|
||||
depth++;
|
||||
if (node->right) st.push(node->right); // 右
|
||||
if (node->left) st.push(node->left); // 左
|
||||
|
||||
} else {
|
||||
st.pop();
|
||||
node = st.top();
|
||||
st.pop();
|
||||
depth--;
|
||||
}
|
||||
result = result > depth ? result : depth;
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
|
|
@ -281,9 +247,163 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
104.二叉树的最大深度
|
||||
> 递归法:
|
||||
```python
|
||||
class Solution:
|
||||
def maxDepth(self, root: TreeNode) -> int:
|
||||
return self.getDepth(root)
|
||||
|
||||
def getDepth(self, node):
|
||||
if not node:
|
||||
return 0
|
||||
leftDepth = self.getDepth(node.left) #左
|
||||
rightDepth = self.getDepth(node.right) #右
|
||||
depth = 1 + max(leftDepth, rightDepth) #中
|
||||
return depth
|
||||
```
|
||||
> 递归法;精简代码
|
||||
```python
|
||||
class Solution:
|
||||
def maxDepth(self, root: TreeNode) -> int:
|
||||
if not root:
|
||||
return 0
|
||||
return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
|
||||
```
|
||||
|
||||
> 迭代法:
|
||||
```python
|
||||
import collections
|
||||
class Solution:
|
||||
def maxDepth(self, root: TreeNode) -> int:
|
||||
if not root:
|
||||
return 0
|
||||
depth = 0 #记录深度
|
||||
queue = collections.deque()
|
||||
queue.append(root)
|
||||
while queue:
|
||||
size = len(queue)
|
||||
depth += 1
|
||||
for i in range(size):
|
||||
node = queue.popleft()
|
||||
if node.left:
|
||||
queue.append(node.left)
|
||||
if node.right:
|
||||
queue.append(node.right)
|
||||
return depth
|
||||
```
|
||||
|
||||
559.N叉树的最大深度
|
||||
> 递归法:
|
||||
```python
|
||||
class Solution:
|
||||
def maxDepth(self, root: 'Node') -> int:
|
||||
if not root:
|
||||
return 0
|
||||
depth = 0
|
||||
for i in range(len(root.children)):
|
||||
depth = max(depth, self.maxDepth(root.children[i]))
|
||||
return depth + 1
|
||||
```
|
||||
|
||||
> 迭代法:
|
||||
```python
|
||||
import collections
|
||||
class Solution:
|
||||
def maxDepth(self, root: 'Node') -> int:
|
||||
queue = collections.deque()
|
||||
if root:
|
||||
queue.append(root)
|
||||
depth = 0 #记录深度
|
||||
while queue:
|
||||
size = len(queue)
|
||||
depth += 1
|
||||
for i in range(size):
|
||||
node = queue.popleft()
|
||||
for j in range(len(node.children)):
|
||||
if node.children[j]:
|
||||
queue.append(node.children[j])
|
||||
return depth
|
||||
```
|
||||
|
||||
> 使用栈来模拟后序遍历依然可以
|
||||
```python
|
||||
class Solution:
|
||||
def maxDepth(self, root: 'Node') -> int:
|
||||
st = []
|
||||
if root:
|
||||
st.append(root)
|
||||
depth = 0
|
||||
result = 0
|
||||
while st:
|
||||
node = st.pop()
|
||||
if node != None:
|
||||
st.append(node) #中
|
||||
st.append(None)
|
||||
depth += 1
|
||||
for i in range(len(node.children)): #处理孩子
|
||||
if node.children[i]:
|
||||
st.append(node.children[i])
|
||||
|
||||
else:
|
||||
node = st.pop()
|
||||
depth -= 1
|
||||
result = max(result, depth)
|
||||
return result
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
func max (a, b int) int {
|
||||
if a > b {
|
||||
return a;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
// 递归
|
||||
func maxDepth(root *TreeNode) int {
|
||||
if root == nil {
|
||||
return 0;
|
||||
}
|
||||
return max(maxDepth(root.Left), maxDepth(root.Right)) + 1;
|
||||
}
|
||||
|
||||
// 遍历
|
||||
func maxDepth(root *TreeNode) int {
|
||||
levl := 0;
|
||||
queue := make([]*TreeNode, 0);
|
||||
if root != nil {
|
||||
queue = append(queue, root);
|
||||
}
|
||||
for l := len(queue); l > 0; {
|
||||
for ;l > 0;l-- {
|
||||
node := queue[0];
|
||||
if node.Left != nil {
|
||||
queue = append(queue, node.Left);
|
||||
}
|
||||
if node.Right != nil {
|
||||
queue = append(queue, node.Right);
|
||||
}
|
||||
queue = queue[1:];
|
||||
}
|
||||
levl++;
|
||||
l = len(queue);
|
||||
}
|
||||
return levl;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
JavaScript
|
||||
```javascript
|
||||
|
|
@ -292,6 +412,44 @@ var maxDepth = function(root) {
|
|||
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right))
|
||||
};
|
||||
```
|
||||
二叉树最大深度递归遍历
|
||||
```javascript
|
||||
var maxDepth = function(root) {
|
||||
//使用递归的方法 递归三部曲
|
||||
//1. 确定递归函数的参数和返回值
|
||||
const getDepth=function(node){
|
||||
//2. 确定终止条件
|
||||
if(node===null){
|
||||
return 0;
|
||||
}
|
||||
//3. 确定单层逻辑
|
||||
let leftDepth=getDepth(node.left);
|
||||
let rightDepth=getDepth(node.right);
|
||||
let depth=1+Math.max(leftDepth,rightDepth);
|
||||
return depth;
|
||||
}
|
||||
return getDepth(root);
|
||||
};
|
||||
```
|
||||
二叉树最大深度层级遍历
|
||||
```javascript
|
||||
var maxDepth = function(root) {
|
||||
//使用递归的方法 递归三部曲
|
||||
//1. 确定递归函数的参数和返回值
|
||||
const getDepth=function(node){
|
||||
//2. 确定终止条件
|
||||
if(node===null){
|
||||
return 0;
|
||||
}
|
||||
//3. 确定单层逻辑
|
||||
let leftDepth=getDepth(node.left);
|
||||
let rightDepth=getDepth(node.right);
|
||||
let depth=1+Math.max(leftDepth,rightDepth);
|
||||
return depth;
|
||||
}
|
||||
return getDepth(root);
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
看完本文,可以一起解决如下两道题目
|
||||
|
|
@ -580,8 +580,10 @@ tree2 的前序遍历是[1 2 3], 后序遍历是[3 2 1]。
|
|||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
106.从中序与后序遍历序列构造二叉树
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public TreeNode buildTree(int[] inorder, int[] postorder) {
|
||||
|
|
@ -617,9 +619,79 @@ class Solution {
|
|||
}
|
||||
```
|
||||
|
||||
105.从前序与中序遍历序列构造二叉树
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public TreeNode buildTree(int[] preorder, int[] inorder) {
|
||||
return helper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
|
||||
}
|
||||
|
||||
public TreeNode helper(int[] preorder, int preLeft, int preRight,
|
||||
int[] inorder, int inLeft, int inRight) {
|
||||
// 递归终止条件
|
||||
if (inLeft > inRight || preLeft > preRight) return null;
|
||||
|
||||
// val 为前序遍历第一个的值,也即是根节点的值
|
||||
// idx 为根据根节点的值来找中序遍历的下标
|
||||
int idx = inLeft, val = preorder[preLeft];
|
||||
TreeNode root = new TreeNode(val);
|
||||
for (int i = inLeft; i <= inRight; i++) {
|
||||
if (inorder[i] == val) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据 idx 来递归找左右子树
|
||||
root.left = helper(preorder, preLeft + 1, preLeft + (idx - inLeft),
|
||||
inorder, inLeft, idx - 1);
|
||||
root.right = helper(preorder, preLeft + (idx - inLeft) + 1, preRight,
|
||||
inorder, idx + 1, inRight);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
105.从前序与中序遍历序列构造二叉树
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
//递归法
|
||||
class Solution:
|
||||
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
|
||||
if not preorder: return None //特殊情况
|
||||
root = TreeNode(preorder[0]) //新建父节点
|
||||
p=inorder.index(preorder[0]) //找到父节点在中序遍历的位置(因为没有重复的元素,才可以这样找)
|
||||
root.left = self.buildTree(preorder[1:p+1],inorder[:p]) //注意左节点时分割中序数组和前续数组的开闭环
|
||||
root.right = self.buildTree(preorder[p+1:],inorder[p+1:]) //分割中序数组和前续数组
|
||||
return root
|
||||
```
|
||||
106.从中序与后序遍历序列构造二叉树
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
//递归法
|
||||
class Solution:
|
||||
def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
|
||||
if not postorder: return None //特殊情况
|
||||
root = TreeNode(postorder[-1]) //新建父节点
|
||||
p=inorder.index(postorder[-1]) //找到父节点在中序遍历的位置*因为没有重复的元素,才可以这样找
|
||||
root.left = self.buildTree(inorder[:p],postorder[:p]) //分割中序数组和后续数组
|
||||
root.right = self.buildTree(inorder[p+1:],postorder[p:-1]) //注意右节点时分割中序数组和后续数组的开闭环
|
||||
return root
|
||||
```
|
||||
Go:
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 构造二叉搜索树,一不小心就平衡了
|
||||
|
|
@ -233,7 +233,27 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
#递归法
|
||||
class Solution:
|
||||
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
|
||||
def buildaTree(left,right):
|
||||
if left > right: return None #左闭右闭的区间,当区间 left > right的时候,就是空节点,当left = right的时候,不为空
|
||||
mid = left + (right - left) // 2 #保证数据不会越界
|
||||
val = nums[mid]
|
||||
root = TreeNode(val)
|
||||
root.left = buildaTree(left,mid - 1)
|
||||
root.right = buildaTree(mid + 1,right)
|
||||
return root
|
||||
root = buildaTree(0,len(nums) - 1) #左闭右闭区间
|
||||
return root
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 求高度还是求深度,你搞懂了不?
|
||||
|
|
@ -142,7 +142,7 @@ int getDepth(TreeNode* node)
|
|||
|
||||
2. 明确终止条件
|
||||
|
||||
递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的书高度为0
|
||||
递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的树高度为0
|
||||
|
||||
代码如下:
|
||||
|
||||
|
|
@ -498,6 +498,62 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
> 递归法:
|
||||
```python
|
||||
class Solution:
|
||||
def isBalanced(self, root: TreeNode) -> bool:
|
||||
return True if self.getDepth(root) != -1 else False
|
||||
|
||||
#返回以该节点为根节点的二叉树的高度,如果不是二叉搜索树了则返回-1
|
||||
def getDepth(self, node):
|
||||
if not node:
|
||||
return 0
|
||||
leftDepth = self.getDepth(node.left)
|
||||
if leftDepth == -1: return -1 #说明左子树已经不是二叉平衡树
|
||||
rightDepth = self.getDepth(node.right)
|
||||
if rightDepth == -1: return -1 #说明右子树已经不是二叉平衡树
|
||||
return -1 if abs(leftDepth - rightDepth)>1 else 1 + max(leftDepth, rightDepth)
|
||||
```
|
||||
|
||||
> 迭代法:
|
||||
```python
|
||||
class Solution:
|
||||
def isBalanced(self, root: TreeNode) -> bool:
|
||||
st = []
|
||||
if not root:
|
||||
return True
|
||||
st.append(root)
|
||||
while st:
|
||||
node = st.pop() #中
|
||||
if abs(self.getDepth(node.left) - self.getDepth(node.right)) > 1:
|
||||
return False
|
||||
if node.right:
|
||||
st.append(node.right) #右(空节点不入栈)
|
||||
if node.left:
|
||||
st.append(node.left) #左(空节点不入栈)
|
||||
return True
|
||||
|
||||
def getDepth(self, cur):
|
||||
st = []
|
||||
if cur:
|
||||
st.append(cur)
|
||||
depth = 0
|
||||
result = 0
|
||||
while st:
|
||||
node = st.pop()
|
||||
if node:
|
||||
st.append(node) #中
|
||||
st.append(None)
|
||||
depth += 1
|
||||
if node.right: st.append(node.right) #右
|
||||
if node.left: st.append(node.left) #左
|
||||
else:
|
||||
node = st.pop()
|
||||
depth -= 1
|
||||
result = max(result, depth)
|
||||
return result
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
|
|
@ -534,7 +590,34 @@ func abs(a int)int{
|
|||
return a
|
||||
}
|
||||
```
|
||||
|
||||
JavaScript:
|
||||
```javascript
|
||||
var isBalanced = function(root) {
|
||||
//还是用递归三部曲 + 后序遍历 左右中 当前左子树右子树高度相差大于1就返回-1
|
||||
// 1. 确定递归函数参数以及返回值
|
||||
const getDepth=function(node){
|
||||
// 2. 确定递归函数终止条件
|
||||
if(node===null){
|
||||
return 0;
|
||||
}
|
||||
// 3. 确定单层递归逻辑
|
||||
let leftDepth=getDepth(node.left);//左子树高度
|
||||
if(leftDepth===-1){
|
||||
return -1;
|
||||
}
|
||||
let rightDepth=getDepth(node.right);//右子树高度
|
||||
if(rightDepth===-1){
|
||||
return -1;
|
||||
}
|
||||
if(Math.abs(leftDepth-rightDepth)>1){
|
||||
return -1;
|
||||
}else{
|
||||
return 1+Math.max(leftDepth,rightDepth);
|
||||
}
|
||||
}
|
||||
return getDepth(root)===-1?false:true;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 和求最大深度一个套路?
|
||||
|
|
@ -301,6 +301,111 @@ class Solution:
|
|||
|
||||
Go:
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
// 递归
|
||||
func minDepth(root *TreeNode) int {
|
||||
if root == nil {
|
||||
return 0;
|
||||
}
|
||||
if root.Left == nil && root.Right != nil {
|
||||
return 1 + minDepth(root.Right);
|
||||
}
|
||||
if root.Right == nil && root.Left != nil {
|
||||
return 1 + minDepth(root.Left);
|
||||
}
|
||||
return min(minDepth(root.Left), minDepth(root.Right)) + 1;
|
||||
}
|
||||
|
||||
// 迭代
|
||||
|
||||
func minDepth(root *TreeNode) int {
|
||||
dep := 0;
|
||||
queue := make([]*TreeNode, 0);
|
||||
if root != nil {
|
||||
queue = append(queue, root);
|
||||
}
|
||||
for l := len(queue); l > 0; {
|
||||
dep++;
|
||||
for ; l > 0; l-- {
|
||||
node := queue[0];
|
||||
if node.Left == nil && node.Right == nil {
|
||||
return dep;
|
||||
}
|
||||
if node.Left != nil {
|
||||
queue = append(queue, node.Left);
|
||||
}
|
||||
if node.Right != nil {
|
||||
queue = append(queue, node.Right);
|
||||
}
|
||||
queue = queue[1:];
|
||||
}
|
||||
l = len(queue);
|
||||
}
|
||||
return dep;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
JavaScript:
|
||||
|
||||
递归法:
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* @param {TreeNode} root
|
||||
* @return {number}
|
||||
*/
|
||||
var minDepth1 = function(root) {
|
||||
if(!root) return 0;
|
||||
// 到叶子节点 返回 1
|
||||
if(!root.left && !root.right) return 1;
|
||||
// 只有右节点时 递归右节点
|
||||
if(!root.left) return 1 + minDepth(root.right);、
|
||||
// 只有左节点时 递归左节点
|
||||
if(!root.right) return 1 + minDepth(root.left);
|
||||
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
|
||||
};
|
||||
```
|
||||
|
||||
迭代法:
|
||||
|
||||
```javascript
|
||||
/**
|
||||
* @param {TreeNode} root
|
||||
* @return {number}
|
||||
*/
|
||||
var minDepth = function(root) {
|
||||
if(!root) return 0;
|
||||
const queue = [root];
|
||||
let dep = 0;
|
||||
while(true) {
|
||||
let size = queue.length;
|
||||
dep++;
|
||||
while(size--){
|
||||
const node = queue.shift();
|
||||
// 到第一个叶子节点 返回 当前深度
|
||||
if(!node.left && !node.right) return dep;
|
||||
node.left && queue.push(node.left);
|
||||
node.right && queue.push(node.right);
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 递归函数什么时候需要返回值
|
||||
|
|
@ -332,13 +332,246 @@ class Solution {
|
|||
}
|
||||
}
|
||||
|
||||
// LC112 简洁方法
|
||||
class Solution {
|
||||
public boolean hasPathSum(TreeNode root, int targetSum) {
|
||||
|
||||
if (root == null) return false; // 为空退出
|
||||
|
||||
// 叶子节点判断是否符合
|
||||
if (root.left == null && root.right == null) return root.val == targetSum;
|
||||
|
||||
// 求两侧分支的路径和
|
||||
return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
|
||||
}
|
||||
}
|
||||
```
|
||||
迭代
|
||||
```java
|
||||
class Solution {
|
||||
public boolean hasPathSum(TreeNode root, int targetSum) {
|
||||
if(root==null)return false;
|
||||
Stack<TreeNode> stack1 = new Stack<>();
|
||||
Stack<Integer> stack2 = new Stack<>();
|
||||
stack1.push(root);stack2.push(root.val);
|
||||
while(!stack1.isEmpty()){
|
||||
int size = stack1.size();
|
||||
for(int i=0;i<size;i++){
|
||||
TreeNode node = stack1.pop();int sum=stack2.pop();
|
||||
// 如果该节点是叶子节点了,同时该节点的路径数值等于sum,那么就返回true
|
||||
if(node.left==null && node.right==null && sum==targetSum)return true;
|
||||
// 右节点,压进去一个节点的时候,将该节点的路径数值也记录下来
|
||||
if(node.right!=null){
|
||||
stack1.push(node.right);stack2.push(sum+node.right.val);
|
||||
}
|
||||
// 左节点,压进去一个节点的时候,将该节点的路径数值也记录下来
|
||||
if(node.left!=null){
|
||||
stack1.push(node.left);stack2.push(sum+node.left.val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
0113.路径总和-ii
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
|
||||
List<List<Integer>> res = new ArrayList<>();
|
||||
if (root == null) return res; // 非空判断
|
||||
|
||||
List<Integer> path = new LinkedList<>();
|
||||
preorderDFS(root, targetSum, res, path);
|
||||
return res;
|
||||
}
|
||||
|
||||
public void preorderDFS(TreeNode root, int targetSum, List<List<Integer>> res, List<Integer> path) {
|
||||
path.add(root.val);
|
||||
// 遇到了叶子节点
|
||||
if (root.left == null && root.right == null) {
|
||||
// 找到了和为 targetSum 的路径
|
||||
if (targetSum - root.val == 0) {
|
||||
res.add(new ArrayList<>(path));
|
||||
}
|
||||
return; // 如果和不为 targetSum,返回
|
||||
}
|
||||
|
||||
if (root.left != null) {
|
||||
preorderDFS(root.left, targetSum - root.val, res, path);
|
||||
path.remove(path.size() - 1); // 回溯
|
||||
}
|
||||
if (root.right != null) {
|
||||
preorderDFS(root.right, targetSum - root.val, res, path);
|
||||
path.remove(path.size() - 1); // 回溯
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
0112.路径总和
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
|
||||
// 递归法
|
||||
|
||||
class Solution:
|
||||
def hasPathSum(self, root: TreeNode, targetSum: int) -> bool:
|
||||
def isornot(root,targetSum)->bool:
|
||||
if (not root.left) and (not root.right) and targetSum == 0:return True // 遇到叶子节点,并且计数为0
|
||||
if (not root.left) and (not root.right):return False //遇到叶子节点,计数不为0
|
||||
if root.left:
|
||||
targetSum -= root.left.val //左节点
|
||||
if isornot(root.left,targetSum):return True //递归,处理左节点
|
||||
targetSum += root.left.val //回溯
|
||||
if root.right:
|
||||
targetSum -= root.right.val //右节点
|
||||
if isornot(root.right,targetSum):return True //递归,处理右节点
|
||||
targetSum += root.right.val //回溯
|
||||
return False
|
||||
|
||||
if root == None:return False //别忘记处理空TreeNode
|
||||
else:return isornot(root,targetSum-root.val)
|
||||
```
|
||||
|
||||
0113.路径总和-ii
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
//递归法
|
||||
class Solution:
|
||||
def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
|
||||
path=[]
|
||||
res=[]
|
||||
def pathes(root,targetSum):
|
||||
if (not root.left) and (not root.right) and targetSum == 0: // 遇到叶子节点,并且计数为0
|
||||
res.append(path[:]) //找到一种路径,记录到res中,注意必须是path[:]而不是path
|
||||
return
|
||||
if (not root.left) and (not root.right):return // 遇到叶子节点直接返回
|
||||
if root.left: //左
|
||||
targetSum -= root.left.val
|
||||
path.append(root.left.val) //递归前记录节点
|
||||
pathes(root.left,targetSum) //递归
|
||||
targetSum += root.left.val //回溯
|
||||
path.pop() //回溯
|
||||
if root.right: //右
|
||||
targetSum -= root.right.val
|
||||
path.append(root.right.val) //递归前记录节点
|
||||
pathes(root.right,targetSum) //递归
|
||||
targetSum += root.right.val //回溯
|
||||
path.pop() //回溯
|
||||
return
|
||||
|
||||
if root == None:return [] //处理空TreeNode
|
||||
else:
|
||||
path.append(root.val) //首先处理根节点
|
||||
pathes(root,targetSum-root.val)
|
||||
return res
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
> 112. 路径总和
|
||||
|
||||
```go
|
||||
//递归法
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
func hasPathSum(root *TreeNode, targetSum int) bool {
|
||||
var flage bool //找没找到的标志
|
||||
if root==nil{
|
||||
return flage
|
||||
}
|
||||
pathSum(root,0,targetSum,&flage)
|
||||
return flage
|
||||
}
|
||||
func pathSum(root *TreeNode, sum int,targetSum int,flage *bool){
|
||||
sum+=root.Val
|
||||
if root.Left==nil&&root.Right==nil&&sum==targetSum{
|
||||
*flage=true
|
||||
return
|
||||
}
|
||||
if root.Left!=nil&&!(*flage){//左节点不为空且还没找到
|
||||
pathSum(root.Left,sum,targetSum,flage)
|
||||
}
|
||||
if root.Right!=nil&&!(*flage){//右节点不为空且没找到
|
||||
pathSum(root.Right,sum,targetSum,flage)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
> 113 递归法
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
func pathSum(root *TreeNode, targetSum int) [][]int {
|
||||
var result [][]int//最终结果
|
||||
if root==nil{
|
||||
return result
|
||||
}
|
||||
var sumNodes []int//经过路径的节点集合
|
||||
hasPathSum(root,&sumNodes,targetSum,&result)
|
||||
return result
|
||||
}
|
||||
func hasPathSum(root *TreeNode,sumNodes *[]int,targetSum int,result *[][]int){
|
||||
*sumNodes=append(*sumNodes,root.Val)
|
||||
if root.Left==nil&&root.Right==nil{//叶子节点
|
||||
fmt.Println(*sumNodes)
|
||||
var sum int
|
||||
var number int
|
||||
for k,v:=range *sumNodes{//求该路径节点的和
|
||||
sum+=v
|
||||
number=k
|
||||
}
|
||||
tempNodes:=make([]int,number+1)//新的nodes接受指针里的值,防止最终指针里的值发生变动,导致最后的结果都是最后一个sumNodes的值
|
||||
for k,v:=range *sumNodes{
|
||||
tempNodes[k]=v
|
||||
}
|
||||
if sum==targetSum{
|
||||
*result=append(*result,tempNodes)
|
||||
}
|
||||
}
|
||||
if root.Left!=nil{
|
||||
hasPathSum(root.Left,sumNodes,targetSum,result)
|
||||
*sumNodes=(*sumNodes)[:len(*sumNodes)-1]//回溯
|
||||
}
|
||||
if root.Right!=nil{
|
||||
hasPathSum(root.Right,sumNodes,targetSum,result)
|
||||
*sumNodes=(*sumNodes)[:len(*sumNodes)-1]//回溯
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
JavaScript:
|
||||
|
||||
0112.路径总和
|
||||
|
|
@ -407,6 +640,62 @@ let pathSum = function (root, targetSum) {
|
|||
};
|
||||
```
|
||||
|
||||
0112 路径总和
|
||||
```javascript
|
||||
var hasPathSum = function(root, targetSum) {
|
||||
//递归方法
|
||||
// 1. 确定函数参数
|
||||
const traversal = function(node,count){
|
||||
// 2. 确定终止条件
|
||||
if(node.left===null&&node.right===null&&count===0){
|
||||
return true;
|
||||
}
|
||||
if(node.left===null&&node.right===null){
|
||||
return false;
|
||||
}
|
||||
//3. 单层递归逻辑
|
||||
if(node.left){
|
||||
if(traversal(node.left,count-node.left.val)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(node.right){
|
||||
if(traversal(node.right,count-node.right.val)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(root===null){
|
||||
return false;
|
||||
}
|
||||
return traversal(root,targetSum-root.val);
|
||||
};
|
||||
```
|
||||
113 路径总和
|
||||
```javascript
|
||||
var pathSum = function(root, targetSum) {
|
||||
//递归方法
|
||||
let resPath = [],curPath = [];
|
||||
// 1. 确定递归函数参数
|
||||
const travelTree = function(node,count){
|
||||
curPath.push(node.val);
|
||||
count-=node.val;
|
||||
if(node.left===null&&node.right===null&&count===0){
|
||||
resPath.push([...curPath]);
|
||||
}
|
||||
node.left&&travelTree(node.left,count);
|
||||
node.right&&travelTree(node.right,count);
|
||||
let cur = curPath.pop();
|
||||
count-=cur;
|
||||
}
|
||||
if(root===null){
|
||||
return resPath;
|
||||
}
|
||||
travelTree(root,targetSum);
|
||||
return resPath;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 115.不同的子序列
|
||||
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
题目数据保证答案符合 32 位带符号整数范围。
|
||||
|
||||

|
||||

|
||||
|
||||
提示:
|
||||
|
||||
|
|
@ -148,7 +148,22 @@ Java:
|
|||
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def numDistinct(self, s: str, t: str) -> int:
|
||||
dp = [[0] * (len(t)+1) for _ in range(len(s)+1)]
|
||||
for i in range(len(s)):
|
||||
dp[i][0] = 1
|
||||
for j in range(1, len(t)):
|
||||
dp[0][j] = 0
|
||||
for i in range(1, len(s)+1):
|
||||
for j in range(1, len(t)+1):
|
||||
if s[i-1] == t[j-1]:
|
||||
dp[i][j] = dp[i-1][j-1] + dp[i-1][j]
|
||||
else:
|
||||
dp[i][j] = dp[i-1][j]
|
||||
return dp[-1][-1]
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 121. 买卖股票的最佳时机
|
||||
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
这道题目最直观的想法,就是暴力,找最优间距了。
|
||||
|
||||
```
|
||||
```C++
|
||||
class Solution {
|
||||
public:
|
||||
int maxProfit(vector<int>& prices) {
|
||||
|
|
@ -196,14 +196,122 @@ public:
|
|||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
```java
|
||||
// 贪心思路
|
||||
class Solution {
|
||||
public int maxProfit(int[] prices) {
|
||||
int minprice = Integer.MAX_VALUE;
|
||||
int maxprofit = 0;
|
||||
for (int i = 0; i < prices.length; i++) {
|
||||
if (prices[i] < minprice) {
|
||||
minprice = prices[i];
|
||||
} else if (prices[i] - minprice > maxprofit) {
|
||||
maxprofit = prices[i] - minprice;
|
||||
}
|
||||
}
|
||||
return maxprofit;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
``` java
|
||||
class Solution { // 动态规划解法
|
||||
public int maxProfit(int[] prices) {
|
||||
// 可交易次数
|
||||
int k = 1;
|
||||
// [天数][交易次数][是否持有股票]
|
||||
int[][][] dp = new int[prices.length][k + 1][2];
|
||||
|
||||
// bad case
|
||||
dp[0][0][0] = 0;
|
||||
dp[0][0][1] = Integer.MIN_VALUE;
|
||||
dp[0][1][0] = Integer.MIN_VALUE;
|
||||
dp[0][1][1] = -prices[0];
|
||||
|
||||
for (int i = 1; i < prices.length; i++) {
|
||||
for (int j = k; j >= 1; j--) {
|
||||
// dp公式
|
||||
dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
|
||||
dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return dp[prices.length - 1][k][0] > 0 ? dp[prices.length - 1][k][0] : 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
> 贪心法:
|
||||
```python
|
||||
class Solution:
|
||||
def maxProfit(self, prices: List[int]) -> int:
|
||||
low = float("inf")
|
||||
result = 0
|
||||
for i in range(len(prices)):
|
||||
low = min(low, prices[i]) #取最左最小价格
|
||||
result = max(result, prices[i] - low) #直接取最大区间利润
|
||||
return result
|
||||
```
|
||||
|
||||
> 动态规划:版本一
|
||||
```python
|
||||
class Solution:
|
||||
def maxProfit(self, prices: List[int]) -> int:
|
||||
length = len(prices)
|
||||
if len == 0:
|
||||
return 0
|
||||
dp = [[0] * 2 for _ in range(length)]
|
||||
dp[0][0] = -prices[0]
|
||||
dp[0][1] = 0
|
||||
for i in range(1, length):
|
||||
dp[i][0] = max(dp[i-1][0], -prices[i])
|
||||
dp[i][1] = max(dp[i-1][1], prices[i] + dp[i-1][0])
|
||||
return dp[-1][1]
|
||||
```
|
||||
|
||||
> 动态规划:版本二
|
||||
```python
|
||||
class Solution:
|
||||
def maxProfit(self, prices: List[int]) -> int:
|
||||
length = len(prices)
|
||||
dp = [[0] * 2 for _ in range(2)] #注意这里只开辟了一个2 * 2大小的二维数组
|
||||
dp[0][0] = -prices[0]
|
||||
dp[0][1] = 0
|
||||
for i in range(1, length):
|
||||
dp[i % 2][0] = max(dp[(i-1) % 2][0], -prices[i])
|
||||
dp[i % 2][1] = max(dp[(i-1) % 2][1], prices[i] + dp[(i-1) % 2][0])
|
||||
return dp[(length-1) % 2][1]
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func maxProfit(prices []int) int {
|
||||
length:=len(prices)
|
||||
if length==0{return 0}
|
||||
dp:=make([][]int,length)
|
||||
for i:=0;i<length;i++{
|
||||
dp[i]=make([]int,2)
|
||||
}
|
||||
|
||||
dp[0][0]=-prices[0]
|
||||
dp[0][1]=0
|
||||
for i:=1;i<length;i++{
|
||||
dp[i][0]=max(dp[i-1][0],-prices[i])
|
||||
dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i])
|
||||
}
|
||||
return dp[length-1][1]
|
||||
}
|
||||
|
||||
func max(a,b int)int {
|
||||
if a>b{
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 122.买卖股票的最佳时机II
|
||||
|
|
@ -133,9 +133,10 @@ public:
|
|||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
// 贪心思路
|
||||
class Solution {
|
||||
public int maxProfit(int[] prices) {
|
||||
int sum = 0;
|
||||
|
|
@ -153,6 +154,29 @@ class Solution {
|
|||
}
|
||||
```
|
||||
|
||||
```java
|
||||
class Solution { // 动态规划
|
||||
public int maxProfit(int[] prices) {
|
||||
// [天数][是否持有股票]
|
||||
int[][] dp = new int[prices.length][2];
|
||||
|
||||
// bad case
|
||||
dp[0][0] = 0;
|
||||
dp[0][1] = -prices[0];
|
||||
|
||||
for (int i = 1; i < prices.length; i++) {
|
||||
// dp公式
|
||||
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
|
||||
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
|
||||
}
|
||||
|
||||
return dp[prices.length - 1][0];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
Python:
|
||||
```python
|
||||
class Solution:
|
||||
|
|
@ -166,7 +190,17 @@ class Solution:
|
|||
Go:
|
||||
|
||||
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
// 贪心
|
||||
var maxProfit = function(prices) {
|
||||
let result = 0
|
||||
for(let i = 1; i < prices.length; i++) {
|
||||
result += Math.max(prices[i] - prices[i - 1], 0)
|
||||
}
|
||||
return result
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 122.买卖股票的最佳时机II
|
||||
|
||||
|
|
@ -133,10 +133,71 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
```java
|
||||
// 动态规划
|
||||
class Solution
|
||||
// 实现1:二维数组存储
|
||||
// 可以将每天持有与否的情况分别用 dp[i][0] 和 dp[i][1] 来进行存储
|
||||
// 时间复杂度:O(n),空间复杂度O(n)
|
||||
public int maxProfit(int[] prices) {
|
||||
int n = prices.length;
|
||||
int[][] dp = new int[n][2]; // 创建二维数组存储状态
|
||||
dp[0][0] = 0; // 初始状态
|
||||
dp[0][1] = -prices[0];
|
||||
for (int i = 1; i < n; ++i) {
|
||||
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]); // 第 i 天,没有股票
|
||||
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]); // 第 i 天,持有股票
|
||||
}
|
||||
return dp[n - 1][0]; // 卖出股票收益高于持有股票收益,因此取[0]
|
||||
}
|
||||
|
||||
// 实现2:变量存储
|
||||
// 第一种方法需要用二维数组存储,有空间开销,其实关心的仅仅是前一天的状态,不关注更多的历史信息
|
||||
// 因此,可以仅保存前一天的信息存入 dp0、dp1 这 2 个变量即可
|
||||
// 时间复杂度:O(n),空间复杂度O(1)
|
||||
public int maxProfit(int[] prices) {
|
||||
int n = prices.length;
|
||||
int dp0 = 0, dp1 = -prices[0]; // 定义变量,存储初始状态
|
||||
for (int i = 1; i < n; ++i) {
|
||||
int newDp0 = Math.max(dp0, dp1 + prices[i]); // 第 i 天,没有股票
|
||||
int newDp1 = Math.max(dp1, dp0 - prices[i]); // 第 i 天,持有股票
|
||||
dp0 = newDp0;
|
||||
dp1 = newDp1;
|
||||
}
|
||||
return dp0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
> 版本一:
|
||||
```python
|
||||
class Solution:
|
||||
def maxProfit(self, prices: List[int]) -> int:
|
||||
length = len(prices)
|
||||
dp = [[0] * 2 for _ in range(length)]
|
||||
dp[0][0] = -prices[0]
|
||||
dp[0][1] = 0
|
||||
for i in range(1, length):
|
||||
dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i]) #注意这里是和121. 买卖股票的最佳时机唯一不同的地方
|
||||
dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i])
|
||||
return dp[-1][1]
|
||||
```
|
||||
|
||||
> 版本二:
|
||||
```python
|
||||
class Solution:
|
||||
def maxProfit(self, prices: List[int]) -> int:
|
||||
length = len(prices)
|
||||
dp = [[0] * 2 for _ in range(2)] #注意这里只开辟了一个2 * 2大小的二维数组
|
||||
dp[0][0] = -prices[0]
|
||||
dp[0][1] = 0
|
||||
for i in range(1, length):
|
||||
dp[i % 2][0] = max(dp[(i-1) % 2][0], dp[(i-1) % 2][1] - prices[i])
|
||||
dp[i % 2][1] = max(dp[(i-1) % 2][1], dp[(i-1) % 2][0] + prices[i])
|
||||
return dp[(length-1) % 2][1]
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 123.买卖股票的最佳时机III
|
||||
|
||||
|
|
@ -101,9 +101,9 @@ dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);
|
|||
|
||||
所以dp[0][2] = 0;
|
||||
|
||||
第0天第二次买入操作,初始值应该是多少呢?
|
||||
第0天第二次买入操作,初始值应该是多少呢?应该不少同学疑惑,第一次还没买入呢,怎么初始化第二次买入呢?
|
||||
|
||||
不用管第几次,现在手头上没有现金,只要买入,现金就做相应的减少。
|
||||
第二次买入依赖于第一次卖出的状态,其实相当于第0天第一次买入了,第一次卖出了,然后在买入一次(第二次买入),那么现在手头上没有现金,只要买入,现金就做相应的减少。
|
||||
|
||||
所以第二次买入操作,初始化为:dp[0][3] = -prices[0];
|
||||
|
||||
|
|
@ -190,12 +190,79 @@ dp[1] = max(dp[1], dp[0] - prices[i]); 如果dp[1]取dp[1],即保持买入股
|
|||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution { // 动态规划
|
||||
public int maxProfit(int[] prices) {
|
||||
// 可交易次数
|
||||
int k = 2;
|
||||
|
||||
// [天数][交易次数][是否持有股票]
|
||||
int[][][] dp = new int[prices.length][k + 1][2];
|
||||
|
||||
// badcase
|
||||
dp[0][0][0] = 0;
|
||||
dp[0][0][1] = Integer.MIN_VALUE;
|
||||
dp[0][1][0] = 0;
|
||||
dp[0][1][1] = -prices[0];
|
||||
dp[0][2][0] = 0;
|
||||
dp[0][2][1] = Integer.MIN_VALUE;
|
||||
|
||||
for (int i = 1; i < prices.length; i++) {
|
||||
for (int j = 2; j >= 1; j--) {
|
||||
// dp公式
|
||||
dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
|
||||
dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int res = 0;
|
||||
for (int i = 1; i < 3; i++) {
|
||||
res = Math.max(res, dp[prices.length - 1][i][0]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
> 版本一:
|
||||
```python
|
||||
class Solution:
|
||||
def maxProfit(self, prices: List[int]) -> int:
|
||||
if len(prices) == 0:
|
||||
return 0
|
||||
dp = [[0] * 5 for _ in range(len(prices))]
|
||||
dp[0][1] = -prices[0]
|
||||
dp[0][3] = -prices[0]
|
||||
for i in range(1, len(prices)):
|
||||
dp[i][0] = dp[i-1][0]
|
||||
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])
|
||||
dp[i][2] = max(dp[i-1][2], dp[i-1][1] + prices[i])
|
||||
dp[i][3] = max(dp[i-1][3], dp[i-1][2] - prices[i])
|
||||
dp[i][4] = max(dp[i-1][4], dp[i-1][3] + prices[i])
|
||||
return dp[-1][4]
|
||||
```
|
||||
|
||||
> 版本二:
|
||||
```python
|
||||
class Solution:
|
||||
def maxProfit(self, prices: List[int]) -> int:
|
||||
if len(prices) == 0:
|
||||
return 0
|
||||
dp = [0] * 5
|
||||
dp[1] = -prices[0]
|
||||
dp[3] = -prices[0]
|
||||
for i in range(1, len(prices)):
|
||||
dp[1] = max(dp[1], dp[0] - prices[i])
|
||||
dp[2] = max(dp[2], dp[1] + prices[i])
|
||||
dp[3] = max(dp[3], dp[2] - prices[i])
|
||||
dp[4] = max(dp[4], dp[3] + prices[i])
|
||||
return dp[4]
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 切割问题其实是一种组合问题!
|
||||
|
|
@ -292,11 +292,59 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
```py
|
||||
class Solution:
|
||||
def partition(self, s: str) -> List[List[str]]:
|
||||
res = []
|
||||
path = [] #放已经回文的子串
|
||||
def backtrack(s,startIndex):
|
||||
if startIndex >= len(s): #如果起始位置已经大于s的大小,说明已经找到了一组分割方案了
|
||||
return res.append(path[:])
|
||||
for i in range(startIndex,len(s)):
|
||||
p = s[startIndex:i+1] #获取[startIndex,i+1]在s中的子串
|
||||
if p == p[::-1]: path.append(p) #是回文子串
|
||||
else: continue #不是回文,跳过
|
||||
backtrack(s,i+1) #寻找i+1为起始位置的子串
|
||||
path.pop() #回溯过程,弹出本次已经填在path的子串
|
||||
backtrack(s,0)
|
||||
return res
|
||||
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {string} s
|
||||
* @return {string[][]}
|
||||
*/
|
||||
const isPalindrome = (s, l, r) => {
|
||||
for (let i = l, j = r; i < j; i++, j--) {
|
||||
if(s[i] !== s[j]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
var partition = function(s) {
|
||||
const res = [], path = [], len = s.length;
|
||||
backtracking(0);
|
||||
return res;
|
||||
function backtracking(i) {
|
||||
if(i >= len) {
|
||||
res.push(Array.from(path));
|
||||
return;
|
||||
}
|
||||
for(let j = i; j < len; j++) {
|
||||
if(!isPalindrome(s, i, j)) continue;
|
||||
path.push(s.substr(i, j - i + 1));
|
||||
backtracking(j + 1);
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 134. 加油站
|
||||
|
|
@ -223,11 +223,46 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
|
||||
start = 0
|
||||
curSum = 0
|
||||
totalSum = 0
|
||||
for i in range(len(gas)):
|
||||
curSum += gas[i] - cost[i]
|
||||
totalSum += gas[i] - cost[i]
|
||||
if curSum < 0:
|
||||
curSum = 0
|
||||
start = i + 1
|
||||
if totalSum < 0: return -1
|
||||
return start
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
var canCompleteCircuit = function(gas, cost) {
|
||||
const gasLen = gas.length
|
||||
let start = 0
|
||||
let curSum = 0
|
||||
let totalSum = 0
|
||||
|
||||
for(let i = 0; i < gasLen; i++) {
|
||||
curSum += gas[i] - cost[i]
|
||||
totalSum += gas[i] - cost[i]
|
||||
if(curSum < 0) {
|
||||
curSum = 0
|
||||
start = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
if(totalSum < 0) return -1
|
||||
|
||||
return start
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 135. 分发糖果
|
||||
|
|
@ -161,11 +161,45 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def candy(self, ratings: List[int]) -> int:
|
||||
candyVec = [1] * len(ratings)
|
||||
for i in range(1, len(ratings)):
|
||||
if ratings[i] > ratings[i - 1]:
|
||||
candyVec[i] = candyVec[i - 1] + 1
|
||||
for j in range(len(ratings) - 2, -1, -1):
|
||||
if ratings[j] > ratings[j + 1]:
|
||||
candyVec[j] = max(candyVec[j], candyVec[j + 1] + 1)
|
||||
return sum(candyVec)
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
var candy = function(ratings) {
|
||||
let candys = new Array(ratings.length).fill(1)
|
||||
|
||||
for(let i = 1; i < ratings.length; i++) {
|
||||
if(ratings[i] > ratings[i - 1]) {
|
||||
candys[i] = candys[i - 1] + 1
|
||||
}
|
||||
}
|
||||
|
||||
for(let i = ratings.length - 2; i >= 0; i--) {
|
||||
if(ratings[i] > ratings[i + 1]) {
|
||||
candys[i] = Math.max(candys[i], candys[i + 1] + 1)
|
||||
}
|
||||
}
|
||||
|
||||
let count = candys.reduce((a, b) => {
|
||||
return a + b
|
||||
})
|
||||
|
||||
return count
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 动态规划:单词拆分
|
||||
|
||||
## 139.单词拆分
|
||||
|
|
@ -252,9 +252,44 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
|
||||
'''排列'''
|
||||
dp = [False]*(len(s) + 1)
|
||||
dp[0] = True
|
||||
# 遍历背包
|
||||
for j in range(1, len(s) + 1):
|
||||
# 遍历单词
|
||||
for word in wordDict:
|
||||
if j >= len(word):
|
||||
dp[j] = dp[j] or (dp[j - len(word)] and word == s[j - len(word):j])
|
||||
return dp[len(s)]
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
```Go
|
||||
func wordBreak(s string,wordDict []string) bool {
|
||||
wordDictSet:=make(map[string]bool)
|
||||
for _,w:=range wordDict{
|
||||
wordDictSet[w]=true
|
||||
}
|
||||
dp:=make([]bool,len(s)+1)
|
||||
dp[0]=true
|
||||
for i:=1;i<=len(s);i++{
|
||||
for j:=0;j<i;j++{
|
||||
if dp[j]&& wordDictSet[s[j:i]]{
|
||||
dp[i]=true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[len(s)]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -234,6 +234,67 @@ class Solution:
|
|||
```
|
||||
|
||||
Go:
|
||||
```go
|
||||
func detectCycle(head *ListNode) *ListNode {
|
||||
slow, fast := head, head
|
||||
for fast != nil && fast.Next != nil {
|
||||
slow = slow.Next
|
||||
fast = fast.Next.Next
|
||||
if slow == fast {
|
||||
for slow != head {
|
||||
slow = slow.Next
|
||||
head = head.Next
|
||||
}
|
||||
return head
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
javaScript
|
||||
|
||||
```js
|
||||
// 两种循环实现方式
|
||||
/**
|
||||
* @param {ListNode} head
|
||||
* @return {ListNode}
|
||||
*/
|
||||
// 先判断是否是环形链表
|
||||
var detectCycle = function(head) {
|
||||
if(!head || !head.next) return null;
|
||||
let slow =head.next, fast = head.next.next;
|
||||
while(fast && fast.next && fast!== slow) {
|
||||
slow = slow.next;
|
||||
fast = fast.next.next;
|
||||
}
|
||||
if(!fast || !fast.next ) return null;
|
||||
slow = head;
|
||||
while (fast !== slow) {
|
||||
slow = slow.next;
|
||||
fast = fast.next;
|
||||
}
|
||||
return slow;
|
||||
};
|
||||
|
||||
var detectCycle = function(head) {
|
||||
if(!head || !head.next) return null;
|
||||
let slow =head.next, fast = head.next.next;
|
||||
while(fast && fast.next) {
|
||||
slow = slow.next;
|
||||
fast = fast.next.next;
|
||||
if(fast == slow) {
|
||||
slow = head;
|
||||
while (fast !== slow) {
|
||||
slow = slow.next;
|
||||
fast = fast.next;
|
||||
}
|
||||
return slow;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -170,8 +170,75 @@ public class EvalRPN {
|
|||
|
||||
}
|
||||
```
|
||||
Go:
|
||||
```Go
|
||||
func evalRPN(tokens []string) int {
|
||||
stack := []int{}
|
||||
for _, token := range tokens {
|
||||
val, err := strconv.Atoi(token)
|
||||
if err == nil {
|
||||
stack = append(stack, val)
|
||||
} else {
|
||||
num1, num2 := stack[len(stack)-2], stack[(len(stack))-1]
|
||||
stack = stack[:len(stack)-2]
|
||||
switch token {
|
||||
case "+":
|
||||
stack = append(stack, num1+num2)
|
||||
case "-":
|
||||
stack = append(stack, num1-num2)
|
||||
case "*":
|
||||
stack = append(stack, num1*num2)
|
||||
case "/":
|
||||
stack = append(stack, num1/num2)
|
||||
}
|
||||
}
|
||||
}
|
||||
return stack[0]
|
||||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
|
||||
/**
|
||||
* @param {string[]} tokens
|
||||
* @return {number}
|
||||
*/
|
||||
var evalRPN = function(tokens) {
|
||||
const s = new Map([
|
||||
["+", (a, b) => a * 1 + b * 1],
|
||||
["-", (a, b) => b - a],
|
||||
["*", (a, b) => b * a],
|
||||
["/", (a, b) => (b / a) | 0]
|
||||
]);
|
||||
const stack = [];
|
||||
for (const i of tokens) {
|
||||
if(!s.has(i)) {
|
||||
stack.push(i);
|
||||
continue;
|
||||
}
|
||||
stack.push(s.get(i)(stack.pop(),stack.pop()))
|
||||
}
|
||||
return stack.pop();
|
||||
};
|
||||
```
|
||||
|
||||
python3
|
||||
|
||||
```python
|
||||
def evalRPN(tokens) -> int:
|
||||
stack = list()
|
||||
for i in range(len(tokens)):
|
||||
if tokens[i] not in ["+", "-", "*", "/"]:
|
||||
stack.append(tokens[i])
|
||||
else:
|
||||
tmp1 = stack.pop()
|
||||
tmp2 = stack.pop()
|
||||
res = eval(tmp2+tokens[i]+tmp1)
|
||||
stack.append(str(int(res)))
|
||||
return stack[-1]
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ public:
|
|||
int end = 0; // 反转的单词在字符串里终止位置
|
||||
bool entry = false; // 标记枚举字符串的过程中是否已经进入了单词区间
|
||||
for (int i = 0; i < s.size(); i++) { // 开始反转单词
|
||||
if ((!entry) || (s[i] != ' ' && s[i - 1] == ' ')) {
|
||||
if (!entry) {
|
||||
start = i; // 确定单词起始位置
|
||||
entry = true; // 进入单词区间
|
||||
}
|
||||
|
|
@ -318,9 +318,61 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func reverseWords(s string) string {
|
||||
//1.使用双指针删除冗余的空格
|
||||
slowIndex, fastIndex := 0, 0
|
||||
b := []byte(s)
|
||||
//删除头部冗余空格
|
||||
for len(b) > 0 && fastIndex < len(b) && b[fastIndex] == ' ' {
|
||||
fastIndex++
|
||||
}
|
||||
//删除单词间冗余空格
|
||||
for ; fastIndex < len(b); fastIndex++ {
|
||||
if fastIndex-1 > 0 && b[fastIndex-1] == b[fastIndex] && b[fastIndex] == ' ' {
|
||||
continue
|
||||
}
|
||||
b[slowIndex] = b[fastIndex]
|
||||
slowIndex++
|
||||
}
|
||||
//删除尾部冗余空格
|
||||
if slowIndex-1 > 0 && b[slowIndex-1] == ' ' {
|
||||
b = b[:slowIndex-1]
|
||||
} else {
|
||||
b = b[:slowIndex]
|
||||
}
|
||||
//2.反转整个字符串
|
||||
reverse(&b, 0, len(b)-1)
|
||||
//3.反转单个单词 i单词开始位置,j单词结束位置
|
||||
i := 0
|
||||
for i < len(b) {
|
||||
j := i
|
||||
for ; j < len(b) && b[j] != ' '; j++ {
|
||||
}
|
||||
reverse(&b, i, j-1)
|
||||
i = j
|
||||
i++
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func reverse(b *[]byte, left, right int) {
|
||||
for left < right {
|
||||
(*b)[left], (*b)[right] = (*b)[right], (*b)[left]
|
||||
left++
|
||||
right--
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 188.买卖股票的最佳时机IV
|
||||
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
输入:k = 2, prices = [3,2,6,5,0,3]
|
||||
输出:7
|
||||
解释:在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4。随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。
|
||||
|
||||
|
||||
|
||||
提示:
|
||||
|
||||
|
|
@ -167,12 +167,65 @@ public:
|
|||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution { //动态规划
|
||||
public int maxProfit(int k, int[] prices) {
|
||||
if (prices == null || prices.length < 2 || k == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// [天数][交易次数][是否持有股票]
|
||||
int[][][] dp = new int[prices.length][k + 1][2];
|
||||
|
||||
// bad case
|
||||
dp[0][0][0] = 0;
|
||||
dp[0][0][1] = Integer.MIN_VALUE;
|
||||
dp[0][1][0] = 0;
|
||||
dp[0][1][1] = -prices[0];
|
||||
// dp[0][j][0] 都均为0
|
||||
// dp[0][j][1] 异常值都取Integer.MIN_VALUE;
|
||||
for (int i = 2; i < k + 1; i++) {
|
||||
dp[0][i][0] = 0;
|
||||
dp[0][i][1] = Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
for (int i = 1; i < prices.length; i++) {
|
||||
for (int j = k; j >= 1; j--) {
|
||||
// dp公式
|
||||
dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]);
|
||||
dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int res = 0;
|
||||
for (int i = 1; i < k + 1; i++) {
|
||||
res = Math.max(res, dp[prices.length - 1][i][0]);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def maxProfit(self, k: int, prices: List[int]) -> int:
|
||||
if len(prices) == 0:
|
||||
return 0
|
||||
dp = [[0] * (2*k+1) for _ in range(len(prices))]
|
||||
for j in range(1, 2*k, 2):
|
||||
dp[0][j] = -prices[0]
|
||||
for i in range(1, len(prices)):
|
||||
for j in range(0, 2*k-1, 2):
|
||||
dp[i][j+1] = max(dp[i-1][j+1], dp[i-1][j] - prices[i])
|
||||
dp[i][j+2] = max(dp[i-1][j+2], dp[i-1][j+1] + prices[i])
|
||||
return dp[-1][2*k]
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 198.打家劫舍
|
||||
|
||||
|
|
@ -111,10 +111,40 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
// 动态规划
|
||||
class Solution {
|
||||
public int rob(int[] nums) {
|
||||
if (nums == null || nums.length == 0) return 0;
|
||||
if (nums.length == 1) return nums[0];
|
||||
|
||||
int[] dp = new int[nums.length];
|
||||
dp[0] = nums[0];
|
||||
dp[1] = Math.max(dp[0], nums[1]);
|
||||
for (int i = 2; i < nums.length; i++) {
|
||||
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
|
||||
}
|
||||
|
||||
return dp[nums.length - 1];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def rob(self, nums: List[int]) -> int:
|
||||
if len(nums) == 0:
|
||||
return 0
|
||||
if len(nums) == 1:
|
||||
return nums[0]
|
||||
dp = [0] * len(nums)
|
||||
dp[0] = nums[0]
|
||||
dp[1] = max(nums[0], nums[1])
|
||||
for i in range(2, len(nums)):
|
||||
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
|
||||
return dp[-1]
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ https://leetcode-cn.com/problems/happy-number/
|
|||
|
||||
题目中说了会 **无限循环**,那么也就是说**求和的过程中,sum会重复出现,这对解题很重要!**
|
||||
|
||||
正如:[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA)中所说,**当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。**
|
||||
正如:[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg)中所说,**当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。**
|
||||
|
||||
所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ public:
|
|||
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
# 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
|
@ -108,10 +108,84 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
```python
|
||||
class Solution:
|
||||
def isHappy(self, n: int) -> bool:
|
||||
set_ = set()
|
||||
while 1:
|
||||
sum_ = self.getSum(n)
|
||||
if sum_ == 1:
|
||||
return True
|
||||
#如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
|
||||
if sum_ in set_:
|
||||
return False
|
||||
else:
|
||||
set_.add(sum_)
|
||||
n = sum_
|
||||
|
||||
#取数值各个位上的单数之和
|
||||
def getSum(self, n):
|
||||
sum_ = 0
|
||||
while n > 0:
|
||||
sum_ += (n%10) * (n%10)
|
||||
n //= 10
|
||||
return sum_
|
||||
```
|
||||
|
||||
Go:
|
||||
```go
|
||||
func isHappy(n int) bool {
|
||||
m := make(map[int]bool)
|
||||
for n != 1 && !m[n] {
|
||||
n, m[n] = getSum(n), true
|
||||
}
|
||||
return n == 1
|
||||
}
|
||||
|
||||
func getSum(n int) int {
|
||||
sum := 0
|
||||
for n > 0 {
|
||||
sum += (n % 10) * (n % 10)
|
||||
n = n / 10
|
||||
}
|
||||
return sum
|
||||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
function getN(n) {
|
||||
if (n == 1 || n == 0) return n;
|
||||
let res = 0;
|
||||
while (n) {
|
||||
res += (n % 10) * (n % 10);
|
||||
n = parseInt(n / 10);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
var isHappy = function(n) {
|
||||
const sumSet = new Set();
|
||||
while (n != 1 && !sumSet.has(n)) {
|
||||
sumSet.add(n);
|
||||
n = getN(n);
|
||||
}
|
||||
return n == 1;
|
||||
};
|
||||
|
||||
// 使用环形链表的思想 说明出现闭环 退出循环
|
||||
var isHappy = function(n) {
|
||||
if (getN(n) == 1) return true;
|
||||
let a = getN(n), b = getN(getN(n));
|
||||
// 如果 a === b
|
||||
while (b !== 1 && getN(b) !== 1 && a !== b) {
|
||||
a = getN(a);
|
||||
b = getN(getN(b));
|
||||
}
|
||||
return b === 1 || getN(b) === 1 ;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 链表操作中,可以使用原链表来直接进行删除操作,也可以设置一个虚拟头结点在进行删除操作,接下来看一看哪种方式更方便。
|
||||
|
|
@ -15,7 +15,18 @@ https://leetcode-cn.com/problems/remove-linked-list-elements/
|
|||
|
||||
题意:删除链表中等于给定值 val 的所有节点。
|
||||
|
||||

|
||||
示例 1:
|
||||
输入:head = [1,2,6,3,4,5,6], val = 6
|
||||
输出:[1,2,3,4,5]
|
||||
|
||||
示例 2:
|
||||
输入:head = [], val = 1
|
||||
输出:[]
|
||||
|
||||
示例 3:
|
||||
输入:head = [7,7,7,7], val = 7
|
||||
输出:[]
|
||||
|
||||
|
||||
# 思路
|
||||
|
||||
|
|
@ -197,10 +208,71 @@ public ListNode removeElements(ListNode head, int val) {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
# Definition for singly-linked list.
|
||||
# class ListNode:
|
||||
# def __init__(self, val=0, next=None):
|
||||
# self.val = val
|
||||
# self.next = next
|
||||
class Solution:
|
||||
def removeElements(self, head: ListNode, val: int) -> ListNode:
|
||||
dummy_head = ListNode(next=head) #添加一个虚拟节点
|
||||
cur = dummy_head
|
||||
while(cur.next!=None):
|
||||
if(cur.next.val == val):
|
||||
cur.next = cur.next.next #删除cur.next节点
|
||||
else:
|
||||
cur = cur.next
|
||||
return dummy_head.next
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for singly-linked list.
|
||||
* type ListNode struct {
|
||||
* Val int
|
||||
* Next *ListNode
|
||||
* }
|
||||
*/
|
||||
func removeElements(head *ListNode, val int) *ListNode {
|
||||
dummyHead := &ListNode{}
|
||||
dummyHead.Next = head
|
||||
cur := dummyHead
|
||||
for cur != nil && cur.Next != nil {
|
||||
if cur.Next.Val == val {
|
||||
cur.Next = cur.Next.Next
|
||||
} else {
|
||||
cur = cur.Next
|
||||
}
|
||||
}
|
||||
return dummyHead.Next
|
||||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {ListNode} head
|
||||
* @param {number} val
|
||||
* @return {ListNode}
|
||||
*/
|
||||
var removeElements = function(head, val) {
|
||||
const ret = new ListNode(0, head);
|
||||
let cur = ret;
|
||||
while(cur.next) {
|
||||
if(cur.next.val === val) {
|
||||
cur.next = cur.next.next;
|
||||
continue;
|
||||
}
|
||||
cur = cur.next;
|
||||
}
|
||||
return ret.next;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 反转链表的写法很简单,一些同学甚至可以背下来但过一阵就忘了该咋写,主要是因为没有理解真正的反转过程。
|
||||
|
|
@ -143,10 +143,112 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
#双指针
|
||||
# Definition for singly-linked list.
|
||||
# class ListNode:
|
||||
# def __init__(self, val=0, next=None):
|
||||
# self.val = val
|
||||
# self.next = next
|
||||
class Solution:
|
||||
def reverseList(self, head: ListNode) -> ListNode:
|
||||
cur = head
|
||||
pre = None
|
||||
while(cur!=None):
|
||||
temp = cur.next # 保存一下 cur的下一个节点,因为接下来要改变cur->next
|
||||
cur.next = pre #反转
|
||||
#更新pre、cur指针
|
||||
pre = cur
|
||||
cur = temp
|
||||
return pre
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
//双指针
|
||||
func reverseList(head *ListNode) *ListNode {
|
||||
var pre *ListNode
|
||||
cur := head
|
||||
for cur != nil {
|
||||
next := cur.Next
|
||||
cur.Next = pre
|
||||
pre = cur
|
||||
cur = next
|
||||
}
|
||||
return pre
|
||||
}
|
||||
|
||||
//递归
|
||||
func reverseList(head *ListNode) *ListNode {
|
||||
return help(nil, head)
|
||||
}
|
||||
|
||||
func help(pre, head *ListNode)*ListNode{
|
||||
if head == nil {
|
||||
return pre
|
||||
}
|
||||
next := head.Next
|
||||
head.Next = pre
|
||||
return help(head, next)
|
||||
}
|
||||
|
||||
```
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {ListNode} head
|
||||
* @return {ListNode}
|
||||
*/
|
||||
|
||||
// 双指针:
|
||||
var reverseList = function(head) {
|
||||
if(!head || !head.next) return head;
|
||||
let temp = null, pre = null, cur = head;
|
||||
while(cur) {
|
||||
temp = cur.next;
|
||||
cur.next = pre;
|
||||
pre = cur;
|
||||
cur = temp;
|
||||
}
|
||||
// temp = cur = null;
|
||||
return pre;
|
||||
};
|
||||
|
||||
// 递归:
|
||||
var reverse = function(pre, head) {
|
||||
if(!head) return pre;
|
||||
const temp = head.next;
|
||||
head.next = pre;
|
||||
pre = head
|
||||
return reverse(pre, temp);
|
||||
}
|
||||
|
||||
var reverseList = function(head) {
|
||||
return reverse(null, head);
|
||||
};
|
||||
|
||||
// 递归2
|
||||
var reverse = function(head) {
|
||||
if(!head || !head.next) return head;
|
||||
// 从后往前翻
|
||||
const pre = reverse(head.next);
|
||||
head.next = pre.next;
|
||||
pre.next = head;
|
||||
return head;
|
||||
}
|
||||
|
||||
var reverseList = function(head) {
|
||||
let cur = head;
|
||||
while(cur && cur.next) {
|
||||
cur = cur.next;
|
||||
}
|
||||
reverse(head);
|
||||
return cur;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 209.长度最小的子数组
|
||||
|
|
@ -116,26 +116,6 @@ public:
|
|||
|
||||
不要以为for里放一个while就以为是$O(n^2)$啊, 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被被操作两次,所以时间复杂度是2 * n 也就是$O(n)$。
|
||||
|
||||
## 其他语言补充
|
||||
|
||||
python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
|
||||
# 定义一个无限大的数
|
||||
res = float("inf")
|
||||
Sum = 0
|
||||
index = 0
|
||||
for i in range(len(nums)):
|
||||
Sum += nums[i]
|
||||
while Sum >= s:
|
||||
res = min(res, i-index+1)
|
||||
Sum -= nums[index]
|
||||
index += 1
|
||||
return 0 if res==float("inf") else res
|
||||
```
|
||||
|
||||
## 相关题目推荐
|
||||
|
||||
* 904.水果成篮
|
||||
|
|
@ -170,24 +150,69 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
|
||||
# 定义一个无限大的数
|
||||
res = float("inf")
|
||||
Sum = 0
|
||||
index = 0
|
||||
for i in range(len(nums)):
|
||||
Sum += nums[i]
|
||||
while Sum >= s:
|
||||
res = min(res, i-index+1)
|
||||
Sum -= nums[index]
|
||||
index += 1
|
||||
return 0 if res==float("inf") else res
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
```go
|
||||
func minSubArrayLen(target int, nums []int) int {
|
||||
i := 0
|
||||
l := len(nums) // 数组长度
|
||||
sum := 0 // 子数组之和
|
||||
result := l + 1 // 初始化返回长度为l+1,目的是为了判断“不存在符合条件的子数组,返回0”的情况
|
||||
for j := 0; j < l; j++ {
|
||||
sum += nums[j]
|
||||
for sum >= target {
|
||||
subLength := j - i + 1
|
||||
if subLength < result {
|
||||
result = subLength
|
||||
}
|
||||
sum -= nums[i]
|
||||
i++
|
||||
}
|
||||
}
|
||||
if result == l+1 {
|
||||
return 0
|
||||
} else {
|
||||
return result
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
JavaScript:
|
||||
```
|
||||
var minSubArrayLen = (target, nums) => {
|
||||
let left = 0, right = 0,win = Infinity,sum = 0;
|
||||
while(right < nums.length){
|
||||
sum += nums[right];
|
||||
while(sum >= target){
|
||||
win = right - left + 1 < win? right - left + 1 : win;
|
||||
sum -= nums[left];
|
||||
left++;
|
||||
|
||||
```js
|
||||
|
||||
var minSubArrayLen = function(target, nums) {
|
||||
// 长度计算一次
|
||||
const len = nums.length;
|
||||
let l = r = sum = 0,
|
||||
res = len + 1; // 子数组最大不会超过自身
|
||||
while(r < len) {
|
||||
sum += nums[r++];
|
||||
// 窗口滑动
|
||||
while(sum >= target) {
|
||||
// r始终为开区间 [l, r)
|
||||
res = res < r - l ? res : r - l;
|
||||
sum-=nums[l++];
|
||||
}
|
||||
right++;
|
||||
}
|
||||
return win === Infinity? 0:win;
|
||||
return res > len ? 0 : res;
|
||||
};
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 213.打家劫舍II
|
||||
|
||||
|
|
@ -98,11 +98,73 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
public int rob(int[] nums) {
|
||||
if (nums == null || nums.length == 0)
|
||||
return 0;
|
||||
int len = nums.length;
|
||||
if (len == 1)
|
||||
return nums[0];
|
||||
return Math.max(robAction(nums, 0, len - 1), robAction(nums, 1, len));
|
||||
}
|
||||
|
||||
int robAction(int[] nums, int start, int end) {
|
||||
int x = 0, y = 0, z = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
y = z;
|
||||
z = Math.max(y, x + nums[i]);
|
||||
x = y;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
```Python
|
||||
class Solution:
|
||||
def rob(self, nums: List[int]) -> int:
|
||||
if (n := len(nums)) == 0:
|
||||
return 0
|
||||
if n == 1:
|
||||
return nums[0]
|
||||
result1 = self.robRange(nums, 0, n - 2)
|
||||
result2 = self.robRange(nums, 1, n - 1)
|
||||
return max(result1 , result2)
|
||||
|
||||
def robRange(self, nums: List[int], start: int, end: int) -> int:
|
||||
if end == start: return nums[start]
|
||||
dp = [0] * len(nums)
|
||||
dp[start] = nums[start]
|
||||
dp[start + 1] = max(nums[start], nums[start + 1])
|
||||
for i in range(start + 2, end + 1):
|
||||
dp[i] = max(dp[i -2] + nums[i], dp[i - 1])
|
||||
return dp[end]
|
||||
```
|
||||
|
||||
javascipt:
|
||||
```javascript
|
||||
var rob = function(nums) {
|
||||
const n = nums.length
|
||||
if (n === 0) return 0
|
||||
if (n === 1) return nums[0]
|
||||
const result1 = robRange(nums, 0, n - 2)
|
||||
const result2 = robRange(nums, 1, n - 1)
|
||||
return Math.max(result1, result2)
|
||||
};
|
||||
|
||||
const robRange = (nums, start, end) => {
|
||||
if (end === start) return nums[start]
|
||||
const dp = Array(nums.length).fill(0)
|
||||
dp[start] = nums[start]
|
||||
dp[start + 1] = Math.max(nums[start], nums[start + 1])
|
||||
for (let i = start + 2; i <= end; i++) {
|
||||
dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1])
|
||||
}
|
||||
return dp[end]
|
||||
}
|
||||
```
|
||||
Go:
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ void backtracking(int targetSum, int k, int sum, int startIndex)
|
|||
|
||||
所以 终止代码如下:
|
||||
|
||||
```
|
||||
```C++
|
||||
if (path.size() == k) {
|
||||
if (sum == targetSum) result.push_back(path);
|
||||
return; // 如果path.size() == k 但sum != targetSum 直接返回
|
||||
|
|
@ -112,7 +112,7 @@ if (path.size() == k) {
|
|||
|
||||
代码如下:
|
||||
|
||||
```
|
||||
```C++
|
||||
for (int i = startIndex; i <= 9; i++) {
|
||||
sum += i;
|
||||
path.push_back(i);
|
||||
|
|
@ -126,7 +126,7 @@ for (int i = startIndex; i <= 9; i++) {
|
|||
|
||||
参照[关于回溯算法,你该了解这些!](https://mp.weixin.qq.com/s/gjSgJbNbd1eAA5WkA-HeWw)中的模板,不难写出如下C++代码:
|
||||
|
||||
```
|
||||
```C++
|
||||
class Solution {
|
||||
private:
|
||||
vector<vector<int>> result; // 存放结果集
|
||||
|
|
@ -180,7 +180,7 @@ if (sum > targetSum) { // 剪枝操作
|
|||
|
||||
最后C++代码如下:
|
||||
|
||||
```
|
||||
```c++
|
||||
class Solution {
|
||||
private:
|
||||
vector<vector<int>> result; // 存放结果集
|
||||
|
|
@ -262,10 +262,66 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
```py
|
||||
class Solution:
|
||||
def combinationSum3(self, k: int, n: int) -> List[List[int]]:
|
||||
res = [] #存放结果集
|
||||
path = [] #符合条件的结果
|
||||
def findallPath(n,k,sum,startIndex):
|
||||
if sum > n: return #剪枝操作
|
||||
if sum == n and len(path) == k: #如果path.size() == k 但sum != n 直接返回
|
||||
return res.append(path[:])
|
||||
for i in range(startIndex,9-(k-len(path))+2): #剪枝操作
|
||||
path.append(i)
|
||||
sum += i
|
||||
findallPath(n,k,sum,i+1) #注意i+1调整startIndex
|
||||
sum -= i #回溯
|
||||
path.pop() #回溯
|
||||
|
||||
findallPath(n,k,0,1)
|
||||
return res
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
// 等差数列
|
||||
var maxV = k => k * (9 + 10 - k) / 2;
|
||||
var minV = k => k * (1 + k) / 2;
|
||||
var combinationSum3 = function(k, n) {
|
||||
if (k > 9 || k < 1) return [];
|
||||
// if (n > maxV(k) || n < minV(k)) return [];
|
||||
// if (n === maxV(k)) return [Array.from({length: k}).map((v, i) => 9 - i)];
|
||||
// if (n === minV(k)) return [Array.from({length: k}).map((v, i) => i + 1)];
|
||||
|
||||
const res = [], path = [];
|
||||
backtracking(k, n, 1, 0);
|
||||
return res;
|
||||
function backtracking(k, n, i, sum){
|
||||
const len = path.length;
|
||||
if (len > k || sum > n) return;
|
||||
if (maxV(k - len) < n - sum) return;
|
||||
if (minV(k - len) > n - sum) return;
|
||||
|
||||
if(len === k && sum == n) {
|
||||
res.push(Array.from(path));
|
||||
return;
|
||||
}
|
||||
|
||||
const min = Math.min(n - sum, 9 + len - k + 1);
|
||||
|
||||
for(let a = i; a <= min; a++) {
|
||||
path.push(a);
|
||||
sum += a;
|
||||
backtracking(k, n, a + 1, sum);
|
||||
path.pop();
|
||||
sum -= a;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 222.完全二叉树的节点个数
|
||||
|
|
@ -240,9 +240,171 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
> 递归法:
|
||||
```python
|
||||
class Solution:
|
||||
def countNodes(self, root: TreeNode) -> int:
|
||||
return self.getNodesNum(root)
|
||||
|
||||
def getNodesNum(self, cur):
|
||||
if not cur:
|
||||
return 0
|
||||
leftNum = self.getNodesNum(cur.left) #左
|
||||
rightNum = self.getNodesNum(cur.right) #右
|
||||
treeNum = leftNum + rightNum + 1 #中
|
||||
return treeNum
|
||||
```
|
||||
|
||||
> 递归法:精简版
|
||||
```python
|
||||
class Solution:
|
||||
def countNodes(self, root: TreeNode) -> int:
|
||||
if not root:
|
||||
return 0
|
||||
return 1 + self.countNodes(root.left) + self.countNodes(root.right)
|
||||
```
|
||||
|
||||
> 迭代法:
|
||||
```python
|
||||
import collections
|
||||
class Solution:
|
||||
def countNodes(self, root: TreeNode) -> int:
|
||||
queue = collections.deque()
|
||||
if root:
|
||||
queue.append(root)
|
||||
result = 0
|
||||
while queue:
|
||||
size = len(queue)
|
||||
for i in range(size):
|
||||
node = queue.popleft()
|
||||
result += 1 #记录节点数量
|
||||
if node.left:
|
||||
queue.append(node.left)
|
||||
if node.right:
|
||||
queue.append(node.right)
|
||||
return result
|
||||
```
|
||||
|
||||
> 完全二叉树
|
||||
```python
|
||||
class Solution:
|
||||
def countNodes(self, root: TreeNode) -> int:
|
||||
if not root:
|
||||
return 0
|
||||
left = root.left
|
||||
right = root.right
|
||||
leftHeight = 0 #这里初始为0是有目的的,为了下面求指数方便
|
||||
rightHeight = 0
|
||||
while left: #求左子树深度
|
||||
left = left.left
|
||||
leftHeight += 1
|
||||
while right: #求右子树深度
|
||||
right = right.right
|
||||
rightHeight += 1
|
||||
if leftHeight == rightHeight:
|
||||
return (2 << leftHeight) - 1 #注意(2<<1) 相当于2^2,所以leftHeight初始为0
|
||||
return self.countNodes(root.left) + self.countNodes(root.right) + 1
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
递归版本
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
//本题直接就是求有多少个节点,无脑存进数组算长度就行了。
|
||||
func countNodes(root *TreeNode) int {
|
||||
if root == nil {
|
||||
return 0
|
||||
}
|
||||
res := 1
|
||||
if root.Right != nil {
|
||||
res += countNodes(root.Right)
|
||||
}
|
||||
if root.Left != nil {
|
||||
res += countNodes(root.Left)
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
JavaScript:
|
||||
|
||||
递归版本
|
||||
```javascript
|
||||
var countNodes = function(root) {
|
||||
//递归法计算二叉树节点数
|
||||
// 1. 确定递归函数参数
|
||||
const getNodeSum=function(node){
|
||||
//2. 确定终止条件
|
||||
if(node===null){
|
||||
return 0;
|
||||
}
|
||||
//3. 确定单层递归逻辑
|
||||
let leftNum=getNodeSum(node.left);
|
||||
let rightNum=getNodeSum(node.right);
|
||||
return leftNum+rightNum+1;
|
||||
}
|
||||
return getNodeSum(root);
|
||||
};
|
||||
```
|
||||
|
||||
迭代(层序遍历)版本
|
||||
```javascript
|
||||
var countNodes = function(root) {
|
||||
//层序遍历
|
||||
let queue=[];
|
||||
if(root===null){
|
||||
return 0;
|
||||
}
|
||||
queue.push(root);
|
||||
let nodeNums=0;
|
||||
while(queue.length){
|
||||
let length=queue.length;
|
||||
while(length--){
|
||||
let node=queue.shift();
|
||||
nodeNums++;
|
||||
node.left&&queue.push(node.left);
|
||||
node.right&&queue.push(node.right);
|
||||
}
|
||||
}
|
||||
return nodeNums;
|
||||
};
|
||||
```
|
||||
|
||||
利用完全二叉树性质
|
||||
```javascript
|
||||
var countNodes = function(root) {
|
||||
//利用完全二叉树的特点
|
||||
if(root===null){
|
||||
return 0;
|
||||
}
|
||||
let left=root.left;
|
||||
let right=root.right;
|
||||
let leftHeight=0,rightHeight=0;
|
||||
while(left){
|
||||
left=left.left;
|
||||
leftHeight++;
|
||||
}
|
||||
while(right){
|
||||
right=right.right;
|
||||
rightHeight++;
|
||||
}
|
||||
if(leftHeight==rightHeight){
|
||||
return Math.pow(2,leftHeight+1)-1;
|
||||
}
|
||||
return countNodes(root.left)+countNodes(root.right)+1;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -156,6 +156,7 @@ public:
|
|||
|
||||
Java:
|
||||
|
||||
使用两个 Queue 实现
|
||||
```java
|
||||
class MyStack {
|
||||
|
||||
|
|
@ -205,7 +206,94 @@ class MyStack {
|
|||
* boolean param_4 = obj.empty();
|
||||
*/
|
||||
```
|
||||
使用两个 Deque 实现
|
||||
```java
|
||||
class MyStack {
|
||||
// Deque 接口继承了 Queue 接口
|
||||
// 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
|
||||
Deque<Integer> que1; // 和栈中保持一样元素的队列
|
||||
Deque<Integer> que2; // 辅助队列
|
||||
/** Initialize your data structure here. */
|
||||
public MyStack() {
|
||||
que1 = new ArrayDeque<>();
|
||||
que2 = new ArrayDeque<>();
|
||||
}
|
||||
|
||||
/** Push element x onto stack. */
|
||||
public void push(int x) {
|
||||
que1.addLast(x);
|
||||
}
|
||||
|
||||
/** Removes the element on top of the stack and returns that element. */
|
||||
public int pop() {
|
||||
int size = que1.size();
|
||||
size--;
|
||||
// 将 que1 导入 que2 ,但留下最后一个值
|
||||
while (size-- > 0) {
|
||||
que2.addLast(que1.peekFirst());
|
||||
que1.pollFirst();
|
||||
}
|
||||
|
||||
int res = que1.pollFirst();
|
||||
// 将 que2 对象的引用赋给了 que1 ,此时 que1,que2 指向同一个队列
|
||||
que1 = que2;
|
||||
// 如果直接操作 que2,que1 也会受到影响,所以为 que2 分配一个新的空间
|
||||
que2 = new ArrayDeque<>();
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Get the top element. */
|
||||
public int top() {
|
||||
return que1.peekLast();
|
||||
}
|
||||
|
||||
/** Returns whether the stack is empty. */
|
||||
public boolean empty() {
|
||||
return que1.isEmpty();
|
||||
}
|
||||
}
|
||||
```
|
||||
优化,使用一个 Deque 实现
|
||||
```java
|
||||
class MyStack {
|
||||
// Deque 接口继承了 Queue 接口
|
||||
// 所以 Queue 中的 add、poll、peek等效于 Deque 中的 addLast、pollFirst、peekFirst
|
||||
Deque<Integer> que1;
|
||||
/** Initialize your data structure here. */
|
||||
public MyStack() {
|
||||
que1 = new ArrayDeque<>();
|
||||
}
|
||||
|
||||
/** Push element x onto stack. */
|
||||
public void push(int x) {
|
||||
que1.addLast(x);
|
||||
}
|
||||
|
||||
/** Removes the element on top of the stack and returns that element. */
|
||||
public int pop() {
|
||||
int size = que1.size();
|
||||
size--;
|
||||
// 将 que1 导入 que2 ,但留下最后一个值
|
||||
while (size-- > 0) {
|
||||
que1.addLast(que1.peekFirst());
|
||||
que1.pollFirst();
|
||||
}
|
||||
|
||||
int res = que1.pollFirst();
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Get the top element. */
|
||||
public int top() {
|
||||
return que1.peekLast();
|
||||
}
|
||||
|
||||
/** Returns whether the stack is empty. */
|
||||
public boolean empty() {
|
||||
return que1.isEmpty();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
|
@ -269,8 +357,115 @@ class MyStack:
|
|||
|
||||
Go:
|
||||
|
||||
javaScript:
|
||||
|
||||
使用数组(push, shift)模拟队列
|
||||
|
||||
```js
|
||||
|
||||
// 使用两个队列实现
|
||||
/**
|
||||
* Initialize your data structure here.
|
||||
*/
|
||||
var MyStack = function() {
|
||||
this.queue1 = [];
|
||||
this.queue2 = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Push element x onto stack.
|
||||
* @param {number} x
|
||||
* @return {void}
|
||||
*/
|
||||
MyStack.prototype.push = function(x) {
|
||||
this.queue1.push(x);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the element on top of the stack and returns that element.
|
||||
* @return {number}
|
||||
*/
|
||||
MyStack.prototype.pop = function() {
|
||||
// 减少两个队列交换的次数, 只有当queue1为空时,交换两个队列
|
||||
if(!this.queue1.length) {
|
||||
[this.queue1, this.queue2] = [this.queue2, this.queue1];
|
||||
}
|
||||
while(this.queue1.length > 1) {
|
||||
this.queue2.push(this.queue1.shift());
|
||||
}
|
||||
return this.queue1.shift();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the top element.
|
||||
* @return {number}
|
||||
*/
|
||||
MyStack.prototype.top = function() {
|
||||
const x = this.pop();
|
||||
this.queue1.push(x);
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the stack is empty.
|
||||
* @return {boolean}
|
||||
*/
|
||||
MyStack.prototype.empty = function() {
|
||||
return !this.queue1.length && !this.queue2.length;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
```js
|
||||
|
||||
// 使用一个队列实现
|
||||
/**
|
||||
* Initialize your data structure here.
|
||||
*/
|
||||
var MyStack = function() {
|
||||
this.queue = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Push element x onto stack.
|
||||
* @param {number} x
|
||||
* @return {void}
|
||||
*/
|
||||
MyStack.prototype.push = function(x) {
|
||||
this.queue.push(x);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the element on top of the stack and returns that element.
|
||||
* @return {number}
|
||||
*/
|
||||
MyStack.prototype.pop = function() {
|
||||
let size = this.queue.length;
|
||||
while(size-- > 1) {
|
||||
this.queue.push(this.queue.shift());
|
||||
}
|
||||
return this.queue.shift();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the top element.
|
||||
* @return {number}
|
||||
*/
|
||||
MyStack.prototype.top = function() {
|
||||
const x = this.pop();
|
||||
this.queue.push(x);
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the stack is empty.
|
||||
* @return {boolean}
|
||||
*/
|
||||
MyStack.prototype.empty = function() {
|
||||
return !this.queue.length;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 226.翻转二叉树
|
||||
|
|
@ -230,6 +230,56 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
> 递归法:前序遍历
|
||||
```python
|
||||
class Solution:
|
||||
def invertTree(self, root: TreeNode) -> TreeNode:
|
||||
if not root:
|
||||
return None
|
||||
root.left, root.right = root.right, root.left #中
|
||||
self.invertTree(root.left) #左
|
||||
self.invertTree(root.right) #右
|
||||
return root
|
||||
```
|
||||
|
||||
> 迭代法:深度优先遍历(前序遍历)
|
||||
```python
|
||||
class Solution:
|
||||
def invertTree(self, root: TreeNode) -> TreeNode:
|
||||
if not root:
|
||||
return root
|
||||
st = []
|
||||
st.append(root)
|
||||
while st:
|
||||
node = st.pop()
|
||||
node.left, node.right = node.right, node.left #中
|
||||
if node.right:
|
||||
st.append(node.right) #右
|
||||
if node.left:
|
||||
st.append(node.left) #左
|
||||
return root
|
||||
```
|
||||
|
||||
> 迭代法:广度优先遍历(层序遍历)
|
||||
```python
|
||||
import collections
|
||||
class Solution:
|
||||
def invertTree(self, root: TreeNode) -> TreeNode:
|
||||
queue = collections.deque() #使用deque()
|
||||
if root:
|
||||
queue.append(root)
|
||||
while queue:
|
||||
size = len(queue)
|
||||
for i in range(size):
|
||||
node = queue.popleft()
|
||||
node.left, node.right = node.right, node.left #节点处理
|
||||
if node.left:
|
||||
queue.append(node.left)
|
||||
if node.right:
|
||||
queue.append(node.right)
|
||||
return root
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func invertTree(root *TreeNode) *TreeNode {
|
||||
|
|
@ -247,7 +297,97 @@ func invertTree(root *TreeNode) *TreeNode {
|
|||
}
|
||||
```
|
||||
|
||||
JavaScript:
|
||||
|
||||
使用递归版本的前序遍历
|
||||
```javascript
|
||||
var invertTree = function(root) {
|
||||
//1. 首先使用递归版本的前序遍历实现二叉树翻转
|
||||
//交换节点函数
|
||||
const inverNode=function(left,right){
|
||||
let temp=left;
|
||||
left=right;
|
||||
right=temp;
|
||||
//需要重新给root赋值一下
|
||||
root.left=left;
|
||||
root.right=right;
|
||||
}
|
||||
//确定递归函数的参数和返回值inverTree=function(root)
|
||||
//确定终止条件
|
||||
if(root===null){
|
||||
return root;
|
||||
}
|
||||
//确定节点处理逻辑 交换
|
||||
inverNode(root.left,root.right);
|
||||
invertTree(root.left);
|
||||
invertTree(root.right);
|
||||
return root;
|
||||
};
|
||||
```
|
||||
使用迭代版本(统一模板))的前序遍历:
|
||||
```javascript
|
||||
var invertTree = function(root) {
|
||||
//我们先定义节点交换函数
|
||||
const invertNode=function(root,left,right){
|
||||
let temp=left;
|
||||
left=right;
|
||||
right=temp;
|
||||
root.left=left;
|
||||
root.right=right;
|
||||
}
|
||||
//使用迭代方法的前序遍历
|
||||
let stack=[];
|
||||
if(root===null){
|
||||
return root;
|
||||
}
|
||||
stack.push(root);
|
||||
while(stack.length){
|
||||
let node=stack.pop();
|
||||
if(node!==null){
|
||||
//前序遍历顺序中左右 入栈顺序是前序遍历的倒序右左中
|
||||
node.right&&stack.push(node.right);
|
||||
node.left&&stack.push(node.left);
|
||||
stack.push(node);
|
||||
stack.push(null);
|
||||
}else{
|
||||
node=stack.pop();
|
||||
//节点处理逻辑
|
||||
invertNode(node,node.left,node.right);
|
||||
}
|
||||
}
|
||||
return root;
|
||||
};
|
||||
```
|
||||
使用层序遍历:
|
||||
```javascript
|
||||
var invertTree = function(root) {
|
||||
//我们先定义节点交换函数
|
||||
const invertNode=function(root,left,right){
|
||||
let temp=left;
|
||||
left=right;
|
||||
right=temp;
|
||||
root.left=left;
|
||||
root.right=right;
|
||||
}
|
||||
//使用层序遍历
|
||||
let queue=[];
|
||||
if(root===null){
|
||||
return root;
|
||||
}
|
||||
queue.push(root);
|
||||
while(queue.length){
|
||||
let length=queue.length;
|
||||
while(length--){
|
||||
let node=queue.shift();
|
||||
//节点处理逻辑
|
||||
invertNode(node,node.left,node.right);
|
||||
node.left&&queue.push(node.left);
|
||||
node.right&&queue.push(node.right);
|
||||
}
|
||||
}
|
||||
return root;
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 工作上一定没人这么搞,但是考察对栈、队列理解程度的好题
|
||||
|
|
@ -131,6 +131,101 @@ public:
|
|||
|
||||
Java:
|
||||
|
||||
使用Stack(堆栈)同名方法:
|
||||
```java
|
||||
class MyQueue {
|
||||
// java中的 Stack 有设计上的缺陷,官方推荐使用 Deque(双端队列) 代替 Stack
|
||||
Deque<Integer> stIn;
|
||||
Deque<Integer> stOut;
|
||||
/** Initialize your data structure here. */
|
||||
public MyQueue() {
|
||||
stIn = new ArrayDeque<>();
|
||||
stOut = new ArrayDeque<>();
|
||||
}
|
||||
|
||||
/** Push element x to the back of queue. */
|
||||
public void push(int x) {
|
||||
stIn.push(x);
|
||||
}
|
||||
|
||||
/** Removes the element from in front of queue and returns that element. */
|
||||
public int pop() {
|
||||
// 只要 stOut 为空,那么就应该将 stIn 中所有的元素倒腾到 stOut 中
|
||||
if (stOut.isEmpty()) {
|
||||
while (!stIn.isEmpty()) {
|
||||
stOut.push(stIn.pop());
|
||||
}
|
||||
}
|
||||
// 再返回 stOut 中的元素
|
||||
return stOut.pop();
|
||||
}
|
||||
|
||||
/** Get the front element. */
|
||||
public int peek() {
|
||||
// 直接使用已有的pop函数
|
||||
int res = this.pop();
|
||||
// 因为pop函数弹出了元素res,所以再添加回去
|
||||
stOut.push(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Returns whether the queue is empty. */
|
||||
public boolean empty() {
|
||||
// 当 stIn 栈为空时,说明没有元素可以倒腾到 stOut 栈了
|
||||
// 并且 stOut 栈也为空时,说明没有以前从 stIn 中倒腾到的元素了
|
||||
return stIn.isEmpty() && stOut.isEmpty();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
个人习惯写法,使用Deque通用api:
|
||||
```java
|
||||
class MyQueue {
|
||||
// java中的 Stack 有设计上的缺陷,官方推荐使用 Deque(双端队列) 代替 Stack
|
||||
// Deque 中的 addFirst、removeFirst、peekFirst 等方法等效于 Stack(堆栈) 中的 push、pop、peek
|
||||
Deque<Integer> stIn;
|
||||
Deque<Integer> stOut;
|
||||
/** Initialize your data structure here. */
|
||||
public MyQueue() {
|
||||
stIn = new ArrayDeque<>();
|
||||
stOut = new ArrayDeque<>();
|
||||
}
|
||||
|
||||
/** Push element x to the back of queue. */
|
||||
public void push(int x) {
|
||||
stIn.addLast(x);
|
||||
}
|
||||
|
||||
/** Removes the element from in front of queue and returns that element. */
|
||||
public int pop() {
|
||||
// 只要 stOut 为空,那么就应该将 stIn 中所有的元素倒腾到 stOut 中
|
||||
if (stOut.isEmpty()) {
|
||||
while (!stIn.isEmpty()) {
|
||||
stOut.addLast(stIn.pollLast());
|
||||
}
|
||||
}
|
||||
// 再返回 stOut 中的元素
|
||||
return stOut.pollLast();
|
||||
}
|
||||
|
||||
/** Get the front element. */
|
||||
public int peek() {
|
||||
// 直接使用已有的pop函数
|
||||
int res = this.pop();
|
||||
// 因为pop函数弹出了元素res,所以再添加回去
|
||||
stOut.addLast(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Returns whether the queue is empty. */
|
||||
public boolean empty() {
|
||||
// 当 stIn 栈为空时,说明没有元素可以倒腾到 stOut 栈了
|
||||
// 并且 stOut 栈也为空时,说明没有以前从 stIn 中倒腾到的元素了
|
||||
return stIn.isEmpty() && stOut.isEmpty();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
class MyQueue {
|
||||
|
||||
|
|
@ -187,9 +282,175 @@ class MyQueue {
|
|||
|
||||
|
||||
Python:
|
||||
```python
|
||||
# 使用两个栈实现先进先出的队列
|
||||
class MyQueue:
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize your data structure here.
|
||||
"""
|
||||
self.stack1 = list()
|
||||
self.stack2 = list()
|
||||
|
||||
def push(self, x: int) -> None:
|
||||
"""
|
||||
Push element x to the back of queue.
|
||||
"""
|
||||
# self.stack1用于接受元素
|
||||
self.stack1.append(x)
|
||||
|
||||
def pop(self) -> int:
|
||||
"""
|
||||
Removes the element from in front of queue and returns that element.
|
||||
"""
|
||||
# self.stack2用于弹出元素,如果self.stack2为[],则将self.stack1中元素全部弹出给self.stack2
|
||||
if self.stack2 == []:
|
||||
while self.stack1:
|
||||
tmp = self.stack1.pop()
|
||||
self.stack2.append(tmp)
|
||||
return self.stack2.pop()
|
||||
|
||||
def peek(self) -> int:
|
||||
"""
|
||||
Get the front element.
|
||||
"""
|
||||
if self.stack2 == []:
|
||||
while self.stack1:
|
||||
tmp = self.stack1.pop()
|
||||
self.stack2.append(tmp)
|
||||
return self.stack2[-1]
|
||||
|
||||
def empty(self) -> bool:
|
||||
"""
|
||||
Returns whether the queue is empty.
|
||||
"""
|
||||
return self.stack1 == [] and self.stack2 == []
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
```Go
|
||||
type MyQueue struct {
|
||||
stack []int
|
||||
back []int
|
||||
}
|
||||
|
||||
/** Initialize your data structure here. */
|
||||
func Constructor() MyQueue {
|
||||
return MyQueue{
|
||||
stack: make([]int, 0),
|
||||
back: make([]int, 0),
|
||||
}
|
||||
}
|
||||
|
||||
/** Push element x to the back of queue. */
|
||||
func (this *MyQueue) Push(x int) {
|
||||
for len(this.back) != 0 {
|
||||
val := this.back[len(this.back)-1]
|
||||
this.back = this.back[:len(this.back)-1]
|
||||
this.stack = append(this.stack, val)
|
||||
}
|
||||
this.stack = append(this.stack, x)
|
||||
}
|
||||
|
||||
/** Removes the element from in front of queue and returns that element. */
|
||||
func (this *MyQueue) Pop() int {
|
||||
for len(this.stack) != 0 {
|
||||
val := this.stack[len(this.stack)-1]
|
||||
this.stack = this.stack[:len(this.stack)-1]
|
||||
this.back = append(this.back, val)
|
||||
}
|
||||
if len(this.back) == 0 {
|
||||
return 0
|
||||
}
|
||||
val := this.back[len(this.back)-1]
|
||||
this.back = this.back[:len(this.back)-1]
|
||||
return val
|
||||
}
|
||||
|
||||
/** Get the front element. */
|
||||
func (this *MyQueue) Peek() int {
|
||||
for len(this.stack) != 0 {
|
||||
val := this.stack[len(this.stack)-1]
|
||||
this.stack = this.stack[:len(this.stack)-1]
|
||||
this.back = append(this.back, val)
|
||||
}
|
||||
if len(this.back) == 0 {
|
||||
return 0
|
||||
}
|
||||
val := this.back[len(this.back)-1]
|
||||
return val
|
||||
}
|
||||
|
||||
/** Returns whether the queue is empty. */
|
||||
func (this *MyQueue) Empty() bool {
|
||||
return len(this.stack) == 0 && len(this.back) == 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Your MyQueue object will be instantiated and called as such:
|
||||
* obj := Constructor();
|
||||
* obj.Push(x);
|
||||
* param_2 := obj.Pop();
|
||||
* param_3 := obj.Peek();
|
||||
* param_4 := obj.Empty();
|
||||
*/
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
// 使用两个数组的栈方法(push, pop) 实现队列
|
||||
/**
|
||||
* Initialize your data structure here.
|
||||
*/
|
||||
var MyQueue = function() {
|
||||
this.stack1 = [];
|
||||
this.stack2 = [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Push element x to the back of queue.
|
||||
* @param {number} x
|
||||
* @return {void}
|
||||
*/
|
||||
MyQueue.prototype.push = function(x) {
|
||||
this.stack1.push(x);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the element from in front of queue and returns that element.
|
||||
* @return {number}
|
||||
*/
|
||||
MyQueue.prototype.pop = function() {
|
||||
const size = this.stack2.length;
|
||||
if(size) {
|
||||
return this.stack2.pop();
|
||||
}
|
||||
while(this.stack1.length) {
|
||||
this.stack2.push(this.stack1.pop());
|
||||
}
|
||||
return this.stack2.pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the front element.
|
||||
* @return {number}
|
||||
*/
|
||||
MyQueue.prototype.peek = function() {
|
||||
const x = this.pop();
|
||||
this.stack2.push(x);
|
||||
return x;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns whether the queue is empty.
|
||||
* @return {boolean}
|
||||
*/
|
||||
MyQueue.prototype.empty = function() {
|
||||
return !this.stack1.length && !this.stack2.length
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 235. 二叉搜索树的最近公共祖先
|
||||
|
|
@ -247,8 +247,23 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, x):
|
||||
# self.val = x
|
||||
# self.left = None
|
||||
# self.right = None
|
||||
|
||||
|
||||
class Solution:
|
||||
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
|
||||
if not root: return root //中
|
||||
if root.val >p.val and root.val > q.val:
|
||||
return self.lowestCommonAncestor(root.left,p,q) //左
|
||||
elif root.val < p.val and root.val < q.val:
|
||||
return self.lowestCommonAncestor(root.right,p,q) //右
|
||||
else: return root
|
||||
```
|
||||
Go:
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 本来是打算将二叉树和二叉搜索树的公共祖先问题一起讲,后来发现篇幅过长了,只能先说一说二叉树的公共祖先问题。
|
||||
|
|
@ -263,10 +263,53 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, x):
|
||||
# self.val = x
|
||||
# self.left = None
|
||||
# self.right = None
|
||||
//递归
|
||||
class Solution:
|
||||
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
|
||||
if not root or root == p or root == q: return root //找到了节点p或者q,或者遇到空节点
|
||||
left = self.lowestCommonAncestor(root.left,p,q) //左
|
||||
right = self.lowestCommonAncestor(root.right,p,q) //右
|
||||
if left and right: return root //中: left和right不为空,root就是最近公共节点
|
||||
elif left and not right: return left //目标节点是通过left返回的
|
||||
elif not left and right: return right //目标节点是通过right返回的
|
||||
else: return None //没找到
|
||||
```
|
||||
Go:
|
||||
```Go
|
||||
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
|
||||
// check
|
||||
if root == nil {
|
||||
return root
|
||||
}
|
||||
// 相等 直接返回root节点即可
|
||||
if root == p || root == q {
|
||||
return root
|
||||
}
|
||||
// Divide
|
||||
left := lowestCommonAncestor(root.Left, p, q)
|
||||
right := lowestCommonAncestor(root.Right, p, q)
|
||||
|
||||
// Conquer
|
||||
// 左右两边都不为空,则根节点为祖先
|
||||
if left != nil && right != nil {
|
||||
return root
|
||||
}
|
||||
if left != nil {
|
||||
return left
|
||||
}
|
||||
if right != nil {
|
||||
return right
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -263,11 +263,159 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
```python
|
||||
class MyQueue: #单调队列(从大到小
|
||||
def __init__(self):
|
||||
self.queue = [] #使用list来实现单调队列
|
||||
|
||||
#每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。
|
||||
#同时pop之前判断队列当前是否为空。
|
||||
def pop(self, value):
|
||||
if self.queue and value == self.queue[0]:
|
||||
self.queue.pop(0)#list.pop()时间复杂度为O(n),这里可以使用collections.deque()
|
||||
|
||||
#如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。
|
||||
#这样就保持了队列里的数值是单调从大到小的了。
|
||||
def push(self, value):
|
||||
while self.queue and value > self.queue[-1]:
|
||||
self.queue.pop()
|
||||
self.queue.append(value)
|
||||
|
||||
#查询当前队列里的最大值 直接返回队列前端也就是front就可以了。
|
||||
def front(self):
|
||||
return self.queue[0]
|
||||
|
||||
class Solution:
|
||||
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
|
||||
que = MyQueue()
|
||||
result = []
|
||||
for i in range(k): #先将前k的元素放进队列
|
||||
que.push(nums[i])
|
||||
result.append(que.front()) #result 记录前k的元素的最大值
|
||||
for i in range(k, len(nums)):
|
||||
que.pop(nums[i - k]) #滑动窗口移除最前面元素
|
||||
que.push(nums[i]) #滑动窗口前加入最后面的元素
|
||||
result.append(que.front()) #记录对应的最大值
|
||||
return result
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
func maxSlidingWindow(nums []int, k int) []int {
|
||||
var queue []int
|
||||
var rtn []int
|
||||
|
||||
for f := 0; f < len(nums); f++ {
|
||||
//维持队列递减, 将 k 插入合适的位置, queue中 <=k 的 元素都不可能是窗口中的最大值, 直接弹出
|
||||
for len(queue) > 0 && nums[f] > nums[queue[len(queue)-1]] {
|
||||
queue = queue[:len(queue)-1]
|
||||
}
|
||||
// 等大的后来者也应入队
|
||||
if len(queue) == 0 || nums[f] <= nums[queue[len(queue)-1]] {
|
||||
queue = append(queue, f)
|
||||
}
|
||||
|
||||
if f >= k - 1 {
|
||||
rtn = append(rtn, nums[queue[0]])
|
||||
//弹出离开窗口的队首
|
||||
if f - k + 1 == queue[0] {
|
||||
queue = queue[1:]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rtn
|
||||
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```go
|
||||
// 封装单调队列的方式解题
|
||||
type MyQueue struct {
|
||||
queue []int
|
||||
}
|
||||
|
||||
func NewMyQueue() *MyQueue {
|
||||
return &MyQueue{
|
||||
queue: make([]int, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MyQueue) Front() int {
|
||||
return m.queue[0]
|
||||
}
|
||||
|
||||
func (m *MyQueue) Back() int {
|
||||
return m.queue[len(m.queue)-1]
|
||||
}
|
||||
|
||||
func (m *MyQueue) Empty() bool {
|
||||
return len(m.queue) == 0
|
||||
}
|
||||
|
||||
func (m *MyQueue) Push(val int) {
|
||||
for !m.Empty() && val > m.Back() {
|
||||
m.queue = m.queue[:len(m.queue)-1]
|
||||
}
|
||||
m.queue = append(m.queue, val)
|
||||
}
|
||||
|
||||
func (m *MyQueue) Pop(val int) {
|
||||
if !m.Empty() && val == m.Front() {
|
||||
m.queue = m.queue[1:]
|
||||
}
|
||||
}
|
||||
|
||||
func maxSlidingWindow(nums []int, k int) []int {
|
||||
queue := NewMyQueue()
|
||||
length := len(nums)
|
||||
res := make([]int, 0)
|
||||
// 先将前k个元素放入队列
|
||||
for i := 0; i < k; i++ {
|
||||
queue.Push(nums[i])
|
||||
}
|
||||
// 记录前k个元素的最大值
|
||||
res = append(res, queue.Front())
|
||||
|
||||
for i := k; i < length; i++ {
|
||||
// 滑动窗口移除最前面的元素
|
||||
queue.Pop(nums[i-k])
|
||||
// 滑动窗口添加最后面的元素
|
||||
queue.Push(nums[i])
|
||||
// 记录最大值
|
||||
res = append(res, queue.Front())
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
```javascript
|
||||
var maxSlidingWindow = function (nums, k) {
|
||||
// 队列数组(存放的是元素下标,为了取值方便)
|
||||
const q = [];
|
||||
// 结果数组
|
||||
const ans = [];
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
// 若队列不为空,且当前元素大于等于队尾所存下标的元素,则弹出队尾
|
||||
while (q.length && nums[i] >= nums[q[q.length - 1]]) {
|
||||
q.pop();
|
||||
}
|
||||
// 入队当前元素下标
|
||||
q.push(i);
|
||||
// 判断当前最大值(即队首元素)是否在窗口中,若不在便将其出队
|
||||
while (q[0] <= i - k) {
|
||||
q.shift();
|
||||
}
|
||||
// 当达到窗口大小时便开始向结果中添加数据
|
||||
if (i >= k - 1) ans.push(nums[q[0]]);
|
||||
}
|
||||
return ans;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,26 +1,33 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 数组就是简单的哈希表,但是数组的大小可不是无限开辟的
|
||||
|
||||
# 242.有效的字母异位词
|
||||
## 242.有效的字母异位词
|
||||
|
||||
https://leetcode-cn.com/problems/valid-anagram/
|
||||
|
||||
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
|
||||
|
||||

|
||||
示例 1:
|
||||
输入: s = "anagram", t = "nagaram"
|
||||
输出: true
|
||||
|
||||
示例 2:
|
||||
输入: s = "rat", t = "car"
|
||||
输出: false
|
||||
|
||||
|
||||
**说明:**
|
||||
你可以假设字符串只包含小写字母。
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
先看暴力的解法,两层for循环,同时还要记录字符是否重复出现,很明显时间复杂度是 O(n^2)。
|
||||
|
||||
|
|
@ -52,7 +59,6 @@ https://leetcode-cn.com/problems/valid-anagram/
|
|||
|
||||
时间复杂度为O(n),空间上因为定义是的一个常量大小的辅助数组,所以空间复杂度为O(1)。
|
||||
|
||||
看完这篇哈希表总结:[哈希表:总结篇!(每逢总结必经典)](https://mp.weixin.qq.com/s/1s91yXtarL-PkX07BfnwLg),详细就可以哈希表的各种用法非常清晰了。
|
||||
|
||||
C++ 代码如下:
|
||||
```C++
|
||||
|
|
@ -107,7 +113,22 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def isAnagram(self, s: str, t: str) -> bool:
|
||||
record = [0] * 26
|
||||
for i in range(len(s)):
|
||||
#并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
|
||||
record[ord(s[i]) - ord("a")] += 1
|
||||
print(record)
|
||||
for i in range(len(t)):
|
||||
record[ord(t[i]) - ord("a")] -= 1
|
||||
for i in range(26):
|
||||
if record[i] != 0:
|
||||
#record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
|
||||
return False
|
||||
return True
|
||||
```
|
||||
|
||||
Go:
|
||||
```go
|
||||
|
|
@ -134,6 +155,35 @@ func isAnagram(s string, t string) bool {
|
|||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {string} s
|
||||
* @param {string} t
|
||||
* @return {boolean}
|
||||
*/
|
||||
var isAnagram = function(s, t) {
|
||||
if(s.length !== t.length) return false;
|
||||
const resSet = new Array(26).fill(0);
|
||||
const base = "a".charCodeAt();
|
||||
for(const i of s) {
|
||||
resSet[i.charCodeAt() - base]++;
|
||||
}
|
||||
for(const i of t) {
|
||||
if(!resSet[i.charCodeAt() - base]) return false;
|
||||
resSet[i.charCodeAt() - base]--;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
```
|
||||
|
||||
## 相关题目
|
||||
|
||||
* 383.赎金信
|
||||
* 49.字母异位词分组
|
||||
* 438.找到字符串中所有字母异位词
|
||||
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 以为只用了递归,其实还用了回溯
|
||||
|
|
@ -77,7 +77,7 @@ if (cur->left == NULL && cur->right == NULL) {
|
|||
|
||||
这里我们先使用vector<int>结构的path容器来记录路径,那么终止处理逻辑如下:
|
||||
|
||||
```
|
||||
```C++
|
||||
if (cur->left == NULL && cur->right == NULL) { // 遇到叶子节点
|
||||
string sPath;
|
||||
for (int i = 0; i < path.size() - 1; i++) { // 将path里记录的路径转为string格式
|
||||
|
|
@ -113,7 +113,7 @@ if (cur->right) {
|
|||
|
||||
那么回溯要怎么回溯呢,一些同学会这么写,如下:
|
||||
|
||||
```
|
||||
```C++
|
||||
if (cur->left) {
|
||||
traversal(cur->left, path, result);
|
||||
}
|
||||
|
|
@ -129,7 +129,7 @@ path.pop_back();
|
|||
|
||||
那么代码应该这么写:
|
||||
|
||||
```
|
||||
```C++
|
||||
if (cur->left) {
|
||||
traversal(cur->left, path, result);
|
||||
path.pop_back(); // 回溯
|
||||
|
|
@ -324,10 +324,57 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
```Python
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
class Solution:
|
||||
def binaryTreePaths(self, root: TreeNode) -> List[str]:
|
||||
path=[]
|
||||
res=[]
|
||||
def backtrace(root, path):
|
||||
if not root:return
|
||||
path.append(root.val)
|
||||
if (not root.left)and (not root.right):
|
||||
res.append(path[:])
|
||||
ways=[]
|
||||
if root.left:ways.append(root.left)
|
||||
if root.right:ways.append(root.right)
|
||||
for way in ways:
|
||||
backtrace(way,path)
|
||||
path.pop()
|
||||
backtrace(root,path)
|
||||
return ["->".join(list(map(str,i))) for i in res]
|
||||
|
||||
|
||||
```
|
||||
Go:
|
||||
|
||||
JavaScript:
|
||||
1.递归版本
|
||||
```javascript
|
||||
var binaryTreePaths = function(root) {
|
||||
//递归遍历+递归三部曲
|
||||
let res=[];
|
||||
//1. 确定递归函数 函数参数
|
||||
const getPath=function(node,curPath){
|
||||
//2. 确定终止条件,到叶子节点就终止
|
||||
if(node.left===null&&node.right===null){
|
||||
curPath+=node.val;
|
||||
res.push(curPath);
|
||||
return ;
|
||||
}
|
||||
//3. 确定单层递归逻辑
|
||||
curPath+=node.val+'->';
|
||||
node.left&&getPath(node.left,curPath);
|
||||
node.right&&getPath(node.right,curPath);
|
||||
}
|
||||
getPath(root,'');
|
||||
return res;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 动态规划:一样的套路,再求一次完全平方数
|
||||
|
||||
## 279.完全平方数
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
输入:n = 13
|
||||
输出:2
|
||||
解释:13 = 4 + 9
|
||||
|
||||
|
||||
提示:
|
||||
* 1 <= n <= 10^4
|
||||
|
||||
|
|
@ -184,9 +184,89 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def numSquares(self, n: int) -> int:
|
||||
'''版本一'''
|
||||
# 初始化
|
||||
nums = [i**2 for i in range(1, n + 1) if i**2 <= n]
|
||||
dp = [10**4]*(n + 1)
|
||||
dp[0] = 0
|
||||
# 遍历背包
|
||||
for j in range(1, n + 1):
|
||||
# 遍历物品
|
||||
for num in nums:
|
||||
if j >= num:
|
||||
dp[j] = min(dp[j], dp[j - num] + 1)
|
||||
return dp[n]
|
||||
|
||||
def numSquares1(self, n: int) -> int:
|
||||
'''版本二'''
|
||||
# 初始化
|
||||
nums = [i**2 for i in range(1, n + 1) if i**2 <= n]
|
||||
dp = [10**4]*(n + 1)
|
||||
dp[0] = 0
|
||||
# 遍历物品
|
||||
for num in nums:
|
||||
# 遍历背包
|
||||
for j in range(num, n + 1)
|
||||
dp[j] = min(dp[j], dp[j - num] + 1)
|
||||
return dp[n]
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Go:
|
||||
```go
|
||||
// 版本一,先遍历物品, 再遍历背包
|
||||
func numSquares1(n int) int {
|
||||
//定义
|
||||
dp := make([]int, n+1)
|
||||
// 初始化
|
||||
dp[0] = 0
|
||||
for i := 1; i <= n; i++ {
|
||||
dp[i] = math.MaxInt32
|
||||
}
|
||||
// 遍历物品
|
||||
for i := 1; i <= n; i++ {
|
||||
// 遍历背包
|
||||
for j := i*i; j <= n; j++ {
|
||||
dp[j] = min(dp[j], dp[j-i*i]+1)
|
||||
}
|
||||
}
|
||||
|
||||
return dp[n]
|
||||
}
|
||||
|
||||
// 版本二,先遍历背包, 再遍历物品
|
||||
func numSquares2(n int) int {
|
||||
//定义
|
||||
dp := make([]int, n+1)
|
||||
// 初始化
|
||||
dp[0] = 0
|
||||
// 遍历背包
|
||||
for j := 1; j <= n; j++ {
|
||||
//初始化
|
||||
dp[j] = math.MaxInt32
|
||||
// 遍历物品
|
||||
for i := 1; i <= n; i++ {
|
||||
if j >= i*i {
|
||||
dp[j] = min(dp[j], dp[j-i*i]+1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dp[n]
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 300.最长递增子序列
|
||||
|
||||
|
|
@ -98,8 +98,6 @@ public:
|
|||
};
|
||||
```
|
||||
|
||||
杨老师的这个专栏很不错,他本身也是Oracle 首席工程师,对Java有极其深刻的理解,讲的内容很硬核,适合使用Java语言的录友们用来进阶!作为面试突击手册非常合适, 所以推荐给大家!现在下单输入口令:javahexin,可以省40元那[机智]
|
||||
|
||||
## 总结
|
||||
|
||||
本题最关键的是要想到dp[i]由哪些状态可以推出来,并取最大值,那么很自然就能想到递推公式:dp[i] = max(dp[i], dp[j] + 1);
|
||||
|
|
@ -110,14 +108,71 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int lengthOfLIS(int[] nums) {
|
||||
int[] dp = new int[nums.length];
|
||||
Arrays.fill(dp, 1);
|
||||
for (int i = 0; i < dp.length; i++) {
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (nums[i] > nums[j]) {
|
||||
dp[i] = Math.max(dp[i], dp[j] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
int res = 0;
|
||||
for (int i = 0; i < dp.length; i++) {
|
||||
res = Math.max(res, dp[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def lengthOfLIS(self, nums: List[int]) -> int:
|
||||
if len(nums) <= 1:
|
||||
return len(nums)
|
||||
dp = [1] * len(nums)
|
||||
result = 0
|
||||
for i in range(1, len(nums)):
|
||||
for j in range(0, i):
|
||||
if nums[i] > nums[j]:
|
||||
dp[i] = max(dp[i], dp[j] + 1)
|
||||
result = max(result, dp[i]) #取长的子序列
|
||||
return result
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
||||
```go
|
||||
func lengthOfLIS(nums []int ) int {
|
||||
dp := []int{}
|
||||
for _, num := range nums {
|
||||
if len(dp) ==0 || dp[len(dp) - 1] < num {
|
||||
dp = append(dp, num)
|
||||
} else {
|
||||
l, r := 0, len(dp) - 1
|
||||
pos := r
|
||||
for l <= r {
|
||||
mid := (l + r) >> 1
|
||||
if dp[mid] >= num {
|
||||
pos = mid;
|
||||
r = mid - 1
|
||||
} else {
|
||||
l = mid + 1
|
||||
}
|
||||
}
|
||||
dp[pos] = num
|
||||
}//二分查找
|
||||
}
|
||||
return len(dp)
|
||||
}
|
||||
```
|
||||
*复杂度分析*
|
||||
- 时间复杂度:O(nlogn)。数组 nums 的长度为 n,我们依次用数组中的元素去更新 dp 数组,相当于插入最后递增的元素,而更新 dp 数组时需要进行 O(logn) 的二分搜索,所以总时间复杂度为 O(nlogn)。
|
||||
- 空间复杂度:O(n),需要额外使用长度为 n 的 dp 数组。
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 309.最佳买卖股票时机含冷冻期
|
||||
|
||||
|
|
@ -159,12 +159,51 @@ public:
|
|||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public int maxProfit(int[] prices) {
|
||||
if (prices == null || prices.length < 2) {
|
||||
return 0;
|
||||
}
|
||||
int[][] dp = new int[prices.length][2];
|
||||
|
||||
// bad case
|
||||
dp[0][0] = 0;
|
||||
dp[0][1] = -prices[0];
|
||||
dp[1][0] = Math.max(dp[0][0], dp[0][1] + prices[1]);
|
||||
dp[1][1] = Math.max(dp[0][1], -prices[1]);
|
||||
|
||||
for (int i = 2; i < prices.length; i++) {
|
||||
// dp公式
|
||||
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
|
||||
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 2][0] - prices[i]);
|
||||
}
|
||||
|
||||
return dp[prices.length - 1][0];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
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] #持股票
|
||||
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])
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 动态规划: 给我个机会,我再兑换一次零钱
|
||||
|
||||
## 322. 零钱兑换
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
示例 5:
|
||||
输入:coins = [1], amount = 2
|
||||
输出:2
|
||||
|
||||
|
||||
提示:
|
||||
|
||||
* 1 <= coins.length <= 12
|
||||
|
|
@ -209,9 +209,100 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def coinChange(self, coins: List[int], amount: int) -> int:
|
||||
'''版本一'''
|
||||
# 初始化
|
||||
dp = [amount + 1]*(amount + 1)
|
||||
dp[0] = 0
|
||||
# 遍历物品
|
||||
for coin in coins:
|
||||
# 遍历背包
|
||||
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:
|
||||
'''版本二'''
|
||||
# 初始化
|
||||
dp = [amount + 1]*(amount + 1)
|
||||
dp[0] = 0
|
||||
# 遍历物品
|
||||
for j in range(1, amount + 1):
|
||||
# 遍历背包
|
||||
for coin in coins:
|
||||
if j >= coin:
|
||||
dp[j] = min(dp[j], dp[j - coin] + 1)
|
||||
return dp[amount] if dp[amount] < amount + 1 else -1
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
Go:
|
||||
```go
|
||||
// 版本一, 先遍历物品,再遍历背包
|
||||
func coinChange1(coins []int, amount int) int {
|
||||
dp := make([]int, amount+1)
|
||||
// 初始化dp[0]
|
||||
dp[0] = 0
|
||||
// 初始化为math.MaxInt32
|
||||
for j := 1; j <= amount; j++ {
|
||||
dp[j] = math.MaxInt32
|
||||
}
|
||||
|
||||
// 遍历物品
|
||||
for i := 0; i < len(coins); i++ {
|
||||
// 遍历背包
|
||||
for j := coins[i]; j <= amount; j++ {
|
||||
if dp[j-coins[i]] != math.MaxInt32 {
|
||||
// 推导公式
|
||||
dp[j] = min(dp[j], dp[j-coins[i]]+1)
|
||||
//fmt.Println(dp,j,i)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 没找到能装满背包的, 就返回-1
|
||||
if dp[amount] == math.MaxInt32 {
|
||||
return -1
|
||||
}
|
||||
return dp[amount]
|
||||
}
|
||||
|
||||
// 版本二,先遍历背包,再遍历物品
|
||||
func coinChange2(coins []int, amount int) int {
|
||||
dp := make([]int, amount+1)
|
||||
// 初始化dp[0]
|
||||
dp[0] = 0
|
||||
// 遍历背包,从1开始
|
||||
for j := 1; j <= amount; j++ {
|
||||
// 初始化为math.MaxInt32
|
||||
dp[j] = math.MaxInt32
|
||||
// 遍历物品
|
||||
for i := 0; i < len(coins); i++ {
|
||||
if j >= coins[i] && dp[j-coins[i]] != math.MaxInt32 {
|
||||
// 推导公式
|
||||
dp[j] = min(dp[j], dp[j-coins[i]]+1)
|
||||
//fmt.Println(dp)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 没找到能装满背包的, 就返回-1
|
||||
if dp[amount] == math.MaxInt32 {
|
||||
return -1
|
||||
}
|
||||
return dp[amount]
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 这也可以用回溯法? 其实深搜和回溯也是相辅相成的,毕竟都用递归。
|
||||
|
|
@ -399,6 +399,49 @@ char ** findItinerary(char *** tickets, int ticketsSize, int* ticketsColSize, in
|
|||
}
|
||||
```
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
|
||||
var findItinerary = function(tickets) {
|
||||
let result = ['JFK']
|
||||
let map = {}
|
||||
|
||||
for (const tickt of tickets) {
|
||||
const [from, to] = tickt
|
||||
if (!map[from]) {
|
||||
map[from] = []
|
||||
}
|
||||
map[from].push(to)
|
||||
}
|
||||
|
||||
for (const city in map) {
|
||||
// 对到达城市列表排序
|
||||
map[city].sort()
|
||||
}
|
||||
function backtracing() {
|
||||
if (result.length === tickets.length + 1) {
|
||||
return true
|
||||
}
|
||||
if (!map[result[result.length - 1]] || !map[result[result.length - 1]].length) {
|
||||
return false
|
||||
}
|
||||
for(let i = 0 ; i < map[result[result.length - 1]].length; i++) {
|
||||
let city = map[result[result.length - 1]][i]
|
||||
// 删除已走过航线,防止死循环
|
||||
map[result[result.length - 1]].splice(i, 1)
|
||||
result.push(city)
|
||||
if (backtracing()) {
|
||||
return true
|
||||
}
|
||||
result.pop()
|
||||
map[result[result.length - 1]].splice(i, 0, city)
|
||||
}
|
||||
}
|
||||
backtracing()
|
||||
return result
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 337.打家劫舍 III
|
||||
|
|
@ -218,10 +218,94 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
```Java
|
||||
class Solution {
|
||||
// 1.递归去偷,超时
|
||||
public int rob(TreeNode root) {
|
||||
if (root == null)
|
||||
return 0;
|
||||
int money = root.val;
|
||||
if (root.left != null) {
|
||||
money += rob(root.left.left) + rob(root.left.right);
|
||||
}
|
||||
if (root.right != null) {
|
||||
money += rob(root.right.left) + rob(root.right.right);
|
||||
}
|
||||
return Math.max(money, rob(root.left) + rob(root.right));
|
||||
}
|
||||
|
||||
// 2.递归去偷,记录状态
|
||||
// 执行用时:3 ms , 在所有 Java 提交中击败了 56.24% 的用户
|
||||
public int rob1(TreeNode root) {
|
||||
Map<TreeNode, Integer> memo = new HashMap<>();
|
||||
return robAction(root, memo);
|
||||
}
|
||||
|
||||
int robAction(TreeNode root, Map<TreeNode, Integer> memo) {
|
||||
if (root == null)
|
||||
return 0;
|
||||
if (memo.containsKey(root))
|
||||
return memo.get(root);
|
||||
int money = root.val;
|
||||
if (root.left != null) {
|
||||
money += robAction(root.left.left, memo) + robAction(root.left.right, memo);
|
||||
}
|
||||
if (root.right != null) {
|
||||
money += robAction(root.right.left, memo) + robAction(root.right.right, memo);
|
||||
}
|
||||
int res = Math.max(money, robAction(root.left, memo) + robAction(root.right, memo));
|
||||
memo.put(root, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
// 3.状态标记递归
|
||||
// 执行用时:0 ms , 在所有 Java 提交中击败了 100% 的用户
|
||||
// 不偷:Max(左孩子不偷,左孩子偷) + Max(又孩子不偷,右孩子偷)
|
||||
// root[0] = Math.max(rob(root.left)[0], rob(root.left)[1]) +
|
||||
// Math.max(rob(root.right)[0], rob(root.right)[1])
|
||||
// 偷:左孩子不偷+ 右孩子不偷 + 当前节点偷
|
||||
// root[1] = rob(root.left)[0] + rob(root.right)[0] + root.val;
|
||||
public int rob3(TreeNode root) {
|
||||
int[] res = robAction1(root);
|
||||
return Math.max(res[0], res[1]);
|
||||
}
|
||||
|
||||
int[] robAction1(TreeNode root) {
|
||||
int res[] = new int[2];
|
||||
if (root == null)
|
||||
return res;
|
||||
|
||||
int[] left = robAction1(root.left);
|
||||
int[] right = robAction1(root.right);
|
||||
|
||||
res[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
|
||||
res[1] = root.val + left[0] + right[0];
|
||||
return res;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
> 动态规划
|
||||
```python
|
||||
class Solution:
|
||||
def rob(self, root: TreeNode) -> int:
|
||||
result = self.robTree(root)
|
||||
return max(result[0], result[1])
|
||||
|
||||
#长度为2的数组,0:不偷,1:偷
|
||||
def robTree(self, cur):
|
||||
if not cur:
|
||||
return (0, 0) #这里返回tuple, 也可以返回list
|
||||
left = self.robTree(cur.left)
|
||||
right = self.robTree(cur.right)
|
||||
#偷cur
|
||||
val1 = cur.val + left[0] + right[0]
|
||||
#不偷cur
|
||||
val2 = max(left[0], left[1]) + max(right[0], right[1])
|
||||
return (val2, val1)
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 343. 整数拆分
|
||||
|
||||
题目链接:https://leetcode-cn.com/problems/integer-break/
|
||||
|
||||
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
|
||||
|
||||
示例 1:
|
||||
|
|
@ -49,11 +51,14 @@ dp[i]的定义讲贯彻整个解题过程,下面哪一步想不懂了,就想
|
|||
|
||||
**那有同学问了,j怎么就不拆分呢?**
|
||||
|
||||
j是从1开始遍历,拆分j的情况,在遍历j的过程中其实都计算过了。
|
||||
j是从1开始遍历,拆分j的情况,在遍历j的过程中其实都计算过了。那么从1遍历j,比较(i - j) * j和dp[i - j] * j 取最大的。递推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
|
||||
|
||||
那么从1遍历j,比较(i - j) * j和dp[i - j] * j 取最大的。
|
||||
也可以这么理解,j * (i - j) 是单纯的把整数拆分为两个数相乘,而j * dp[i - j]是拆分成两个以及两个以上的个数相乘。
|
||||
|
||||
如果定义dp[i - j] * dp[j] 也是默认将一个数强制拆成4份以及4份以上了。
|
||||
|
||||
所以递推公式:dp[i] = max({dp[i], (i - j) * j, dp[i - j] * j});
|
||||
|
||||
递推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
|
||||
|
||||
3. dp的初始化
|
||||
|
||||
|
|
@ -185,11 +190,38 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int integerBreak(int n) {
|
||||
//dp[i]为正整数i拆分结果的最大乘积
|
||||
int[] dp = new int[n+1];
|
||||
dp[2] = 1;
|
||||
for (int i = 3; i <= n; ++i) {
|
||||
for (int j = 1; j < i - 1; ++j) {
|
||||
//j*(i-j)代表把i拆分为j和i-j两个数相乘
|
||||
//j*dp[i-j]代表把i拆分成j和继续把(i-j)这个数拆分,取(i-j)拆分结果中的最大乘积与j相乘
|
||||
dp[i] = Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j]));
|
||||
}
|
||||
}
|
||||
return dp[n];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def integerBreak(self, n: int) -> int:
|
||||
dp = [0] * (n + 1)
|
||||
dp[2] = 1
|
||||
for i in range(3, n + 1):
|
||||
# 假设对正整数 i 拆分出的第一个正整数是 j(1 <= j < i),则有以下两种方案:
|
||||
# 1) 将 i 拆分成 j 和 i−j 的和,且 i−j 不再拆分成多个正整数,此时的乘积是 j * (i-j)
|
||||
# 2) 将 i 拆分成 j 和 i−j 的和,且 i−j 继续拆分成多个正整数,此时的乘积是 j * dp[i-j]
|
||||
for j in range(1, i - 1):
|
||||
dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]))
|
||||
return dp[n]
|
||||
```
|
||||
Go:
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -157,7 +157,18 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def reverseString(self, s: List[str]) -> None:
|
||||
"""
|
||||
Do not return anything, modify s in-place instead.
|
||||
"""
|
||||
left, right = 0, len(s) - 1
|
||||
while(left < right):
|
||||
s[left], s[right] = s[right], s[left]
|
||||
left += 1
|
||||
right -= 1
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
|
|
@ -172,6 +183,26 @@ func reverseString(s []byte) {
|
|||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {character[]} s
|
||||
* @return {void} Do not return anything, modify s in-place instead.
|
||||
*/
|
||||
var reverseString = function(s) {
|
||||
return s.reverse();
|
||||
};
|
||||
|
||||
var reverseString = function(s) {
|
||||
let l = -1, r = s.length;
|
||||
while(++l < --r) [s[l], s[r]] = [s[r], s[l]];
|
||||
return s;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -162,7 +162,33 @@ class Solution {
|
|||
|
||||
|
||||
Python:
|
||||
```python
|
||||
#时间复杂度:O(nlogk)
|
||||
#空间复杂度:O(n)
|
||||
import heapq
|
||||
class Solution:
|
||||
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
|
||||
#要统计元素出现频率
|
||||
map_ = {} #nums[i]:对应出现的次数
|
||||
for i in range(len(nums)):
|
||||
map_[nums[i]] = map_.get(nums[i], 0) + 1
|
||||
|
||||
#对频率排序
|
||||
#定义一个小顶堆,大小为k
|
||||
pri_que = [] #小顶堆
|
||||
|
||||
#用固定大小为k的小顶堆,扫面所有频率的数值
|
||||
for key, freq in map_.items():
|
||||
heapq.heappush(pri_que, (freq, key))
|
||||
if len(pri_que) > k: #如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k
|
||||
heapq.heappop(pri_que)
|
||||
|
||||
#找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒叙来输出到数组
|
||||
result = [0] * k
|
||||
for i in range(k-1, -1, -1):
|
||||
result[i] = heapq.heappop(pri_que)[1]
|
||||
return result
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
||||
> 如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费!
|
||||
|
||||
# 349. 两个数组的交集
|
||||
|
||||
## 349. 两个数组的交集
|
||||
|
||||
https://leetcode-cn.com/problems/intersection-of-two-arrays/
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ https://leetcode-cn.com/problems/intersection-of-two-arrays/
|
|||
输出结果中的每个元素一定是唯一的。
|
||||
我们可以不考虑输出结果的顺序。
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
这道题目,主要要学会使用一种哈希数据结构:unordered_set,这个数据结构可以解决很多类似的问题。
|
||||
|
||||
|
|
@ -31,7 +32,7 @@ https://leetcode-cn.com/problems/intersection-of-two-arrays/
|
|||
|
||||
这道题用暴力的解法时间复杂度是O(n^2),那来看看使用哈希法进一步优化。
|
||||
|
||||
那么用数组来做哈希表也是不错的选择,例如[242. 有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig),[0383.赎金信](https://mp.weixin.qq.com/s/sYZIR4dFBrw_lr3eJJnteQ)
|
||||
那么用数组来做哈希表也是不错的选择,例如[242. 有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA)
|
||||
|
||||
但是要注意,**使用数组来做哈希的题目,是因为题目都限制了数值的大小。**
|
||||
|
||||
|
|
@ -52,6 +53,7 @@ std::set和std::multiset底层实现都是红黑树,std::unordered_set的底
|
|||

|
||||
|
||||
C++代码如下:
|
||||
|
||||
```C++
|
||||
class Solution {
|
||||
public:
|
||||
|
|
@ -69,6 +71,13 @@ public:
|
|||
};
|
||||
```
|
||||
|
||||
## 拓展
|
||||
|
||||
那有同学可能问了,遇到哈希问题我直接都用set不就得了,用什么数组啊。
|
||||
|
||||
直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的。
|
||||
|
||||
不要小瞧 这个耗时,在数据量大的情况,差距是很明显的。
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
|
@ -109,11 +118,70 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
```python3
|
||||
class Solution:
|
||||
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
|
||||
result_set = set()
|
||||
|
||||
set1 = set(nums1)
|
||||
for num in nums2:
|
||||
if num in set1:
|
||||
result_set.add(num) # set1里出现的nums2元素 存放到结果
|
||||
return result_set
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
```go
|
||||
func intersection(nums1 []int, nums2 []int) []int {
|
||||
m := make(map[int]int)
|
||||
for _, v := range nums1 {
|
||||
m[v] = 1
|
||||
}
|
||||
var res []int
|
||||
// 利用count>0,实现重复值只拿一次放入返回结果中
|
||||
for _, v := range nums2 {
|
||||
if count, ok := m[v]; ok && count > 0 {
|
||||
res = append(res, v)
|
||||
m[v]--
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {number[]} nums1
|
||||
* @param {number[]} nums2
|
||||
* @return {number[]}
|
||||
*/
|
||||
var intersection = function(nums1, nums2) {
|
||||
// 根据数组大小交换操作的数组
|
||||
if(nums1.length < nums2.length) {
|
||||
const _ = nums1;
|
||||
nums1 = nums2;
|
||||
nums2 = _;
|
||||
}
|
||||
const nums1Set = new Set(nums1);
|
||||
const resSet = new Set();
|
||||
// for(const n of nums2) {
|
||||
// nums1Set.has(n) && resSet.add(n);
|
||||
// }
|
||||
// 循环 比 迭代器快
|
||||
for(let i = nums2.length - 1; i >= 0; i--) {
|
||||
nums1Set.has(nums2[i]) && resSet.add(nums2[i]);
|
||||
}
|
||||
return Array.from(resSet);
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
## 相关题目
|
||||
|
||||
* 350.两个数组的交集 II
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 本周讲解了[贪心理论基础](https://mp.weixin.qq.com/s/O935TaoHE9Eexwe_vSbRAg),以及第一道贪心的题目:[贪心算法:分发饼干](https://mp.weixin.qq.com/s/YSuLIAYyRGlyxbp9BNC1uw),可能会给大家一种贪心算法比较简单的错觉,好了,接下来几天的题目难度要上来了,哈哈。
|
||||
|
|
@ -138,12 +138,38 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def wiggleMaxLength(self, nums: List[int]) -> int:
|
||||
preC,curC,res = 0,0,1 #题目里nums长度大于等于1,当长度为1时,其实到不了for循环里去,所以不用考虑nums长度
|
||||
for i in range(len(nums) - 1):
|
||||
curC = nums[i + 1] - nums[i]
|
||||
if curC * preC <= 0 and curC !=0: #差值为0时,不算摆动
|
||||
res += 1
|
||||
preC = curC #如果当前差值和上一个差值为一正一负时,才需要用当前差值替代上一个差值
|
||||
return res
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
var wiggleMaxLength = function(nums) {
|
||||
if(nums.length <= 1) return nums.length
|
||||
let result = 1
|
||||
let preDiff = 0
|
||||
let curDiff = 0
|
||||
for(let i = 0; i <= nums.length; i++) {
|
||||
curDiff = nums[i + 1] - nums[i]
|
||||
if((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) {
|
||||
result++
|
||||
preDiff = curDiff
|
||||
}
|
||||
}
|
||||
return result
|
||||
};
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 动态规划:Carl称它为排列总和!
|
||||
|
||||
## 377. 组合总和 Ⅳ
|
||||
|
|
@ -163,7 +163,7 @@ class Solution {
|
|||
return dp[target];
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
|
@ -183,7 +183,23 @@ class Solution:
|
|||
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
func combinationSum4(nums []int, target int) int {
|
||||
//定义dp数组
|
||||
dp := make([]int, target+1)
|
||||
// 初始化
|
||||
dp[0] = 1
|
||||
// 遍历顺序, 先遍历背包,再循环遍历物品
|
||||
for j:=0;j<=target;j++ {
|
||||
for i:=0 ;i < len(nums);i++ {
|
||||
if j >= nums[i] {
|
||||
dp[j] += dp[j-nums[i]]
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[target]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -26,9 +26,9 @@ canConstruct("a", "b") -> false
|
|||
canConstruct("aa", "ab") -> false
|
||||
canConstruct("aa", "aab") -> true
|
||||
|
||||
# 思路
|
||||
## 思路
|
||||
|
||||
这道题目和[242.有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)很像,[242.有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)相当于求 字符串a 和 字符串b 是否可以相互组成 ,而这道题目是求 字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。
|
||||
这道题目和[242.有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA)很像,[242.有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA)相当于求 字符串a 和 字符串b 是否可以相互组成 ,而这道题目是求 字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。
|
||||
|
||||
本题判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成,但是这里需要注意两点。
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ canConstruct("aa", "aab") -> true
|
|||
|
||||
* 第二点 “你可以假设两个字符串均只含有小写字母。” *说明只有小写字母*,这一点很重要
|
||||
|
||||
# 暴力解法
|
||||
## 暴力解法
|
||||
|
||||
那么第一个思路其实就是暴力枚举了,两层for循环,不断去寻找,代码如下:
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ public:
|
|||
这里时间复杂度是比较高的,而且里面还有一个字符串删除也就是erase的操作,也是费时的,当然这段代码也可以过这道题。
|
||||
|
||||
|
||||
# 哈希解法
|
||||
## 哈希解法
|
||||
|
||||
因为题目所只有小写字母,那可以采用空间换取时间的哈希策略, 用一个长度为26的数组还记录magazine里字母出现的次数。
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ public:
|
|||
|
||||
依然是数组在哈希法中的应用。
|
||||
|
||||
一些同学可能想,用数组干啥,都用map完事了,**其实在本题的情况下,使用map的空间消耗要比数组大一些的,因为map要维护红黑树或者哈希表,而且还要做哈希函数。 所以数组更加简单直接有效!**
|
||||
一些同学可能想,用数组干啥,都用map完事了,**其实在本题的情况下,使用map的空间消耗要比数组大一些的,因为map要维护红黑树或者哈希表,而且还要做哈希函数,是费时的!数据量大的话就能体现出来差别了。 所以数组更加简单直接有效!**
|
||||
|
||||
代码如下:
|
||||
|
||||
|
|
@ -105,8 +105,6 @@ public:
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
|
|
@ -138,10 +136,74 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
```py
|
||||
class Solution(object):
|
||||
def canConstruct(self, ransomNote, magazine):
|
||||
"""
|
||||
:type ransomNote: str
|
||||
:type magazine: str
|
||||
:rtype: bool
|
||||
"""
|
||||
|
||||
# use a dict to store the number of letter occurance in ransomNote
|
||||
hashmap = dict()
|
||||
for s in ransomNote:
|
||||
if s in hashmap:
|
||||
hashmap[s] += 1
|
||||
else:
|
||||
hashmap[s] = 1
|
||||
|
||||
# check if the letter we need can be found in magazine
|
||||
for l in magazine:
|
||||
if l in hashmap:
|
||||
hashmap[l] -= 1
|
||||
|
||||
for key in hashmap:
|
||||
if hashmap[key] > 0:
|
||||
return False
|
||||
|
||||
return True
|
||||
```
|
||||
|
||||
Go:
|
||||
```go
|
||||
func canConstruct(ransomNote string, magazine string) bool {
|
||||
record := make([]int, 26)
|
||||
for _, v := range magazine {
|
||||
record[v-'a']++
|
||||
}
|
||||
for _, v := range ransomNote {
|
||||
record[v-'a']--
|
||||
if record[v-'a'] < 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {string} ransomNote
|
||||
* @param {string} magazine
|
||||
* @return {boolean}
|
||||
*/
|
||||
var canConstruct = function(ransomNote, magazine) {
|
||||
const strArr = new Array(26).fill(0),
|
||||
base = "a".charCodeAt();
|
||||
for(const s of magazine) {
|
||||
strArr[s.charCodeAt() - base]++;
|
||||
}
|
||||
for(const s of ransomNote) {
|
||||
const index = s.charCodeAt() - base;
|
||||
if(!strArr[index]) return false;
|
||||
strArr[index]--;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 392.判断子序列
|
||||
|
|
@ -144,7 +144,20 @@ Java:
|
|||
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def isSubsequence(self, s: str, t: str) -> bool:
|
||||
dp = [[0] * (len(t)+1) for _ in range(len(s)+1)]
|
||||
for i in range(1, len(s)+1):
|
||||
for j in range(1, len(t)+1):
|
||||
if s[i-1] == t[j-1]:
|
||||
dp[i][j] = dp[i-1][j-1] + 1
|
||||
else:
|
||||
dp[i][j] = dp[i][j-1]
|
||||
if dp[-1][-1] == len(s):
|
||||
return True
|
||||
return False
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 404.左叶子之和
|
||||
|
|
@ -205,10 +205,139 @@ class Solution {
|
|||
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```Python
|
||||
**递归**
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
class Solution:
|
||||
def sumOfLeftLeaves(self, root: TreeNode) -> int:
|
||||
self.res=0
|
||||
def areleftleaves(root):
|
||||
if not root:return
|
||||
if root.left and (not root.left.left) and (not root.left.right):self.res+=root.left.val
|
||||
areleftleaves(root.left)
|
||||
areleftleaves(root.right)
|
||||
areleftleaves(root)
|
||||
return self.res
|
||||
```
|
||||
Go:
|
||||
|
||||
> 递归法
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
func sumOfLeftLeaves(root *TreeNode) int {
|
||||
var res int
|
||||
findLeft(root,&res)
|
||||
return res
|
||||
}
|
||||
func findLeft(root *TreeNode,res *int){
|
||||
//左节点
|
||||
if root.Left!=nil&&root.Left.Left==nil&&root.Left.Right==nil{
|
||||
*res=*res+root.Left.Val
|
||||
}
|
||||
if root.Left!=nil{
|
||||
findLeft(root.Left,res)
|
||||
}
|
||||
if root.Right!=nil{
|
||||
findLeft(root.Right,res)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> 迭代法
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
func sumOfLeftLeaves(root *TreeNode) int {
|
||||
var res int
|
||||
queue:=list.New()
|
||||
queue.PushBack(root)
|
||||
for queue.Len()>0{
|
||||
length:=queue.Len()
|
||||
for i:=0;i<length;i++{
|
||||
node:=queue.Remove(queue.Front()).(*TreeNode)
|
||||
if node.Left!=nil&&node.Left.Left==nil&&node.Left.Right==nil{
|
||||
res=res+node.Left.Val
|
||||
}
|
||||
if node.Left!=nil{
|
||||
queue.PushBack(node.Left)
|
||||
}
|
||||
if node.Right!=nil{
|
||||
queue.PushBack(node.Right)
|
||||
}
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
JavaScript:
|
||||
递归版本
|
||||
```javascript
|
||||
var sumOfLeftLeaves = function(root) {
|
||||
//采用后序遍历 递归遍历
|
||||
// 1. 确定递归函数参数
|
||||
const nodesSum = function(node){
|
||||
// 2. 确定终止条件
|
||||
if(node===null){
|
||||
return 0;
|
||||
}
|
||||
let leftValue = sumOfLeftLeaves(node.left);
|
||||
let rightValue = sumOfLeftLeaves(node.right);
|
||||
// 3. 单层递归逻辑
|
||||
let midValue = 0;
|
||||
if(node.left&&node.left.left===null&&node.left.right===null){
|
||||
midValue = node.left.val;
|
||||
}
|
||||
let sum = midValue + leftValue + rightValue;
|
||||
return sum;
|
||||
}
|
||||
return nodesSum(root);
|
||||
};
|
||||
```
|
||||
迭代版本
|
||||
```javascript
|
||||
var sumOfLeftLeaves = function(root) {
|
||||
//采用层序遍历
|
||||
if(root===null){
|
||||
return null;
|
||||
}
|
||||
let queue = [];
|
||||
let sum = 0;
|
||||
queue.push(root);
|
||||
while(queue.length){
|
||||
let node = queue.shift();
|
||||
if(node.left!==null&&node.left.left===null&&node.left.right===null){
|
||||
sum+=node.left.val;
|
||||
}
|
||||
node.left&&queue.push(node.left);
|
||||
node.right&&queue.push(node.right);
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -216,6 +345,4 @@ Go:
|
|||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
|
||||
|
||||
<div align="center"><img src=../pics/公众号.png width=450 alt=> </img></div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 406.根据身高重建队列
|
||||
|
|
@ -211,11 +211,40 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
|
||||
people.sort(key=lambda x: (x[0], -x[1]), reverse=True)
|
||||
que = []
|
||||
for p in people:
|
||||
if p[1] > len(que):
|
||||
que.append(p)
|
||||
else:
|
||||
que.insert(p[1], p)
|
||||
return que
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
var reconstructQueue = function(people) {
|
||||
let queue = []
|
||||
people.sort((a, b ) => {
|
||||
if(b[0] !== a[0]) {
|
||||
return b[0] - a[0]
|
||||
} else {
|
||||
return a[1] - b[1]
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
for(let i = 0; i < people.length; i++) {
|
||||
queue.splice(people[i][1], 0, people[i])
|
||||
}
|
||||
return queue
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 动态规划:分割等和子集可以用01背包!
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 416. 分割等和子集
|
||||
|
||||
|
|
@ -29,6 +28,10 @@
|
|||
输出: false
|
||||
解释: 数组不能分割成两个元素和相等的子集.
|
||||
|
||||
提示:
|
||||
* 1 <= nums.length <= 200
|
||||
* 1 <= nums[i] <= 100
|
||||
|
||||
## 思路
|
||||
|
||||
这道题目初步看,是如下两题几乎是一样的,大家可以用回溯法,解决如下两题
|
||||
|
|
@ -174,7 +177,7 @@ public:
|
|||
|
||||
这道题目就是一道01背包应用类的题目,需要我们拆解题目,然后套入01背包的场景。
|
||||
|
||||
01背包相对于本题,主要要理解,题目中物品是nums[i],重量是nums[i]i,价值也是nums[i],背包体积是sum/2。
|
||||
01背包相对于本题,主要要理解,题目中物品是nums[i],重量是nums[i],价值也是nums[i],背包体积是sum/2。
|
||||
|
||||
看代码的话,就可以发现,基本就是按照01背包的写法来的。
|
||||
|
||||
|
|
@ -222,8 +225,18 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def canPartition(self, nums: List[int]) -> bool:
|
||||
taraget = sum(nums)
|
||||
if taraget % 2 == 1: return False
|
||||
taraget //= 2
|
||||
dp = [0] * 10001
|
||||
for i in range(len(nums)):
|
||||
for j in range(taraget, nums[i] - 1, -1):
|
||||
dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
|
||||
return taraget == dp[taraget]
|
||||
```
|
||||
Go:
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 435. 无重叠区间
|
||||
|
|
@ -212,7 +212,19 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def eraseOverlapIntervals(self, intervals: List[List[int]]) -> int:
|
||||
if len(intervals) == 0: return 0
|
||||
intervals.sort(key=lambda x: x[1])
|
||||
count = 1 # 记录非交叉区间的个数
|
||||
end = intervals[0][1] # 记录区间分割点
|
||||
for i in range(1, len(intervals)):
|
||||
if end <= intervals[i][0]:
|
||||
count += 1
|
||||
end = intervals[i][1]
|
||||
return len(intervals) - count
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 二叉搜索树删除节点就涉及到结构调整了
|
||||
|
|
@ -281,7 +281,43 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
class Solution:
|
||||
def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
|
||||
if not root: return root #第一种情况:没找到删除的节点,遍历到空节点直接返回了
|
||||
if root.val == key:
|
||||
if not root.left and not root.right: #第二种情况:左右孩子都为空(叶子节点),直接删除节点, 返回NULL为根节点
|
||||
del root
|
||||
return None
|
||||
if not root.left and root.right: #第三种情况:其左孩子为空,右孩子不为空,删除节点,右孩子补位 ,返回右孩子为根节点
|
||||
tmp = root
|
||||
root = root.right
|
||||
del tmp
|
||||
return root
|
||||
if root.left and not root.right: #第四种情况:其右孩子为空,左孩子不为空,删除节点,左孩子补位,返回左孩子为根节点
|
||||
tmp = root
|
||||
root = root.left
|
||||
del tmp
|
||||
return root
|
||||
else: #第五种情况:左右孩子节点都不为空,则将删除节点的左子树放到删除节点的右子树的最左面节点的左孩子的位置
|
||||
v = root.right
|
||||
while v.left:
|
||||
v = v.left
|
||||
v.left = root.left
|
||||
tmp = root
|
||||
root = root.right
|
||||
del tmp
|
||||
return root
|
||||
if root.val > key: root.left = self.deleteNode(root.left,key) #左递归
|
||||
if root.val < key: root.right = self.deleteNode(root.right,key) #右递归
|
||||
return root
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 452. 用最少数量的箭引爆气球
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
|
||||
其实都可以!只不过对应的遍历顺序不同,我就按照气球的起始位置排序了。
|
||||
|
||||
既然按照其实位置排序,那么就从前向后遍历气球数组,靠左尽可能让气球重复。
|
||||
既然按照起始位置排序,那么就从前向后遍历气球数组,靠左尽可能让气球重复。
|
||||
|
||||
从前向后遍历遇到重叠的气球了怎么办?
|
||||
|
||||
|
|
@ -142,16 +142,8 @@ Java:
|
|||
```java
|
||||
class Solution {
|
||||
public int findMinArrowShots(int[][] points) {
|
||||
Arrays.sort(points, new Comparator<int[]>() {
|
||||
@Override
|
||||
public int compare(int[] o1, int[] o2) {
|
||||
if (o1[0] != o2[0]) {
|
||||
return Integer.compare(o1[0],o2[0]);
|
||||
} else {
|
||||
return Integer.compare(o1[0],o2[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (points.length == 0) return 0;
|
||||
Arrays.sort(points, (o1, o2) -> Integer.compare(o1[0], o2[0]));
|
||||
|
||||
int count = 1;
|
||||
for (int i = 1; i < points.length; i++) {
|
||||
|
|
@ -167,11 +159,40 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def findMinArrowShots(self, points: List[List[int]]) -> int:
|
||||
if len(points) == 0: return 0
|
||||
points.sort(key=lambda x: x[0])
|
||||
result = 1
|
||||
for i in range(1, len(points)):
|
||||
if points[i][0] > points[i - 1][1]: # 气球i和气球i-1不挨着,注意这里不是>=
|
||||
result += 1
|
||||
else:
|
||||
points[i][1] = min(points[i - 1][1], points[i][1]) # 更新重叠气球最小右边界
|
||||
return result
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
var findMinArrowShots = function(points) {
|
||||
points.sort((a, b) => {
|
||||
return a[0] - b[0]
|
||||
})
|
||||
let result = 1
|
||||
for(let i = 1; i < points.length; i++) {
|
||||
if(points[i][0] > points[i - 1][1]) {
|
||||
result++
|
||||
} else {
|
||||
points[i][1] = Math.min(points[i - 1][1], points[i][1])
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 需要哈希的地方都能找到map的身影
|
||||
|
||||
# 第454题.四数相加II
|
||||
|
||||
|
||||
https://leetcode-cn.com/problems/4sum-ii/
|
||||
|
||||
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
|
||||
|
|
@ -24,10 +25,8 @@ A = [ 1, 2]
|
|||
B = [-2,-1]
|
||||
C = [-1, 2]
|
||||
D = [ 0, 2]
|
||||
|
||||
输出:
|
||||
2
|
||||
|
||||
**解释:**
|
||||
两个元组如下:
|
||||
1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
|
||||
|
|
@ -121,8 +120,88 @@ class Solution {
|
|||
|
||||
Python:
|
||||
|
||||
```
|
||||
class Solution(object):
|
||||
def fourSumCount(self, nums1, nums2, nums3, nums4):
|
||||
"""
|
||||
:type nums1: List[int]
|
||||
:type nums2: List[int]
|
||||
:type nums3: List[int]
|
||||
:type nums4: List[int]
|
||||
:rtype: int
|
||||
"""
|
||||
# use a dict to store the elements in nums1 and nums2 and their sum
|
||||
hashmap = dict()
|
||||
for n1 in nums1:
|
||||
for n2 in nums2:
|
||||
if n1 + n2 in hashmap:
|
||||
hashmap[n1+n2] += 1
|
||||
else:
|
||||
hashmap[n1+n2] = 1
|
||||
|
||||
# if the -(a+b) exists in nums3 and nums4, we shall add the count
|
||||
count = 0
|
||||
for n3 in nums3:
|
||||
for n4 in nums4:
|
||||
key = - n3 - n4
|
||||
if key in hashmap:
|
||||
count += hashmap[key]
|
||||
return count
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
Go:
|
||||
```go
|
||||
func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {
|
||||
m := make(map[int]int)
|
||||
count := 0
|
||||
for _, v1 := range nums1 {
|
||||
for _, v2 := range nums2 {
|
||||
m[v1+v2]++
|
||||
}
|
||||
}
|
||||
for _, v3 := range nums3 {
|
||||
for _, v4 := range nums4 {
|
||||
count += m[-v3-v4]
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
```
|
||||
|
||||
javaScript:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {number[]} nums1
|
||||
* @param {number[]} nums2
|
||||
* @param {number[]} nums3
|
||||
* @param {number[]} nums4
|
||||
* @return {number}
|
||||
*/
|
||||
var fourSumCount = function(nums1, nums2, nums3, nums4) {
|
||||
const twoSumMap = new Map();
|
||||
let count = 0;
|
||||
|
||||
for(const n1 of nums1) {
|
||||
for(const n2 of nums2) {
|
||||
const sum = n1 + n2;
|
||||
twoSumMap.set(sum, (twoSumMap.get(sum) || 0) + 1)
|
||||
}
|
||||
}
|
||||
|
||||
for(const n3 of nums3) {
|
||||
for(const n4 of nums4) {
|
||||
const sum = n3 + n4;
|
||||
count += (twoSumMap.get(0 - sum) || 0)
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
## 455.分发饼干
|
||||
|
|
@ -134,11 +134,37 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def findContentChildren(self, g: List[int], s: List[int]) -> int:
|
||||
g.sort()
|
||||
s.sort()
|
||||
res = 0
|
||||
for i in range(len(s)):
|
||||
if res <len(g) and s[i] >= g[res]: #小饼干先喂饱小胃口
|
||||
res += 1
|
||||
return res
|
||||
```
|
||||
Go:
|
||||
|
||||
Javascript:
|
||||
```Javascript
|
||||
|
||||
var findContentChildren = function(g, s) {
|
||||
g = g.sort((a, b) => a - b)
|
||||
s = s.sort((a, b) => a - b)
|
||||
let result = 0
|
||||
let index = s.length - 1
|
||||
for(let i = g.length - 1; i >= 0; i--) {
|
||||
if(index >= 0 && s[index] >= g[i]) {
|
||||
result++
|
||||
index--
|
||||
}
|
||||
}
|
||||
return result
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
|
||||
|
|
@ -149,15 +149,151 @@ public:
|
|||
|
||||
## 其他语言版本
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public boolean repeatedSubstringPattern(String s) {
|
||||
if (s.equals("")) return false;
|
||||
|
||||
int len = s.length();
|
||||
// 原串加个空格(哨兵),使下标从1开始,这样j从0开始,也不用初始化了
|
||||
s = " " + s;
|
||||
char[] chars = s.toCharArray();
|
||||
int[] next = new int[len + 1];
|
||||
|
||||
// 构造 next 数组过程,j从0开始(空格),i从2开始
|
||||
for (int i = 2, j = 0; i <= len; i++) {
|
||||
// 匹配不成功,j回到前一位置 next 数组所对应的值
|
||||
while (j > 0 && chars[i] != chars[j + 1]) j = next[j];
|
||||
// 匹配成功,j往后移
|
||||
if (chars[i] == chars[j + 1]) j++;
|
||||
// 更新 next 数组的值
|
||||
next[i] = j;
|
||||
}
|
||||
|
||||
// 最后判断是否是重复的子字符串,这里 next[len] 即代表next数组末尾的值
|
||||
if (next[len] > 0 && len % (len - next[len]) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Python:
|
||||
|
||||
这里使用了前缀表统一减一的实现方式
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def repeatedSubstringPattern(self, s: str) -> bool:
|
||||
if len(s) == 0:
|
||||
return False
|
||||
nxt = [0] * len(s)
|
||||
self.getNext(nxt, s)
|
||||
if nxt[-1] != -1 and len(s) % (len(s) - (nxt[-1] + 1)) == 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def getNext(self, nxt, s):
|
||||
nxt[0] = -1
|
||||
j = -1
|
||||
for i in range(1, len(s)):
|
||||
while j >= 0 and s[i] != s[j+1]:
|
||||
j = nxt[j]
|
||||
if s[i] == s[j+1]:
|
||||
j += 1
|
||||
nxt[i] = j
|
||||
return nxt
|
||||
```
|
||||
|
||||
前缀表(不减一)的代码实现
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def repeatedSubstringPattern(self, s: str) -> bool:
|
||||
if len(s) == 0:
|
||||
return False
|
||||
nxt = [0] * len(s)
|
||||
self.getNext(nxt, s)
|
||||
if nxt[-1] != 0 and len(s) % (len(s) - nxt[-1]) == 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def getNext(self, nxt, s):
|
||||
nxt[0] = 0
|
||||
j = 0
|
||||
for i in range(1, len(s)):
|
||||
while j > 0 and s[i] != s[j]:
|
||||
j = nxt[j - 1]
|
||||
if s[i] == s[j]:
|
||||
j += 1
|
||||
nxt[i] = j
|
||||
return nxt
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
这里使用了前缀表统一减一的实现方式
|
||||
|
||||
```go
|
||||
func repeatedSubstringPattern(s string) bool {
|
||||
n := len(s)
|
||||
if n == 0 {
|
||||
return false
|
||||
}
|
||||
next := make([]int, n)
|
||||
j := -1
|
||||
next[0] = j
|
||||
for i := 1; i < n; i++ {
|
||||
for j >= 0 && s[i] != s[j+1] {
|
||||
j = next[j]
|
||||
}
|
||||
if s[i] == s[j+1] {
|
||||
j++
|
||||
}
|
||||
next[i] = j
|
||||
}
|
||||
// next[n-1]+1 最长相同前后缀的长度
|
||||
if next[n-1] != -1 && n%(n-(next[n-1]+1)) == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
```
|
||||
|
||||
前缀表(不减一)的代码实现
|
||||
|
||||
```go
|
||||
func repeatedSubstringPattern(s string) bool {
|
||||
n := len(s)
|
||||
if n == 0 {
|
||||
return false
|
||||
}
|
||||
j := 0
|
||||
next := make([]int, n)
|
||||
next[0] = j
|
||||
for i := 1; i < n; i++ {
|
||||
for j > 0 && s[i] != s[j] {
|
||||
j = next[j-1]
|
||||
}
|
||||
if s[i] == s[j] {
|
||||
j++
|
||||
}
|
||||
next[i] = j
|
||||
}
|
||||
// next[n-1] 最长相同前后缀的长度
|
||||
if next[n-1] != 0 && n%(n-next[n-1]) == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 动态规划:一和零!
|
||||
|
||||
## 474.一和零
|
||||
|
|
@ -190,10 +190,59 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
|
||||
dp = [[0] * (n + 1) for _ in range(m + 1)] # 默认初始化0
|
||||
# 遍历物品
|
||||
for str in strs:
|
||||
ones = str.count('1')
|
||||
zeros = str.count('0')
|
||||
# 遍历背包容量且从后向前遍历!
|
||||
for i in range(m, zeros - 1, -1):
|
||||
for j in range(n, ones - 1, -1):
|
||||
dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1)
|
||||
return dp[m][n]
|
||||
```
|
||||
|
||||
Go:
|
||||
```go
|
||||
func findMaxForm(strs []string, m int, n int) int {
|
||||
// 定义数组
|
||||
dp := make([][]int, m+1)
|
||||
for i,_ := range dp {
|
||||
dp[i] = make([]int, n+1 )
|
||||
}
|
||||
// 遍历
|
||||
for i:=0;i<len(strs);i++ {
|
||||
zeroNum,oneNum := 0 , 0
|
||||
//计算0,1 个数
|
||||
//或者直接strings.Count(strs[i],"0")
|
||||
for _,v := range strs[i] {
|
||||
if v == '0' {
|
||||
zeroNum++
|
||||
}
|
||||
}
|
||||
oneNum = len(strs[i])-zeroNum
|
||||
// 从后往前 遍历背包容量
|
||||
for j:= m ; j >= zeroNum;j-- {
|
||||
for k:=n ; k >= oneNum;k-- {
|
||||
// 推导公式
|
||||
dp[j][k] = max(dp[j][k],dp[j-zeroNum][k-oneNum]+1)
|
||||
}
|
||||
}
|
||||
//fmt.Println(dp)
|
||||
}
|
||||
return dp[m][n]
|
||||
}
|
||||
|
||||
func max(a,b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 和子集问题有点像,但又处处是陷阱
|
||||
|
|
@ -229,10 +229,59 @@ class Solution {
|
|||
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def findSubsequences(self, nums: List[int]) -> List[List[int]]:
|
||||
res = []
|
||||
path = []
|
||||
def backtrack(nums,startIndex):
|
||||
repeat = [] #这里使用数组来进行去重操作
|
||||
if len(path) >=2:
|
||||
res.append(path[:]) #注意这里不要加return,要取树上的节点
|
||||
for i in range(startIndex,len(nums)):
|
||||
if nums[i] in repeat:
|
||||
continue
|
||||
if len(path) >= 1:
|
||||
if nums[i] < path[-1]:
|
||||
continue
|
||||
repeat.append(nums[i]) #记录这个元素在本层用过了,本层后面不能再用了
|
||||
path.append(nums[i])
|
||||
backtrack(nums,i+1)
|
||||
path.pop()
|
||||
backtrack(nums,0)
|
||||
return res
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
Javascript:
|
||||
|
||||
```Javascript
|
||||
|
||||
var findSubsequences = function(nums) {
|
||||
let result = []
|
||||
let path = []
|
||||
function backtracing(startIndex) {
|
||||
if(path.length > 1) {
|
||||
result.push(path.slice())
|
||||
}
|
||||
let uset = []
|
||||
for(let i = startIndex; i < nums.length; i++) {
|
||||
if((path.length > 0 && nums[i] < path[path.length - 1]) || uset[nums[i] + 100]) {
|
||||
continue
|
||||
}
|
||||
uset[nums[i] + 100] = true
|
||||
path.push(nums[i])
|
||||
backtracing(i + 1)
|
||||
path.pop()
|
||||
}
|
||||
}
|
||||
backtracing(0)
|
||||
return result
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
# 动态规划:目标和!
|
||||
|
||||
## 494. 目标和
|
||||
|
|
@ -21,8 +21,8 @@
|
|||
|
||||
输入:nums: [1, 1, 1, 1, 1], S: 3
|
||||
输出:5
|
||||
解释:
|
||||
|
||||
解释:
|
||||
-1+1+1+1+1 = 3
|
||||
+1-1+1+1+1 = 3
|
||||
+1+1-1+1+1 = 3
|
||||
|
|
@ -150,7 +150,7 @@ dp[j] 表示:填满j(包括j)这么大容积的包,有dp[i]种方法
|
|||
|
||||
有哪些来源可以推出dp[j]呢?
|
||||
|
||||
不考虑nums[i]的情况下,填满容量为j - nums[i]的背包,有dp[j - nums[i]]中方法。
|
||||
不考虑nums[i]的情况下,填满容量为j - nums[i]的背包,有dp[j - nums[i]]种方法。
|
||||
|
||||
那么只要搞到nums[i]的话,凑成dp[j]就有dp[j - nums[i]] 种方法。
|
||||
|
||||
|
|
@ -225,7 +225,7 @@ public:
|
|||
|
||||
是的,如果仅仅是求个数的话,就可以用dp,但[回溯算法:39. 组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)要求的是把所有组合列出来,还是要使用回溯法爆搜的。
|
||||
|
||||
本地还是有点难度,大家也可以记住,在求装满背包有几种方法的情况下,递推公式一般为:
|
||||
本题还是有点难度,大家也可以记住,在求装满背包有几种方法的情况下,递推公式一般为:
|
||||
|
||||
```
|
||||
dp[j] += dp[j - nums[i]];
|
||||
|
|
@ -261,10 +261,50 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def findTargetSumWays(self, nums: List[int], target: int) -> int:
|
||||
sumValue = sum(nums)
|
||||
if target > sumValue or (sumValue + target) % 2 == 1: return 0
|
||||
bagSize = (sumValue + target) // 2
|
||||
dp = [0] * (bagSize + 1)
|
||||
dp[0] = 1
|
||||
for i in range(len(nums)):
|
||||
for j in range(bagSize, nums[i] - 1, -1):
|
||||
dp[j] += dp[j - nums[i]]
|
||||
return dp[bagSize]
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
```go
|
||||
func findTargetSumWays(nums []int, target int) int {
|
||||
sum := 0
|
||||
for _, v := range nums {
|
||||
sum += v
|
||||
}
|
||||
if target > sum {
|
||||
return 0
|
||||
}
|
||||
if (sum+target)%2 == 1 {
|
||||
return 0
|
||||
}
|
||||
// 计算背包大小
|
||||
bag := (sum + target) / 2
|
||||
// 定义dp数组
|
||||
dp := make([]int, bag+1)
|
||||
// 初始化
|
||||
dp[0] = 1
|
||||
// 遍历顺序
|
||||
for i := 0; i < len(nums); i++ {
|
||||
for j := bag; j >= nums[i]; j-- {
|
||||
//推导公式
|
||||
dp[j] += dp[j-nums[i]]
|
||||
//fmt.Println(dp)
|
||||
}
|
||||
}
|
||||
return dp[bag]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
|
||||
> 二叉树上应该怎么求,二叉搜索树上又应该怎么求?
|
||||
|
|
@ -394,8 +394,39 @@ class Solution {
|
|||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
||||
```python
|
||||
# Definition for a binary tree node.
|
||||
# class TreeNode:
|
||||
# def __init__(self, val=0, left=None, right=None):
|
||||
# self.val = val
|
||||
# self.left = left
|
||||
# self.right = right
|
||||
//递归法
|
||||
class Solution:
|
||||
def findMode(self, root: TreeNode) -> List[int]:
|
||||
if not root: return
|
||||
self.pre = root
|
||||
self.count = 0 //统计频率
|
||||
self.countMax = 0 //最大频率
|
||||
self.res = []
|
||||
def findNumber(root):
|
||||
if not root: return None // 第一个节点
|
||||
findNumber(root.left) //左
|
||||
if self.pre.val == root.val: //中: 与前一个节点数值相同
|
||||
self.count += 1
|
||||
else: // 与前一个节点数值不同
|
||||
self.pre = root
|
||||
self.count = 1
|
||||
if self.count > self.countMax: // 如果计数大于最大值频率
|
||||
self.countMax = self.count // 更新最大频率
|
||||
self.res = [root.val] //更新res
|
||||
elif self.count == self.countMax: // 如果和最大值相同,放进res中
|
||||
self.res.append(root.val)
|
||||
findNumber(root.right) //右
|
||||
return
|
||||
findNumber(root)
|
||||
return self.res
|
||||
```
|
||||
Go:
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
<p align="center">
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ"><img src="https://img.shields.io/badge/PDF下载-代码随想录-blueviolet" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||
</p>
|
||||
<p align="center"><strong>欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
<p align="center"><strong>欢迎大家<a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||
|
||||
## 509. 斐波那契数
|
||||
|
||||
|
|
@ -171,12 +171,55 @@ public:
|
|||
|
||||
|
||||
Java:
|
||||
|
||||
```Java
|
||||
class Solution {
|
||||
public int fib(int n) {
|
||||
if (n < 2) return n;
|
||||
int a = 0, b = 1, c = 0;
|
||||
for (int i = 1; i < n; i++) {
|
||||
c = a + b;
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
```python3
|
||||
class Solution:
|
||||
def fib(self, n: int) -> int:
|
||||
if n < 2:
|
||||
return n
|
||||
a, b, c = 0, 1, 0
|
||||
for i in range(1, n):
|
||||
c = a + b
|
||||
a, b = b, c
|
||||
return c
|
||||
|
||||
# 递归实现
|
||||
class Solution:
|
||||
def fib(self, n: int) -> int:
|
||||
if n < 2:
|
||||
return n
|
||||
return self.fib(n - 1) + self.fib(n - 2)
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
func fib(n int) int {
|
||||
if n < 2 {
|
||||
return n
|
||||
}
|
||||
a, b, c := 0, 1, 0
|
||||
for i := 1; i < n; i++ {
|
||||
c = a + b
|
||||
a, b = b, c
|
||||
}
|
||||
return c
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue