Skip to content

Commit

Permalink
C:/Program Files/Git/problems/1-40更新链接‘
Browse files Browse the repository at this point in the history
  • Loading branch information
XuDaHaoRen committed Aug 21, 2021
1 parent 391a04b commit 4e19ab8
Show file tree
Hide file tree
Showing 19 changed files with 80 additions and 80 deletions.
6 changes: 3 additions & 3 deletions problems/0005.最长回文子串.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

# 5.最长回文子串

题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/
[力扣题目链接](https://leetcode-cn.com/problems/longest-palindromic-substring/)

给你一个字符串 s,找到 s 中最长的回文子串。

Expand All @@ -30,11 +30,11 @@
示例 4:
* 输入:s = "ac"
* 输出:"a"
 


# 思路

本题和[647.回文子串](https://mp.weixin.qq.com/s/2WetyP6IYQ6VotegepVpEw) 差不多是一样的,但647.回文子串更基本一点,建议可以先做647.回文子串
本题和[647.回文子串](https://programmercarl.com/0647.回文子串.html) 差不多是一样的,但647.回文子串更基本一点,建议可以先做647.回文子串

## 暴力解法

Expand Down
10 changes: 5 additions & 5 deletions problems/0015.三数之和.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@



> 用哈希表解决了[两数之和](https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ),那么三数之和呢?
> 用哈希表解决了[两数之和](https://programmercarl.com/0001.两数之和.html),那么三数之和呢?
# 第15题. 三数之和

https://leetcode-cn.com/problems/3sum/
[力扣题目链接](https://leetcode-cn.com/problems/3sum/)

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

Expand Down Expand Up @@ -163,13 +163,13 @@ public:
# 思考题


既然三数之和可以使用双指针法,我们之前讲过的[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ),可不可以使用双指针法呢?
既然三数之和可以使用双指针法,我们之前讲过的[1.两数之和](https://programmercarl.com/0001.两数之和.html),可不可以使用双指针法呢?

如果不能,题意如何更改就可以使用双指针法呢? **大家留言说出自己的想法吧!**

两数之和 就不能使用双指针法,因为[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ)要求返回的是索引下表, 而双指针法一定要排序,一旦排序之后原数组的索引就被改变了。
两数之和 就不能使用双指针法,因为[1.两数之和](https://programmercarl.com/0001.两数之和.html)要求返回的是索引下表, 而双指针法一定要排序,一旦排序之后原数组的索引就被改变了。

如果[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ)要求返回的是数值的话,就可以使用双指针法了。
如果[1.两数之和](https://programmercarl.com/0001.两数之和.html)要求返回的是数值的话,就可以使用双指针法了。



Expand Down
18 changes: 9 additions & 9 deletions problems/0017.电话号码的字母组合.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

# 17.电话号码的字母组合

题目链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
[力扣题目链接](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/)

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

Expand All @@ -29,7 +29,7 @@

如果输入"233"呢,那么就三层for循环,如果"2333"呢,就四层for循环.......

大家应该感觉出和[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)遇到的一样的问题,就是这for循环的层数如何写出来,此时又是回溯法登场的时候了。
大家应该感觉出和[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)遇到的一样的问题,就是这for循环的层数如何写出来,此时又是回溯法登场的时候了。

理解本题后,要解决如下三个问题:

Expand Down Expand Up @@ -58,7 +58,7 @@ const string letterMap[10] = {

## 回溯法来解决n个for循环的问题

对于回溯法还不了解的同学看这篇:[关于回溯算法,你该了解这些!](https://mp.weixin.qq.com/s/gjSgJbNbd1eAA5WkA-HeWw)
对于回溯法还不了解的同学看这篇:[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)


例如:输入:"23",抽象为树形结构,如图所示:
Expand All @@ -75,7 +75,7 @@ const string letterMap[10] = {

再来看参数,参数指定是有题目中给的string digits,然后还要有一个参数就是int型的index。

注意这个index可不是 [回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)[回溯算法:求组合总和!](https://mp.weixin.qq.com/s/HX7WW6ixbFZJASkRnCTC3w)中的startIndex了。
注意这个index可不是 [回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)[回溯算法:求组合总和!](https://programmercarl.com/0216.组合总和III.html)中的startIndex了。

这个index是记录遍历第几个数字了,就是用来遍历digits的(题目中给出数字字符串),同时index也表示树的深度。

Expand Down Expand Up @@ -120,9 +120,9 @@ for (int i = 0; i < letters.size(); i++) {
}
```

**注意这里for循环,可不像是在[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)[回溯算法:求组合总和!](https://mp.weixin.qq.com/s/HX7WW6ixbFZJASkRnCTC3w)中从startIndex开始遍历的**
**注意这里for循环,可不像是在[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)[回溯算法:求组合总和!](https://programmercarl.com/0216.组合总和III.html)中从startIndex开始遍历的**

**因为本题每一个数字代表的是不同集合,也就是求不同集合之间的组合,而[77. 组合](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)[216.组合总和III](https://mp.weixin.qq.com/s/HX7WW6ixbFZJASkRnCTC3w)都是是求同一个集合中的组合!**
**因为本题每一个数字代表的是不同集合,也就是求不同集合之间的组合,而[77. 组合](https://programmercarl.com/0077.组合.html)[216.组合总和III](https://programmercarl.com/0216.组合总和III.html)都是是求同一个集合中的组合!**


注意:输入1 * #按键等等异常情况
Expand All @@ -134,7 +134,7 @@ for (int i = 0; i < letters.size(); i++) {

## C++代码

关键地方都讲完了,按照[关于回溯算法,你该了解这些!](https://mp.weixin.qq.com/s/gjSgJbNbd1eAA5WkA-HeWw)中的回溯法模板,不难写出如下C++代码:
关键地方都讲完了,按照[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)中的回溯法模板,不难写出如下C++代码:


```c++
Expand Down Expand Up @@ -224,13 +224,13 @@ public:
};
```

我不建议把回溯藏在递归的参数里这种写法,很不直观,我在[二叉树:以为使用了递归,其实还隐藏着回溯](https://mp.weixin.qq.com/s/ivLkHzWdhjQQD1rQWe6zWA)这篇文章中也深度分析了,回溯隐藏在了哪里。
我不建议把回溯藏在递归的参数里这种写法,很不直观,我在[二叉树:以为使用了递归,其实还隐藏着回溯](https://programmercarl.com/二叉树中递归带着回溯.html)这篇文章中也深度分析了,回溯隐藏在了哪里。

所以大家可以按照版本一来写就可以了。

# 总结

本篇将题目的三个要点一一列出,并重点强调了和前面讲解过的[77. 组合](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)[216.组合总和III](https://mp.weixin.qq.com/s/HX7WW6ixbFZJASkRnCTC3w)的区别,本题是多个集合求组合,所以在回溯的搜索过程中,都有一些细节需要注意的。
本篇将题目的三个要点一一列出,并重点强调了和前面讲解过的[77. 组合](https://programmercarl.com/0077.组合.html)[216.组合总和III](https://programmercarl.com/0216.组合总和III.html)的区别,本题是多个集合求组合,所以在回溯的搜索过程中,都有一些细节需要注意的。

其实本题不算难,但也处处是细节,大家还要自己亲自动手写一写。

Expand Down
26 changes: 13 additions & 13 deletions problems/0018.四数之和.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# 第18题. 四数之和

https://leetcode-cn.com/problems/4sum/
[力扣题目链接](https://leetcode-cn.com/problems/4sum/)

题意:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

Expand All @@ -31,37 +31,37 @@ https://leetcode-cn.com/problems/4sum/

# 思路

四数之和,和[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)是一个思路,都是使用双指针法, 基本解法就是在[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg) 的基础上再套一层for循环。
四数之和,和[15.三数之和](https://programmercarl.com/0015.三数之和.html)是一个思路,都是使用双指针法, 基本解法就是在[15.三数之和](https://programmercarl.com/0015.三数之和.html) 的基础上再套一层for循环。

但是有一些细节需要注意,例如: 不要判断`nums[k] > target` 就返回了,三数之和 可以通过 `nums[i] > 0` 就返回了,因为 0 已经是确定的数了,四数之和这道题目 target是任意值。(大家亲自写代码就能感受出来)

[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)的双指针解法是一层for循环num[i]为确定值,然后循环内有left和right下表作为双指针,找到nums[i] + nums[left] + nums[right] == 0。
[15.三数之和](https://programmercarl.com/0015.三数之和.html)的双指针解法是一层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) 。

那么一样的道理,五数之和、六数之和等等都采用这种解法。

对于[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)双指针法就是将原本暴力O(n^3)的解法,降为O(n^2)的解法,四数之和的双指针解法就是将原本暴力O(n^4)的解法,降为O(n^3)的解法。
对于[15.三数之和](https://programmercarl.com/0015.三数之和.html)双指针法就是将原本暴力O(n^3)的解法,降为O(n^2)的解法,四数之和的双指针解法就是将原本暴力O(n^4)的解法,降为O(n^3)的解法。

之前我们讲过哈希表的经典题目:[454.四数相加II](https://mp.weixin.qq.com/s/12g_w6RzHuEpFts1pT6BWw),相对于本题简单很多,因为本题是要求在一个集合中找出四个数相加等于target,同时四元组不能重复。
之前我们讲过哈希表的经典题目:[454.四数相加II](https://programmercarl.com/0454.四数相加II.html),相对于本题简单很多,因为本题是要求在一个集合中找出四个数相加等于target,同时四元组不能重复。

[454.四数相加II](https://mp.weixin.qq.com/s/12g_w6RzHuEpFts1pT6BWw)是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于本题还是简单了不少!
[454.四数相加II](https://programmercarl.com/0454.四数相加II.html)是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于本题还是简单了不少!

我们来回顾一下,几道题目使用了双指针法。

双指针法将时间复杂度O(n^2)的解法优化为 O(n)的解法。也就是降一个数量级,题目如下:

* [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)
* [27.移除元素](https://programmercarl.com/0027.移除元素.html)
* [15.三数之和](https://programmercarl.com/0015.三数之和.html)
* [18.四数之和](https://programmercarl.com/0018.四数之和.html)


操作链表:

* [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)
* [206.反转链表](https://programmercarl.com/0206.翻转链表.html)
* [19.删除链表的倒数第N个节点](https://programmercarl.com/0019.删除链表的倒数第N个节点.html)
* [面试题 02.07. 链表相交](https://programmercarl.com/面试题02.07.链表相交.html)
* [142题.环形链表II](https://programmercarl.com/0142.环形链表II.html)

双指针法在字符串题目中还有很多应用,后面还会介绍到。

Expand Down
4 changes: 2 additions & 2 deletions problems/0019.删除链表的倒数第N个节点.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

## 19.删除链表的倒数第N个节点

题目链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/
[力扣题目链接](https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/)

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

Expand Down Expand Up @@ -41,7 +41,7 @@

分为如下几步:

* 首先这里我推荐大家使用虚拟头结点,这样方面处理删除实际头结点的逻辑,如果虚拟头结点不清楚,可以看这篇: [链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/L5aanfALdLEwVWGvyXPDqA)
* 首先这里我推荐大家使用虚拟头结点,这样方面处理删除实际头结点的逻辑,如果虚拟头结点不清楚,可以看这篇: [链表:听说用虚拟头节点会方便很多?](https://programmercarl.com/0203.移除链表元素.html)

* 定义fast指针和slow指针,初始值为虚拟头结点,如图:

Expand Down
2 changes: 1 addition & 1 deletion problems/0020.有效的括号.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# 20. 有效的括号

https://leetcode-cn.com/problems/valid-parentheses/
[力扣题目链接](https://leetcode-cn.com/problems/valid-parentheses/)

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

Expand Down
4 changes: 2 additions & 2 deletions problems/0024.两两交换链表中的节点.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

## 24. 两两交换链表中的节点

https://leetcode-cn.com/problems/swap-nodes-in-pairs/
[力扣题目链接](https://leetcode-cn.com/problems/swap-nodes-in-pairs/)

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

Expand All @@ -24,7 +24,7 @@ https://leetcode-cn.com/problems/swap-nodes-in-pairs/

建议使用虚拟头结点,这样会方便很多,要不然每次针对头结点(没有前一个指针指向头结点),还要单独处理。

对虚拟头结点的操作,还不熟悉的话,可以看这篇[链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/L5aanfALdLEwVWGvyXPDqA)
对虚拟头结点的操作,还不熟悉的话,可以看这篇[链表:听说用虚拟头节点会方便很多?](https://programmercarl.com/0203.移除链表元素.html)

接下来就是交换相邻两个元素了,**此时一定要画图,不画图,操作多个指针很容易乱,而且要操作的先后顺序**

Expand Down
6 changes: 3 additions & 3 deletions problems/0027.移除元素.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

## 27. 移除元素

题目地址:https://leetcode-cn.com/problems/remove-element/
[力扣题目链接](https://leetcode-cn.com/problems/remove-element/)

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

Expand All @@ -34,7 +34,7 @@

**要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。**

数组的基础知识可以看这里[程序员算法面试中,必须掌握的数组理论知识](https://mp.weixin.qq.com/s/c2KABb-Qgg66HrGf8z-8Og)
数组的基础知识可以看这里[程序员算法面试中,必须掌握的数组理论知识](https://programmercarl.com/数组理论基础.html)

### 暴力解法

Expand Down Expand Up @@ -106,7 +106,7 @@ public:
* 时间复杂度:$O(n)$
* 空间复杂度:$O(1)$
旧文链接:[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA)
旧文链接:[数组:就移除个元素很难么?](https://programmercarl.com/0027.移除元素.html)
## 相关题目推荐
Expand Down
2 changes: 1 addition & 1 deletion problems/0028.实现strStr.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# 28. 实现 strStr()

https://leetcode-cn.com/problems/implement-strstr/
[力扣题目链接](https://leetcode-cn.com/problems/implement-strstr/)

实现 strStr() 函数。

Expand Down
2 changes: 1 addition & 1 deletion problems/0031.下一个排列.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

# 31.下一个排列

链接:https://leetcode-cn.com/problems/next-permutation/
[力扣题目链接](https://leetcode-cn.com/problems/next-permutation/)

实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@

对二分还不了解的同学先做这两题:

* [704.二分查找](https://mp.weixin.qq.com/s/4X-8VRgnYRGd5LYGZ33m4w)
* [35.搜索插入位置](https://mp.weixin.qq.com/s/fCf5QbPDtE6SSlZ1yh_q8Q)
* [704.二分查找](https://programmercarl.com/0704.二分查找.html)
* [35.搜索插入位置](https://programmercarl.com/0035.搜索插入位置.html)

下面我来把所有情况都讨论一下。

Expand All @@ -56,9 +56,9 @@

## 寻找右边界

先来寻找右边界,至于二分查找,如果看过[704.二分查找](https://mp.weixin.qq.com/s/4X-8VRgnYRGd5LYGZ33m4w)就会知道,二分查找中什么时候用while (left <= right),有什么时候用while (left < right),其实只要清楚**循环不变量**,很容易区分两种写法。
先来寻找右边界,至于二分查找,如果看过[704.二分查找](https://programmercarl.com/0704.二分查找.html)就会知道,二分查找中什么时候用while (left <= right),有什么时候用while (left < right),其实只要清楚**循环不变量**,很容易区分两种写法。

那么这里我采用while (left <= right)的写法,区间定义为[left, right],即左闭又闭的区间(如果这里有点看不懂了,强烈建议把[704.二分查找](https://mp.weixin.qq.com/s/4X-8VRgnYRGd5LYGZ33m4w)这篇文章先看了,704题目做了之后再做这道题目就好很多了)
那么这里我采用while (left <= right)的写法,区间定义为[left, right],即左闭又闭的区间(如果这里有点看不懂了,强烈建议把[704.二分查找](https://programmercarl.com/0704.二分查找.html)这篇文章先看了,704题目做了之后再做这道题目就好很多了)

确定好:计算出来的右边界是不包好target的右边界,左边界同理。

Expand Down
2 changes: 1 addition & 1 deletion problems/0035.搜索插入位置.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

# 35.搜索插入位置

题目地址:https://leetcode-cn.com/problems/search-insert-position/
[力扣题目链接](https://leetcode-cn.com/problems/search-insert-position/)

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

Expand Down
Loading

0 comments on commit 4e19ab8

Please sign in to comment.