From be40b09991fed2d2f2612c24c8cb5115c2fcb7b0 Mon Sep 17 00:00:00 2001 From: yqq Date: Mon, 14 Jun 2021 16:34:46 +0800 Subject: [PATCH 01/39] adddddd --- problems/0035.搜索插入位置.md | 4 ++-- problems/0070.爬楼梯完全背包版本.md | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/problems/0035.搜索插入位置.md b/problems/0035.搜索插入位置.md index e891e3c5..a8da3045 100644 --- a/problems/0035.搜索插入位置.md +++ b/problems/0035.搜索插入位置.md @@ -76,7 +76,7 @@ public: ``` 时间复杂度:O(n) -时间复杂度:O(1) +空间复杂度:O(1) 效率如下: @@ -158,7 +158,7 @@ public: **大家要仔细看注释,思考为什么要写while (left < right), 为什么要写right = middle**。 -``` +```cpp class Solution { public: int searchInsert(vector& nums, int target) { diff --git a/problems/0070.爬楼梯完全背包版本.md b/problems/0070.爬楼梯完全背包版本.md index d6b12450..f92e6716 100644 --- a/problems/0070.爬楼梯完全背包版本.md +++ b/problems/0070.爬楼梯完全背包版本.md @@ -88,7 +88,8 @@ 以上分析完毕,C++代码如下: -``` + +```cpp class Solution { public: int climbStairs(int n) { From cb9175f41a672e321cdd13ec5ba4a0fa7e3066da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BD=99=E6=9D=9C=E6=9E=97?= Date: Tue, 17 Aug 2021 22:53:03 +0800 Subject: [PATCH 02/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A00707.=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E9=93=BE=E8=A1=A8=20Swift=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0707.设计链表.md | 81 +++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md index 0aa038e8..0b8cd2e4 100644 --- a/problems/0707.设计链表.md +++ b/problems/0707.设计链表.md @@ -948,6 +948,87 @@ class MyLinkedList { } ``` +Swift: + +```swift +class MyLinkedList { + var dummyHead: ListNode? + var size: Int + + init() { + dummyHead = ListNode(0) + size = 0 + } + + func get(_ index: Int) -> Int { + if index >= size || index < 0 { + return -1 + } + + var curNode = dummyHead?.next + var curIndex = index + + while curIndex > 0 { + curNode = curNode?.next + curIndex -= 1 + } + + return curNode?.value ?? -1 + } + + func addAtHead(_ val: Int) { + let newHead = ListNode(val) + newHead.next = dummyHead?.next + dummyHead?.next = newHead + size += 1 + } + + func addAtTail(_ val: Int) { + let newNode = ListNode(val) + var curNode = dummyHead + while curNode?.next != nil { + curNode = curNode?.next + } + + curNode?.next = newNode + size += 1 + } + + func addAtIndex(_ index: Int, _ val: Int) { + if index > size { + return + } + + let newNode = ListNode(val) + var curNode = dummyHead + var curIndex = index + + while curIndex > 0 { + curNode = curNode?.next + curIndex -= 1 + } + + newNode.next = curNode?.next + curNode?.next = newNode + size += 1 + } + + func deleteAtIndex(_ index: Int) { + if index >= size || index < 0 { + return + } + + var curNode = dummyHead + for _ in 0.. Date: Wed, 18 Aug 2021 01:26:55 +0800 Subject: [PATCH 03/39] =?UTF-8?q?Update=200102.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E5=B1=82=E5=BA=8F=E9=81=8D=E5=8E=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0102.二叉树的层序遍历.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 0f9b2df6..9b1435a2 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -1129,7 +1129,7 @@ var largestValues = function(root) { queue.push(root); while(root!==null&&queue.length){ //设置max初始值就是队列的第一个元素 - let max=queue[0]; + let max=queue[0].val; let length=queue.length; while(length--){ let node = queue.shift(); From 704c3bb7960fc40b3000d36e7ec6266747a9cc87 Mon Sep 17 00:00:00 2001 From: ironartisan Date: Wed, 18 Aug 2021 22:33:42 +0800 Subject: [PATCH 04/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A00084.=E6=9F=B1=E7=8A=B6?= =?UTF-8?q?=E5=9B=BE=E4=B8=AD=E6=9C=80=E5=A4=A7=E7=9A=84=E7=9F=A9=E5=BD=A2?= =?UTF-8?q?java=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0084.柱状图中最大的矩形.md | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/problems/0084.柱状图中最大的矩形.md b/problems/0084.柱状图中最大的矩形.md index 941888db..bec3bc99 100644 --- a/problems/0084.柱状图中最大的矩形.md +++ b/problems/0084.柱状图中最大的矩形.md @@ -195,6 +195,40 @@ public: Java: +动态规划 +```java +class Solution { + public int largestRectangleArea(int[] heights) { + int length = heights.length; + int[] minLeftIndex = new int [length]; + int[] maxRigthIndex = new int [length]; + + // 记录左边第一个小于该柱子的下标 + minLeftIndex[0] = -1 ; + for (int i = 1; i < length; i++) { + int t = i - 1; + // 这里不是用if,而是不断向右寻找的过程 + while (t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t]; + minLeftIndex[i] = t; + } + // 记录每个柱子 右边第一个小于该柱子的下标 + maxRigthIndex[length - 1] = length; + for (int i = length - 2; i >= 0; i--) { + int t = i + 1; + while(t < length && heights[t] >= heights[i]) t = maxRigthIndex[t]; + maxRigthIndex[i] = t; + } + // 求和 + int result = 0; + for (int i = 0; i < length; i++) { + int sum = heights[i] * (maxRigthIndex[i] - minLeftIndex[i] - 1); + result = Math.max(sum, result); + } + return result; + } +} +``` + Python: 动态规划 From 4b71311621baad2dc356dbe100e608435cc47bd8 Mon Sep 17 00:00:00 2001 From: shuwen Date: Thu, 19 Aug 2021 12:41:16 +0800 Subject: [PATCH 05/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=B1=82=E5=BA=8F?= =?UTF-8?q?=E9=81=8D=E5=8E=86=E4=B8=AD=E7=9A=84=20104.=20=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91=E7=9A=84=E6=9C=80=E5=A4=A7=E6=B7=B1=E5=BA=A6?= =?UTF-8?q?=20Python=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0102.二叉树的层序遍历.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 0f9b2df6..dc386684 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -1532,6 +1532,29 @@ Java: Python: +```python 3 +class Solution: + def maxDepth(self, root: TreeNode) -> int: + if root == None: + return 0 + + queue_ = [root] + result = [] + while queue_: + length = len(queue_) + sub = [] + for i in range(length): + cur = queue_.pop(0) + sub.append(cur.val) + #子节点入队列 + if cur.left: queue_.append(cur.left) + if cur.right: queue_.append(cur.right) + result.append(sub) + + + return len(result) +``` + Go: From bd3d65c41530e2f8268986ce9f4b13d889d5925d Mon Sep 17 00:00:00 2001 From: DoubleYellowIce <65336599+DoubleYellowIce@users.noreply.github.com> Date: Thu, 19 Aug 2021 14:34:15 +0800 Subject: [PATCH 06/39] =?UTF-8?q?Update=200188.=E4=B9=B0=E5=8D=96=E8=82=A1?= =?UTF-8?q?=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6=E6=9C=BAIV.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0188.买卖股票的最佳时机IV.md | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/problems/0188.买卖股票的最佳时机IV.md b/problems/0188.买卖股票的最佳时机IV.md index 9fe7a919..66676a7a 100644 --- a/problems/0188.买卖股票的最佳时机IV.md +++ b/problems/0188.买卖股票的最佳时机IV.md @@ -196,7 +196,7 @@ class Solution { } } -// 版本二: 空间优化 +// 版本二: 二维 dp数组 class Solution { public int maxProfit(int k, int[] prices) { if (prices.length == 0) return 0; @@ -220,6 +220,25 @@ class Solution { return dp[len - 1][k*2]; } } + +//版本三:一维 dp数组 +class Solution { + public int maxProfit(int k, int[] prices) { + //在版本二的基础上,由于我们只关心前一天的股票买入情况,所以只存储前一天的股票买入情况 + if(prices.length==0)return 0; + int[] dp=new int[2*k+1]; + for (int i = 1; i <2*k ; i+=2) { + dp[i]=-prices[0]; + } + for (int i = 0; i Date: Thu, 19 Aug 2021 14:46:15 +0800 Subject: [PATCH 07/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A00279.=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E5=B9=B3=E6=96=B9=E6=95=B0python3=E7=89=88=E6=9C=AC=E4=B8=80?= =?UTF-8?q?=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0279.完全平方数.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/problems/0279.完全平方数.md b/problems/0279.完全平方数.md index e51f0a99..863bd60c 100644 --- a/problems/0279.完全平方数.md +++ b/problems/0279.完全平方数.md @@ -217,6 +217,22 @@ class Solution: Python3: ```python class Solution: + '''版本一,先遍历背包, 再遍历物品''' + def numSquares(self, n: int) -> int: + dp = [n] * (n + 1) + dp[0] = 0 + # 遍历背包 + for j in range(1, n+1): + for i in range(1, n): + num = i ** 2 + if num > j: break + # 遍历物品 + if j - num >= 0: + dp[j] = min(dp[j], dp[j - num] + 1) + return dp[n] + +class Solution: + '''版本二, 先遍历物品, 再遍历背包''' def numSquares(self, n: int) -> int: # 初始化 # 组成和的完全平方数的最多个数,就是只用1构成 From 7c6930971d6175fe6656a4b31c4ac1c6d765d795 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 15:00:28 +0800 Subject: [PATCH 08/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200203.=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E9=93=BE=E8=A1=A8=E5=85=83=E7=B4=A0.md=20python?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用更符合PEP8要求的代码规范来约束 --- problems/0203.移除链表元素.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md index f3724fc2..d67a7d2a 100644 --- a/problems/0203.移除链表元素.md +++ b/problems/0203.移除链表元素.md @@ -245,13 +245,15 @@ Python: # 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) #添加一个虚拟节点 + dummy_head = ListNode(next=head) cur = dummy_head - while(cur.next!=None): - if(cur.next.val == val): - cur.next = cur.next.next #删除cur.next节点 + + while cur.next: + if cur.next.val == val: + cur.next = cur.next.next # 删除下一个节点 else: cur = cur.next return dummy_head.next From aa4ce0f096013a20847b4b7c325a22fbe26e6deb Mon Sep 17 00:00:00 2001 From: ironartisan Date: Thu, 19 Aug 2021 15:03:44 +0800 Subject: [PATCH 09/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A00279.=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E5=B9=B3=E6=96=B9=E6=95=B0java=E7=89=88=E6=9C=AC=E4=BA=8C?= =?UTF-8?q?=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0279.完全平方数.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/problems/0279.完全平方数.md b/problems/0279.完全平方数.md index 863bd60c..f23453da 100644 --- a/problems/0279.完全平方数.md +++ b/problems/0279.完全平方数.md @@ -161,6 +161,7 @@ public: Java: ```Java class Solution { + // 版本一,先遍历物品, 再遍历背包 public int numSquares(int n) { int max = Integer.MAX_VALUE; int[] dp = new int[n + 1]; @@ -170,7 +171,9 @@ class Solution { } //当和为0时,组合的个数为0 dp[0] = 0; + // 遍历物品 for (int i = 1; i * i <= n; i++) { + // 遍历背包 for (int j = i * i; j <= n; j++) { if (dp[j - i * i] != max) { dp[j] = Math.min(dp[j], dp[j - i * i] + 1); @@ -180,6 +183,28 @@ class Solution { return dp[n]; } } + +class Solution { + // 版本二, 先遍历背包, 再遍历物品 + public int numSquares(int n) { + int max = Integer.MAX_VALUE; + int[] dp = new int[n + 1]; + // 初始化 + for (int j = 0; j <= n; j++) { + dp[j] = max; + } + // 当和为0时,组合的个数为0 + dp[0] = 0; + // 遍历背包 + for (int j = 1; j <= n; j++) { + // 遍历物品 + for (int i = 1; i * i <= j; i++) { + dp[j] = Math.min(dp[j], dp[j - i * i] + 1); + } + } + return dp[n]; + } +} ``` Python: @@ -187,7 +212,7 @@ 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) From 4df16b4258c41d3b6cfb0d9f7e4b9a51f9cba0a0 Mon Sep 17 00:00:00 2001 From: ironartisan Date: Thu, 19 Aug 2021 15:05:17 +0800 Subject: [PATCH 10/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A00279.=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E5=B9=B3=E6=96=B9=E6=95=B0java=E7=89=88=E6=9C=AC=E4=BA=8C?= =?UTF-8?q?=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0279.完全平方数.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0279.完全平方数.md b/problems/0279.完全平方数.md index f23453da..3c0f0414 100644 --- a/problems/0279.完全平方数.md +++ b/problems/0279.完全平方数.md @@ -226,7 +226,7 @@ class Solution: 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) From f6eee532e49acba882be2b202825ee7082d9a69c Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 16:26:42 +0800 Subject: [PATCH 11/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200344.=E5=8F=8D?= =?UTF-8?q?=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2.md=20python=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E4=BC=98=E5=8C=96=EF=BC=8C=E5=88=A0=E9=99=A4=E5=8F=A6?= =?UTF-8?q?=E4=B8=80=E7=A7=8D=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 另一种解法进行了不必要的操作,且代码可读性较差。 推荐使用第一种解法 --- problems/0344.反转字符串.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/problems/0344.反转字符串.md b/problems/0344.反转字符串.md index 4f96f839..763097be 100644 --- a/problems/0344.反转字符串.md +++ b/problems/0344.反转字符串.md @@ -162,21 +162,14 @@ class Solution: Do not return anything, modify s in-place instead. """ left, right = 0, len(s) - 1 - while(left < right): + + # 该方法已经不需要判断奇偶数,经测试后时间空间复杂度比用 for i in range(right//2)更低 + # 推荐该写法,更加通俗易懂 + while left < right: s[left], s[right] = s[right], s[left] left += 1 right -= 1 - -# 下面的写法更加简洁,但是都是同样的算法 -# class Solution: -# def reverseString(self, s: List[str]) -> None: -# """ -# Do not return anything, modify s in-place instead. -# """ - # 不需要判别是偶数个还是奇数个序列,因为奇数个的时候,中间那个不需要交换就可 -# for i in range(len(s)//2): -# s[i], s[len(s)-1-i] = s[len(s)-1-i], s[i] -# return s + ``` Go: From 0990dfe810af83c4ed41c605fd165dad1f76645b Mon Sep 17 00:00:00 2001 From: shuwen Date: Thu, 19 Aug 2021 17:00:42 +0800 Subject: [PATCH 12/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200102.=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91=E7=9A=84=E5=B1=82=E5=BA=8F=E9=81=8D=E5=8E=86?= =?UTF-8?q?.md=20=20=E5=85=B3=E4=BA=8E111.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E6=9C=80=E5=B0=8F=E6=B7=B1=E5=BA=A6=E7=9A=84Python?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0102.二叉树的层序遍历.md | 32 ++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index dc386684..109ed70f 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -1562,6 +1562,8 @@ JavaScript: # 111.二叉树的最小深度 +题目地址:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/ + 相对于 104.二叉树的最大深度 ,本题还也可以使用层序遍历的方式来解决,思路是一样的。 **需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点** @@ -1597,7 +1599,35 @@ public: Java: -Python: +Python 3: + +```python 3 +# 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 minDepth(self, root: TreeNode) -> int: + if root == None: + return 0 + + #根节点的深度为1 + queue_ = [(root,1)] + while queue_: + cur, depth = queue_.pop(0) + + if cur.left == None and cur.right == None: + return depth + #先左子节点,由于左子节点没有孩子,则就是这一层了 + if cur.left: + queue_.append((cur.left,depth + 1)) + if cur.right: + queue_.append((cur.right,depth + 1)) + + return 0 +``` Go: From e6571ecaac55a91a557b32248560ef5fac612cf1 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 17:30:36 +0800 Subject: [PATCH 13/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200541.=E5=8F=8D?= =?UTF-8?q?=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2II.md=20python=E9=83=A8?= =?UTF-8?q?=E5=88=86=EF=BC=8C=E5=8E=BB=E9=99=A4=E8=87=AA=E9=80=A0=E8=BD=AE?= =?UTF-8?q?=E5=AD=90=E9=83=A8=E5=88=86=EF=BC=8C=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=8F=AF=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 维持原方法的思路,简化了包和匿名函数的用法 原代码使用了reduce包 + 匿名函数来实现 ''.join的操作,去除该部分提升运行效率 --- problems/0541.反转字符串II.md | 35 ++++++++++++------------------ 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/problems/0541.反转字符串II.md b/problems/0541.反转字符串II.md index ab1ef16a..02713c65 100644 --- a/problems/0541.反转字符串II.md +++ b/problems/0541.反转字符串II.md @@ -155,34 +155,27 @@ class Solution { Python: ```python - -class Solution(object): - def reverseStr(self, s, k): +class Solution: + def reverseStr(self, s: str, k: int) -> str: """ - :type s: str - :type k: int - :rtype: str + 1. 使用range(start, end, step)来确定需要调换的初始位置 + 2. 对于字符串s = 'abc',如果使用s[0:999] ===> 'abc'。字符串末尾如果超过最大长度,则会返回至字符串最后一个值,这个特性可以避免一些边界条件的处理。 + 3. 用切片整体替换,而不是一个个替换. """ - from functools import reduce - # turn s into a list - s = list(s) - - # another way to simply use a[::-1], but i feel this is easier to understand - def reverse(s): - left, right = 0, len(s) - 1 + def reverse_substring(text): + left, right = 0, len(text) - 1 while left < right: - s[left], s[right] = s[right], s[left] + text[left], text[right] = text[right], text[left] left += 1 right -= 1 - return s + return text - # make sure we reverse each 2k elements - for i in range(0, len(s), 2*k): - s[i:(i+k)] = reverse(s[i:(i+k)]) - - # combine list into str. - return reduce(lambda a, b: a+b, s) + res = list(s) + + for cur in range(0, len(s), 2 * k): + res[cur: cur + k] = reverse_substring(res[cur: cur + k]) + return ''.join(res) ``` From 51e719a4351fb97ed41ad6995bc6470d5204ad35 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 17:57:39 +0800 Subject: [PATCH 14/39] =?UTF-8?q?=E7=AE=80=E5=8C=96=20=E5=89=91=E6=8C=87Of?= =?UTF-8?q?fer05.=E6=9B=BF=E6=8D=A2=E7=A9=BA=E6=A0=BC.md=20python=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 减少不必要的变量使用,优化空间复杂度,使用切片替换而不是单个替换 --- problems/剑指Offer05.替换空格.md | 58 +++++++++----------------- 1 file changed, 20 insertions(+), 38 deletions(-) diff --git a/problems/剑指Offer05.替换空格.md b/problems/剑指Offer05.替换空格.md index 4ae5f9f2..3f373d0d 100644 --- a/problems/剑指Offer05.替换空格.md +++ b/problems/剑指Offer05.替换空格.md @@ -202,45 +202,27 @@ func replaceSpace(s string) string { python: ```python -class Solution(object): - def replaceSpace(self, s): - """ - :type s: str - :rtype: str - """ - list_s = list(s) - - # 记录原本字符串的长度 - original_end = len(s) - - # 将空格改成%20 使得字符串总长增长 2n,n为原本空格数量。 - # 所以记录空格数量就可以得到目标字符串的长度 - n_space = 0 - for ss in s: - if ss == ' ': - n_space += 1 - - list_s += ['0'] * 2 * n_space - - # 设置左右指针位置 - left, right = original_end - 1, len(list_s) - 1 - - # 循环直至左指针越界 - while left >= 0: - if list_s[left] == ' ': - list_s[right] = '0' - list_s[right - 1] = '2' - list_s[right - 2] = '%' - right -= 3 - else: - list_s[right] = list_s[left] - right -= 1 - - left -= 1 +class Solution: + def replaceSpace(self, s: str) -> str: + counter = s.count(' ') - # 将list变回str,输出 - s = ''.join(list_s) - return s + res = list(s) + # 每碰到一个空格就多拓展两个格子,1 + 2 = 3个位置存’%20‘ + res.extend([' '] * counter * 2) + + # 原始字符串的末尾,拓展后的末尾 + left, right = len(s) - 1, len(res) - 1 + + while left >= 0: + if res[left] != ' ': + res[right] = res[left] + right -= 1 + else: + # [right - 2, right), 左闭右开 + res[right - 2: right + 1] = '%20' + right -= 3 + left -= 1 + return ''.join(res) ``` From 6255eae04cefc676d243bc53ea4070bc900b3c99 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 21:01:20 +0800 Subject: [PATCH 15/39] =?UTF-8?q?=E8=A1=A5=E5=85=85=20=E5=89=91=E6=8C=87Of?= =?UTF-8?q?fer58-II.=E5=B7=A6=E6=97=8B=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?.md=20python=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 如果不让使用自带函数reversed() 可以使用该方法 --- problems/剑指Offer58-II.左旋转字符串.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md index 1073dafa..6070f85b 100644 --- a/problems/剑指Offer58-II.左旋转字符串.md +++ b/problems/剑指Offer58-II.左旋转字符串.md @@ -136,13 +136,28 @@ class Solution: # return "".join(s) +# 方法三:如果连reversed也不让使用,那么自己手写一个 +class Solution: + def reverseLeftWords(self, s: str, n: int) -> str: + def reverse_sub(lst, left, right): + while left < right: + lst[left], lst[right] = lst[right], lst[left] + left += 1 + right -= 1 + + res = list(s) + end = len(res) - 1 + reverse_sub(res, 0, n - 1) + reverse_sub(res, n, end) + reverse_sub(res, 0, end) + return ''.join(res) # 时间复杂度:O(n) # 空间复杂度:O(n),python的string为不可变,需要开辟同样大小的list空间来修改 ``` ```python 3 -#方法三:考虑不能用切片的情况下,利用模+下标实现 +#方法四:考虑不能用切片的情况下,利用模+下标实现 class Solution: def reverseLeftWords(self, s: str, n: int) -> str: new_s = '' From 1a82f98a175ab03569c67a436b093203ab343d20 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Thu, 19 Aug 2021 21:04:57 +0800 Subject: [PATCH 16/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20=E5=89=91=E6=8C=87Of?= =?UTF-8?q?fer58-II.=E5=B7=A6=E6=97=8B=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2?= =?UTF-8?q?.md=20=E6=A0=BC=E5=BC=8F=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新排版 --- .../剑指Offer58-II.左旋转字符串.md | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md index 6070f85b..15607a50 100644 --- a/problems/剑指Offer58-II.左旋转字符串.md +++ b/problems/剑指Offer58-II.左旋转字符串.md @@ -125,17 +125,21 @@ python: class Solution: def reverseLeftWords(self, s: str, n: int) -> str: return s[n:] + s[0:n] - +``` +```python # 方法二:也可以使用上文描述的方法,有些面试中不允许使用切片,那就使用上文作者提到的方法 -# class Solution: -# def reverseLeftWords(self, s: str, n: int) -> str: -# s = list(s) -# s[0:n] = list(reversed(s[0:n])) -# s[n:] = list(reversed(s[n:])) -# s.reverse() +class Solution: + def reverseLeftWords(self, s: str, n: int) -> str: + s = list(s) + s[0:n] = list(reversed(s[0:n])) + s[n:] = list(reversed(s[n:])) + s.reverse() + + return "".join(s) -# return "".join(s) +``` +```python # 方法三:如果连reversed也不让使用,那么自己手写一个 class Solution: def reverseLeftWords(self, s: str, n: int) -> str: @@ -152,8 +156,10 @@ class Solution: reverse_sub(res, 0, end) return ''.join(res) +# 同方法二 # 时间复杂度:O(n) # 空间复杂度:O(n),python的string为不可变,需要开辟同样大小的list空间来修改 + ``` ```python 3 From bf92f955a3442d29c8c9f3e409d814ab644a63d1 Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Thu, 19 Aug 2021 21:45:44 +0800 Subject: [PATCH 17/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=201002.=E6=9F=A5?= =?UTF-8?q?=E6=89=BE=E5=B8=B8=E7=94=A8=E5=AD=97=E7=AC=A6=20GO=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 1002.查找常用字符 GO版本 --- problems/1002.查找常用字符.md | 36 ++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/problems/1002.查找常用字符.md b/problems/1002.查找常用字符.md index 723e5656..a789373b 100644 --- a/problems/1002.查找常用字符.md +++ b/problems/1002.查找常用字符.md @@ -233,7 +233,41 @@ var commonChars = function (words) { return res }; ``` - +GO +```golang +func commonChars(words []string) []string { + length:=len(words) + fre:=make([][]int,0)//统计每个字符串的词频 + res:=make([]string,0) + //统计词频 + for i:=0;ib{ + return b + } + return a +} +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) From d51d819060914d89b4eb89bd9a9495e48a10ab22 Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Thu, 19 Aug 2021 22:02:21 +0800 Subject: [PATCH 18/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200349.=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=95=B0=E7=BB=84=E7=9A=84=E4=BA=A4=E9=9B=86=20go?= =?UTF-8?q?=E7=89=88=E6=9C=AC=EF=BC=88=E5=88=A9=E7=94=A8set=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E7=94=A8=E7=BB=9F=E8=AE=A1=E6=AC=A1=E6=95=B0=EF=BC=8C?= =?UTF-8?q?=E5=87=8F=E5=B0=91=E7=A9=BA=E9=97=B4=E5=A4=8D=E6=9D=82=E5=BA=A6?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新 0349.两个数组的交集 go版本(利用set,不用统计次数,减少空间复杂度) --- problems/0349.两个数组的交集.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0349.两个数组的交集.md b/problems/0349.两个数组的交集.md index 7489352d..62abf639 100644 --- a/problems/0349.两个数组的交集.md +++ b/problems/0349.两个数组的交集.md @@ -143,6 +143,26 @@ func intersection(nums1 []int, nums2 []int) []int { return res } ``` +```golang +//优化版,利用set,减少count统计 +func intersection(nums1 []int, nums2 []int) []int { + set:=make(map[int]struct{},0) + res:=make([]int,0) + for _,v:=range nums1{ + if _,ok:=set[v];!ok{ + set[v]=struct{}{} + } + } + for _,v:=range nums2{ + //如果存在于上一个数组中,则加入结果集,并清空该set值 + if _,ok:=set[v];ok{ + res=append(res,v) + delete(set, v) + } + } + return res +} +``` javaScript: From a69006f901230b1ba73e73ce8b86918b404480e4 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 00:06:33 +0800 Subject: [PATCH 19/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200232.=E7=94=A8?= =?UTF-8?q?=E6=A0=88=E5=AE=9E=E7=8E=B0=E9=98=9F=E5=88=97.md=20python?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit python代码简化,符合PEP8标准,可读性加强,效率提升 --- problems/0232.用栈实现队列.md | 50 ++++++++++++++++------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md index 0df82d35..46d884d3 100644 --- a/problems/0232.用栈实现队列.md +++ b/problems/0232.用栈实现队列.md @@ -281,48 +281,54 @@ class MyQueue { Python: ```python -# 使用两个栈实现先进先出的队列 class MyQueue: + def __init__(self): """ - Initialize your data structure here. + in主要负责push,out主要负责pop """ - self.stack1 = list() - self.stack2 = list() + self.stack_in = [] + self.stack_out = [] + def push(self, x: int) -> None: """ - Push element x to the back of queue. + 有新元素进来,就往in里面push """ - # self.stack1用于接受元素 - self.stack1.append(x) + self.stack_in.append(x) + def pop(self) -> int: """ - Removes the element from in front of queue and returns that element. + 1. 检查如果out里面元素,则直接pop + 2. 如果out没有元素,就把in里面的元素(除了第一个)依次pop后装进out里面 + 3. 直接把in剩下的元素pop出来,就是queue头部的 """ - # 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() + if self.stack_out: + return self.stack_out.pop() + else: + for i in range(1, len(self.stack_in)): + self.stack_out.append(self.stack_in.pop()) + return self.stack_in.pop() + def peek(self) -> int: """ - Get the front element. + 1. 查out有没有元素,有就把最上面的返回 + 2. 如果out没有元素,就把in最下面的返回 """ - if self.stack2 == []: - while self.stack1: - tmp = self.stack1.pop() - self.stack2.append(tmp) - return self.stack2[-1] + if self.stack_out: + return self.stack_out[-1] + else: + return self.stack_in[0] + def empty(self) -> bool: """ - Returns whether the queue is empty. + 只要in或者out有元素,说明队列不为空 """ - return self.stack1 == [] and self.stack2 == [] + return not (self.stack_in or self.stack_out) + ``` From 77e789a248dc21b8b939ee37e0d5d58512e90d8d Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 01:49:06 +0800 Subject: [PATCH 20/39] =?UTF-8?q?=E7=AE=80=E5=8C=96=200225.=E7=94=A8?= =?UTF-8?q?=E9=98=9F=E5=88=97=E5=AE=9E=E7=8E=B0=E6=A0=88.md=20python?= =?UTF-8?q?=E9=83=A8=E5=88=86=EF=BC=8C=E5=86=97=E4=BD=99=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=A4=AA=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原方法用了很多不必要的变量和操作,改进后的代码更直观,效率和空间都得到了优化 --- problems/0225.用队列实现栈.md | 65 +++++++++++++++++------------ 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md index b327c17b..d82220db 100644 --- a/problems/0225.用队列实现栈.md +++ b/problems/0225.用队列实现栈.md @@ -294,53 +294,66 @@ Python: ```python from collections import deque + class MyStack: + def __init__(self): """ - Initialize your data structure here. + Python普通的Queue或SimpleQueue没有类似于peek的功能 + 也无法用索引访问,在实现top的时候较为困难。 + + 用list可以,但是在使用pop(0)的时候时间复杂度为O(1) + 因此这里使用双向队列,我们保证只执行popleft()和append(),因为deque可以用索引访问,可以实现和peek相似的功能 + + in - 存所有数据 + out - 仅在pop的时候会用到 """ - #使用两个队列来实现 - self.que1 = deque() - self.que2 = deque() + self.queue_in = deque() + self.queue_out = deque() def push(self, x: int) -> None: """ - Push element x onto stack. + 直接append即可 """ - self.que1.append(x) + self.queue_in.append(x) + def pop(self) -> int: """ - Removes the element on top of the stack and returns that element. + 1. 首先确认不空 + 2. 因为队列的特殊性,FIFO,所以我们只有在pop()的时候才会使用queue_out + 3. 先把queue_in中的所有元素(除了最后一个),依次出列放进queue_out + 4. 交换in和out,此时out里只有一个元素 + 5. 把out中的pop出来,即是原队列的最后一个 + + tip:这不能像栈实现队列一样,因为另一个queue也是FIFO,如果执行pop()它不能像 + stack一样从另一个pop(),所以干脆in只用来存数据,pop()的时候两个进行交换 """ - size = len(self.que1) - size -= 1#这里先减一是为了保证最后面的元素 - while size > 0: - size -= 1 - self.que2.append(self.que1.popleft()) + if self.empty(): + return None - - result = self.que1.popleft() - self.que1, self.que2= self.que2, self.que1#将que2和que1交换 que1经过之前的操作应该是空了 - #一定注意不能直接使用que1 = que2 这样que2的改变会影响que1 可以用浅拷贝 - return result + for i in range(len(self.queue_in) - 1): + self.queue_out.append(self.queue_in.popleft()) + + self.queue_in, self.queue_out = self.queue_out, self.queue_in # 交换in和out,这也是为啥in只用来存 + return self.queue_out.popleft() def top(self) -> int: """ - Get the top element. + 1. 首先确认不空 + 2. 我们仅有in会存放数据,所以返回第一个即可 """ - return self.que1[-1] + if self.empty(): + return None + + return self.queue_in[-1] + def empty(self) -> bool: """ - Returns whether the stack is empty. + 因为只有in存了数据,只要判断in是不是有数即可 """ - #print(self.que1) - if len(self.que1) == 0: - return True - else: - return False - + return len(self.queue_in) == 0 ``` From 55eb649434a95116e0fdcde2a89db5be1f85d801 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 01:50:53 +0800 Subject: [PATCH 21/39] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=200225.=E7=94=A8?= =?UTF-8?q?=E9=98=9F=E5=88=97=E5=AE=9E=E7=8E=B0=E6=A0=88.md=EF=BC=8Cdoc?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 时间复杂度错误,修正 --- problems/0225.用队列实现栈.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md index d82220db..ccf93f1f 100644 --- a/problems/0225.用队列实现栈.md +++ b/problems/0225.用队列实现栈.md @@ -302,7 +302,7 @@ class MyStack: Python普通的Queue或SimpleQueue没有类似于peek的功能 也无法用索引访问,在实现top的时候较为困难。 - 用list可以,但是在使用pop(0)的时候时间复杂度为O(1) + 用list可以,但是在使用pop(0)的时候时间复杂度为O(n) 因此这里使用双向队列,我们保证只执行popleft()和append(),因为deque可以用索引访问,可以实现和peek相似的功能 in - 存所有数据 From 571defa00789aa9764abb6aa7efe54944ed42a49 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 02:15:03 +0800 Subject: [PATCH 22/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200020.=E6=9C=89?= =?UTF-8?q?=E6=95=88=E7=9A=84=E6=8B=AC=E5=8F=B7.md=20python=E9=83=A8?= =?UTF-8?q?=E5=88=86=E9=A2=9D=E5=A4=96=E6=96=B9=E6=B3=95=E6=8F=90=E4=BE=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 补充了题主的方法,改写了原先冗余的做法,可读性提升,PEP8标准 --- problems/0020.有效的括号.md | 44 +++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/problems/0020.有效的括号.md b/problems/0020.有效的括号.md index a26aa308..57729c38 100644 --- a/problems/0020.有效的括号.md +++ b/problems/0020.有效的括号.md @@ -162,18 +162,44 @@ class Solution { Python: ```python3 +# 方法一,仅使用栈,更省空间 class Solution: def isValid(self, s: str) -> bool: - stack = [] # 保存还未匹配的左括号 - mapping = {")": "(", "]": "[", "}": "{"} - for i in s: - if i in "([{": # 当前是左括号,则入栈 - stack.append(i) - elif stack and stack[-1] == mapping[i]: # 当前是配对的右括号则出栈 - stack.pop() - else: # 不是匹配的右括号或者没有左括号与之匹配,则返回false + stack = [] + + for item in s: + if item == '(': + stack.append(')') + elif item == '[': + stack.append(']') + elif item == '{': + stack.append('}') + elif not stack or stack[-1] != item: return False - return stack == [] # 最后必须正好把左括号匹配完 + else: + stack.pop() + + return True if not stack else False +``` + +```python3 +# 方法二,使用字典 +class Solution: + def isValid(self, s: str) -> bool: + stack = [] + mapping = { + '(': ')', + '[': ']', + '{': '}' + } + for item in s: + if item in mapping.keys(): + stack.append(mapping[item]) + elif not stack or stack[-1] != item: + return False + else: + stack.pop() + return True if not stack else False ``` Go: From ce2c6fb562ae22b2b18230d8f00202f67c89c696 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 02:55:31 +0800 Subject: [PATCH 23/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0+=E8=A1=A5=E5=85=85=201?= =?UTF-8?q?047.=E5=88=A0=E9=99=A4=E5=AD=97=E7=AC=A6=E4=B8=B2=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E6=89=80=E6=9C=89=E7=9B=B8=E9=82=BB=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E9=A1=B9.md=20python=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 补充使用双指针的方法,但是更推荐栈的做法 --- ...除字符串中的所有相邻重复项.md | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index c4ae85c9..7b059d40 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -197,15 +197,38 @@ class Solution { Python: ```python3 +# 方法一,使用栈,推荐! class Solution: def removeDuplicates(self, s: str) -> str: - t = list() - for i in s: - if t and t[-1] == i: - t.pop(-1) + res = list() + for item in s: + if res and res[-1] == item: + t.pop() else: - t.append(i) - return "".join(t) # 字符串拼接 + t.append(item) + return "".join(res) # 字符串拼接 +``` + +```python3 +# 双指针 +class Solution: + def removeDuplicates(self, s: str) -> str: + res = list(s) + slow = fast = 0 + length = len(res) + + while fast < length: + # 如果一样直接换,不一样会把后面的填在slow的位置 + res[slow] = res[fast] + + # 如果发现和前一个一样,就退一格指针 + if slow > 0 and res[slow] == res[slow - 1]: + slow -= 1 + else: + slow += 1 + fast += 1 + + return ''.join(res[0: slow]) ``` Go: From 13293e8c2f0e30743848e632244cc1a112e0422c Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 02:58:09 +0800 Subject: [PATCH 24/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0=201047.=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=AD=97=E7=AC=A6=E4=B8=B2=E4=B8=AD=E7=9A=84=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=9B=B8=E9=82=BB=E9=87=8D=E5=A4=8D=E9=A1=B9.md=20pyt?= =?UTF-8?q?hon=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1047.删除字符串中的所有相邻重复项.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 7b059d40..1d63e7f8 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -210,7 +210,7 @@ class Solution: ``` ```python3 -# 双指针 +# 方法二,使用双指针模拟栈,如果不让用栈可以作为备选方法。 class Solution: def removeDuplicates(self, s: str) -> str: res = list(s) From 5e3d23fa38c78b9e66f12bd0e768968d7f31ed6c Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 02:59:10 +0800 Subject: [PATCH 25/39] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=201047.=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=AD=97=E7=AC=A6=E4=B8=B2=E4=B8=AD=E7=9A=84=E6=89=80?= =?UTF-8?q?=E6=9C=89=E7=9B=B8=E9=82=BB=E9=87=8D=E5=A4=8D=E9=A1=B9.md=20pyt?= =?UTF-8?q?hon=E6=96=B9=E6=B3=95=E4=B8=80=E4=BB=A3=E7=A0=81=E7=9A=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1047.删除字符串中的所有相邻重复项.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 1d63e7f8..b60a8d1d 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -203,9 +203,9 @@ class Solution: res = list() for item in s: if res and res[-1] == item: - t.pop() + res.pop() else: - t.append(item) + res.append(item) return "".join(res) # 字符串拼接 ``` From 8b94306cc6030eb79f2a8376b01f6398d888f7ed Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 03:23:30 +0800 Subject: [PATCH 26/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200024.=E4=B8=A4?= =?UTF-8?q?=E4=B8=A4=E4=BA=A4=E6=8D=A2=E9=93=BE=E8=A1=A8=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E8=8A=82=E7=82=B9.md=20python=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用变量名使交换的过程更加清晰,而不是使用之前的next.next这样可读性较差 从后往前换 pre = dummy,cur = 2, post=3 dummpy -> 1 -> 2 -> None 先把cur.next = post.next,此时链表为 1 -> None 再 post.next = cur 此时链表为 2 -> 1 -> None, dummpy -> 1 -> None 最后 pre.next = post, 此时为 dummpy -> 2 -> 1 -> None --- .../0024.两两交换链表中的节点.md | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 91e566dd..672b9a8f 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -160,21 +160,29 @@ 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 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 #记录临时节点 + res = ListNode(next=head) + pre = res + + # 必须有pre的下一个和下下个才能交换,否则说明已经交换结束了 + while pre.next and pre.next.next: + cur = pre.next + post = pre.next.next - cur.next = cur.next.next #步骤一 - cur.next.next = tmp #步骤二 - cur.next.next.next = tmp1 #步骤三 - - cur = cur.next.next #cur移动两位,准备下一轮交换 - return dummy.next + # pre,cur,post对应最左,中间的,最右边的节点 + cur.next = post.next + post.next = cur + pre.next = post + + pre = pre.next.next + return res.next ``` Go: From ca576c5bd0a62769c4b080028e7092d7fb945890 Mon Sep 17 00:00:00 2001 From: Eyjan_Huang <81480748+Eyjan-Huang@users.noreply.github.com> Date: Fri, 20 Aug 2021 03:29:26 +0800 Subject: [PATCH 27/39] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=200232.=E7=94=A8?= =?UTF-8?q?=E6=A0=88=E5=AE=9E=E7=8E=B0=E9=98=9F=E5=88=97.md=20python?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加限制条件,仅在栈不为空的情况下才允许后续pop()和peek()的操作 --- problems/0232.用栈实现队列.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md index 46d884d3..27a3de4e 100644 --- a/problems/0232.用栈实现队列.md +++ b/problems/0232.用栈实现队列.md @@ -304,6 +304,9 @@ class MyQueue: 2. 如果out没有元素,就把in里面的元素(除了第一个)依次pop后装进out里面 3. 直接把in剩下的元素pop出来,就是queue头部的 """ + if self.empty: + return None + if self.stack_out: return self.stack_out.pop() else: @@ -317,6 +320,9 @@ class MyQueue: 1. 查out有没有元素,有就把最上面的返回 2. 如果out没有元素,就把in最下面的返回 """ + if self.empty: + return None + if self.stack_out: return self.stack_out[-1] else: From b3ac4e3b2a20e9063c8294a40720a062d8c1f1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=81=E5=AE=A2=E5=AD=A6=E4=BC=9F?= Date: Thu, 19 Aug 2021 16:33:56 +0800 Subject: [PATCH 28/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=2024.=20=E4=B8=A4?= =?UTF-8?q?=E4=B8=A4=E4=BA=A4=E6=8D=A2=E9=93=BE=E8=A1=A8=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E8=8A=82=E7=82=B9=20Swift=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0024.两两交换链表中的节点.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 91e566dd..55a6bb50 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -248,6 +248,27 @@ fun swapPairs(head: ListNode?): ListNode? { } ``` +Swift: +```swift +func swapPairs(_ head: ListNode?) -> ListNode? { + if head == nil || head?.next == nil { + return head + } + let dummyHead: ListNode = ListNode(-1, head) + var current: ListNode? = dummyHead + while current?.next != nil && current?.next?.next != nil { + let temp1 = current?.next + let temp2 = current?.next?.next?.next + + current?.next = current?.next?.next + current?.next?.next = temp1 + current?.next?.next?.next = temp2 + + current = current?.next?.next + } + return dummyHead.next +} +``` ----------------------- From 3e754148100b7bf5894e9ab543121613fb0c8cb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=81=E5=AE=A2=E5=AD=A6=E4=BC=9F?= Date: Fri, 20 Aug 2021 13:37:18 +0800 Subject: [PATCH 29/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=2019.=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E9=93=BE=E8=A1=A8=E7=9A=84=E5=80=92=E6=95=B0=E7=AC=AC?= =?UTF-8?q?N=E4=B8=AA=E8=8A=82=E7=82=B9=20Swift=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0019.删除链表的倒数第N个节点.md | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/problems/0019.删除链表的倒数第N个节点.md b/problems/0019.删除链表的倒数第N个节点.md index 3e1a682c..4d3e57db 100644 --- a/problems/0019.删除链表的倒数第N个节点.md +++ b/problems/0019.删除链表的倒数第N个节点.md @@ -204,6 +204,31 @@ fun removeNthFromEnd(head: ListNode?, n: Int): ListNode? { } ``` +Swift: +```swift +func removeNthFromEnd(_ head: ListNode?, _ n: Int) -> ListNode? { + if head == nil { + return nil + } + if n == 0 { + return head + } + let dummyHead = ListNode(-1, head) + var fast: ListNode? = dummyHead + var slow: ListNode? = dummyHead + // fast 前移 n + for _ in 0 ..< n { + fast = fast?.next + } + while fast?.next != nil { + fast = fast?.next + slow = slow?.next + } + slow?.next = slow?.next?.next + return dummyHead.next +} +``` + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) From 0498cf3935ead6fdf06495e00004ed8e6f2146e3 Mon Sep 17 00:00:00 2001 From: binglu18 <57309010+binglu18@users.noreply.github.com> Date: Fri, 20 Aug 2021 15:33:59 +0800 Subject: [PATCH 30/39] =?UTF-8?q?=E8=A1=A5=E5=85=850102.=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=A0=91=E7=9A=84=E5=B1=82=E5=BA=8F=E9=81=8D=E5=8E=86.md=20515?= =?UTF-8?q?=E9=A2=98java=E8=A7=A3=E6=B3=95=E4=BA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0102.二叉树的层序遍历.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 0f9b2df6..4a26d853 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -1070,6 +1070,29 @@ class Solution { return retVal; } } + +方法二:用一个max变量来保存最大值 +class Solution { + public List largestValues(TreeNode root) { + Queue queue = new LinkedList(); + List result = new ArrayList<>(); + if (root!=null) queue.add(root); + while(!queue.isEmpty()){ + int size = queue.size(); + int max = Integer.MIN_VALUE; // 初始化为最小值 + for(int i=0;i Date: Fri, 20 Aug 2021 15:37:35 +0800 Subject: [PATCH 31/39] =?UTF-8?q?update=20=E6=96=B9=E6=B3=95=E4=BA=8C=2001?= =?UTF-8?q?02.=E4=BA=8C=E5=8F=89=E6=A0=91=E7=9A=84=E5=B1=82=E5=BA=8F?= =?UTF-8?q?=E9=81=8D=E5=8E=86.md=20515=E9=A2=98java=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0102.二叉树的层序遍历.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 4a26d853..15d00af2 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -1070,8 +1070,10 @@ class Solution { return retVal; } } +``` -方法二:用一个max变量来保存最大值 +```java +//方法二:用一个max变量来保存最大值 class Solution { public List largestValues(TreeNode root) { Queue queue = new LinkedList(); From 07d27158b238812f603f250794b9a681f71e7f8e Mon Sep 17 00:00:00 2001 From: binglu18 <57309010+binglu18@users.noreply.github.com> Date: Fri, 20 Aug 2021 16:10:24 +0800 Subject: [PATCH 32/39] =?UTF-8?q?update=200102.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E5=B1=82=E5=BA=8F=E9=81=8D=E5=8E=86.md=20515java?= =?UTF-8?q?=E8=A7=A3=E6=B3=95=E4=BA=8Cformat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0102.二叉树的层序遍历.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 15d00af2..d0f584fe 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -1078,16 +1078,17 @@ class Solution { public List largestValues(TreeNode root) { Queue queue = new LinkedList(); List result = new ArrayList<>(); - if (root!=null) queue.add(root); + if (root != null) queue.add(root); + while(!queue.isEmpty()){ int size = queue.size(); int max = Integer.MIN_VALUE; // 初始化为最小值 - for(int i=0;i Date: Fri, 20 Aug 2021 17:14:16 +0800 Subject: [PATCH 33/39] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200150.=E9=80=86?= =?UTF-8?q?=E6=B3=A2=E5=85=B0=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=B1=82=E5=80=BC?= =?UTF-8?q?.md=20python=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用format string提升效率,增加可读性,避免使用索引访问,直接使用切片。 --- problems/0150.逆波兰表达式求值.md | 24 ++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md index 2b294337..bcde7d5b 100644 --- a/problems/0150.逆波兰表达式求值.md +++ b/problems/0150.逆波兰表达式求值.md @@ -223,17 +223,19 @@ var evalRPN = function(tokens) { 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] +class Solution: + def evalRPN(self, tokens: List[str]) -> int: + stack = [] + for item in tokens: + if item not in {"+", "-", "*", "/"}: + stack.append(item) + else: + first_num, second_num = stack.pop(), stack.pop() + stack.append( + int(eval(f'{second_num} {item} {first_num}')) # 第一个出来的在运算符后面 + ) + return int(stack.pop()) # 如果一开始只有一个数,那么会是字符串形式的 + ``` From f07fb2fd195b54809474dd8e4997e2654f453f04 Mon Sep 17 00:00:00 2001 From: ColorQian <82574279+ColorQian@users.noreply.github.com> Date: Sat, 21 Aug 2021 17:21:06 +0800 Subject: [PATCH 34/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=200102.=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91=E7=9A=84=E5=B1=82=E5=BA=8F=E9=81=8D=E5=8E=86?= =?UTF-8?q?.md=20=E4=B8=AD=E7=9A=84=20=20111.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E6=9C=80=E5=B0=8F=E6=B7=B1=E5=BA=A6=20=E7=9A=84java?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0102.二叉树的层序遍历.md | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index dde5af47..b9bc05e0 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -1597,6 +1597,43 @@ public: ``` Java: +```java +class Solution { + + public int minDepth(TreeNode root){ + if (root == null) { + return 0; + } + + Queue queue = new LinkedList<>(); + queue.offer(root); + int depth = 0; + + while (!queue.isEmpty()){ + + int size = queue.size(); + depth++; + + TreeNode cur = null; + for (int i = 0; i < size; i++) { + cur = queue.poll(); + + //如果当前节点的左右孩子都为空,直接返回最小深度 + if (cur.left == null && cur.right == null){ + return depth; + } + + if (cur.left != null) queue.offer(cur.left); + if (cur.right != null) queue.offer(cur.right); + } + + + } + + return depth; + } +} +``` Python 3: From 34444b3a4d7c5fb5eb9d9bc61bc300c47e08a39d Mon Sep 17 00:00:00 2001 From: yqq Date: Sat, 21 Aug 2021 18:00:54 +0800 Subject: [PATCH 35/39] fix 0494 --- problems/0494.目标和.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/problems/0494.目标和.md b/problems/0494.目标和.md index 77b3c76d..5d89f7dc 100644 --- a/problems/0494.目标和.md +++ b/problems/0494.目标和.md @@ -19,15 +19,15 @@ 示例: -输入:nums: [1, 1, 1, 1, 1], S: 3 -输出:5 +输入: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 -+1+1+1-1+1 = 3 -+1+1+1+1-1 = 3 +解释: +-1+1+1+1+1 = 3 ++1-1+1+1+1 = 3 ++1+1-1+1+1 = 3 ++1+1+1-1+1 = 3 ++1+1+1+1-1 = 3 一共有5种方法让最终目标和为3。 @@ -202,6 +202,7 @@ public: for (int i = 0; i < nums.size(); i++) sum += nums[i]; if (S > sum) return 0; // 此时没有方案 if ((S + sum) % 2 == 1) return 0; // 此时没有方案 + if (S + sum < 0) return 0; // 以确保bagSize为正数 int bagSize = (S + sum) / 2; vector dp(bagSize + 1, 0); dp[0] = 1; @@ -311,7 +312,7 @@ Javascript: const findTargetSumWays = (nums, target) => { const sum = nums.reduce((a, b) => a+b); - + if(target > sum) { return 0; } From 4e19ab8d0072e9007e782fad643723000e0c7727 Mon Sep 17 00:00:00 2001 From: XuDaHaoRen <1547794387@qq.com> Date: Sat, 21 Aug 2021 21:21:03 +0800 Subject: [PATCH 36/39] =?UTF-8?q?C:/Program=20Files/Git/problems/1-40?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=93=BE=E6=8E=A5=E2=80=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0005.最长回文子串.md | 6 ++--- problems/0015.三数之和.md | 10 +++---- problems/0017.电话号码的字母组合.md | 18 ++++++------- problems/0018.四数之和.md | 26 +++++++++---------- ...0019.删除链表的倒数第N个节点.md | 4 +-- problems/0020.有效的括号.md | 2 +- .../0024.两两交换链表中的节点.md | 4 +-- problems/0027.移除元素.md | 6 ++--- problems/0028.实现strStr.md | 2 +- problems/0031.下一个排列.md | 2 +- ...元素的第一个和最后一个位置.md | 8 +++--- problems/0035.搜索插入位置.md | 2 +- problems/0037.解数独.md | 8 +++--- problems/0039.组合总和.md | 18 ++++++------- problems/0040.组合总和II.md | 16 ++++++------ problems/0042.接雨水.md | 6 ++--- problems/0045.跳跃游戏II.md | 6 ++--- problems/0046.全排列.md | 8 +++--- problems/0047.全排列II.md | 8 +++--- 19 files changed, 80 insertions(+), 80 deletions(-) diff --git a/problems/0005.最长回文子串.md b/problems/0005.最长回文子串.md index de20feeb..c78b827c 100644 --- a/problems/0005.最长回文子串.md +++ b/problems/0005.最长回文子串.md @@ -10,7 +10,7 @@ # 5.最长回文子串 -题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/ +[力扣题目链接](https://leetcode-cn.com/problems/longest-palindromic-substring/) 给你一个字符串 s,找到 s 中最长的回文子串。 @@ -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.回文子串 ## 暴力解法 diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md index 9a3a8d5b..ac5561f2 100644 --- a/problems/0015.三数之和.md +++ b/problems/0015.三数之和.md @@ -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 ?请你找出所有满足条件且不重复的三元组。 @@ -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)要求返回的是数值的话,就可以使用双指针法了。 diff --git a/problems/0017.电话号码的字母组合.md b/problems/0017.电话号码的字母组合.md index 7aa72e1b..1ebf6f49 100644 --- a/problems/0017.电话号码的字母组合.md +++ b/problems/0017.电话号码的字母组合.md @@ -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 的字符串,返回所有它能表示的字母组合。 @@ -29,7 +29,7 @@ 如果输入"233"呢,那么就三层for循环,如果"2333"呢,就四层for循环....... -大家应该感觉出和[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)遇到的一样的问题,就是这for循环的层数如何写出来,此时又是回溯法登场的时候了。 +大家应该感觉出和[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)遇到的一样的问题,就是这for循环的层数如何写出来,此时又是回溯法登场的时候了。 理解本题后,要解决如下三个问题: @@ -58,7 +58,7 @@ const string letterMap[10] = { ## 回溯法来解决n个for循环的问题 -对于回溯法还不了解的同学看这篇:[关于回溯算法,你该了解这些!](https://mp.weixin.qq.com/s/gjSgJbNbd1eAA5WkA-HeWw) +对于回溯法还不了解的同学看这篇:[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html) 例如:输入:"23",抽象为树形结构,如图所示: @@ -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也表示树的深度。 @@ -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 * #按键等等异常情况 @@ -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++ @@ -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)的区别,本题是多个集合求组合,所以在回溯的搜索过程中,都有一些细节需要注意的。 其实本题不算难,但也处处是细节,大家还要自己亲自动手写一写。 diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md index 75cd9e8e..66f06f64 100644 --- a/problems/0018.四数之和.md +++ b/problems/0018.四数之和.md @@ -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 相等?找出所有满足条件且不重复的四元组。 @@ -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) 双指针法在字符串题目中还有很多应用,后面还会介绍到。 diff --git a/problems/0019.删除链表的倒数第N个节点.md b/problems/0019.删除链表的倒数第N个节点.md index 3e1a682c..2a08cbc0 100644 --- a/problems/0019.删除链表的倒数第N个节点.md +++ b/problems/0019.删除链表的倒数第N个节点.md @@ -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 个结点,并且返回链表的头结点。 @@ -41,7 +41,7 @@ 分为如下几步: -* 首先这里我推荐大家使用虚拟头结点,这样方面处理删除实际头结点的逻辑,如果虚拟头结点不清楚,可以看这篇: [链表:听说用虚拟头节点会方便很多?](https://mp.weixin.qq.com/s/L5aanfALdLEwVWGvyXPDqA) +* 首先这里我推荐大家使用虚拟头结点,这样方面处理删除实际头结点的逻辑,如果虚拟头结点不清楚,可以看这篇: [链表:听说用虚拟头节点会方便很多?](https://programmercarl.com/0203.移除链表元素.html) * 定义fast指针和slow指针,初始值为虚拟头结点,如图: diff --git a/problems/0020.有效的括号.md b/problems/0020.有效的括号.md index a26aa308..3fbdfba6 100644 --- a/problems/0020.有效的括号.md +++ b/problems/0020.有效的括号.md @@ -12,7 +12,7 @@ # 20. 有效的括号 -https://leetcode-cn.com/problems/valid-parentheses/ +[力扣题目链接](https://leetcode-cn.com/problems/valid-parentheses/) 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 91e566dd..1926a8ca 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -9,7 +9,7 @@ ## 24. 两两交换链表中的节点 -https://leetcode-cn.com/problems/swap-nodes-in-pairs/ +[力扣题目链接](https://leetcode-cn.com/problems/swap-nodes-in-pairs/) 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 @@ -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)。 接下来就是交换相邻两个元素了,**此时一定要画图,不画图,操作多个指针很容易乱,而且要操作的先后顺序** diff --git a/problems/0027.移除元素.md b/problems/0027.移除元素.md index 3819d6a5..fadd4d7e 100644 --- a/problems/0027.移除元素.md +++ b/problems/0027.移除元素.md @@ -9,7 +9,7 @@ ## 27. 移除元素 -题目地址:https://leetcode-cn.com/problems/remove-element/ +[力扣题目链接](https://leetcode-cn.com/problems/remove-element/) 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 @@ -34,7 +34,7 @@ **要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。** -数组的基础知识可以看这里[程序员算法面试中,必须掌握的数组理论知识](https://mp.weixin.qq.com/s/c2KABb-Qgg66HrGf8z-8Og)。 +数组的基础知识可以看这里[程序员算法面试中,必须掌握的数组理论知识](https://programmercarl.com/数组理论基础.html)。 ### 暴力解法 @@ -106,7 +106,7 @@ public: * 时间复杂度:$O(n)$ * 空间复杂度:$O(1)$ -旧文链接:[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA) +旧文链接:[数组:就移除个元素很难么?](https://programmercarl.com/0027.移除元素.html) ## 相关题目推荐 diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md index 4fb418f0..481be2ed 100644 --- a/problems/0028.实现strStr.md +++ b/problems/0028.实现strStr.md @@ -11,7 +11,7 @@ # 28. 实现 strStr() -https://leetcode-cn.com/problems/implement-strstr/ +[力扣题目链接](https://leetcode-cn.com/problems/implement-strstr/) 实现 strStr() 函数。 diff --git a/problems/0031.下一个排列.md b/problems/0031.下一个排列.md index 10ac9df4..05321a9a 100644 --- a/problems/0031.下一个排列.md +++ b/problems/0031.下一个排列.md @@ -11,7 +11,7 @@ # 31.下一个排列 -链接:https://leetcode-cn.com/problems/next-permutation/ +[力扣题目链接](https://leetcode-cn.com/problems/next-permutation/) 实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 diff --git a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md index f83de1a8..68dd797d 100644 --- a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md +++ b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md @@ -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) 下面我来把所有情况都讨论一下。 @@ -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的右边界,左边界同理。 diff --git a/problems/0035.搜索插入位置.md b/problems/0035.搜索插入位置.md index 4ad8a80c..1fc07143 100644 --- a/problems/0035.搜索插入位置.md +++ b/problems/0035.搜索插入位置.md @@ -11,7 +11,7 @@ # 35.搜索插入位置 -题目地址:https://leetcode-cn.com/problems/search-insert-position/ +[力扣题目链接](https://leetcode-cn.com/problems/search-insert-position/) 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 diff --git a/problems/0037.解数独.md b/problems/0037.解数独.md index 64be7013..b6fa0d6e 100644 --- a/problems/0037.解数独.md +++ b/problems/0037.解数独.md @@ -11,7 +11,7 @@ ## 37. 解数独 -题目地址:https://leetcode-cn.com/problems/sudoku-solver/ +[力扣题目链接](https://leetcode-cn.com/problems/sudoku-solver/) 编写一个程序,通过填充空格来解决数独问题。 @@ -40,11 +40,11 @@ 怎么做二维递归呢? -大家已经跟着「代码随想录」刷过了如下回溯法题目,例如:[77.组合(组合问题)](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ),[131.分割回文串(分割问题)](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q),[78.子集(子集问题)](https://mp.weixin.qq.com/s/NNRzX-vJ_pjK4qxohd_LtA),[46.全排列(排列问题)](https://mp.weixin.qq.com/s/SCOjeMX1t41wcvJq49GhMw),以及[51.N皇后(N皇后问题)](https://mp.weixin.qq.com/s/lU_QwCMj6g60nh8m98GAWg),其实这些题目都是一维递归。 +大家已经跟着「代码随想录」刷过了如下回溯法题目,例如:[77.组合(组合问题)](https://programmercarl.com/0077.组合.html),[131.分割回文串(分割问题)](https://programmercarl.com/0131.分割回文串.html),[78.子集(子集问题)](https://programmercarl.com/0078.子集.html),[46.全排列(排列问题)](https://programmercarl.com/0046.全排列.html),以及[51.N皇后(N皇后问题)](https://programmercarl.com/0051.N皇后.html),其实这些题目都是一维递归。 **如果以上这几道题目没有做过的话,不建议上来就做这道题哈!** -[N皇后问题](https://mp.weixin.qq.com/s/lU_QwCMj6g60nh8m98GAWg)是因为每一行每一列只放一个皇后,只需要一层for循环遍历一行,递归来来遍历列,然后一行一列确定皇后的唯一位置。 +[N皇后问题](https://programmercarl.com/0051.N皇后.html)是因为每一行每一列只放一个皇后,只需要一层for循环遍历一行,递归来来遍历列,然后一行一列确定皇后的唯一位置。 本题就不一样了,**本题中棋盘的每一个位置都要放一个数字,并检查数字是否合法,解数独的树形结构要比N皇后更宽更深**。 @@ -59,7 +59,7 @@ **递归函数的返回值需要是bool类型,为什么呢?** -因为解数独找到一个符合的条件(就在树的叶子节点上)立刻就返回,相当于找从根节点到叶子节点一条唯一路径,所以需要使用bool返回值,这一点在[回溯算法:N皇后问题](https://mp.weixin.qq.com/s/lU_QwCMj6g60nh8m98GAWg)中已经介绍过了,一样的道理。 +因为解数独找到一个符合的条件(就在树的叶子节点上)立刻就返回,相当于找从根节点到叶子节点一条唯一路径,所以需要使用bool返回值,这一点在[回溯算法:N皇后问题](https://programmercarl.com/0051.N皇后.html)中已经介绍过了,一样的道理。 代码如下: diff --git a/problems/0039.组合总和.md b/problems/0039.组合总和.md index 0c452e22..8cea3b9e 100644 --- a/problems/0039.组合总和.md +++ b/problems/0039.组合总和.md @@ -9,7 +9,7 @@ ## 39. 组合总和 -题目链接:https://leetcode-cn.com/problems/combination-sum/ +[力扣题目链接](https://leetcode-cn.com/problems/combination-sum/) 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 @@ -44,14 +44,14 @@ candidates 中的数字可以无限制重复被选取。 题目中的**无限制重复被选取,吓得我赶紧想想 出现0 可咋办**,然后看到下面提示:1 <= candidates[i] <= 200,我就放心了。 -本题和[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ),[回溯算法:求组合总和!](https://mp.weixin.qq.com/s/HX7WW6ixbFZJASkRnCTC3w)和区别是:本题没有数量要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。 +本题和[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html),[回溯算法:求组合总和!](https://programmercarl.com/0216.组合总和III.html)和区别是:本题没有数量要求,可以无限重复,但是有总和的限制,所以间接的也是有个数的限制。 本题搜索的过程抽象成树形结构如下: ![39.组合总和](https://img-blog.csdnimg.cn/20201223170730367.png) 注意图中叶子节点的返回条件,因为本题没有组合数量要求,仅仅是总和的限制,所以递归没有层数的限制,只要选取的元素总和超过target,就返回! -而在[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)和[回溯算法:求组合总和!](https://mp.weixin.qq.com/s/HX7WW6ixbFZJASkRnCTC3w) 中都可以知道要递归K层,因为要取k个元素的组合。 +而在[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)和[回溯算法:求组合总和!](https://programmercarl.com/0216.组合总和III.html) 中都可以知道要递归K层,因为要取k个元素的组合。 ## 回溯三部曲 @@ -65,9 +65,9 @@ candidates 中的数字可以无限制重复被选取。 **本题还需要startIndex来控制for循环的起始位置,对于组合问题,什么时候需要startIndex呢?** -我举过例子,如果是一个集合来求组合的话,就需要startIndex,例如:[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ),[回溯算法:求组合总和!](https://mp.weixin.qq.com/s/HX7WW6ixbFZJASkRnCTC3w)。 +我举过例子,如果是一个集合来求组合的话,就需要startIndex,例如:[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html),[回溯算法:求组合总和!](https://programmercarl.com/0216.组合总和III.html)。 -如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如:[回溯算法:电话号码的字母组合](https://mp.weixin.qq.com/s/e2ua2cmkE_vpYjM3j6HY0A) +如果是多个集合取组合,各个集合之间相互不影响,那么就不用startIndex,例如:[回溯算法:电话号码的字母组合](https://programmercarl.com/0017.电话号码的字母组合.html) **注意以上我只是说求组合的情况,如果是排列问题,又是另一套分析的套路,后面我再讲解排列的时候就重点介绍**。 @@ -103,7 +103,7 @@ if (sum == target) { 单层for循环依然是从startIndex开始,搜索candidates集合。 -**注意本题和[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)、[回溯算法:求组合总和!](https://mp.weixin.qq.com/s/HX7WW6ixbFZJASkRnCTC3w)的一个区别是:本题元素为可重复选取的**。 +**注意本题和[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)、[回溯算法:求组合总和!](https://programmercarl.com/0216.组合总和III.html)的一个区别是:本题元素为可重复选取的**。 如何重复选取呢,看代码,注释部分: @@ -117,7 +117,7 @@ for (int i = startIndex; i < candidates.size(); i++) { } ``` -按照[关于回溯算法,你该了解这些!](https://mp.weixin.qq.com/s/gjSgJbNbd1eAA5WkA-HeWw)中给出的模板,不难写出如下C++完整代码: +按照[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)中给出的模板,不难写出如下C++完整代码: ```CPP // 版本一 @@ -213,14 +213,14 @@ public: ## 总结 -本题和我们之前讲过的[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)、[回溯算法:求组合总和!](https://mp.weixin.qq.com/s/HX7WW6ixbFZJASkRnCTC3w)有两点不同: +本题和我们之前讲过的[回溯算法:求组合问题!](https://programmercarl.com/0077.组合.html)、[回溯算法:求组合总和!](https://programmercarl.com/0216.组合总和III.html)有两点不同: * 组合没有数量要求 * 元素可无限重复选取 针对这两个问题,我都做了详细的分析。 -并且给出了对于组合问题,什么时候用startIndex,什么时候不用,并用[回溯算法:电话号码的字母组合](https://mp.weixin.qq.com/s/e2ua2cmkE_vpYjM3j6HY0A)做了对比。 +并且给出了对于组合问题,什么时候用startIndex,什么时候不用,并用[回溯算法:电话号码的字母组合](https://programmercarl.com/0017.电话号码的字母组合.html)做了对比。 最后还给出了本题的剪枝优化,这个优化如果是初学者的话并不容易想到。 diff --git a/problems/0040.组合总和II.md b/problems/0040.组合总和II.md index 5ea11ca7..fdccf140 100644 --- a/problems/0040.组合总和II.md +++ b/problems/0040.组合总和II.md @@ -11,7 +11,7 @@ ## 40.组合总和II -题目链接:https://leetcode-cn.com/problems/combination-sum-ii/ +[力扣题目链接](https://leetcode-cn.com/problems/combination-sum-ii/) 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 @@ -44,12 +44,12 @@ candidates 中的每个数字在每个组合中只能使用一次。 **如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。 -这道题目和[39.组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)如下区别: +这道题目和[39.组合总和](https://programmercarl.com/0039.组合总和.html)如下区别: 1. 本题candidates 中的每个数字在每个组合中只能使用一次。 -2. 本题数组candidates的元素是有重复的,而[39.组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)是无重复元素的数组candidates +2. 本题数组candidates的元素是有重复的,而[39.组合总和](https://programmercarl.com/0039.组合总和.html)是无重复元素的数组candidates -最后本题和[39.组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)要求一样,解集不能包含重复的组合。 +最后本题和[39.组合总和](https://programmercarl.com/0039.组合总和.html)要求一样,解集不能包含重复的组合。 **本题的难点在于区别2中:集合(数组candidates)有重复元素,但还不能有重复的组合**。 @@ -84,7 +84,7 @@ candidates 中的每个数字在每个组合中只能使用一次。 * **递归函数参数** -与[39.组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)套路相同,此题还需要加一个bool型数组used,用来记录同一树枝上的元素是否使用过。 +与[39.组合总和](https://programmercarl.com/0039.组合总和.html)套路相同,此题还需要加一个bool型数组used,用来记录同一树枝上的元素是否使用过。 这个集合去重的重任就是used来完成的。 @@ -98,7 +98,7 @@ void backtracking(vector& candidates, int target, int sum, int startIndex, * **递归终止条件** -与[39.组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)相同,终止条件为 `sum > target` 和 `sum == target`。 +与[39.组合总和](https://programmercarl.com/0039.组合总和.html)相同,终止条件为 `sum > target` 和 `sum == target`。 代码如下: @@ -116,7 +116,7 @@ if (sum == target) { * **单层搜索的逻辑** -这里与[39.组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)最大的不同就是要去重了。 +这里与[39.组合总和](https://programmercarl.com/0039.组合总和.html)最大的不同就是要去重了。 前面我们提到:要去重的是“同一树层上的使用过”,如果判断同一树层上元素(相同的元素)是否使用过了呢。 @@ -244,7 +244,7 @@ public: ## 总结 -本题同样是求组合总和,但就是因为其数组candidates有重复元素,而要求不能有重复的组合,所以相对于[39.组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)难度提升了不少。 +本题同样是求组合总和,但就是因为其数组candidates有重复元素,而要求不能有重复的组合,所以相对于[39.组合总和](https://programmercarl.com/0039.组合总和.html)难度提升了不少。 **关键是去重的逻辑,代码很简单,网上一搜一大把,但几乎没有能把这块代码含义讲明白的,基本都是给出代码,然后说这就是去重了,究竟怎么个去重法也是模棱两可**。 diff --git a/problems/0042.接雨水.md b/problems/0042.接雨水.md index 22c8c0ef..522b10f9 100644 --- a/problems/0042.接雨水.md +++ b/problems/0042.接雨水.md @@ -11,7 +11,7 @@ # 42. 接雨水 -题目链接:https://leetcode-cn.com/problems/trapping-rain-water/ +[力扣题目链接](https://leetcode-cn.com/problems/trapping-rain-water/) 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 @@ -27,7 +27,7 @@ * 输入:height = [4,2,0,3,2,5] * 输出:9 -  + # 思路 @@ -186,7 +186,7 @@ public: 这个解法可以说是最不好理解的了,所以下面我花了大量的篇幅来介绍这种方法。 -单调栈就是保持栈内元素有序。和[栈与队列:单调队列](https://mp.weixin.qq.com/s/Xgcqx5eBa3xZabt_LurnNQ)一样,需要我们自己维持顺序,没有现成的容器可以用。 +单调栈就是保持栈内元素有序。和[栈与队列:单调队列](https://programmercarl.com/0239.滑动窗口最大值.html)一样,需要我们自己维持顺序,没有现成的容器可以用。 ### 准备工作 diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index d946315b..8dd59838 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -11,7 +11,7 @@ ## 45.跳跃游戏II -题目地址:https://leetcode-cn.com/problems/jump-game-ii/ +[力扣题目链接](https://leetcode-cn.com/problems/jump-game-ii/) 给定一个非负整数数组,你最初位于数组的第一个位置。 @@ -30,7 +30,7 @@ ## 思路 -本题相对于[55.跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)还是难了不少。 +本题相对于[55.跳跃游戏](https://programmercarl.com/0055.跳跃游戏.html)还是难了不少。 但思路是相似的,还是要看最大覆盖范围。 @@ -132,7 +132,7 @@ public: ## 总结 -相信大家可以发现,这道题目相当于[55.跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)难了不止一点。 +相信大家可以发现,这道题目相当于[55.跳跃游戏](https://programmercarl.com/0055.跳跃游戏.html)难了不止一点。 但代码又十分简单,贪心就是这么巧妙。 diff --git a/problems/0046.全排列.md b/problems/0046.全排列.md index c0626fb7..df9394eb 100644 --- a/problems/0046.全排列.md +++ b/problems/0046.全排列.md @@ -9,7 +9,7 @@ ## 46.全排列 -题目链接:https://leetcode-cn.com/problems/permutations/ +[力扣题目链接](https://leetcode-cn.com/problems/permutations/) 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 @@ -30,11 +30,11 @@ **如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。 -此时我们已经学习了[77.组合问题](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)、 [131.分割回文串](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)和[78.子集问题](https://mp.weixin.qq.com/s/NNRzX-vJ_pjK4qxohd_LtA),接下来看一看排列问题。 +此时我们已经学习了[77.组合问题](https://programmercarl.com/0077.组合.html)、 [131.分割回文串](https://programmercarl.com/0131.分割回文串.html)和[78.子集问题](https://programmercarl.com/0078.子集.html),接下来看一看排列问题。 相信这个排列问题就算是让你用for循环暴力把结果搜索出来,这个暴力也不是很好写。 -所以正如我们在[关于回溯算法,你该了解这些!](https://mp.weixin.qq.com/s/gjSgJbNbd1eAA5WkA-HeWw)所讲的为什么回溯法是暴力搜索,效率这么低,还要用它? +所以正如我们在[关于回溯算法,你该了解这些!](https://programmercarl.com/回溯算法理论基础.html)所讲的为什么回溯法是暴力搜索,效率这么低,还要用它? **因为一些问题能暴力搜出来就已经很不错了!** @@ -84,7 +84,7 @@ if (path.size() == nums.size()) { * 单层搜索的逻辑 -这里和[77.组合问题](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)、[131.切割问题](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)和[78.子集问题](https://mp.weixin.qq.com/s/NNRzX-vJ_pjK4qxohd_LtA)最大的不同就是for循环里不用startIndex了。 +这里和[77.组合问题](https://programmercarl.com/0077.组合.html)、[131.切割问题](https://programmercarl.com/0131.分割回文串.html)和[78.子集问题](https://programmercarl.com/0078.子集.html)最大的不同就是for循环里不用startIndex了。 因为排列问题,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。 diff --git a/problems/0047.全排列II.md b/problems/0047.全排列II.md index 61428299..01706eb3 100644 --- a/problems/0047.全排列II.md +++ b/problems/0047.全排列II.md @@ -10,7 +10,7 @@ ## 47.全排列 II -题目链接:https://leetcode-cn.com/problems/permutations-ii/ +[力扣题目链接](https://leetcode-cn.com/problems/permutations-ii/) 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 @@ -33,11 +33,11 @@ **如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。 -这道题目和[回溯算法:排列问题!](https://mp.weixin.qq.com/s/SCOjeMX1t41wcvJq49GhMw)的区别在与**给定一个可包含重复数字的序列**,要返回**所有不重复的全排列**。 +这道题目和[回溯算法:排列问题!](https://programmercarl.com/0046.全排列.html)的区别在与**给定一个可包含重复数字的序列**,要返回**所有不重复的全排列**。 这里又涉及到去重了。 -在[回溯算法:求组合总和(三)](https://mp.weixin.qq.com/s/_1zPYk70NvHsdY8UWVGXmQ) 、[回溯算法:求子集问题(二)](https://mp.weixin.qq.com/s/WJ4JNDRJgsW3eUN72Hh3uQ)我们分别详细讲解了组合问题和子集问题如何去重。 +在[回溯算法:求组合总和(三)](https://programmercarl.com/0040.组合总和II.html) 、[回溯算法:求子集问题(二)](https://programmercarl.com/0090.子集II.html)我们分别详细讲解了组合问题和子集问题如何去重。 那么排列问题其实也是一样的套路。 @@ -51,7 +51,7 @@ **一般来说:组合问题和排列问题是在树形结构的叶子节点上收集结果,而子集问题就是取树上所有节点的结果**。 -在[回溯算法:排列问题!](https://mp.weixin.qq.com/s/SCOjeMX1t41wcvJq49GhMw)中已经详解讲解了排列问题的写法,在[回溯算法:求组合总和(三)](https://mp.weixin.qq.com/s/_1zPYk70NvHsdY8UWVGXmQ) 、[回溯算法:求子集问题(二)](https://mp.weixin.qq.com/s/WJ4JNDRJgsW3eUN72Hh3uQ)中详细讲解的去重的写法,所以这次我就不用回溯三部曲分析了,直接给出代码,如下: +在[回溯算法:排列问题!](https://programmercarl.com/0046.全排列.html)中已经详解讲解了排列问题的写法,在[回溯算法:求组合总和(三)](https://programmercarl.com/0040.组合总和II.html) 、[回溯算法:求子集问题(二)](https://programmercarl.com/0090.子集II.html)中详细讲解的去重的写法,所以这次我就不用回溯三部曲分析了,直接给出代码,如下: ## C++代码 From 92db66643f54eb4326dd7ec3878de9d792f7b2bf Mon Sep 17 00:00:00 2001 From: ironartisan Date: Sun, 22 Aug 2021 11:10:11 +0800 Subject: [PATCH 37/39] =?UTF-8?q?=E6=9B=B4=E6=AD=A30015.=E4=B8=89=E6=95=B0?= =?UTF-8?q?=E4=B9=8B=E5=92=8C=E9=94=99=E5=88=AB=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0015.三数之和.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md index ac5561f2..19c7d0fe 100644 --- a/problems/0015.三数之和.md +++ b/problems/0015.三数之和.md @@ -37,7 +37,7 @@ 两层for循环就可以确定 a 和b 的数值了,可以使用哈希法来确定 0-(a+b) 是否在 数组里出现过,其实这个思路是正确的,但是我们有一个非常棘手的问题,就是题目中说的不可以包含重复的三元组。 -把符合条件的三元组放进vector中,然后在去去重,这样是非常费时的,很容易超时,也是这道题目通过率如此之低的根源所在。 +把符合条件的三元组放进vector中,然后再去重,这样是非常费时的,很容易超时,也是这道题目通过率如此之低的根源所在。 去重的过程不好处理,有很多小细节,如果在面试中很难想到位。 @@ -95,7 +95,7 @@ public: ![15.三数之和](https://code-thinking.cdn.bcebos.com/gifs/15.%E4%B8%89%E6%95%B0%E4%B9%8B%E5%92%8C.gif) -拿这个nums数组来举例,首先将数组排序,然后有一层for循环,i从下表0的地方开始,同时定一个下表left 定义在i+1的位置上,定义下表right 在数组结尾的位置上。 +拿这个nums数组来举例,首先将数组排序,然后有一层for循环,i从下标0的地方开始,同时定一个下标left 定义在i+1的位置上,定义下表right 在数组结尾的位置上。 依然还是在数组中找到 abc 使得a + b +c =0,我们这里相当于 a = nums[i] b = nums[left] c = nums[right]。 From 8df67e8513567d0e686ccc93bdbf867cc9dd80ef Mon Sep 17 00:00:00 2001 From: ironartisan Date: Sun, 22 Aug 2021 11:12:15 +0800 Subject: [PATCH 38/39] =?UTF-8?q?=E6=9B=B4=E6=AD=A30015.=E4=B8=89=E6=95=B0?= =?UTF-8?q?=E4=B9=8B=E5=92=8C=E9=94=99=E5=88=AB=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0015.三数之和.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md index 19c7d0fe..1adb2d24 100644 --- a/problems/0015.三数之和.md +++ b/problems/0015.三数之和.md @@ -95,11 +95,11 @@ public: ![15.三数之和](https://code-thinking.cdn.bcebos.com/gifs/15.%E4%B8%89%E6%95%B0%E4%B9%8B%E5%92%8C.gif) -拿这个nums数组来举例,首先将数组排序,然后有一层for循环,i从下标0的地方开始,同时定一个下标left 定义在i+1的位置上,定义下表right 在数组结尾的位置上。 +拿这个nums数组来举例,首先将数组排序,然后有一层for循环,i从下标0的地方开始,同时定一个下标left 定义在i+1的位置上,定义下标right 在数组结尾的位置上。 依然还是在数组中找到 abc 使得a + b +c =0,我们这里相当于 a = nums[i] b = nums[left] c = nums[right]。 -接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下表就应该向左移动,这样才能让三数之和小一些。 +接下来如何移动left 和right呢, 如果nums[i] + nums[left] + nums[right] > 0 就说明 此时三数之和大了,因为数组是排序后了,所以right下标就应该向左移动,这样才能让三数之和小一些。 如果 nums[i] + nums[left] + nums[right] < 0 说明 此时 三数之和小了,left 就向右移动,才能让三数之和大一些,直到left与right相遇为止。 @@ -167,7 +167,7 @@ public: 如果不能,题意如何更改就可以使用双指针法呢? **大家留言说出自己的想法吧!** -两数之和 就不能使用双指针法,因为[1.两数之和](https://programmercarl.com/0001.两数之和.html)要求返回的是索引下表, 而双指针法一定要排序,一旦排序之后原数组的索引就被改变了。 +两数之和 就不能使用双指针法,因为[1.两数之和](https://programmercarl.com/0001.两数之和.html)要求返回的是索引下标, 而双指针法一定要排序,一旦排序之后原数组的索引就被改变了。 如果[1.两数之和](https://programmercarl.com/0001.两数之和.html)要求返回的是数值的话,就可以使用双指针法了。 From 2de05852ea1d92eb667268f253c81d4cc7f1789e Mon Sep 17 00:00:00 2001 From: ironartisan Date: Sun, 22 Aug 2021 21:48:40 +0800 Subject: [PATCH 39/39] =?UTF-8?q?=E6=B7=BB=E5=8A=A00018.=E5=9B=9B=E6=95=B0?= =?UTF-8?q?=E4=B9=8B=E5=92=8C=E5=8F=8C=E6=8C=87=E9=92=88=E6=B3=95python3?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0018.四数之和.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md index 66f06f64..6af033b9 100644 --- a/problems/0018.四数之和.md +++ b/problems/0018.四数之和.md @@ -167,7 +167,33 @@ class Solution { Python: ```python +# 双指针法 +class Solution: + def fourSum(self, nums: List[int], target: int) -> List[List[int]]: + + nums.sort() + n = len(nums) + res = [] + for i in range(n): + if i > 0 and nums[i] == nums[i - 1]: continue + for k in range(i+1, n): + if k > i + 1 and nums[k] == nums[k-1]: continue + p = k + 1 + q = n - 1 + while p < q: + if nums[i] + nums[k] + nums[p] + nums[q] > target: q -= 1 + elif nums[i] + nums[k] + nums[p] + nums[q] < target: p += 1 + else: + res.append([nums[i], nums[k], nums[p], nums[q]]) + while p < q and nums[p] == nums[p + 1]: p += 1 + while p < q and nums[q] == nums[q - 1]: q -= 1 + p += 1 + q -= 1 + return res +``` +```python +# 哈希表法 class Solution(object): def fourSum(self, nums, target): """