diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md index d6b55fd6..ea7502b1 100644 --- a/problems/0018.四数之和.md +++ b/problems/0018.四数之和.md @@ -74,7 +74,7 @@ public: sort(nums.begin(), nums.end()); for (int k = 0; k < nums.size(); k++) { // 剪枝处理 - if (nums[k] > target && nums[k] >= 0 && target >= 0) { + if (nums[k] > target && nums[k] >= 0) { break; // 这里使用break,统一通过最后的return返回 } // 对nums[k]去重 @@ -83,7 +83,7 @@ public: } for (int i = k + 1; i < nums.size(); i++) { // 2级剪枝处理 - if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0 && target >= 0) { + if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) { break; } diff --git a/problems/0019.删除链表的倒数第N个节点.md b/problems/0019.删除链表的倒数第N个节点.md index 3499ab9d..65a4e383 100644 --- a/problems/0019.删除链表的倒数第N个节点.md +++ b/problems/0019.删除链表的倒数第N个节点.md @@ -33,6 +33,9 @@ ## 思路 +《代码随想录》算法公开课:[链表遍历学清楚! | LeetCode:19.删除链表倒数第N个节点](https://www.bilibili.com/video/BV1vW4y1U7Gf),相信结合视频在看本篇题解,更有助于大家对链表的理解。 + + 双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。 思路是这样的,但要注意一些细节。 diff --git a/problems/0020.有效的括号.md b/problems/0020.有效的括号.md index eaf0a719..3c7da61b 100644 --- a/problems/0020.有效的括号.md +++ b/problems/0020.有效的括号.md @@ -41,6 +41,9 @@ # 思路 +《代码随想录》算法视频公开课:[栈的拿手好戏!| LeetCode:20. 有效的括号](https://www.bilibili.com/video/BV1AF411w78g),相信结合视频在看本篇题解,更有助于大家对链表的理解。 + + ## 题外话 **括号匹配是使用栈解决的经典问题。** @@ -79,8 +82,10 @@ cd a/b/c/../../ 1. 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。 ![括号匹配1](https://img-blog.csdnimg.cn/2020080915505387.png) + 2. 第二种情况,括号没有多余,但是 括号的类型没有匹配上。 ![括号匹配2](https://img-blog.csdnimg.cn/20200809155107397.png) + 3. 第三种情况,字符串里右方向的括号多余了,所以不匹配。 ![括号匹配3](https://img-blog.csdnimg.cn/20200809155115779.png) @@ -110,7 +115,8 @@ cd a/b/c/../../ class Solution { public: bool isValid(string s) { - stack st; + if (s.size() % 2 != 0) return false; // 如果s的长度为奇数,一定不符合要求 + stack st; for (int i = 0; i < s.size(); i++) { if (s[i] == '(') st.push(')'); else if (s[i] == '{') st.push('}'); @@ -124,6 +130,7 @@ public: return st.empty(); } }; + ``` 技巧性的东西没有固定的学习方法,还是要多看多练,自己灵活运用了。 diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 4b4b39e7..905a0539 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -18,7 +18,8 @@ ## 思路 -针对本题重点难点,我录制了B站讲解视频,[帮你把链表细节学清楚! | LeetCode:24. 两两交换链表中的节点](https://www.bilibili.com/video/BV1YT411g7br),相信结合视频在看本篇题解,更有助于大家对链表的理解。 +《代码随想录》算法公开课:[帮你把链表细节学清楚! | LeetCode:24. 两两交换链表中的节点](https://www.bilibili.com/video/BV1YT411g7br),相信结合视频在看本篇题解,更有助于大家对链表的理解。 + 这道题目正常模拟就可以了。 diff --git a/problems/0053.最大子序和(动态规划).md b/problems/0053.最大子序和(动态规划).md index 228ceade..00f3eb84 100644 --- a/problems/0053.最大子序和(动态规划).md +++ b/problems/0053.最大子序和(动态规划).md @@ -4,7 +4,7 @@

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

-## 53. 最大子序和 +# 53. 最大子序和 [力扣题目链接](https://leetcode.cn/problems/maximum-subarray/) diff --git a/problems/0054.螺旋矩阵.md b/problems/0054.螺旋矩阵.md index 8f2691fe..efbda5ff 100644 --- a/problems/0054.螺旋矩阵.md +++ b/problems/0054.螺旋矩阵.md @@ -132,69 +132,6 @@ public: * [剑指Offer 29.顺时针打印矩阵](https://leetcode.cn/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/) ## 其他语言版本 -Python: -```python -class Solution: - def spiralOrder(self, matrix: List[List[int]]) -> List[int]: - m, n = len(matrix), len(matrix[0]) - left, right, up, down = 0, n - 1, 0, m - 1 # 定位四个方向的边界,闭区间 - res = [] - - while True: - for i in range(left, right + 1): # 上边,从左到右 - res.append(matrix[up][i]) - up += 1 # 上边界下移 - if len(res) >= m * n: # 判断是否已经遍历完 - break - - for i in range(up, down + 1): # 右边,从上到下 - res.append(matrix[i][right]) - right -= 1 # 右边界左移 - - if len(res) >= m * n: - break - - for i in range(right, left - 1, -1): # 下边,从右到左 - res.append(matrix[down][i]) - down -= 1 # 下边界上移 - - if len(res) >= m * n: - break - - for i in range(down, up - 1, -1): # 左边,从下到上 - res.append(matrix[i][left]) - left += 1 # 左边界右移 - - if len(res) >= m * n: - break - - return res -``` -```python3 -class Solution: - def spiralOrder(self, matrix: List[List[int]]) -> List[int]: - r=len(matrix) - if r == 0 or len(matrix[0])==0: - return [] - c=len(matrix[0]) - res=matrix[0] - - if r>1: - for i in range (1,r): - res.append(matrix[i][c-1]) - for j in range(c-2, -1, -1): - res.append(matrix[r-1][j]) - if c>1: - for i in range(r-2, 0, -1): - res.append(matrix[i][0]) - - M=[] - for k in range(1, r-1): - e=matrix[k][1:-1] - M.append(e) - - return res+self.spiralOrder(M) -``` -----------------------
diff --git a/problems/0072.编辑距离.md b/problems/0072.编辑距离.md index 641d3128..e40461de 100644 --- a/problems/0072.编辑距离.md +++ b/problems/0072.编辑距离.md @@ -4,7 +4,7 @@

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

-## 72. 编辑距离 +# 72. 编辑距离 [力扣题目链接](https://leetcode.cn/problems/edit-distance/) diff --git a/problems/0115.不同的子序列.md b/problems/0115.不同的子序列.md index 9ae04139..fe76c3ed 100644 --- a/problems/0115.不同的子序列.md +++ b/problems/0115.不同的子序列.md @@ -4,7 +4,7 @@

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

-## 115.不同的子序列 +# 115.不同的子序列 [力扣题目链接](https://leetcode.cn/problems/distinct-subsequences/) diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md index a577f1dd..868c0e3e 100644 --- a/problems/0121.买卖股票的最佳时机.md +++ b/problems/0121.买卖股票的最佳时机.md @@ -4,7 +4,7 @@

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

-## 121. 买卖股票的最佳时机 +# 121. 买卖股票的最佳时机 [力扣题目链接](https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/) diff --git a/problems/0122.买卖股票的最佳时机II(动态规划).md b/problems/0122.买卖股票的最佳时机II(动态规划).md index fa9f8842..98bf3e52 100644 --- a/problems/0122.买卖股票的最佳时机II(动态规划).md +++ b/problems/0122.买卖股票的最佳时机II(动态规划).md @@ -4,7 +4,7 @@

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

-## 122.买卖股票的最佳时机II +# 122.买卖股票的最佳时机II [力扣题目链接](https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/) diff --git a/problems/0123.买卖股票的最佳时机III.md b/problems/0123.买卖股票的最佳时机III.md index c15aaee8..947e6947 100644 --- a/problems/0123.买卖股票的最佳时机III.md +++ b/problems/0123.买卖股票的最佳时机III.md @@ -4,7 +4,7 @@

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

-## 123.买卖股票的最佳时机III +# 123.买卖股票的最佳时机III [力扣题目链接](https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/) diff --git a/problems/0142.环形链表II.md b/problems/0142.环形链表II.md index 0b9059dc..2054fd35 100644 --- a/problems/0142.环形链表II.md +++ b/problems/0142.环形链表II.md @@ -24,7 +24,8 @@ ## 思路 -为了易于大家理解,我录制讲解视频:[B站:把环形链表讲清楚! ](https://www.bilibili.com/video/BV1if4y1d7ob)。结合视频在看本篇题解,事半功倍。 +《代码随想录》算法公开课:[把环形链表讲清楚!| LeetCode:142.环形链表II](https://www.bilibili.com/video/BV1if4y1d7ob),相信结合视频在看本篇题解,更有助于大家对链表的理解。 + 这道题目,不仅考察对链表的操作,而且还需要一些数学运算。 diff --git a/problems/0188.买卖股票的最佳时机IV.md b/problems/0188.买卖股票的最佳时机IV.md index 7ff19852..8319fcba 100644 --- a/problems/0188.买卖股票的最佳时机IV.md +++ b/problems/0188.买卖股票的最佳时机IV.md @@ -4,7 +4,7 @@

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

-## 188.买卖股票的最佳时机IV +# 188.买卖股票的最佳时机IV [力扣题目链接](https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iv/) diff --git a/problems/0198.打家劫舍.md b/problems/0198.打家劫舍.md index ad660f27..6428359c 100644 --- a/problems/0198.打家劫舍.md +++ b/problems/0198.打家劫舍.md @@ -4,7 +4,7 @@

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

-## 198.打家劫舍 +# 198.打家劫舍 [力扣题目链接](https://leetcode.cn/problems/house-robber/) diff --git a/problems/0213.打家劫舍II.md b/problems/0213.打家劫舍II.md index d6b53a24..7ae7aae0 100644 --- a/problems/0213.打家劫舍II.md +++ b/problems/0213.打家劫舍II.md @@ -4,7 +4,7 @@

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

-## 213.打家劫舍II +# 213.打家劫舍II [力扣题目链接](https://leetcode.cn/problems/house-robber-ii/) diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md index 17c50cd9..fb2851f1 100644 --- a/problems/0225.用队列实现栈.md +++ b/problems/0225.用队列实现栈.md @@ -28,6 +28,10 @@ # 思路 + +《代码随想录》算法公开课:[队列的基本操作! | LeetCode:225. 用队列实现栈](https://www.bilibili.com/video/BV1Fd4y1K7sm),相信结合视频在看本篇题解,更有助于大家对链表的理解。 + + (这里要强调是单向队列) 有的同学可能疑惑这种题目有什么实际工程意义,**其实很多算法题目主要是对知识点的考察和教学意义远大于其工程实践的意义,所以面试题也是这样!** diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md index 4dc7b794..7364e6c1 100644 --- a/problems/0232.用栈实现队列.md +++ b/problems/0232.用栈实现队列.md @@ -38,6 +38,9 @@ queue.empty(); // 返回 false ## 思路 +《代码随想录》算法公开课:[栈的基本操作! | LeetCode:232.用栈实现队列](https://www.bilibili.com/video/BV1nY4y1w7VC),相信结合视频在看本篇题解,更有助于大家对链表的理解。 + + 这是一道模拟题,不涉及到具体算法,考察的就是对栈和队列的掌握程度。 使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈**一个输入栈,一个输出栈**,这里要注意输入栈和输出栈的关系。 @@ -170,14 +173,6 @@ class MyQueue { } } -/** - * Your MyQueue object will be instantiated and called as such: - * MyQueue obj = new MyQueue(); - * obj.push(x); - * int param_2 = obj.pop(); - * int param_3 = obj.peek(); - * boolean param_4 = obj.empty(); - */ ``` diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md index 474b3a75..6ec98506 100644 --- a/problems/0239.滑动窗口最大值.md +++ b/problems/0239.滑动窗口最大值.md @@ -36,7 +36,7 @@ 难点是如何求一个区间里的最大值呢? (这好像是废话),暴力一下不就得了。 -暴力方法,遍历一遍的过程中每次从窗口中在找到最大的数值,这样很明显是$O(n × k)$的算法。 +暴力方法,遍历一遍的过程中每次从窗口中在找到最大的数值,这样很明显是O(n × k)的算法。 有的同学可能会想用一个大顶堆(优先级队列)来存放这个窗口里的k个数字,这样就可以知道最大的最大值是多少了, **但是问题是这个窗口是移动的,而大顶堆每次只能弹出最大值,我们无法移除其他数值,这样就造成大顶堆维护的不是滑动窗口里面的数值了。所以不能用大顶堆。** @@ -183,13 +183,13 @@ public: }; ``` -在来看一下时间复杂度,使用单调队列的时间复杂度是 $O(n)$。 +在来看一下时间复杂度,使用单调队列的时间复杂度是 O(n)。 -有的同学可能想了,在队列中 push元素的过程中,还有pop操作呢,感觉不是纯粹的$O(n)$。 +有的同学可能想了,在队列中 push元素的过程中,还有pop操作呢,感觉不是纯粹的O(n)。 -其实,大家可以自己观察一下单调队列的实现,nums 中的每个元素最多也就被 push_back 和 pop_back 各一次,没有任何多余操作,所以整体的复杂度还是 $O(n)$。 +其实,大家可以自己观察一下单调队列的实现,nums 中的每个元素最多也就被 push_back 和 pop_back 各一次,没有任何多余操作,所以整体的复杂度还是 O(n)。 -空间复杂度因为我们定义一个辅助队列,所以是$O(k)$。 +空间复杂度因为我们定义一个辅助队列,所以是O(k)。 # 扩展 diff --git a/problems/0300.最长上升子序列.md b/problems/0300.最长上升子序列.md index 41c6a7ce..9e256897 100644 --- a/problems/0300.最长上升子序列.md +++ b/problems/0300.最长上升子序列.md @@ -4,7 +4,7 @@

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

-## 300.最长递增子序列 +# 300.最长递增子序列 [力扣题目链接](https://leetcode.cn/problems/longest-increasing-subsequence/) diff --git a/problems/0309.最佳买卖股票时机含冷冻期.md b/problems/0309.最佳买卖股票时机含冷冻期.md index 3791a71f..45772181 100644 --- a/problems/0309.最佳买卖股票时机含冷冻期.md +++ b/problems/0309.最佳买卖股票时机含冷冻期.md @@ -4,7 +4,7 @@

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

-## 309.最佳买卖股票时机含冷冻期 +# 309.最佳买卖股票时机含冷冻期 [力扣题目链接](https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/) diff --git a/problems/0337.打家劫舍III.md b/problems/0337.打家劫舍III.md index d2add232..d0a22877 100644 --- a/problems/0337.打家劫舍III.md +++ b/problems/0337.打家劫舍III.md @@ -5,7 +5,7 @@

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

-## 337.打家劫舍 III +# 337.打家劫舍 III [力扣题目链接](https://leetcode.cn/problems/house-robber-iii/) diff --git a/problems/0392.判断子序列.md b/problems/0392.判断子序列.md index dedeb0ad..9dbafe19 100644 --- a/problems/0392.判断子序列.md +++ b/problems/0392.判断子序列.md @@ -5,7 +5,7 @@

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

-## 392.判断子序列 +# 392.判断子序列 [力扣题目链接](https://leetcode.cn/problems/is-subsequence/) diff --git a/problems/0459.重复的子字符串.md b/problems/0459.重复的子字符串.md index 3d6df872..69f71ee3 100644 --- a/problems/0459.重复的子字符串.md +++ b/problems/0459.重复的子字符串.md @@ -31,13 +31,16 @@ # 思路 +针对本题,我录制了视频讲解:[字符串这么玩,可有点难度! | LeetCode:459.重复的子字符串](https://www.bilibili.com/video/BV1cg41127fw),结合本题解一起看,事半功倍! + + 暴力的解法, 就是一个for循环获取 子串的终止位置, 然后判断子串是否能重复构成字符串,又嵌套一个for循环,所以是O(n^2)的时间复杂度。 有的同学可以想,怎么一个for循环就可以获取子串吗? 至少得一个for获取子串起始位置,一个for获取子串结束位置吧。 其实我们只需要判断,以第一个字母为开始的子串就可以,所以一个for循环获取子串的终止位置就行了。 而且遍历的时候 都不用遍历结束,只需要遍历到中间位置,因为子串结束位置大于中间位置的话,一定不能重复组成字符串。 -暴力的解法,这里就不讲了。 +暴力的解法,这里就不详细讲解了。 主要讲一讲移动匹配 和 KMP两种方法。 diff --git a/problems/0516.最长回文子序列.md b/problems/0516.最长回文子序列.md index 60d5e920..378f9b74 100644 --- a/problems/0516.最长回文子序列.md +++ b/problems/0516.最长回文子序列.md @@ -4,7 +4,8 @@

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

-## 516.最长回文子序列 +# 516.最长回文子序列 + [力扣题目链接](https://leetcode.cn/problems/longest-palindromic-subsequence/) 给定一个字符串 s ,找到其中最长的回文子序列,并返回该序列的长度。可以假设 s 的最大长度为 1000 。 diff --git a/problems/0583.两个字符串的删除操作.md b/problems/0583.两个字符串的删除操作.md index 0e02e721..36c175c3 100644 --- a/problems/0583.两个字符串的删除操作.md +++ b/problems/0583.两个字符串的删除操作.md @@ -4,7 +4,7 @@

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

-## 583. 两个字符串的删除操作 +# 583. 两个字符串的删除操作 [力扣题目链接](https://leetcode.cn/problems/delete-operation-for-two-strings/) diff --git a/problems/0647.回文子串.md b/problems/0647.回文子串.md index fa9bf7b8..69efe7d0 100644 --- a/problems/0647.回文子串.md +++ b/problems/0647.回文子串.md @@ -4,7 +4,7 @@

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

-## 647. 回文子串 +# 647. 回文子串 [力扣题目链接](https://leetcode.cn/problems/palindromic-substrings/) diff --git a/problems/0674.最长连续递增序列.md b/problems/0674.最长连续递增序列.md index 7e4d0c19..c197e897 100644 --- a/problems/0674.最长连续递增序列.md +++ b/problems/0674.最长连续递增序列.md @@ -4,7 +4,7 @@

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

-## 674. 最长连续递增序列 +# 674. 最长连续递增序列 [力扣题目链接](https://leetcode.cn/problems/longest-continuous-increasing-subsequence/) diff --git a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md index 7734450e..6e4a86eb 100644 --- a/problems/0714.买卖股票的最佳时机含手续费(动态规划).md +++ b/problems/0714.买卖股票的最佳时机含手续费(动态规划).md @@ -4,7 +4,7 @@

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

-## 714.买卖股票的最佳时机含手续费 +# 714.买卖股票的最佳时机含手续费 [力扣题目链接](https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/) diff --git a/problems/0718.最长重复子数组.md b/problems/0718.最长重复子数组.md index 6de8b80f..d45f9111 100644 --- a/problems/0718.最长重复子数组.md +++ b/problems/0718.最长重复子数组.md @@ -4,7 +4,7 @@

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

-## 718. 最长重复子数组 +# 718. 最长重复子数组 [力扣题目链接](https://leetcode.cn/problems/maximum-length-of-repeated-subarray/) diff --git a/problems/1035.不相交的线.md b/problems/1035.不相交的线.md index 83ccb08c..831b60c8 100644 --- a/problems/1035.不相交的线.md +++ b/problems/1035.不相交的线.md @@ -4,7 +4,7 @@

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

-## 1035.不相交的线 +# 1035.不相交的线 [力扣题目链接](https://leetcode.cn/problems/uncrossed-lines/) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 2c51bbb3..e22c747a 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -32,34 +32,21 @@ # 思路 -## 题外话 - -这道题目就像是我们玩过的游戏对对碰,如果相同的元素放在挨在一起就要消除。 - -可能我们在玩游戏的时候感觉理所当然应该消除,但程序又怎么知道该如果消除呢,特别是消除之后又有新的元素可能挨在一起。 - -此时游戏的后端逻辑就可以用一个栈来实现(我没有实际考察对对碰或者爱消除游戏的代码实现,仅从原理上进行推断)。 - -游戏开发可能使用栈结构,编程语言的一些功能实现也会使用栈结构,实现函数递归调用就需要栈,但不是每种编程语言都支持递归,例如: - -![1047.删除字符串中的所有相邻重复项](https://img-blog.csdnimg.cn/20210309093252776.png) - -**递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中**,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。 - -相信大家应该遇到过一种错误就是栈溢出,系统输出的异常是`Segmentation fault`(当然不是所有的`Segmentation fault` 都是栈溢出导致的) ,如果你使用了递归,就要想一想是不是无限递归了,那么系统调用栈就会溢出。 - -而且**在企业项目开发中,尽量不要使用递归!**在项目比较大的时候,由于参数多,全局变量等等,使用递归很容易判断不充分return的条件,非常容易无限递归(或者递归层级过深),**造成栈溢出错误(这种问题还不好排查!)** - -好了,题外话over,我们进入正题。 +《代码随想录》算法视频公开课:[栈的好戏还要继续!| LeetCode:1047. 删除字符串中的所有相邻重复项](https://www.bilibili.com/video/BV12a411P7mw),相信结合视频在看本篇题解,更有助于大家对本题的理解。 ## 正题 -本题要删除相邻相同元素,其实也是匹配问题,相同左元素相当于左括号,相同右元素就是相当于右括号,匹配上了就删除。 +本题要删除相邻相同元素,相对于[20. 有效的括号](https://programmercarl.com/0020.%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7.html)来说其实也是匹配问题,20. 有效的括号 是匹配左右括号,本题是匹配相邻元素,最后都是做消除的操作。 -那么再来看一下本题:可以把字符串顺序放到一个栈中,然后如果相同的话 栈就弹出,这样最后栈里剩下的元素都是相邻不相同的元素了。 +本题也是用栈来解决的经典题目。 +那么栈里应该放的是什么元素呢? -如动画所示: +我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢? + +所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。 + +然后再去做对应的消除操作。 如动画所示: ![1047.删除字符串中的所有相邻重复项](https://code-thinking.cdn.bcebos.com/gifs/1047.删除字符串中的所有相邻重复项.gif) @@ -113,6 +100,22 @@ public: }; ``` +## 题外话 + +这道题目就像是我们玩过的游戏对对碰,如果相同的元素放在挨在一起就要消除。 + +可能我们在玩游戏的时候感觉理所当然应该消除,但程序又怎么知道该如果消除呢,特别是消除之后又有新的元素可能挨在一起。 + +此时游戏的后端逻辑就可以用一个栈来实现(我没有实际考察对对碰或者爱消除游戏的代码实现,仅从原理上进行推断)。 + +游戏开发可能使用栈结构,编程语言的一些功能实现也会使用栈结构,实现函数递归调用就需要栈,但不是每种编程语言都支持递归,例如: + +**递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中**,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。 + +相信大家应该遇到过一种错误就是栈溢出,系统输出的异常是`Segmentation fault`(当然不是所有的`Segmentation fault` 都是栈溢出导致的) ,如果你使用了递归,就要想一想是不是无限递归了,那么系统调用栈就会溢出。 + +而且**在企业项目开发中,尽量不要使用递归**!在项目比较大的时候,由于参数多,全局变量等等,使用递归很容易判断不充分return的条件,非常容易无限递归(或者递归层级过深),**造成栈溢出错误(这种问题还不好排查!)** + ## 其他语言版本 @@ -195,7 +198,7 @@ class Solution { Python: ```python -# 方法一,使用栈,推荐! +# 方法一,使用栈 class Solution: def removeDuplicates(self, s: str) -> str: res = list() diff --git a/problems/1143.最长公共子序列.md b/problems/1143.最长公共子序列.md index 4f4cb32a..097dc6e6 100644 --- a/problems/1143.最长公共子序列.md +++ b/problems/1143.最长公共子序列.md @@ -4,7 +4,7 @@

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

-## 1143.最长公共子序列 +# 1143.最长公共子序列 [力扣题目链接](https://leetcode.cn/problems/longest-common-subsequence/) diff --git a/problems/前序/深圳互联网公司总结.md b/problems/前序/深圳互联网公司总结.md index 3d548abb..f8c07016 100644 --- a/problems/前序/深圳互联网公司总结.md +++ b/problems/前序/深圳互联网公司总结.md @@ -22,7 +22,7 @@ * 深信服(总部深圳) * 大疆(总部深圳,无人机巨头) * 一加手机(总部深圳) -* 柔宇科技(国内领先的柔性屏幕制造商,最近正在准备上市) +* 柔宇科技(最近口碑急转直下) ## 二线大厂 @@ -66,7 +66,7 @@ ## 其他行业(有软件/互联网业务) * 三大电信运营商:中国移动、中国电信、中国联通 -* 房产企业:恒大、万科 +* 房产企业:恒大(暴雷)、万科 * 中信深圳 * 广发证券,深交所 * 珍爱网(珍爱网是国内知名的婚恋服务网站之一) diff --git a/problems/动态规划-股票问题总结篇.md b/problems/动态规划-股票问题总结篇.md index 47a9b34b..366810e5 100644 --- a/problems/动态规划-股票问题总结篇.md +++ b/problems/动态规划-股票问题总结篇.md @@ -4,6 +4,8 @@

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

+# Leetcode股票问题总结篇! + 之前我们已经把力扣上股票系列的题目都讲过的,但没有来一篇股票总结,来帮大家高屋建瓴,所以总结篇这就来了! ![股票问题总结](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) diff --git a/problems/动态规划总结篇.md b/problems/动态规划总结篇.md index 847baa9a..45bd3916 100644 --- a/problems/动态规划总结篇.md +++ b/problems/动态规划总结篇.md @@ -5,6 +5,7 @@

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

+# 动态规划最强总结篇! 如今动态规划已经讲解了42道经典题目,共50篇文章,是时候做一篇总结了。 diff --git a/problems/背包问题理论基础完全背包.md b/problems/背包问题理论基础完全背包.md index fc4609a6..44f7d30d 100644 --- a/problems/背包问题理论基础完全背包.md +++ b/problems/背包问题理论基础完全背包.md @@ -3,6 +3,8 @@

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

+ + # 动态规划:关于完全背包,你该了解这些! ## 完全背包