From 426b00a4e2889bb4c6d2599f29c965e173a5f536 Mon Sep 17 00:00:00 2001 From: Nada Date: Sun, 10 Apr 2022 14:56:56 +0800 Subject: [PATCH 01/21] =?UTF-8?q?Update=200018.=E5=9B=9B=E6=95=B0=E4=B9=8B?= =?UTF-8?q?=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加剪枝逻辑处理 --- problems/0018.四数之和.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md index 7304254e..ee70cb69 100644 --- a/problems/0018.四数之和.md +++ b/problems/0018.四数之和.md @@ -31,7 +31,7 @@ 四数之和,和[15.三数之和](https://programmercarl.com/0015.三数之和.html)是一个思路,都是使用双指针法, 基本解法就是在[15.三数之和](https://programmercarl.com/0015.三数之和.html) 的基础上再套一层for循环。 -但是有一些细节需要注意,例如: 不要判断`nums[k] > target` 就返回了,三数之和 可以通过 `nums[i] > 0` 就返回了,因为 0 已经是确定的数了,四数之和这道题目 target是任意值。(大家亲自写代码就能感受出来) +但是有一些细节需要注意,例如: 不要判断`nums[k] > target` 就返回了,三数之和 可以通过 `nums[i] > 0` 就返回了,因为 0 已经是确定的数了,四数之和这道题目 target是任意值。比如:数组是`[-4, -3, -2, -1]`,`target`是`-10`,不能因为`-4 > -10`而跳过。但是我们依旧可以去做剪枝,逻辑变成`nums[i] > target && (nums[i] >=0 || target >= 0)`就可以了。 [15.三数之和](https://programmercarl.com/0015.三数之和.html)的双指针解法是一层for循环num[i]为确定值,然后循环内有left和right下标作为双指针,找到nums[i] + nums[left] + nums[right] == 0。 @@ -72,15 +72,20 @@ public: vector> result; sort(nums.begin(), nums.end()); for (int k = 0; k < nums.size(); k++) { - // 这种剪枝是错误的,这道题目target 是任意值 - // if (nums[k] > target) { - // return result; - // } + // 剪枝处理 + if (nums[k] > target && (nums[k] >= 0 || target >= 0)) { + break; // 这里使用break,统一通过最后的return返回 + } // 去重 if (k > 0 && nums[k] == nums[k - 1]) { continue; } for (int i = k + 1; i < nums.size(); i++) { + // 2级剪枝处理 + if (nums[k] + nums[i] > target && (nums[k] + nums[i] >= 0 || target >= 0)) { + break; + } + // 正确去重方法 if (i > k + 1 && nums[i] == nums[i - 1]) { continue; From f9146a3b98fd46ca548c8852bf3b7df0625cfe72 Mon Sep 17 00:00:00 2001 From: zhenghao <1650937065@qq.com> Date: Wed, 20 Apr 2022 10:23:18 +0800 Subject: [PATCH 02/21] =?UTF-8?q?=E6=9B=B4=E6=96=B00435=20=E6=97=A0?= =?UTF-8?q?=E9=87=8D=E5=8F=A0=E5=8C=BA=E9=97=B4=20java=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B3=E8=BE=B9=E7=95=8C=E8=A7=A3=E6=B3=95=E4=B8=AD=E6=8E=92?= =?UTF-8?q?=E5=BA=8F=E7=9A=84=E5=88=A4=E6=96=AD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0435.无重叠区间.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/problems/0435.无重叠区间.md b/problems/0435.无重叠区间.md index b24ca024..cf58b9e2 100644 --- a/problems/0435.无重叠区间.md +++ b/problems/0435.无重叠区间.md @@ -184,13 +184,14 @@ public: class Solution { public int eraseOverlapIntervals(int[][] intervals) { Arrays.sort(intervals, (a, b) -> { - if (a[0] == a[0]) return a[1] - b[1]; - return a[0] - b[0]; + // 按照区间右边界升序排序 + return a[1] - b[1]; }); int count = 0; int edge = Integer.MIN_VALUE; for (int i = 0; i < intervals.length; i++) { + // 若上一个区间的右边界小于当前区间的左边界,说明无交集 if (edge <= intervals[i][0]) { edge = intervals[i][1]; } else { From 4154d3db2eadecdddaba45d09f09bfe16c0cc594 Mon Sep 17 00:00:00 2001 From: 243wresfdxvc Date: Thu, 21 Apr 2022 09:55:19 +0000 Subject: [PATCH 03/21] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200134.=20=E5=8A=A0?= =?UTF-8?q?=E6=B2=B9=E7=AB=99.md=20C=E8=AF=AD=E8=A8=80=E8=B4=AA=E5=BF=83?= =?UTF-8?q?=E8=A7=A3=E6=B3=95=E6=96=B9=E6=B3=95=E4=BA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0134.加油站.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/problems/0134.加油站.md b/problems/0134.加油站.md index ca95af67..45e05fed 100644 --- a/problems/0134.加油站.md +++ b/problems/0134.加油站.md @@ -341,6 +341,7 @@ var canCompleteCircuit = function(gas, cost) { ``` ### C +贪心算法:方法一 ```c int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize){ int curSum = 0; @@ -370,5 +371,36 @@ int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize){ } ``` +贪心算法:方法二 +```c +int canCompleteCircuit(int* gas, int gasSize, int* cost, int costSize){ + int curSum = 0; + int totalSum = 0; + int start = 0; + + int i; + for(i = 0; i < gasSize; ++i) { + // 当前i站中加油量与耗油量的差 + int diff = gas[i] - cost[i]; + + curSum += diff; + totalSum += diff; + + // 若0到i的加油量都为负,则开始位置应为i+1 + if(curSum < 0) { + curSum = 0; + // 当i + 1 == gasSize时,totalSum < 0(此时i为gasSize - 1),油车不可能返回原点 + start = i + 1; + } + } + + // 若总和小于0,加油车无论如何都无法返回原点。返回-1 + if(totalSum < 0) + return -1; + + return start; +} +``` + -----------------------
From be07599474b87bf7dba3e97107b19435a304e5e7 Mon Sep 17 00:00:00 2001 From: berserk-112 <40333359+berserk-112@users.noreply.github.com> Date: Fri, 22 Apr 2022 09:16:34 +0800 Subject: [PATCH 04/21] =?UTF-8?q?Update=200309.=E6=9C=80=E4=BD=B3=E4=B9=B0?= =?UTF-8?q?=E5=8D=96=E8=82=A1=E7=A5=A8=E6=97=B6=E6=9C=BA=E5=90=AB=E5=86=B7?= =?UTF-8?q?=E5=86=BB=E6=9C=9F.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0309.最佳买卖股票时机含冷冻期.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/problems/0309.最佳买卖股票时机含冷冻期.md b/problems/0309.最佳买卖股票时机含冷冻期.md index 53caa46e..8bd2fcf8 100644 --- a/problems/0309.最佳买卖股票时机含冷冻期.md +++ b/problems/0309.最佳买卖股票时机含冷冻期.md @@ -214,8 +214,8 @@ class Solution { for (int i = 2; i <= prices.length; i++) { /* - dp[i][0] 第i天未持有股票收益; - dp[i][1] 第i天持有股票收益; + dp[i][0] 第i天持有股票收益; + dp[i][1] 第i天不持有股票收益; 情况一:第i天是冷静期,不能以dp[i-1][1]购买股票,所以以dp[i - 2][1]买股票,没问题 情况二:第i天不是冷静期,理论上应该以dp[i-1][1]购买股票,但是第i天不是冷静期说明,第i-1天没有卖出股票, 则dp[i-1][1]=dp[i-2][1],所以可以用dp[i-2][1]买股票,没问题 From c3f746a25d81c299ca8a3efa4fc1f9e8d45509d3 Mon Sep 17 00:00:00 2001 From: qyg <1600314850@qq.com> Date: Fri, 22 Apr 2022 10:55:01 +0800 Subject: [PATCH 05/21] =?UTF-8?q?0209.=E9=95=BF=E5=BA=A6=E6=9C=80=E5=B0=8F?= =?UTF-8?q?=E7=9A=84=E5=AD=90=E6=95=B0=E7=BB=84=EF=BC=9A=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E7=AC=94=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0209.长度最小的子数组.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0209.长度最小的子数组.md b/problems/0209.长度最小的子数组.md index 82a11381..23b27edd 100644 --- a/problems/0209.长度最小的子数组.md +++ b/problems/0209.长度最小的子数组.md @@ -112,7 +112,7 @@ public: **一些录友会疑惑为什么时间复杂度是O(n)**。 -不要以为for里放一个while就以为是O(n^2)啊, 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被被操作两次,所以时间复杂度是 2 × n 也就是O(n)。 +不要以为for里放一个while就以为是O(n^2)啊, 主要是看每一个元素被操作的次数,每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)。 ## 相关题目推荐 From 4d668b0efc89cd15f50dcb93da01e1ace633b07b Mon Sep 17 00:00:00 2001 From: qyg <1600314850@qq.com> Date: Fri, 22 Apr 2022 11:02:11 +0800 Subject: [PATCH 06/21] =?UTF-8?q?0059.=E8=9E=BA=E6=97=8B=E7=9F=A9=E9=98=B5?= =?UTF-8?q?II=EF=BC=9A=E8=B0=83=E6=95=B4=E7=AC=94=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0059.螺旋矩阵II.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/0059.螺旋矩阵II.md b/problems/0059.螺旋矩阵II.md index 5c679982..1162c7eb 100644 --- a/problems/0059.螺旋矩阵II.md +++ b/problems/0059.螺旋矩阵II.md @@ -30,7 +30,7 @@ 相信很多同学刚开始做这种题目的时候,上来就是一波判断猛如虎。 -结果运行的时候各种问题,然后开始各种修修补补,最后发现改了这里哪里有问题,改了那里这里又跑不起来了。 +结果运行的时候各种问题,然后开始各种修修补补,最后发现改了这里那里有问题,改了那里这里又跑不起来了。 大家还记得我们在这篇文章[数组:每次遇到二分法,都是一看就会,一写就废](https://programmercarl.com/0704.二分查找.html)中讲解了二分法,提到如果要写出正确的二分法一定要坚持**循环不变量原则**。 @@ -47,7 +47,7 @@ 可以发现这里的边界条件非常多,在一个循环中,如此多的边界条件,如果不按照固定规则来遍历,那就是**一进循环深似海,从此offer是路人**。 -这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开又闭的原则,这样这一圈才能按照统一的规则画下来。 +这里一圈下来,我们要画每四条边,这四条边怎么画,每画一条边都要坚持一致的左闭右开,或者左开右闭的原则,这样这一圈才能按照统一的规则画下来。 那么我按照左闭右开的原则,来画一圈,大家看一下: @@ -59,7 +59,7 @@ 一些同学做这道题目之所以一直写不好,代码越写越乱。 -就是因为在画每一条边的时候,一会左开又闭,一会左闭右闭,一会又来左闭右开,岂能不乱。 +就是因为在画每一条边的时候,一会左开右闭,一会左闭右闭,一会又来左闭右开,岂能不乱。 代码如下,已经详细注释了每一步的目的,可以看出while循环里判断的情况是很多的,代码里处理的原则也是统一的左闭右开。 From 664746fe155a137f01c5d1478b0325c2dd8e0ffe Mon Sep 17 00:00:00 2001 From: qyg <1600314850@qq.com> Date: Fri, 22 Apr 2022 11:21:18 +0800 Subject: [PATCH 07/21] =?UTF-8?q?=E6=95=B0=E7=BB=84=E6=80=BB=E7=BB=93?= =?UTF-8?q?=E7=AF=87=EF=BC=9A=E8=B0=83=E6=95=B4=E7=AC=94=E8=AF=AF=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=8C=E7=BB=B4=E6=95=B0=E7=BB=84=E7=9A=84?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=98=AF=E9=92=88=E5=AF=B9Java=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E7=9A=84=E9=99=90=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/数组总结篇.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/problems/数组总结篇.md b/problems/数组总结篇.md index d256298b..39fa17a6 100644 --- a/problems/数组总结篇.md +++ b/problems/数组总结篇.md @@ -43,19 +43,19 @@ **那么二维数组在内存的空间地址是连续的么?** -我们来举一个例子,例如: `int[][] rating = new int[3][4];` , 这个二维数据在内存空间可不是一个 `3*4` 的连续地址空间 +我们来举一个Java的例子,例如: `int[][] rating = new int[3][4];` , 这个二维数组在内存空间可不是一个 `3*4` 的连续地址空间 看了下图,就应该明白了: -所以**二维数据在内存中不是 `3*4` 的连续地址空间,而是四条连续的地址空间组成!** +所以**Java的二维数组在内存中不是 `3*4` 的连续地址空间,而是四条连续的地址空间组成!** # 数组的经典题目 在面试中,数组是必考的基础数据结构。 -其实数据的题目在思想上一般比较简单的,但是如果想高效,并不容易。 +其实数组的题目在思想上一般比较简单的,但是如果想高效,并不容易。 我们之前一共讲解了四道经典数组题目,每一道题目都代表一个类型,一种思想。 @@ -115,7 +115,7 @@ 在这道题目中,我们再一次介绍到了**循环不变量原则**,其实这也是写程序中的重要原则。 -相信大家又遇到过这种情况: 感觉题目的边界调节超多,一波接着一波的判断,找边界,踩了东墙补西墙,好不容易运行通过了,代码写的十分冗余,毫无章法,其实**真正解决题目的代码都是简洁的,或者有原则性的**,大家可以在这道题目中体会到这一点。 +相信大家有遇到过这种情况: 感觉题目的边界调节超多,一波接着一波的判断,找边界,拆了东墙补西墙,好不容易运行通过了,代码写的十分冗余,毫无章法,其实**真正解决题目的代码都是简洁的,或者有原则性的**,大家可以在这道题目中体会到这一点。 # 总结 From 074937378aad536271afd42fdb5cc27a1f193f7f Mon Sep 17 00:00:00 2001 From: qyg <1600314850@qq.com> Date: Fri, 22 Apr 2022 11:42:50 +0800 Subject: [PATCH 08/21] =?UTF-8?q?=E9=93=BE=E8=A1=A8=E7=90=86=E8=AE=BA?= =?UTF-8?q?=E5=9F=BA=E7=A1=80=EF=BC=9A=E8=B0=83=E6=95=B4=E7=AC=94=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/链表理论基础.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/problems/链表理论基础.md b/problems/链表理论基础.md index 095282f5..2fe9f14c 100644 --- a/problems/链表理论基础.md +++ b/problems/链表理论基础.md @@ -24,7 +24,7 @@ ## 双链表 -单链表中的节点只能指向节点的下一个节点。 +单链表中的指针域只能指向节点的下一个节点。 双链表:每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。 @@ -56,7 +56,7 @@ ![链表3](https://img-blog.csdnimg.cn/20200806194613920.png) -这个链表起始节点为2, 终止节点为7, 各个节点分布在内存个不同地址空间上,通过指针串联在一起。 +这个链表起始节点为2, 终止节点为7, 各个节点分布在内存的不同地址空间上,通过指针串联在一起。 # 链表的定义 From 5a7e247e5f5a70c1e33dfce4cc42b498cc031f61 Mon Sep 17 00:00:00 2001 From: ChubbyPan Date: Fri, 22 Apr 2022 07:59:32 +0000 Subject: [PATCH 09/21] update build binary tree in ACM pattern with python --- .../前序/ACM模式如何构建二叉树.md | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/problems/前序/ACM模式如何构建二叉树.md b/problems/前序/ACM模式如何构建二叉树.md index bd2e9780..f6ec2dd3 100644 --- a/problems/前序/ACM模式如何构建二叉树.md +++ b/problems/前序/ACM模式如何构建二叉树.md @@ -213,7 +213,61 @@ int main() { ## Python -```Python +```Python3 +class TreeNode: + def __init__(self, val = 0, left = None, right = None): + self.val = val + self.left = left + self.right = right + + +# 根据数组构建二叉树 + +def construct_binary_tree(nums: []) -> TreeNode: + if not nums: + return None + # 用于存放构建好的节点 + root = TreeNode(-1) + Tree = [] + # 将数组元素全部转化为树节点 + for i in range(len(nums)): + if nums[i]!= -1: + node = TreeNode(nums[i]) + else: + node = None + Tree.append(node) + if i == 0: + root = node + for i in range(len(Tree)): + node = Tree[i] + if node and (2 * i + 2) < len(Tree): + node.left = Tree[i * 2 + 1] + node.right = Tree[i * 2 + 2] + return root + + + +# 算法:中序遍历二叉树 + +class Solution: + def __init__(self): + self.T = [] + def inorder(self, root: TreeNode) -> []: + if not root: + return + self.inorder(root.left) + self.T.append(root.val) + self.inorder(root.right) + return self.T + + + +# 验证创建二叉树的有效性,二叉排序树的中序遍历应为顺序排列 + +test_tree = [3, 1, 5, -1, 2, 4 ,6] +root = construct_binary_tree(test_tree) +A = Solution() +print(A.inorder(root)) ``` From a0c16d48cb851b3c118cf3da0900797be767f9d0 Mon Sep 17 00:00:00 2001 From: Steve2020 <841532108@qq.com> Date: Sat, 23 Apr 2022 18:19:36 +0800 Subject: [PATCH 10/21] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=EF=BC=880435.=E6=97=A0?= =?UTF-8?q?=E9=87=8D=E5=8F=A0=E5=8C=BA=E9=97=B4.md=EF=BC=89=EF=BC=9A?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0typescript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0435.无重叠区间.md | 51 +++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/problems/0435.无重叠区间.md b/problems/0435.无重叠区间.md index b24ca024..c7f755bf 100644 --- a/problems/0435.无重叠区间.md +++ b/problems/0435.无重叠区间.md @@ -263,7 +263,7 @@ func min(a,b int)int{ } return a } -``` +``` ### Javascript: - 按右边界排序 @@ -306,6 +306,55 @@ var eraseOverlapIntervals = function(intervals) { } ``` +### TypeScript + +> 按右边界排序,从左往右遍历 + +```typescript +function eraseOverlapIntervals(intervals: number[][]): number { + const length = intervals.length; + if (length === 0) return 0; + intervals.sort((a, b) => a[1] - b[1]); + let right: number = intervals[0][1]; + let count: number = 1; + for (let i = 1; i < length; i++) { + if (intervals[i][0] >= right) { + count++; + right = intervals[i][1]; + } + } + return length - count; +}; +``` + +> 按左边界排序,从左往右遍历 + +```typescript +function eraseOverlapIntervals(intervals: number[][]): number { + if (intervals.length === 0) return 0; + intervals.sort((a, b) => a[0] - b[0]); + let right: number = intervals[0][1]; + let tempInterval: number[]; + let resCount: number = 0; + for (let i = 1, length = intervals.length; i < length; i++) { + tempInterval = intervals[i]; + if (tempInterval[0] >= right) { + // 未重叠 + right = tempInterval[1]; + } else { + // 有重叠,移除当前interval和前一个interval中右边界更大的那个 + right = Math.min(right, tempInterval[1]); + resCount++; + } + } + return resCount; +}; +``` + + + + + -----------------------
From 7c752afaf472f8e3056d9bfefd9628548cbec5d8 Mon Sep 17 00:00:00 2001 From: h4 <20080114+tan-i-ham@users.noreply.github.com> Date: Sat, 23 Apr 2022 22:19:09 +0900 Subject: [PATCH 11/21] chore: Sync 150 markdown render format --- problems/0150.逆波兰表达式求值.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md index f4dad823..fd3d69aa 100644 --- a/problems/0150.逆波兰表达式求值.md +++ b/problems/0150.逆波兰表达式求值.md @@ -109,7 +109,7 @@ public: }; ``` -# 题外话 +## 题外话 我们习惯看到的表达式都是中缀表达式,因为符合我们的习惯,但是中缀表达式对于计算机来说就不是很友好了。 @@ -128,7 +128,7 @@ public: -# 其他语言版本 +## 其他语言版本 java: From 531c1b0a3bfac9867a8403baaf95a6cd284f6a41 Mon Sep 17 00:00:00 2001 From: Steve2020 <841532108@qq.com> Date: Sat, 23 Apr 2022 21:19:23 +0800 Subject: [PATCH 12/21] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=EF=BC=880763.=E5=88=92?= =?UTF-8?q?=E5=88=86=E5=AD=97=E6=AF=8D=E5=8C=BA=E9=97=B4.md=EF=BC=89?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0typescript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0763.划分字母区间.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/problems/0763.划分字母区间.md b/problems/0763.划分字母区间.md index 03d3a73b..901dccb4 100644 --- a/problems/0763.划分字母区间.md +++ b/problems/0763.划分字母区间.md @@ -174,6 +174,31 @@ var partitionLabels = function(s) { }; ``` +### TypeScript + +```typescript +function partitionLabels(s: string): number[] { + const length: number = s.length; + const resArr: number[] = []; + const helperMap: Map = new Map(); + for (let i = 0; i < length; i++) { + helperMap.set(s[i], i); + } + let left: number = 0; + let right: number = 0; + for (let i = 0; i < length; i++) { + right = Math.max(helperMap.get(s[i])!, right); + if (i === right) { + resArr.push(i - left + 1); + left = i + 1; + } + } + return resArr; +}; +``` + + + -----------------------
From 8966752197c174e46052ab549495a045ce1a5f14 Mon Sep 17 00:00:00 2001 From: Steve2020 <841532108@qq.com> Date: Sat, 23 Apr 2022 21:44:11 +0800 Subject: [PATCH 13/21] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=EF=BC=880056.=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=8C=BA=E9=97=B4.md=EF=BC=89=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0typescript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0056.合并区间.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0056.合并区间.md b/problems/0056.合并区间.md index a9caeaf0..b44d602c 100644 --- a/problems/0056.合并区间.md +++ b/problems/0056.合并区间.md @@ -266,6 +266,26 @@ var merge = function(intervals) { }; ``` +### TypeScript + +```typescript +function merge(intervals: number[][]): number[][] { + const resArr: number[][] = []; + intervals.sort((a, b) => a[0] - b[0]); + resArr[0] = [...intervals[0]]; // 避免修改原intervals + for (let i = 1, length = intervals.length; i < length; i++) { + let interval: number[] = intervals[i]; + let last: number[] = resArr[resArr.length - 1]; + if (interval[0] <= last[1]) { + last[1] = Math.max(interval[1], last[1]); + } else { + resArr.push([...intervals[i]]); + } + } + return resArr; +}; +``` + ----------------------- From e2807eb59ad5b9e45311544278c905fd942e85b3 Mon Sep 17 00:00:00 2001 From: 243wresfdxvc Date: Sat, 23 Apr 2022 16:15:53 +0000 Subject: [PATCH 14/21] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200203.=E7=A7=BB?= =?UTF-8?q?=E5=87=BA=E9=93=BE=E8=A1=A8=E5=85=83=E7=B4=A0.md=20C=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0203.移除链表元素.md | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md index c34831b7..751553e2 100644 --- a/problems/0203.移除链表元素.md +++ b/problems/0203.移除链表元素.md @@ -145,6 +145,38 @@ public: ## 其他语言版本 C: +用原来的链表操作: +```c +struct ListNode* removeElements(struct ListNode* head, int val){ + struct ListNode* temp; + // 当头结点存在并且头结点的值等于val时 + while(head && head->val == val) { + temp = head; + // 将新的头结点设置为head->next并删除原来的头结点 + head = head->next; + free(temp); + } + + struct ListNode *cur = head; + // 当cur存在并且cur->next存在时 + // 此解法需要判断cur存在因为cur指向head。若head本身为NULL或者原链表中元素都为val的话,cur也会为NULL + while(cur && (temp = cur->next)) { + // 若cur->next的值等于val + if(temp->val == val) { + // 将cur->next设置为cur->next->next并删除cur->next + cur->next = temp->next; + free(temp); + } + // 若cur->next不等于val,则将cur后移一位 + else + cur = cur->next; + } + + // 返回头结点 + return head; +} +``` +设置一个虚拟头结点: ```c /** * Definition for singly-linked list. From 7cf68bd1f2eaa6ad83d69b969f29b1b146397dfa Mon Sep 17 00:00:00 2001 From: Steve2020 <841532108@qq.com> Date: Sun, 24 Apr 2022 17:40:23 +0800 Subject: [PATCH 15/21] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=EF=BC=880738.=E5=8D=95?= =?UTF-8?q?=E8=B0=83=E9=80=92=E5=A2=9E=E7=9A=84=E6=95=B0=E5=AD=97.md?= =?UTF-8?q?=EF=BC=89=EF=BC=9A=E5=A2=9E=E5=8A=A0typescript=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0738.单调递增的数字.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/problems/0738.单调递增的数字.md b/problems/0738.单调递增的数字.md index c8ce8a2b..4e4079a7 100644 --- a/problems/0738.单调递增的数字.md +++ b/problems/0738.单调递增的数字.md @@ -225,6 +225,28 @@ var monotoneIncreasingDigits = function(n) { }; ``` +### TypeScript + +```typescript +function monotoneIncreasingDigits(n: number): number { + let strArr: number[] = String(n).split('').map(i => parseInt(i)); + const length = strArr.length; + let flag: number = length; + for (let i = length - 2; i >= 0; i--) { + if (strArr[i] > strArr[i + 1]) { + strArr[i] -= 1; + flag = i + 1; + } + } + for (let i = flag; i < length; i++) { + strArr[i] = 9; + } + return parseInt(strArr.join('')); +}; +``` + + + -----------------------
From d5f21d534198069fee0dd4a90397d1322d435179 Mon Sep 17 00:00:00 2001 From: eat to 160 pounds <2915390277@qq.com> Date: Sun, 24 Apr 2022 21:05:31 +0800 Subject: [PATCH 16/21] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E4=B8=89?= =?UTF-8?q?=E6=95=B0=E4=B9=8B=E5=92=8Cjavascript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0015.三数之和.md | 70 +++++++++++++---------------------- 1 file changed, 26 insertions(+), 44 deletions(-) diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md index bfde6b35..cc184c87 100644 --- a/problems/0015.三数之和.md +++ b/problems/0015.三数之和.md @@ -313,54 +313,36 @@ func threeSum(nums []int)[][]int{ javaScript: ```js -/** - * @param {number[]} nums - * @return {number[][]} - */ - -// 循环内不考虑去重 var threeSum = function(nums) { - const len = nums.length; - if(len < 3) return []; - nums.sort((a, b) => a - b); - const resSet = new Set(); - for(let i = 0; i < len - 2; i++) { - if(nums[i] > 0) break; - let l = i + 1, r = len - 1; + const res = [], len = nums.length + // 将数组排序 + nums.sort((a, b) => a - b) + for (let i = 0; i < len; i++) { + let l = i + 1, r = len - 1, iNum = nums[i] + // 数组排过序,如果第一个数大于0直接返回res + if (iNum > 0) return res + // 去重 + if (iNum == nums[i - 1]) continue while(l < r) { - const sum = nums[i] + nums[l] + nums[r]; - if(sum < 0) { l++; continue }; - if(sum > 0) { r--; continue }; - resSet.add(`${nums[i]},${nums[l]},${nums[r]}`); - l++; - r--; + let lNum = nums[l], rNum = nums[r], threeSum = iNum + lNum + rNum + // 三数之和小于0,则左指针向右移动 + if (threeSum < 0) l++ + else if (threeSum > 0) r-- + else { + res.push([iNum, lNum, rNum]) + // 去重 + while(l < r && nums[l] == nums[l + 1]){ + l++ + } + while(l < r && nums[r] == nums[r - 1]) { + r-- + } + l++ + r-- + } } } - return Array.from(resSet).map(i => i.split(",")); -}; - -// 去重优化 -var threeSum = function(nums) { - const len = nums.length; - if(len < 3) return []; - nums.sort((a, b) => a - b); - const res = []; - for(let i = 0; i < len - 2; i++) { - if(nums[i] > 0) break; - // a去重 - if(i > 0 && nums[i] === nums[i - 1]) continue; - let l = i + 1, r = len - 1; - while(l < r) { - const sum = nums[i] + nums[l] + nums[r]; - if(sum < 0) { l++; continue }; - if(sum > 0) { r--; continue }; - res.push([nums[i], nums[l], nums[r]]) - // b c 去重 - while(l < r && nums[l] === nums[++l]); - while(l < r && nums[r] === nums[--r]); - } - } - return res; + return res }; ``` TypeScript: From 84750aca45f96f15e4dc271410c32cde78667e41 Mon Sep 17 00:00:00 2001 From: 243wresfdxvc Date: Sun, 24 Apr 2022 18:32:09 +0000 Subject: [PATCH 17/21] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200860.=E6=9F=A0?= =?UTF-8?q?=E6=AA=AC=E6=B0=B4=E6=89=BE=E9=9B=B6.md=20C=E8=AF=AD=E8=A8=80?= =?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/0860.柠檬水找零.md | 43 ++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/problems/0860.柠檬水找零.md b/problems/0860.柠檬水找零.md index ffd5490d..2738f574 100644 --- a/problems/0860.柠檬水找零.md +++ b/problems/0860.柠檬水找零.md @@ -250,6 +250,49 @@ var lemonadeChange = function(bills) { return true }; +``` +### C +```c +bool lemonadeChange(int* bills, int billsSize){ + // 分别记录五元、十元的数量(二十元不用记录,因为不会用到20元找零) + int fiveCount = 0; int tenCount = 0; + + int i; + for(i = 0; i < billsSize; ++i) { + // 分情况讨论每位顾客的付款 + switch(bills[i]) { + // 情况一:直接收款五元 + case 5: + fiveCount++; + break; + // 情况二:收款十元 + case 10: + // 若没有五元找零,返回false + if(fiveCount == 0) + return false; + // 收款十元并找零五元 + fiveCount--; + tenCount++; + break; + // 情况三:收款二十元 + case 20: + // 若可以,优先用十元和五元找零(因为十元只能找零20,所以需要尽量用掉。而5元能找零十元和二十元) + if(fiveCount > 0 && tenCount > 0) { + fiveCount--; + tenCount--; + } + // 若没有十元,但是有三张五元。用三张五元找零 + else if(fiveCount >= 3) + fiveCount-=3; + // 无法找开,返回false + else + return false; + break; + } + } + // 全部可以找开,返回true + return true; +} ``` ----------------------- From 8291e5e1c6d1b9c913a35015848124ad9cfd1808 Mon Sep 17 00:00:00 2001 From: Steve2020 <841532108@qq.com> Date: Mon, 25 Apr 2022 14:05:53 +0800 Subject: [PATCH 18/21] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=EF=BC=880714.=E4=B9=B0?= =?UTF-8?q?=E5=8D=96=E8=82=A1=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6?= =?UTF-8?q?=E6=9C=BA=E5=90=AB=E6=89=8B=E7=BB=AD=E8=B4=B9.md=EF=BC=89?= =?UTF-8?q?=EF=BC=9A=E5=A2=9E=E5=8A=A0typescript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...买卖股票的最佳时机含手续费.md | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/problems/0714.买卖股票的最佳时机含手续费.md b/problems/0714.买卖股票的最佳时机含手续费.md index 2f27d6ea..b27631c6 100644 --- a/problems/0714.买卖股票的最佳时机含手续费.md +++ b/problems/0714.买卖股票的最佳时机含手续费.md @@ -293,6 +293,50 @@ var maxProfit = function(prices, fee) { }; ``` +TypeScript: + +> 贪心 + +```typescript +function maxProfit(prices: number[], fee: number): number { + if (prices.length === 0) return 0; + let minPrice: number = prices[0]; + let profit: number = 0; + for (let i = 1, length = prices.length; i < length; i++) { + if (minPrice > prices[i]) { + minPrice = prices[i]; + } + if (minPrice + fee < prices[i]) { + profit += prices[i] - minPrice - fee; + minPrice = prices[i] - fee; + } + } + return profit; +}; +``` + +> 动态规划 + +```typescript +function maxProfit(prices: number[], fee: number): number { + /** + dp[i][1]: 第i天不持有股票的最大所剩现金 + dp[i][0]: 第i天持有股票的最大所剩现金 + */ + const length: number = prices.length; + const dp: number[][] = new Array(length).fill(0).map(_ => []); + dp[0][1] = 0; + dp[0][0] = -prices[0]; + for (let i = 1, length = prices.length; i < length; i++) { + dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] + prices[i] - fee); + dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] - prices[i]); + } + return Math.max(dp[length - 1][0], dp[length - 1][1]); +}; +``` + + + -----------------------
From 3ec08f41dd08cdd830215bdf2b602bbdcfc92512 Mon Sep 17 00:00:00 2001 From: 243wresfdxvc Date: Mon, 25 Apr 2022 18:18:50 +0000 Subject: [PATCH 19/21] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200406.=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E8=BA=AB=E9=AB=98=E9=87=8D=E5=BB=BA=E9=98=9F=E5=88=97?= =?UTF-8?q?.md=20C=E8=AF=AD=E8=A8=80=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0406.根据身高重建队列.md | 47 +++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/problems/0406.根据身高重建队列.md b/problems/0406.根据身高重建队列.md index b2354d09..9cefa11c 100644 --- a/problems/0406.根据身高重建队列.md +++ b/problems/0406.根据身高重建队列.md @@ -290,6 +290,53 @@ var reconstructQueue = function(people) { }; ``` +### C +```c +int cmp(const void *p1, const void *p2) { + int *pp1 = *(int**)p1; + int *pp2 = *(int**)p2; + // 若身高相同,则按照k从小到大排列 + // 若身高不同,按身高从大到小排列 + return pp1[0] == pp2[0] ? pp1[1] - pp2[1] : pp2[0] - pp1[0]; +} + +// 将start与end中间的元素都后移一位 +// start为将要新插入元素的位置 +void moveBack(int **people, int peopleSize, int start, int end) { + int i; + for(i = end; i > start; i--) { + people[i] = people[i-1]; + } +} + +int** reconstructQueue(int** people, int peopleSize, int* peopleColSize, int* returnSize, int** returnColumnSizes){ + int i; + // 将people按身高从大到小排列(若身高相同,按k从小到大排列) + qsort(people, peopleSize, sizeof(int*), cmp); + + for(i = 0; i < peopleSize; ++i) { + // people[i]要插入的位置 + int position = people[i][1]; + int *temp = people[i]; + // 将position到i中间的元素后移一位 + // 注:因为已经排好序,position不会比i大。(举例:排序后people最后一位元素最小,其可能的k最大值为peopleSize-2,小于此时的i) + moveBack(people, peopleSize, position, i); + // 将temp放置到position处 + people[position] = temp; + + } + + + // 设置返回二维数组的大小以及里面每个一维数组的长度 + *returnSize = peopleSize; + *returnColumnSizes = (int*)malloc(sizeof(int) * peopleSize); + for(i = 0; i < peopleSize; ++i) { + (*returnColumnSizes)[i] = 2; + } + return people; +} +``` + -----------------------
From 00b5e2aa64f49ce9273aca6aa8074d98fe4e489a Mon Sep 17 00:00:00 2001 From: eat to 160 pounds <2915390277@qq.com> Date: Fri, 6 May 2022 15:06:32 +0800 Subject: [PATCH 20/21] =?UTF-8?q?131=E5=88=86=E5=89=B2=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=E6=9B=B4=E6=B8=85=E6=A5=9A=E7=9A=84typescript?= =?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/0131.分割回文串.md | 41 ++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md index 10b747cb..7a702898 100644 --- a/problems/0131.分割回文串.md +++ b/problems/0131.分割回文串.md @@ -454,31 +454,36 @@ var partition = function(s) { ```typescript function partition(s: string): string[][] { - function isPalindromeStr(s: string, left: number, right: number): boolean { - while (left < right) { - if (s[left++] !== s[right--]) { - return false; + const res: string[][] = [] + const path: string[] = [] + const isHuiwen = ( + str: string, + startIndex: number, + endIndex: number + ): boolean => { + for (; startIndex < endIndex; startIndex++, endIndex--) { + if (str[startIndex] !== str[endIndex]) { + return false } } - return true; + return true } - function backTracking(s: string, startIndex: number, route: string[]): void { - let length: number = s.length; - if (length === startIndex) { - resArr.push(route.slice()); - return; + const rec = (str: string, index: number): void => { + if (index >= str.length) { + res.push([...path]) + return } - for (let i = startIndex; i < length; i++) { - if (isPalindromeStr(s, startIndex, i)) { - route.push(s.slice(startIndex, i + 1)); - backTracking(s, i + 1, route); - route.pop(); + for (let i = index; i < str.length; i++) { + if (!isHuiwen(str, index, i)) { + continue } + path.push(str.substring(index, i + 1)) + rec(str, i + 1) + path.pop() } } - const resArr: string[][] = []; - backTracking(s, 0, []); - return resArr; + rec(s, 0) + return res }; ``` From 0e5e657a6d5ba057e8dfa77019b25c5404fe9a9b Mon Sep 17 00:00:00 2001 From: 243wresfdxvc Date: Tue, 10 May 2022 23:04:35 +0000 Subject: [PATCH 21/21] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200404.=E5=B7=A6?= =?UTF-8?q?=E5=8F=B6=E5=AD=90=E4=B9=8B=E5=92=8C.md=20C=E8=AF=AD=E8=A8=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/0404.左叶子之和.md | 49 ++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/problems/0404.左叶子之和.md b/problems/0404.左叶子之和.md index 6420da81..d7fd629e 100644 --- a/problems/0404.左叶子之和.md +++ b/problems/0404.左叶子之和.md @@ -466,6 +466,55 @@ func sumOfLeftLeaves(_ root: TreeNode?) -> Int { } ``` +## C +递归法: +```c +int sumOfLeftLeaves(struct TreeNode* root){ + // 递归结束条件:若当前结点为空,返回0 + if(!root) + return 0; + + // 递归取左子树的左结点和和右子树的左结点和 + int leftValue = sumOfLeftLeaves(root->left); + int rightValue = sumOfLeftLeaves(root->right); + + // 若当前结点的左结点存在,且其为叶子结点。取它的值 + int midValue = 0; + if(root->left && (!root->left->left && !root->left->right)) + midValue = root->left->val; + + return leftValue + rightValue + midValue; +} +``` + +迭代法: +```c +int sumOfLeftLeaves(struct TreeNode* root){ + struct TreeNode* stack[1000]; + int stackTop = 0; + + // 若传入root结点不为空,将其入栈 + if(root) + stack[stackTop++] = root; + + int sum = 0; + //若栈不为空,进行循环 + while(stackTop) { + // 出栈栈顶元素 + struct TreeNode *topNode = stack[--stackTop]; + // 若栈顶元素的左孩子为左叶子结点,将其值加入sum中 + if(topNode->left && (!topNode->left->left && !topNode->left->right)) + sum += topNode->left->val; + + // 若当前栈顶结点有左右孩子。将他们加入栈中进行遍历 + if(topNode->right) + stack[stackTop++] = topNode->right; + if(topNode->left) + stack[stackTop++] = topNode->left; + } + return sum; +} +``` -----------------------