From 2b5b52081f0797672ed875318562bfa52b9187e9 Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Sun, 6 Jun 2021 22:39:18 +0800 Subject: [PATCH 001/110] =?UTF-8?q?update=2046.=E5=85=A8=E6=8E=92=E5=88=97?= =?UTF-8?q?=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0046.全排列.md | 40 +++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/problems/0046.全排列.md b/problems/0046.全排列.md index 06367851..30c3374b 100644 --- a/problems/0046.全排列.md +++ b/problems/0046.全排列.md @@ -244,31 +244,35 @@ func backtrack(nums,pathNums []int,used []bool){ } } +``` + Javascript: -```javascript +```js +/** + * @param {number[]} nums + * @return {number[][]} + */ var permute = function(nums) { - let result = [] - let path = [] - function backtracing(used) { - if(path.length === nums.length) { - result.push(path.slice(0)) - return + const res = [], path = []; + backtracking(nums, nums.length, []); + return res; + + function backtracking(n, k, used) { + if(path.length === k) { + res.push(Array.from(path)); + return; } - for(let i = 0; i < nums.length; i++) { - if(used[nums[i]]) { - continue - } - used[nums[i]] = true - path.push(nums[i]) - backtracing(used) - path.pop() - used[nums[i]] = false + for (let i = 0; i < k; i++ ) { + if(used[i]) continue; + path.push(n[i]); + used[i] = true; // 同支 + backtracking(n, k, used); + path.pop(); + used[i] = false; } } - backtracing([]) - return result }; ``` From e1bbd30d8ec02cab5b1c11dfb360f9252c809382 Mon Sep 17 00:00:00 2001 From: borninfreedom Date: Tue, 15 Jun 2021 16:01:10 +0800 Subject: [PATCH 002/110] =?UTF-8?q?update=20=E5=9B=9B=E6=95=B0=E7=9B=B8?= =?UTF-8?q?=E5=8A=A0II=EF=BC=8C=E6=B7=BB=E5=8A=A0=E4=BA=86=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E6=9B=B4=E5=8A=A0=E7=AE=80=E6=B4=81=E7=9A=84python?= =?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/0454.四数相加II.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/problems/0454.四数相加II.md b/problems/0454.四数相加II.md index 835178dd..0621ab5b 100644 --- a/problems/0454.四数相加II.md +++ b/problems/0454.四数相加II.md @@ -120,7 +120,7 @@ class Solution { Python: -``` +```python class Solution(object): def fourSumCount(self, nums1, nums2, nums3, nums4): """ @@ -147,7 +147,31 @@ class Solution(object): if key in hashmap: count += hashmap[key] return count + +# 下面这个写法更为简洁,但是表达的是同样的算法 +# class Solution: +# def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int: +# from collections import defaultdict + +# hashmap = defaultdict(int) + +# for x1 in nums1: +# for x2 in nums2: +# hashmap[x1+x2] += 1 + +# count=0 +# for x3 in nums3: +# for x4 in nums4: +# key = -x3-x4 +# value = hashmap.get(key) + + # dict的get方法会返回None(key不存在)或者key对应的value + # 所以如果value==0,就会继续执行or,count+0,否则就会直接加value + # 这样就不用去写if判断了 + +# count += value or 0 +# return count ``` From 999bbae8c24ed0dae872603ea0c0aab0ae1d7afe Mon Sep 17 00:00:00 2001 From: borninfreedom Date: Tue, 15 Jun 2021 16:13:23 +0800 Subject: [PATCH 003/110] =?UTF-8?q?=E5=B0=86python3=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=8C=BA=E6=A0=87=E8=AF=86=E6=94=B9=E4=B8=BApython?= =?UTF-8?q?=EF=BC=8C=E5=9B=A0=E4=B8=BAtypora=E4=B8=8D=E8=83=BD=E8=AF=86?= =?UTF-8?q?=E5=88=ABpython3=EF=BC=8C=E5=90=8C=E6=97=B6=E6=94=B9=E4=B8=BApy?= =?UTF-8?q?thon=E5=AF=B9=E9=AB=98=E4=BA=AE=E9=98=85=E8=AF=BB=E5=B9=B6?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E5=BD=B1=E5=93=8D=EF=BC=8C=E8=80=8C=E4=B8=94?= =?UTF-8?q?python=E5=AF=B9=E5=85=B6=E4=BB=96markdown=E8=BD=AF=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E5=85=BC=E5=AE=B9=E6=80=A7=E6=9B=B4=E5=A5=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0001.两数之和.md | 2 +- problems/0349.两个数组的交集.md | 2 +- problems/0707.设计链表.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index 02e9996f..31a808b0 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -107,7 +107,7 @@ public int[] twoSum(int[] nums, int target) { Python: -```python3 +```python class Solution: def twoSum(self, nums: List[int], target: int) -> List[int]: hashmap={} diff --git a/problems/0349.两个数组的交集.md b/problems/0349.两个数组的交集.md index 090480a4..5c635d39 100644 --- a/problems/0349.两个数组的交集.md +++ b/problems/0349.两个数组的交集.md @@ -118,7 +118,7 @@ class Solution { ``` Python: -```python3 +```python class Solution: def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]: result_set = set() diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md index 2fa1af29..2d096063 100644 --- a/problems/0707.设计链表.md +++ b/problems/0707.设计链表.md @@ -239,7 +239,7 @@ class MyLinkedList { ``` Python: -```python3 +```python # 单链表 class Node: From fb21a5727e249ce000d14edf59b291b6d099ce2b Mon Sep 17 00:00:00 2001 From: borninfreedom Date: Tue, 15 Jun 2021 16:50:32 +0800 Subject: [PATCH 004/110] =?UTF-8?q?update=E8=B5=8E=E9=87=91=E4=BF=A1?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E4=BA=86=E4=BD=BF=E7=94=A8=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E4=BD=9C=E4=B8=BA=E5=93=88=E5=B8=8C=E8=A1=A8=E5=92=8C?= =?UTF-8?q?=E4=BD=BF=E7=94=A8defaultdict=E4=B8=A4=E7=A7=8D=E5=86=99?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0383.赎金信.md | 49 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/problems/0383.赎金信.md b/problems/0383.赎金信.md index 23e2c5fd..5374a08f 100644 --- a/problems/0383.赎金信.md +++ b/problems/0383.赎金信.md @@ -135,8 +135,52 @@ class Solution { ``` -Python: -```py +Python写法一(使用数组作为哈希表): + +```python +class Solution: + def canConstruct(self, ransomNote: str, magazine: str) -> bool: + + arr = [0] * 26 + + for x in magazine: + arr[ord(x) - ord('a')] += 1 + + for x in ransomNote: + if arr[ord(x) - ord('a')] == 0: + return False + else: + arr[ord(x) - ord('a')] -= 1 + + return True +``` + +Python写法二(使用defaultdict): + +```python +class Solution: + def canConstruct(self, ransomNote: str, magazine: str) -> bool: + + from collections import defaultdict + + hashmap = defaultdict(int) + + for x in magazine: + hashmap[x] += 1 + + for x in ransomNote: + value = hashmap.get(x) + if value is None or value == 0: + return False + else: + hashmap[x] -= 1 + + return True +``` + +Python写法三: + +```python class Solution(object): def canConstruct(self, ransomNote, magazine): """ @@ -166,6 +210,7 @@ class Solution(object): ``` Go: + ```go func canConstruct(ransomNote string, magazine string) bool { record := make([]int, 26) From c79cc4845411209b7ce143ebc4f98adfd969b2b2 Mon Sep 17 00:00:00 2001 From: yff-1996 Date: Tue, 15 Jun 2021 16:19:01 +0800 Subject: [PATCH 005/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A00151.=E7=BF=BB?= =?UTF-8?q?=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2=E9=87=8C=E7=9A=84=E5=8D=95?= =?UTF-8?q?=E8=AF=8D=20Python=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0151.翻转字符串里的单词.md | 51 ++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/problems/0151.翻转字符串里的单词.md b/problems/0151.翻转字符串里的单词.md index d76734e4..a174d550 100644 --- a/problems/0151.翻转字符串里的单词.md +++ b/problems/0151.翻转字符串里的单词.md @@ -318,6 +318,57 @@ class Solution { Python: +```Python3 +class Solution: + #1.去除多余的空格 + def trim_spaces(self,s): + n=len(s) + left=0 + right=n-1 + + while left<=right and s[left]==' ': #去除开头的空格 + left+=1 + while left<=right and s[right]==' ': #去除结尾的空格 + right=right-1 + tmp=[] + while left<=right: #去除单词中间多余的空格 + if s[left]!=' ': + tmp.append(s[left]) + elif tmp[-1]!=' ': #当前位置是空格,但是相邻的上一个位置不是空格,则该空格是合理的 + tmp.append(s[left]) + left+=1 + return tmp +#2.翻转字符数组 + def reverse_string(self,nums,left,right): + while left Date: Tue, 15 Jun 2021 17:35:31 +0800 Subject: [PATCH 006/110] =?UTF-8?q?0435.=E6=97=A0=E9=87=8D=E5=8F=A0?= =?UTF-8?q?=E5=8C=BA=E9=97=B4.md=20Javascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0435.无重叠区间.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0435.无重叠区间.md b/problems/0435.无重叠区间.md index 248526a1..23ee9f94 100644 --- a/problems/0435.无重叠区间.md +++ b/problems/0435.无重叠区间.md @@ -228,7 +228,27 @@ class Solution: Go: +Javascript: +```Javascript +var eraseOverlapIntervals = function(intervals) { + intervals.sort((a, b) => { + return a[1] - b[1] + }) + let count = 1 + let end = intervals[0][1] + + for(let i = 1; i < intervals.length; i++) { + let interval = intervals[i] + if(interval[0] >= right) { + end = interval[1] + count += 1 + } + } + + return intervals.length - count +}; +``` ----------------------- From 3a2ab58846f8071e704a0043600f457bfee70277 Mon Sep 17 00:00:00 2001 From: yff-1996 Date: Tue, 15 Jun 2021 18:42:59 +0800 Subject: [PATCH 007/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0151.=E7=BF=BB?= =?UTF-8?q?=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2=E9=87=8C=E7=9A=84=E5=8D=95?= =?UTF-8?q?=E8=AF=8D=20python=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0151.翻转字符串里的单词.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/problems/0151.翻转字符串里的单词.md b/problems/0151.翻转字符串里的单词.md index a174d550..c76ff0e1 100644 --- a/problems/0151.翻转字符串里的单词.md +++ b/problems/0151.翻转字符串里的单词.md @@ -359,10 +359,10 @@ class Solution: return None #4.翻转字符串里的单词 - def reverseWords(self, s): #测试用例:"the sky is blue - l = self.trim_spaces(s) #输出:"the sky is blue" - self.reverse_string( l, 0, len(l) - 1) #输出:"blue is sky the" - self.reverse_each_word(l) #输出:"blue is sky the" + def reverseWords(self, s): #测试用例:"the sky is blue" + l = self.trim_spaces(s) #输出:['t', 'h', 'e', ' ', 's', 'k', 'y', ' ', 'i', 's', ' ', 'b', 'l', 'u', 'e' + self.reverse_string( l, 0, len(l) - 1) #输出:['e', 'u', 'l', 'b', ' ', 's', 'i', ' ', 'y', 'k', 's', ' ', 'e', 'h', 't'] + self.reverse_each_word(l) #输出:['b', 'l', 'u', 'e', ' ', 'i', 's', ' ', 's', 'k', 'y', ' ', 't', 'h', 'e'] return ''.join(l) #输出:blue is sky the From 7f76ec27103666f6003c0c8ed9b40c1432469d56 Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Tue, 15 Jun 2021 20:07:14 +0800 Subject: [PATCH 008/110] Update --- problems/0344.反转字符串.md | 20 +++++++++----------- problems/0541.反转字符串II.md | 8 ++++---- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/problems/0344.反转字符串.md b/problems/0344.反转字符串.md index 1b86e847..fd395ce6 100644 --- a/problems/0344.反转字符串.md +++ b/problems/0344.反转字符串.md @@ -20,14 +20,13 @@ https://leetcode-cn.com/problems/reverse-string/ 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。 -示例 1: +示例 1: +输入:["h","e","l","l","o"] +输出:["o","l","l","e","h"] -输入:["h","e","l","l","o"] -输出:["o","l","l","e","h"] -示例 2: - -输入:["H","a","n","n","a","h"] -输出:["h","a","n","n","a","H"] +示例 2: +输入:["H","a","n","n","a","h"] +输出:["h","a","n","n","a","H"] # 思路 @@ -56,7 +55,7 @@ https://leetcode-cn.com/problems/reverse-string/ 接下来再来讲一下如何解决反转字符串的问题。 -大家应该还记得,我们已经讲过了[206.反转链表](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg)。 +大家应该还记得,我们已经讲过了[206.反转链表](https://mp.weixin.qq.com/s/ckEvIVGcNLfrz6OLOMoT0A)。 在反转链表中,使用了双指针的方法。 @@ -64,7 +63,7 @@ https://leetcode-cn.com/problems/reverse-string/ 因为字符串也是一种数组,所以元素在内存中是连续分布,这就决定了反转链表和反转字符串方式上还是有所差异的。 -如果对数组和链表原理不清楚的同学,可以看这两篇,[关于链表,你该了解这些!](https://mp.weixin.qq.com/s/ntlZbEdKgnFQKZkSUAOSpQ),[必须掌握的数组理论知识](https://mp.weixin.qq.com/s/X7R55wSENyY62le0Fiawsg)。 +如果对数组和链表原理不清楚的同学,可以看这两篇,[关于链表,你该了解这些!](https://mp.weixin.qq.com/s/fDGMmLrW7ZHlzkzlf_dZkw),[必须掌握的数组理论知识](https://mp.weixin.qq.com/s/c2KABb-Qgg66HrGf8z-8Og)。 对于字符串,我们定义两个指针(也可以说是索引下表),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。 @@ -119,8 +118,7 @@ s[i] ^= s[j]; 相信大家本着我所讲述的原则来做字符串相关的题目,在选择库函数的角度上会有所原则,也会有所收获。 - -## C++代码 +C++代码如下: ```C++ class Solution { diff --git a/problems/0541.反转字符串II.md b/problems/0541.反转字符串II.md index 00581fc0..3f7767fd 100644 --- a/problems/0541.反转字符串II.md +++ b/problems/0541.反转字符串II.md @@ -22,8 +22,8 @@ https://leetcode-cn.com/problems/reverse-string-ii/ 示例: -输入: s = "abcdefg", k = 2 -输出: "bacdfeg" +输入: s = "abcdefg", k = 2 +输出: "bacdfeg" # 思路 @@ -38,7 +38,7 @@ https://leetcode-cn.com/problems/reverse-string-ii/ **所以当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。** 性能如下: - + 那么这里具体反转的逻辑我们要不要使用库函数呢,其实用不用都可以,使用reverse来实现反转也没毛病,毕竟不是解题关键部分。 @@ -65,7 +65,7 @@ public: }; ``` -那么我们也可以实现自己的reverse函数,其实和题目[344. 反转字符串](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA)道理是一样的。 +那么我们也可以实现自己的reverse函数,其实和题目[344. 反转字符串](https://mp.weixin.qq.com/s/_rNm66OJVl92gBDIbGpA3w)道理是一样的。 下面我实现的reverse函数区间是左闭右闭区间,代码如下: From b3eacc519bbe2e4f7ce1903dcb1eb7f740dfe535 Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Tue, 15 Jun 2021 21:11:42 +0800 Subject: [PATCH 009/110] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=A0=91=E7=9A=84=E9=80=92=E5=BD=92=E9=81=8D=E5=8E=86=20go?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=9A=84=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/二叉树的递归遍历.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/problems/二叉树的递归遍历.md b/problems/二叉树的递归遍历.md index f2072e30..68f17257 100644 --- a/problems/二叉树的递归遍历.md +++ b/problems/二叉树的递归遍历.md @@ -221,12 +221,12 @@ class Solution: Go: 前序遍历: -``` +```go func PreorderTraversal(root *TreeNode) (res []int) { var traversal func(node *TreeNode) traversal = func(node *TreeNode) { if node == nil { - return + return } res = append(res,node.Val) traversal(node.Left) @@ -239,12 +239,12 @@ func PreorderTraversal(root *TreeNode) (res []int) { ``` 中序遍历: -``` +```go func InorderTraversal(root *TreeNode) (res []int) { var traversal func(node *TreeNode) traversal = func(node *TreeNode) { if node == nil { - return + return } traversal(node.Left) res = append(res,node.Val) @@ -256,12 +256,12 @@ func InorderTraversal(root *TreeNode) (res []int) { ``` 后序遍历: -``` +```go func PostorderTraversal(root *TreeNode) (res []int) { var traversal func(node *TreeNode) traversal = func(node *TreeNode) { if node == nil { - return + return } traversal(node.Left) traversal(node.Right) From 11115137a8e1b51958954eba3899f052f380353e Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Tue, 15 Jun 2021 22:20:45 +0800 Subject: [PATCH 010/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A00071.0501.=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E4=B8=AD=E7=9A=84=E4=BC=97?= =?UTF-8?q?=E6=95=B0=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加0071.0501.二叉搜索树中的众数 go版本 --- problems/0501.二叉搜索树中的众数.md | 93 ++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/problems/0501.二叉搜索树中的众数.md b/problems/0501.二叉搜索树中的众数.md index dfd589ce..3ca7d892 100644 --- a/problems/0501.二叉搜索树中的众数.md +++ b/problems/0501.二叉搜索树中的众数.md @@ -428,7 +428,100 @@ class Solution: return self.res ``` Go: +暴力法(非BSL) +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func findMode(root *TreeNode) []int { + var history map[int]int + var maxValue int + var maxIndex int + var result []int + history=make(map[int]int) + traversal(root,history) + for k,value:=range history{ + if value>maxValue{ + maxValue=value + maxIndex=k + } + } + for k,value:=range history{ + if value==history[maxIndex]{ + result=append(result,k) + } + } + return result +} +func traversal(root *TreeNode,history map[int]int){ + if root.Left!=nil{ + traversal(root.Left,history) + } + if value,ok:=history[root.Val];ok{ + history[root.Val]=value+1 + }else{ + history[root.Val]=1 + } + if root.Right!=nil{ + traversal(root.Right,history) + } +} +``` + +计数法BSL(此代码在执行代码里能执行,但提交后报错,不知为何,思路是对的) + +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ + var count,maxCount int //统计计数 +func findMode(root *TreeNode) []int { + var result []int + var pre *TreeNode //前指针 + if root.Left==nil&&root.Right==nil{ + result=append(result,root.Val) + return result + } + traversal(root,&result,pre) + return result +} +func traversal(root *TreeNode,result *[]int,pre *TreeNode){//遍历统计 + //如果BSL中序遍历相邻的两个节点值相同,则统计频率;如果不相同,依据BSL中序遍历排好序的性质,重新计数 + if pre==nil{ + count=1 + }else if pre.Val==root.Val{ + count++ + }else { + count=1 + } + //如果统计的频率等于最大频率,则加入结果集;如果统计的频率大于最大频率,更新最大频率且重新将结果加入新的结果集中 + if count==maxCount{ + *result=append(*result,root.Val) + }else if count>maxCount{ + maxCount=count//重新赋值maxCount + *result=[]int{}//清空result中的内容 + *result=append(*result,root.Val) + } + pre=root//保存上一个的节点 + if root.Left!=nil{ + traversal(root.Left,result,pre) + } + if root.Right!=nil{ + traversal(root.Right,result,pre) + } +} +``` From 7221797cca0a206f469732c3dc5a06c3ef9d3885 Mon Sep 17 00:00:00 2001 From: yangxk201396 <54167260+yangxk201396@users.noreply.github.com> Date: Wed, 16 Jun 2021 02:06:23 +0800 Subject: [PATCH 011/110] =?UTF-8?q?Update=201005.K=E6=AC=A1=E5=8F=96?= =?UTF-8?q?=E5=8F=8D=E5=90=8E=E6=9C=80=E5=A4=A7=E5=8C=96=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 1005.K次取反后最大化的数组和.md Golang版本 --- ...1005.K次取反后最大化的数组和.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/problems/1005.K次取反后最大化的数组和.md b/problems/1005.K次取反后最大化的数组和.md index 387de147..c3e99f7e 100644 --- a/problems/1005.K次取反后最大化的数组和.md +++ b/problems/1005.K次取反后最大化的数组和.md @@ -138,6 +138,30 @@ class Solution: ``` Go: +```Go +func largestSumAfterKNegations(nums []int, K int) int { + sort.Slice(nums, func(i, j int) bool { + return math.Abs(float64(nums[i])) > math.Abs(float64(nums[j])) + }) + + for i := 0; i < len(nums); i++ { + if K > 0 && nums[i] < 0 { + nums[i] = -nums[i] + K-- + } + } + + if K%2 == 1 { + nums[len(nums)-1] = -nums[len(nums)-1] + } + + result := 0 + for i := 0; i < len(nums); i++ { + result += nums[i] + } + return result +} +``` Javascript: From 1ad27bcb0d5bba938a5e27ce5c12ebb4eda9a81e Mon Sep 17 00:00:00 2001 From: callmePicacho <38685653+callmePicacho@users.noreply.github.com> Date: Wed, 16 Jun 2021 07:55:38 +0800 Subject: [PATCH 012/110] =?UTF-8?q?=E4=B8=BA"=E6=BB=91=E5=8A=A8=E7=AA=97?= =?UTF-8?q?=E5=8F=A3"=E7=B3=BB=E5=88=97=E7=9B=B8=E5=85=B3=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E6=8E=A8=E8=8D=90=E6=B7=BB=E5=8A=A0=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0209.长度最小的子数组.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/problems/0209.长度最小的子数组.md b/problems/0209.长度最小的子数组.md index 90280451..42687514 100644 --- a/problems/0209.长度最小的子数组.md +++ b/problems/0209.长度最小的子数组.md @@ -109,7 +109,7 @@ public: }; ``` -时间复杂度:$O(n)$ +时间复杂度:$O(n)$ 空间复杂度:$O(1)$ **一些录友会疑惑为什么时间复杂度是O(n)**。 @@ -118,8 +118,8 @@ public: ## 相关题目推荐 -* 904.水果成篮 -* 76.最小覆盖子串 +* [904.水果成篮](https://leetcode-cn.com/problems/fruit-into-baskets/) +* [76.最小覆盖子串](https://leetcode-cn.com/problems/minimum-window-substring/) From 2ed2d8bf13e823df335492d806c6d069fa32b9ff Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Wed, 16 Jun 2021 08:10:13 +0800 Subject: [PATCH 013/110] =?UTF-8?q?0763.=E5=88=92=E5=88=86=E5=AD=97?= =?UTF-8?q?=E6=AF=8D=E5=8C=BA=E9=97=B4.md=20Javascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0763.划分字母区间.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/problems/0763.划分字母区间.md b/problems/0763.划分字母区间.md index bcdd71dc..1e2fcc03 100644 --- a/problems/0763.划分字母区间.md +++ b/problems/0763.划分字母区间.md @@ -128,7 +128,26 @@ class Solution: Go: - +Javascript: +```Javascript +var partitionLabels = function(s) { + let hash = {} + for(let i = 0; i < s.length; i++) { + hash[s[i]] = i + } + let result = [] + let left = 0 + let right = 0 + for(let i = 0; i < s.length; i++) { + right = Math.max(right, hash[s[i]]) + if(right === i) { + result.push(right - left + 1) + left = i + 1 + } + } + return result +}; +``` ----------------------- From 0bafb2d775466d18eec6b142163657ffe3a66b05 Mon Sep 17 00:00:00 2001 From: Kelvin Date: Tue, 15 Jun 2021 21:05:09 -0400 Subject: [PATCH 014/110] =?UTF-8?q?=E6=9B=B4=E6=94=B9=20=E8=83=8C=E5=8C=85?= =?UTF-8?q?=E7=90=86=E8=AE=BA=E5=9F=BA=E7=A1=8001=E8=83=8C=E5=8C=85-2.md?= =?UTF-8?q?=20Java=20=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/背包理论基础01背包-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/背包理论基础01背包-2.md b/problems/背包理论基础01背包-2.md index e85d31b4..075bb5b1 100644 --- a/problems/背包理论基础01背包-2.md +++ b/problems/背包理论基础01背包-2.md @@ -214,7 +214,7 @@ int main() { Java: ```java - public static void main(String[] args) { + public static void main(String[] args) { int[] weight = {1, 3, 4}; int[] value = {15, 20, 30}; int bagWight = 4; From ecd98c9a79e1e3efbde2dc140d9adc7b2af93c3b Mon Sep 17 00:00:00 2001 From: Kelvin Date: Tue, 15 Jun 2021 21:06:42 -0400 Subject: [PATCH 015/110] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20=E8=83=8C=E5=8C=85?= =?UTF-8?q?=E7=90=86=E8=AE=BA=E5=9F=BA=E7=A1=8001=E8=83=8C=E5=8C=85-2.md?= =?UTF-8?q?=20Python3=20=E5=AE=9E=E7=8E=B0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/背包理论基础01背包-2.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/背包理论基础01背包-2.md b/problems/背包理论基础01背包-2.md index 075bb5b1..aee1a929 100644 --- a/problems/背包理论基础01背包-2.md +++ b/problems/背包理论基础01背包-2.md @@ -242,7 +242,24 @@ Java: Python: +```python +def test_1_wei_bag_problem(): + weight = [1, 3, 4] + value = [15, 20, 30] + bag_weight = 4 + # 初始化: 全为0 + dp = [0] * (bag_weight + 1) + # 先遍历物品, 再遍历背包容量 + for i in range(len(weight)): + for j in range(bag_weight, weight[i] - 1, -1): + # 递归公式 + dp[j] = max(dp[j], dp[j - weight[i]] + value[i]) + + print(dp) + +test_1_wei_bag_problem() +``` Go: ```go From 5dc2a0b745086c026e75cde53d898a67f9e98eb1 Mon Sep 17 00:00:00 2001 From: Kelvin Date: Tue, 15 Jun 2021 21:09:06 -0400 Subject: [PATCH 016/110] =?UTF-8?q?=E6=9B=B4=E6=94=B9=20=E8=83=8C=E5=8C=85?= =?UTF-8?q?=E7=90=86=E8=AE=BA=E5=9F=BA=E7=A1=8001=E8=83=8C=E5=8C=85-2.md?= =?UTF-8?q?=20=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加一个空行, 因为如果没有空行浏览器render文字就会有问题. --- problems/背包理论基础01背包-2.md | 1 + 1 file changed, 1 insertion(+) diff --git a/problems/背包理论基础01背包-2.md b/problems/背包理论基础01背包-2.md index aee1a929..c8b80655 100644 --- a/problems/背包理论基础01背包-2.md +++ b/problems/背包理论基础01背包-2.md @@ -5,6 +5,7 @@

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

+ # 动态规划:关于01背包问题,你该了解这些!(滚动数组) 昨天[动态规划:关于01背包问题,你该了解这些!](https://mp.weixin.qq.com/s/FwIiPPmR18_AJO5eiidT6w)中是用二维dp数组来讲解01背包。 From 3746acd22b02e94945a20d9c2a69de788a0f016c Mon Sep 17 00:00:00 2001 From: Kelvin Date: Tue, 15 Jun 2021 21:10:08 -0400 Subject: [PATCH 017/110] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20=E8=83=8C=E5=8C=85?= =?UTF-8?q?=E7=90=86=E8=AE=BA=E5=9F=BA=E7=A1=8001=E8=83=8C=E5=8C=85-2.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 小typo. --- problems/背包理论基础01背包-2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/背包理论基础01背包-2.md b/problems/背包理论基础01背包-2.md index c8b80655..48275908 100644 --- a/problems/背包理论基础01背包-2.md +++ b/problems/背包理论基础01背包-2.md @@ -36,7 +36,7 @@ **其实可以发现如果把dp[i - 1]那一层拷贝到dp[i]上,表达式完全可以是:dp[i][j] = max(dp[i][j], dp[i][j - weight[i]] + value[i]);** -**于其把dp[i - 1]这一层拷贝到dp[i]上,不如只用一个一维数组了**,只用dp[j](一维数组,也可以理解是一个滚动数组)。 +**与其把dp[i - 1]这一层拷贝到dp[i]上,不如只用一个一维数组了**,只用dp[j](一维数组,也可以理解是一个滚动数组)。 这就是滚动数组的由来,需要满足的条件是上一层可以重复利用,直接拷贝到当前层。 From a7d9d7aa23d2bb1d647d758b3ea1d65aef8e28e6 Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Wed, 16 Jun 2021 09:39:16 +0800 Subject: [PATCH 018/110] =?UTF-8?q?=E6=8F=90=E4=BA=A4=20=E3=80=8A=E4=BB=8E?= =?UTF-8?q?=E5=89=8D=E5=BA=8F=E4=B8=8E=E4=B8=AD=E5=BA=8F=E9=81=8D=E5=8E=86?= =?UTF-8?q?=E5=BA=8F=E5=88=97=E6=9E=84=E9=80=A0=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E3=80=8BJavaScript=E7=89=88=E6=9C=AC=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...中序与后序遍历序列构造二叉树.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/problems/0106.从中序与后序遍历序列构造二叉树.md b/problems/0106.从中序与后序遍历序列构造二叉树.md index 600a38e0..4c5a70a0 100644 --- a/problems/0106.从中序与后序遍历序列构造二叉树.md +++ b/problems/0106.从中序与后序遍历序列构造二叉树.md @@ -775,6 +775,20 @@ var buildTree = function(inorder, postorder) { }; ``` +从前序与中序遍历序列构造二叉树 + +```javascript +var buildTree = function(preorder, inorder) { + if(!preorder.length) + return null; + let root = new TreeNode(preorder[0]); + let mid = inorder.findIndex((number) => number === root.val); + root.left = buildTree(preorder.slice(1, mid + 1), inorder.slice(0, mid)); + root.right = buildTree(preorder.slice(mid + 1, preorder.length), inorder.slice(mid + 1, inorder.length)); + return root; +}; +``` + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) From 381c4e1bdf8c2b894e88817a79ffd388144c164c Mon Sep 17 00:00:00 2001 From: yangxk201396 <54167260+yangxk201396@users.noreply.github.com> Date: Wed, 16 Jun 2021 10:43:50 +0800 Subject: [PATCH 019/110] =?UTF-8?q?Update=200134.=E5=8A=A0=E6=B2=B9?= =?UTF-8?q?=E7=AB=99.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0134.加油站.md Golang 版本 --- problems/0134.加油站.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/problems/0134.加油站.md b/problems/0134.加油站.md index dfed2d96..9b660ea0 100644 --- a/problems/0134.加油站.md +++ b/problems/0134.加油站.md @@ -240,6 +240,25 @@ class Solution: ``` Go: +```go +func canCompleteCircuit(gas []int, cost []int) int { + curSum := 0 + totalSum := 0 + start := 0 + for i := 0; i < len(gas); i++ { + curSum += gas[i] - cost[i] + totalSum += gas[i] - cost[i] + if curSum < 0 { + start = i+1 + curSum = 0 + } + } + if totalSum < 0 { + return -1 + } + return start +} +``` Javascript: ```Javascript From d5b0e0ce587df7bb9c627bbad784b71d01098e36 Mon Sep 17 00:00:00 2001 From: Jijie LIU Date: Wed, 16 Jun 2021 14:49:07 +0200 Subject: [PATCH 020/110] =?UTF-8?q?Update=2093.=E5=A4=8D=E5=8E=9FIP?= =?UTF-8?q?=E5=9C=B0=E5=9D=80,=20=E6=B7=BB=E5=8A=A0Python3=E7=89=88?= =?UTF-8?q?=E6=9C=AC=EF=BC=8C=E7=94=A8=E4=BA=86=E6=96=B0=E7=9A=84=E5=89=AA?= =?UTF-8?q?=E6=9E=9D=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0093.复原IP地址.md | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/problems/0093.复原IP地址.md b/problems/0093.复原IP地址.md index a8b9a215..c47896d9 100644 --- a/problems/0093.复原IP地址.md +++ b/problems/0093.复原IP地址.md @@ -338,6 +338,46 @@ class Solution(object): return ans``` ``` +```python3 +class Solution: + def __init__(self) -> None: + self.s = "" + self.res = [] + + def isVaild(self, s: str) -> bool: + if len(s) > 1 and s[0] == "0": + return False + + if 0 <= int(s) <= 255: + return True + + return False + + def backTrack(self, path: List[str], start: int) -> None: + if start == len(self.s) and len(path) == 4: + self.res.append(".".join(path)) + return + + for end in range(start + 1, len(self.s) + 1): + # 剪枝 + # 保证切割完,s没有剩余的字符。 + if len(self.s) - end > 3 * (4 - len(path) - 1): + continue + if self.isVaild(self.s[start:end]): + # 在参数处,更新状态,实则创建一个新的变量 + # 不会影响当前的状态,当前的path变量没有改变 + # 因此递归完不用path.pop() + self.backTrack(path + [self.s[start:end]], end) + + def restoreIpAddresses(self, s: str) -> List[str]: + # prune + if len(s) > 3 * 4: + return [] + self.s = s + self.backTrack([], 0) + return self.res +``` + JavaScript: ```js From 2f514cd212303f53e8f30da93498b66e2df9577c Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Wed, 16 Jun 2021 23:11:56 +0800 Subject: [PATCH 021/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A00235.=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E7=9A=84=E6=9C=80=E8=BF=91?= =?UTF-8?q?=E5=85=AC=E5=85=B1=E7=A5=96=E5=85=88=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加0235.二叉搜索树的最近公共祖先 go版本 --- ...35.二叉搜索树的最近公共祖先.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/problems/0235.二叉搜索树的最近公共祖先.md b/problems/0235.二叉搜索树的最近公共祖先.md index 15ff7af4..d78db42a 100644 --- a/problems/0235.二叉搜索树的最近公共祖先.md +++ b/problems/0235.二叉搜索树的最近公共祖先.md @@ -265,6 +265,54 @@ class Solution: else: return root ``` Go: +> BSL法 + +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +//利用BSL的性质(前序遍历有序) +func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { + if root==nil{return nil} + if root.Val>p.Val&&root.Val>q.Val{//当前节点的值大于给定的值,则说明满足条件的在左边 + return lowestCommonAncestor(root.Left,p,q) + }else if root.Val 普通法 + +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +//递归会将值层层返回 +func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { + //终止条件 + if root==nil||root.Val==p.Val||root.Val==q.Val{return root}//最后为空或者找到一个值时,就返回这个值 + //后序遍历 + findLeft:=lowestCommonAncestor(root.Left,p,q) + findRight:=lowestCommonAncestor(root.Right,p,q) + //处理单层逻辑 + if findLeft!=nil&&findRight!=nil{return root}//说明在root节点的两边 + if findLeft==nil{//左边没找到,就说明在右边找到了 + return findRight + }else {return findLeft} +} +``` + From 6994866773b176ff7154ff59f08a159278bfe1e3 Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Thu, 17 Jun 2021 08:15:32 +0800 Subject: [PATCH 022/110] =?UTF-8?q?0738.=E5=8D=95=E8=B0=83=E9=80=92?= =?UTF-8?q?=E5=A2=9E=E7=9A=84=E6=95=B0=E5=AD=97.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0738.单调递增的数字.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/0738.单调递增的数字.md b/problems/0738.单调递增的数字.md index 5bddb234..41ca67be 100644 --- a/problems/0738.单调递增的数字.md +++ b/problems/0738.单调递增的数字.md @@ -163,7 +163,30 @@ class Solution: Go: +Javascript: +```Javascript +var monotoneIncreasingDigits = function(n) { + n = n.toString() + n = n.split('').map(item => { + return +item + }) + let flag = Infinity + for(let i = n.length - 1; i > 0; i--) { + if(n [i - 1] > n[i]) { + flag = i + n[i - 1] = n[i - 1] - 1 + n[i] = 9 + } + } + for(let i = flag; i < n.length; i++) { + n[i] = 9 + } + + n = n.join('') + return +n +}; +``` ----------------------- From 78b32e8c6c2c7708e1407c729ceebfeeca033f4d Mon Sep 17 00:00:00 2001 From: KailokFung Date: Thu, 17 Jun 2021 17:53:56 +0800 Subject: [PATCH 023/110] =?UTF-8?q?feat(0541):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=8F=A6=E4=B8=80=E7=A7=8DJava=E7=89=88=E6=9C=AC=E5=86=99?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0541.反转字符串II.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/0541.反转字符串II.md b/problems/0541.反转字符串II.md index 00581fc0..4b3ed43b 100644 --- a/problems/0541.反转字符串II.md +++ b/problems/0541.反转字符串II.md @@ -103,6 +103,7 @@ public: Java: ```Java +//解法一 class Solution { public String reverseStr(String s, int k) { StringBuffer res = new StringBuffer(); @@ -128,6 +129,28 @@ class Solution { return res.toString(); } } + +//解法二(似乎更容易理解点) +//题目的意思其实概括为 每隔2k个反转前k个,尾数不够k个时候全部反转 +class Solution { + public String reverseStr(String s, int k) { + char[] ch = s.toCharArray(); + for(int i = 0; i < ch.length; i += 2 * k){ + int start = i; + //这里是判断尾数够不够k个来取决end指针的位置 + int end = Math.min(ch.length - 1, start + k - 1); + //用异或运算反转 + while(start < end){ + ch[start] ^= ch[end]; + ch[end] ^= ch[start]; + ch[start] ^= ch[end]; + start++; + end--; + } + } + return new String(ch); + } +} ``` Python: From 928b034e9bca9667949e22b589ece1b6f0b7a4d0 Mon Sep 17 00:00:00 2001 From: Jijie LIU Date: Thu, 17 Jun 2021 17:27:30 +0200 Subject: [PATCH 024/110] =?UTF-8?q?update=2037.=20=E8=A7=A3=E6=95=B0?= =?UTF-8?q?=E7=8B=AC:=20=E6=8F=90=E4=BE=9Bpython3=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=EF=BC=8C=E7=AE=80=E5=8C=96isValid=EF=BC=8C=20=E6=8F=90?= =?UTF-8?q?=E9=AB=98=E5=9B=9E=E6=BA=AF=E5=87=BD=E6=95=B0=E7=9A=84=E5=8F=AF?= =?UTF-8?q?=E8=AF=BB=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0037.解数独.md | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/problems/0037.解数独.md b/problems/0037.解数独.md index 4eb60704..e43708b8 100644 --- a/problems/0037.解数独.md +++ b/problems/0037.解数独.md @@ -321,6 +321,59 @@ class Solution: backtrack(board) ``` +Python3: + +```python3 +class Solution: + def __init__(self) -> None: + self.board = [] + + def isValid(self, row: int, col: int, target: int) -> bool: + for idx in range(len(self.board)): + # 同列是否重复 + if self.board[idx][col] == str(target): + return False + # 同行是否重复 + if self.board[row][idx] == str(target): + return False + # 9宫格里是否重复 + box_row, box_col = (row // 3) * 3 + idx // 3, (col // 3) * 3 + idx % 3 + if self.board[box_row][box_col] == str(target): + return False + return True + + def getPlace(self) -> List[int]: + for row in range(len(self.board)): + for col in range(len(self.board)): + if self.board[row][col] == ".": + return [row, col] + return [-1, -1] + + def isSolved(self) -> bool: + row, col = self.getPlace() # 找个空位置 + + if row == -1 and col == -1: # 没有空位置,棋盘被填满的 + return True + + for i in range(1, 10): + if self.isValid(row, col, i): # 检查这个空位置放i,是否合适 + self.board[row][col] = str(i) # 放i + if self.isSolved(): # 合适,立刻返回, 填下一个空位置。 + return True + self.board[row][col] = "." # 不合适,回溯 + + return False # 空位置没法解决 + + def solveSudoku(self, board: List[List[str]]) -> None: + """ + Do not return anything, modify board in-place instead. + """ + if board is None or len(board) == 0: + return + self.board = board + self.isSolved() +``` + Go: Javascript: From 31ac198cd18ab1c1eb32665ddf52623c6e3b6c03 Mon Sep 17 00:00:00 2001 From: jojoo15 <75017412+jojoo15@users.noreply.github.com> Date: Thu, 17 Jun 2021 18:11:09 +0200 Subject: [PATCH 025/110] =?UTF-8?q?=E4=BC=98=E5=8C=96=200738.=E5=8D=95?= =?UTF-8?q?=E8=B0=83=E9=80=92=E5=A2=9E=E7=9A=84=E6=95=B0=E5=AD=97=20python?= =?UTF-8?q?3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化 0738.单调递增的数字 python3 --- problems/0738.单调递增的数字.md | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/problems/0738.单调递增的数字.md b/problems/0738.单调递增的数字.md index 5bddb234..665f0fd6 100644 --- a/problems/0738.单调递增的数字.md +++ b/problems/0738.单调递增的数字.md @@ -147,18 +147,15 @@ class Solution { Python: -```python +```python3 class Solution: def monotoneIncreasingDigits(self, n: int) -> int: - strNum = list(str(n)) - flag = len(strNum) - for i in range(len(strNum) - 1, 0, -1): - if int(strNum[i]) < int(strNum[i - 1]): - strNum[i - 1] = str(int(strNum[i - 1]) - 1) - flag = i - for i in range(flag, len(strNum)): - strNum[i] = '9' - return int("".join(strNum)) + a = list(str(n)) + for i in range(len(a)-1,0,-1): + if int(a[i]) < int(a[i-1]): + a[i-1] = str(int(a[i-1]) - 1) + a[i:] = '9' * (len(a) - i) #python不需要设置flag值,直接按长度给9就好了 + return int("".join(a)) ``` Go: From ae3843698a156e7b7be6c0348df5ae882b645b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=97=A4=E9=9C=B2?= <080301087@163.com> Date: Fri, 18 Jun 2021 11:07:32 +0800 Subject: [PATCH 026/110] =?UTF-8?q?Update=200102.=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?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0102.二叉树的层序遍历.md | 100 +++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 89d0dda7..341f4ba5 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -98,7 +98,7 @@ class Solution: out_list = [] while quene: - length = len(queue) # 这里一定要先求出队列的长度,不能用range(len(queue)),因为queue长度是变化的 + length = len(queue) in_list = [] for _ in range(length): curnode = queue.pop(0) # (默认移除列表最后一个元素)这里需要移除队列最头上的那个 @@ -627,6 +627,27 @@ public: } }; ``` +python代码: + +```python +class Solution: + def largestValues(self, root: TreeNode) -> List[int]: + if root is None: + return [] + queue = [root] + out_list = [] + while queue: + length = len(queue) + in_list = [] + for _ in range(length): + curnode = queue.pop(0) + in_list.append(curnode.val) + if curnode.left: queue.append(curnode.left) + if curnode.right: queue.append(curnode.right) + out_list.append(max(in_list)) + return out_list +``` + javascript代码: ```javascript @@ -712,6 +733,42 @@ public: }; ``` +python代码: + +```python +# 层序遍历解法 +class Solution: + def connect(self, root: 'Node') -> 'Node': + if not root: + return None + queue = [root] + while queue: + n = len(queue) + for i in range(n): + node = queue.pop(0) + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) + if i == n - 1: + break + node.next = queue[0] + return root + +# 链表解法 +class Solution: + def connect(self, root: 'Node') -> 'Node': + first = root + while first: + cur = first + while cur: # 遍历每一层的节点 + if cur.left: cur.left.next = cur.right # 找左节点的next + if cur.right and cur.next: cur.right.next = cur.next.left # 找右节点的next + cur = cur.next # cur同层移动到下一节点 + first = first.left # 从本层扩展到下一层 + return root +``` + ## 117.填充每个节点的下一个右侧节点指针II 题目地址:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/ @@ -753,7 +810,48 @@ public: } }; ``` +python代码: +```python +# 层序遍历解法 +class Solution: + def connect(self, root: 'Node') -> 'Node': + if not root: + return None + queue = [root] + while queue: # 遍历每一层 + length = len(queue) + tail = None # 每一层维护一个尾节点 + for i in range(length): # 遍历当前层 + curnode = queue.pop(0) + if tail: + tail.next = curnode # 让尾节点指向当前节点 + tail = curnode # 让当前节点成为尾节点 + if curnode.left : queue.append(curnode.left) + if curnode.right: queue.append(curnode.right) + return root + +# 链表解法 +class Solution: + def connect(self, root: 'Node') -> 'Node': + if not root: + return None + first = root + while first: # 遍历每一层 + dummyHead = Node(None) # 为下一行创建一个虚拟头节点,相当于下一行所有节点链表的头结点(每一层都会创建); + tail = dummyHead # 为下一行维护一个尾节点指针(初始化是虚拟节点) + cur = first + while cur: # 遍历当前层的节点 + if cur.left: # 链接下一行的节点 + tail.next = cur.left + tail = tail.next + if cur.right: + tail.next = cur.right + tail = tail.next + cur = cur.next # cur同层移动到下一节点 + first = dummyHead.next # 此处为换行操作,更新到下一行 + return root +``` ## 总结 From d971558d3b7d4ef924eac935451d2bfdfbb6a0dd Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Fri, 18 Jun 2021 22:45:20 +0800 Subject: [PATCH 027/110] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=200222.=E5=AE=8C?= =?UTF-8?q?=E5=85=A8=E4=BA=8C=E5=8F=89=E6=A0=91=E7=9A=84=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E4=B8=AA=E6=95=B0=20go=E7=89=88=20=EF=BC=88=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=88=A9=E7=94=A8=E5=AE=8C=E5=85=A8=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E7=9A=84=E9=80=92=E5=BD=92=E8=A7=A3=E6=B3=95?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增利用完全二叉树特性的递归解法 --- .../0222.完全二叉树的节点个数.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/problems/0222.完全二叉树的节点个数.md b/problems/0222.完全二叉树的节点个数.md index 998e22f3..ec68b6c6 100644 --- a/problems/0222.完全二叉树的节点个数.md +++ b/problems/0222.完全二叉树的节点个数.md @@ -335,6 +335,30 @@ func countNodes(root *TreeNode) int { } ``` +利用完全二叉树特性的递归解法 +```go +func countNodes(root *TreeNode) int { + if root == nil { + return 0 + } + leftH, rightH := 0, 0 + leftNode := root.Left + rightNode := root.Right + for leftNode != nil { + leftNode = leftNode.Left + leftH++ + } + for rightNode != nil { + rightNode = rightNode.Right + rightH++ + } + if leftH == rightH { + return (2 << leftH) - 1 + } + return countNodes(root.Left) + countNodes(root.Right) + 1 +} +``` + JavaScript: From 4a33ef6a04bb13ace9ab8a7551fd783815a4e0f9 Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Sat, 19 Jun 2021 11:33:02 +0800 Subject: [PATCH 028/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200669.=E4=BF=AE?= =?UTF-8?q?=E5=89=AA=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=20Golang?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0669.修剪二叉搜索树 Golang版本 --- problems/0669.修剪二叉搜索树.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/problems/0669.修剪二叉搜索树.md b/problems/0669.修剪二叉搜索树.md index 06d99b9d..2a88f195 100644 --- a/problems/0669.修剪二叉搜索树.md +++ b/problems/0669.修剪二叉搜索树.md @@ -286,7 +286,33 @@ class Solution: return root ``` Go: +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func trimBST(root *TreeNode, low int, high int) *TreeNode { + if root==nil{ + return nil + } + if root.Valhigh{//如果该节点的值大于最大值,则该节点更换为该节点的左节点值,继续遍历 + left:=trimBST(root.Left,low,high) + return left + } + root.Left=trimBST(root.Left,low,high) + root.Right=trimBST(root.Right,low,high) + return root +} +``` From 9d92c13420c5cd078ab2ba16e5cf39aa16252c21 Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Sat, 19 Jun 2021 14:05:20 +0800 Subject: [PATCH 029/110] =?UTF-8?q?0714.=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=BA=E5=90=AB?= =?UTF-8?q?=E6=89=8B=E7=BB=AD=E8=B4=B9.md=20Javascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...买卖股票的最佳时机含手续费.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/problems/0714.买卖股票的最佳时机含手续费.md b/problems/0714.买卖股票的最佳时机含手续费.md index abd20625..2e8f9208 100644 --- a/problems/0714.买卖股票的最佳时机含手续费.md +++ b/problems/0714.买卖股票的最佳时机含手续费.md @@ -217,7 +217,29 @@ class Solution: # 贪心思路 Go: +Javascript: +```Javascript +// 贪心思路 +var maxProfit = function(prices, fee) { + let result = 0 + let minPrice = prices[0] + for(let i = 1; i < prices.length; i++) { + if(prices[i] < minPrice) { + minPrice = prices[i] + } + if(prices[i] >= minPrice && prices[i] <= minPrice + fee) { + continue + } + if(prices[i] > minPrice + fee) { + result += prices[i] - minPrice - fee + // 买入和卖出只需要支付一次手续费 + minPrice = prices[i] -fee + } + } + return result +}; +``` ----------------------- From ed14cefdb171abdf7a6b295d912617889910c746 Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Sat, 19 Jun 2021 15:32:30 +0800 Subject: [PATCH 030/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200108.=E5=B0=86?= =?UTF-8?q?=E6=9C=89=E5=BA=8F=E6=95=B0=E7=BB=84=E8=BD=AC=E6=8D=A2=E4=B8=BA?= =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=20Golang=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0108.将有序数组转换为二叉搜索树 Golang版本 --- ...将有序数组转换为二叉搜索树.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/0108.将有序数组转换为二叉搜索树.md b/problems/0108.将有序数组转换为二叉搜索树.md index 2692be47..35b8bb2e 100644 --- a/problems/0108.将有序数组转换为二叉搜索树.md +++ b/problems/0108.将有序数组转换为二叉搜索树.md @@ -258,6 +258,29 @@ class Solution: Go: +> 递归(隐含回溯) + +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ + //递归(隐含回溯) +func sortedArrayToBST(nums []int) *TreeNode { + if len(nums)==0{return nil}//终止条件,最后数组为空则可以返回 + root:=&TreeNode{nums[len(nums)/2],nil,nil}//按照BSL的特点,从中间构造节点 + root.Left=sortedArrayToBST(nums[:len(nums)/2])//数组的左边为左子树 + root.Right=sortedArrayToBST(nums[len(nums)/2+1:])//数字的右边为右子树 + return root +} +``` + + + ----------------------- From d2e05f9b047bfd92faab571fa8276a776ce34b2f Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Sat, 19 Jun 2021 16:30:36 +0800 Subject: [PATCH 031/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200538.=E6=8A=8A?= =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E8=BD=AC=E6=8D=A2?= =?UTF-8?q?=E4=B8=BA=E7=B4=AF=E5=8A=A0=E6=A0=91=20Golang=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0538.把二叉搜索树转换为累加树 Golang版本 --- ...38.把二叉搜索树转换为累加树.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0538.把二叉搜索树转换为累加树.md b/problems/0538.把二叉搜索树转换为累加树.md index 765e78d3..06a53ce7 100644 --- a/problems/0538.把二叉搜索树转换为累加树.md +++ b/problems/0538.把二叉搜索树转换为累加树.md @@ -219,6 +219,26 @@ class Solution: Go: +> 弄一个sum暂存其和值 + +```go + //右中左 +func bstToGst(root *TreeNode) *TreeNode { + var sum int + RightMLeft(root,&sum) + return root +} +func RightMLeft(root *TreeNode,sum *int) *TreeNode { + if root==nil{return nil}//终止条件,遇到空节点就返回 + RightMLeft(root.Right,sum)//先遍历右边 + temp:=*sum//暂存总和值 + *sum+=root.Val//将总和值变更 + root.Val+=temp//更新节点值 + RightMLeft(root.Left,sum)//遍历左节点 + return root +} +``` + ----------------------- From 2e8ba2bbb8e27132129d83c64795ba8feaed39d2 Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Sat, 19 Jun 2021 20:25:29 +0800 Subject: [PATCH 032/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200216.=E7=BB=84?= =?UTF-8?q?=E5=90=88=E6=80=BB=E5=92=8CIII=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0216.组合总和III go版本 --- problems/0216.组合总和III.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md index 9f75b23d..67e67ad0 100644 --- a/problems/0216.组合总和III.md +++ b/problems/0216.组合总和III.md @@ -284,6 +284,37 @@ class Solution: Go: + +> 回溯+减枝 + +```go +func combinationSum3(k int, n int) [][]int { + var track []int// 遍历路径 + var result [][]int// 存放结果集 + backTree(n,k,1,&track,&result) + return result +} +func backTree(n,k,startIndex int,track *[]int,result *[][]int){ + if len(*track)==k{ + var sum int + tmp:=make([]int,k) + for k,v:=range *track{ + sum+=v + tmp[k]=v + } + if sum==n{ + *result=append(*result,tmp) + } + return + } + for i:=startIndex;i<=9-(k-len(*track))+1;i++{//减枝(k-len(*track)表示还剩多少个可填充的元素) + *track=append(*track,i)//记录路径 + backTree(n,k,i+1,track,result)//递归 + *track=(*track)[:len(*track)-1]//回溯 + } +} +``` + javaScript: ```js From d73ef9071538e4f8660d1aa8d62fe815304cf8bf Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Sat, 19 Jun 2021 21:35:01 +0800 Subject: [PATCH 033/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200017.=E7=94=B5?= =?UTF-8?q?=E8=AF=9D=E5=8F=B7=E7=A0=81=E7=9A=84=E5=AD=97=E6=AF=8D=E7=BB=84?= =?UTF-8?q?=E5=90=88=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0017.电话号码的字母组合 go版本 --- problems/0017.电话号码的字母组合.md | 40 ++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/problems/0017.电话号码的字母组合.md b/problems/0017.电话号码的字母组合.md index aefee698..1562052c 100644 --- a/problems/0017.电话号码的字母组合.md +++ b/problems/0017.电话号码的字母组合.md @@ -342,6 +342,46 @@ class Solution: Go: + +> 主要在于递归中传递下一个数字 + +```go +func letterCombinations(digits string) []string { + lenth:=len(digits) + if lenth==0 ||lenth>4{ + return nil + } + digitsMap:= [10]string{ + "", // 0 + "", // 1 + "abc", // 2 + "def", // 3 + "ghi", // 4 + "jkl", // 5 + "mno", // 6 + "pqrs", // 7 + "tuv", // 8 + "wxyz", // 9 + } + res:=make([]string,0) + recursion("",digits,0,digitsMap,&res) + return res +} +func recursion(tempString ,digits string, Index int,digitsMap [10]string, res *[]string) {//index表示第几个数字 + if len(tempString)==len(digits){//终止条件,字符串长度等于digits的长度 + *res=append(*res,tempString) + return + } + tmpK:=digits[Index]-'0' // 将index指向的数字转为int(确定下一个数字) + letter:=digitsMap[tmpK]// 取数字对应的字符集 + for i:=0;i Date: Sat, 19 Jun 2021 22:05:48 +0800 Subject: [PATCH 034/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200039.=E7=BB=84?= =?UTF-8?q?=E5=90=88=E6=80=BB=E5=92=8C=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0039.组合总和 go版本 --- problems/0039.组合总和.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/problems/0039.组合总和.md b/problems/0039.组合总和.md index e3e4a117..ba8128b5 100644 --- a/problems/0039.组合总和.md +++ b/problems/0039.组合总和.md @@ -286,6 +286,39 @@ class Solution: ``` Go: + +> 主要在于递归中传递下一个数字 + +```go +func combinationSum(candidates []int, target int) [][]int { + var trcak []int + var res [][]int + backtracking(0,0,target,candidates,trcak,&res) + return res +} +func backtracking(startIndex,sum,target int,candidates,trcak []int,res *[][]int){ + //终止条件 + if sum==target{ + tmp:=make([]int,len(trcak)) + copy(tmp,trcak)//拷贝 + *res=append(*res,tmp)//放入结果集 + return + } + if sum>target{return} + //回溯 + for i:=startIndex;i Date: Sat, 19 Jun 2021 22:16:42 +0800 Subject: [PATCH 035/110] =?UTF-8?q?=E6=9C=80=E5=A4=A7=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=A0=91JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0654.最大二叉树.md | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/problems/0654.最大二叉树.md b/problems/0654.最大二叉树.md index f0d3e594..4e1e7a72 100644 --- a/problems/0654.最大二叉树.md +++ b/problems/0654.最大二叉树.md @@ -311,6 +311,42 @@ func findMax(nums []int) (index int){ } ``` +JavaScript版本 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {number[]} nums + * @return {TreeNode} + */ +var constructMaximumBinaryTree = function (nums) { + const BuildTree = (arr, left, right) => { + if (left > right) + return null; + let maxValue = -1; + let maxIndex = -1; + for (let i = left; i <= right; ++i) { + if (arr[i] > maxValue) { + maxValue = arr[i]; + maxIndex = i; + } + } + let root = new TreeNode(maxValue); + root.left = BuildTree(arr, left, maxIndex - 1); + root.right = BuildTree(arr, maxIndex + 1, right); + return root; + } + let root = BuildTree(nums, 0, nums.length - 1); + return root; +}; +``` From 26f3ee6c93c7ed53a3d98ba1f92fbc8d295dfcb8 Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Sat, 19 Jun 2021 23:23:34 +0800 Subject: [PATCH 036/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200040.=E7=BB=84?= =?UTF-8?q?=E5=90=88=E6=80=BB=E5=92=8CII=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0040.组合总和II go版本 --- problems/0040.组合总和II.md | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/problems/0040.组合总和II.md b/problems/0040.组合总和II.md index a462b524..021bba94 100644 --- a/problems/0040.组合总和II.md +++ b/problems/0040.组合总和II.md @@ -314,6 +314,48 @@ class Solution: ``` Go: + +> 主要在于如何在回溯中去重 + +```go +func combinationSum2(candidates []int, target int) [][]int { + var trcak []int + var res [][]int + var history map[int]bool + history=make(map[int]bool) + sort.Ints(candidates) + backtracking(0,0,target,candidates,trcak,&res,history) + return res +} +func backtracking(startIndex,sum,target int,candidates,trcak []int,res *[][]int,history map[int]bool){ + //终止条件 + if sum==target{ + tmp:=make([]int,len(trcak)) + copy(tmp,trcak)//拷贝 + *res=append(*res,tmp)//放入结果集 + return + } + if sum>target{return} + //回溯 + // used[i - 1] == true,说明同一树支candidates[i - 1]使用过 + // used[i - 1] == false,说明同一树层candidates[i - 1]使用过 + for i:=startIndex;i0&&candidates[i]==candidates[i-1]&&history[i-1]==false{ + continue + } + //更新路径集合和sum + trcak=append(trcak,candidates[i]) + sum+=candidates[i] + history[i]=true + //递归 + backtracking(i+1,sum,target,candidates,trcak,res,history) + //回溯 + trcak=trcak[:len(trcak)-1] + sum-=candidates[i] + history[i]=false + } +} +``` javaScript: ```js From a85e41093b1b94a2aa63109459fdcb0647a813b2 Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Sun, 20 Jun 2021 00:45:47 +0800 Subject: [PATCH 037/110] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=200257.=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91=E7=9A=84=E6=89=80=E6=9C=89=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=20go=20=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0257.二叉树的所有路径.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/0257.二叉树的所有路径.md b/problems/0257.二叉树的所有路径.md index fe7a2604..d5a0478e 100644 --- a/problems/0257.二叉树的所有路径.md +++ b/problems/0257.二叉树的所有路径.md @@ -350,6 +350,29 @@ class Solution: ``` Go: + +```go +func binaryTreePaths(root *TreeNode) []string { + res := make([]string, 0) + var travel func(node *TreeNode, s string) + travel = func(node *TreeNode, s string) { + if node.Left == nil && node.Right == nil { + v := s + strconv.Itoa(node.Val) + res = append(res, v) + return + } + s = s + strconv.Itoa(node.Val) + "->" + if node.Left != nil { + travel(node.Left, s) + } + if node.Right != nil { + travel(node.Right, s) + } + } + travel(root, "") + return res +} +``` JavaScript: 1.递归版本 From 7d2a897577ff9fefedc377c8e0f1c421c1b879d1 Mon Sep 17 00:00:00 2001 From: haofeng <852172305@qq.com> Date: Sun, 20 Jun 2021 12:02:07 +0800 Subject: [PATCH 038/110] =?UTF-8?q?Update=200337.=E6=89=93=E5=AE=B6?= =?UTF-8?q?=E5=8A=AB=E8=88=8DIII.md=20=E6=B7=BB=E5=8A=A0=20python3=20?= =?UTF-8?q?=E6=9A=B4=E5=8A=9B=E9=80=92=E5=BD=92=EF=BC=8C=E8=AE=B0=E5=BF=86?= =?UTF-8?q?=E5=8C=96=E9=80=92=E5=BD=92=E4=BB=A3=E7=A0=81=EF=BC=8C=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0337.打家劫舍III.md | 89 +++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/problems/0337.打家劫舍III.md b/problems/0337.打家劫舍III.md index 0a4b752b..3504a574 100644 --- a/problems/0337.打家劫舍III.md +++ b/problems/0337.打家劫舍III.md @@ -287,24 +287,85 @@ class Solution { Python: -> 动态规划 -```python +> 暴力递归 + +```python3 + +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right class Solution: def rob(self, root: TreeNode) -> int: - result = self.robTree(root) + if root is None: + return 0 + if root.left is None and root.right is None: + return root.val + # 偷父节点 + val1 = root.val + if root.left: + val1 += self.rob(root.left.left) + self.rob(root.left.right) + if root.right: + val1 += self.rob(root.right.left) + self.rob(root.right.right) + # 不偷父节点 + val2 = self.rob(root.left) + self.rob(root.right) + return max(val1, val2) +``` + +> 记忆化递归 + +```python3 + +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + memory = {} + def rob(self, root: TreeNode) -> int: + if root is None: + return 0 + if root.left is None and root.right is None: + return root.val + if self.memory.get(root) is not None: + return self.memory[root] + # 偷父节点 + val1 = root.val + if root.left: + val1 += self.rob(root.left.left) + self.rob(root.left.right) + if root.right: + val1 += self.rob(root.right.left) + self.rob(root.right.right) + # 不偷父节点 + val2 = self.rob(root.left) + self.rob(root.right) + self.memory[root] = max(val1, val2) + return max(val1, val2) +``` + +> 动态规划 +```python3 +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def rob(self, root: TreeNode) -> int: + result = self.rob_tree(root) return max(result[0], result[1]) - #长度为2的数组,0:不偷,1:偷 - def robTree(self, cur): - if not cur: - return (0, 0) #这里返回tuple, 也可以返回list - left = self.robTree(cur.left) - right = self.robTree(cur.right) - #偷cur - val1 = cur.val + left[0] + right[0] - #不偷cur - val2 = max(left[0], left[1]) + max(right[0], right[1]) - return (val2, val1) + def rob_tree(self, node): + if node is None: + return (0, 0) # (偷当前节点金额,不偷当前节点金额) + left = self.rob_tree(node.left) + right = self.rob_tree(node.right) + val1 = node.val + left[1] + right[1] # 偷当前节点,不能偷子节点 + val2 = max(left[0], left[1]) + max(right[0], right[1]) # 不偷当前节点,可偷可不偷子节点 + return (val1, val2) ``` Go: From c430004a0b8b91419e43bb648b0b2c3b5a8b5db2 Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Sun, 20 Jun 2021 14:47:48 +0800 Subject: [PATCH 039/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200131.=E5=88=86?= =?UTF-8?q?=E5=89=B2=E5=9B=9E=E6=96=87=E4=B8=B2=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0131.分割回文串 go版本 --- problems/0131.分割回文串.md | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md index 9d23fd13..43453409 100644 --- a/problems/0131.分割回文串.md +++ b/problems/0131.分割回文串.md @@ -312,6 +312,50 @@ class Solution: ``` Go: +> 注意切片(go切片是披着值类型外衣的引用类型) + +```go +func partition(s string) [][]string { + var tmpString []string//切割字符串集合 + var res [][]string//结果集合 + backTracking(s,tmpString,0,&res) + return res +} +func backTracking(s string,tmpString []string,startIndex int,res *[][]string){ + if startIndex==len(s){//到达字符串末尾了 + //进行一次切片拷贝,怕之后的操作影响tmpString切片内的值 + t := make([]string, len(tmpString)) + copy(t, tmpString) + *res=append(*res,t) + } + for i:=startIndex;i Date: Sun, 20 Jun 2021 16:39:35 +0800 Subject: [PATCH 040/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200093.=E5=A4=8D?= =?UTF-8?q?=E5=8E=9FIP=E5=9C=B0=E5=9D=80=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0093.复原IP地址 go版本 --- problems/0093.复原IP地址.md | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/problems/0093.复原IP地址.md b/problems/0093.复原IP地址.md index a8b9a215..1c8e4069 100644 --- a/problems/0093.复原IP地址.md +++ b/problems/0093.复原IP地址.md @@ -367,6 +367,47 @@ var restoreIpAddresses = function(s) { } }; ``` +Go: +> 回溯(对于前导 0的IP(特别注意s[startIndex]=='0'的判断,不应该写成s[startIndex]==0,因为s截取出来不是数字)) + +```go +func restoreIpAddresses(s string) []string { + var res,path []string + backTracking(s,path,0,&res) + return res +} +func backTracking(s string,path []string,startIndex int,res *[]string){ + //终止条件 + if startIndex==len(s)&&len(path)==4{ + tmpIpString:=path[0]+"."+path[1]+"."+path[2]+"."+path[3] + *res=append(*res,tmpIpString) + } + for i:=startIndex;i1&&s[startIndex]=='0'{//对于前导 0的IP(特别注意s[startIndex]=='0'的判断,不应该写成s[startIndex]==0,因为s截取出来不是数字) + return false + } + if checkInt>255{ + return false + } + return true +} + +``` + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From aa87376071b0f66897c18f74509a9c899c8ce858 Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Mon, 21 Jun 2021 10:12:10 +0800 Subject: [PATCH 041/110] Update --- README.md | 4 ++ problems/0051.N皇后.md | 8 --- problems/0151.翻转字符串里的单词.md | 63 +++++++------------ problems/0160.相交链表.md | 2 + problems/剑指Offer05.替换空格.md | 32 ++++------ .../剑指Offer58-II.左旋转字符串.md | 35 +++++------ problems/栈与队列理论基础.md | 15 +---- 7 files changed, 60 insertions(+), 99 deletions(-) create mode 100644 problems/0160.相交链表.md diff --git a/README.md b/README.md index daef7c02..b9ee3a9e 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,10 @@ 4. [马上秋招了,慌得很!](https://mp.weixin.qq.com/s/7q7W8Cb2-a5U5atZdOnOFA) 5. [Carl看了上百份简历,总结了这些!](https://mp.weixin.qq.com/s/sJa87MZD28piCOVMFkIbwQ) 6. [面试中遇到了发散性问题.....](https://mp.weixin.qq.com/s/SSonDxi2pjkSVwHNzZswng) +7. [英语到底重不重要!](https://mp.weixin.qq.com/s/1PRZiyF_-TVA-ipwDNjdKw) +8. [计算机专业要不要读研!](https://mp.weixin.qq.com/s/c9v1L3IjqiXtkNH7sOMAdg) +9. [秋招和提前批都越来越提前了....](https://mp.weixin.qq.com/s/SNFiRDx8CKyjhTPlys6ywQ) + ## 数组 diff --git a/problems/0051.N皇后.md b/problems/0051.N皇后.md index 5242fce2..fd2c7d0f 100644 --- a/problems/0051.N皇后.md +++ b/problems/0051.N皇后.md @@ -353,14 +353,6 @@ class Solution { } ``` -## 其他语言版本 - - -Java: - - -Python: - Go: ```Go diff --git a/problems/0151.翻转字符串里的单词.md b/problems/0151.翻转字符串里的单词.md index d76734e4..e092a717 100644 --- a/problems/0151.翻转字符串里的单词.md +++ b/problems/0151.翻转字符串里的单词.md @@ -16,19 +16,19 @@ https://leetcode-cn.com/problems/reverse-words-in-a-string/ 给定一个字符串,逐个翻转字符串中的每个单词。 -示例 1: -输入: "the sky is blue" -输出: "blue is sky the" +示例 1: +输入: "the sky is blue" +输出: "blue is sky the" -示例 2: -输入: "  hello world!  " -输出: "world! hello" -解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。 +示例 2: +输入: "  hello world!  " +输出: "world! hello" +解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。 -示例 3: -输入: "a good   example" -输出: "example good a" -解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。 +示例 3: +输入: "a good   example" +输出: "example good a" +解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。 # 思路 @@ -50,12 +50,15 @@ https://leetcode-cn.com/problems/reverse-words-in-a-string/ * 将整个字符串反转 * 将每个单词反转 -如动画所示: +举个例子,源字符串为:"the sky is blue " -![151翻转字符串里的单词](https://tva1.sinaimg.cn/large/008eGmZEly1gp0kv5gl4mg30gy0c4nbp.gif) +* 移除多余空格 : "the sky is blue" +* 字符串反转:"eulb si yks eht" +* 单词反转:"blue is sky the" 这样我们就完成了翻转字符串里的单词。 + 思路很明确了,我们说一说代码的实现细节,就拿移除多余空格来说,一些同学会上来写如下代码: ```C++ @@ -80,13 +83,13 @@ void removeExtraSpaces(string& s) { 如果不仔细琢磨一下erase的时间复杂读,还以为以上的代码是O(n)的时间复杂度呢。 -想一下真正的时间复杂度是多少,一个erase本来就是O(n)的操作,erase实现原理题目:[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA),最优的算法来移除元素也要O(n)。 +想一下真正的时间复杂度是多少,一个erase本来就是O(n)的操作,erase实现原理题目:[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/RMkulE4NIb6XsSX83ra-Ww),最优的算法来移除元素也要O(n)。 erase操作上面还套了一个for循环,那么以上代码移除冗余空格的代码时间复杂度为O(n^2)。 那么使用双指针法来去移除空格,最后resize(重新设置)一下字符串的大小,就可以做到O(n)的时间复杂度。 -如果对这个操作比较生疏了,可以再看一下这篇文章:[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA)是如何移除元素的。 +如果对这个操作比较生疏了,可以再看一下这篇文章:[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/RMkulE4NIb6XsSX83ra-Ww)是如何移除元素的。 那么使用双指针来移除冗余空格代码如下: fastIndex走的快,slowIndex走的慢,最后slowIndex就标记着移除多余空格后新字符串的长度。 @@ -122,7 +125,7 @@ void removeExtraSpaces(string& s) { 此时我们已经实现了removeExtraSpaces函数来移除冗余空格。 -还做实现反转字符串的功能,支持反转字符串子区间,这个实现我们分别在[字符串:这道题目,使用库函数一行代码搞定](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA)和[字符串:简单的反转还不够!](https://mp.weixin.qq.com/s/XGSk1GyPWhfqj2g7Cb1Vgw)里已经讲过了。 +还做实现反转字符串的功能,支持反转字符串子区间,这个实现我们分别在[344.反转字符串](https://mp.weixin.qq.com/s/_rNm66OJVl92gBDIbGpA3w)和[541.反转字符串II](https://mp.weixin.qq.com/s/pzXt6PQ029y7bJ9YZB2mVQ)里已经讲过了。 代码如下: @@ -135,11 +138,8 @@ void reverse(string& s, int start, int end) { } ``` -## 本题C++整体代码 +本题C++整体代码 -效率: - - ```C++ // 版本一 @@ -203,6 +203,7 @@ public: return s; } + // 当然这里的主函数reverseWords写的有一些冗余的,可以精简一些,精简之后的主函数为: /* 主函数简单写法 string reverseWords(string s) { removeExtraSpaces(s); @@ -220,25 +221,8 @@ public: }; ``` -当然这里的主函数reverseWords写的有一些冗余的,可以精简一些,精简之后的主函数为: - -```C++ -// 注意这里仅仅是主函数,其他函数和版本一一致 -string reverseWords(string s) { - removeExtraSpaces(s); - reverse(s, 0, s.size() - 1); - for(int i = 0; i < s.size(); i++) { - int j = i; - // 查找单词间的空格,翻转单词 - while(j < s.size() && s[j] != ' ') j++; - reverse(s, i, j - 1); - i = j; - } - return s; -} -``` - - +效率: + @@ -316,7 +300,6 @@ class Solution { } ``` -Python: Go: diff --git a/problems/0160.相交链表.md b/problems/0160.相交链表.md new file mode 100644 index 00000000..d26f66fd --- /dev/null +++ b/problems/0160.相交链表.md @@ -0,0 +1,2 @@ + +同:[链表:链表相交](./面试题02.07.链表相交.md) diff --git a/problems/剑指Offer05.替换空格.md b/problems/剑指Offer05.替换空格.md index a4c0149f..f68d8e22 100644 --- a/problems/剑指Offer05.替换空格.md +++ b/problems/剑指Offer05.替换空格.md @@ -13,9 +13,9 @@ https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/ 请实现一个函数,把字符串 s 中的每个空格替换成"%20"。 -示例 1: -输入:s = "We are happy." -输出:"We%20are%20happy." +示例 1: +输入:s = "We are happy." +输出:"We%20are%20happy." # 思路 @@ -42,9 +42,9 @@ i指向新长度的末尾,j指向旧长度的末尾。 时间复杂度,空间复杂度均超过100%的用户。 - + -## C++代码 +C++代码如下: ```C++ class Solution { @@ -76,17 +76,17 @@ public: }; ``` -时间复杂度:O(n) -空间复杂度:O(1) +* 时间复杂度:O(n) +* 空间复杂度:O(1) 此时算上本题,我们已经做了七道双指针相关的题目了分别是: -* [27.移除元素](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA) -* [15.三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A) -* [18.四数之和](https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g) -* [206.翻转链表](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg) -* [142.环形链表II](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA) -* [344.反转字符串](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA) +* [27.移除元素](https://mp.weixin.qq.com/s/RMkulE4NIb6XsSX83ra-Ww) +* [15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg) +* [18.四数之和](https://mp.weixin.qq.com/s/SBU3THi1Kv6Sar7htqCB2Q) +* [206.翻转链表](https://mp.weixin.qq.com/s/ckEvIVGcNLfrz6OLOMoT0A) +* [142.环形链表II](https://mp.weixin.qq.com/s/gt_VH3hQTqNxyWcl1ECSbQ) +* [344.反转字符串](https://mp.weixin.qq.com/s/_rNm66OJVl92gBDIbGpA3w) # 拓展 @@ -121,10 +121,6 @@ for (int i = 0; i < a.size(); i++) { 所以想处理字符串,我们还是会定义一个string类型。 - - - - ## 其他语言版本 @@ -150,8 +146,6 @@ public static String replaceSpace(StringBuffer str) { } ``` -Python: - Go: ```go diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md index 39c8382c..70c6f015 100644 --- a/problems/剑指Offer58-II.左旋转字符串.md +++ b/problems/剑指Offer58-II.左旋转字符串.md @@ -16,16 +16,16 @@ https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/ 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。 -示例 1: -输入: s = "abcdefg", k = 2 -输出: "cdefgab" +示例 1: +输入: s = "abcdefg", k = 2 +输出: "cdefgab" -示例 2: -输入: s = "lrloseumgh", k = 6 -输出: "umghlrlose" +示例 2: +输入: s = "lrloseumgh", k = 6 +输出: "umghlrlose" -限制: -1 <= k < s.length <= 10000 +限制: +1 <= k < s.length <= 10000 # 思路 @@ -34,7 +34,7 @@ https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/ 不能使用额外空间的话,模拟在本串操作要实现左旋转字符串的功能还是有点困难的。 -那么我们可以想一下上一题目[字符串:花式反转还不够!](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw)中讲过,使用整体反转+局部反转就可以实现,反转单词顺序的目的。 +那么我们可以想一下上一题目[字符串:花式反转还不够!](https://mp.weixin.qq.com/s/4j6vPFHkFAXnQhmSkq2X9g)中讲过,使用整体反转+局部反转就可以实现,反转单词顺序的目的。 这道题目也非常类似,依然可以通过局部反转+整体反转 达到左旋转的目的。 @@ -50,13 +50,13 @@ https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/ 如图: - + 最终得到左旋2个单元的字符串:cdefgab 思路明确之后,那么代码实现就很简单了 -# C++代码 +C++代码如下: ```C++ class Solution { @@ -73,15 +73,16 @@ public: # 总结 + 此时我们已经反转好多次字符串了,来一起回顾一下吧。 -在这篇文章[字符串:这道题目,使用库函数一行代码搞定](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA),第一次讲到反转一个字符串应该怎么做,使用了双指针法。 +在这篇文章[344.反转字符串](https://mp.weixin.qq.com/s/_rNm66OJVl92gBDIbGpA3w),第一次讲到反转一个字符串应该怎么做,使用了双指针法。 -然后发现[字符串:简单的反转还不够!](https://mp.weixin.qq.com/s/XGSk1GyPWhfqj2g7Cb1Vgw),这里开始给反转加上了一些条件,当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。 +然后发现[541. 反转字符串II](https://mp.weixin.qq.com/s/pzXt6PQ029y7bJ9YZB2mVQ),这里开始给反转加上了一些条件,当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。 -后来在[字符串:花式反转还不够!](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw)中,要对一句话里的单词顺序进行反转,发现先整体反转再局部反转 是一个很妙的思路。 +后来在[151.翻转字符串里的单词](https://mp.weixin.qq.com/s/4j6vPFHkFAXnQhmSkq2X9g)中,要对一句话里的单词顺序进行反转,发现先整体反转再局部反转 是一个很妙的思路。 -最后再讲到本地,本题则是先局部反转再 整体反转,与[字符串:花式反转还不够!](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw)类似,但是也是一种新的思路。 +最后再讲到本题,本题则是先局部反转再 整体反转,与[151.翻转字符串里的单词](https://mp.weixin.qq.com/s/4j6vPFHkFAXnQhmSkq2X9g)类似,但是也是一种新的思路。 好了,反转字符串一共就介绍到这里,相信大家此时对反转字符串的常见操作已经很了解了。 @@ -93,7 +94,6 @@ public: **如果想让这套题目有意义,就不要申请额外空间。** - ## 其他语言版本 Java: @@ -117,7 +117,6 @@ class Solution { } } ``` -Python: Go: @@ -151,4 +150,4 @@ func reverse(b []byte, left, right int){ * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) -
\ No newline at end of file +
diff --git a/problems/栈与队列理论基础.md b/problems/栈与队列理论基础.md index 04f99981..db871a3c 100644 --- a/problems/栈与队列理论基础.md +++ b/problems/栈与队列理论基础.md @@ -85,20 +85,7 @@ std::queue> third; // 定义以list为底层容器的队列 所以STL 队列也不被归类为容器,而被归类为container adapter( 容器适配器)。 -我这里讲的都是(clck)C++ 语言中情况, 使用其他语言的同学也要思考栈与队列的底层实现问题, 不要对数据结构的使用浅尝辄止,而要深挖起内部原理,才能夯实基础。 - - - -## 其他语言版本 - - -Java: - - -Python: - - -Go: +我这里讲的都是C++ 语言中情况, 使用其他语言的同学也要思考栈与队列的底层实现问题, 不要对数据结构的使用浅尝辄止,而要深挖起内部原理,才能夯实基础。 From 8496fe91463af3f016ed41d6eb7c072859f5b9ab Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Mon, 21 Jun 2021 10:48:55 +0800 Subject: [PATCH 042/110] =?UTF-8?q?0968.=E7=9B=91=E6=8E=A7=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91.md=20Javascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0968.监控二叉树.md | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/problems/0968.监控二叉树.md b/problems/0968.监控二叉树.md index 8f1a3fdb..a0eb5883 100644 --- a/problems/0968.监控二叉树.md +++ b/problems/0968.监控二叉树.md @@ -369,7 +369,42 @@ class Solution: ``` Go: +Javascript: +```Javascript +var minCameraCover = function(root) { + let result = 0 + function traversal(cur) { + if(cur === null) { + return 2 + } + let left = traversal(cur.left) + let right = traversal(cur.right) + + if(left === 2 && right === 2) { + return 0 + } + + if(left === 0 || right === 0) { + result++ + return 1 + } + + if(left === 1 || right === 1) { + return 2 + } + + return -1 + } + + if(traversal(root) === 0) { + result++ + } + + return result + +}; +``` ----------------------- From b19dc143561ce730f58917ea54c9f3293a533ce4 Mon Sep 17 00:00:00 2001 From: ORain <58782338+ORainn@users.noreply.github.com> Date: Mon, 21 Jun 2021 10:49:31 +0800 Subject: [PATCH 043/110] =?UTF-8?q?java=E8=AF=AD=E8=A8=80=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/0392.判断子序列.md | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/problems/0392.判断子序列.md b/problems/0392.判断子序列.md index 9048ac44..d97d2684 100644 --- a/problems/0392.判断子序列.md +++ b/problems/0392.判断子序列.md @@ -140,8 +140,29 @@ public: ## 其他语言版本 -Java: - +Java: +``` +class Solution { + public boolean isSubsequence(String s, String t) { + int length1 = s.length(); int length2 = t.length(); + int[][] dp = new int[length1+1][length2+1]; + for(int i = 1; i <= length1; i++){ + for(int j = 1; j <= length2; j++){ + if(s.charAt(i-1) == t.charAt(j-1)){ + dp[i][j] = dp[i-1][j-1] + 1; + }else{ + dp[i][j] = dp[i][j-1]; + } + } + } + if(dp[length1][length2] == length1){ + return true; + }else{ + return false; + } + } +} +``` Python: ```python From fa601e179aab6b17b31a9a88d2af0cf62fe1464e Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Mon, 21 Jun 2021 15:46:42 +0800 Subject: [PATCH 044/110] =?UTF-8?q?JavaScript=E7=89=88=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BA=8C=E5=8F=89=E6=A0=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0617.合并二叉树.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/problems/0617.合并二叉树.md b/problems/0617.合并二叉树.md index be6bb425..2ff093a3 100644 --- a/problems/0617.合并二叉树.md +++ b/problems/0617.合并二叉树.md @@ -370,6 +370,36 @@ func mergeTrees(t1 *TreeNode, t2 *TreeNode) *TreeNode { } ``` +JavaScript: + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root1 + * @param {TreeNode} root2 + * @return {TreeNode} + */ +var mergeTrees = function (root1, root2) { + const preOrder = (root1, root2) => { + if (!root1) + return root2 + if (!root2) + return root1; + root1.val += root2.val; + root1.left = preOrder(root1.left, root2.left); + root1.right = preOrder(root1.right, root2.right); + return root1; + } + return preOrder(root1, root2); +}; +``` ----------------------- From 75ef824eb6025cf9555ecdea0fa653f0ec88b7cb Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Mon, 21 Jun 2021 15:49:05 +0800 Subject: [PATCH 045/110] =?UTF-8?q?JavaScript=E7=89=88=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E3=80=8A=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E6=90=9C=E7=B4=A2=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0700.二叉搜索树中的搜索.md | 57 ++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/problems/0700.二叉搜索树中的搜索.md b/problems/0700.二叉搜索树中的搜索.md index 16b21f26..d6899ac5 100644 --- a/problems/0700.二叉搜索树中的搜索.md +++ b/problems/0700.二叉搜索树中的搜索.md @@ -290,7 +290,64 @@ func searchBST(root *TreeNode, val int) *TreeNode { } ``` +JavaScript版本 +> 递归 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} val + * @return {TreeNode} + */ +var searchBST = function (root, val) { + if (!root || root.val === val) { + return root; + } + if (root.val > val) + return searchBST(root.left, val); + if (root.val < val) + return searchBST(root.right, val); + return null; +}; +``` + +> 迭代 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} val + * @return {TreeNode} + */ +var searchBST = function (root, val) { + while (root !== null) { + if (root.val > val) + root = root.left; + else if (root.val < val) + root = root.right; + else + return root; + } + return root; +}; +``` From 19b7541a7ec06e19638ed680c96cc99beea57f18 Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Mon, 21 Jun 2021 15:51:11 +0800 Subject: [PATCH 046/110] =?UTF-8?q?JavaScript=E7=89=88=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E3=80=8A=E9=AA=8C=E8=AF=81=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E6=A0=91=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0098.验证二叉搜索树.md | 69 ++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/problems/0098.验证二叉搜索树.md b/problems/0098.验证二叉搜索树.md index eb877abb..e38c5ade 100644 --- a/problems/0098.验证二叉搜索树.md +++ b/problems/0098.验证二叉搜索树.md @@ -377,6 +377,75 @@ func isBST(root *TreeNode, min, max int) bool { } ``` +JavaScript版本 + +> 辅助数组解决 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {boolean} + */ +var isValidBST = function (root) { + let arr = []; + const buildArr = (root) => { + if (root) { + buildArr(root.left); + arr.push(root.val); + buildArr(root.right); + } + } + buildArr(root); + for (let i = 1; i < arr.length; ++i) { + if (arr[i] <= arr[i - 1]) + return false; + } + return true; +}; +``` + +> 递归中解决 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {boolean} + */ +let pre = null; +var isValidBST = function (root) { + let pre = null; + const inOrder = (root) => { + if (root === null) + return true; + let left = inOrder(root.left); + + if (pre !== null && pre.val >= root.val) + return false; + pre = root; + + let right = inOrder(root.right); + return left && right; + } + return inOrder(root); +}; +``` + ----------------------- From 7d3b01b3b06bf5b898225478c245304a628f1cfb Mon Sep 17 00:00:00 2001 From: Yan Wen Date: Mon, 21 Jun 2021 17:07:27 +0800 Subject: [PATCH 047/110] =?UTF-8?q?update=E5=8F=8D=E8=BD=AC=E9=93=BE?= =?UTF-8?q?=E8=A1=A8=EF=BC=9A=E6=B7=BB=E5=8A=A0python=E9=80=92=E5=BD=92?= =?UTF-8?q?=E6=B3=95=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0206.翻转链表.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/problems/0206.翻转链表.md b/problems/0206.翻转链表.md index 7c002382..963d7916 100644 --- a/problems/0206.翻转链表.md +++ b/problems/0206.翻转链表.md @@ -142,7 +142,7 @@ class Solution { } ``` -Python: +Python迭代法: ```python #双指针 # Definition for singly-linked list. @@ -163,6 +163,32 @@ class Solution: return pre ``` +Python递归法: + +```python +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def reverseList(self, head: ListNode) -> ListNode: + + def reverse(pre,cur): + if not cur: + return pre + + tmp = cur.next + cur.next = pre + + return reverse(cur,tmp) + + return reverse(None,head) + +``` + + + Go: ```go From 8969d0fd654da6881238e59aafee6f7613ad2811 Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Mon, 21 Jun 2021 21:32:02 +0800 Subject: [PATCH 048/110] =?UTF-8?q?JavaScript=E7=89=88=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E3=80=8A=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E7=9A=84?= =?UTF-8?q?=E6=9C=80=E5=B0=8F=E7=BB=9D=E5=AF=B9=E5=B7=AE=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0530.二叉搜索树的最小绝对差.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/problems/0530.二叉搜索树的最小绝对差.md b/problems/0530.二叉搜索树的最小绝对差.md index 0bbc4908..8fa756bc 100644 --- a/problems/0530.二叉搜索树的最小绝对差.md +++ b/problems/0530.二叉搜索树的最小绝对差.md @@ -256,6 +256,39 @@ func findMIn(root *TreeNode,res *[]int){ } ``` +JavaScript版本 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {number} + */ +var getMinimumDifference = function (root) { + let arr = []; + const buildArr = (root) => { + if (root) { + buildArr(root.left); + arr.push(root.val); + buildArr(root.right); + } + } + buildArr(root); + let diff = arr[arr.length - 1]; + for (let i = 1; i < arr.length; ++i) { + if (diff > arr[i] - arr[i - 1]) + diff = arr[i] - arr[i - 1]; + } + return diff; +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From 4f66b8679ca619b6e3087934d4934f6538ec6769 Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Mon, 21 Jun 2021 21:33:43 +0800 Subject: [PATCH 049/110] =?UTF-8?q?JavaScript=E7=89=88=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E3=80=8A=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E4=BC=97=E6=95=B0=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0501.二叉搜索树中的众数.md | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/problems/0501.二叉搜索树中的众数.md b/problems/0501.二叉搜索树中的众数.md index 3ca7d892..1831a7a5 100644 --- a/problems/0501.二叉搜索树中的众数.md +++ b/problems/0501.二叉搜索树中的众数.md @@ -523,6 +523,55 @@ func traversal(root *TreeNode,result *[]int,pre *TreeNode){//遍历统计 } ``` +JavaScript版本 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {number[]} + */ +var findMode = function (root) { + let maxCount = 0; + let curCount = 0; + let pre = null; + let res = []; + const inOrder = (root) => { + if (root === null) + return; + inOrder(root.left); + + if (pre === null) + curCount = 1; + else if (pre.val === root.val) + curCount++; + else + curCount = 1; + pre = root; + + if (curCount === maxCount) + res.push(root.val); + + if (curCount > maxCount) { + maxCount = curCount; + res.splice(0, res.length); + res.push(root.val); + } + + inOrder(root.right); + return; + } + inOrder(root); + return res; +}; +``` ----------------------- From b33da0c412e49d67610bc7d6016c8e51541da637 Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Mon, 21 Jun 2021 21:35:19 +0800 Subject: [PATCH 050/110] =?UTF-8?q?JavaScript=E7=89=88=E6=9C=AC=E7=9A=84?= =?UTF-8?q?=E3=80=8A=E4=BA=8C=E5=8F=89=E7=9A=84=E6=9C=80=E8=BF=91=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E7=A5=96=E5=85=88=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0236.二叉树的最近公共祖先.md | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/problems/0236.二叉树的最近公共祖先.md b/problems/0236.二叉树的最近公共祖先.md index 2f7aa6c3..2413af1d 100644 --- a/problems/0236.二叉树的最近公共祖先.md +++ b/problems/0236.二叉树的最近公共祖先.md @@ -311,7 +311,34 @@ func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { } ``` +JavaScript版本 +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @param {TreeNode} q + * @return {TreeNode} + */ +var lowestCommonAncestor = function(root, p, q) { + if(root === p || root === q || root === null) + return root; + let left = lowestCommonAncestor(root.left, p , q); + let right = lowestCommonAncestor(root.right, p, q); + if(left && right) + return root; + if(!left) + return right; + return left; +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From fb8a5ab545dcd42947de8226272dca4e252d4172 Mon Sep 17 00:00:00 2001 From: callmePicacho <38685653+callmePicacho@users.noreply.github.com> Date: Tue, 22 Jun 2021 05:53:54 +0800 Subject: [PATCH 051/110] =?UTF-8?q?Update=200739.=E6=AF=8F=E6=97=A5?= =?UTF-8?q?=E6=B8=A9=E5=BA=A6.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 提交 Go 语言题解,提高代码可读性 --- problems/0739.每日温度.md | 59 +++++++++++++++++------------------ 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/problems/0739.每日温度.md b/problems/0739.每日温度.md index eeea6ead..e72fd6a4 100644 --- a/problems/0739.每日温度.md +++ b/problems/0739.每日温度.md @@ -217,47 +217,46 @@ Go: > 暴力法 ```go -func dailyTemperatures(temperatures []int) []int { - length:=len(temperatures) - res:=make([]int,length) - for i:=0;i t[i] { + res = append(res, j-i) + break + } } - for j=temperatures[j]{//大于等于 - j++ - } - if j 单调栈法 ```go -func dailyTemperatures(temperatures []int) []int { - length:=len(temperatures) - res:=make([]int,length) - stack:=[]int{} - for i:=0;i0&&temperatures[i]>temperatures[stack[len(stack)-1]]{ - res[stack[len(stack)-1]]=i-stack[len(stack)-1]//存放结果集 - stack=stack[:len(stack)-1]//删除stack[len(stack)-1]的元素 - } - //如果栈顶元素大于等于新来的元素,则加入到栈中。当栈内元素个数为0时,直接入栈 - if len(stack)==0||temperatures[i]<=temperatures[stack[len(stack)-1]]{ - stack = append(stack, i) +// 单调递减栈 +func dailyTemperatures(num []int) []int { + ans := make([]int, len(num)) + stack := []int{} + for i, v := range num { + // 栈不空,且当前遍历元素 v 破坏了栈的单调性 + for len(stack) != 0 && v > num[stack[len(stack)-1]] { + // pop + top := stack[len(stack)-1] + stack = stack[:len(stack)-1] + + ans[top] = i - top } + stack = append(stack, i) } - return res + return ans } ``` From 6d9303e27d6318923c1f4622920d2d1193cd909f Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Tue, 22 Jun 2021 11:37:04 +0800 Subject: [PATCH 052/110] 0763 golang --- problems/0763.划分字母区间.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/problems/0763.划分字母区间.md b/problems/0763.划分字母区间.md index 1e2fcc03..b36e00b7 100644 --- a/problems/0763.划分字母区间.md +++ b/problems/0763.划分字母区间.md @@ -128,6 +128,33 @@ class Solution: Go: +```go + +func partitionLabels(s string) []int { + var res []int; + var marks [26]int; + size, left, right := len(s), 0, 0; + for i := 0; i < size; i++ { + marks[s[i] - 'a'] = i; + } + for i := 0; i < size; i++ { + right = max(right, marks[s[i] - 'a']); + if i == right { + res = append(res, right - left + 1); + left = i + 1; + } + } + return res; +} + +func max(a, b int) int { + if a < b { + a = b; + } + return a; +} +``` + Javascript: ```Javascript var partitionLabels = function(s) { From 4ec57cd4550eb843baaa26659f139a34cf7459a4 Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Tue, 22 Jun 2021 23:03:46 +0800 Subject: [PATCH 053/110] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200112.=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E6=80=BB=E5=92=8C=20=E6=96=87=E6=A1=A3=E7=9A=84?= =?UTF-8?q?=E5=86=99=E9=94=99=E7=9A=84=E5=9C=B0=E6=96=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0112.路径总和.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md index 54f79d1d..d798ca90 100644 --- a/problems/0112.路径总和.md +++ b/problems/0112.路径总和.md @@ -117,7 +117,7 @@ if (cur->left) { // 左 } if (cur->right) { // 右 count -= cur->right->val; - if (traversal(cur->right, count - cur->right->val)) return true; + if (traversal(cur->right, count)) return true; count += cur->right->val; } return false; From 1f813d446f9d8a3710576f579200114f75e2ee8a Mon Sep 17 00:00:00 2001 From: Jijie LIU Date: Tue, 22 Jun 2021 17:22:42 +0200 Subject: [PATCH 054/110] =?UTF-8?q?update=20406=20=E6=A0=B9=E6=8D=AE?= =?UTF-8?q?=E8=BA=AB=E9=AB=98=E9=87=8D=E5=BB=BA=E9=98=9F=E5=88=97:=20?= =?UTF-8?q?=E7=A7=BB=E9=99=A4Pyhton=E7=89=88=E6=9C=AC=E7=9A=84=E5=86=97?= =?UTF-8?q?=E4=BD=99=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0406.根据身高重建队列.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/problems/0406.根据身高重建队列.md b/problems/0406.根据身高重建队列.md index 9aca5b94..946c41ce 100644 --- a/problems/0406.根据身高重建队列.md +++ b/problems/0406.根据身高重建队列.md @@ -214,13 +214,10 @@ Python: ```python class Solution: def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]: - people.sort(key=lambda x: (x[0], -x[1]), reverse=True) + people.sort(key=lambda x: (-x[0], x[1])) que = [] for p in people: - if p[1] > len(que): - que.append(p) - else: - que.insert(p[1], p) + que.insert(p[1], p) return que ``` From ac40cc8be29fdbf22b2b6a5b889315de74f602c3 Mon Sep 17 00:00:00 2001 From: KailokFung Date: Wed, 23 Jun 2021 10:24:40 +0800 Subject: [PATCH 055/110] =?UTF-8?q?fix(1047):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=8F=8C=E6=8C=87=E9=92=88java=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...除字符串中的所有相邻重复项.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 305a287d..4f13cda3 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -171,6 +171,29 @@ class Solution { } ``` +拓展:双指针 +```java +class Solution { + public String removeDuplicates(String s) { + char[] ch = s.toCharArray(); + int fast = 0; + int slow = 0; + while(fast < s.length()){ + // 直接用fast指针覆盖slow指针的值 + ch[slow] = ch[fast]; + // 遇到前后相同值的,就跳过,即slow指针后退一步,下次循环就可以直接被覆盖掉了 + if(slow > 0 && ch[slow] == ch[slow - 1]){ + slow--; + }else{ + slow++; + } + fast++; + } + return new String(ch,0,slow); + } +} +``` + Python: ```python3 class Solution: From 625558094da614c5f9a2b358f3291bf102f7e1a7 Mon Sep 17 00:00:00 2001 From: KailokFung Date: Wed, 23 Jun 2021 10:31:45 +0800 Subject: [PATCH 056/110] =?UTF-8?q?fix(1047):=20=E4=BD=BF=E7=94=A8ArrayDeq?= =?UTF-8?q?ue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1047.删除字符串中的所有相邻重复项.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 4f13cda3..760a0946 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -127,7 +127,9 @@ Java: ```Java class Solution { public String removeDuplicates(String S) { - Deque deque = new LinkedList<>(); + //ArrayDeque会比LinkedList在除了删除元素这一点外会快一点 + //参考:https://stackoverflow.com/questions/6163166/why-is-arraydeque-better-than-linkedlist + ArrayDeque deque = new ArrayDeque<>(); char ch; for (int i = 0; i < S.length(); i++) { ch = S.charAt(i); From e719e4f647a8e2400f220933cc53668549efe7c4 Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Wed, 23 Jun 2021 10:51:37 +0800 Subject: [PATCH 057/110] Update --- problems/0028.实现strStr.md | 25 +++++++++++----------- problems/0232.用栈实现队列.md | 32 ++++++++++++++--------------- problems/1035.不相交的线.md | 3 ++- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md index 04508440..aaa28d3d 100644 --- a/problems/0028.实现strStr.md +++ b/problems/0028.实现strStr.md @@ -59,7 +59,7 @@ KMP的经典思想就是:**当出现字符串不匹配时,可以记录一部 * 总结 -读完本篇可以顺便,把leetcode上28.实现strStr()题目做了。 +读完本篇可以顺便把leetcode上28.实现strStr()题目做了。 # 什么是KMP @@ -126,16 +126,15 @@ next数组就是一个前缀表(prefix table)。 # 最长公共前后缀? -文章中字符串的前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串; +文章中字符串的**前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串**。 -后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串。 +**后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串**。 -**正确理解什么是前缀什么是后缀很重要。** +**正确理解什么是前缀什么是后缀很重要**! 那么网上清一色都说 “kmp 最长公共前后缀” 又是什么回事呢? - -我查了一遍 算法导论 和 算法4里KMP的章节,都没有提到 “最长公共前后缀”这个词,也不知道从哪里来了,我理解是用“最长相等前后缀” 准确一些。 +我查了一遍 算法导论 和 算法4里KMP的章节,都没有提到 “最长公共前后缀”这个词,也不知道从哪里来了,我理解是用“最长相等前后缀” 更准确一些。 **因为前缀表要求的就是相同前后缀的长度。** @@ -220,7 +219,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减 # 使用next数组来匹配 -以下我们以前缀表统一减一之后的next数组来做演示。 +**以下我们以前缀表统一减一之后的next数组来做演示**。 有了next数组,就可以根据next数组来 匹配文本串s,和模式串t了。 @@ -236,7 +235,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减 暴力的解法显而易见是O(n * m),所以**KMP在字符串匹配中极大的提高的搜索的效率。** -为了和[字符串:KMP是时候上场了(一文读懂系列)](https://mp.weixin.qq.com/s/70OXnZ4Ez29CKRrUpVJmug)字符串命名统一,方便大家理解,以下文章统称haystack为文本串, needle为模式串。 +为了和力扣题目28.实现strStr保持一致,方便大家理解,以下文章统称haystack为文本串, needle为模式串。 都知道使用KMP算法,一定要构造next数组。 @@ -402,7 +401,7 @@ for (int i = 0; i < s.size(); i++) { // 注意i就从0开始 } ``` -此时所有逻辑的代码都已经写出来了,本题整体代码如下: +此时所有逻辑的代码都已经写出来了,力扣 28.实现strStr 题目的整体代码如下: # 前缀表统一减一 C++代码实现 @@ -448,7 +447,9 @@ public: # 前缀表(不减一)C++实现 -那么前缀表就不减一了,也不右移的,到底行不行呢?行! +那么前缀表就不减一了,也不右移的,到底行不行呢? + +**行!** 我之前说过,这仅仅是KMP算法实现上的问题,如果就直接使用前缀表可以换一种回退方式,找j=next[j-1] 来进行回退。 @@ -544,7 +545,7 @@ public: 我们介绍了什么是KMP,KMP可以解决什么问题,然后分析KMP算法里的next数组,知道了next数组就是前缀表,再分析为什么要是前缀表而不是什么其他表。 -接着从给出的模式串中,我们一步一步的推导出了前缀表,得出前缀表无论是统一减一还是不同意减一得到的next数组仅仅是kmp的实现方式的不同。 +接着从给出的模式串中,我们一步一步的推导出了前缀表,得出前缀表无论是统一减一还是不减一得到的next数组仅仅是kmp的实现方式的不同。 其中还分析了KMP算法的时间复杂度,并且和暴力方法做了对比。 @@ -815,4 +816,4 @@ func strStr(haystack string, needle string) int { * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) -
\ No newline at end of file +
diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md index c2af71f7..be6e1df6 100644 --- a/problems/0232.用栈实现队列.md +++ b/problems/0232.用栈实现队列.md @@ -15,10 +15,10 @@ https://leetcode-cn.com/problems/implement-queue-using-stacks/ 使用栈实现队列的下列操作: -push(x) -- 将一个元素放入队列的尾部。 -pop() -- 从队列首部移除元素。 -peek() -- 返回队列首部的元素。 -empty() -- 返回队列是否为空。 +push(x) -- 将一个元素放入队列的尾部。 +pop() -- 从队列首部移除元素。 +peek() -- 返回队列首部的元素。 +empty() -- 返回队列是否为空。 示例: @@ -46,18 +46,18 @@ queue.empty(); // 返回 false 下面动画模拟以下队列的执行过程如下: -执行语句: -queue.push(1); -queue.push(2); -queue.pop(); **注意此时的输出栈的操作** -queue.push(3); -queue.push(4); -queue.pop(); -queue.pop();**注意此时的输出栈的操作** -queue.pop(); -queue.empty(); +执行语句: +queue.push(1); +queue.push(2); +queue.pop(); **注意此时的输出栈的操作** +queue.push(3); +queue.push(4); +queue.pop(); +queue.pop();**注意此时的输出栈的操作** +queue.pop(); +queue.empty(); -![232.用栈实现队列版本2](https://code-thinking.cdn.bcebos.com/gifs/232.%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97%E7%89%88%E6%9C%AC2.gif) +![232.用栈实现队列版本2](https://code-thinking.cdn.bcebos.com/gifs/232.用栈实现队列版本2.gif) 在push数据的时候,只要数据放进输入栈就好,**但在pop的时候,操作就复杂一些,输出栈如果为空,就把进栈数据全部导入进来(注意是全部导入)**,再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了。 @@ -125,8 +125,6 @@ public: - - ## 其他语言版本 Java: diff --git a/problems/1035.不相交的线.md b/problems/1035.不相交的线.md index be159543..c7481306 100644 --- a/problems/1035.不相交的线.md +++ b/problems/1035.不相交的线.md @@ -26,7 +26,8 @@ 拿示例一A = [1,4,2], B = [1,2,4]为例,相交情况如图: -![1035.不相交的线](https://img-blog.csdnimg.cn/20210321164517460.png) +![](https://gitee.com/programmercarl/pics/raw/master/pic1/20210527113415.png) + 其实也就是说A和B的最长公共子序列是[1,4],长度为2。 这个公共子序列指的是相对顺序不变(即数字4在字符串A中数字1的后面,那么数字4也应该在字符串B数字1的后面) From cfca263b917143367385184f39be97ce0e4f8233 Mon Sep 17 00:00:00 2001 From: Yan Wen Date: Wed, 23 Jun 2021 16:26:43 +0800 Subject: [PATCH 058/110] =?UTF-8?q?update=E5=8F=8D=E8=BD=AC=E5=AD=97?= =?UTF-8?q?=E7=AC=A6=E4=B8=B2=EF=BC=8C=E6=B7=BB=E5=8A=A0=E4=BA=86python?= =?UTF-8?q?=E6=9B=B4=E5=8A=A0=E7=AE=80=E6=B4=81=E7=9A=84=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0344.反转字符串.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/problems/0344.反转字符串.md b/problems/0344.反转字符串.md index 1b86e847..079ebb0b 100644 --- a/problems/0344.反转字符串.md +++ b/problems/0344.反转字符串.md @@ -157,7 +157,7 @@ class Solution { ``` Python: -```python3 +```python class Solution: def reverseString(self, s: List[str]) -> None: """ @@ -168,6 +168,17 @@ class Solution: 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 a150c61f9db97521b2b758affe64e202d6a821d4 Mon Sep 17 00:00:00 2001 From: KailokFung Date: Wed, 23 Jun 2021 18:01:20 +0800 Subject: [PATCH 059/110] =?UTF-8?q?fix(0239):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=B8=80=E7=A7=8Djava=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0239.滑动窗口最大值.md | 35 ++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md index d108335b..ad54a940 100644 --- a/problems/0239.滑动窗口最大值.md +++ b/problems/0239.滑动窗口最大值.md @@ -208,6 +208,7 @@ public: Java: ```Java +//解法一 //自定义数组 class MyQueue { Deque deque = new LinkedList<>(); @@ -260,6 +261,40 @@ class Solution { return res; } } + +//解法二 +//利用双端队列手动实现单调队列 +/** + * 用一个单调队列来存储对应的下标,每当窗口滑动的时候,直接取队列的头部指针对应的值放入结果集即可 + * 单调队列类似 (tail -->) 3 --> 2 --> 1 --> 0 (--> head) (右边为头结点,元素存的是下标) + */ +class Solution { + public int[] maxSlidingWindow(int[] nums, int k) { + ArrayDeque deque = new ArrayDeque<>(); + int n = nums.length; + int[] res = new int[n - k + 1]; + int idx = 0; + for(int i = 0; i < n; i++) { + // 根据题意,i为nums下标,是要在[i - k + 1, k] 中选到最大值,只需要保证两点 + // 1.队列头结点需要在[i - k + 1, k]范围内,不符合则要弹出 + while(!deque.isEmpty() && deque.peek() < i - k + 1){ + deque.poll(); + } + // 2.既然是单调,就要保证每次放进去的数字要比末尾的都大,否则也弹出 + while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { + deque.pollLast(); + } + + deque.offer(i); + + // 因为单调,当i增长到符合第一个k范围的时候,每滑动一步都将队列头节点放入结果就行了 + if(i >= k - 1){ + res[idx++] = nums[deque.peek()]; + } + } + return res; + } +} ``` Python: From bf7597facfb1f993024ff932fabe6f0bf5198b31 Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Wed, 23 Jun 2021 21:49:11 +0800 Subject: [PATCH 060/110] =?UTF-8?q?=E6=8F=90=E4=BE=9BJavascript=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E7=9A=84=E3=80=8A=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E6=95=B0=E7=9A=84=E6=9C=80=E8=BF=91=E5=85=AC=E5=85=B1=E7=A5=96?= =?UTF-8?q?=E5=85=88=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...35.二叉搜索树的最近公共祖先.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/problems/0235.二叉搜索树的最近公共祖先.md b/problems/0235.二叉搜索树的最近公共祖先.md index d78db42a..a893c191 100644 --- a/problems/0235.二叉搜索树的最近公共祖先.md +++ b/problems/0235.二叉搜索树的最近公共祖先.md @@ -314,7 +314,62 @@ func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { ``` +JavaScript版本 +> 递归 +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @param {TreeNode} q + * @return {TreeNode} + */ +var lowestCommonAncestor = function(root, p, q) { + if(root.val > p.val && root.val > q.val) + return lowestCommonAncestor(root.left, p , q); + else if(root.val < p.val && root.val < q.val) + return lowestCommonAncestor(root.right, p , q); + return root; +}; +``` + +> 迭代 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @param {TreeNode} q + * @return {TreeNode} + */ +var lowestCommonAncestor = function(root, p, q) { + while(1) { + if(root.val > p.val && root.val > q.val) + root = root.left; + else if(root.val < p.val && root.val < q.val) + root = root.right; + else + break; + } + return root; +}; +``` ----------------------- From 826927e6ad0d54dcfd92ff634b7496525b4d2004 Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Wed, 23 Jun 2021 22:15:10 +0800 Subject: [PATCH 061/110] =?UTF-8?q?=E6=8F=90=E4=BE=9BJavaScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E7=9A=84=E3=80=8A=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E6=A0=91=E4=B8=AD=E7=9A=84=E6=8F=92=E5=85=A5=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0701.二叉搜索树中的插入操作.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/problems/0701.二叉搜索树中的插入操作.md b/problems/0701.二叉搜索树中的插入操作.md index 6a8ba7fc..0f5b603a 100644 --- a/problems/0701.二叉搜索树中的插入操作.md +++ b/problems/0701.二叉搜索树中的插入操作.md @@ -286,6 +286,39 @@ func insertIntoBST(root *TreeNode, val int) *TreeNode { } ``` +JavaScript版本 + +> 有返回值的递归写法 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} val + * @return {TreeNode} + */ +var insertIntoBST = function (root, val) { + const setInOrder = (root, val) => { + if (root === null) { + let node = new TreeNode(val); + return node; + } + if (root.val > val) + root.left = setInOrder(root.left, val); + else if (root.val < val) + root.right = setInOrder(root.right, val); + return root; + } + return setInOrder(root, val); +}; +``` From 007813f33b731210fb75f65c6a1309dd47f7b9a1 Mon Sep 17 00:00:00 2001 From: liulei <718356979@qq.com> Date: Thu, 24 Jun 2021 08:40:16 +0800 Subject: [PATCH 062/110] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=A0=91=E7=9A=84=E8=BF=AD=E4=BB=A3=E9=81=8D=E5=8E=86=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0java=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/二叉树的迭代遍历.md | 75 +++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/problems/二叉树的迭代遍历.md b/problems/二叉树的迭代遍历.md index 8706dc47..30b921ff 100644 --- a/problems/二叉树的迭代遍历.md +++ b/problems/二叉树的迭代遍历.md @@ -155,9 +155,82 @@ public: ## 其他语言版本 - Java: +```java +// 前序遍历顺序:中-左-右,入栈顺序:中-右-左 +class Solution { + public List preorderTraversal(TreeNode root) { + List result = new ArrayList<>(); + if (root == null){ + return result; + } + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()){ + TreeNode node = stack.pop(); + result.add(node.val); + if (node.right != null){ + stack.push(node.right); + } + if (node.left != null){ + stack.push(node.left); + } + } + return result; + } +} + +// 中序遍历顺序: 左-中-右 入栈顺序: 左-右 +class Solution { + public List inorderTraversal(TreeNode root) { + List result = new ArrayList<>(); + if (root == null){ + return result; + } + Stack stack = new Stack<>(); + TreeNode cur = root; + while (cur != null || !stack.isEmpty()){ + if (cur != null){ + stack.push(cur); + cur = cur.left; + }else{ + cur = stack.pop(); + result.add(cur.val); + cur = cur.right; + } + } + return result; + } +} + +// 后序遍历顺序 左-右-中 入栈顺序:中-左-右 出栈顺序:中-右-左, 最后翻转结果 +class Solution { + public List postorderTraversal(TreeNode root) { + List result = new ArrayList<>(); + if (root == null){ + return result; + } + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()){ + TreeNode node = stack.pop(); + result.add(node.val); + if (node.left != null){ + stack.push(node.left); + } + if (node.right != null){ + stack.push(node.right); + } + } + Collections.reverse(result); + return result; + } +} +``` + + + Python: ```python3 From fc2dc45a198f9562fcbefdb399d71482c8c45cd8 Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Thu, 24 Jun 2021 21:41:10 +0800 Subject: [PATCH 063/110] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=200617.=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E4=BA=8C=E5=8F=89=E6=A0=91=20go=E7=89=88=20=EF=BC=88?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=89=8D=E5=BA=8F=E9=81=8D=E5=8E=86=E7=AE=80?= =?UTF-8?q?=E6=B4=81=E7=89=88=E8=A7=A3=E9=A2=98=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加前序遍历简洁版解题 --- problems/0617.合并二叉树.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/problems/0617.合并二叉树.md b/problems/0617.合并二叉树.md index 2ff093a3..f325df64 100644 --- a/problems/0617.合并二叉树.md +++ b/problems/0617.合并二叉树.md @@ -368,6 +368,20 @@ func mergeTrees(t1 *TreeNode, t2 *TreeNode) *TreeNode { Right: mergeTrees(t1.Right,t2.Right)} return root } + +// 前序遍历简洁版 +func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode { + if root1 == nil { + return root2 + } + if root2 == nil { + return root1 + } + root1.Val += root2.Val + root1.Left = mergeTrees(root1.Left, root2.Left) + root1.Right = mergeTrees(root1.Right, root2.Right) + return root1 +} ``` JavaScript: From 24e7994d2708b90f304dd424f0175bcce845955f Mon Sep 17 00:00:00 2001 From: Jijie LIU Date: Thu, 24 Jun 2021 20:29:02 +0200 Subject: [PATCH 064/110] =?UTF-8?q?update=2063.=20=E4=B8=8D=E5=90=8C?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20II=EF=BC=9A=E6=8F=90=E4=BE=9B=E4=B8=80?= =?UTF-8?q?=E7=BB=B4dp=E6=95=B0=E7=BB=84=E7=9A=84Python=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0063.不同路径II.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/problems/0063.不同路径II.md b/problems/0063.不同路径II.md index 52f00322..a61ffd02 100644 --- a/problems/0063.不同路径II.md +++ b/problems/0063.不同路径II.md @@ -232,6 +232,38 @@ class Solution: return dp[-1][-1] ``` +```python +class Solution: + """ + 使用一维dp数组 + """ + + def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: + m, n = len(obstacleGrid), len(obstacleGrid[0]) + + # 初始化dp数组 + # 该数组缓存当前行 + curr = [0] * n + for j in range(n): + if obstacleGrid[0][j] == 1: + break + curr[j] = 1 + + for i in range(1, m): # 从第二行开始 + for j in range(n): # 从第一列开始,因为第一列可能有障碍物 + # 有障碍物处无法通行,状态就设成0 + if obstacleGrid[i][j] == 1: + curr[j] = 0 + elif j > 0: + # 等价于 + # dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + curr[j] = curr[j] + curr[j - 1] + # 隐含的状态更新 + # dp[i][0] = dp[i - 1][0] + + return curr[n - 1] +``` + Go: From fe71144f142063bc8d8f48b81e390bd3e2fa011e Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Fri, 25 Jun 2021 11:32:49 +0800 Subject: [PATCH 065/110] =?UTF-8?q?0509.=E6=96=90=E6=B3=A2=E9=82=A3?= =?UTF-8?q?=E5=A5=91=E6=95=B0=E5=88=97.md=20Javascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0509.斐波那契数.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/problems/0509.斐波那契数.md b/problems/0509.斐波那契数.md index cf004b50..dddac899 100644 --- a/problems/0509.斐波那契数.md +++ b/problems/0509.斐波那契数.md @@ -220,7 +220,17 @@ func fib(n int) int { return c } ``` - +Javascript: +```Javascript +var fib = function(n) { + let dp = [0, 1] + for(let i = 2; i <= n; i++) { + dp[i] = dp[i - 1] + dp[i - 2] + } + console.log(dp) + return dp[n] +}; +``` From bce132cb329b69a2677bcf5415d7469913014dca Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Fri, 25 Jun 2021 11:49:59 +0800 Subject: [PATCH 066/110] =?UTF-8?q?0070.=E7=88=AC=E6=A5=BC=E6=A2=AF.md=20J?= =?UTF-8?q?avascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0070.爬楼梯.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/problems/0070.爬楼梯.md b/problems/0070.爬楼梯.md index 680af587..96899d37 100644 --- a/problems/0070.爬楼梯.md +++ b/problems/0070.爬楼梯.md @@ -283,7 +283,18 @@ func climbStairs(n int) int { return dp[n] } ``` - +Javascript: +```Javascript +var climbStairs = function(n) { + // dp[i] 为第 i 阶楼梯有多少种方法爬到楼顶 + // dp[i] = dp[i - 1] + dp[i - 2] + let dp = [1 , 2] + for(let i = 2; i < n; i++) { + dp[i] = dp[i - 1] + dp[i - 2] + } + return dp[n - 1] +}; +``` ----------------------- From ad1faf8a150a8954661e39cbd25f0fdc1b1f8b5b Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Fri, 25 Jun 2021 22:54:40 +0800 Subject: [PATCH 067/110] =?UTF-8?q?=E6=8F=90=E4=BE=9BJavaScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E7=9A=84=E3=80=8A=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E6=A0=91=E4=B8=AD=E7=9A=84=E6=8F=92=E5=85=A5=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0701.二叉搜索树中的插入操作.md | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/problems/0701.二叉搜索树中的插入操作.md b/problems/0701.二叉搜索树中的插入操作.md index 0f5b603a..794e0ae2 100644 --- a/problems/0701.二叉搜索树中的插入操作.md +++ b/problems/0701.二叉搜索树中的插入操作.md @@ -320,7 +320,84 @@ var insertIntoBST = function (root, val) { }; ``` +> 无返回值的递归 +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} val + * @return {TreeNode} + */ +var insertIntoBST = function (root, val) { + let parent = new TreeNode(0); + const preOrder = (cur, val) => { + if (cur === null) { + let node = new TreeNode(val); + if (parent.val > val) + parent.left = node; + else + parent.right = node; + return; + } + parent = cur; + if (cur.val > val) + preOrder(cur.left, val); + if (cur.val < val) + preOrder(cur.right, val); + } + if (root === null) + root = new TreeNode(val); + preOrder(root, val); + return root; +}; +``` + +> 迭代 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} val + * @return {TreeNode} + */ +var insertIntoBST = function (root, val) { + if (root === null) { + root = new TreeNode(val); + } else { + let parent = new TreeNode(0); + let cur = root; + while (cur) { + parent = cur; + if (cur.val > val) + cur = cur.left; + else + cur = cur.right; + } + let node = new TreeNode(val); + if (parent.val > val) + parent.left = node; + else + parent.right = node; + } + return root; +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From b461cf71587352d713a61e5a5d3f56d72a100019 Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Fri, 25 Jun 2021 22:56:08 +0800 Subject: [PATCH 068/110] =?UTF-8?q?=E6=8F=90=E4=BE=9BJavaScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E7=9A=84=E3=80=8A=E5=88=A0=E9=99=A4=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=91=E4=B8=AD=E7=9A=84=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0450.删除二叉搜索树中的节点.md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/problems/0450.删除二叉搜索树中的节点.md b/problems/0450.删除二叉搜索树中的节点.md index 3ed44c0a..1cd3d370 100644 --- a/problems/0450.删除二叉搜索树中的节点.md +++ b/problems/0450.删除二叉搜索树中的节点.md @@ -359,6 +359,51 @@ func deleteNode1(root *TreeNode)*TreeNode{ } ``` +JavaScript版本 + +> 递归 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @param {number} key + * @return {TreeNode} + */ +var deleteNode = function (root, key) { + if (root === null) + return root; + if (root.val === key) { + if (!root.left) + return root.right; + else if (!root.right) + return root.left; + else { + let cur = root.right; + while (cur.left) { + cur = cur.left; + } + cur.left = root.left; + let temp = root; + root = root.right; + delete root; + return root; + } + } + if (root.val > key) + root.left = deleteNode(root.left, key); + if (root.val < key) + root.right = deleteNode(root.right, key); + return root; +}; +``` From a921b3ba3dbd9179721cf4f408f2a5f41a34e7ad Mon Sep 17 00:00:00 2001 From: jojoo15 <75017412+jojoo15@users.noreply.github.com> Date: Sat, 26 Jun 2021 13:10:28 +0200 Subject: [PATCH 069/110] =?UTF-8?q?=E4=BC=98=E5=8C=96=200062=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E8=B7=AF=E5=BE=84=20python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化 0062不同路径 python3版本 --- problems/0062.不同路径.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/problems/0062.不同路径.md b/problems/0062.不同路径.md index 47cb41af..50e70b3e 100644 --- a/problems/0062.不同路径.md +++ b/problems/0062.不同路径.md @@ -279,9 +279,7 @@ Python: ```python class Solution: # 动态规划 def uniquePaths(self, m: int, n: int) -> int: - dp = [[0 for i in range(n)] for j in range(m)] - for i in range(m): dp[i][0] = 1 - for j in range(n): dp[0][j] = 1 + dp = [[1 for i in range(n)] for j in range(m)] for i in range(1, m): for j in range(1, n): dp[i][j] = dp[i][j - 1] + dp[i - 1][j] From 178cf44b202bf10707fed8825d3bf23b8e9d8f8b Mon Sep 17 00:00:00 2001 From: "xeniaxie(xl)" Date: Sat, 26 Jun 2021 20:33:27 +0800 Subject: [PATCH 070/110] =?UTF-8?q?0501=E4=BA=8C=E5=8F=89=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E6=A0=91=E4=B8=AD=E7=9A=84=E4=BC=97=E6=95=B0JavaScrip?= =?UTF-8?q?t=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0501.二叉搜索树中的众数.md | 74 +++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/problems/0501.二叉搜索树中的众数.md b/problems/0501.二叉搜索树中的众数.md index 3ca7d892..74c53458 100644 --- a/problems/0501.二叉搜索树中的众数.md +++ b/problems/0501.二叉搜索树中的众数.md @@ -522,7 +522,79 @@ func traversal(root *TreeNode,result *[]int,pre *TreeNode){//遍历统计 } } ``` - +JavaScript版本: +使用额外空间map的方法: +```javascript +var findMode = function(root) { + // 使用递归中序遍历 + let map = new Map(); + // 1. 确定递归函数以及函数参数 + const traverTree = function(root) { + // 2. 确定递归终止条件 + if(root === null) { + return ; + } + traverTree(root.left); + // 3. 单层递归逻辑 + map.set(root.val,map.has(root.val)?map.get(root.val)+1:1); + traverTree(root.right); + } + traverTree(root); + //上面把数据都存储到map + //下面开始寻找map里面的 + // 定义一个最大出现次数的初始值为root.val的出现次数 + let maxCount = map.get(root.val); + // 定义一个存放结果的数组res + let res = []; + for(let [key,value] of map) { + // 如果当前值等于最大出现次数就直接在res增加该值 + if(value === maxCount) { + res.push(key); + } + // 如果value的值大于原本的maxCount就清空res的所有值,因为找到了更大的 + if(value>maxCount) { + res = []; + maxCount = value; + res.push(key); + } + } + return res; +}; +``` +不使用额外空间,利用二叉树性质,中序遍历(有序): +```javascript +var findMode = function(root) { + // 不使用额外空间,使用中序遍历,设置出现最大次数初始值为1 + let count = 0,maxCount = 1; + let pre = root,res = []; + // 1.确定递归函数及函数参数 + const travelTree = function(cur) { + // 2. 确定递归终止条件 + if(cur === null) { + return ; + } + travelTree(cur.left); + // 3. 单层递归逻辑 + if(pre.val === cur.val) { + count++; + }else { + count = 1; + } + pre = cur; + if(count === maxCount) { + res.push(cur.val); + } + if(count > maxCount) { + res = []; + maxCount = count; + res.push(cur.val); + } + travelTree(cur.right); + } + travelTree(root); + return res; +}; +``` ----------------------- From f3b21c7984039eaa37c8da08eac725e6c8d1e11b Mon Sep 17 00:00:00 2001 From: "xeniaxie(xl)" Date: Sat, 26 Jun 2021 21:12:39 +0800 Subject: [PATCH 071/110] =?UTF-8?q?0236=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E6=9C=80=E8=BF=91=E5=85=AC=E5=85=B1=E7=A5=96=E5=85=88?= =?UTF-8?q?JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0236.二叉树的最近公共祖先.md | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/problems/0236.二叉树的最近公共祖先.md b/problems/0236.二叉树的最近公共祖先.md index 2f7aa6c3..7673a0ab 100644 --- a/problems/0236.二叉树的最近公共祖先.md +++ b/problems/0236.二叉树的最近公共祖先.md @@ -310,7 +310,31 @@ func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { return nil } ``` - +JavaScript版本: +```javascript +var lowestCommonAncestor = function(root, p, q) { + // 使用递归的方法 + // 需要从下到上,所以使用后序遍历 + // 1. 确定递归的函数 + const travelTree = function(root,p,q) { + // 2. 确定递归终止条件 + if(root === null || root === p||root === q) { + return root; + } + // 3. 确定递归单层逻辑 + let left = travelTree(root.left,p,q); + let right = travelTree(root.right,p,q); + if(left !== null&&right !== null) { + return root; + } + if(left ===null) { + return right; + } + return left; + } + return travelTree(root,p,q); +}; +``` ----------------------- From 1844077399766d28727f1b0d297855a473030339 Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Sat, 26 Jun 2021 22:53:33 +0800 Subject: [PATCH 072/110] =?UTF-8?q?0746.=E4=BD=BF=E7=94=A8=E6=9C=80?= =?UTF-8?q?=E5=B0=8F=E8=8A=B1=E8=B4=B9=E7=88=AC=E6=A5=BC=E6=A2=AF.md=20Jav?= =?UTF-8?q?ascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..2ca27187 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "type": "pwa-chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file From 3dc4167c59a29b7654d0a03a76645bee1e6e57db Mon Sep 17 00:00:00 2001 From: Yan Wen Date: Sun, 27 Jun 2021 09:19:45 +0800 Subject: [PATCH 073/110] =?UTF-8?q?update=E5=B7=A6=E6=97=8B=E8=BD=AC?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=EF=BC=8C=E6=B7=BB=E5=8A=A0python?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../剑指Offer58-II.左旋转字符串.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md index 39c8382c..ca903900 100644 --- a/problems/剑指Offer58-II.左旋转字符串.md +++ b/problems/剑指Offer58-II.左旋转字符串.md @@ -119,6 +119,27 @@ class Solution { ``` Python: +```python +# 方法一:可以使用切片方法 +class Solution: + def reverseLeftWords(self, s: str, n: int) -> str: + return s[n:] + s[0:n] + +# 方法二:也可以使用上文描述的方法,有些面试中不允许使用切片,那就使用上文作者提到的方法 +# 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) + + +# 时间复杂度:O(n) +# 空间复杂度:O(n),python的string为不可变,需要开辟同样大小的list空间来修改 +``` + Go: ```go From c0dbcc8a73eec6517b8b26e376a8c7060b8b858b Mon Sep 17 00:00:00 2001 From: "xeniaxie(xl)" Date: Sun, 27 Jun 2021 10:28:58 +0800 Subject: [PATCH 074/110] =?UTF-8?q?0235=E4=BA=8C=E5=8F=89=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E6=A0=91=E7=9A=84=E6=9C=80=E8=BF=91=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E7=A5=96=E5=85=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...35.二叉搜索树的最近公共祖先.md | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/problems/0235.二叉搜索树的最近公共祖先.md b/problems/0235.二叉搜索树的最近公共祖先.md index d78db42a..b8b23f09 100644 --- a/problems/0235.二叉搜索树的最近公共祖先.md +++ b/problems/0235.二叉搜索树的最近公共祖先.md @@ -312,7 +312,46 @@ func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { }else {return findLeft} } ``` - +JavaScript版本: +1. 使用递归的方法: +```javascript +var lowestCommonAncestor = function(root, p, q) { + // 使用递归的方法 + // 1. 使用给定的递归函数lowestCommonAncestor + // 2. 确定递归终止条件 + if(root === null) { + return root; + } + if(root.val>p.val&&root.val>q.val) { + // 向左子树查询 + let left = lowestCommonAncestor(root.left,p,q); + return left !== null&&left; + } + if(root.valp.val&&root.val>q.val) { + root = root.left; + }else if(root.val Date: Sun, 27 Jun 2021 10:35:03 +0800 Subject: [PATCH 075/110] =?UTF-8?q?Revert=20"0235=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=91=E7=9A=84=E6=9C=80=E8=BF=91=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E7=A5=96=E5=85=88"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit c0dbcc8a73eec6517b8b26e376a8c7060b8b858b. --- ...35.二叉搜索树的最近公共祖先.md | 41 +------------------ 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/problems/0235.二叉搜索树的最近公共祖先.md b/problems/0235.二叉搜索树的最近公共祖先.md index b8b23f09..d78db42a 100644 --- a/problems/0235.二叉搜索树的最近公共祖先.md +++ b/problems/0235.二叉搜索树的最近公共祖先.md @@ -312,46 +312,7 @@ func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { }else {return findLeft} } ``` -JavaScript版本: -1. 使用递归的方法: -```javascript -var lowestCommonAncestor = function(root, p, q) { - // 使用递归的方法 - // 1. 使用给定的递归函数lowestCommonAncestor - // 2. 确定递归终止条件 - if(root === null) { - return root; - } - if(root.val>p.val&&root.val>q.val) { - // 向左子树查询 - let left = lowestCommonAncestor(root.left,p,q); - return left !== null&&left; - } - if(root.valp.val&&root.val>q.val) { - root = root.left; - }else if(root.val Date: Sun, 27 Jun 2021 10:45:48 +0800 Subject: [PATCH 076/110] =?UTF-8?q?0235=E4=BA=8C=E5=8F=89=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E6=A0=91=E7=9A=84=E6=9C=80=E8=BF=91=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E7=A5=96=E5=85=88Javascript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...35.二叉搜索树的最近公共祖先.md | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/problems/0235.二叉搜索树的最近公共祖先.md b/problems/0235.二叉搜索树的最近公共祖先.md index d78db42a..8ea3cdc5 100644 --- a/problems/0235.二叉搜索树的最近公共祖先.md +++ b/problems/0235.二叉搜索树的最近公共祖先.md @@ -312,8 +312,46 @@ func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { }else {return findLeft} } ``` - - +JavaScript版本: +1. 使用递归的方法 +```javascript +var lowestCommonAncestor = function(root, p, q) { + // 使用递归的方法 + // 1. 使用给定的递归函数lowestCommonAncestor + // 2. 确定递归终止条件 + if(root === null) { + return root; + } + if(root.val>p.val&&root.val>q.val) { + // 向左子树查询 + let left = lowestCommonAncestor(root.left,p,q); + return left !== null&&left; + } + if(root.valp.val&&root.val>q.val) { + root = root.left; + }else if(root.val Date: Sun, 27 Jun 2021 13:11:31 +0800 Subject: [PATCH 077/110] =?UTF-8?q?Update=20=E8=83=8C=E5=8C=85=E7=90=86?= =?UTF-8?q?=E8=AE=BA=E5=9F=BA=E7=A1=8001=E8=83=8C=E5=8C=85-1.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/背包理论基础01背包-1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/背包理论基础01背包-1.md b/problems/背包理论基础01背包-1.md index 1269d9c1..3cbfb347 100644 --- a/problems/背包理论基础01背包-1.md +++ b/problems/背包理论基础01背包-1.md @@ -82,7 +82,7 @@ leetcode上没有纯01背包的问题,都是01背包应用方面的题目, 那么可以有两个方向推出来dp[i][j], -* 由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j] +* 由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以被背包内的价值依然和前面相同。) * 由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值 所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); From 1a16c119a39f1929af9294b653385defa7c904f3 Mon Sep 17 00:00:00 2001 From: KailokFung Date: Sun, 27 Jun 2021 15:44:40 +0800 Subject: [PATCH 078/110] =?UTF-8?q?feat(=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=90=86=E8=AE=BA=E5=9F=BA=E7=A1=80.md):=20=E6=96=B0=E5=A2=9Ej?= =?UTF-8?q?ava=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/二叉树理论基础.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/problems/二叉树理论基础.md b/problems/二叉树理论基础.md index 55383e91..d4dfe0c6 100644 --- a/problems/二叉树理论基础.md +++ b/problems/二叉树理论基础.md @@ -188,6 +188,21 @@ struct TreeNode { Java: +```java +public class TreeNode { + int val; + TreeNode left; + TreeNode right; + TreeNode() {} + TreeNode(int val) { this.val = val; } + TreeNode(int val, TreeNode left, TreeNode right) { + this.val = val; + this.left = left; + this.right = right; + } +} +``` + Python: From 5e68f30728cbcdb670eda7f12d3c208796f5c731 Mon Sep 17 00:00:00 2001 From: Jijie LIU Date: Sun, 27 Jun 2021 17:40:11 +0200 Subject: [PATCH 079/110] =?UTF-8?q?update=20279.=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E5=B9=B3=E6=96=B9=E6=95=B0:=20=E6=8F=90=E4=BE=9B=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0279.完全平方数.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/problems/0279.完全平方数.md b/problems/0279.完全平方数.md index 60d6d165..d0922de1 100644 --- a/problems/0279.完全平方数.md +++ b/problems/0279.完全平方数.md @@ -214,8 +214,26 @@ class Solution: return dp[n] ``` +Python3: +```python +class Solution: + def numSquares(self, n: int) -> int: + # 初始化 + # 组成和的完全平方数的最多个数,就是只用1构成 + # 因此,dp[i] = i + dp = [i for i in range(n + 1)] + # dp[0] = 0 无意义,只是为了方便记录特殊情况: + # n本身就是完全平方数,dp[n] = min(dp[n], dp[n - n] + 1) = 1 + for i in range(1, n): # 遍历物品 + if i * i > n: + break + num = i * i + for j in range(num, n + 1): # 遍历背包 + dp[j] = min(dp[j], dp[j - num] + 1) + return dp[n] +``` Go: ```go From e7f1f7f02dd556357a454c8856e7027ade71e02c Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Mon, 28 Jun 2021 15:19:38 +0800 Subject: [PATCH 080/110] Update --- README.md | 2 +- ...将有序数组转换为二叉搜索树.md | 2 +- .../0450.删除二叉搜索树中的节点.md | 1 - problems/0459.重复的子字符串.md | 41 +++++++++---------- problems/0494.目标和.md | 2 +- problems/双指针总结.md | 30 ++++---------- problems/字符串总结.md | 39 +++++++----------- 7 files changed, 45 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index b9ee3a9e..5f6b88d4 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ (持续更新中.....) -## 备战秋招 +## 知识星球精选 1. [选择方向的时候,我也迷茫了](https://mp.weixin.qq.com/s/ZCzFiAHZHLqHPLJQXNm75g) 2. [刷题就用库函数了,怎么了?](https://mp.weixin.qq.com/s/6K3_OSaudnHGq2Ey8vqYfg) diff --git a/problems/0108.将有序数组转换为二叉搜索树.md b/problems/0108.将有序数组转换为二叉搜索树.md index 35b8bb2e..b8861b24 100644 --- a/problems/0108.将有序数组转换为二叉搜索树.md +++ b/problems/0108.将有序数组转换为二叉搜索树.md @@ -54,7 +54,7 @@ 如下两棵树,都是这个数组的平衡二叉搜索树: -![108.将有序数组转换为二叉搜索树](https://code-thinking.cdn.bcebos.com/pics/108.%E5%B0%86%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E8%BD%AC%E6%8D%A2%E4%B8%BA%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91.png) +![108.将有序数组转换为二叉搜索树](https://code-thinking.cdn.bcebos.com/pics/108.将有序数组转换为二叉搜索树.png) 如果要分割的数组长度为偶数的时候,中间元素为两个,是取左边元素 就是树1,取右边元素就是树2。 diff --git a/problems/0450.删除二叉搜索树中的节点.md b/problems/0450.删除二叉搜索树中的节点.md index 3ed44c0a..e4930aeb 100644 --- a/problems/0450.删除二叉搜索树中的节点.md +++ b/problems/0450.删除二叉搜索树中的节点.md @@ -67,7 +67,6 @@ if (root == nullptr) return root; 第五种情况有点难以理解,看下面动画: ![450.删除二叉搜索树中的节点](https://tva1.sinaimg.cn/large/008eGmZEly1gnbj3k596mg30dq0aigyz.gif) - 动画中颗二叉搜索树中,删除元素7, 那么删除节点(元素7)的左孩子就是5,删除节点(元素7)的右子树的最左面节点是元素8。 diff --git a/problems/0459.重复的子字符串.md b/problems/0459.重复的子字符串.md index deb755bf..368489a5 100644 --- a/problems/0459.重复的子字符串.md +++ b/problems/0459.重复的子字符串.md @@ -17,18 +17,18 @@ https://leetcode-cn.com/problems/repeated-substring-pattern/ 给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。 -示例 1: -输入: "abab" -输出: True -解释: 可由子字符串 "ab" 重复两次构成。 +示例 1: +输入: "abab" +输出: True +解释: 可由子字符串 "ab" 重复两次构成。 -示例 2: -输入: "aba" -输出: False +示例 2: +输入: "aba" +输出: False -示例 3: -输入: "abcabcabcabc" -输出: True +示例 3: +输入: "abcabcabcabc" +输出: True 解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。) # 思路 @@ -41,13 +41,11 @@ https://leetcode-cn.com/problems/repeated-substring-pattern/ * [帮你把KMP算法学个通透!(求next数组代码篇)](https://www.bilibili.com/video/BV1M5411j7Xx) -如果KMP还不够了解,可以看我的这个视频[帮你把KMP算法学个通透!B站](https://www.bilibili.com/video/BV1PD4y1o7nd/) - -我们在[字符串:都来看看KMP的看家本领!](https://mp.weixin.qq.com/s/Gk9FKZ9_FSWLEkdGrkecyg)里提到了,在一个串中查找是否出现过另一个串,这是KMP的看家本领。 +我们在[字符串:KMP算法精讲](https://mp.weixin.qq.com/s/MoRBHbS4hQXn7LcPdmHmIg)里提到了,在一个串中查找是否出现过另一个串,这是KMP的看家本领。 那么寻找重复子串怎么也涉及到KMP算法了呢? -这里就要说一说next数组了,next 数组记录的就是最长相同前后缀( [字符串:听说你对KMP有这些疑问?](https://mp.weixin.qq.com/s/mqx6IM2AO4kLZwvXdPtEeQ) 这里介绍了什么是前缀,什么是后缀,什么又是最长相同前后缀), 如果 next[len - 1] != -1,则说明字符串有最长相同的前后缀(就是字符串里的前缀子串和后缀子串相同的最长长度)。 +这里就要说一说next数组了,next 数组记录的就是最长相同前后缀( [字符串:KMP算法精讲](https://mp.weixin.qq.com/s/MoRBHbS4hQXn7LcPdmHmIg) 这里介绍了什么是前缀,什么是后缀,什么又是最长相同前后缀), 如果 next[len - 1] != -1,则说明字符串有最长相同的前后缀(就是字符串里的前缀子串和后缀子串相同的最长长度)。 最长相等前后缀的长度为:next[len - 1] + 1。 @@ -62,7 +60,7 @@ https://leetcode-cn.com/problems/repeated-substring-pattern/ 如图: -![459.重复的子字符串_1](https://code-thinking.cdn.bcebos.com/pics/459.%E9%87%8D%E5%A4%8D%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2_1.png) +![459.重复的子字符串_1](https://code-thinking.cdn.bcebos.com/pics/459.重复的子字符串_1.png) next[len - 1] = 7,next[len - 1] + 1 = 8,8就是此时字符串asdfasdfasdf的最长相同前后缀的长度。 @@ -70,7 +68,7 @@ next[len - 1] = 7,next[len - 1] + 1 = 8,8就是此时字符串asdfasdfasdf (len - (next[len - 1] + 1)) 也就是: 12(字符串的长度) - 8(最长公共前后缀的长度) = 4, 4正好可以被 12(字符串的长度) 整除,所以说明有重复的子字符串(asdf)。 -代码如下:(这里使用了前缀表统一减一的实现方式) +C++代码如下:(这里使用了前缀表统一减一的实现方式) ```C++ class Solution { @@ -104,7 +102,7 @@ public: ``` -前缀表(不减一)的代码实现 +前缀表(不减一)的C++代码实现 ```C++ class Solution { @@ -139,12 +137,11 @@ public: # 拓展 -此时我们已经分享了三篇KMP的文章,首先是[字符串:KMP是时候上场了(一文读懂系列)](https://mp.weixin.qq.com/s/70OXnZ4Ez29CKRrUpVJmug)讲解KMP算法的基础理论,给出next数组究竟是如何来了,前缀表又是怎么回事,为什么要选择前缀表。 +在[字符串:KMP算法精讲](https://mp.weixin.qq.com/s/MoRBHbS4hQXn7LcPdmHmIg)中讲解KMP算法的基础理论,给出next数组究竟是如何来了,前缀表又是怎么回事,为什么要选择前缀表。 -然后通过[字符串:都来看看KMP的看家本领!](https://mp.weixin.qq.com/s/Gk9FKZ9_FSWLEkdGrkecyg)讲解一道KMP的经典题目,判断文本串里是否出现过模式串,这里涉及到构造next数组的代码实现,以及使用next数组完成模式串与文本串的匹配过程。 - -后来很多同学反馈说:搞不懂前后缀,什么又是最长相同前后缀(最长公共前后缀我认为这个用词不准确),以及为什么前缀表要统一减一(右移)呢,不减一行不行?针对这些问题,我在[字符串:听说你对KMP有这些疑问?](https://mp.weixin.qq.com/s/mqx6IM2AO4kLZwvXdPtEeQ)中又给出了详细的讲解。 +讲解一道KMP的经典题目,力扣:28. 实现 strStr(),判断文本串里是否出现过模式串,这里涉及到构造next数组的代码实现,以及使用next数组完成模式串与文本串的匹配过程。 +后来很多同学反馈说:搞不懂前后缀,什么又是最长相同前后缀(最长公共前后缀我认为这个用词不准确),以及为什么前缀表要统一减一(右移)呢,不减一行不行?针对这些问题,我在[字符串:KMP算法精讲](https://mp.weixin.qq.com/s/MoRBHbS4hQXn7LcPdmHmIg)给出了详细的讲解。 ## 其他语言版本 @@ -301,4 +298,4 @@ func repeatedSubstringPattern(s string) bool { * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) -
\ No newline at end of file +
diff --git a/problems/0494.目标和.md b/problems/0494.目标和.md index c917ed5c..a0e07a1f 100644 --- a/problems/0494.目标和.md +++ b/problems/0494.目标和.md @@ -158,7 +158,7 @@ dp[j] 表示:填满j(包括j)这么大容积的包,有dp[i]种方法 那么只需要搞到一个2(nums[i]),有dp[3]方法可以凑齐容量为3的背包,相应的就有多少种方法可以凑齐容量为5的背包。 -那么需要把 这些方法累加起来就可以了,dp[i] += dp[j - nums[i]] +那么需要把 这些方法累加起来就可以了,dp[j] += dp[j - nums[i]] 所以求组合类问题的公式,都是类似这种: diff --git a/problems/双指针总结.md b/problems/双指针总结.md index 13f2f174..b03d3ff2 100644 --- a/problems/双指针总结.md +++ b/problems/双指针总结.md @@ -12,7 +12,7 @@ # 数组篇 -在[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA)中,原地移除数组上的元素,我们说到了数组上的元素,不能真正的删除,只能覆盖。 +在[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/RMkulE4NIb6XsSX83ra-Ww)中,原地移除数组上的元素,我们说到了数组上的元素,不能真正的删除,只能覆盖。 一些同学可能会写出如下代码(伪代码): @@ -30,11 +30,11 @@ for (int i = 0; i < array.size(); i++) { # 字符串篇 -在[字符串:这道题目,使用库函数一行代码搞定](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA)中讲解了反转字符串,注意这里强调要原地反转,要不然就失去了题目的意义。 +在[字符串:这道题目,使用库函数一行代码搞定](https://mp.weixin.qq.com/s/_rNm66OJVl92gBDIbGpA3w)中讲解了反转字符串,注意这里强调要原地反转,要不然就失去了题目的意义。 使用双指针法,**定义两个指针(也可以说是索引下表),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。**,时间复杂度是O(n)。 -在[替换空格](https://mp.weixin.qq.com/s/t0A9C44zgM-RysAQV3GZpg) 中介绍使用双指针填充字符串的方法,如果想把这道题目做到极致,就不要只用额外的辅助空间了! +在[替换空格](https://mp.weixin.qq.com/s/69HNjR4apcRSAo_KyknPjA) 中介绍使用双指针填充字符串的方法,如果想把这道题目做到极致,就不要只用额外的辅助空间了! 思路就是**首先扩充数组到每个空格替换成"%20"之后的大小。然后双指针从后向前替换空格。** @@ -44,7 +44,7 @@ for (int i = 0; i < array.size(); i++) { **其实很多数组(字符串)填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。** -那么在[字符串:花式反转还不够!](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw)中,我们使用双指针法,用O(n)的时间复杂度完成字符串删除类的操作,因为题目要产出冗余空格。 +那么在[字符串:花式反转还不够!](https://mp.weixin.qq.com/s/4j6vPFHkFAXnQhmSkq2X9g)中,我们使用双指针法,用O(n)的时间复杂度完成字符串删除类的操作,因为题目要产出冗余空格。 **在删除冗余空格的过程中,如果不注意代码效率,很容易写成了O(n^2)的时间复杂度。其实使用双指针法O(n)就可以搞定。** @@ -54,19 +54,19 @@ for (int i = 0; i < array.size(); i++) { 翻转链表是现场面试,白纸写代码的好题,考察了候选者对链表以及指针的熟悉程度,而且代码也不长,适合在白纸上写。 -在[链表:听说过两天反转链表又写不出来了?](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg)中,讲如何使用双指针法来翻转链表,**只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表。** +在[链表:听说过两天反转链表又写不出来了?](https://mp.weixin.qq.com/s/ckEvIVGcNLfrz6OLOMoT0A)中,讲如何使用双指针法来翻转链表,**只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表。** 思路还是很简单的,代码也不长,但是想在白纸上一次性写出bugfree的代码,并不是容易的事情。 -在链表中求环,应该是双指针在链表里最经典的应用,在[链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA)中讲解了如何通过双指针判断是否有环,而且还要找到环的入口。 +在链表中求环,应该是双指针在链表里最经典的应用,在[链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/gt_VH3hQTqNxyWcl1ECSbQ)中讲解了如何通过双指针判断是否有环,而且还要找到环的入口。 **使用快慢指针(双指针法),分别定义 fast 和 slow指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇 ,说明这个链表有环。** -那么找到环的入口,其实需要点简单的数学推理,我在文章中把找环的入口清清楚楚的推理的一遍,如果对找环入口不够清楚的同学建议自己看一看[链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA)。 +那么找到环的入口,其实需要点简单的数学推理,我在文章中把找环的入口清清楚楚的推理的一遍,如果对找环入口不够清楚的同学建议自己看一看[链表:环找到了,那入口呢?](https://mp.weixin.qq.com/s/gt_VH3hQTqNxyWcl1ECSbQ)。 # N数之和篇 -在[哈希表:解决了两数之和,那么能解决三数之和么?](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)中,讲到使用哈希法可以解决1.两数之和的问题 +在[哈希表:解决了两数之和,那么能解决三数之和么?](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)中,讲到使用哈希法可以解决1.两数之和的问题 其实使用双指针也可以解决1.两数之和的问题,只不过1.两数之和求的是两个元素的下标,没法用双指针,如果改成求具体两个元素的数值就可以了,大家可以尝试用双指针做一个leetcode上两数之和的题目,就可以体会到我说的意思了。 @@ -82,7 +82,7 @@ for (int i = 0; i < array.size(); i++) { 只用双指针法时间复杂度为O(n^2),但比哈希法的O(n^2)效率高得多,哈希法在使用两层for循环的时候,能做的剪枝操作很有限。 -在[双指针法:一样的道理,能解决四数之和](https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g)中,讲到了四数之和,其实思路是一样的,**在三数之和的基础上再套一层for循环,依然是使用双指针法。** +在[双指针法:一样的道理,能解决四数之和](https://mp.weixin.qq.com/s/SBU3THi1Kv6Sar7htqCB2Q)中,讲到了四数之和,其实思路是一样的,**在三数之和的基础上再套一层for循环,依然是使用双指针法。** 对于三数之和使用双指针法就是将原本暴力O(n^3)的解法,降为O(n^2)的解法,四数之和的双指针解法就是将原本暴力O(n^4)的解法,降为O(n^3)的解法。 @@ -94,18 +94,6 @@ for (int i = 0; i < array.size(); i++) { 本文中一共介绍了leetcode上九道使用双指针解决问题的经典题目,除了链表一些题目一定要使用双指针,其他题目都是使用双指针来提高效率,一般是将O(n^2)的时间复杂度,降为O(n)。 建议大家可以把文中涉及到的题目在好好做一做,琢磨琢磨,基本对双指针法就不在话下了。 -## 其他语言版本 - - -Java: - - -Python: - - -Go: - - ----------------------- diff --git a/problems/字符串总结.md b/problems/字符串总结.md index 21fdc9bc..71be6422 100644 --- a/problems/字符串总结.md +++ b/problems/字符串总结.md @@ -43,9 +43,10 @@ for (int i = 0; i < a.size(); i++) { 所以想处理字符串,我们还是会定义一个string类型。 + # 要不要使用库函数 -在文章[字符串:这道题目,使用库函数一行代码搞定](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA)中强调了**打基础的时候,不要太迷恋于库函数。** +在文章[344.反转字符串](https://mp.weixin.qq.com/s/_rNm66OJVl92gBDIbGpA3w)中强调了**打基础的时候,不要太迷恋于库函数。** 甚至一些同学习惯于调用substr,split,reverse之类的库函数,却不知道其实现原理,也不知道其时间复杂度,这样实现出来的代码,如果在面试现场,面试官问:“分析其时间复杂度”的话,一定会一脸懵逼! @@ -56,15 +57,15 @@ for (int i = 0; i < a.size(); i++) { # 双指针法 -在[字符串:这道题目,使用库函数一行代码搞定](https://mp.weixin.qq.com/s/X02S61WCYiCEhaik6VUpFA) ,我们使用双指针法实现了反转字符串的操作,**双指针法在数组,链表和字符串中很常用。** +在[344.反转字符串](https://mp.weixin.qq.com/s/_rNm66OJVl92gBDIbGpA3w) ,我们使用双指针法实现了反转字符串的操作,**双指针法在数组,链表和字符串中很常用。** -接着在[字符串:替换空格](https://mp.weixin.qq.com/s/t0A9C44zgM-RysAQV3GZpg),同样还是使用双指针法在时间复杂度O(n)的情况下完成替换空格。 +接着在[字符串:替换空格](https://mp.weixin.qq.com/s/69HNjR4apcRSAo_KyknPjA),同样还是使用双指针法在时间复杂度O(n)的情况下完成替换空格。 **其实很多数组填充类的问题,都可以先预先给数组扩容带填充后的大小,然后在从后向前进行操作。** -那么针对数组删除操作的问题,其实在[数组:就移除个元素很难么?](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA)中就已经提到了使用双指针法进行移除操作。 +那么针对数组删除操作的问题,其实在[27. 移除元素](https://mp.weixin.qq.com/s/RMkulE4NIb6XsSX83ra-Ww)中就已经提到了使用双指针法进行移除操作。 -同样的道理在[字符串:花式反转还不够!](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw)中我们使用O(n)的时间复杂度,完成了删除冗余空格。 +同样的道理在[151.翻转字符串里的单词](https://mp.weixin.qq.com/s/4j6vPFHkFAXnQhmSkq2X9g)中我们使用O(n)的时间复杂度,完成了删除冗余空格。 一些同学会使用for循环里调用库函数erase来移除元素,这其实是O(n^2)的操作,因为erase就是O(n)的操作,所以这也是典型的不知道库函数的时间复杂度,上来就用的案例了。 @@ -72,7 +73,7 @@ for (int i = 0; i < a.size(); i++) { 在反转上还可以在加一些玩法,其实考察的是对代码的掌控能力。 -[字符串:简单的反转还不够!](https://mp.weixin.qq.com/s/XGSk1GyPWhfqj2g7Cb1Vgw)中,一些同学可能为了处理逻辑:每隔2k个字符的前k的字符,写了一堆逻辑代码或者再搞一个计数器,来统计2k,再统计前k个字符。 +[541. 反转字符串II](https://mp.weixin.qq.com/s/pzXt6PQ029y7bJ9YZB2mVQ)中,一些同学可能为了处理逻辑:每隔2k个字符的前k的字符,写了一堆逻辑代码或者再搞一个计数器,来统计2k,再统计前k个字符。 其实**当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章**。 @@ -80,34 +81,34 @@ for (int i = 0; i < a.size(); i++) { 因为要找的也就是每2 * k 区间的起点,这样写程序会高效很多。 -在[字符串:花式反转还不够!](https://mp.weixin.qq.com/s/X3qpi2v5RSp08mO-W5Vicw)中要求翻转字符串里的单词,这道题目可以说是综合考察了字符串的多种操作。是考察字符串的好题。 +在[151.翻转字符串里的单词](https://mp.weixin.qq.com/s/4j6vPFHkFAXnQhmSkq2X9g)中要求翻转字符串里的单词,这道题目可以说是综合考察了字符串的多种操作。是考察字符串的好题。 这道题目通过 **先整体反转再局部反转**,实现了反转字符串里的单词。 后来发现反转字符串还有一个牛逼的用处,就是达到左旋的效果。 -在[字符串:反转个字符串还有这个用处?](https://mp.weixin.qq.com/s/PmcdiWSmmccHAONzU0ScgQ)中,我们通过**先局部反转再整体反转**达到了左旋的效果。 +在[字符串:反转个字符串还有这个用处?](https://mp.weixin.qq.com/s/Px_L-RfT2b_jXKcNmccPsw)中,我们通过**先局部反转再整体反转**达到了左旋的效果。 # KMP KMP的主要思想是**当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。** -KMP的精髓所在就是前缀表,在[字符串:KMP是时候上场了(一文读懂系列)](https://mp.weixin.qq.com/s/70OXnZ4Ez29CKRrUpVJmug)中提到了,什么是KMP,什么是前缀表,以及为什么要用前缀表。 +KMP的精髓所在就是前缀表,在[KMP精讲](https://mp.weixin.qq.com/s/MoRBHbS4hQXn7LcPdmHmIg)中提到了,什么是KMP,什么是前缀表,以及为什么要用前缀表。 前缀表:起始位置到下表i之前(包括i)的子串中,有多大长度的相同前缀后缀。 那么使用KMP可以解决两类经典问题: -1. 匹配问题:[28. 实现 strStr()](https://mp.weixin.qq.com/s/Gk9FKZ9_FSWLEkdGrkecyg) -2. 重复子串问题:[459.重复的子字符串](https://mp.weixin.qq.com/s/lR2JPtsQSR2I_9yHbBmBuQ) +1. 匹配问题:[28. 实现 strStr()](https://mp.weixin.qq.com/s/MoRBHbS4hQXn7LcPdmHmIg) +2. 重复子串问题:[459.重复的子字符串](https://mp.weixin.qq.com/s/32Pve4j8IWvdgxYEZdTeFg) -在[字符串:听说你对KMP有这些疑问?](https://mp.weixin.qq.com/s/mqx6IM2AO4kLZwvXdPtEeQ) 强调了什么是前缀,什么是后缀,什么又是最长相等前后缀。 +再一次强调了什么是前缀,什么是后缀,什么又是最长相等前后缀。 前缀:指不包含最后一个字符的所有以第一个字符开头的连续子串。 后缀:指不包含第一个字符的所有以最后一个字符结尾的连续子串。 -然后**针对前缀表到底要不要减一,这其实是不同KMP实现的方式**,我们在[字符串:前缀表不右移,难道就写不出KMP了?](https://mp.weixin.qq.com/s/p3hXynQM2RRROK5c6X7xfw)中针对之前两个问题,分别给出了两个不同版本的的KMP实现。 +然后**针对前缀表到底要不要减一,这其实是不同KMP实现的方式**,我们在[KMP精讲](https://mp.weixin.qq.com/s/MoRBHbS4hQXn7LcPdmHmIg)中针对之前两个问题,分别给出了两个不同版本的的KMP实现。 其中主要**理解j=next[x]这一步最为关键!** @@ -123,18 +124,6 @@ KMP算法是字符串查找最重要的算法,但彻底理解KMP并不容易 -## 其他语言版本 - - -Java: - - -Python: - - -Go: - - ----------------------- From 5efc824e841ee5019c94f105cec9b29c01d69e3b Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Mon, 28 Jun 2021 15:22:47 +0800 Subject: [PATCH 081/110] Update --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f6b88d4..60aa4fd5 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ > 1. **介绍**:本项目是一套完整的刷题计划,旨在帮助大家少走弯路,循序渐进学算法,[关注作者](#关于作者) > 2. **PDF版本** : [「代码随想录」算法精讲 PDF 版本](https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ) 。 +> 3. **刷题顺序** : README已经将刷题顺序排好了,按照顺序一道一道刷就可以。 > 3. **学习社区** : 一起学习打卡/面试技巧/如何选择offer/大厂内推/职场规则/简历修改/技术分享/程序人生。欢迎加入[「代码随想录」学习社区](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) 。 > 4. **提交代码**:本项目统一使用C++语言进行讲解,但已经有Java、Python、Go、JavaScript等等多语言版本,感谢[这里的每一位贡献者](https://github.com/youngyangyang04/leetcode-master/graphs/contributors),如果你也想贡献代码点亮你的头像,[点击这里](https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A)了解提交代码的方式。 > 5. **转载须知** :以下所有文章皆为我([程序员Carl](https://github.com/youngyangyang04))的原创。引用本项目文章请注明出处,发现恶意抄袭或搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境! @@ -41,7 +42,7 @@ 对于刷题,我们都是想用最短的时间**按照循序渐进的难度顺序把经典题目都做一遍**,这样效率才是最高的! -所以我整理了leetcode刷题攻略:一个超级详细的刷题顺序,**每道题目都是我精心筛选,都是经典题目高频面试题**,大家只要按照这个顺序刷就可以了,**你没看错,就是题目顺序都排好了,文章顺序就是刷题顺序!挨个刷就可以,不用自己再去题海里选题了!** +所以我整理了leetcode刷题攻略:一个超级详细的刷题顺序,**每道题目都是我精心筛选,都是经典题目高频面试题**,大家只要按照这个顺序刷就可以了,**你没看错,README已经把题目顺序都排好了,文章顺序就是刷题顺序!挨个刷就可以,不用自己再去题海里选题了!** 而且每道题目我都写了的详细题解(图文并茂,难点配有视频),力扣上我的题解都是排在对应题目的首页,质量是有目共睹的。 From dc03975acdb47f6c5eaa0b2b3a47d119f8fe78f2 Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Tue, 29 Jun 2021 00:20:13 +0800 Subject: [PATCH 082/110] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=200098.=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=20go?= =?UTF-8?q?=E7=89=88=20=EF=BC=88=E5=A2=9E=E5=8A=A0=E4=B8=AD=E5=BA=8F?= =?UTF-8?q?=E9=81=8D=E5=8E=86=E8=A7=A3=E9=A2=98=E6=B3=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加中序遍历解题法 --- problems/0098.验证二叉搜索树.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/problems/0098.验证二叉搜索树.md b/problems/0098.验证二叉搜索树.md index e38c5ade..b93d8cd5 100644 --- a/problems/0098.验证二叉搜索树.md +++ b/problems/0098.验证二叉搜索树.md @@ -376,6 +376,28 @@ func isBST(root *TreeNode, min, max int) bool { return isBST(root.Left, min, root.Val) && isBST(root.Right, root.Val, max) } ``` +```go +// 中序遍历解法 +func isValidBST(root *TreeNode) bool { + // 保存上一个指针 + var prev *TreeNode + var travel func(node *TreeNode) bool + travel = func(node *TreeNode) bool { + if node == nil { + return true + } + leftRes := travel(node.Left) + // 当前值小于等于前一个节点的值,返回false + if prev != nil && node.Val <= prev.Val { + return false + } + prev = node + rightRes := travel(node.Right) + return leftRes && rightRes + } + return travel(root) +} +``` JavaScript版本 From f75acf5b896d78b5b124b7c6b3713a75a4206acc Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Tue, 29 Jun 2021 14:22:56 +0800 Subject: [PATCH 083/110] =?UTF-8?q?0-1=E8=83=8C=E5=8C=85javascript?= =?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/背包理论基础01背包-1.md | 46 ++++++++++++++++++++++++ problems/背包理论基础01背包-2.md | 23 ++++++++++++ 2 files changed, 69 insertions(+) diff --git a/problems/背包理论基础01背包-1.md b/problems/背包理论基础01背包-1.md index 3cbfb347..85bc7e42 100644 --- a/problems/背包理论基础01背包-1.md +++ b/problems/背包理论基础01背包-1.md @@ -380,6 +380,52 @@ func main() { } ``` +javaScript: + +```js +function testWeightBagProblem (wight, value, size) { + const len = wight.length, + dp = Array.from({length: len + 1}).map( + () => Array(size + 1).fill(0) + ); + + for(let i = 1; i <= len; i++) { + for(let j = 0; j <= size; j++) { + if(wight[i - 1] <= j) { + dp[i][j] = Math.max( + dp[i - 1][j], + value[i - 1] + dp[i - 1][j - wight[i - 1]] + ) + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + +// console.table(dp); + + return dp[len][size]; +} + +function testWeightBagProblem2 (wight, value, size) { + const len = wight.length, + dp = Array(size + 1).fill(0); + for(let i = 1; i <= len; i++) { + for(let j = size; j >= wight[i - 1]; j--) { + dp[j] = Math.max(dp[j], value[i - 1] + dp[j - wight[i - 1]]); + } + } + return dp[size]; +} + + +function test () { + console.log(testWeightBagProblem([1, 3, 4, 5], [15, 20, 30, 55], 6)); +} + +test(); +``` + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) diff --git a/problems/背包理论基础01背包-2.md b/problems/背包理论基础01背包-2.md index 48275908..36856cd6 100644 --- a/problems/背包理论基础01背包-2.md +++ b/problems/背包理论基础01背包-2.md @@ -294,6 +294,29 @@ func main() { } ``` +javaScript: + +```js + +function testWeightBagProblem(wight, value, size) { + const len = wight.length, + dp = Array(size + 1).fill(0); + for(let i = 1; i <= len; i++) { + for(let j = size; j >= wight[i - 1]; j--) { + dp[j] = Math.max(dp[j], value[i - 1] + dp[j - wight[i - 1]]); + } + } + return dp[size]; +} + + +function test () { + console.log(testWeightBagProblem([1, 3, 4, 5], [15, 20, 30, 55], 6)); +} + +test(); +``` + ----------------------- From 204c0c5e959c76c035bf35c704c91f388e8d94aa Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Tue, 29 Jun 2021 14:27:49 +0800 Subject: [PATCH 084/110] =?UTF-8?q?416.=20=E5=88=86=E5=89=B2=E7=AD=89?= =?UTF-8?q?=E5=92=8C=E5=AD=90=E9=9B=86=20javascript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0416.分割等和子集.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0416.分割等和子集.md b/problems/0416.分割等和子集.md index 0d306c74..75c665cd 100644 --- a/problems/0416.分割等和子集.md +++ b/problems/0416.分割等和子集.md @@ -240,6 +240,26 @@ class Solution: Go: +javaScript: + +```js +var canPartition = function(nums) { + const sum = (nums.reduce((p, v) => p + v)); + if (sum & 1) return false; + const dp = Array(sum / 2 + 1).fill(0); + for(let i = 0; i < nums.length; i++) { + for(let j = sum / 2; j >= nums[i]; j--) { + dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]); + if (dp[j] === sum / 2) { + return true; + } + } + } + return dp[sum / 2] === sum / 2; +}; +``` + + ----------------------- From abc55ed100b031a00383038a3b7e2ee91c667b7a Mon Sep 17 00:00:00 2001 From: KailokFung Date: Tue, 29 Jun 2021 16:50:34 +0800 Subject: [PATCH 085/110] =?UTF-8?q?feat(0226):=20=E6=96=B0=E5=A2=9Ejava=20?= =?UTF-8?q?bfs=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0226.翻转二叉树.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/problems/0226.翻转二叉树.md b/problems/0226.翻转二叉树.md index 2b628ec4..bb0d6d34 100644 --- a/problems/0226.翻转二叉树.md +++ b/problems/0226.翻转二叉树.md @@ -205,6 +205,7 @@ public: Java: ```Java +//DFS递归 class Solution { /** * 前后序遍历都可以 @@ -226,6 +227,31 @@ class Solution { root.right = tmp; } } + +//BFS +class Solution { + public TreeNode invertTree(TreeNode root) { + if (root == null) {return null;} + ArrayDeque deque = new ArrayDeque<>(); + deque.offer(root); + while (!deque.isEmpty()) { + int size = deque.size(); + while (size-- > 0) { + TreeNode node = deque.poll(); + swap(node); + if (node.left != null) {deque.offer(node.left);} + if (node.right != null) {deque.offer(node.right);} + } + } + return root; + } + + public void swap(TreeNode root) { + TreeNode temp = root.left; + root.left = root.right; + root.right = temp; + } +} ``` Python: From 011b0cc6fdd8058b738984066f075b37eb8245fc Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Tue, 29 Jun 2021 21:55:02 +0800 Subject: [PATCH 086/110] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=200530.=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E7=9A=84=E6=9C=80=E5=B0=8F?= =?UTF-8?q?=E7=BB=9D=E5=AF=B9=E5=B7=AE=20go=E7=89=88=20=EF=BC=88=E4=B8=AD?= =?UTF-8?q?=E5=BA=8F=E9=81=8D=E5=8E=86=E7=9A=84=E5=90=8C=E6=97=B6=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=E6=9C=80=E5=B0=8F=E5=80=BC=EF=BC=8C=E4=B8=8D=E7=94=A8?= =?UTF-8?q?=E9=A2=9D=E5=A4=96=E7=9A=84=E5=AD=98=E5=82=A8=E7=A9=BA=E9=97=B4?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 中序遍历的同时计算最小值,不用额外的存储空间 --- .../0530.二叉搜索树的最小绝对差.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/0530.二叉搜索树的最小绝对差.md b/problems/0530.二叉搜索树的最小绝对差.md index 8fa756bc..47b2b434 100644 --- a/problems/0530.二叉搜索树的最小绝对差.md +++ b/problems/0530.二叉搜索树的最小绝对差.md @@ -255,6 +255,29 @@ func findMIn(root *TreeNode,res *[]int){ findMIn(root.Right,res) } ``` +```go +// 中序遍历的同时计算最小值 +func getMinimumDifference(root *TreeNode) int { + // 保留前一个节点的指针 + var prev *TreeNode + // 定义一个比较大的值 + min := math.MaxInt64 + var travel func(node *TreeNode) + travel = func(node *TreeNode) { + if node == nil { + return + } + travel(node.Left) + if prev != nil && node.Val - prev.Val < min { + min = node.Val - prev.Val + } + prev = node + travel(node.Right) + } + travel(root) + return min +} +``` JavaScript版本 From f85d1c1a3792d848f42f7fda03fbab5fd712d29c Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Tue, 29 Jun 2021 22:41:40 +0800 Subject: [PATCH 087/110] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200501.=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E4=B8=AD=E7=9A=84=E4=BC=97?= =?UTF-8?q?=E6=95=B0=20go=E7=89=88=EF=BC=88=E5=8E=9F=E5=85=88=E7=9A=84?= =?UTF-8?q?=E5=86=99=E6=B3=95=E6=9C=89=E9=97=AE=E9=A2=98=EF=BC=8C=E8=BF=87?= =?UTF-8?q?=E4=B8=8D=E4=BA=86leetcode=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原先的写法有问题,过不了leetcode,更新正确的解法 --- problems/0501.二叉搜索树中的众数.md | 64 +++++++++----------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/problems/0501.二叉搜索树中的众数.md b/problems/0501.二叉搜索树中的众数.md index f4b239c3..d2326d67 100644 --- a/problems/0501.二叉搜索树中的众数.md +++ b/problems/0501.二叉搜索树中的众数.md @@ -474,7 +474,7 @@ func traversal(root *TreeNode,history map[int]int){ } ``` -计数法BSL(此代码在执行代码里能执行,但提交后报错,不知为何,思路是对的) +计数法,不使用额外空间,利用二叉树性质,中序遍历 ```go /** @@ -485,41 +485,35 @@ func traversal(root *TreeNode,history map[int]int){ * Right *TreeNode * } */ - var count,maxCount int //统计计数 -func findMode(root *TreeNode) []int { - var result []int - var pre *TreeNode //前指针 - if root.Left==nil&&root.Right==nil{ - result=append(result,root.Val) - return result + func findMode(root *TreeNode) []int { + res := make([]int, 0) + count := 1 + max := 1 + var prev *TreeNode + var travel func(node *TreeNode) + travel = func(node *TreeNode) { + if node == nil { + return + } + travel(node.Left) + if prev != nil && prev.Val == node.Val { + count++ + } else { + count = 1 + } + if count >= max { + if count > max && len(res) > 0 { + res = []int{node.Val} + } else { + res = append(res, node.Val) + } + max = count + } + prev = node + travel(node.Right) } - traversal(root,&result,pre) - return result -} -func traversal(root *TreeNode,result *[]int,pre *TreeNode){//遍历统计 - //如果BSL中序遍历相邻的两个节点值相同,则统计频率;如果不相同,依据BSL中序遍历排好序的性质,重新计数 - if pre==nil{ - count=1 - }else if pre.Val==root.Val{ - count++ - }else { - count=1 - } - //如果统计的频率等于最大频率,则加入结果集;如果统计的频率大于最大频率,更新最大频率且重新将结果加入新的结果集中 - if count==maxCount{ - *result=append(*result,root.Val) - }else if count>maxCount{ - maxCount=count//重新赋值maxCount - *result=[]int{}//清空result中的内容 - *result=append(*result,root.Val) - } - pre=root//保存上一个的节点 - if root.Left!=nil{ - traversal(root.Left,result,pre) - } - if root.Right!=nil{ - traversal(root.Right,result,pre) - } + travel(root) + return res } ``` From 383c9cb1705b6a0760a5208ff879a1cf56c35eb8 Mon Sep 17 00:00:00 2001 From: daniel1n <54945782+daniel1n@users.noreply.github.com> Date: Thu, 1 Jul 2021 18:25:51 +0800 Subject: [PATCH 088/110] =?UTF-8?q?Update=200501.=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=91=E4=B8=AD=E7=9A=84=E4=BC=97=E6=95=B0?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit java的暴力解法(map记录频率) --- problems/0501.二叉搜索树中的众数.md | 34 ++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/problems/0501.二叉搜索树中的众数.md b/problems/0501.二叉搜索树中的众数.md index d2326d67..66be790f 100644 --- a/problems/0501.二叉搜索树中的众数.md +++ b/problems/0501.二叉搜索树中的众数.md @@ -345,6 +345,40 @@ public: Java: +暴力法 +```java +class Solution { + public int[] findMode(FindModeInBinarySearchTree.TreeNode root) { + Map map = new HashMap<>(); + List list = new ArrayList<>(); + if (root == null) return list.stream().mapToInt(Integer::intValue).toArray(); + // 获得频率 Map + searchBST(root, map); + List> mapList = map.entrySet().stream() + .sorted((c1, c2) -> c2.getValue().compareTo(c1.getValue())) + .collect(Collectors.toList()); + list.add(mapList.get(0).getKey()); + // 把频率最高的加入 list + for (int i = 1; i < mapList.size(); i++) { + if (mapList.get(i).getValue() == mapList.get(i - 1).getValue()) { + list.add(mapList.get(i).getKey()); + } else { + break; + } + } + return list.stream().mapToInt(Integer::intValue).toArray(); + } + + void searchBST(FindModeInBinarySearchTree.TreeNode curr, Map map) { + if (curr == null) return; + map.put(curr.val, map.getOrDefault(curr.val, 0) + 1); + searchBST(curr.left, map); + searchBST(curr.right, map); + } + +} +``` + ```Java class Solution { ArrayList resList; From d5e128e20921517085aa199e3a0667e8c2c252de Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Thu, 1 Jul 2021 23:13:32 +0800 Subject: [PATCH 089/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200701.=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E4=B8=AD=E7=9A=84=E6=8F=92?= =?UTF-8?q?=E5=85=A5=E6=93=8D=E4=BD=9C=20go=E7=89=88=EF=BC=88=E8=BF=AD?= =?UTF-8?q?=E4=BB=A3=E6=B3=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0701.二叉搜索树中的插入操作.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/problems/0701.二叉搜索树中的插入操作.md b/problems/0701.二叉搜索树中的插入操作.md index 794e0ae2..61027453 100644 --- a/problems/0701.二叉搜索树中的插入操作.md +++ b/problems/0701.二叉搜索树中的插入操作.md @@ -271,6 +271,9 @@ class Solution: Go: + +递归法 + ```Go func insertIntoBST(root *TreeNode, val int) *TreeNode { if root == nil { @@ -285,6 +288,31 @@ func insertIntoBST(root *TreeNode, val int) *TreeNode { return root } ``` +迭代法 +```go +func insertIntoBST(root *TreeNode, val int) *TreeNode { + if root == nil { + return &TreeNode{Val:val} + } + node := root + var pnode *TreeNode + for node != nil { + if val > node.Val { + pnode = node + node = node.Right + } else { + pnode = node + node = node.Left + } + } + if val > pnode.Val { + pnode.Right = &TreeNode{Val: val} + } else { + pnode.Left = &TreeNode{Val: val} + } + return root +} +``` JavaScript版本 From c47bafa412965064846d82be391a0ba851ae4d20 Mon Sep 17 00:00:00 2001 From: amdrose <927410375@qq.com> Date: Fri, 2 Jul 2021 01:47:13 +0800 Subject: [PATCH 090/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200001.=E4=B8=A4?= =?UTF-8?q?=E6=95=B0=E4=B9=8B=E5=92=8C.md=20php=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0001.两数之和.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index 31a808b0..5be94996 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -187,7 +187,23 @@ var twoSum = function (nums, target) { }; ``` +php +```php +function twoSum(array $nums, int $target): array +{ + for ($i = 0; $i < count($nums);$i++) { + // 计算剩下的数 + $residue = $target - $nums[$i]; + // 匹配的index,有则返回index, 无则返回false + $match_index = array_search($residue, $nums); + if ($match_index !== false && $match_index != $i) { + return array($i, $match_index); + } + } + return []; +} +``` ----------------------- From 46a4b5161cd5a777d6eb81547f2b25a7279248a5 Mon Sep 17 00:00:00 2001 From: amdrose <927410375@qq.com> Date: Fri, 2 Jul 2021 01:54:55 +0800 Subject: [PATCH 091/110] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200015.=E4=B8=89?= =?UTF-8?q?=E6=95=B0=E4=B9=8B=E5=92=8C.md=20php=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0015.三数之和.md | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md index 5b77a170..36abb58c 100644 --- a/problems/0015.三数之和.md +++ b/problems/0015.三数之和.md @@ -354,6 +354,47 @@ def is_valid(strs) end ``` +php: + +```php +function threeSum(array $nums): array +{ + $result = []; + $length = count($nums); + if ($length < 3) { + return []; + } + sort($nums); + for ($i = 0; $i < $length; $i++) { + // 如果大于0结束 + if ($nums[$i] > 0) break; + // 去重 + if ($i > 0 && $nums[$i] == $nums[$i - 1]) continue; + $left = $i + 1; + $right = $length - 1; + // 比较 + while ($left < $right) { + $sum = $nums[$i] + $nums[$left] + $nums[$right]; + if ($sum < 0) { + $left++; + } elseif ($sum > 0) { + $right--; + } else { + array_push($result, [$nums[$i], $nums[$left], $nums[$right]]); + while ($left < $right && $nums[$left] == $nums[$left + 1]) $left++; + while ($left < $right && $nums[$right - 1] == $nums[$right]) $right--; + $left++; + $right--; + } + } + } + + return $result; +} +``` + + + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) From 759f05328dfabb652a034b6400d2a162edc91679 Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Fri, 2 Jul 2021 07:51:09 +0800 Subject: [PATCH 092/110] =?UTF-8?q?=E6=95=B4=E6=95=B0=E6=8B=86=E5=88=86.md?= =?UTF-8?q?=20Javascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 16 ---------------- problems/0343.整数拆分.md | 13 +++++++++++++ 2 files changed, 13 insertions(+), 16 deletions(-) delete mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 2ca27187..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - // 使用 IntelliSense 了解相关属性。 - // 悬停以查看现有属性的描述。 - // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - - { - "type": "pwa-chrome", - "request": "launch", - "name": "Launch Chrome against localhost", - "url": "http://localhost:8080", - "webRoot": "${workspaceFolder}" - } - ] -} \ No newline at end of file diff --git a/problems/0343.整数拆分.md b/problems/0343.整数拆分.md index cf60575f..7b0dbd0f 100644 --- a/problems/0343.整数拆分.md +++ b/problems/0343.整数拆分.md @@ -225,7 +225,20 @@ class Solution: Go: +Javascript: +```Javascript +var integerBreak = function(n) { + let dp = new Array(n + 1).fill(0) + dp[2] = 1 + for(let i = 3; i <= n; i++) { + for(let j = 1; j < i; j++) { + dp[i] = Math.max(dp[i], dp[i - j] * j, (i - j) * j) + } + } + return dp[n] +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From 6360e80430bec5f648bf242ef1a2871a938d7189 Mon Sep 17 00:00:00 2001 From: hengzzha <80679845+hengzzha@users.noreply.github.com> Date: Fri, 2 Jul 2021 15:20:36 +0800 Subject: [PATCH 093/110] =?UTF-8?q?Update=20=E5=8A=A8=E6=80=81=E8=A7=84?= =?UTF-8?q?=E5=88=92-=E8=82=A1=E7=A5=A8=E9=97=AE=E9=A2=98=E6=80=BB?= =?UTF-8?q?=E7=BB=93=E7=AF=87.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/动态规划-股票问题总结篇.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/problems/动态规划-股票问题总结篇.md b/problems/动态规划-股票问题总结篇.md index cac77b65..d22132c0 100644 --- a/problems/动态规划-股票问题总结篇.md +++ b/problems/动态规划-股票问题总结篇.md @@ -381,6 +381,12 @@ dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]); dp[i][2] = dp[i - 1][0] + prices[i]; dp[i][3] = dp[i - 1][2]; ``` +```C++ +dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3]- prices[i], dp[i - 1][1]) - prices[i]; +dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]); +dp[i][2] = dp[i - 1][0] + prices[i]; +dp[i][3] = dp[i - 1][2]; +``` 整体代码如下: From 4d64b1fe75c43d2cb8ef66ca9dfa52c633b55c2f Mon Sep 17 00:00:00 2001 From: daniel1n <54945782+daniel1n@users.noreply.github.com> Date: Fri, 2 Jul 2021 15:41:43 +0800 Subject: [PATCH 094/110] =?UTF-8?q?Update=200108.=E5=B0=86=E6=9C=89?= =?UTF-8?q?=E5=BA=8F=E6=95=B0=E7=BB=84=E8=BD=AC=E6=8D=A2=E4=B8=BA=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新java的 递归和迭代 --- ...将有序数组转换为二叉搜索树.md | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/problems/0108.将有序数组转换为二叉搜索树.md b/problems/0108.将有序数组转换为二叉搜索树.md index b8861b24..87b11ed4 100644 --- a/problems/0108.将有序数组转换为二叉搜索树.md +++ b/problems/0108.将有序数组转换为二叉搜索树.md @@ -209,6 +209,8 @@ public: Java: + +递归: 左闭右开 [left,right) ```Java class Solution { public TreeNode sortedArrayToBST(int[] nums) { @@ -232,6 +234,75 @@ class Solution { ``` +递归: 左闭右闭 [left,right] +```java +class Solution { + public TreeNode sortedArrayToBST(int[] nums) { + TreeNode root = traversal(nums, 0, nums.length - 1); + return root; + } + + // 左闭右闭区间[left, right) + private TreeNode traversal(int[] nums, int left, int right) { + if (left > right) return null; + + int mid = left + ((right - left) >> 1); + TreeNode root = new TreeNode(nums[mid]); + root.left = traversal(nums, left, mid - 1); + root.right = traversal(nums, mid + 1, right); + return root; + } +} +``` +迭代: 左闭右闭 [left,right] +```java +class Solution { + public TreeNode sortedArrayToBST(int[] nums) { + if (nums.length == 0) return null; + + //根节点初始化 + TreeNode root = new TreeNode(-1); + Queue nodeQueue = new LinkedList<>(); + Queue leftQueue = new LinkedList<>(); + Queue rightQueue = new LinkedList<>(); + + // 根节点入队列 + nodeQueue.offer(root); + // 0为左区间下表初始位置 + leftQueue.offer(0); + // nums.size() - 1为右区间下表初始位置 + rightQueue.offer(nums.length - 1); + + while (!nodeQueue.isEmpty()) { + TreeNode currNode = nodeQueue.poll(); + int left = leftQueue.poll(); + int right = rightQueue.poll(); + int mid = left + ((right - left) >> 1); + + // 将mid对应的元素给中间节点 + currNode.val = nums[mid]; + + // 处理左区间 + if (left <= mid - 1) { + currNode.left = new TreeNode(-1); + nodeQueue.offer(currNode.left); + leftQueue.offer(left); + rightQueue.offer(mid - 1); + } + + // 处理右区间 + if (right >= mid + 1) { + currNode.right = new TreeNode(-1); + nodeQueue.offer(currNode.right); + leftQueue.offer(mid + 1); + rightQueue.offer(right); + } + } + return root; + } +} +``` + Python: ```python3 # Definition for a binary tree node. From 6f7a2545b6a52070450b565a136b9dbba586135c Mon Sep 17 00:00:00 2001 From: Jijie LIU Date: Fri, 2 Jul 2021 15:44:32 +0200 Subject: [PATCH 095/110] =?UTF-8?q?update115:=20=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E4=B8=80=E7=BB=B4dp=E6=95=B0=E7=BB=84=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E5=89=AA=E6=9E=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0115.不同的子序列.md | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/problems/0115.不同的子序列.md b/problems/0115.不同的子序列.md index d3bc6d97..62af9d0f 100644 --- a/problems/0115.不同的子序列.md +++ b/problems/0115.不同的子序列.md @@ -186,6 +186,40 @@ class Solution: return dp[-1][-1] ``` +Python3: +```python +class SolutionDP2: + """ + 既然dp[i]只用到dp[i - 1]的状态, + 我们可以通过缓存dp[i - 1]的状态来对dp进行压缩, + 减少空间复杂度。 + (原理等同同于滚动数组) + """ + + def numDistinct(self, s: str, t: str) -> int: + n1, n2 = len(s), len(t) + if n1 < n2: + return 0 + + dp = [0 for _ in range(n2 + 1)] + dp[0] = 1 + + for i in range(1, n1 + 1): + # 必须深拷贝 + # 不然prev[i]和dp[i]是同一个地址的引用 + prev = dp.copy() + # 剪枝,保证s的长度大于等于t + # 因为对于任意i,i > n1, dp[i] = 0 + # 没必要跟新状态。 + end = i if i < n2 else n2 + for j in range(1, end + 1): + if s[i - 1] == t[j - 1]: + dp[j] = prev[j - 1] + prev[j] + else: + dp[j] = prev[j] + return dp[-1] +``` + Go: From 891bf6a7eb92cb54eec4fa1d4a7ee0fcd1448fdb Mon Sep 17 00:00:00 2001 From: "xeniaxie(xl)" Date: Sat, 3 Jul 2021 16:10:02 +0800 Subject: [PATCH 096/110] =?UTF-8?q?669=E4=BF=AE=E5=89=AA=E4=BA=8C=E5=8F=89?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=91JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0669.修剪二叉搜索树.md | 53 ++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/problems/0669.修剪二叉搜索树.md b/problems/0669.修剪二叉搜索树.md index 06d99b9d..e20c3cea 100644 --- a/problems/0669.修剪二叉搜索树.md +++ b/problems/0669.修剪二叉搜索树.md @@ -289,6 +289,59 @@ Go: +JavaScript版本: +迭代: +```js +var trimBST = function(root, low, high) { + if(root === null) { + return null; + } + while(root !==null &&(root.valhigh)) { + if(root.valhigh) { + cur.right = cur.right.left; + } + cur = cur.right; + } + return root; +}; +``` + +递归: +```js +var trimBST = function (root,low,high) { + if(root === null) { + return null; + } + if(root.valhigh) { + let left = trimBST(root.left,low,high); + return left; + } + root.left = trimBST(root.left,low,high); + root.right = trimBST(root.right,low,high); + return root; + } +``` + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From 59403e05819e659dd3a0566656774bc6dd48846e Mon Sep 17 00:00:00 2001 From: KailokFung Date: Sat, 3 Jul 2021 16:14:10 +0800 Subject: [PATCH 097/110] =?UTF-8?q?feat(0257):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=B8=A4=E7=A7=8Djava=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0257.二叉树的所有路径.md | 49 ++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/problems/0257.二叉树的所有路径.md b/problems/0257.二叉树的所有路径.md index d5a0478e..ce596396 100644 --- a/problems/0257.二叉树的所有路径.md +++ b/problems/0257.二叉树的所有路径.md @@ -283,6 +283,7 @@ public: Java: ```Java +//解法一 class Solution { /** * 递归法 @@ -321,6 +322,52 @@ class Solution { } } +//解法二(常规前序遍历,不用回溯),更容易理解 +class Solution { + public List binaryTreePaths(TreeNode root) { + List res = new ArrayList<>(); + helper(root, new StringBuilder(), res); + return res; + } + + public void helper(TreeNode root, StringBuilder sb, List res) { + if (root == null) {return;} + // 遇到叶子结点就放入当前路径到res集合中 + if (root.left == null && root.right ==null) { + sb.append(root.val); + res.add(sb.toString()); + // 记得结束当前方法 + return; + } + helper(root.left,new StringBuilder(sb).append(root.val + "->"),res); + helper(root.right,new StringBuilder(sb).append(root.val + "->"),res); + } +} + +//针对解法二优化,思路本质是一样的 +class Solution { + public List binaryTreePaths(TreeNode root) { + List res = new ArrayList<>(); + helper(root, "", res); + return res; + } + + public void helper(TreeNode root, String path, List res) { + if (root == null) {return;} + // 由原始解法二可以知道,root的值肯定会下面某一个条件加入到path中,那么干脆直接在这一步加入即可 + StringBuilder sb = new StringBuilder(path); + sb.append(root.val); + if (root.left == null && root.right ==null) { + res.add(sb.toString()); + }else{ + // 如果是非叶子结点则还需要跟上一个 “->” + sb.append("->"); + helper(root.left,sb.toString(),res); + helper(root.right,sb.toString(),res); + } + } +} + ``` Python: @@ -350,7 +397,7 @@ class Solution: ``` Go: - + ```go func binaryTreePaths(root *TreeNode) []string { res := make([]string, 0) From 57326a9bfd63f0c97be66ee9d220b76015a27030 Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Sat, 3 Jul 2021 17:24:49 +0800 Subject: [PATCH 098/110] Update --- README.md | 2 + problems/0020.有效的括号.md | 53 ++++--------------- problems/0225.用队列实现栈.md | 29 +++++----- ...除字符串中的所有相邻重复项.md | 13 +++-- 4 files changed, 35 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 60aa4fd5..2c462a52 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,8 @@ * 编程语言 * [C++面试&C++学习指南知识点整理](https://github.com/youngyangyang04/TechCPP) +* 项目 + * [基于跳表的轻量级KV存储引擎](https://github.com/youngyangyang04/Skiplist-CPP) * 编程素养 * [看了这么多代码,谈一谈代码风格!](./problems/前序/代码风格.md) diff --git a/problems/0020.有效的括号.md b/problems/0020.有效的括号.md index dae84354..178bc6f8 100644 --- a/problems/0020.有效的括号.md +++ b/problems/0020.有效的括号.md @@ -22,24 +22,24 @@ https://leetcode-cn.com/problems/valid-parentheses/ * 注意空字符串可被认为是有效字符串。 示例 1: -输入: "()" -输出: true +* 输入: "()" +* 输出: true 示例 2: -输入: "()[]{}" -输出: true +* 输入: "()[]{}" +* 输出: true 示例 3: -输入: "(]" -输出: false +* 输入: "(]" +* 输出: false 示例 4: -输入: "([)]" -输出: false +* 输入: "([)]" +* 输出: false 示例 5: -输入: "{[]}" -输出: true +* 输入: "{[]}" +* 输出: true # 思路 @@ -90,7 +90,7 @@ cd a/b/c/../../ 动画如下: -![20.有效括号](https://code-thinking.cdn.bcebos.com/gifs/20.%E6%9C%89%E6%95%88%E6%8B%AC%E5%8F%B7.gif) +![20.有效括号](https://code-thinking.cdn.bcebos.com/gifs/20.有效括号.gif) 第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false @@ -130,10 +130,6 @@ public: 技巧性的东西没有固定的学习方法,还是要多看多练,自己总灵活运用了。 - - - - ## 其他语言版本 @@ -162,33 +158,6 @@ class Solution { return deque.isEmpty(); } } -// 方法2 -class Solution { - public boolean isValid(String s) { - - Stack stack = new Stack<>(); - Map map = new HashMap() { - { - put('}', '{'); - put(']', '['); - put(')', '('); - } - }; - - for (Character c : s.toCharArray()) { // 顺序读取字符 - if (!stack.isEmpty() && map.containsKey(c)) { // 是右括号 && 栈不为空 - if (stack.peek() == map.get(c)) { // 取其对应的左括号直接和栈顶比 - stack.pop(); // 相同则抵消,出栈 - } else { - return false; // 不同则直接返回 - } - } else { - stack.push(c); // 左括号,直接入栈 - } - } - return stack.isEmpty(); // 看左右是否抵消完 - } -} ``` Python: diff --git a/problems/0225.用队列实现栈.md b/problems/0225.用队列实现栈.md index 055c2e3d..85b981e5 100644 --- a/problems/0225.用队列实现栈.md +++ b/problems/0225.用队列实现栈.md @@ -34,7 +34,7 @@ https://leetcode-cn.com/problems/implement-stack-using-queues/ 有的同学可能疑惑这种题目有什么实际工程意义,**其实很多算法题目主要是对知识点的考察和教学意义远大于其工程实践的意义,所以面试题也是这样!** -刚刚做过[栈与队列:我用栈来实现队列怎么样?](https://mp.weixin.qq.com/s/P6tupDwRFi6Ay-L7DT4NVg)的同学可能依然想着用一个输入队列,一个输出队列,就可以模拟栈的功能,仔细想一下还真不行! +刚刚做过[栈与队列:我用栈来实现队列怎么样?](https://mp.weixin.qq.com/s/Cj6R0qu8rFA7Et9V_ZMjCA)的同学可能依然想着用一个输入队列,一个输出队列,就可以模拟栈的功能,仔细想一下还真不行! **队列模拟栈,其实一个队列就够了**,那么我们先说一说两个队列来实现栈的思路。 @@ -46,18 +46,21 @@ https://leetcode-cn.com/problems/implement-stack-using-queues/ 如下面动画所示,**用两个队列que1和que2实现队列的功能,que2其实完全就是一个备份的作用**,把que1最后面的元素以外的元素都备份到que2,然后弹出最后面的元素,再把其他元素从que2导回que1。 -模拟的队列执行语句如下: -queue.push(1); -queue.push(2); -queue.pop(); // 注意弹出的操作 -queue.push(3); -queue.push(4); -queue.pop(); // 注意弹出的操作 -queue.pop(); -queue.pop(); -queue.empty(); +模拟的队列执行语句如下: -![225.用队列实现栈](https://code-thinking.cdn.bcebos.com/gifs/225.%E7%94%A8%E9%98%9F%E5%88%97%E5%AE%9E%E7%8E%B0%E6%A0%88.gif) +``` +queue.push(1); +queue.push(2); +queue.pop(); // 注意弹出的操作 +queue.push(3); +queue.push(4); +queue.pop(); // 注意弹出的操作 +queue.pop(); +queue.pop(); +queue.empty(); +``` + +![225.用队列实现栈](https://code-thinking.cdn.bcebos.com/gifs/225.用队列实现栈.gif) 详细如代码注释所示: @@ -152,7 +155,7 @@ public: }; ``` -## 其他语言版本 +# 其他语言版本 Java: diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 760a0946..c6a49376 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -23,15 +23,14 @@ https://leetcode-cn.com/problems/remove-all-adjacent-duplicates-in-string/ 示例: -输入:"abbaca" -输出:"ca" -解释: -例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。 +* 输入:"abbaca" +* 输出:"ca" +* 解释:例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。   提示: -1 <= S.length <= 20000 -S 仅由小写英文字母组成。 +* 1 <= S.length <= 20000 +* S 仅由小写英文字母组成。 # 思路 @@ -64,7 +63,7 @@ S 仅由小写英文字母组成。 如动画所示: -![1047.删除字符串中的所有相邻重复项](https://code-thinking.cdn.bcebos.com/gifs/1047.%E5%88%A0%E9%99%A4%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E6%89%80%E6%9C%89%E7%9B%B8%E9%82%BB%E9%87%8D%E5%A4%8D%E9%A1%B9.gif) +![1047.删除字符串中的所有相邻重复项](https://code-thinking.cdn.bcebos.com/gifs/1047.删除字符串中的所有相邻重复项.gif) 从栈中弹出剩余元素,此时是字符串ac,因为从栈里弹出的元素是倒叙的,所以在对字符串进行反转一下,就得到了最终的结果。 From abac363863b792ebdd39271ac27badd8ba2bc16b Mon Sep 17 00:00:00 2001 From: liuwei20210312 <1970650352@qq.com> Date: Sat, 3 Jul 2021 19:00:31 +0800 Subject: [PATCH 099/110] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=EF=BC=8C202?= =?UTF-8?q?01003=E4=BA=8C=E5=8F=89=E6=A0=91=E5=91=A8=E6=9C=AB=E6=80=BB?= =?UTF-8?q?=E7=BB=93.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/周总结/20201003二叉树周末总结.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/problems/周总结/20201003二叉树周末总结.md b/problems/周总结/20201003二叉树周末总结.md index b7c123bc..0cb8b654 100644 --- a/problems/周总结/20201003二叉树周末总结.md +++ b/problems/周总结/20201003二叉树周末总结.md @@ -40,9 +40,8 @@ public: return isSame; } - bool isSymmetric(TreeNode* root) { - if (root == NULL) return true; - return compare(root->left, root->right); + bool isSymmetric(TreeNode* p, TreeNode* q) { + return compare(p, q); } }; ``` From 52ed0ac5d318f8efcde282d71d5408501ecdfba4 Mon Sep 17 00:00:00 2001 From: hengzzha <80679845+hengzzha@users.noreply.github.com> Date: Sun, 4 Jul 2021 09:03:43 +0800 Subject: [PATCH 100/110] =?UTF-8?q?Update=20=E5=8A=A8=E6=80=81=E8=A7=84?= =?UTF-8?q?=E5=88=92-=E8=82=A1=E7=A5=A8=E9=97=AE=E9=A2=98=E6=80=BB?= =?UTF-8?q?=E7=BB=93=E7=AF=87.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 冗余代码 --- problems/动态规划-股票问题总结篇.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/problems/动态规划-股票问题总结篇.md b/problems/动态规划-股票问题总结篇.md index d22132c0..590a8008 100644 --- a/problems/动态规划-股票问题总结篇.md +++ b/problems/动态规划-股票问题总结篇.md @@ -375,12 +375,6 @@ p[i][3] = dp[i - 1][2]; 综上分析,递推代码如下: -```C++ -dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3], dp[i - 1][1]) - prices[i]; -dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]); -dp[i][2] = dp[i - 1][0] + prices[i]; -dp[i][3] = dp[i - 1][2]; -``` ```C++ dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3]- prices[i], dp[i - 1][1]) - prices[i]; dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]); From be54fec1ddad9b074bcfe4a07760be799d49878b Mon Sep 17 00:00:00 2001 From: Qi Jia <13632059+jackeyjia@users.noreply.github.com> Date: Sat, 3 Jul 2021 20:38:53 -0700 Subject: [PATCH 101/110] add js solution --- problems/0096.不同的二叉搜索树.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/0096.不同的二叉搜索树.md b/problems/0096.不同的二叉搜索树.md index a9631315..56f50d46 100644 --- a/problems/0096.不同的二叉搜索树.md +++ b/problems/0096.不同的二叉搜索树.md @@ -211,6 +211,23 @@ func numTrees(n int)int{ } ``` +Javascript: +```Javascript +const numTrees =(n) => { + let dp = new Array(n+1).fill(0); + dp[0] = 1; + dp[1] = 1; + + for(let i = 2; i <= n; i++) { + for(let j = 1; j <= i; j++) { + dp[i] += dp[j-1] * dp[i-j]; + } + } + + return dp[n]; +}; +``` + ----------------------- From 50ed227f5500d627d40c5dfcd96a0fe584ee0000 Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Sun, 4 Jul 2021 18:19:20 +0800 Subject: [PATCH 102/110] =?UTF-8?q?=E6=8F=90=E4=BE=9BJavaScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E7=9A=84=E3=80=8A=E5=B0=86=E6=9C=89=E5=BA=8F=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E8=BD=AC=E6=8D=A2=E4=B8=BA=E4=BA=8C=E5=8F=89=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E6=A0=91=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...将有序数组转换为二叉搜索树.md | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/problems/0108.将有序数组转换为二叉搜索树.md b/problems/0108.将有序数组转换为二叉搜索树.md index b8861b24..b38330b9 100644 --- a/problems/0108.将有序数组转换为二叉搜索树.md +++ b/problems/0108.将有序数组转换为二叉搜索树.md @@ -279,6 +279,36 @@ func sortedArrayToBST(nums []int) *TreeNode { } ``` +JavaScript版本 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {number[]} nums + * @return {TreeNode} + */ +var sortedArrayToBST = function (nums) { + const buildTree = (Arr, left, right) => { + if (left > right) + return null; + + let mid = Math.floor(left + (right - left) / 2); + + let root = new TreeNode(Arr[mid]); + root.left = buildTree(Arr, left, mid - 1); + root.right = buildTree(Arr, mid + 1, right); + return root; + } + return buildTree(nums, 0, nums.length - 1); +}; +``` From f539571a6598e31788113ae2a3344b3e675afe09 Mon Sep 17 00:00:00 2001 From: kok-s0s <2694308562@qq.com> Date: Sun, 4 Jul 2021 18:22:39 +0800 Subject: [PATCH 103/110] =?UTF-8?q?=E6=8F=90=E4=BE=9BJavaScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E7=9A=84=E3=80=8A=E6=8A=8A=E4=BA=8C=E5=8F=89=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E6=A0=91=E8=BD=AC=E6=8D=A2=E4=B8=BA=E7=B4=AF=E5=8A=A0?= =?UTF-8?q?=E6=A0=91=E3=80=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...38.把二叉搜索树转换为累加树.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/problems/0538.把二叉搜索树转换为累加树.md b/problems/0538.把二叉搜索树转换为累加树.md index 06a53ce7..3ecb8195 100644 --- a/problems/0538.把二叉搜索树转换为累加树.md +++ b/problems/0538.把二叉搜索树转换为累加树.md @@ -239,7 +239,70 @@ func RightMLeft(root *TreeNode,sum *int) *TreeNode { } ``` +JavaScript版本 +> 递归 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {TreeNode} + */ +var convertBST = function(root) { + let pre = 0; + const ReverseInOrder = (cur) => { + if(cur) { + ReverseInOrder(cur.right); + cur.val += pre; + pre = cur.val; + ReverseInOrder(cur.left); + } + } + ReverseInOrder(root); + return root; +}; +``` + +> 迭代 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {TreeNode} + */ +var convertBST = function (root) { + let pre = 0; + let cur = root; + let stack = []; + while (cur !== null || stack.length !== 0) { + while (cur !== null) { + stack.push(cur); + cur = cur.right; + } + cur = stack.pop(); + cur.val += pre; + pre = cur.val; + cur = cur.left; + } + return root; +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From ae9b1358afda3c366116ecc553ece8039d3007e5 Mon Sep 17 00:00:00 2001 From: ltinyho Date: Sun, 4 Jul 2021 20:07:30 +0800 Subject: [PATCH 104/110] =?UTF-8?q?Update=200102.=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?= 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 341f4ba5..2f56af52 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -18,7 +18,7 @@ * 637.二叉树的层平均值 * 429.N叉树的前序遍历 * 515.在每个树行中找最大值 -* 116. 填充每个节点的下一个右侧节点指针 +* 116.填充每个节点的下一个右侧节点指针 * 117.填充每个节点的下一个右侧节点指针II From b85bb72a0b66e1bfb20d3afcf6e79244ec4f7e4d Mon Sep 17 00:00:00 2001 From: daniel1n <54945782+daniel1n@users.noreply.github.com> Date: Mon, 5 Jul 2021 10:54:06 +0800 Subject: [PATCH 105/110] =?UTF-8?q?Update=200216.=E7=BB=84=E5=90=88?= =?UTF-8?q?=E6=80=BB=E5=92=8CIII.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增java的模板方法 --- problems/0216.组合总和III.md | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md index 67e67ad0..11087d5b 100644 --- a/problems/0216.组合总和III.md +++ b/problems/0216.组合总和III.md @@ -227,6 +227,44 @@ public: Java: + +模板方法 +```java +class Solution { + List> result = new ArrayList<>(); + LinkedList path = new LinkedList<>(); + + public List> combinationSum3(int k, int n) { + backTracking(n, k, 1, 0); + return result; + } + + private void backTracking(int targetSum, int k, int startIndex, int sum) { + // 减枝 + if (sum > targetSum) { + return; + } + + if (path.size() == k) { + if (sum == targetSum) result.add(new ArrayList<>(path)); + return; + } + + // 减枝 9 - (k - path.size()) + 1 + for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) { + path.add(i); + sum += i; + backTracking(targetSum, k, i + 1, sum); + //回溯 + path.removeLast(); + //回溯 + sum -= i; + } + } +} +``` + +其他方法 ```java class Solution { List> res = new ArrayList<>(); From bf9df800ac4d04fa91fff7d1327aa21797ea3f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=97=A4=E9=9C=B2?= <080301087@163.com> Date: Mon, 5 Jul 2021 11:42:08 +0800 Subject: [PATCH 106/110] =?UTF-8?q?Update=200617.=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91.md=20-=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E4=BA=86python3=E7=89=88=E6=9C=AC=E7=9A=84=E8=BF=AD=E4=BB=A3?= =?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/0617.合并二叉树.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/problems/0617.合并二叉树.md b/problems/0617.合并二叉树.md index f325df64..19b58bd3 100644 --- a/problems/0617.合并二叉树.md +++ b/problems/0617.合并二叉树.md @@ -319,7 +319,7 @@ Python: # self.val = val # self.left = left # self.right = right -//递归法*前序遍历 +# 递归法*前序遍历 class Solution: def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode: if not root1: return root2 // 如果t1为空,合并之后就应该是t2 @@ -328,6 +328,32 @@ class Solution: root1.left = self.mergeTrees(root1.left , root2.left) //左 root1.right = self.mergeTrees(root1.right , root2.right) //右 return root1 //root1修改了结构和数值 + +# 迭代法-覆盖原来的树 +class Solution: + def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode: + if not root1: return root2 + if not root2: return root1 + # 迭代,将树2覆盖到树1 + queue1 = [root1] + queue2 = [root2] + root = root1 + while queue1 and queue2: + root1 = queue1.pop(0) + root2 = queue2.pop(0) + root1.val += root2.val + if not root1.left: # 如果树1左儿子不存在,则覆盖后树1的左儿子为树2的左儿子 + root1.left = root2.left + elif root1.left and root2.left: + queue1.append(root1.left) + queue2.append(root2.left) + + if not root1.right: # 同理,处理右儿子 + root1.right = root2.right + elif root1.right and root2.right: + queue1.append(root1.right) + queue2.append(root2.right) + return root ``` Go: From c99a153c01d14b50ce1108ee5fecab4418b563b4 Mon Sep 17 00:00:00 2001 From: Qi Jia <13632059+jackeyjia@users.noreply.github.com> Date: Mon, 5 Jul 2021 15:02:52 -0700 Subject: [PATCH 107/110] add js solution for findTargetSumWays --- problems/0494.目标和.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/problems/0494.目标和.md b/problems/0494.目标和.md index a0e07a1f..b7da0252 100644 --- a/problems/0494.目标和.md +++ b/problems/0494.目标和.md @@ -306,6 +306,36 @@ func findTargetSumWays(nums []int, target int) int { } ``` +Javascript: +```javascript +const findTargetSumWays = (nums, target) => { + + const sum = nums.reduce((a, b) => a+b); + + if(target > sum) { + return 0; + } + + if((target + sum) % 2) { + return 0; + } + + const halfSum = (target + sum) / 2; + nums.sort((a, b) => a - b); + + let dp = new Array(halfSum+1).fill(0); + dp[0] = 1; + + for(let i = 0; i < nums.length; i++) { + for(let j = halfSum; j >= nums[i]; j--) { + dp[j] += dp[j - nums[i]]; + } + } + + return dp[halfSum]; +}; +``` + ----------------------- From 14154b96020aae63e2c2351ae7021b9e61a337ac Mon Sep 17 00:00:00 2001 From: Qi Jia <13632059+jackeyjia@users.noreply.github.com> Date: Mon, 5 Jul 2021 16:26:30 -0700 Subject: [PATCH 108/110] add js solution for findMaxForm --- problems/0474.一和零.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/problems/0474.一和零.md b/problems/0474.一和零.md index fd925f76..6b73c080 100644 --- a/problems/0474.一和零.md +++ b/problems/0474.一和零.md @@ -244,6 +244,35 @@ func max(a,b int) int { } ``` +Javascript: +```javascript +const findMaxForm = (strs, m, n) => { + const dp = Array.from(Array(m+1), () => Array(n+1).fill(0)); + let numOfZeros, numOfOnes; + + for(let str of strs) { + numOfZeros = 0; + numOfOnes = 0; + + for(let c of str) { + if (c === '0') { + numOfZeros++; + } else { + numOfOnes++; + } + } + + for(let i = m; i >= numOfZeros; i--) { + for(let j = n; j >= numOfOnes; j--) { + dp[i][j] = Math.max(dp[i][j], dp[i - numOfZeros][j - numOfOnes] + 1); + } + } + } + + return dp[m][n]; +}; +``` + ----------------------- From 01ee8a2d5739f2e4acb2184cec6bd67f0f8115cf Mon Sep 17 00:00:00 2001 From: Qi Jia <13632059+jackeyjia@users.noreply.github.com> Date: Mon, 5 Jul 2021 16:57:23 -0700 Subject: [PATCH 109/110] add js solution for coin-change-2 --- problems/0518.零钱兑换II.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/problems/0518.零钱兑换II.md b/problems/0518.零钱兑换II.md index 08043ea3..3f907da9 100644 --- a/problems/0518.零钱兑换II.md +++ b/problems/0518.零钱兑换II.md @@ -243,6 +243,22 @@ func change(amount int, coins []int) int { } ``` +Javascript: +```javascript +const change = (amount, coins) => { + let dp = Array(amount + 1).fill(0); + dp[0] = 1; + + for(let i =0; i < coins.length; i++) { + for(let j = coins[i]; j <= amount; j++) { + dp[j] += dp[j - coins[i]]; + } + } + + return dp[amount]; +} +``` + ----------------------- From e86975c82f9b846303ab07c6724463cf25952b52 Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Wed, 7 Jul 2021 21:23:57 +0800 Subject: [PATCH 110/110] Update --- README.md | 4 +- problems/0040.组合总和II.md | 3 + problems/0045.跳跃游戏II.md | 9 +- problems/0046.全排列.md | 7 +- problems/0047.全排列II.md | 2 + problems/0051.N皇后.md | 3 + problems/0102.二叉树的层序遍历.md | 1095 ++++++++++----------- problems/0111.二叉树的最小深度.md | 4 +- problems/0150.逆波兰表达式求值.md | 50 +- problems/0216.组合总和III.md | 6 +- problems/0239.滑动窗口最大值.md | 48 +- problems/0332.重新安排行程.md | 3 + problems/0406.根据身高重建队列.md | 8 +- problems/0435.无重叠区间.md | 4 +- problems/0491.递增子序列.md | 3 + problems/0496.下一个更大元素I.md | 187 ++++ problems/背包理论基础01背包-1.md | 24 +- 17 files changed, 810 insertions(+), 650 deletions(-) create mode 100644 problems/0496.下一个更大元素I.md diff --git a/README.md b/README.md index 2c462a52..f6567cc4 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,7 @@ 7. [英语到底重不重要!](https://mp.weixin.qq.com/s/1PRZiyF_-TVA-ipwDNjdKw) 8. [计算机专业要不要读研!](https://mp.weixin.qq.com/s/c9v1L3IjqiXtkNH7sOMAdg) 9. [秋招和提前批都越来越提前了....](https://mp.weixin.qq.com/s/SNFiRDx8CKyjhTPlys6ywQ) +10. [你的简历里「专业技能」写的够专业么?](https://mp.weixin.qq.com/s/bp6y-e5FVN28H9qc8J9zrg) ## 数组 @@ -395,7 +396,8 @@ ## 单调栈 -1. [每日温度](./problems/0739.每日温度.md) +1. [单调栈:每日温度](./problems/0739.每日温度.md) +2. [单调栈:下一个更大元素I](./problems/0496.下一个更大元素I.md) ## 图论 diff --git a/problems/0040.组合总和II.md b/problems/0040.组合总和II.md index 021bba94..70e012da 100644 --- a/problems/0040.组合总和II.md +++ b/problems/0040.组合总和II.md @@ -41,6 +41,9 @@ candidates 中的每个数字在每个组合中只能使用一次。 ## 思路 +**如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。 + + 这道题目和[39.组合总和](https://mp.weixin.qq.com/s/FLg8G6EjVcxBjwCbzpACPw)如下区别: 1. 本题candidates 中的每个数字在每个组合中只能使用一次。 diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index 4128da4c..a161d944 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -30,7 +30,7 @@ ## 思路 -本题相对于[贪心算法:跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)还是难了不少。 +本题相对于[55.跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)还是难了不少。 但思路是相似的,还是要看最大覆盖范围。 @@ -132,7 +132,7 @@ public: ## 总结 -相信大家可以发现,这道题目相当于[贪心算法:跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)难了不止一点。 +相信大家可以发现,这道题目相当于[55.跳跃游戏](https://mp.weixin.qq.com/s/606_N9j8ACKCODoCbV1lSA)难了不止一点。 但代码又十分简单,贪心就是这么巧妙。 @@ -228,11 +228,6 @@ var jump = function(nums) { }; ``` -/* -dp[i]表示从起点到当前位置的最小跳跃次数 -dp[i]=min(dp[j]+1,dp[i]) 表示从j位置用一步跳跃到当前位置,这个j位置可能有很多个,却最小一个就可以 -*/ -``` diff --git a/problems/0046.全排列.md b/problems/0046.全排列.md index 30c3374b..3ee7271e 100644 --- a/problems/0046.全排列.md +++ b/problems/0046.全排列.md @@ -27,7 +27,10 @@ ## 思路 -此时我们已经学习了[组合问题](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)、[切割问题](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)和[子集问题](https://mp.weixin.qq.com/s/NNRzX-vJ_pjK4qxohd_LtA),接下来看一看排列问题。 +**如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](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),接下来看一看排列问题。 相信这个排列问题就算是让你用for循环暴力把结果搜索出来,这个暴力也不是很好写。 @@ -81,7 +84,7 @@ if (path.size() == nums.size()) { * 单层搜索的逻辑 -这里和[组合问题](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)、[切割问题](https://mp.weixin.qq.com/s/Pb1epUTbU8fHIht-g_MS5Q)和[子集问题](https://mp.weixin.qq.com/s/NNRzX-vJ_pjK4qxohd_LtA)最大的不同就是for循环里不用startIndex了。 +这里和[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了。 因为排列问题,每次都要从头开始搜索,例如元素1在[1,2]中已经使用过了,但是在[2,1]中还要再使用一次1。 diff --git a/problems/0047.全排列II.md b/problems/0047.全排列II.md index b4fb3470..079ca834 100644 --- a/problems/0047.全排列II.md +++ b/problems/0047.全排列II.md @@ -29,6 +29,8 @@ * -10 <= nums[i] <= 10 ## 思路 +**如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。 + 这道题目和[回溯算法:排列问题!](https://mp.weixin.qq.com/s/SCOjeMX1t41wcvJq49GhMw)的区别在与**给定一个可包含重复数字的序列**,要返回**所有不重复的全排列**。 diff --git a/problems/0051.N皇后.md b/problems/0051.N皇后.md index fd2c7d0f..a8919ec3 100644 --- a/problems/0051.N皇后.md +++ b/problems/0051.N皇后.md @@ -41,6 +41,9 @@ n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并 ## 思路 +**如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。 + + 都知道n皇后问题是回溯算法解决的经典问题,但是用回溯解决多了组合、切割、子集、排列问题之后,遇到这种二位矩阵还会有点不知所措。 首先来看一下皇后们的约束条件: diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 341f4ba5..b13fdd8d 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -18,7 +18,7 @@ * 637.二叉树的层平均值 * 429.N叉树的前序遍历 * 515.在每个树行中找最大值 -* 116. 填充每个节点的下一个右侧节点指针 +* 116.填充每个节点的下一个右侧节点指针 * 117.填充每个节点的下一个右侧节点指针II @@ -80,15 +80,10 @@ public: } }; ``` + python代码: ```python -# Definition for a binary tree node. -# class TreeNode: -# def __init__(self, val=0, left=None, right=None): -# self.val = val -# self.left = left -# self.right = right class Solution: def levelOrder(self, root: TreeNode) -> List[List[int]]: if not root: @@ -110,7 +105,94 @@ class Solution: return out_list ``` +java: +```Java +// 102.二叉树的层序遍历 +class Solution { + public List> resList = new ArrayList>(); + + public List> levelOrder(TreeNode root) { + //checkFun01(root,0); + checkFun02(root); + + return resList; + } + + //DFS--递归方式 + public void checkFun01(TreeNode node, Integer deep) { + if (node == null) return; + deep++; + + if (resList.size() < deep) { + //当层级增加时,list的Item也增加,利用list的索引值进行层级界定 + List item = new ArrayList(); + resList.add(item); + } + resList.get(deep - 1).add(node.val); + + checkFun01(node.left, deep); + checkFun01(node.right, deep); + } + + //BFS--迭代方式--借助队列 + public void checkFun02(TreeNode node) { + if (node == null) return; + Queue que = new LinkedList(); + que.offer(node); + + while (!que.isEmpty()) { + List itemList = new ArrayList(); + int len = que.size(); + + while (len > 0) { + TreeNode tmpNode = que.poll(); + itemList.add(tmpNode.val); + + if (tmpNode.left != null) que.offer(tmpNode.left); + if (tmpNode.right != null) que.offer(tmpNode.right); + len--; + } + + resList.add(itemList); + } + + } +} +``` + +go: + +```go +/** +102. 二叉树的层序遍历 + */ +func levelOrder(root *TreeNode) [][]int { + res:=[][]int{} + if root==nil{//防止为空 + return res + } + queue:=list.New() + queue.PushBack(root) + var tmpArr []int + for queue.Len()>0 { + length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数) + for i:=0;i List[List[int]]: if not root: @@ -218,7 +294,88 @@ class Solution: # 内存消耗:15.2 MB, 在所有 Python3 提交中击败了63.76%的用户 ``` +Java: +```java +// 107. 二叉树的层序遍历 II +public class N0107 { + + /** + * 解法:队列,迭代。 + * 层序遍历,再翻转数组即可。 + */ + public List> solution1(TreeNode root) { + List> list = new ArrayList<>(); + Deque que = new LinkedList<>(); + + if (root == null) { + return list; + } + + que.offerLast(root); + while (!que.isEmpty()) { + List levelList = new ArrayList<>(); + + int levelSize = que.size(); + for (int i = 0; i < levelSize; i++) { + TreeNode peek = que.peekFirst(); + levelList.add(que.pollFirst().val); + + if (peek.left != null) { + que.offerLast(peek.left); + } + if (peek.right != null) { + que.offerLast(peek.right); + } + } + list.add(levelList); + } + + List> result = new ArrayList<>(); + for (int i = list.size() - 1; i >= 0; i-- ) { + result.add(list.get(i)); + } + + return result; + } +} +``` + +go: + +```GO +/** +107. 二叉树的层序遍历 II + */ +func levelOrderBottom(root *TreeNode) [][]int { + queue:=list.New() + res:=[][]int{} + if root==nil{ + return res + } + queue.PushBack(root) + for queue.Len()>0{ + length:=queue.Len() + tmp:=[]int{} + for i:=0;i List[int]: if not root: @@ -322,7 +473,87 @@ class Solution: ``` +Java: +```java +// 199.二叉树的右视图 +public class N0199 { + /** + * 解法:队列,迭代。 + * 每次返回每层的最后一个字段即可。 + * + * 小优化:每层右孩子先入队。代码略。 + */ + public List rightSideView(TreeNode root) { + List list = new ArrayList<>(); + Deque que = new LinkedList<>(); + + if (root == null) { + return list; + } + + que.offerLast(root); + while (!que.isEmpty()) { + int levelSize = que.size(); + + for (int i = 0; i < levelSize; i++) { + TreeNode poll = que.pollFirst(); + + if (poll.left != null) { + que.addLast(poll.left); + } + if (poll.right != null) { + que.addLast(poll.right); + } + + if (i == levelSize - 1) { + list.add(poll.val); + } + } + } + + return list; + } +} +``` + +go: + +```GO + +/** +199. 二叉树的右视图 + */ +func rightSideView(root *TreeNode) []int { + queue:=list.New() + res:=[][]int{} + var finaRes []int + if root==nil{ + return finaRes + } + queue.PushBack(root) + for queue.Len()>0{ + length:=queue.Len() + tmp:=[]int{} + for i:=0;i List[float]: if not root: @@ -426,7 +651,93 @@ class Solution: # 内存消耗:17 MB, 在所有 Python3 提交中击败了89.68%的用户 ``` +java: +```java + +// 637. 二叉树的层平均值 +public class N0637 { + + /** + * 解法:队列,迭代。 + * 每次返回每层的最后一个字段即可。 + */ + public List averageOfLevels(TreeNode root) { + List list = new ArrayList<>(); + Deque que = new LinkedList<>(); + + if (root == null) { + return list; + } + + que.offerLast(root); + while (!que.isEmpty()) { + TreeNode peek = que.peekFirst(); + + int levelSize = que.size(); + double levelSum = 0.0; + for (int i = 0; i < levelSize; i++) { + TreeNode poll = que.pollFirst(); + + levelSum += poll.val; + + if (poll.left != null) { + que.addLast(poll.left); + } + if (poll.right != null) { + que.addLast(poll.right); + } + } + list.add(levelSum / levelSize); + } + return list; + } +} +``` + +go: + +```GO +/** +637. 二叉树的层平均值 + */ +func averageOfLevels(root *TreeNode) []float64 { + res:=[][]int{} + var finRes []float64 + if root==nil{//防止为空 + return finRes + } + queue:=list.New() + queue.PushBack(root) + var tmpArr []int + for queue.Len()>0 { + length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数) + for i:=0;i List[List[int]]: @@ -562,7 +866,97 @@ class Solution: # 内存消耗:16.5 MB, 在所有 Python3 提交中击败了89.19%的用户 ``` +java: +```java + +// 429. N 叉树的层序遍历 +public class N0429 { + /** + * 解法1:队列,迭代。 + */ + public List> levelOrder(Node root) { + List> list = new ArrayList<>(); + Deque que = new LinkedList<>(); + + if (root == null) { + return list; + } + + que.offerLast(root); + while (!que.isEmpty()) { + int levelSize = que.size(); + List levelList = new ArrayList<>(); + + for (int i = 0; i < levelSize; i++) { + Node poll = que.pollFirst(); + + levelList.add(poll.val); + + List children = poll.children; + if (children == null || children.size() == 0) { + continue; + } + for (Node child : children) { + if (child != null) { + que.offerLast(child); + } + } + } + list.add(levelList); + } + + return list; + } + + class Node { + public int val; + public List children; + + public Node() {} + + public Node(int _val) { + val = _val; + } + + public Node(int _val, List _children) { + val = _val; + children = _children; + } + } +} +``` + + +go: + +```GO +/** +429. N 叉树的层序遍历 + */ + +func levelOrder(root *Node) [][]int { + queue:=list.New() + res:=[][]int{}//结果集 + if root==nil{ + return res + } + queue.PushBack(root) + for queue.Len()>0{ + length:=queue.Len()//记录当前层的数量 + var tmp []int + for T:=0;T0 { + length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数) + for i:=0;i max { + max = val + } + } + return max +} +``` + javascript代码: ```javascript @@ -733,6 +1175,7 @@ public: }; ``` + python代码: ```python @@ -769,6 +1212,47 @@ class Solution: return root ``` +go: + +```GO +/** +116. 填充每个节点的下一个右侧节点指针 +117. 填充每个节点的下一个右侧节点指针 II + */ + +func connect(root *Node) *Node { + res:=[][]*Node{} + if root==nil{//防止为空 + return root + } + queue:=list.New() + queue.PushBack(root) + var tmpArr []*Node + for queue.Len()>0 { + length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数) + for i:=0;i> resList = new ArrayList>(); - - public List> levelOrder(TreeNode root) { - //checkFun01(root,0); - checkFun02(root); - - return resList; - } - - //DFS--递归方式 - public void checkFun01(TreeNode node, Integer deep) { - if (node == null) return; - deep++; - - if (resList.size() < deep) { - //当层级增加时,list的Item也增加,利用list的索引值进行层级界定 - List item = new ArrayList(); - resList.add(item); - } - resList.get(deep - 1).add(node.val); - - checkFun01(node.left, deep); - checkFun01(node.right, deep); - } - - //BFS--迭代方式--借助队列 - public void checkFun02(TreeNode node) { - if (node == null) return; - Queue que = new LinkedList(); - que.offer(node); - - while (!que.isEmpty()) { - List itemList = new ArrayList(); - int len = que.size(); - - while (len > 0) { - TreeNode tmpNode = que.poll(); - itemList.add(tmpNode.val); - - if (tmpNode.left != null) que.offer(tmpNode.left); - if (tmpNode.right != null) que.offer(tmpNode.right); - len--; - } - - resList.add(itemList); - } - - } -} - - -// 107. 二叉树的层序遍历 II -public class N0107 { - - /** - * 解法:队列,迭代。 - * 层序遍历,再翻转数组即可。 - */ - public List> solution1(TreeNode root) { - List> list = new ArrayList<>(); - Deque que = new LinkedList<>(); - - if (root == null) { - return list; - } - - que.offerLast(root); - while (!que.isEmpty()) { - List levelList = new ArrayList<>(); - - int levelSize = que.size(); - for (int i = 0; i < levelSize; i++) { - TreeNode peek = que.peekFirst(); - levelList.add(que.pollFirst().val); - - if (peek.left != null) { - que.offerLast(peek.left); - } - if (peek.right != null) { - que.offerLast(peek.right); - } - } - list.add(levelList); - } - - List> result = new ArrayList<>(); - for (int i = list.size() - 1; i >= 0; i-- ) { - result.add(list.get(i)); - } - - return result; - } -} - -// 199.二叉树的右视图 -public class N0199 { - /** - * 解法:队列,迭代。 - * 每次返回每层的最后一个字段即可。 - * - * 小优化:每层右孩子先入队。代码略。 - */ - public List rightSideView(TreeNode root) { - List list = new ArrayList<>(); - Deque que = new LinkedList<>(); - - if (root == null) { - return list; - } - - que.offerLast(root); - while (!que.isEmpty()) { - int levelSize = que.size(); - - for (int i = 0; i < levelSize; i++) { - TreeNode poll = que.pollFirst(); - - if (poll.left != null) { - que.addLast(poll.left); - } - if (poll.right != null) { - que.addLast(poll.right); - } - - if (i == levelSize - 1) { - list.add(poll.val); - } - } - } - - return list; - } -} - -// 637. 二叉树的层平均值 -public class N0637 { - - /** - * 解法:队列,迭代。 - * 每次返回每层的最后一个字段即可。 - */ - public List averageOfLevels(TreeNode root) { - List list = new ArrayList<>(); - Deque que = new LinkedList<>(); - - if (root == null) { - return list; - } - - que.offerLast(root); - while (!que.isEmpty()) { - TreeNode peek = que.peekFirst(); - - int levelSize = que.size(); - double levelSum = 0.0; - for (int i = 0; i < levelSize; i++) { - TreeNode poll = que.pollFirst(); - - levelSum += poll.val; - - if (poll.left != null) { - que.addLast(poll.left); - } - if (poll.right != null) { - que.addLast(poll.right); - } - } - list.add(levelSum / levelSize); - } - return list; - } -} - -// 429. N 叉树的层序遍历 -public class N0429 { - /** - * 解法1:队列,迭代。 - */ - public List> levelOrder(Node root) { - List> list = new ArrayList<>(); - Deque que = new LinkedList<>(); - - if (root == null) { - return list; - } - - que.offerLast(root); - while (!que.isEmpty()) { - int levelSize = que.size(); - List levelList = new ArrayList<>(); - - for (int i = 0; i < levelSize; i++) { - Node poll = que.pollFirst(); - - levelList.add(poll.val); - - List children = poll.children; - if (children == null || children.size() == 0) { - continue; - } - for (Node child : children) { - if (child != null) { - que.offerLast(child); - } - } - } - list.add(levelList); - } - - return list; - } - - class Node { - public int val; - public List children; - - public Node() {} - - public Node(int _val) { - val = _val; - } - - public Node(int _val, List _children) { - val = _val; - children = _children; - } - } -} -``` - - -Python: - - -Go: -```Go -func levelOrder(root *TreeNode) [][]int { - result:=make([][]int,0) - if root==nil{ - return result - } - - queue:=make([]*TreeNode,0) - queue=append(queue,root) - - for len(queue)>0{ - list:=make([]int,0) - l:=len(queue) - - for i:=0;i 二叉树的层序遍历(GO语言完全版) - -```go -/** -102. 二叉树的层序遍历 - */ -func levelOrder(root *TreeNode) [][]int { - res:=[][]int{} - if root==nil{//防止为空 - return res - } - queue:=list.New() - queue.PushBack(root) - var tmpArr []int - for queue.Len()>0 { - length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数) - for i:=0;i0{ - length:=queue.Len() - tmp:=[]int{} - for i:=0;i0{ - length:=queue.Len() - tmp:=[]int{} - for i:=0;i0 { - length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数) - for i:=0;i0{ - length:=queue.Len()//记录当前层的数量 - var tmp []int - for T:=0;T0 { - length:=queue.Len()//保存当前层的长度,然后处理当前层(十分重要,防止添加下层元素影响判断层中元素的个数) - for i:=0;i max { - max = val - } - } - return max -} +```GO /** 116. 填充每个节点的下一个右侧节点指针 117. 填充每个节点的下一个右侧节点指针 II @@ -1391,26 +1377,31 @@ func connect(root *Node) *Node { return root } ``` -Javascript: -```javascript -var levelOrder = function (root) { - let ans = []; - if (!root) return ans; - let queue = [root]; - while (queue.length) { - let size = queue.length; - let temp = []; - while (size--) { - let n = queue.shift(); - temp.push(n.val); - if (n.left) queue.push(n.left); - if (n.right) queue.push(n.right); - } - ans.push(temp); - } - return ans; -}; -``` + +## 总结 + +二叉树的层序遍历,就是图论中的广度优先搜索在二叉树中的应用,需要借助队列来实现(此时是不是又发现队列的应用了)。 + +虽然不能一口气打十个,打八个也还行。 + +* 102.二叉树的层序遍历 +* 107.二叉树的层次遍历II +* 199.二叉树的右视图 +* 637.二叉树的层平均值 +* 429.N叉树的前序遍历 +* 515.在每个树行中找最大值 +* 116.填充每个节点的下一个右侧节点指针 +* 117.填充每个节点的下一个右侧节点指针II + +如果非要打十个,还得找叶师傅! + +![我要打十个](https://tva1.sinaimg.cn/large/008eGmZEly1gnadnltbpjg309603w4qp.gif) + + + + +# 其他语言版本 + > 二叉树的层序遍历(Javascript语言完全版) (迭代 + 递归) diff --git a/problems/0111.二叉树的最小深度.md b/problems/0111.二叉树的最小深度.md index 48795722..a36faeff 100644 --- a/problems/0111.二叉树的最小深度.md +++ b/problems/0111.二叉树的最小深度.md @@ -29,7 +29,7 @@ ## 思路 -看完了这篇[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg),再来看看如何求最小深度。 +看完了这篇[104.二叉树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg),再来看看如何求最小深度。 直觉上好像和求最大深度差不多,其实还是差不少的。 @@ -154,7 +154,7 @@ public: ## 迭代法 -相对于[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg),本题还可以使用层序遍历的方式来解决,思路是一样的。 +相对于[104.二叉树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg),本题还可以使用层序遍历的方式来解决,思路是一样的。 如果对层序遍历还不清楚的话,可以看这篇:[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog) diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md index c8b0da08..aceb91b4 100644 --- a/problems/0150.逆波兰表达式求值.md +++ b/problems/0150.逆波兰表达式求值.md @@ -26,27 +26,26 @@ https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/   示例 1: -输入: ["2", "1", "+", "3", " * "] -输出: 9 -解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9 +* 输入: ["2", "1", "+", "3", " * "] +* 输出: 9 +* 解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9 示例 2: -输入: ["4", "13", "5", "/", "+"] -输出: 6 -解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6 +* 输入: ["4", "13", "5", "/", "+"] +* 输出: 6 +* 解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6 示例 3: -输入: ["10", "6", "9", "3", "+", "-11", " * ", "/", " * ", "17", "+", "5", "+"] -输出: 22 -解释: -该算式转化为常见的中缀算术表达式为: - ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 -= ((10 * (6 / (12 * -11))) + 17) + 5 -= ((10 * (6 / -132)) + 17) + 5 -= ((10 * 0) + 17) + 5 -= (0 + 17) + 5 -= 17 + 5 -= 22 +* 输入: ["10", "6", "9", "3", "+", "-11", " * ", "/", " * ", "17", "+", "5", "+"] +* 输出: 22 +* 解释:该算式转化为常见的中缀算术表达式为: + ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 += ((10 * (6 / (12 * -11))) + 17) + 5 += ((10 * (6 / -132)) + 17) + 5 += ((10 * 0) + 17) + 5 += (0 + 17) + 5 += 17 + 5 += 22   逆波兰表达式:是一种后缀表达式,所谓后缀就是指算符写在后面。 @@ -63,20 +62,20 @@ https://leetcode-cn.com/problems/evaluate-reverse-polish-notation/ # 思路 -在上一篇文章中[栈与队列:匹配问题都是栈的强项](https://mp.weixin.qq.com/s/eynAEbUbZoAWrk0ZlEugqg)提到了 递归就是用栈来实现的。 +在上一篇文章中[1047.删除字符串中的所有相邻重复项](https://mp.weixin.qq.com/s/1-x6r1wGA9mqIHW5LrMvBg)提到了 递归就是用栈来实现的。 -所以**栈与递归之间在某种程度上是可以转换的!**这一点我们在后续讲解二叉树的时候,会更详细的讲解到。 +所以**栈与递归之间在某种程度上是可以转换的!** 这一点我们在后续讲解二叉树的时候,会更详细的讲解到。 那么来看一下本题,**其实逆波兰表达式相当于是二叉树中的后序遍历**。 大家可以把运算符作为中间节点,按照后序遍历的规则画出一个二叉树。 但我们没有必要从二叉树的角度去解决这个问题,只要知道逆波兰表达式是用后续遍历的方式把二叉树序列化了,就可以了。 -在进一步看,本题中每一个子表达式要得出一个结果,然后拿这个结果再进行运算,那么**这岂不就是一个相邻字符串消除的过程,和[栈与队列:匹配问题都是栈的强项](https://mp.weixin.qq.com/s/eynAEbUbZoAWrk0ZlEugqg)中的对对碰游戏是不是就非常像了。** +在进一步看,本题中每一个子表达式要得出一个结果,然后拿这个结果再进行运算,那么**这岂不就是一个相邻字符串消除的过程,和[1047.删除字符串中的所有相邻重复项](https://mp.weixin.qq.com/s/1-x6r1wGA9mqIHW5LrMvBg)中的对对碰游戏是不是就非常像了。** 如动画所示: -![150.逆波兰表达式求值](https://code-thinking.cdn.bcebos.com/gifs/150.%E9%80%86%E6%B3%A2%E5%85%B0%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%B1%82%E5%80%BC.gif) +![150.逆波兰表达式求值](https://code-thinking.cdn.bcebos.com/gifs/150.逆波兰表达式求值.gif) -相信看完动画大家应该知道,这和[1047. 删除字符串中的所有相邻重复项](https://mp.weixin.qq.com/s/eynAEbUbZoAWrk0ZlEugqg)是差不错的,只不过本题不要相邻元素做消除了,而是做运算! +相信看完动画大家应该知道,这和[1047. 删除字符串中的所有相邻重复项](https://mp.weixin.qq.com/s/1-x6r1wGA9mqIHW5LrMvBg)是差不错的,只不过本题不要相邻元素做消除了,而是做运算! C++代码如下: @@ -126,7 +125,7 @@ public: -## 其他语言版本 +# 其他语言版本 java: @@ -153,23 +152,20 @@ public class EvalRPN { } return stack.pop(); } - - private boolean isOpe(String s) { return s.length() == 1 && s.charAt(0) <'0' || s.charAt(0) >'9'; } - private int stoi(String s) { return Integer.valueOf(s); } - public static void main(String[] args) { new EvalRPN().evalRPN(new String[] {"10","6","9","3","+","-11","*","/","*","17","+","5","+"}); } } ``` + Go: ```Go func evalRPN(tokens []string) int { diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md index 67e67ad0..bfd798e6 100644 --- a/problems/0216.组合总和III.md +++ b/problems/0216.组合总和III.md @@ -34,7 +34,7 @@ 本题就是在[1,2,3,4,5,6,7,8,9]这个集合中找到和为n的k个数的组合。 -相对于[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ),无非就是多了一个限制,本题是要找到和为n的k个数的组合,而整个集合已经是固定的了[1,...,9]。 +相对于[77. 组合](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ),无非就是多了一个限制,本题是要找到和为n的k个数的组合,而整个集合已经是固定的了[1,...,9]。 想到这一点了,做过[77. 组合](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)之后,本题是简单一些了。 @@ -53,7 +53,7 @@ * **确定递归函数参数** -和[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)一样,依然需要一维数组path来存放符合条件的结果,二维数组result来存放结果集。 +和[77. 组合](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)一样,依然需要一维数组path来存放符合条件的结果,二维数组result来存放结果集。 这里我依然定义path 和 result为全局变量。 @@ -103,7 +103,7 @@ if (path.size() == k) { * **单层搜索过程** -本题和[回溯算法:求组合问题!](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)区别之一就是集合固定的就是9个数[1,...,9],所以for循环固定i<=9 +本题和[77. 组合](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ)区别之一就是集合固定的就是9个数[1,...,9],所以for循环固定i<=9 如图: ![216.组合总和III](https://img-blog.csdnimg.cn/20201123195717975.png) diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md index ad54a940..bb89a1ac 100644 --- a/problems/0239.滑动窗口最大值.md +++ b/problems/0239.滑动窗口最大值.md @@ -22,13 +22,13 @@ https://leetcode-cn.com/problems/sliding-window-maximum/ 你能在线性时间复杂度内解决此题吗?   - + 提示: -1 <= nums.length <= 10^5 --10^4 <= nums[i] <= 10^4 -1 <= k <= nums.length +* 1 <= nums.length <= 10^5 +* -10^4 <= nums[i] <= 10^4 +* 1 <= k <= nums.length @@ -84,7 +84,7 @@ public: 动画如下: -![239.滑动窗口最大值](https://code-thinking.cdn.bcebos.com/gifs/239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC.gif) +![239.滑动窗口最大值](https://code-thinking.cdn.bcebos.com/gifs/239.滑动窗口最大值.gif) 对于窗口里的元素{2, 3, 5, 1 ,4},单调队列里只维护{5, 4} 就够了,保持单调队列里单调递减,此时队列出口元素就是窗口里最大元素。 @@ -100,11 +100,11 @@ public: 为了更直观的感受到单调队列的工作过程,以题目示例为例,输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3,动画如下: -![239.滑动窗口最大值-2](https://code-thinking.cdn.bcebos.com/gifs/239.%E6%BB%91%E5%8A%A8%E7%AA%97%E5%8F%A3%E6%9C%80%E5%A4%A7%E5%80%BC-2.gif) +![239.滑动窗口最大值-2](https://code-thinking.cdn.bcebos.com/gifs/239.滑动窗口最大值-2.gif) 那么我们用什么数据结构来实现这个单调队列呢? -使用deque最为合适,在文章[栈与队列:来看看栈和队列不为人知的一面](https://mp.weixin.qq.com/s/VZRjOccyE09aE-MgLbCMjQ)中,我们就提到了常用的queue在没有指定容器的情况下,deque就是默认底层容器。 +使用deque最为合适,在文章[栈与队列:来看看栈和队列不为人知的一面](https://mp.weixin.qq.com/s/HCXfQ_Bhpi63YaX0ZRSnAQ)中,我们就提到了常用的queue在没有指定容器的情况下,deque就是默认底层容器。 基于刚刚说过的单调队列pop和push的规则,代码不难实现,如下: @@ -201,9 +201,7 @@ public: - - -## 其他语言版本 +# 其他语言版本 Java: @@ -337,36 +335,6 @@ class Solution: Go: -```go -func maxSlidingWindow(nums []int, k int) []int { - var queue []int - var rtn []int - - for f := 0; f < len(nums); f++ { - //维持队列递减, 将 k 插入合适的位置, queue中 <=k 的 元素都不可能是窗口中的最大值, 直接弹出 - for len(queue) > 0 && nums[f] > nums[queue[len(queue)-1]] { - queue = queue[:len(queue)-1] - } - // 等大的后来者也应入队 - if len(queue) == 0 || nums[f] <= nums[queue[len(queue)-1]] { - queue = append(queue, f) - } - - if f >= k - 1 { - rtn = append(rtn, nums[queue[0]]) - //弹出离开窗口的队首 - if f - k + 1 == queue[0] { - queue = queue[1:] - } - } - } - - return rtn - -} - -``` - ```go // 封装单调队列的方式解题 type MyQueue struct { diff --git a/problems/0332.重新安排行程.md b/problems/0332.重新安排行程.md index 97059e4a..3c7e34d8 100644 --- a/problems/0332.重新安排行程.md +++ b/problems/0332.重新安排行程.md @@ -33,6 +33,9 @@ ## 思路 +**如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。 + + 这道题目还是很难的,之前我们用回溯法解决了如下问题:[组合问题](https://mp.weixin.qq.com/s/OnBjbLzuipWz_u4QfmgcqQ),[分割问题](https://mp.weixin.qq.com/s/v--VmA8tp9vs4bXCqHhBuA),[子集问题](https://mp.weixin.qq.com/s/NNRzX-vJ_pjK4qxohd_LtA),[排列问题](https://mp.weixin.qq.com/s/SCOjeMX1t41wcvJq49GhMw)。 直觉上来看 这道题和回溯法没有什么关系,更像是图论中的深度优先搜索。 diff --git a/problems/0406.根据身高重建队列.md b/problems/0406.根据身高重建队列.md index 946c41ce..2b447da4 100644 --- a/problems/0406.根据身高重建队列.md +++ b/problems/0406.根据身高重建队列.md @@ -43,9 +43,9 @@ 本题有两个维度,h和k,看到这种题目一定要想如何确定一个维度,然后在按照另一个维度重新排列。 -其实如果大家认真做了[贪心算法:分发糖果](https://mp.weixin.qq.com/s/8MwlgFfvaNYmjGwjuMlETQ),就会发现和此题有点点的像。 +其实如果大家认真做了[135. 分发糖果](https://mp.weixin.qq.com/s/8MwlgFfvaNYmjGwjuMlETQ),就会发现和此题有点点的像。 -在[贪心算法:分发糖果](https://mp.weixin.qq.com/s/8MwlgFfvaNYmjGwjuMlETQ)我就强调过一次,遇到两个维度权衡的时候,一定要先确定一个维度,再确定另一个维度。 +在[135. 分发糖果](https://mp.weixin.qq.com/s/8MwlgFfvaNYmjGwjuMlETQ)我就强调过一次,遇到两个维度权衡的时候,一定要先确定一个维度,再确定另一个维度。 **如果两个维度一起考虑一定会顾此失彼**。 @@ -161,11 +161,11 @@ public: ## 总结 -关于出现两个维度一起考虑的情况,我们已经做过两道题目了,另一道就是[贪心算法:分发糖果](https://mp.weixin.qq.com/s/8MwlgFfvaNYmjGwjuMlETQ)。 +关于出现两个维度一起考虑的情况,我们已经做过两道题目了,另一道就是[135. 分发糖果](https://mp.weixin.qq.com/s/8MwlgFfvaNYmjGwjuMlETQ)。 **其技巧都是确定一边然后贪心另一边,两边一起考虑,就会顾此失彼**。 -这道题目可以说比[贪心算法:分发糖果](https://mp.weixin.qq.com/s/8MwlgFfvaNYmjGwjuMlETQ)难不少,其贪心的策略也是比较巧妙。 +这道题目可以说比[135. 分发糖果](https://mp.weixin.qq.com/s/8MwlgFfvaNYmjGwjuMlETQ)难不少,其贪心的策略也是比较巧妙。 最后我给出了两个版本的代码,可以明显看是使用C++中的list(底层链表实现)比vector(数组)效率高得多。 diff --git a/problems/0435.无重叠区间.md b/problems/0435.无重叠区间.md index 23ee9f94..37bb0b5d 100644 --- a/problems/0435.无重叠区间.md +++ b/problems/0435.无重叠区间.md @@ -122,9 +122,9 @@ public: ## 补充 -本题其实和[贪心算法:用最少数量的箭引爆气球](https://mp.weixin.qq.com/s/HxVAJ6INMfNKiGwI88-RFw)非常像,弓箭的数量就相当于是非交叉区间的数量,只要把弓箭那道题目代码里射爆气球的判断条件加个等号(认为[0,1][1,2]不是相邻区间),然后用总区间数减去弓箭数量 就是要移除的区间数量了。 +本题其实和[452.用最少数量的箭引爆气球](https://mp.weixin.qq.com/s/HxVAJ6INMfNKiGwI88-RFw)非常像,弓箭的数量就相当于是非交叉区间的数量,只要把弓箭那道题目代码里射爆气球的判断条件加个等号(认为[0,1][1,2]不是相邻区间),然后用总区间数减去弓箭数量 就是要移除的区间数量了。 -把[贪心算法:用最少数量的箭引爆气球](https://mp.weixin.qq.com/s/HxVAJ6INMfNKiGwI88-RFw)代码稍做修改,就可以AC本题。 +把[452.用最少数量的箭引爆气球](https://mp.weixin.qq.com/s/HxVAJ6INMfNKiGwI88-RFw)代码稍做修改,就可以AC本题。 ```C++ class Solution { diff --git a/problems/0491.递增子序列.md b/problems/0491.递增子序列.md index 5538a2c9..85c9d307 100644 --- a/problems/0491.递增子序列.md +++ b/problems/0491.递增子序列.md @@ -28,6 +28,9 @@ ## 思路 +**如果对回溯算法基础还不了解的话,我还特意录制了一期视频:[带你学透回溯算法(理论篇)](https://www.bilibili.com/video/BV1cy4y167mM/)** 可以结合题解和视频一起看,希望对大家理解回溯算法有所帮助。 + + 这个递增子序列比较像是取有序的子集。而且本题也要求不能有相同的递增子序列。 这又是子集,又是去重,是不是不由自主的想起了刚刚讲过的[回溯算法:求子集问题(二)](https://mp.weixin.qq.com/s/WJ4JNDRJgsW3eUN72Hh3uQ)。 diff --git a/problems/0496.下一个更大元素I.md b/problems/0496.下一个更大元素I.md new file mode 100644 index 00000000..88e89e52 --- /dev/null +++ b/problems/0496.下一个更大元素I.md @@ -0,0 +1,187 @@ + +# 496.下一个更大元素 I + +题目链接:https://leetcode-cn.com/problems/next-greater-element-i/ + +给你两个 没有重复元素 的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。 + +请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值。 + +nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出 -1 。 + +示例 1: + +输入: nums1 = [4,1,2], nums2 = [1,3,4,2]. +输出: [-1,3,-1] +解释: +对于 num1 中的数字 4 ,你无法在第二个数组中找到下一个更大的数字,因此输出 -1 。 +对于 num1 中的数字 1 ,第二个数组中数字1右边的下一个较大数字是 3 。 +对于 num1 中的数字 2 ,第二个数组中没有下一个更大的数字,因此输出 -1 。 + +示例 2: +输入: nums1 = [2,4], nums2 = [1,2,3,4]. +输出: [3,-1] +解释: +对于 num1 中的数字 2 ,第二个数组中的下一个较大数字是 3 。 +对于 num1 中的数字 4 ,第二个数组中没有下一个更大的数字,因此输出-1 。 +  +提示: + +* 1 <= nums1.length <= nums2.length <= 1000 +* 0 <= nums1[i], nums2[i] <= 10^4 +* nums1和nums2中所有整数 互不相同 +* nums1 中的所有整数同样出现在 nums2 中 + +# 思路 + +做本题之前,建议先做一下[739. 每日温度](https://mp.weixin.qq.com/s/YeQ7eE0-hZpxJfJJziq25Q) + +在[739. 每日温度](https://mp.weixin.qq.com/s/YeQ7eE0-hZpxJfJJziq25Q)中是求每个元素下一个比当前元素大的元素的位置。 + +本题则是说nums1 是 nums2的子集,找nums1中的元素在nums2中下一个比当前元素大的元素。 + +看上去和[739. 每日温度](https://mp.weixin.qq.com/s/YeQ7eE0-hZpxJfJJziq25Q) 就如出一辙了。 + +几乎是一样的,但是这么绕了一下,其实还上升了一点难度。 + +需要对单调栈使用的更熟练一些,才能顺利的把本题写出来。 + +从题目示例中我们可以看出最后是要求nums1的每个元素在nums2中下一个比当前元素大的元素,那么就要定义一个和nums1一样大小的数组result来存放结果。 + +一些同学可能看到两个数组都已经懵了,不知道要定一个一个多大的result数组来存放结果了。 + +**这么定义这个result数组初始化应该为多少呢?** + +题目说如果不存在对应位置就输出 -1 ,所以result数组如果某位置没有被赋值,那么就应该是是-1,所以就初始化为-1。 + +在遍历nums2的过程中,我们要判断nums2[i]是否在nums1中出现过,因为最后是要根据nums1元素的下标来更新result数组。 + +**注意题目中说是两个没有重复元素 的数组 nums1 和 nums2**。 + +没有重复元素,我们就可以用map来做映射了。根据数值快速找到下标,还可以判断nums2[i]是否在nums1中出现过。 + +C++中,当我们要使用集合来解决哈希问题的时候,优先使用unordered_set,因为它的查询和增删效率是最优的。我在[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg)中也做了详细的解释。 + +那么预处理代码如下: + +```C++ +unordered_map umap; // key:下表元素,value:下表 +for (int i = 0; i < nums1.size(); i++) { + umap[nums1[i]] = i; +} +``` + +使用单调栈,首先要想单调栈是从大到小还是从小到大。 + +本题和739. 每日温度是一样的。 + +栈头到栈底的顺序,要从小到大,也就是保持栈里的元素为递增顺序。只要保持递增,才能找到右边第一个比自己大的元素。 + +可能这里有一些同学不理解,那么可以自己尝试一下用递减栈,能不能求出来。其实递减栈就是求右边第一个比自己小的元素了。 + + +接下来就要分析如下三种情况,一定要分析清楚。 + +1. 情况一:当前遍历的元素T[i]小于栈顶元素T[st.top()]的情况 + +此时满足递增栈(栈头到栈底的顺序),所以直接入栈。 + +2. 情况二:当前遍历的元素T[i]等于栈顶元素T[st.top()]的情况 + +如果相等的话,依然直接入栈,因为我们要求的是右边第一个比自己大的元素,而不是大于等于! + +3. 情况三:当前遍历的元素T[i]大于栈顶元素T[st.top()]的情况 + +此时如果入栈就不满足递增栈了,这也是找到右边第一个比自己大的元素的时候。 + +判断栈顶元素是否在nums1里出现过,(注意栈里的元素是nums2的元素),如果出现过,开始记录结果。 + +记录结果这块逻辑有一点小绕,要清楚,此时栈顶元素在nums2中右面第一个大的元素是nums2[i]即当前遍历元素。 + +代码如下: + +```C++ +while (!st.empty() && nums2[i] > nums2[st.top()]) { + if (umap.count(nums2[st.top()]) > 0) { // 看map里是否存在这个元素 + int index = umap[nums2[st.top()]]; // 根据map找到nums2[st.top()] 在 nums1中的下表 + result[index] = nums2[i]; + } + st.pop(); +} +st.push(i); +``` + +以上分析完毕,C++代码如下: + + +```C++ +// 版本一 +class Solution { +public: + vector nextGreaterElement(vector& nums1, vector& nums2) { + stack st; + vector result(nums1.size(), -1); + if (nums1.size() == 0) return result; + + unordered_map umap; // key:下表元素,value:下表 + for (int i = 0; i < nums1.size(); i++) { + umap[nums1[i]] = i; + } + st.push(0); + for (int i = 1; i < nums2.size(); i++) { + if (nums2[i] < nums2[st.top()]) { // 情况一 + st.push(i); + } else if (nums2[i] == nums2[st.top()]) { // 情况二 + st.push(i); + } else { // 情况三 + while (!st.empty() && nums2[i] > nums2[st.top()]) { + if (umap.count(nums2[st.top()]) > 0) { // 看map里是否存在这个元素 + int index = umap[nums2[st.top()]]; // 根据map找到nums2[st.top()] 在 nums1中的下表 + result[index] = nums2[i]; + } + st.pop(); + } + st.push(i); + } + } + return result; + } +}; +``` + +针对版本一,进行代码精简后,代码如下: + + +```C++ +// 版本二 +class Solution { +public: + vector nextGreaterElement(vector& nums1, vector& nums2) { + stack st; + vector result(nums1.size(), -1); + if (nums1.size() == 0) return result; + + unordered_map umap; // key:下表元素,value:下表 + for (int i = 0; i < nums1.size(); i++) { + umap[nums1[i]] = i; + } + st.push(0); + for (int i = 1; i < nums2.size(); i++) { + while (!st.empty() && nums2[i] > nums2[st.top()]) { + if (umap.count(nums2[st.top()]) > 0) { // 看map里是否存在这个元素 + int index = umap[nums2[st.top()]]; // 根据map找到nums2[st.top()] 在 nums1中的下表 + result[index] = nums2[i]; + } + st.pop(); + } + st.push(i); + } + return result; + } +}; +``` + +精简的代码是直接把情况一二三都合并到了一起,其实这种代码精简是精简,但思路不是很清晰。 + +建议大家把情况一二三想清楚了,先写出版本一的代码,然后在其基础上在做精简! + diff --git a/problems/背包理论基础01背包-1.md b/problems/背包理论基础01背包-1.md index 85bc7e42..2a99c97f 100644 --- a/problems/背包理论基础01背包-1.md +++ b/problems/背包理论基础01背包-1.md @@ -99,10 +99,17 @@ leetcode上没有纯01背包的问题,都是01背包应用方面的题目, 状态转移方程 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化。 -dp[0][j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。 +dp[0][j],即:i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。 -代码如下: -``` +那么很明显当 j < weight[0]的时候,dp[0][j] 应该是 0,因为背包容量比编号0的物品重量还小。 + +当j >= weight[0]是,dp[0][j] 应该是value[0],因为背包容量放足够放编号0物品。 + +代码初始化如下: +``` +for (int j = 0 ; j < weight[0]; j++) { // 当然这一步,如果把dp数组预先初始化为0了,这一步就可以省略,但很多同学应该没有想清楚这一点。 + dp[0][j] = 0; +} // 正序遍历 for (int j = weight[0]; j <= bagWeight; j++) { dp[0][j] = value[0]; @@ -116,14 +123,11 @@ for (int j = weight[0]; j <= bagWeight; j++) { dp[0][j] 和 dp[i][0] 都已经初始化了,那么其他下标应该初始化多少呢? +其实从递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 可以看出dp[i][j] 是又左上方数值推导出来了,那么 其他下标初始为什么数值都可以,因为都会被覆盖。 -dp[i][j]在推导的时候一定是取价值最大的数,如果题目给的价值都是正整数那么非0下标都初始化为0就可以了,因为0就是最小的了,不会影响取最大价值的结果。 +初始-1,初始-2,初始100,都可以! -如果题目给的价值有负数,那么非0下标就要初始化为负无穷了。例如:一个物品的价值是-2,但对应的位置依然初始化为0,那么取最大值的时候,就会取0而不是-2了,所以要初始化为负无穷。 - -而背包问题的物品价值都是正整数,所以初始化为0,就可以了。 - -**这样才能让dp数组在递归公式的过程中取最大的价值,而不是被初始值覆盖了**。 +但只不过一开始就统一把dp数组统一初始为0,更方便一些。 如图: @@ -159,7 +163,7 @@ for (int j = weight[0]; j <= bagWeight; j++) { // weight数组的大小 就是物品个数 for(int i = 1; i < weight.size(); i++) { // 遍历物品 for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量 - if (j < weight[i]) dp[i][j] = dp[i - 1][j]; // 这个是为了展现dp数组里元素的变化 + if (j < weight[i]) dp[i][j] = dp[i - 1][j]; else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); }