From f8004f9b41bc011f8e961f3065dbab61f1f63a7d Mon Sep 17 00:00:00 2001 From: simonhancrew <597494370@qq.com> Date: Thu, 27 May 2021 15:58:22 +0800 Subject: [PATCH 01/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200977.=E6=9C=89?= =?UTF-8?q?=E5=BA=8F=E6=95=B0=E7=BB=84=E7=9A=84=E5=B9=B3=E6=96=B9=20Python?= =?UTF-8?q?3=20Go=20Rust=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0977.有序数组的平方.md | 60 +++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/problems/0977.有序数组的平方.md b/problems/0977.有序数组的平方.md index 167a258c..b5d392e6 100644 --- a/problems/0977.有序数组的平方.md +++ b/problems/0977.有序数组的平方.md @@ -100,10 +100,66 @@ public: Java: Python: - +```Python +class Solution: + def sortedSquares(self, nums: List[int]) -> List[int]: + n = len(nums) + i,j,k = 0,n - 1,n - 1 + ans = [-1] * n + while i <= j: + lm = nums[i] ** 2 + rm = nums[j] ** 2 + if lm > rm: + ans[k] = lm + i += 1 + else: + ans[k] = rm + j -= 1 + k -= 1 + return ans +``` Go: - +```Go +func sortedSquares(nums []int) []int { + n := len(nums) + i, j, k := 0, n-1, n-1 + ans := make([]int, n) + for i <= j { + lm, rm := nums[i]*nums[i], nums[j]*nums[j] + if lm > rm { + ans[k] = lm + i++ + } else { + ans[k] = rm + j-- + } + k-- + } + return ans +} +``` +Rust +``` +impl Solution { + pub fn sorted_squares(nums: Vec) -> Vec { + let n = nums.len(); + let (mut i,mut j,mut k) = (0,n - 1,n- 1); + let mut ans = vec![0;n]; + while i <= j{ + if nums[i] * nums[i] < nums[j] * nums[j] { + ans[k] = nums[j] * nums[j]; + j -= 1; + }else{ + ans[k] = nums[i] * nums[i]; + i += 1; + } + k -= 1; + } + ans + } +} +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From 597f24d2a07341d2dadcc1ecbfdbff372863377c Mon Sep 17 00:00:00 2001 From: boom-jumper <56831966+boom-jumper@users.noreply.github.com> Date: Thu, 27 May 2021 20:30:37 +0800 Subject: [PATCH 02/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A00232=E7=94=A8=E6=A0=88?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E9=98=9F=E5=88=97=20python3=20=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/0232.用栈实现队列.md | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md index 10314a08..c2af71f7 100644 --- a/problems/0232.用栈实现队列.md +++ b/problems/0232.用栈实现队列.md @@ -282,6 +282,50 @@ class MyQueue { Python: +```python +# 使用两个栈实现先进先出的队列 +class MyQueue: + def __init__(self): + """ + Initialize your data structure here. + """ + self.stack1 = list() + self.stack2 = list() + + def push(self, x: int) -> None: + """ + Push element x to the back of queue. + """ + # self.stack1用于接受元素 + self.stack1.append(x) + + def pop(self) -> int: + """ + Removes the element from in front of queue and returns that element. + """ + # self.stack2用于弹出元素,如果self.stack2为[],则将self.stack1中元素全部弹出给self.stack2 + if self.stack2 == []: + while self.stack1: + tmp = self.stack1.pop() + self.stack2.append(tmp) + return self.stack2.pop() + + def peek(self) -> int: + """ + Get the front element. + """ + if self.stack2 == []: + while self.stack1: + tmp = self.stack1.pop() + self.stack2.append(tmp) + return self.stack2[-1] + + def empty(self) -> bool: + """ + Returns whether the queue is empty. + """ + return self.stack1 == [] and self.stack2 == [] +``` Go: From 0ae9d1808cf4db850f28ad9cfa837506bfec9588 Mon Sep 17 00:00:00 2001 From: boom-jumper <56831966+boom-jumper@users.noreply.github.com> Date: Thu, 27 May 2021 20:37:53 +0800 Subject: [PATCH 03/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A00150=E9=80=86=E6=B3=A2?= =?UTF-8?q?=E5=85=B0=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=B1=82=E5=80=BC=20python?= =?UTF-8?q?3=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0150.逆波兰表达式求值.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md index e38bc1a3..c8b0da08 100644 --- a/problems/0150.逆波兰表达式求值.md +++ b/problems/0150.逆波兰表达式求值.md @@ -224,6 +224,22 @@ var evalRPN = function(tokens) { }; ``` +python3 + +```python +def evalRPN(tokens) -> int: + stack = list() + for i in range(len(tokens)): + if tokens[i] not in ["+", "-", "*", "/"]: + stack.append(tokens[i]) + else: + tmp1 = stack.pop() + tmp2 = stack.pop() + res = eval(tmp2+tokens[i]+tmp1) + stack.append(str(int(res))) + return stack[-1] +``` + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From d7235d9f51b532dda387bf6e00be225f931ed275 Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Thu, 27 May 2021 21:39:32 +0800 Subject: [PATCH 04/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=2002.07.=E9=93=BE?= =?UTF-8?q?=E8=A1=A8=E7=9B=B8=E4=BA=A4=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/面试题02.07.链表相交.md | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/problems/面试题02.07.链表相交.md b/problems/面试题02.07.链表相交.md index 9e97264c..13014dd1 100644 --- a/problems/面试题02.07.链表相交.md +++ b/problems/面试题02.07.链表相交.md @@ -155,6 +155,42 @@ Python: Go: +```go +func getIntersectionNode(headA, headB *ListNode) *ListNode { + curA := headA + curB := headB + lenA, lenB := 0, 0 + // 求A,B的长度 + for curA != nil { + curA = curA.Next + lenA++ + } + for curB != nil { + curB = curB.Next + lenB++ + } + var step int + var fast, slow *ListNode + // 请求长度差,并且让更长的链表先走相差的长度 + if lenA > lenB { + step = lenA - lenB + fast, slow = headA, headB + } else { + step = lenB - lenA + fast, slow = headB, headA + } + for i:=0; i < step; i++ { + fast = fast.Next + } + // 遍历两个链表遇到相同则跳出遍历 + for fast != slow { + fast = fast.Next + slow = slow.Next + } + return fast +} +``` + javaScript: ```js From 7f3b661add171dab5cee5ebae5516962cf55cf3e Mon Sep 17 00:00:00 2001 From: zqh1059405318 <1059405318@qq.com> Date: Thu, 27 May 2021 23:44:00 +0800 Subject: [PATCH 05/95] =?UTF-8?q?=E6=9B=B4=E6=96=B00541.=E5=8F=8D=E8=BD=AC?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2II=20Java=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0541.反转字符串II.md | 33 ++++++++++++++---------------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/problems/0541.反转字符串II.md b/problems/0541.反转字符串II.md index db53caf7..6c8f3e94 100644 --- a/problems/0541.反转字符串II.md +++ b/problems/0541.反转字符串II.md @@ -106,27 +106,24 @@ Java: class Solution { public String reverseStr(String s, int k) { StringBuffer res = new StringBuffer(); - - for (int i = 0; i < s.length(); i += (2 * k)) { + int length = s.length(); + int start = 0; + while (start < length) { + // 找到k处和2k处 StringBuffer temp = new StringBuffer(); - // 剩余字符大于 k 个,每隔 2k 个字符的前 k 个字符进行反转 - if (i + k <= s.length()) { - // 反转前 k 个字符 - temp.append(s.substring(i, i + k)); - res.append(temp.reverse()); + // 与length进行判断,如果大于length了,那就将其置为length + int firstK = (start + k > length) ? length : start + k; + int secondK = (start + (2 * k) > length) ? length : start + (2 * k); - // 反转完前 k 个字符之后,如果紧接着还有 k 个字符,则直接加入这 k 个字符 - if (i + 2 * k <= s.length()) { - res.append(s.substring(i + k, i + 2 * k)); - // 不足 k 个字符,则直接加入剩下所有字符 - } else { - res.append(s.substring(i + k, s.length())); - } - continue; - } - // 剩余字符少于 k 个,则将剩余字符全部反转。 - temp.append(s.substring(i, s.length())); + //无论start所处位置,至少会反转一次 + temp.append(s.substring(start, firstK)); res.append(temp.reverse()); + + // 如果firstK到secondK之间有元素,这些元素直接放入res里即可。 + if (firstK < secondK) { //此时剩余长度一定大于k。 + res.append(s.substring(firstK, secondK)); + } + start += (2 * k); } return res.toString(); } From ce1a80b0166b8f37c03c3ed867dc6d89279f345a Mon Sep 17 00:00:00 2001 From: jojoo15 <75017412+jojoo15@users.noreply.github.com> Date: Thu, 27 May 2021 18:01:48 +0200 Subject: [PATCH 06/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200078.=E5=AD=90?= =?UTF-8?q?=E9=9B=86=20python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0078.子集 python3版本 --- problems/0078.子集.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/problems/0078.子集.md b/problems/0078.子集.md index 17c4fb5c..0b2f3c09 100644 --- a/problems/0078.子集.md +++ b/problems/0078.子集.md @@ -205,7 +205,20 @@ class Solution { ``` Python: - +```python3 +class Solution: + def subsets(self, nums: List[int]) -> List[List[int]]: + res = [] + path = [] + def backtrack(nums,startIndex): + res.append(path[:]) #收集子集,要放在终止添加的上面,否则会漏掉自己 + for i in range(startIndex,len(nums)): #当startIndex已经大于数组的长度了,就终止了,for循环本来也结束了,所以不需要终止条件 + path.append(nums[i]) + backtrack(nums,i+1) #递归 + path.pop() #回溯 + backtrack(nums,0) + return res +``` Go: ```Go From c722642392ab8853f91ffac654149531b8117973 Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Fri, 28 May 2021 00:33:17 +0800 Subject: [PATCH 07/95] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200142.=E7=8E=AF?= =?UTF-8?q?=E5=BD=A2=E9=93=BE=E8=A1=A8II=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1、原先的Go版本代码显示错乱,一部分代码未显示 2、去掉多余判断,让代码更简洁 --- problems/0142.环形链表II.md | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/problems/0142.环形链表II.md b/problems/0142.环形链表II.md index 15c2d1f9..9deb1e0c 100644 --- a/problems/0142.环形链表II.md +++ b/problems/0142.环形链表II.md @@ -234,25 +234,19 @@ class Solution: ``` Go: -```func detectCycle(head *ListNode) *ListNode { - if head ==nil{ - return head - } - slow:=head - fast:=head.Next - - for fast!=nil&&fast.Next!=nil{ - if fast==slow{ - slow=head - fast=fast.Next - for fast!=slow { - fast=fast.Next - slow=slow.Next +```go +func detectCycle(head *ListNode) *ListNode { + slow, fast := head, head + for fast != nil && fast.Next != nil { + slow = slow.Next + fast = fast.Next.Next + if slow == fast { + for slow != head { + slow = slow.Next + head = head.Next } - return slow + return head } - fast=fast.Next.Next - slow=slow.Next } return nil } From b41866f1f4a2fcc7c631bbaf9de5166465a7586c Mon Sep 17 00:00:00 2001 From: jojoo15 <75017412+jojoo15@users.noreply.github.com> Date: Thu, 27 May 2021 18:57:04 +0200 Subject: [PATCH 08/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200090.=E5=AD=90?= =?UTF-8?q?=E9=9B=86=20python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0090.子集 python3版本 --- problems/0090.子集II.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/problems/0090.子集II.md b/problems/0090.子集II.md index 6b12a95b..71aef5c7 100644 --- a/problems/0090.子集II.md +++ b/problems/0090.子集II.md @@ -208,7 +208,23 @@ class Solution { ``` Python: - +```python3 +class Solution: + def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: + res = [] #存放符合条件结果的集合 + path = [] #用来存放符合条件结果 + def backtrack(nums,startIndex): + res.append(path[:]) + for i in range(startIndex,len(nums)): + if i > startIndex and nums[i] == nums[i - 1]: #我们要对同一树层使用过的元素进行跳过 + continue + path.append(nums[i]) + backtrack(nums,i+1) #递归 + path.pop() #回溯 + nums = sorted(nums) #去重需要排序 + backtrack(nums,0) + return res +``` Go: ```Go From 60624686a894dadcfefb79cd38e40f0308217f93 Mon Sep 17 00:00:00 2001 From: jojoo15 <75017412+jojoo15@users.noreply.github.com> Date: Fri, 28 May 2021 00:09:28 +0200 Subject: [PATCH 09/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200491.=E9=80=92?= =?UTF-8?q?=E5=A2=9E=E5=AD=90=E5=BA=8F=E5=88=97=20python3=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0491.递增子序列 python3版本 --- problems/0491.递增子序列.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/problems/0491.递增子序列.md b/problems/0491.递增子序列.md index 691f7aef..5538a2c9 100644 --- a/problems/0491.递增子序列.md +++ b/problems/0491.递增子序列.md @@ -229,7 +229,28 @@ class Solution { Python: - +```python3 +class Solution: + def findSubsequences(self, nums: List[int]) -> List[List[int]]: + res = [] + path = [] + def backtrack(nums,startIndex): + repeat = [] #这里使用数组来进行去重操作 + if len(path) >=2: + res.append(path[:]) #注意这里不要加return,要取树上的节点 + for i in range(startIndex,len(nums)): + if nums[i] in repeat: + continue + if len(path) >= 1: + if nums[i] < path[-1]: + continue + repeat.append(nums[i]) #记录这个元素在本层用过了,本层后面不能再用了 + path.append(nums[i]) + backtrack(nums,i+1) + path.pop() + backtrack(nums,0) + return res +``` Go: From 6c33729d9f15ea6db9f9497c70bb87081394b2c1 Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Fri, 28 May 2021 08:11:56 +0800 Subject: [PATCH 10/95] =?UTF-8?q?0055.=E8=B7=B3=E8=B7=83=E6=B8=B8=E6=88=8F?= =?UTF-8?q?.md=20Javascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0055.跳跃游戏.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/problems/0055.跳跃游戏.md b/problems/0055.跳跃游戏.md index b4b42a4a..8618515e 100644 --- a/problems/0055.跳跃游戏.md +++ b/problems/0055.跳跃游戏.md @@ -141,7 +141,20 @@ func canJUmp(nums []int) bool { } ``` - +Javascript: +```Javascript +var canJump = function(nums) { + if(nums.length === 1) return true + let cover = 0 + for(let i = 0; i <= cover; i++) { + cover = Math.max(cover, i + nums[i]) + if(cover >= nums.length - 1) { + return true + } + } + return false +}; +``` ----------------------- From c01a968b92f97c98433432bfabc769c22d5f0f1c Mon Sep 17 00:00:00 2001 From: xll <18574553598@163.com> Date: Fri, 28 May 2021 11:05:37 +0800 Subject: [PATCH 11/95] =?UTF-8?q?0404=E5=B7=A6=E5=8F=B6=E5=AD=90=E4=B9=8B?= =?UTF-8?q?=E5=92=8CJavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0404.左叶子之和.md | 46 +++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/problems/0404.左叶子之和.md b/problems/0404.左叶子之和.md index 30d702b4..e5daa9db 100644 --- a/problems/0404.左叶子之和.md +++ b/problems/0404.左叶子之和.md @@ -226,7 +226,51 @@ class Solution: ``` Go: - +JavaScript: +递归版本 +```javascript +var sumOfLeftLeaves = function(root) { + //采用后序遍历 递归遍历 + // 1. 确定递归函数参数 + const nodesSum = function(node){ + // 2. 确定终止条件 + if(node===null){ + return 0; + } + let leftValue = sumOfLeftLeaves(node.left); + let rightValue = sumOfLeftLeaves(node.right); + // 3. 单层递归逻辑 + let midValue = 0; + if(node.left&&node.left.left===null&&node.left.right===null){ + midValue = node.left.val; + } + let sum = midValue + leftValue + rightValue; + return sum; + } + return nodesSum(root); +}; +``` +迭代版本 +```javascript +var sumOfLeftLeaves = function(root) { + //采用层序遍历 + if(root===null){ + return null; + } + let queue = []; + let sum = 0; + queue.push(root); + while(queue.length){ + let node = queue.shift(); + if(node.left!==null&&node.left.left===null&&node.left.right===null){ + sum+=node.left.val; + } + node.left&&queue.push(node.left); + node.right&&queue.push(node.right); + } + return sum; +}; +``` From f6a9d649ea71d8d0685423278b8c3879fb8143f4 Mon Sep 17 00:00:00 2001 From: LiangDazhu <42199191+LiangDazhu@users.noreply.github.com> Date: Fri, 28 May 2021 16:30:11 +0800 Subject: [PATCH 12/95] =?UTF-8?q?Update=200343.=E6=95=B4=E6=95=B0=E6=8B=86?= =?UTF-8?q?=E5=88=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added python version code 有一行文本我觉得写重复了, 给删掉了 --- problems/0343.整数拆分.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/problems/0343.整数拆分.md b/problems/0343.整数拆分.md index c9423a1a..fefaa293 100644 --- a/problems/0343.整数拆分.md +++ b/problems/0343.整数拆分.md @@ -51,10 +51,6 @@ dp[i]的定义讲贯彻整个解题过程,下面哪一步想不懂了,就想 **那有同学问了,j怎么就不拆分呢?** -j是从1开始遍历,拆分j的情况,在遍历j的过程中其实都计算过了。 - -**那有同学问了,j怎么就不拆分呢?** - j是从1开始遍历,拆分j的情况,在遍历j的过程中其实都计算过了。那么从1遍历j,比较(i - j) * j和dp[i - j] * j 取最大的。递推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j)); 也可以这么理解,j * (i - j) 是单纯的把整数拆分为两个数相乘,而j * dp[i - j]是拆分成两个以及两个以上的个数相乘。 @@ -213,8 +209,19 @@ class Solution { ``` Python: - - +```python +class Solution: + def integerBreak(self, n: int) -> int: + dp = [0] * (n + 1) + dp[2] = 1 + for i in range(3, n + 1): + # 假设对正整数 i 拆分出的第一个正整数是 j(1 <= j < i),则有以下两种方案: + # 1) 将 i 拆分成 j 和 i−j 的和,且 i−j 不再拆分成多个正整数,此时的乘积是 j * (i-j) + # 2) 将 i 拆分成 j 和 i−j 的和,且 i−j 继续拆分成多个正整数,此时的乘积是 j * dp[i-j] + for j in range(1, i): + dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j])) + return dp[n] +``` Go: From f9686c7d84422f9403ded97760c8b2e2d653e090 Mon Sep 17 00:00:00 2001 From: jojoo15 <75017412+jojoo15@users.noreply.github.com> Date: Fri, 28 May 2021 11:19:43 +0200 Subject: [PATCH 13/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200046.=E5=85=A8?= =?UTF-8?q?=E6=8E=92=E5=88=97=20python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0046.全排列 python3版本 --- problems/0046.全排列.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/problems/0046.全排列.md b/problems/0046.全排列.md index 0beb45cf..6e5b528e 100644 --- a/problems/0046.全排列.md +++ b/problems/0046.全排列.md @@ -182,7 +182,26 @@ class Solution { ``` Python: - +```python3 +class Solution: + def permute(self, nums: List[int]) -> List[List[int]]: + res = [] #存放符合条件结果的集合 + path = [] #用来存放符合条件的结果 + used = [] #用来存放已经用过的数字 + def backtrack(nums,used): + if len(path) == len(nums): + return res.append(path[:]) #此时说明找到了一组 + for i in range(0,len(nums)): + if nums[i] in used: + continue #used里已经收录的元素,直接跳过 + path.append(nums[i]) + used.append(nums[i]) + backtrack(nums,used) + used.pop() + path.pop() + backtrack(nums,used) + return res +``` Go: ```Go From 14221a52fe02d489330b6fc254d187de99c99ae2 Mon Sep 17 00:00:00 2001 From: jojoo15 <75017412+jojoo15@users.noreply.github.com> Date: Fri, 28 May 2021 11:26:43 +0200 Subject: [PATCH 14/95] =?UTF-8?q?=E6=9B=B4=E6=96=B0=200046.=E5=85=A8?= =?UTF-8?q?=E6=8E=92=E5=88=97=20python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新 0046.全排列 python3版本,比之前那个更简洁一点,少了个used数组 --- problems/0046.全排列.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/problems/0046.全排列.md b/problems/0046.全排列.md index 0beb45cf..3ead73e3 100644 --- a/problems/0046.全排列.md +++ b/problems/0046.全排列.md @@ -182,7 +182,23 @@ class Solution { ``` Python: - +```python3 +class Solution: + def permute(self, nums: List[int]) -> List[List[int]]: + res = [] #存放符合条件结果的集合 + path = [] #用来存放符合条件的结果 + def backtrack(nums): + if len(path) == len(nums): + return res.append(path[:]) #此时说明找到了一组 + for i in range(0,len(nums)): + if nums[i] in path: #path里已经收录的元素,直接跳过 + continue + path.append(nums[i]) + backtrack(nums) #递归 + path.pop() #回溯 + backtrack(nums) + return res +``` Go: ```Go From 60d89d920053650736e17fa814d020deedcda89e Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Fri, 28 May 2021 22:59:27 +0800 Subject: [PATCH 15/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200349.=E4=B8=A4?= =?UTF-8?q?=E4=B8=AA=E6=95=B0=E7=BB=84=E7=9A=84=E4=BA=A4=E9=9B=86=20go?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0349.两个数组的交集.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/0349.两个数组的交集.md b/problems/0349.两个数组的交集.md index fe019a0a..090480a4 100644 --- a/problems/0349.两个数组的交集.md +++ b/problems/0349.两个数组的交集.md @@ -132,6 +132,23 @@ class Solution: Go: +```go +func intersection(nums1 []int, nums2 []int) []int { + m := make(map[int]int) + for _, v := range nums1 { + m[v] = 1 + } + var res []int + // 利用count>0,实现重复值只拿一次放入返回结果中 + for _, v := range nums2 { + if count, ok := m[v]; ok && count > 0 { + res = append(res, v) + m[v]-- + } + } + return res +} +``` javaScript: From 1590897824de40843710804d6a0397eca0131ee1 Mon Sep 17 00:00:00 2001 From: LiangDazhu <42199191+LiangDazhu@users.noreply.github.com> Date: Fri, 28 May 2021 23:33:19 +0800 Subject: [PATCH 16/95] =?UTF-8?q?Update=200096.=E4=B8=8D=E5=90=8C=E7=9A=84?= =?UTF-8?q?=E4=BA=8C=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 Added python version code --- problems/0096.不同的二叉搜索树.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/problems/0096.不同的二叉搜索树.md b/problems/0096.不同的二叉搜索树.md index cee0102f..a9631315 100644 --- a/problems/0096.不同的二叉搜索树.md +++ b/problems/0096.不同的二叉搜索树.md @@ -186,7 +186,16 @@ class Solution { ``` Python: - +```python +class Solution: + def numTrees(self, n: int) -> int: + dp = [0] * (n + 1) + dp[0], dp[1] = 1, 1 + for i in range(2, n + 1): + for j in range(1, i + 1): + dp[i] += dp[j - 1] * dp[i - j] + return dp[-1] +``` Go: ```Go From c4de753d6db1548205de14efdb4fc9194d7223c4 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 29 May 2021 08:07:50 +0800 Subject: [PATCH 17/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200020.=E6=9C=89?= =?UTF-8?q?=E6=95=88=E7=9A=84=E6=8B=AC=E5=8F=B7=20Ruby=20=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/0015.三数之和.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md index 811fc316..4f4ec63a 100644 --- a/problems/0015.三数之和.md +++ b/problems/0015.三数之和.md @@ -336,6 +336,23 @@ var threeSum = function(nums) { ``` +ruby: +```ruby +def is_valid(strs) + symbol_map = {')' => '(', '}' => '{', ']' => '['} + stack = [] + strs.size.times {|i| + c = strs[i] + if symbol_map.has_key?(c) + top_e = stack.shift + return false if symbol_map[c] != top_e + else + stack.unshift(c) + end + } + stack.empty? +end +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From bd95f6a248f9175216582225500e3c074f0c4180 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 29 May 2021 09:12:26 +0800 Subject: [PATCH 18/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200027.=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=85=83=E7=B4=A0=20Ruby=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0027.移除元素.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/problems/0027.移除元素.md b/problems/0027.移除元素.md index 8da0fb89..f0f61d06 100644 --- a/problems/0027.移除元素.md +++ b/problems/0027.移除元素.md @@ -186,6 +186,20 @@ var removeElement = (nums, val) => { }; ``` +Ruby: +```ruby +def remove_element(nums, val) + i = 0 + nums.each_index do |j| + if nums[j] != val + nums[i] = nums[j] + i+=1 + end + end + i +end +``` + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) From 5512ccdb63370be27a387acab0c1ae366607b089 Mon Sep 17 00:00:00 2001 From: xll <18574553598@163.com> Date: Sat, 29 May 2021 10:44:58 +0800 Subject: [PATCH 19/95] =?UTF-8?q?0513=E4=BA=8C=E5=8F=89=E6=A0=91=E5=B7=A6?= =?UTF-8?q?=E5=B0=8F=E8=A7=92=E7=9A=84=E5=80=BCJavaScript=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/0513.找树左下角的值.md | 47 ++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/problems/0513.找树左下角的值.md b/problems/0513.找树左下角的值.md index 5c9613e5..97464e3d 100644 --- a/problems/0513.找树左下角的值.md +++ b/problems/0513.找树左下角的值.md @@ -298,6 +298,53 @@ class Solution: ``` Go: +JavaScript: +1. 递归版本 +```javascript +var findBottomLeftValue = function(root) { + //首先考虑递归遍历 前序遍历 找到最大深度的叶子节点即可 + let maxPath = 0,resNode = null; + // 1. 确定递归函数的函数参数 + const dfsTree = function(node,curPath){ + // 2. 确定递归函数终止条件 + if(node.left===null&&node.right===null){ + if(curPath>maxPath){ + maxPath = curPath; + resNode = node.val; + } + // return ; + } + node.left&&dfsTree(node.left,curPath+1); + node.right&&dfsTree(node.right,curPath+1); + } + dfsTree(root,1); + return resNode; +}; +``` +2. 层序遍历 +```javascript +var findBottomLeftValue = function(root) { + //考虑层序遍历 记录最后一行的第一个节点 + let queue = []; + if(root===null){ + return null; + } + queue.push(root); + let resNode; + while(queue.length){ + let length = queue.length; + for(let i=0; i Date: Sat, 29 May 2021 12:50:49 +0800 Subject: [PATCH 20/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=861047-golang?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...除字符串中的所有相邻重复项.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 9ca08c96..305a287d 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -186,6 +186,23 @@ class Solution: Go: +```go +func removeDuplicates(s string) string { + var stack []byte + for i := 0; i < len(s);i++ { + // 栈不空 且 与栈顶元素不等 + if len(stack) > 0 && stack[len(stack)-1] == s[i] { + // 弹出栈顶元素 并 忽略当前元素(s[i]) + stack = stack[:len(stack)-1] + }else{ + // 入栈 + stack = append(stack, s[i]) + } + } + return string(stack) +} +``` + javaScript: ```js From fb91b760eb6fa0583210ca260b77f71418787ab8 Mon Sep 17 00:00:00 2001 From: hk27xing <244798299@qq.com> Date: Sat, 29 May 2021 16:13:32 +0800 Subject: [PATCH 21/95] =?UTF-8?q?=E7=BA=A0=E6=AD=A339.=E7=BB=84=E5=90=88?= =?UTF-8?q?=E6=80=BB=E5=92=8C=20Java=E7=89=88=E6=9C=AC=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0039.组合总和.md | 40 +++++++++++++++-------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/problems/0039.组合总和.md b/problems/0039.组合总和.md index ab118ee0..a83e42f4 100644 --- a/problems/0039.组合总和.md +++ b/problems/0039.组合总和.md @@ -237,34 +237,28 @@ public: Java: ```Java +// 剪枝优化 class Solution { - List> lists = new ArrayList<>(); - Deque deque = new LinkedList<>(); - - public List> combinationSum3(int k, int n) { - int[] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; - backTracking(arr, n, k, 0); - return lists; + public List> combinationSum(int[] candidates, int target) { + List> res = new ArrayList<>(); + Arrays.sort(candidates); // 先进行排序 + backtracking(res, new ArrayList<>(), candidates, target, 0, 0); + return res; } - public void backTracking(int[] arr, int n, int k, int startIndex) { - //如果 n 小于0,没必要继续本次递归,已经不符合要求了 - if (n < 0) { + public void backtracking(List> res, List path, int[] candidates, int target, int sum, int idx) { + // 找到了数字和为 target 的组合 + if (sum == target) { + res.add(new ArrayList<>(path)); return; } - if (deque.size() == k) { - if (n == 0) { - lists.add(new ArrayList(deque)); - } - return; - } - for (int i = startIndex; i < arr.length - (k - deque.size()) + 1; i++) { - deque.push(arr[i]); - //减去当前元素 - n -= arr[i]; - backTracking(arr, n, k, i + 1); - //恢复n - n += deque.pop(); + + for (int i = idx; i < candidates.length; i++) { + // 如果 sum + candidates[i] > target 就终止遍历 + if (sum + candidates[i] > target) break; + path.add(candidates[i]); + backtracking(res, path, candidates, target, sum + candidates[i], i); + path.remove(path.size() - 1); // 回溯,移除路径 path 最后一个元素 } } } From b1b389da3204c4faf0c65519e8f58cf59afe18d4 Mon Sep 17 00:00:00 2001 From: xll <18574553598@163.com> Date: Sat, 29 May 2021 22:20:52 +0800 Subject: [PATCH 22/95] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E6=80=BB=E5=92=8CJavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0112.路径总和.md | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md index b4a3f38b..4ccd8912 100644 --- a/problems/0112.路径总和.md +++ b/problems/0112.路径总和.md @@ -524,6 +524,62 @@ let pathSum = function (root, targetSum) { }; ``` +0112 路径总和 +```javascript +var hasPathSum = function(root, targetSum) { + //递归方法 + // 1. 确定函数参数 + const traversal = function(node,count){ + // 2. 确定终止条件 + if(node.left===null&&node.right===null&&count===0){ + return true; + } + if(node.left===null&&node.right===null){ + return false; + } + //3. 单层递归逻辑 + if(node.left){ + if(traversal(node.left,count-node.left.val)){ + return true; + } + } + if(node.right){ + if(traversal(node.right,count-node.right.val)){ + return true; + } + } + return false; + } + if(root===null){ + return false; + } + return traversal(root,targetSum-root.val); +}; +``` +113 路径总和 +```javascript +var pathSum = function(root, targetSum) { + //递归方法 + let resPath = [],curPath = []; + // 1. 确定递归函数参数 + const travelTree = function(node,count){ + curPath.push(node.val); + count-=node.val; + if(node.left===null&&node.right===null&&count===0){ + resPath.push([...curPath]); + } + node.left&&travelTree(node.left,count); + node.right&&travelTree(node.right,count); + let cur = curPath.pop(); + count-=cur; + } + if(root===null){ + return resPath; + } + travelTree(root,targetSum); + return resPath; +}; +``` From 406d44819ac878232b49a6ffafad06d944643a6a Mon Sep 17 00:00:00 2001 From: X-shuffle <53906918+X-shuffle@users.noreply.github.com> Date: Sun, 30 May 2021 10:38:30 +0800 Subject: [PATCH 23/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=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=20GO?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 二叉树的层序遍历 GO版本 --- problems/0102.二叉树的层序遍历.md | 243 ++++++++++++++++++++++ 1 file changed, 243 insertions(+) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index ee93911e..00607082 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -836,6 +836,249 @@ func levelOrder(root *TreeNode) [][]int { return result } ``` +> 二叉树的层序遍历(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 +} +/** +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 Date: Sun, 30 May 2021 14:07:55 +0800 Subject: [PATCH 24/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200203.=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E9=93=BE=E8=A1=A8=E5=85=83=E7=B4=A0=20python3?= =?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/0203.移除链表元素.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md index dce5d265..cac9f233 100644 --- a/problems/0203.移除链表元素.md +++ b/problems/0203.移除链表元素.md @@ -208,7 +208,23 @@ public ListNode removeElements(ListNode head, int val) { ``` 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 removeElements(self, head: ListNode, val: int) -> ListNode: + dummy_head = ListNode(next=head) #添加一个虚拟节点 + cur = dummy_head + while(cur.next!=None): + if(cur.next.val == val): + cur.next = cur.next.next #删除cur.next节点 + else: + cur = cur.next + return dummy_head.next +``` Go: From 5e1860876b8d594d2e4d74a03772495c06cc357f Mon Sep 17 00:00:00 2001 From: evanlai Date: Sun, 30 May 2021 14:10:11 +0800 Subject: [PATCH 25/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200206.=E7=BF=BB?= =?UTF-8?q?=E8=BD=AC=E9=93=BE=E8=A1=A8=20python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0206.翻转链表.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/problems/0206.翻转链表.md b/problems/0206.翻转链表.md index 52ef6484..7c002382 100644 --- a/problems/0206.翻转链表.md +++ b/problems/0206.翻转链表.md @@ -143,7 +143,25 @@ class Solution { ``` Python: - +```python +#双指针 +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def reverseList(self, head: ListNode) -> ListNode: + cur = head + pre = None + while(cur!=None): + temp = cur.next # 保存一下 cur的下一个节点,因为接下来要改变cur->next + cur.next = pre #反转 + #更新pre、cur指针 + pre = cur + cur = temp + return pre +``` Go: From 013ba0575ed1729e8a1c31c251313e379d38adc2 Mon Sep 17 00:00:00 2001 From: evanlai Date: Sun, 30 May 2021 14:13:38 +0800 Subject: [PATCH 26/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200019.=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E9=93=BE=E8=A1=A8=E7=9A=84=E5=80=92=E6=95=B0=E7=AC=AC?= =?UTF-8?q?N=E4=B8=AA=E8=8A=82=E7=82=B9=20python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0019.删除链表的倒数第N个节点.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/problems/0019.删除链表的倒数第N个节点.md b/problems/0019.删除链表的倒数第N个节点.md index 7d2fe97e..52735794 100644 --- a/problems/0019.删除链表的倒数第N个节点.md +++ b/problems/0019.删除链表的倒数第N个节点.md @@ -112,6 +112,30 @@ class Solution { } } ``` + +Python: +```python +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, val=0, next=None): +# self.val = val +# self.next = next +class Solution: + def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: + head_dummy = ListNode() + head_dummy.next = head + + slow, fast = head_dummy, head_dummy + while(n!=0): #fast先往前走n步 + fast = fast.next + n -= 1 + while(fast.next!=None): + slow = slow.next + fast = fast.next + #fast 走到结尾后,slow的下一个节点为倒数第N个节点 + slow.next = slow.next.next #删除 + return head_dummy.next +``` Go: ```Go /** From e98fb5a56f256371d01ed7e9456aa0fde805626f Mon Sep 17 00:00:00 2001 From: evanlai Date: Sun, 30 May 2021 14:21:41 +0800 Subject: [PATCH 27/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E9=9D=A2=E8=AF=95?= =?UTF-8?q?=E9=A2=9802.07.=E9=93=BE=E8=A1=A8=E7=9B=B8=E4=BA=A4=20python3?= =?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/面试题02.07.链表相交.md | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/problems/面试题02.07.链表相交.md b/problems/面试题02.07.链表相交.md index 13014dd1..78f34e71 100644 --- a/problems/面试题02.07.链表相交.md +++ b/problems/面试题02.07.链表相交.md @@ -151,7 +151,44 @@ public class Solution { ``` Python: +```python +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None +class Solution: + def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: + lengthA,lengthB = 0,0 + curA,curB = headA,headB + while(curA!=None): #求链表A的长度 + curA = curA.next + lengthA +=1 + + while(curB!=None): #求链表B的长度 + curB = curB.next + lengthB +=1 + + curA, curB = headA, headB + + if lengthB>lengthA: #让curA为最长链表的头,lenA为其长度 + lengthA, lengthB = lengthB, lengthA + curA, curB = curB, curA + + gap = lengthA - lengthB #求长度差 + while(gap!=0): + curA = curA.next #让curA和curB在同一起点上 + gap -= 1 + + while(curA!=None): + if curA == curB: + return curA + else: + curA = curA.next + curB = curB.next + return None +``` Go: From bf2ffec6674a429663a11aca03abbd9f36a9864c Mon Sep 17 00:00:00 2001 From: LiangDazhu <42199191+LiangDazhu@users.noreply.github.com> Date: Sun, 30 May 2021 19:21:51 +0800 Subject: [PATCH 28/95] =?UTF-8?q?Update=200416.=E5=88=86=E5=89=B2=E7=AD=89?= =?UTF-8?q?=E5=92=8C=E5=AD=90=E9=9B=86.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added python version code --- problems/0416.分割等和子集.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/problems/0416.分割等和子集.md b/problems/0416.分割等和子集.md index e69eb1a4..55d200e2 100644 --- a/problems/0416.分割等和子集.md +++ b/problems/0416.分割等和子集.md @@ -222,8 +222,18 @@ class Solution { ``` Python: - - +```python +class Solution: + def canPartition(self, nums: List[int]) -> bool: + taraget = sum(nums) + if taraget % 2 == 1: return False + taraget //= 2 + dp = [0] * 10001 + for i in range(len(nums)): + for j in range(taraget, nums[i] - 1, -1): + dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]) + return taraget == dp[taraget] +``` Go: From 1516dc3d152b818f1e3d4f3675924c35918e0558 Mon Sep 17 00:00:00 2001 From: resyon Date: Sun, 30 May 2021 21:27:11 +0800 Subject: [PATCH 29/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=860239-golang?= =?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/0239.滑动窗口最大值.md | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md index 6cc355ca..ed17157a 100644 --- a/problems/0239.滑动窗口最大值.md +++ b/problems/0239.滑动窗口最大值.md @@ -267,6 +267,36 @@ Python: 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 + +} + +``` + Javascript: ```javascript var maxSlidingWindow = function (nums, k) { From 0de459b1ff5f491e13c4fec93cbc7727dabc73e6 Mon Sep 17 00:00:00 2001 From: LiangDazhu <42199191+LiangDazhu@users.noreply.github.com> Date: Sun, 30 May 2021 22:54:01 +0800 Subject: [PATCH 30/95] =?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-2.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dp[j]可以通过dp[j - weight[i]]推导出来, 应该是写错了吧 --- 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 a169425a..e831d88f 100644 --- a/problems/背包理论基础01背包-2.md +++ b/problems/背包理论基础01背包-2.md @@ -55,7 +55,7 @@ dp[j]为 容量为j的背包所背的最大价值,那么如何推导dp[j]呢? -dp[j]可以通过dp[j - weight[j]]推导出来,dp[j - weight[i]]表示容量为j - weight[i]的背包所背的最大价值。 +dp[j]可以通过dp[j - weight[i]]推导出来,dp[j - weight[i]]表示容量为j - weight[i]的背包所背的最大价值。 dp[j - weight[i]] + value[i] 表示 容量为 j - 物品i重量 的背包 加上 物品i的价值。(也就是容量为j的背包,放入物品i了之后的价值即:dp[j]) From 60ad3b081134174577ad58416d275b1bb78267cd Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Sun, 30 May 2021 23:37:15 +0800 Subject: [PATCH 31/95] =?UTF-8?q?0045.=E8=B7=B3=E8=B7=83=E6=B8=B8=E6=88=8F?= =?UTF-8?q?||.md=20Javascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0045.跳跃游戏II.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/problems/0045.跳跃游戏II.md b/problems/0045.跳跃游戏II.md index 31b52b31..4128da4c 100644 --- a/problems/0045.跳跃游戏II.md +++ b/problems/0045.跳跃游戏II.md @@ -208,6 +208,26 @@ func jump(nums []int) int { } return dp[len(nums)-1] } +``` + +Javascript: +```Javascript +var jump = function(nums) { + let curIndex = 0 + let nextIndex = 0 + let steps = 0 + for(let i = 0; i < nums.length - 1; i++) { + nextIndex = Math.max(nums[i] + i, nextIndex) + if(i === curIndex) { + curIndex = nextIndex + steps++ + } + } + + return steps +}; +``` + /* dp[i]表示从起点到当前位置的最小跳跃次数 dp[i]=min(dp[j]+1,dp[i]) 表示从j位置用一步跳跃到当前位置,这个j位置可能有很多个,却最小一个就可以 From e9c91e78998bde1a123865df30aca4071bba8159 Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Mon, 31 May 2021 10:55:43 +0800 Subject: [PATCH 32/95] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E7=9A=84?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E8=BF=AD=E4=BB=A3=E6=B3=95=20javaScript?= =?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/二叉树的统一迭代法.md | 80 +++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/problems/二叉树的统一迭代法.md b/problems/二叉树的统一迭代法.md index dca5d3e3..f4091ad5 100644 --- a/problems/二叉树的统一迭代法.md +++ b/problems/二叉树的统一迭代法.md @@ -374,6 +374,86 @@ func postorderTraversal(root *TreeNode) []int { } ``` +javaScript: + +> 前序遍历统一迭代法 + +```js + +// 前序遍历:中左右 +// 压栈顺序:右左中 + +var preorderTraversal = function(root, res = []) { + const stack = []; + if (root) stack.push(root); + while(stack.length) { + const node = stack.pop(); + if(!node) { + res.push(stack.pop().val); + continue; + } + if (node.right) stack.push(node.right); // 右 + if (node.left) stack.push(node.left); // 左 + stack.push(node); // 中 + stack.push(null); + }; + return res; +}; + +``` + +> 中序遍历统一迭代法 + +```js + +// 中序遍历:左中右 +// 压栈顺序:右中左 + +var inorderTraversal = function(root, res = []) { + const stack = []; + if (root) stack.push(root); + while(stack.length) { + const node = stack.pop(); + if(!node) { + res.push(stack.pop().val); + continue; + } + if (node.right) stack.push(node.right); // 右 + stack.push(node); // 中 + stack.push(null); + if (node.left) stack.push(node.left); // 左 + }; + return res; +}; + +``` + +> 后序遍历统一迭代法 + +```js + +// 后续遍历:左右中 +// 压栈顺序:中右左 + +var postorderTraversal = function(root, res = []) { + const stack = []; + if (root) stack.push(root); + while(stack.length) { + const node = stack.pop(); + if(!node) { + res.push(stack.pop().val); + continue; + } + stack.push(node); // 中 + stack.push(null); + if (node.right) stack.push(node.right); // 右 + if (node.left) stack.push(node.left); // 左 + }; + return res; +}; + +``` + ----------------------- From 18a37ec17d2e596d12f37373b0decffded380f76 Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Mon, 31 May 2021 15:25:34 +0800 Subject: [PATCH 33/95] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E7=9A=84?= =?UTF-8?q?=E5=B1=82=E5=BA=8F=E9=81=8D=E5=8E=86=20=E4=B8=80=E5=A5=97?= =?UTF-8?q?=E6=89=93=E5=85=AB=E4=B8=AAJavaScript=20=E8=BF=AD=E4=BB=A3=20+?= =?UTF-8?q?=20=E9=80=92=E5=BD=92=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0102.二叉树的层序遍历.md | 270 ++++++++++++++++++++++ 1 file changed, 270 insertions(+) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 00607082..2be38bc4 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -1100,6 +1100,276 @@ var levelOrder = function (root) { }; ``` +> 二叉树的层序遍历(Javascript语言完全版) (迭代 + 递归) + +```js +/** + * 102. 二叉树的层序遍历 + * @param {TreeNode} root + * @return {number[][]} + */ + +// 迭代 + +var levelOrder = function(root) { + const queue = [], res = []; + root && queue.push(root); + while(len = queue.length) { + const val = []; + while(len--) { + const node = queue.shift(); + val.push(node.val); + node.left && queue.push(node.left); + node.right && queue.push(node.right); + } + res.push(val); + } + return res; +}; + +// 递归 +var levelOrder = function(root) { + const res = []; + function defs (root, i) { + if(!root) return; + if(!res[i]) res[i] = []; + res[i].push(root.val) + root.left && defs(root.left, i + 1); + root.right && defs(root.right, i + 1); + } + defs(root, 0); + return res; +}; + + +/** + * 107. 二叉树的层序遍历 II + * @param {TreeNode} root + * @return {number[][]} + */ + +// 迭代 + +var levelOrderBottom = function(root) { + const queue = [], res = []; + root && queue.push(root); + while(len = queue.length) { + const val = []; + while(len--) { + const node = queue.shift(); + val.push(node.val); + node.left && queue.push(node.left); + node.right && queue.push(node.right); + } + res.push(val); + } + return res.reverse() +}; + +// 递归 + +var levelOrderBottom = function(root) { + const res = []; + function defs (root, i) { + if(!root) return; + if(!res[i]) res[i] = []; + res[i].push(root.val); + root.left && defs(root.left, i + 1); + root.right && defs(root.right, i + 1); + } + defs(root, 0); + return res.reverse(); +}; + +/** + * 199. 二叉树的右视图 + * @param {TreeNode} root + * @return {number[]} + */ + +// 迭代 + +var rightSideView = function(root) { + const res = [], queue = []; + root && queue.push(root); + while(l = queue.length) { + while (l--) { + const {val, left, right} = queue.shift(); + !l && res.push(val); + left && queue.push(left); + right && queue.push(right); + } + } + return res; +}; + +// 递归 +var rightSideView = function(root) { + const res = []; + function defs(root, i) { + if(!root) return; + res[i] = root.val; + root.left && defs(root.left, i + 1); + root.right && defs(root.right, i + 1); + } + defs(root, 0); + return res; +}; + +/** + * 637. 二叉树的层平均值 + * @param {TreeNode} root + * @return {number[]} + */ + +// 迭代 +var averageOfLevels = function(root) { + const stack = [], res = []; + root && stack.push(root); + while(len = stack.length) { + let sum = 0, l = len; + while(l--) { + const {val, left, right} = stack.shift(); + sum += val; + left && stack.push(left); + right && stack.push(right); + } + res.push(sum/len); + } + return res; +}; + +// 递归 +var averageOfLevels = function(root) { + const resCount = [], res = []; + function defs(root, i) { + if(!root) return; + if(isNaN(res[i])) resCount[i] = res[i] = 0; + res[i] += root.val; + resCount[i]++; + root.left && defs(root.left, i + 1); + root.right && defs(root.right, i + 1); + } + defs(root, 0); + return res.map((val, i) => val / resCount[i]); +}; + +/** + * 515. 在每个树行中找最大值 + * @param {TreeNode} root + * @return {number[]} + */ + +// 迭代 +const MIN_G = Number.MIN_SAFE_INTEGER; +var largestValues = function(root) { + const stack = [], res = []; + root && stack.push(root); + while(len = stack.length) { + let max = MIN_G; + while(len--) { + const {val, left, right} = stack.shift(); + max = max > val ? max : val; + left && stack.push(left); + right && stack.push(right); + } + res.push(max); + } + return res; +}; + +// 递归 +var largestValues = function(root) { + const res = []; + function defs (root, i) { + if(!root) return; + if(isNaN(res[i])) res[i] = root.val; + res[i] = res[i] > root.val ? res[i] : root.val; + root.left && defs(root.left, i + 1); + root.right && defs(root.right, i + 1); + } + defs(root, 0); + return res; +}; + +/** + * 429. N 叉树的层序遍历 + * @param {Node|null} root + * @return {number[][]} + */ + +// 迭代 +var levelOrder = function(root) { + const stack = [], res = []; + root && stack.push(root); + while(len = stack.length) { + const vals = []; + while(len--) { + const {val, children} = stack.shift(); + vals.push(val); + for(const e of children) { + stack.push(e); + } + } + res.push(vals); + } + return res; +}; + +// 递归 + +var levelOrder = function(root) { + const res = []; + function defs (root, i) { + if(!root) return; + if(!res[i]) res[i] = []; + res[i].push(root.val); + for(const e of root.children) { + defs(e, i + 1); + } + } + defs(root, 0); + return res; +}; + +/** + * 116. 填充每个节点的下一个右侧节点指针 + * 117. 填充每个节点的下一个右侧节点指针 II + * @param {Node} root + * @return {Node} + */ + +// 迭代 +var connect = function(root) { + const stack = []; + root && stack.push(root); + while(len = stack.length) { + while(len--) { + const node1 = stack.shift(), + node2 = len ? stack[0] : null; + node1.next = node2; + node1.left && stack.push(node1.left); + node1.right && stack.push(node1.right); + } + } + return root; +}; + +// 递归 +var connect = function(root) { + const res = []; + function defs (root, i) { + if(!root) return; + if(res[i]) res[i].next = root; + res[i] = root; + root.left && defs(root.left, i + 1); + root.right && defs(root.right, i + 1); + } + defs(root, 0); + return root; +}; +``` + ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) From 4a5c0cb75b1c265f2dacfb3826dccdb3f0bdae98 Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Mon, 31 May 2021 17:19:02 +0800 Subject: [PATCH 34/95] update: stack to queue --- problems/0102.二叉树的层序遍历.md | 48 +++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 2be38bc4..51bd8510 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -1224,15 +1224,15 @@ var rightSideView = function(root) { // 迭代 var averageOfLevels = function(root) { - const stack = [], res = []; - root && stack.push(root); - while(len = stack.length) { + const queue = [], res = []; + root && queue.push(root); + while(len = queue.length) { let sum = 0, l = len; while(l--) { - const {val, left, right} = stack.shift(); + const {val, left, right} = queue.shift(); sum += val; - left && stack.push(left); - right && stack.push(right); + left && queue.push(left); + right && queue.push(right); } res.push(sum/len); } @@ -1263,15 +1263,15 @@ var averageOfLevels = function(root) { // 迭代 const MIN_G = Number.MIN_SAFE_INTEGER; var largestValues = function(root) { - const stack = [], res = []; - root && stack.push(root); - while(len = stack.length) { + const queue = [], res = []; + root && queue.push(root); + while(len = queue.length) { let max = MIN_G; while(len--) { - const {val, left, right} = stack.shift(); + const {val, left, right} = queue.shift(); max = max > val ? max : val; - left && stack.push(left); - right && stack.push(right); + left && queue.push(left); + right && queue.push(right); } res.push(max); } @@ -1300,15 +1300,15 @@ var largestValues = function(root) { // 迭代 var levelOrder = function(root) { - const stack = [], res = []; - root && stack.push(root); - while(len = stack.length) { + const queue = [], res = []; + root && queue.push(root); + while(len = queue.length) { const vals = []; while(len--) { - const {val, children} = stack.shift(); + const {val, children} = queue.shift(); vals.push(val); for(const e of children) { - stack.push(e); + queue.push(e); } } res.push(vals); @@ -1341,15 +1341,15 @@ var levelOrder = function(root) { // 迭代 var connect = function(root) { - const stack = []; - root && stack.push(root); - while(len = stack.length) { + const queue = []; + root && queue.push(root); + while(len = queue.length) { while(len--) { - const node1 = stack.shift(), - node2 = len ? stack[0] : null; + const node1 = queue.shift(), + node2 = len ? queue[0] : null; node1.next = node2; - node1.left && stack.push(node1.left); - node1.right && stack.push(node1.right); + node1.left && queue.push(node1.left); + node1.right && queue.push(node1.right); } } return root; From 17b8c2d9acb2481783b7820717a0db989c0dd961 Mon Sep 17 00:00:00 2001 From: Lulu Date: Mon, 31 May 2021 20:37:11 +0800 Subject: [PATCH 35/95] fix typo --- .../关于时间复杂度,你不知道的都在这里!.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/前序/关于时间复杂度,你不知道的都在这里!.md b/problems/前序/关于时间复杂度,你不知道的都在这里!.md index bd3bd284..3f5bc156 100644 --- a/problems/前序/关于时间复杂度,你不知道的都在这里!.md +++ b/problems/前序/关于时间复杂度,你不知道的都在这里!.md @@ -117,7 +117,7 @@ O(2 * n^2 + 10 * n + 1000) < O(3 * n^2),所以说最后省略掉常数项系 ![时间复杂度1.png](https://img-blog.csdnimg.cn/20200728191447349.png) -假如有两个算法的时间复杂度,分别是log以2为底n的对数和log以10为底n的对数,那么这里如果还记得高中数学的话,应该不能理解`以2为底n的对数 = 以2为底10的对数 * 以10为底n的对数`。 +假如有两个算法的时间复杂度,分别是log以2为底n的对数和log以10为底n的对数,那么这里如果还记得高中数学的话,应该不难理解`以2为底n的对数 = 以2为底10的对数 * 以10为底n的对数`。 而以2为底10的对数是一个常数,在上文已经讲述了我们计算时间复杂度是忽略常数项系数的。 From 276a7b1e14ca7a54ac9826bde248e0a1c6833444 Mon Sep 17 00:00:00 2001 From: LiangDazhu <42199191+LiangDazhu@users.noreply.github.com> Date: Mon, 31 May 2021 21:34:11 +0800 Subject: [PATCH 36/95] =?UTF-8?q?Update=201049.=E6=9C=80=E5=90=8E=E4=B8=80?= =?UTF-8?q?=E5=9D=97=E7=9F=B3=E5=A4=B4=E7=9A=84=E9=87=8D=E9=87=8FII.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added python version code --- problems/1049.最后一块石头的重量II.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/problems/1049.最后一块石头的重量II.md b/problems/1049.最后一块石头的重量II.md index fcd3712a..f74600b1 100644 --- a/problems/1049.最后一块石头的重量II.md +++ b/problems/1049.最后一块石头的重量II.md @@ -178,7 +178,17 @@ class Solution { ``` Python: - +```python +class Solution: + def lastStoneWeightII(self, stones: List[int]) -> int: + sumweight = sum(stones) + target = sumweight // 2 + dp = [0] * 15001 + for i in range(len(stones)): + for j in range(target, stones[i] - 1, -1): + dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]) + return sumweight - 2 * dp[target] +``` Go: From 659595f2b4d09d45d7301b728ac274b1cd52b39a Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Mon, 31 May 2021 22:26:44 +0800 Subject: [PATCH 37/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200202.=E5=BF=AB?= =?UTF-8?q?=E4=B9=90=E6=95=B0=20go=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0202.快乐数.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/problems/0202.快乐数.md b/problems/0202.快乐数.md index c07405ec..396231fe 100644 --- a/problems/0202.快乐数.md +++ b/problems/0202.快乐数.md @@ -111,6 +111,24 @@ Python: Go: +```go +func isHappy(n int) bool { + m := make(map[int]bool) + for n != 1 && !m[n] { + n, m[n] = getSum(n), true + } + return n == 1 +} + +func getSum(n int) int { + sum := 0 + for n > 0 { + sum += (n % 10) * (n % 10) + n = n / 10 + } + return sum +} +``` javaScript: From 605b9159de96de727cf4592144783c6d203f6fbe Mon Sep 17 00:00:00 2001 From: LiangDazhu <42199191+LiangDazhu@users.noreply.github.com> Date: Mon, 31 May 2021 22:49:40 +0800 Subject: [PATCH 38/95] =?UTF-8?q?Update=200494.=E7=9B=AE=E6=A0=87=E5=92=8C?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added python version code --- problems/0494.目标和.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/problems/0494.目标和.md b/problems/0494.目标和.md index a9ddc768..c772a09d 100644 --- a/problems/0494.目标和.md +++ b/problems/0494.目标和.md @@ -150,7 +150,7 @@ dp[j] 表示:填满j(包括j)这么大容积的包,有dp[i]种方法 有哪些来源可以推出dp[j]呢? -不考虑nums[i]的情况下,填满容量为j - nums[i]的背包,有dp[j - nums[i]]中方法。 +不考虑nums[i]的情况下,填满容量为j - nums[i]的背包,有dp[j - nums[i]]种方法。 那么只要搞到nums[i]的话,凑成dp[j]就有dp[j - nums[i]] 种方法。 @@ -261,7 +261,19 @@ class Solution { ``` Python: - +```python +class Solution: + def findTargetSumWays(self, nums: List[int], target: int) -> int: + sumValue = sum(nums) + if target > sumValue or (sumValue + target) % 2 == 1: return 0 + bagSize = (sumValue + target) // 2 + dp = [0] * (bagSize + 1) + dp[0] = 1 + for i in range(len(nums)): + for j in range(bagSize, nums[i] - 1, -1): + dp[j] += dp[j - nums[i]] + return dp[bagSize] +``` Go: From 425f407d6c66854446a1a2654bc1639171aee172 Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Mon, 31 May 2021 11:20:40 -0700 Subject: [PATCH 39/95] =?UTF-8?q?Update=200024.=E4=B8=A4=E4=B8=A4=E4=BA=A4?= =?UTF-8?q?=E6=8D=A2=E9=93=BE=E8=A1=A8=E4=B8=AD=E7=9A=84=E8=8A=82=E7=82=B9?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0024.两两交换链表中的节点.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md index 643f6055..59ded523 100644 --- a/problems/0024.两两交换链表中的节点.md +++ b/problems/0024.两两交换链表中的节点.md @@ -129,6 +129,23 @@ class Solution { ``` Python: +```python +class Solution: + def swapPairs(self, head: ListNode) -> ListNode: + dummy = ListNode(0) #设置一个虚拟头结点 + dummy.next = head + cur = dummy + while cur.next and cur.next.next: + tmp = cur.next #记录临时节点 + tmp1 = cur.next.next.next #记录临时节点 + + cur.next = cur.next.next #步骤一 + cur.next.next = tmp #步骤二 + cur.next.next.next = tmp1 #步骤三 + + cur = cur.next.next #cur移动两位,准备下一轮交换 + return dummy.next +``` Go: ```go From e5b81df01cdc6588710edb4bf7a88de6cc8a8da8 Mon Sep 17 00:00:00 2001 From: Yang Date: Mon, 31 May 2021 16:43:45 -0400 Subject: [PATCH 40/95] =?UTF-8?q?Update=200452.=E7=94=A8=E6=9C=80=E5=B0=91?= =?UTF-8?q?=E6=95=B0=E9=87=8F=E7=9A=84=E7=AE=AD=E5=BC=95=E7=88=86=E6=B0=94?= =?UTF-8?q?=E7=90=83.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Java code: - Fix an error in sorting (simplified as well) - Add checking for boundary condition --- problems/0452.用最少数量的箭引爆气球.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/problems/0452.用最少数量的箭引爆气球.md b/problems/0452.用最少数量的箭引爆气球.md index a8b55ca9..9b0cc925 100644 --- a/problems/0452.用最少数量的箭引爆气球.md +++ b/problems/0452.用最少数量的箭引爆气球.md @@ -142,16 +142,8 @@ Java: ```java class Solution { public int findMinArrowShots(int[][] points) { - Arrays.sort(points, new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - if (o1[0] != o2[0]) { - return Integer.compare(o1[0],o2[0]); - } else { - return Integer.compare(o1[0],o2[0]); - } - } - }); + if (points.length == 0) return 0; + Arrays.sort(points, (o1, o2) -> Integer.compare(o1[0], o2[0])); int count = 1; for (int i = 1; i < points.length; i++) { From 72b2521873136f8f45648c185fd463f976f586ca Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Tue, 1 Jun 2021 08:15:47 +0800 Subject: [PATCH 41/95] =?UTF-8?q?1005.K=E6=AC=A1=E5=8F=96=E5=8F=8D.md=20Ja?= =?UTF-8?q?vascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...1005.K次取反后最大化的数组和.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/problems/1005.K次取反后最大化的数组和.md b/problems/1005.K次取反后最大化的数组和.md index 43282f25..e57e26ad 100644 --- a/problems/1005.K次取反后最大化的数组和.md +++ b/problems/1005.K次取反后最大化的数组和.md @@ -140,7 +140,29 @@ class Solution: Go: +Javascript: +```Javascript +var largestSumAfterKNegations = function(nums, k) { + nums.sort((a, b) => { + return Math.abs(b) - Math.abs(a) + }) + for(let i = 0; i < nums.length; i++) { + if(nums[i] < 0 && k > 0) { + nums[i] *= -1 + k-- + } + } + if(k > 0 && k % 2 === 1) { + nums[nums.length - 1] *= -1 + } + k = 0 + + return nums.reduce((a, b) => { + return a + b + }) +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From 7a0d134d6e96541deb2fe4757743aed4c3ecd94e Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Mon, 31 May 2021 18:31:10 -0700 Subject: [PATCH 42/95] =?UTF-8?q?Update=200242.=E6=9C=89=E6=95=88=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AF=8D=E5=BC=82=E4=BD=8D=E8=AF=8D.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0242.有效的字母异位词.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/problems/0242.有效的字母异位词.md b/problems/0242.有效的字母异位词.md index 6a6faf63..ba942f70 100644 --- a/problems/0242.有效的字母异位词.md +++ b/problems/0242.有效的字母异位词.md @@ -113,7 +113,22 @@ class Solution { ``` Python: - +```python +class Solution: + def isAnagram(self, s: str, t: str) -> bool: + record = [0] * 26 + for i in range(len(s)): + #并不需要记住字符a的ASCII,只要求出一个相对数值就可以了 + record[ord(s[i]) - ord("a")] += 1 + print(record) + for i in range(len(t)): + record[ord(t[i]) - ord("a")] -= 1 + for i in range(26): + if record[i] != 0: + #record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。 + return False + return True +``` Go: ```go From 4fc751affb0fba096c9263256555d59aa82615aa Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Mon, 31 May 2021 18:42:19 -0700 Subject: [PATCH 43/95] =?UTF-8?q?Update=200202.=E5=BF=AB=E4=B9=90=E6=95=B0?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0202.快乐数.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/problems/0202.快乐数.md b/problems/0202.快乐数.md index c07405ec..999e7d52 100644 --- a/problems/0202.快乐数.md +++ b/problems/0202.快乐数.md @@ -108,7 +108,29 @@ class Solution { ``` Python: - +```python +class Solution: + def isHappy(self, n: int) -> bool: + set_ = set() + while 1: + sum_ = self.getSum(n) + if sum_ == 1: + return True + #如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false + if sum_ in set_: + return False + else: + set_.add(sum_) + n = sum_ + + #取数值各个位上的单数之和 + def getSum(self, n): + sum_ = 0 + while n > 0: + sum_ += (n%10) * (n%10) + n //= 10 + return sum_ +``` Go: From be0ef14cef18a6aeae95872c82dca0221d16f76b Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Tue, 1 Jun 2021 12:01:24 +0800 Subject: [PATCH 44/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20101.=20=E5=AF=B9?= =?UTF-8?q?=E7=A7=B0=E4=BA=8C=E5=8F=89=E6=A0=91=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0101.对称二叉树.md | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/problems/0101.对称二叉树.md b/problems/0101.对称二叉树.md index d8797d30..b58cef2e 100644 --- a/problems/0101.对称二叉树.md +++ b/problems/0101.对称二叉树.md @@ -363,6 +363,54 @@ Python: Go: +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +// 递归 +func defs(left *TreeNode, right *TreeNode) bool { + if left == nil && right == nil { + return true; + }; + if left == nil || right == nil { + return false; + }; + if left.Val != right.Val { + return false; + } + return defs(left.Left, right.Right) && defs(right.Left, left.Right); +} +func isSymmetric(root *TreeNode) bool { + return defs(root.Left, root.Right); +} + +// 迭代 +func isSymmetric(root *TreeNode) bool { + var queue []*TreeNode; + if root != nil { + queue = append(queue, root.Left, root.Right); + } + for len(queue) > 0 { + left := queue[0]; + right := queue[1]; + queue = queue[2:]; + if left == nil && right == nil { + continue; + } + if left == nil || right == nil || left.Val != right.Val { + return false; + }; + queue = append(queue, left.Left, right.Right, right.Left, left.Right); + } + return true; +} +``` + JavaScript ```javascript From 0ddb3430986065f6a248c7936c3351544615161d Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Tue, 1 Jun 2021 12:22:46 +0800 Subject: [PATCH 45/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20104.=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91=E7=9A=84=E6=9C=80=E5=A4=A7=E6=B7=B1=E5=BA=A6?= =?UTF-8?q?=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0104.二叉树的最大深度.md | 49 +++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/problems/0104.二叉树的最大深度.md b/problems/0104.二叉树的最大深度.md index 756afb68..5f0fe411 100644 --- a/problems/0104.二叉树的最大深度.md +++ b/problems/0104.二叉树的最大深度.md @@ -284,6 +284,55 @@ Python: Go: +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func max (a, b int) int { + if a > b { + return a; + } + return b; +} +// 递归 +func maxDepth(root *TreeNode) int { + if root == nil { + return 0; + } + return max(maxDepth(root.Left), maxDepth(root.Right)) + 1; +} + +// 遍历 +func maxDepth(root *TreeNode) int { + levl := 0; + queue := make([]*TreeNode, 0); + if root != nil { + queue = append(queue, root); + } + for l := len(queue); l > 0; { + for ;l > 0;l-- { + node := queue[0]; + if node.Left != nil { + queue = append(queue, node.Left); + } + if node.Right != nil { + queue = append(queue, node.Right); + } + queue = queue[1:]; + } + levl++; + l = len(queue); + } + return levl; +} + +``` + JavaScript ```javascript From 51edb80d7c8771b0b9af932a577daeb658efd100 Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Tue, 1 Jun 2021 14:20:54 +0800 Subject: [PATCH 46/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20111.=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91=E7=9A=84=E6=9C=80=E5=B0=8F=E6=B7=B1=E5=BA=A6?= =?UTF-8?q?=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0111.二叉树的最小深度.md | 58 +++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/problems/0111.二叉树的最小深度.md b/problems/0111.二叉树的最小深度.md index 8ee15eac..48795722 100644 --- a/problems/0111.二叉树的最小深度.md +++ b/problems/0111.二叉树的最小深度.md @@ -301,6 +301,64 @@ class Solution: Go: +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func min(a, b int) int { + if a < b { + return a; + } + return b; +} +// 递归 +func minDepth(root *TreeNode) int { + if root == nil { + return 0; + } + if root.Left == nil && root.Right != nil { + return 1 + minDepth(root.Right); + } + if root.Right == nil && root.Left != nil { + return 1 + minDepth(root.Left); + } + return min(minDepth(root.Left), minDepth(root.Right)) + 1; +} + +// 迭代 + +func minDepth(root *TreeNode) int { + dep := 0; + queue := make([]*TreeNode, 0); + if root != nil { + queue = append(queue, root); + } + for l := len(queue); l > 0; { + dep++; + for ; l > 0; l-- { + node := queue[0]; + if node.Left == nil && node.Right == nil { + return dep; + } + if node.Left != nil { + queue = append(queue, node.Left); + } + if node.Right != nil { + queue = append(queue, node.Right); + } + queue = queue[1:]; + } + l = len(queue); + } + return dep; +} +``` + JavaScript: From ea88604bfdf249d686e1aba4a26795a35a57dcc8 Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Tue, 1 Jun 2021 02:44:13 -0700 Subject: [PATCH 47/95] =?UTF-8?q?Update=200459.=E9=87=8D=E5=A4=8D=E7=9A=84?= =?UTF-8?q?=E5=AD=90=E5=AD=97=E7=AC=A6=E4=B8=B2.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0459.重复的子字符串.md | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/problems/0459.重复的子字符串.md b/problems/0459.重复的子字符串.md index d9dfc62c..51a903ef 100644 --- a/problems/0459.重复的子字符串.md +++ b/problems/0459.重复的子字符串.md @@ -184,6 +184,55 @@ class Solution { Python: +这里使用了前缀表统一减一的实现方式 + +```python +class Solution: + def repeatedSubstringPattern(self, s: str) -> bool: + if len(s) == 0: + return False + nxt = [0] * len(s) + self.getNext(nxt, s) + if nxt[-1] != -1 and len(s) % (len(s) - (nxt[-1] + 1)) == 0: + return True + return False + + def getNext(self, nxt, s): + nxt[0] = -1 + j = -1 + for i in range(1, len(s)): + while j >= 0 and s[i] != s[j+1]: + j = nxt[j] + if s[i] == s[j+1]: + j += 1 + nxt[i] = j + return nxt +``` + +前缀表(不减一)的代码实现 + +```python +class Solution: + def repeatedSubstringPattern(self, s: str) -> bool: + if len(s) == 0: + return False + nxt = [0] * len(s) + self.getNext(nxt, s) + if nxt[-1] != 0 and len(s) % (len(s) - nxt[-1]) == 0: + return True + return False + + def getNext(self, nxt, s): + nxt[0] = 0 + j = 0 + for i in range(1, len(s)): + while j > 0 and s[i] != s[j]: + j = nxt[j - 1] + if s[i] == s[j]: + j += 1 + nxt[i] = j + return nxt +``` Go: From 9dd0af1946f66e1bf243d9fbc5910a9ed003a7ed Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Tue, 1 Jun 2021 17:48:26 +0800 Subject: [PATCH 48/95] Update --- README.md | 23 ++- problems/0001.两数之和.md | 13 +- problems/0015.三数之和.md | 10 +- problems/0072.编辑距离.md | 34 +++-- problems/0115.不同的子序列.md | 2 +- problems/0121.买卖股票的最佳时机.md | 14 +- .../0123.买卖股票的最佳时机III.md | 4 +- problems/0416.分割等和子集.md | 7 +- problems/0718.最长重复子数组.md | 2 +- problems/动态规划总结篇.md | 140 ++++++++++++++++++ 10 files changed, 200 insertions(+), 49 deletions(-) create mode 100644 problems/动态规划总结篇.md diff --git a/README.md b/README.md index 05fc0627..b4e82eb0 100644 --- a/README.md +++ b/README.md @@ -112,14 +112,24 @@ (持续更新中.....) +## 备战秋招 + +1. [选择方向的时候,我也迷茫了](https://mp.weixin.qq.com/s/ZCzFiAHZHLqHPLJQXNm75g) +2. [刷题就用库函数了,怎么了?](https://mp.weixin.qq.com/s/6K3_OSaudnHGq2Ey8vqYfg) +3. [关于实习,大家可能有点迷茫!](https://mp.weixin.qq.com/s/xcxzi7c78kQGjvZ8hh7taA) +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) + ## 数组 1. [数组过于简单,但你该了解这些!](./problems/数组理论基础.md) 2. [数组:每次遇到二分法,都是一看就会,一写就废](./problems/0704.二分查找.md) 3. [数组:就移除个元素很难么?](./problems/0027.移除元素.md) -4. [数组:滑动窗口拯救了你](./problems/0209.长度最小的子数组.md) -5. [数组:这个循环可以转懵很多人!](./problems/0059.螺旋矩阵II.md) -6. [数组:总结篇](./problems/数组总结篇.md) +4. [数组:有序数组的平方,还有序么?](./problems/0977.有序数组的平方.md) +5. [数组:滑动窗口拯救了你](./problems/0209.长度最小的子数组.md) +6. [数组:这个循环可以转懵很多人!](./problems/0059.螺旋矩阵II.md) +7. [数组:总结篇](./problems/数组总结篇.md) ## 链表 @@ -292,6 +302,7 @@ 动态规划专题已经开始啦,来不及解释了,小伙伴们上车别掉队! +背包问题大纲 1. [关于动态规划,你该了解这些!](./problems/动态规划理论基础.md) 2. [动态规划:斐波那契数](./problems/0509.斐波那契数.md) 3. [动态规划:爬楼梯](./problems/0070.爬楼梯.md) @@ -366,6 +377,7 @@ 52. [为了绝杀编辑距离,Carl做了三步铺垫,你都知道么?](./problems/为了绝杀编辑距离,卡尔做了三步铺垫.md) 53. [动态规划:回文子串](./problems/0647.回文子串.md) 54. [动态规划:最长回文子序列](./problems/0516.最长回文子序列.md) +55. [动态规划总结篇](./problems/动态规划总结篇.md) (持续更新中....) @@ -390,12 +402,7 @@ [各类基础算法模板](https://github.com/youngyangyang04/leetcode/blob/master/problems/算法模板.md) -# 备战秋招 -1. [技术比较弱,也对技术不感兴趣,如何选择方向?](https://mp.weixin.qq.com/s/ZCzFiAHZHLqHPLJQXNm75g) -2. [刷题就用库函数了,怎么了?](https://mp.weixin.qq.com/s/6K3_OSaudnHGq2Ey8vqYfg) -3. [关于实习,大家可能有点迷茫!](https://mp.weixin.qq.com/s/xcxzi7c78kQGjvZ8hh7taA) -4. [马上秋招了,慌得很!](https://mp.weixin.qq.com/s/7q7W8Cb2-a5U5atZdOnOFA) # B站算法视频讲解 diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index 77318294..41a95daf 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -29,17 +29,17 @@ https://leetcode-cn.com/problems/two-sum/ 很明显暴力的解法是两层for循环查找,时间复杂度是O(n^2)。 建议大家做这道题目之前,先做一下这两道 -* [242. 有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig) -* [349. 两个数组的交集](https://mp.weixin.qq.com/s/N9iqAchXreSVW7zXUS4BVA) +* [242. 有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA) +* [349. 两个数组的交集](https://mp.weixin.qq.com/s/aMSA5zrp3jJcLjuSB0Es2Q) -[242. 有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig) 这道题目是用数组作为哈希表来解决哈希问题,[349. 两个数组的交集](https://mp.weixin.qq.com/s/N9iqAchXreSVW7zXUS4BVA)这道题目是通过set作为哈希表来解决哈希问题。 +[242. 有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA) 这道题目是用数组作为哈希表来解决哈希问题,[349. 两个数组的交集](https://mp.weixin.qq.com/s/aMSA5zrp3jJcLjuSB0Es2Q)这道题目是通过set作为哈希表来解决哈希问题。 本题呢,则要使用map,那么来看一下使用数组和set来做哈希法的局限。 * 数组的大小是受限制的,而且如果元素很少,而哈希值太大会造成内存空间的浪费。 -* set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下标位置,因为要返回x 和 y的下标。所以set 也不能用。 +* set是一个集合,里面放的元素只能是一个key,而两数之和这道题目,不仅要判断y是否存在而且还要记录y的下表位置,因为要返回x 和 y的下表。所以set 也不能用。 -此时就要选择另一种数据结构:map ,map是一种key value的存储结构,可以用key保存数值,用value在保存数值所在的下标。 +此时就要选择另一种数据结构:map ,map是一种key value的存储结构,可以用key保存数值,用value在保存数值所在的下表。 C++中map,有三种类型: @@ -51,13 +51,12 @@ C++中map,有三种类型: std::unordered_map 底层实现为哈希表,std::map 和std::multimap 的底层实现是红黑树。 -同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。 更多哈希表的理论知识请看[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/g8N6WmoQmsCUw3_BaWxHZA)。 +同理,std::map 和std::multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。 更多哈希表的理论知识请看[关于哈希表,你该了解这些!](https://mp.weixin.qq.com/s/RSUANESA_tkhKhYe3ZR8Jg)。 **这道题目中并不需要key有序,选择std::unordered_map 效率更高!** 解题思路动画如下: - ![](https://code-thinking.cdn.bcebos.com/gifs/1.两数之和.gif) diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md index 4f4ec63a..5b77a170 100644 --- a/problems/0015.三数之和.md +++ b/problems/0015.三数之和.md @@ -105,8 +105,7 @@ public: 时间复杂度:O(n^2)。 - -## 双指针法C++代码 +C++代码代码如下: ```C++ class Solution { @@ -163,13 +162,14 @@ public: # 思考题 -既然三数之和可以使用双指针法,我们之前讲过的[两数之和](https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ),可不可以使用双指针法呢? + +既然三数之和可以使用双指针法,我们之前讲过的[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ),可不可以使用双指针法呢? 如果不能,题意如何更改就可以使用双指针法呢? **大家留言说出自己的想法吧!** -两数之和 就不能使用双指针法,因为[两数之和](https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ)要求返回的是索引下表, 而双指针法一定要排序,一旦排序之后原数组的索引就被改变了。 +两数之和 就不能使用双指针法,因为[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ)要求返回的是索引下表, 而双指针法一定要排序,一旦排序之后原数组的索引就被改变了。 -如果[两数之和](https://mp.weixin.qq.com/s/uVAtjOHSeqymV8FeQbliJQ)要求返回的是数值的话,就可以使用双指针法了。 +如果[1.两数之和](https://mp.weixin.qq.com/s/vaMsLnH-f7_9nEK4Cuu3KQ)要求返回的是数值的话,就可以使用双指针法了。 diff --git a/problems/0072.编辑距离.md b/problems/0072.编辑距离.md index 9dd842e8..824c74af 100644 --- a/problems/0072.编辑距离.md +++ b/problems/0072.编辑距离.md @@ -8,6 +8,8 @@ ## 72. 编辑距离 +https://leetcode-cn.com/problems/edit-distance/ + 给你两个单词 word1 和 word2,请你计算出将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作: @@ -16,23 +18,23 @@ * 删除一个字符 * 替换一个字符 -示例 1: -输入:word1 = "horse", word2 = "ros" -输出:3 -解释: -horse -> rorse (将 'h' 替换为 'r') -rorse -> rose (删除 'r') -rose -> ros (删除 'e') +示例 1: +输入:word1 = "horse", word2 = "ros" +输出:3 +解释: +horse -> rorse (将 'h' 替换为 'r') +rorse -> rose (删除 'r') +rose -> ros (删除 'e') -示例 2: -输入:word1 = "intention", word2 = "execution" -输出:5 -解释: -intention -> inention (删除 't') -inention -> enention (将 'i' 替换为 'e') -enention -> exention (将 'n' 替换为 'x') -exention -> exection (将 'n' 替换为 'c') -exection -> execution (插入 'u') +示例 2: +输入:word1 = "intention", word2 = "execution" +输出:5 +解释: +intention -> inention (删除 't') +inention -> enention (将 'i' 替换为 'e') +enention -> exention (将 'n' 替换为 'x') +exention -> exection (将 'n' 替换为 'c') +exection -> execution (插入 'u')   提示: diff --git a/problems/0115.不同的子序列.md b/problems/0115.不同的子序列.md index ef098978..1661acf8 100644 --- a/problems/0115.不同的子序列.md +++ b/problems/0115.不同的子序列.md @@ -16,7 +16,7 @@ 题目数据保证答案符合 32 位带符号整数范围。 -![115.不同的子序列示例](https://code-thinking.cdn.bcebos.com/pics/115.%E4%B8%8D%E5%90%8C%E7%9A%84%E5%AD%90%E5%BA%8F%E5%88%97%E7%A4%BA%E4%BE%8B.jpg) +![115.不同的子序列示例](https://code-thinking.cdn.bcebos.com/pics/115.不同的子序列示例.jpg) 提示: diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md index 0544c93f..d018efb7 100644 --- a/problems/0121.买卖股票的最佳时机.md +++ b/problems/0121.买卖股票的最佳时机.md @@ -16,14 +16,14 @@ 返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。 -示例 1: -输入:[7,1,5,3,6,4] -输出:5 +示例 1: +输入:[7,1,5,3,6,4] +输出:5 解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。 -示例 2: -输入:prices = [7,6,4,3,1] -输出:0 +示例 2: +输入:prices = [7,6,4,3,1] +输出:0 解释:在这种情况下, 没有交易完成, 所以最大利润为 0。 @@ -33,7 +33,7 @@ 这道题目最直观的想法,就是暴力,找最优间距了。 -``` +```C++ class Solution { public: int maxProfit(vector& prices) { diff --git a/problems/0123.买卖股票的最佳时机III.md b/problems/0123.买卖股票的最佳时机III.md index ecce8dc0..24370d38 100644 --- a/problems/0123.买卖股票的最佳时机III.md +++ b/problems/0123.买卖股票的最佳时机III.md @@ -101,9 +101,9 @@ dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]); 所以dp[0][2] = 0; -第0天第二次买入操作,初始值应该是多少呢? +第0天第二次买入操作,初始值应该是多少呢?应该不少同学疑惑,第一次还没买入呢,怎么初始化第二次买入呢? -不用管第几次,现在手头上没有现金,只要买入,现金就做相应的减少。 +第二次买入依赖于第一次卖出的状态,其实相当于第0天第一次买入了,第一次卖出了,然后在买入一次(第二次买入),那么现在手头上没有现金,只要买入,现金就做相应的减少。 所以第二次买入操作,初始化为:dp[0][3] = -prices[0]; diff --git a/problems/0416.分割等和子集.md b/problems/0416.分割等和子集.md index 55d200e2..0d306c74 100644 --- a/problems/0416.分割等和子集.md +++ b/problems/0416.分割等和子集.md @@ -5,7 +5,6 @@

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

-# 动态规划:分割等和子集可以用01背包! ## 416. 分割等和子集 @@ -29,6 +28,10 @@ 输出: false 解释: 数组不能分割成两个元素和相等的子集. +提示: +* 1 <= nums.length <= 200 +* 1 <= nums[i] <= 100 + ## 思路 这道题目初步看,是如下两题几乎是一样的,大家可以用回溯法,解决如下两题 @@ -174,7 +177,7 @@ public: 这道题目就是一道01背包应用类的题目,需要我们拆解题目,然后套入01背包的场景。 -01背包相对于本题,主要要理解,题目中物品是nums[i],重量是nums[i]i,价值也是nums[i],背包体积是sum/2。 +01背包相对于本题,主要要理解,题目中物品是nums[i],重量是nums[i],价值也是nums[i],背包体积是sum/2。 看代码的话,就可以发现,基本就是按照01背包的写法来的。 diff --git a/problems/0718.最长重复子数组.md b/problems/0718.最长重复子数组.md index 3a377077..be9109b2 100644 --- a/problems/0718.最长重复子数组.md +++ b/problems/0718.最长重复子数组.md @@ -128,7 +128,7 @@ public: **此时遍历B数组的时候,就要从后向前遍历,这样避免重复覆盖**。 -``` +```C++ class Solution { public: int findLength(vector& A, vector& B) { diff --git a/problems/动态规划总结篇.md b/problems/动态规划总结篇.md new file mode 100644 index 00000000..797f426a --- /dev/null +++ b/problems/动态规划总结篇.md @@ -0,0 +1,140 @@ + +

+ + + + +

+

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

+ + +如今动态规划已经讲解了42道经典题目,共50篇文章,是时候做一篇总结了。 + +关于动态规划,在专题第一篇[关于动态规划,你该了解这些!](https://mp.weixin.qq.com/s/ocZwfPlCWrJtVGACqFNAag)就说了动规五部曲,**而且强调了五部对解动规题目至关重要!** + +这是Carl做过一百多道动规题目总结出来的经验结晶啊,如果大家跟着「代码随想哦」刷过动规专题,一定会对这动规五部曲的作用感受极其深刻。 + +动规五部曲分别为: + +1. 确定dp数组(dp table)以及下标的含义 +2. 确定递推公式 +3. dp数组如何初始化 +4. 确定遍历顺序 +5. 举例推导dp数组 + +动规专题刚开始的时候,讲的题目比较简单,不少录友和我反应:这么简单的题目 讲的复杂了,不用那么多步骤分析,想出递推公式直接就AC这道题目了。 + +**Carl的观点一直都是 简单题是用来 巩固方法论的**。 简单题目是可以靠感觉,但后面稍稍难一点的题目,估计感觉就不好使了。 + +在动规专题讲解中,也充分体现出,这动规五部曲的重要性。 + +还有不少录友对动规的理解是:递推公式是才是最难最重要的,只要想出递归公式,其他都好办。 + +**其实这么想的同学基本对动规理解的不到位的**。 + +动规五部曲里,哪一部没想清楚,这道题目基本就做不出来,即使做出来了也没有想清楚,而是朦朦胧胧的就把题目过了。 + +* 如果想不清楚dp数组的具体含义,递归公式从何谈起,甚至初始化的时候就写错了。 +* 例如[动态规划:不同路径还不够,要有障碍!](https://mp.weixin.qq.com/s/lhqF0O4le9-wvalptOVOww) 在这道题目中,初始化才是重头戏 +* 如果看过背包系列,特别是完全背包,那么两层for循环先后顺序绝对可以搞懵很多人,反而递归公式是简单的。 +* 至于推导dp数组的重要性,动规专题里几乎每篇Carl都反复强调,当程序结果不对的时候,一定要自己推导公式,看看和程序打印的日志是否一样。 + +好啦,我们再一起回顾一下,动态规划专题中我们都讲了哪些内容。 + +## 动划基础 + +* [关于动态规划,你该了解这些!](https://mp.weixin.qq.com/s/ocZwfPlCWrJtVGACqFNAag) +* [动态规划:斐波那契数](https://mp.weixin.qq.com/s/ko0zLJplF7n_4TysnPOa_w) +* [动态规划:爬楼梯](https://mp.weixin.qq.com/s/Ohop0jApSII9xxOMiFhGIw) +* [动态规划:使用最小花费爬楼梯](https://mp.weixin.qq.com/s/djZB9gkyLFAKcQcSvKDorA) +* [动态规划:不同路径](https://mp.weixin.qq.com/s/MGgGIt4QCpFMROE9X9he_A) +* [动态规划:不同路径还不够,要有障碍!](https://mp.weixin.qq.com/s/lhqF0O4le9-wvalptOVOww) +* [动态规划:整数拆分,你要怎么拆?](https://mp.weixin.qq.com/s/cVbyHrsWH_Rfzlj-ESr01A) +* [动态规划:不同的二叉搜索树](https://mp.weixin.qq.com/s/8VE8pDrGxTf8NEVYBDwONw) + +## 背包问题系列 + +背包问题大纲 + +* [动态规划:关于01背包问题,你该了解这些!](https://mp.weixin.qq.com/s/FwIiPPmR18_AJO5eiidT6w) +* [动态规划:关于01背包问题,你该了解这些!(滚动数组)](https://mp.weixin.qq.com/s/M4uHxNVKRKm5HPjkNZBnFA) +* [动态规划:分割等和子集可以用01背包!](https://mp.weixin.qq.com/s/sYw3QtPPQ5HMZCJcT4EaLQ) +* [动态规划:最后一块石头的重量 II](https://mp.weixin.qq.com/s/WbwAo3jaUaNJjvhHgq0BGg) +* [动态规划:目标和!](https://mp.weixin.qq.com/s/2pWmaohX75gwxvBENS-NCw) +* [动态规划:一和零!](https://mp.weixin.qq.com/s/x-u3Dsp76DlYqtCe0xEKJw) +* [动态规划:关于完全背包,你该了解这些!](https://mp.weixin.qq.com/s/akwyxlJ4TLvKcw26KB9uJw) +* [动态规划:给你一些零钱,你要怎么凑?](https://mp.weixin.qq.com/s/PlowDsI4WMBOzf3q80AksQ) +* [动态规划:Carl称它为排列总和!](https://mp.weixin.qq.com/s/Iixw0nahJWQgbqVNk8k6gA) +* [动态规划:以前我没得选,现在我选择再爬一次!](https://mp.weixin.qq.com/s/e_wacnELo-2PG76EjrUakA) +* [动态规划: 给我个机会,我再兑换一次零钱](https://mp.weixin.qq.com/s/dyk-xNilHzNtVdPPLObSeQ) +* [动态规划:一样的套路,再求一次完全平方数](https://mp.weixin.qq.com/s/VfJT78p7UGpDZsapKF_QJQ) +* [动态规划:单词拆分](https://mp.weixin.qq.com/s/3Spx1B6MbIYjS8YkVbByzA) +* [动态规划:关于多重背包,你该了解这些!](https://mp.weixin.qq.com/s/b-UUUmbvG7URWyCjQkiuuQ) +* [听说背包问题很难? 这篇总结篇来拯救你了](https://mp.weixin.qq.com/s/ZOehl3U1mDiyOQjFG1wNJA) + +## 打家劫舍系列 + +* [动态规划:开始打家劫舍!](https://mp.weixin.qq.com/s/UZ31WdLEEFmBegdgLkJ8Dw) +* [动态规划:继续打家劫舍!](https://mp.weixin.qq.com/s/kKPx4HpH3RArbRcxAVHbeQ) +* [动态规划:还要打家劫舍!](https://mp.weixin.qq.com/s/BOJ1lHsxbQxUZffXlgglEQ) + +## 股票系列 + +股票问题总结 + +* [动态规划:买卖股票的最佳时机](https://mp.weixin.qq.com/s/keWo5qYJY4zmHn3amfXdfQ) +* [动态规划:本周我们都讲了这些(系列六)](https://mp.weixin.qq.com/s/GVu-6eF0iNkpVDKRXTPOTA) +* [动态规划:买卖股票的最佳时机II](https://mp.weixin.qq.com/s/d4TRWFuhaY83HPa6t5ZL-w) +* [动态规划:买卖股票的最佳时机III](https://mp.weixin.qq.com/s/Sbs157mlVDtAR0gbLpdKzg) +* [动态规划:买卖股票的最佳时机IV](https://mp.weixin.qq.com/s/jtxZJWAo2y5sUsW647Z5cw) +* [动态规划:最佳买卖股票时机含冷冻期](https://mp.weixin.qq.com/s/TczJGFAPnkjH9ET8kwH1OA) +* [动态规划:本周我们都讲了这些(系列七)](https://mp.weixin.qq.com/s/vdzDlrEvhXWRzblTnOnzKg) +* [动态规划:买卖股票的最佳时机含手续费](https://mp.weixin.qq.com/s/2Cd_uINjerZ25VHH0K2IBQ) +* [动态规划:股票系列总结篇](https://mp.weixin.qq.com/s/sC5XyEtDQWkonKnbCvZhDw) + +## 子序列系列 + + + +* [动态规划:最长递增子序列](https://mp.weixin.qq.com/s/f8nLO3JGfgriXep_gJQpqQ) +* [动态规划:最长连续递增序列](https://mp.weixin.qq.com/s/c0Nn0TtjkTISVdqRsyMmyA) +* [动态规划:最长重复子数组](https://mp.weixin.qq.com/s/U5WaWqBwdoxzQDotOdWqZg) +* [动态规划:最长公共子序列](https://mp.weixin.qq.com/s/Qq0q4HaE4TyasCTj2WGFOg) +* [动态规划:不相交的线](https://mp.weixin.qq.com/s/krfYzSYEO8jIoVfyHzR0rw) +* [动态规划:最大子序和](https://mp.weixin.qq.com/s/2Xtyi2L4r8sM-BcxgUKmcA) +* [动态规划:判断子序列](https://mp.weixin.qq.com/s/2pjT4B4fjfOx5iB6N6xyng) +* [动态规划:不同的子序列](https://mp.weixin.qq.com/s/1SULY2XVSROtk_hsoVLu8A) +* [动态规划:两个字符串的删除操作](https://mp.weixin.qq.com/s/a8BerpqSf76DCqkPDJrpYg) +* [动态规划:编辑距离](https://mp.weixin.qq.com/s/8aG71XjSgZG6kZbiAdkJnQ) +* [为了绝杀编辑距离,我做了三步铺垫,你都知道么?](https://mp.weixin.qq.com/s/kbs4kCUzg8gPFttF9H3Yyw) +* [动态规划:回文子串](https://mp.weixin.qq.com/s/2WetyP6IYQ6VotegepVpEw) +* [动态规划:最长回文子序列](https://mp.weixin.qq.com/s/jbd3p4QPm5Kh1s2smTzWag) + + +## 动规结束语 + +关于动规,还有 树形DP(打家劫舍系列里有一道),数位DP,区间DP ,概率型DP,博弈型DP,状态压缩dp等等等,这些我就不去做讲解了,面试中出现的概率非常低。 + +能把本篇中列举的题目都研究通透的话,你的动规水平就已经非常高了。 对付面试已经足够! + +这已经是全网对动规最深刻的讲解系列了。 + +**其实大家去网上搜一搜也可以发现,能把动态规划讲清楚的资料挺少的,因为动规确实很难!要给别人讲清楚更难!** + +《剑指offer》上 动规的题目很少,经典的算法书籍《算法4》 没有讲 动规,而《算法导论》讲的动规基本属于劝退级别的。 + +讲清楚一道题容易,讲清楚两道题也容易,但把整个动态规划的各个分支讲清楚,每道题目讲通透,并用一套方法论把整个动规贯彻始终就非常难了。 + +所以Carl花费的这么大精力,把自己对动规算法理解 一五一十的全部分享给了录友们,帮助大家少走弯路! + +**至于动态规划PDF,即将在公众号「代码随想录」全网首发!** + +最后感谢录友们的一路支持,Carl才有继续更下去的动力[玫瑰],[撒花] + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) +* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) +
+ From 3362183d8446e551f0361ead95dca6bec8b7411a Mon Sep 17 00:00:00 2001 From: boom-jumper <56831966+boom-jumper@users.noreply.github.com> Date: Tue, 1 Jun 2021 18:08:16 +0800 Subject: [PATCH 49/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A00347=E5=89=8DK=E4=B8=AA?= =?UTF-8?q?=E9=AB=98=E9=A2=91=E5=85=83=E7=B4=A0=20python3=20=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/0347.前K个高频元素.md | 57 ++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/problems/0347.前K个高频元素.md b/problems/0347.前K个高频元素.md index 841584b4..29963b48 100644 --- a/problems/0347.前K个高频元素.md +++ b/problems/0347.前K个高频元素.md @@ -162,6 +162,63 @@ class Solution { Python: +```python +class Solution: + def sift(self, alist, low, high): + '''小根堆构建''' + i = low + j = 2 * i + 1 + tmp = alist[low] + while j <= high: + if j + 1 <= high and alist[j+1] <= alist[j]: + j += 1 + if alist[j] < tmp: + alist[i] = alist[j] + i = j + j = 2 * i + 1 + else: + alist[i] = tmp + break + else: + alist[i] = tmp + + + def topK(self, nums, k): + # 建立小根堆 + heap = nums[:k] + for i in range((k-2)//2, -1, -1): + self.sift(heap, i, k-1) + + # 把后续的k到len(nums)填充到小根堆里 + for i in range(k, len(nums)): + if nums[i] >= heap[0]: + heap[0] = nums[i] + self.sift(heap, 0, k-1) + + # 排序 + for i in range(k-1, -1, -1): + heap[0], heap[i]= heap[i], heap[0] + self.sift(heap, 0, i-1) + return heap + + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + dict1 = dict() + for val in nums: + if val not in dict1: + dict1[val] = 1 + else: + dict1[val] += 1 + res = list() + ind = list() + for item in dict1: + res.append([dict1[item], item]) + result = list() + heap = self.topK(res, k) + print(heap) + for val in heap: + result.append(val[1]) + return result +``` Go: From d9e4b337243d51e39bf378737c8c2eac600de3d8 Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Tue, 1 Jun 2021 03:47:40 -0700 Subject: [PATCH 50/95] =?UTF-8?q?Update=200239.=E6=BB=91=E5=8A=A8=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E6=9C=80=E5=A4=A7=E5=80=BC.md?= 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 ed17157a..47383a47 100644 --- a/problems/0239.滑动窗口最大值.md +++ b/problems/0239.滑动窗口最大值.md @@ -263,6 +263,41 @@ class Solution { ``` Python: +```python +class MyQueue: #单调队列(从大到小 + def __init__(self): + self.queue = [] #使用list来实现单调队列 + + #每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。 + #同时pop之前判断队列当前是否为空。 + def pop(self, value): + if self.queue and value == self.queue[0]: + self.queue.pop(0)#list.pop()时间复杂度为O(n),这里可以使用collections.deque() + + #如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。 + #这样就保持了队列里的数值是单调从大到小的了。 + def push(self, value): + while self.queue and value > self.queue[-1]: + self.queue.pop() + self.queue.append(value) + + #查询当前队列里的最大值 直接返回队列前端也就是front就可以了。 + def front(self): + return self.queue[0] + +class Solution: + def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]: + que = MyQueue() + result = [] + for i in range(k): #先将前k的元素放进队列 + que.push(nums[i]) + result.append(que.front()) #result 记录前k的元素的最大值 + for i in range(k, len(nums)): + que.pop(nums[i - k]) #滑动窗口移除最前面元素 + que.push(nums[i]) #滑动窗口前加入最后面的元素 + result.append(que.front()) #记录对应的最大值 + return result +``` Go: From 9219242b3af749a96efbbaf7d8ea5089a36ba7fe Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Tue, 1 Jun 2021 20:34:57 +0800 Subject: [PATCH 51/95] =?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=20go=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 使用map方式解题,降低时间复杂度 --- problems/0001.两数之和.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index 77318294..3d0674ce 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -134,6 +134,20 @@ func twoSum(nums []int, target int) []int { } return []int{} } + +```go +// 使用map方式解题,降低时间复杂度 +func twoSum(nums []int, target int) []int { + m := make(map[int]int) + for index, val := range nums { + if preIndex, ok := m[target-val]; ok { + return []int{preIndex, index} + } else { + m[val] = index + } + } + return []int{} +} ``` Rust From 36626386c329d75524843fab42f740e548578173 Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Tue, 1 Jun 2021 20:35:55 +0800 Subject: [PATCH 52/95] =?UTF-8?q?=E6=9B=B4=E6=94=B9=200001.=E4=B8=A4?= =?UTF-8?q?=E6=95=B0=E4=B9=8B=E5=92=8C=20=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0001.两数之和.md | 1 + 1 file changed, 1 insertion(+) diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md index 3d0674ce..4a1a987f 100644 --- a/problems/0001.两数之和.md +++ b/problems/0001.两数之和.md @@ -134,6 +134,7 @@ func twoSum(nums []int, target int) []int { } return []int{} } +``` ```go // 使用map方式解题,降低时间复杂度 From ce970df5ffdb2e428b4ec2417e2bbccdc9371a31 Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Tue, 1 Jun 2021 23:43:02 +0800 Subject: [PATCH 53/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200454.=E5=9B=9B?= =?UTF-8?q?=E6=95=B0=E7=9B=B8=E5=8A=A0II=20go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0454.四数相加II.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/problems/0454.四数相加II.md b/problems/0454.四数相加II.md index 2c648f58..5291060c 100644 --- a/problems/0454.四数相加II.md +++ b/problems/0454.四数相加II.md @@ -154,6 +154,23 @@ class Solution(object): Go: +```go +func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int { + m := make(map[int]int) + count := 0 + for _, v1 := range nums1 { + for _, v2 := range nums2 { + m[v1+v2]++ + } + } + for _, v3 := range nums3 { + for _, v4 := range nums4 { + count += m[-v3-v4] + } + } + return count +} +``` javaScript: From 67313906d16f8cf0e613968bf0f9b8031a273cdd Mon Sep 17 00:00:00 2001 From: Yang Date: Tue, 1 Jun 2021 14:41:22 -0400 Subject: [PATCH 54/95] =?UTF-8?q?Update=200056.=E5=90=88=E5=B9=B6=E5=8C=BA?= =?UTF-8?q?=E9=97=B4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Java solution. For sorting, no need to compare the second element in an interval. --- problems/0056.合并区间.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/problems/0056.合并区间.md b/problems/0056.合并区间.md index eb8e7bff..f42fced7 100644 --- a/problems/0056.合并区间.md +++ b/problems/0056.合并区间.md @@ -144,11 +144,7 @@ class Solution { Arrays.sort(intervals, new Comparator() { @Override public int compare(int[] o1, int[] o2) { - if (o1[0] != o2[0]) { - return Integer.compare(o1[0],o2[0]); - } else { - return Integer.compare(o1[1],o2[1]); - } + return Integer.compare(o1[0], o2[0]); } }); From 838e290312af9218c62630a18022087205c8a2bc Mon Sep 17 00:00:00 2001 From: Yang Date: Tue, 1 Jun 2021 14:46:19 -0400 Subject: [PATCH 55/95] =?UTF-8?q?Update=200056.=E5=90=88=E5=B9=B6=E5=8C=BA?= =?UTF-8?q?=E9=97=B4.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify sorting --- problems/0056.合并区间.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/problems/0056.合并区间.md b/problems/0056.合并区间.md index f42fced7..43ff447d 100644 --- a/problems/0056.合并区间.md +++ b/problems/0056.合并区间.md @@ -141,12 +141,7 @@ Java: class Solution { public int[][] merge(int[][] intervals) { List res = new LinkedList<>(); - Arrays.sort(intervals, new Comparator() { - @Override - public int compare(int[] o1, int[] o2) { - return Integer.compare(o1[0], o2[0]); - } - }); + Arrays.sort(intervals, (o1, o2) -> o1[0] - o2[0]); int start = intervals[0][0]; for (int i = 1; i < intervals.length; i++) { From f4736c7dd2fb5ce75864dc34baf5e4bf212c16d4 Mon Sep 17 00:00:00 2001 From: Yang Date: Tue, 1 Jun 2021 14:48:52 -0400 Subject: [PATCH 56/95] Improve comparison --- problems/0056.合并区间.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0056.合并区间.md b/problems/0056.合并区间.md index 43ff447d..d4ffc554 100644 --- a/problems/0056.合并区间.md +++ b/problems/0056.合并区间.md @@ -141,7 +141,7 @@ Java: class Solution { public int[][] merge(int[][] intervals) { List res = new LinkedList<>(); - Arrays.sort(intervals, (o1, o2) -> o1[0] - o2[0]); + Arrays.sort(intervals, (o1, o2) -> Integer.compare(o1[0], o2[0])); int start = intervals[0][0]; for (int i = 1; i < intervals.length; i++) { From bb5cfa68b2a20bc3609b56cd65d2542630c86f37 Mon Sep 17 00:00:00 2001 From: "Neil.Liu" <88214924@qq.com> Date: Wed, 2 Jun 2021 10:15:47 +0800 Subject: [PATCH 57/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A00151.=E7=BF=BB=E8=BD=AC?= =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E9=87=8C=E7=9A=84=E5=8D=95=E8=AF=8D?= =?UTF-8?q?Go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0151.翻转字符串里的单词.md | 56 +++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/problems/0151.翻转字符串里的单词.md b/problems/0151.翻转字符串里的单词.md index 512360fe..63499b71 100644 --- a/problems/0151.翻转字符串里的单词.md +++ b/problems/0151.翻转字符串里的单词.md @@ -318,9 +318,61 @@ class Solution { Python: - Go: +```go +import ( + "fmt" +) + +func reverseWords(s string) string { + //1.使用双指针删除冗余的空格 + slowIndex, fastIndex := 0, 0 + b := []byte(s) + //删除头部冗余空格 + for len(b) > 0 && fastIndex < len(b) && b[fastIndex] == ' ' { + fastIndex++ + } + //删除单词间冗余空格 + for ; fastIndex < len(b); fastIndex++ { + if fastIndex-1 > 0 && b[fastIndex-1] == b[fastIndex] && b[fastIndex] == ' ' { + continue + } + b[slowIndex] = b[fastIndex] + slowIndex++ + } + //删除尾部冗余空格 + if slowIndex-1 > 0 && b[slowIndex-1] == ' ' { + b = b[:slowIndex-1] + } else { + b = b[:slowIndex] + } + //2.反转整个字符串 + reverse(&b, 0, len(b)-1) + //3.反转单个单词 i单词开始位置,j单词结束位置 + i := 0 + for i < len(b) { + j := i + for ; j < len(b) && b[j] != ' '; j++ { + } + reverse(&b, i, j-1) + i = j + i++ + } + return string(b) +} + +func reverse(b *[]byte, left, right int) { + for left < right { + (*b)[left], (*b)[right] = (*b)[right], (*b)[left] + left++ + right-- + } +} +``` + + + @@ -328,4 +380,4 @@ Go: * 作者微信:[程序员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 From fae5373477b50d259c94c08dcef1ce6254081491 Mon Sep 17 00:00:00 2001 From: "Neil.Liu" <88214924@qq.com> Date: Wed, 2 Jun 2021 10:25:09 +0800 Subject: [PATCH 58/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=89=91=E6=8C=87Offer?= =?UTF-8?q?58-II.=E5=B7=A6=E6=97=8B=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2Go?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../剑指Offer58-II.左旋转字符串.md | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md index 648546c1..39c8382c 100644 --- a/problems/剑指Offer58-II.左旋转字符串.md +++ b/problems/剑指Offer58-II.左旋转字符串.md @@ -23,7 +23,7 @@ https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/ 示例 2: 输入: s = "lrloseumgh", k = 6 输出: "umghlrlose" -  + 限制: 1 <= k < s.length <= 10000 @@ -119,9 +119,31 @@ class Solution { ``` Python: - Go: +```go +func reverseLeftWords(s string, n int) string { + b := []byte(s) + // 1. 反转前n个字符 + // 2. 反转第n到end字符 + // 3. 反转整个字符 + reverse(b, 0, n-1) + reverse(b, n, len(b)-1) + reverse(b, 0, len(b)-1) + return string(b) +} +// 切片是引用传递 +func reverse(b []byte, left, right int){ + for left < right{ + b[left], b[right] = b[right],b[left] + left++ + right-- + } +} +``` + + + @@ -129,4 +151,4 @@ Go: * 作者微信:[程序员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 From 9163ed6b65667e4c95a9ed2b26bd63a6a516fc9f Mon Sep 17 00:00:00 2001 From: zhangzw Date: Wed, 2 Jun 2021 11:49:59 +0800 Subject: [PATCH 59/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A01049.=E6=9C=80=E5=90=8E?= =?UTF-8?q?=E4=B8=80=E5=9D=97=E7=9F=B3=E5=A4=B4=E7=9A=84=E9=87=8D=E9=87=8F?= =?UTF-8?q?II=20Go=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../1049.最后一块石头的重量II.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/problems/1049.最后一块石头的重量II.md b/problems/1049.最后一块石头的重量II.md index f74600b1..c09e476a 100644 --- a/problems/1049.最后一块石头的重量II.md +++ b/problems/1049.最后一块石头的重量II.md @@ -191,7 +191,33 @@ class Solution: ``` Go: +```go +func lastStoneWeightII(stones []int) int { + // 15001 = 30 * 1000 /2 +1 + dp := make([]int, 15001) + // 求target + sum := 0 + for _, v := range stones { + sum += v + } + target := sum / 2 + // 遍历顺序 + for i := 0; i < len(stones); i++ { + for j := target; j >= stones[i]; j-- { + // 推导公式 + dp[j] = max(dp[j], dp[j-stones[i]]+stones[i]) + } + } + return sum - 2 * dp[target] +} +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` From 9f84671e690208a1b40debe15b1bfa624448f348 Mon Sep 17 00:00:00 2001 From: zhangzw Date: Wed, 2 Jun 2021 11:51:50 +0800 Subject: [PATCH 60/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A00494.=E7=9B=AE=E6=A0=87?= =?UTF-8?q?=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 --- problems/0494.目标和.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/problems/0494.目标和.md b/problems/0494.目标和.md index c772a09d..c917ed5c 100644 --- a/problems/0494.目标和.md +++ b/problems/0494.目标和.md @@ -276,7 +276,35 @@ class Solution: ``` Go: - +```go +func findTargetSumWays(nums []int, target int) int { + sum := 0 + for _, v := range nums { + sum += v + } + if target > sum { + return 0 + } + if (sum+target)%2 == 1 { + return 0 + } + // 计算背包大小 + bag := (sum + target) / 2 + // 定义dp数组 + dp := make([]int, bag+1) + // 初始化 + dp[0] = 1 + // 遍历顺序 + for i := 0; i < len(nums); i++ { + for j := bag; j >= nums[i]; j-- { + //推导公式 + dp[j] += dp[j-nums[i]] + //fmt.Println(dp) + } + } + return dp[bag] +} +``` From 9707fbc521b16e79a43ef588e4f4a77454a30fdf Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Wed, 2 Jun 2021 02:41:59 -0700 Subject: [PATCH 61/95] =?UTF-8?q?Update=200347.=E5=89=8DK=E4=B8=AA?= =?UTF-8?q?=E9=AB=98=E9=A2=91=E5=85=83=E7=B4=A0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0347.前K个高频元素.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/problems/0347.前K个高频元素.md b/problems/0347.前K个高频元素.md index 841584b4..71af618e 100644 --- a/problems/0347.前K个高频元素.md +++ b/problems/0347.前K个高频元素.md @@ -162,7 +162,33 @@ class Solution { Python: - +```python +#时间复杂度:O(nlogk) +#空间复杂度:O(n) +import heapq +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + #要统计元素出现频率 + map_ = {} #nums[i]:对应出现的次数 + for i in range(len(nums)): + map_[nums[i]] = map_.get(nums[i], 0) + 1 + + #对频率排序 + #定义一个小顶堆,大小为k + pri_que = [] #小顶堆 + + #用固定大小为k的小顶堆,扫面所有频率的数值 + for key, freq in map_.items(): + heapq.heappush(pri_que, (freq, key)) + if len(pri_que) > k: #如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k + heapq.heappop(pri_que) + + #找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒叙来输出到数组 + result = [0] * k + for i in range(k-1, -1, -1): + result[i] = heapq.heappop(pri_que)[1] + return result +``` Go: From 2a7c3cb87c2fbcefe1b1995cfa0d45ba7e857627 Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Wed, 2 Jun 2021 03:09:05 -0700 Subject: [PATCH 62/95] =?UTF-8?q?Update=20=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E7=BB=9F=E4=B8=80=E8=BF=AD=E4=BB=A3=E6=B3=95.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/二叉树的统一迭代法.md | 71 +++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/problems/二叉树的统一迭代法.md b/problems/二叉树的统一迭代法.md index dca5d3e3..dc79643d 100644 --- a/problems/二叉树的统一迭代法.md +++ b/problems/二叉树的统一迭代法.md @@ -239,7 +239,78 @@ Java: ``` Python: +> 迭代法前序遍历 +```python +class Solution: + def preorderTraversal(self, root: TreeNode) -> List[int]: + result = [] + st= [] + if root: + st.append(root) + while st: + node = st.pop() + if node != None: + if node.right: #右 + st.append(node.right) + if node.left: #左 + st.append(node.left) + st.append(node) #中 + st.append(None) + else: + node = st.pop() + result.append(node.val) + return result +``` + +> 迭代法中序遍历 +```python +class Solution: + def inorderTraversal(self, root: TreeNode) -> List[int]: + result = [] + st = [] + if root: + st.append(root) + while st: + node = st.pop() + if node != None: + if node.right: #添加右节点(空节点不入栈) + st.append(node.right) + + st.append(node) #添加中节点 + st.append(None) #中节点访问过,但是还没有处理,加入空节点做为标记。 + + if node.left: #添加左节点(空节点不入栈) + st.append(node.left) + else: #只有遇到空节点的时候,才将下一个节点放进结果集 + node = st.pop() #重新取出栈中元素 + result.append(node.val) #加入到结果集 + return result +``` + +> 迭代法后序遍历 +```python +class Solution: + def postorderTraversal(self, root: TreeNode) -> List[int]: + result = [] + st = [] + if root: + st.append(root) + while st: + node = st.pop() + if node != None: + st.append(node) #中 + st.append(None) + + if node.right: #右 + st.append(node.right) + if node.left: #左 + st.append(node.left) + else: + node = st.pop() + result.append(node.val) + return result +``` Go: > 前序遍历统一迭代法 From 045f3f98d6234e548c8b98edee911f2eb39b482f Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Wed, 2 Jun 2021 20:10:28 +0800 Subject: [PATCH 63/95] =?UTF-8?q?0134.=E5=8A=A0=E6=B2=B9=E7=AB=99.md=20Jav?= =?UTF-8?q?ascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0134.加油站.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/problems/0134.加油站.md b/problems/0134.加油站.md index 5c3f70a8..dfed2d96 100644 --- a/problems/0134.加油站.md +++ b/problems/0134.加油站.md @@ -241,7 +241,28 @@ class Solution: Go: +Javascript: +```Javascript +var canCompleteCircuit = function(gas, cost) { + const gasLen = gas.length + let start = 0 + let curSum = 0 + let totalSum = 0 + for(let i = 0; i < gasLen; i++) { + curSum += gas[i] - cost[i] + totalSum += gas[i] - cost[i] + if(curSum < 0) { + curSum = 0 + start = i + 1 + } + } + + if(totalSum < 0) return -1 + + return start +}; +``` ----------------------- From bed3f0b09fc46f11d319f33225e78e7c12d5842b Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Wed, 2 Jun 2021 20:11:11 +0800 Subject: [PATCH 64/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200383.=E8=B5=8E?= =?UTF-8?q?=E9=87=91=E4=BF=A1=20go=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0383.赎金信.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/problems/0383.赎金信.md b/problems/0383.赎金信.md index fd8175db..23e2c5fd 100644 --- a/problems/0383.赎金信.md +++ b/problems/0383.赎金信.md @@ -166,6 +166,21 @@ class Solution(object): ``` Go: +```go +func canConstruct(ransomNote string, magazine string) bool { + record := make([]int, 26) + for _, v := range magazine { + record[v-'a']++ + } + for _, v := range ransomNote { + record[v-'a']-- + if record[v-'a'] < 0 { + return false + } + } + return true +} +``` javaScript: From 41c4f17833df822a740ae2b901fb3bb530b5b47b Mon Sep 17 00:00:00 2001 From: evanlai Date: Wed, 2 Jun 2021 23:39:59 +0800 Subject: [PATCH 65/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200455.=E5=88=86?= =?UTF-8?q?=E5=8F=91=E9=A5=BC=E5=B9=B2=20python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0455.分发饼干.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/problems/0455.分发饼干.md b/problems/0455.分发饼干.md index b3714c43..ecf7f132 100644 --- a/problems/0455.分发饼干.md +++ b/problems/0455.分发饼干.md @@ -134,7 +134,21 @@ class Solution { ``` Python: - +```python +class Solution: + def findContentChildren(self, g: List[int], s: List[int]) -> int: + #先考虑胃口小的孩子 + g.sort() + s.sort() + i=j=0 + count = 0 + while(i Date: Wed, 2 Jun 2021 23:41:29 +0800 Subject: [PATCH 66/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200376.=E6=91=86?= =?UTF-8?q?=E5=8A=A8=E5=BA=8F=E5=88=97=20python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0376.摆动序列.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/problems/0376.摆动序列.md b/problems/0376.摆动序列.md index 6fa30cde..bbca5ea0 100644 --- a/problems/0376.摆动序列.md +++ b/problems/0376.摆动序列.md @@ -138,7 +138,21 @@ class Solution { ``` Python: - +```python +class Solution: + def wiggleMaxLength(self, nums: List[int]) -> int: + #贪心 求波峰数量 + 波谷数量 + if len(nums)<=1: + return len(nums) + cur, pre = 0,0 #当前一对差值,前一对差值 + count = 1#默认最右边有一个峰值 + for i in range(len(nums)-1): + cur = nums[i+1] - nums[i] + if((cur>0 and pre<=0) or (cur<0 and pre>=0)): + count += 1 + pre = cur + return count +``` Go: From 37515f2202b8a9868a25f8c000f46fe589a093a3 Mon Sep 17 00:00:00 2001 From: fusunx <1102654482@qq.com> Date: Thu, 3 Jun 2021 08:25:39 +0800 Subject: [PATCH 67/95] =?UTF-8?q?0135.=E5=88=86=E5=8F=91=E7=B3=96=E6=9E=9C?= =?UTF-8?q?.md=20Javascript?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0135.分发糖果.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/0135.分发糖果.md b/problems/0135.分发糖果.md index a3311791..fd791277 100644 --- a/problems/0135.分发糖果.md +++ b/problems/0135.分发糖果.md @@ -176,7 +176,30 @@ class Solution: Go: +Javascript: +```Javascript +var candy = function(ratings) { + let candys = new Array(ratings.length).fill(1) + for(let i = 1; i < ratings.length; i++) { + if(ratings[i] > ratings[i - 1]) { + candys[i] = candys[i - 1] + 1 + } + } + + for(let i = ratings.length - 2; i >= 0; i--) { + if(ratings[i] > ratings[i + 1]) { + candys[i] = Math.max(candys[i], candys[i + 1] + 1) + } + } + + let count = candys.reduce((a, b) => { + return a + b + }) + + return count +}; +``` ----------------------- From 1a4a287243e43649166fea0d028dc8b733602387 Mon Sep 17 00:00:00 2001 From: nmydt <62681228+nmydt@users.noreply.github.com> Date: Thu, 3 Jun 2021 13:00:14 +0800 Subject: [PATCH 68/95] =?UTF-8?q?=E5=A2=9E=E5=8A=A0112.=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=80=BB=E5=92=8C=20JAVA=20=E8=BF=AD=E4=BB=A3=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/0112.路径总和.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md index 4ccd8912..d810a046 100644 --- a/problems/0112.路径总和.md +++ b/problems/0112.路径总和.md @@ -345,6 +345,36 @@ class Solution { return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val); } } +``` +迭代 +```java +class Solution { + public boolean hasPathSum(TreeNode root, int targetSum) { + if(root==null)return false; + Stack stack1 = new Stack<>(); + Stack stack2 = new Stack<>(); + stack1.push(root);stack2.push(root.val); + while(!stack1.isEmpty()){ + int size = stack1.size(); + for(int i=0;i Date: Thu, 3 Jun 2021 14:30:31 +0800 Subject: [PATCH 69/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A00028.=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?strStr=20Go=E8=AF=AD=E8=A8=80=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0028.实现strStr.md | 90 ++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md index b8ebcaa1..1dba5a38 100644 --- a/problems/0028.实现strStr.md +++ b/problems/0028.实现strStr.md @@ -726,10 +726,98 @@ class Solution: Go: +```go +// 方法一:前缀表使用减1实现 + +// getNext 构造前缀表next +// params: +// next 前缀表数组 +// s 模式串 +func getNext(next []int, s string) { + j := -1 // j表示 最长相等前后缀长度 + next[0] = j + + for i := 1; i < len(s); i++ { + for j >= 0 && s[i] != s[j+1] { + j = next[j] // 回退前一位 + } + if s[i] == s[j+1] { + j++ + } + next[i] = j // next[i]是i(包括i)之前的最长相等前后缀长度 + } +} +func strStr(haystack string, needle string) int { + if len(needle) == 0 { + return 0 + } + next := make([]int, len(needle)) + getNext(next, needle) + j := -1 // 模式串的起始位置 next为-1 因此也为-1 + for i := 0; i < len(haystack); i++ { + for j >= 0 && haystack[i] != needle[j+1] { + j = next[j] // 寻找下一个匹配点 + } + if haystack[i] == needle[j+1] { + j++ + } + if j == len(needle)-1 { // j指向了模式串的末尾 + return i - len(needle) + 1 + } + } + return -1 +} +``` + +```go +// 方法二: 前缀表无减一或者右移 + +// getNext 构造前缀表next +// params: +// next 前缀表数组 +// s 模式串 +func getNext(next []int, s string) { + j := 0 + next[0] = j + for i := 1; i < len(s); i++ { + for j > 0 && s[i] != s[j] { + j = next[j-1] + } + if s[i] == s[j] { + j++ + } + next[i] = j + } +} +func strStr(haystack string, needle string) int { + n := len(needle) + if n == 0 { + return 0 + } + j := 0 + next := make([]int, n) + getNext(next, needle) + for i := 0; i < len(haystack); i++ { + for j > 0 && haystack[i] != needle[j] { + j = next[j-1] // 回退到j的前一位 + } + if haystack[i] == needle[j] { + j++ + } + if j == n { + return i - n + 1 + } + } + return -1 +} +``` + + + ----------------------- * 作者微信:[程序员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 From 7bf42a83f42131f87c881a42567994379ceb6b8c Mon Sep 17 00:00:00 2001 From: "Neil.Liu" <88214924@qq.com> Date: Thu, 3 Jun 2021 15:42:44 +0800 Subject: [PATCH 70/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A00459.=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E7=9A=84=E5=AD=90=E5=AD=97=E7=AC=A6=E4=B8=B2=20Go=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0459.重复的子字符串.md | 60 +++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/problems/0459.重复的子字符串.md b/problems/0459.重复的子字符串.md index 51a903ef..deb755bf 100644 --- a/problems/0459.重复的子字符串.md +++ b/problems/0459.重复的子字符串.md @@ -236,6 +236,64 @@ class Solution: Go: +这里使用了前缀表统一减一的实现方式 + +```go +func repeatedSubstringPattern(s string) bool { + n := len(s) + if n == 0 { + return false + } + next := make([]int, n) + j := -1 + next[0] = j + for i := 1; i < n; i++ { + for j >= 0 && s[i] != s[j+1] { + j = next[j] + } + if s[i] == s[j+1] { + j++ + } + next[i] = j + } + // next[n-1]+1 最长相同前后缀的长度 + if next[n-1] != -1 && n%(n-(next[n-1]+1)) == 0 { + return true + } + return false +} +``` + +前缀表(不减一)的代码实现 + +```go +func repeatedSubstringPattern(s string) bool { + n := len(s) + if n == 0 { + return false + } + j := 0 + next := make([]int, n) + next[0] = j + for i := 1; i < n; i++ { + for j > 0 && s[i] != s[j] { + j = next[j-1] + } + if s[i] == s[j] { + j++ + } + next[i] = j + } + // next[n-1] 最长相同前后缀的长度 + if next[n-1] != 0 && n%(n-next[n-1]) == 0 { + return true + } + return false +} +``` + + + @@ -243,4 +301,4 @@ Go: * 作者微信:[程序员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 From 36957838cb9b449ba118d5762e401933258acdf8 Mon Sep 17 00:00:00 2001 From: jojoo15 <75017412+jojoo15@users.noreply.github.com> Date: Thu, 3 Jun 2021 10:41:52 +0200 Subject: [PATCH 71/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200037.=E8=A7=A3?= =?UTF-8?q?=E6=95=B0=E7=8B=AC=20python3=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加 0037.解数独 python3版本 --- problems/0037.解数独.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/problems/0037.解数独.md b/problems/0037.解数独.md index d5df95e8..4eb60704 100644 --- a/problems/0037.解数独.md +++ b/problems/0037.解数独.md @@ -287,7 +287,39 @@ class Solution { ``` Python: - +```python3 +class Solution: + def solveSudoku(self, board: List[List[str]]) -> None: + """ + Do not return anything, modify board in-place instead. + """ + def backtrack(board): + for i in range(len(board)): #遍历行 + for j in range(len(board[0])): #遍历列 + if board[i][j] != ".": continue + for k in range(1,10): #(i, j) 这个位置放k是否合适 + if isValid(i,j,k,board): + board[i][j] = str(k) #放置k + if backtrack(board): return True #如果找到合适一组立刻返回 + board[i][j] = "." #回溯,撤销k + return False #9个数都试完了,都不行,那么就返回false + return True #遍历完没有返回false,说明找到了合适棋盘位置了 + def isValid(row,col,val,board): + for i in range(9): #判断行里是否重复 + if board[row][i] == str(val): + return False + for j in range(9): #判断列里是否重复 + if board[j][col] == str(val): + return False + startRow = (row // 3) * 3 + startcol = (col // 3) * 3 + for i in range(startRow,startRow + 3): #判断9方格里是否重复 + for j in range(startcol,startcol + 3): + if board[i][j] == str(val): + return False + return True + backtrack(board) +``` Go: From 17dd8f8499e6f5ab65d0529b3b9d9b388479b680 Mon Sep 17 00:00:00 2001 From: NevS <1173325467@qq.com> Date: Fri, 4 Jun 2021 00:20:25 +0800 Subject: [PATCH 72/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200541.=E5=8F=8D?= =?UTF-8?q?=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2II=20go=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0541.反转字符串II.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/problems/0541.反转字符串II.md b/problems/0541.反转字符串II.md index 6c8f3e94..00581fc0 100644 --- a/problems/0541.反转字符串II.md +++ b/problems/0541.反转字符串II.md @@ -164,6 +164,30 @@ class Solution(object): Go: +```go +func reverseStr(s string, k int) string { + ss := []byte(s) + length := len(s) + for i := 0; i < length; i += 2 * k { + if i + k <= length { + reverse(ss[i:i+k]) + } else { + reverse(ss[i:length]) + } + } + return string(ss) +} + +func reverse(b []byte) { + left := 0 + right := len(b) - 1 + for left < right { + b[left], b[right] = b[right], b[left] + left++ + right-- + } +} +``` javaScript: From 0dd4590945249059a37638bfe3ab79dc134b8e40 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Thu, 3 Jun 2021 18:44:16 -0400 Subject: [PATCH 73/95] =?UTF-8?q?Update=20=E9=93=BE=E8=A1=A8=E7=90=86?= =?UTF-8?q?=E8=AE=BA=E5=9F=BA=E7=A1=80.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix typo --- problems/链表理论基础.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/链表理论基础.md b/problems/链表理论基础.md index ea3b9098..252247c7 100644 --- a/problems/链表理论基础.md +++ b/problems/链表理论基础.md @@ -83,7 +83,7 @@ struct ListNode { 有同学说了,我不定义构造函数行不行,答案是可以的,C++默认生成一个构造函数。 -但是这个构造函数不会初始化任何成员变化,下面我来举两个例子: +但是这个构造函数不会初始化任何成员变量,下面我来举两个例子: 通过自己定义构造函数初始化节点: From b503c622640ca966325a37b96b63080a3bac1972 Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Fri, 4 Jun 2021 09:30:11 +0800 Subject: [PATCH 74/95] Update --- README.md | 6 +- problems/0018.四数之和.md | 27 +- problems/0028.实现strStr.md | 5 - problems/0454.四数相加II.md | 3 +- problems/二叉树的理论基础.md | 202 ----------- .../背包理论基础01背包-一维DP.md | 231 ------------- .../背包理论基础01背包-二维DP.md | 318 ------------------ 7 files changed, 18 insertions(+), 774 deletions(-) delete mode 100644 problems/二叉树的理论基础.md delete mode 100644 problems/背包理论基础01背包-一维DP.md delete mode 100644 problems/背包理论基础01背包-二维DP.md diff --git a/README.md b/README.md index b4e82eb0..58f71049 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,10 @@

- + - +

# LeetCode 刷题攻略 @@ -302,7 +302,7 @@ 动态规划专题已经开始啦,来不及解释了,小伙伴们上车别掉队! -背包问题大纲 + 1. [关于动态规划,你该了解这些!](./problems/动态规划理论基础.md) 2. [动态规划:斐波那契数](./problems/0509.斐波那契数.md) 3. [动态规划:爬楼梯](./problems/0070.爬楼梯.md) diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md index a1591736..0caf12be 100644 --- a/problems/0018.四数之和.md +++ b/problems/0018.四数之和.md @@ -31,38 +31,39 @@ https://leetcode-cn.com/problems/4sum/ # 思路 -四数之和,和[三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)是一个思路,都是使用双指针法, 基本解法就是在[三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A) 的基础上再套一层for循环。 +四数之和,和[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)是一个思路,都是使用双指针法, 基本解法就是在[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg) 的基础上再套一层for循环。 但是有一些细节需要注意,例如: 不要判断`nums[k] > target` 就返回了,三数之和 可以通过 `nums[i] > 0` 就返回了,因为 0 已经是确定的数了,四数之和这道题目 target是任意值。(大家亲自写代码就能感受出来) -[三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)的双指针解法是一层for循环num[i]为确定值,然后循环内有left和right下表作为双指针,找到nums[i] + nums[left] + nums[right] == 0。 +[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)的双指针解法是一层for循环num[i]为确定值,然后循环内有left和right下表作为双指针,找到nums[i] + nums[left] + nums[right] == 0。 四数之和的双指针解法是两层for循环nums[k] + nums[i]为确定值,依然是循环内有left和right下表作为双指针,找出nums[k] + nums[i] + nums[left] + nums[right] == target的情况,三数之和的时间复杂度是O(n^2),四数之和的时间复杂度是O(n^3) 。 那么一样的道理,五数之和、六数之和等等都采用这种解法。 -对于[三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A)双指针法就是将原本暴力O(n^3)的解法,降为O(n^2)的解法,四数之和的双指针解法就是将原本暴力O(n^4)的解法,降为O(n^3)的解法。 +对于[15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg)双指针法就是将原本暴力O(n^3)的解法,降为O(n^2)的解法,四数之和的双指针解法就是将原本暴力O(n^4)的解法,降为O(n^3)的解法。 -之前我们讲过哈希表的经典题目:[四数相加II](https://mp.weixin.qq.com/s/Ue8pKKU5hw_m-jPgwlHcbA),相对于本题简单很多,因为本题是要求在一个集合中找出四个数相加等于target,同时四元组不能重复。 +之前我们讲过哈希表的经典题目:[454.四数相加II](https://mp.weixin.qq.com/s/12g_w6RzHuEpFts1pT6BWw),相对于本题简单很多,因为本题是要求在一个集合中找出四个数相加等于target,同时四元组不能重复。 -而[四数相加II](https://mp.weixin.qq.com/s/Ue8pKKU5hw_m-jPgwlHcbA)是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于本题还是简单了不少! +而[454.四数相加II](https://mp.weixin.qq.com/s/12g_w6RzHuEpFts1pT6BWw)是四个独立的数组,只要找到A[i] + B[j] + C[k] + D[l] = 0就可以,不用考虑有重复的四个元素相加等于0的情况,所以相对于本题还是简单了不少! 我们来回顾一下,几道题目使用了双指针法。 双指针法将时间复杂度O(n^2)的解法优化为 O(n)的解法。也就是降一个数量级,题目如下: -* [0027.移除元素](https://mp.weixin.qq.com/s/wj0T-Xs88_FHJFwayElQlA) -* [15.三数之和](https://mp.weixin.qq.com/s/r5cgZFu0tv4grBAexdcd8A) + +* [27.移除元素](https://mp.weixin.qq.com/s/RMkulE4NIb6XsSX83ra-Ww) +* [15.三数之和](https://mp.weixin.qq.com/s/QfTNEByq1YlNSXRKEumwHg) * [18.四数之和](https://mp.weixin.qq.com/s/nQrcco8AZJV1pAOVjeIU_g) -双指针来记录前后指针实现链表反转: -* [206.反转链表](https://mp.weixin.qq.com/s/pnvVP-0ZM7epB8y3w_Njwg) +操作链表: -使用双指针来确定有环: +* [206.反转链表](https://mp.weixin.qq.com/s/ckEvIVGcNLfrz6OLOMoT0A) +* [19.删除链表的倒数第N个节点](https://mp.weixin.qq.com/s/gxu65X1343xW_sBrkTz0Eg) +* [面试题 02.07. 链表相交](https://mp.weixin.qq.com/s/BhfFfaGvt9Zs7UmH4YehZw) +* [142题.环形链表II](https://mp.weixin.qq.com/s/gt_VH3hQTqNxyWcl1ECSbQ) -* [142题.环形链表II](https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA) - -双指针法在数组和链表中还有很多应用,后面还会介绍到。 +双指针法在字符串题目中还有很多应用,后面还会介绍到。 C++代码 diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md index b8ebcaa1..6f257d5e 100644 --- a/problems/0028.实现strStr.md +++ b/problems/0028.实现strStr.md @@ -61,11 +61,6 @@ KMP的经典思想就是:**当出现字符串不匹配时,可以记录一部 读完本篇可以顺便,把leetcode上28.实现strStr()题目做了。 -如果文字实在看不下去,就看我在B站上的视频吧,如下: - -* [帮你把KMP算法学个通透!(理论篇)B站](https://www.bilibili.com/video/BV1PD4y1o7nd/) -* [帮你把KMP算法学个通透!(求next数组代码篇)B站](https://www.bilibili.com/video/BV1M5411j7Xx/) - # 什么是KMP diff --git a/problems/0454.四数相加II.md b/problems/0454.四数相加II.md index 2c648f58..939ed20d 100644 --- a/problems/0454.四数相加II.md +++ b/problems/0454.四数相加II.md @@ -11,6 +11,7 @@ # 第454题.四数相加II + https://leetcode-cn.com/problems/4sum-ii/ 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。 @@ -24,10 +25,8 @@ A = [ 1, 2] B = [-2,-1] C = [-1, 2] D = [ 0, 2] - 输出: 2 - **解释:** 两个元组如下: 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 diff --git a/problems/二叉树的理论基础.md b/problems/二叉树的理论基础.md deleted file mode 100644 index 4b52e511..00000000 --- a/problems/二叉树的理论基础.md +++ /dev/null @@ -1,202 +0,0 @@ -

- - - - -

-

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

- -## 二叉树理论基础 - -我们要开启新的征程了,大家跟上! - -说道二叉树,大家对于二叉树其实都很熟悉了,本文呢我也不想教科书式的把二叉树的基础内容再啰嗦一遍,所以一下我讲的都是一些比较重点的内容。 - -相信只要耐心看完,都会有所收获。 - -## 二叉树的种类 - -在我们解题过程中二叉树有两种主要的形式:满二叉树和完全二叉树。 - -### 满二叉树 - -满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。 - -如图所示: - - - -这棵二叉树为满二叉树,也可以说深度为 k,有 $(2^k)-1$ 个节点的二叉树。 - - -### 完全二叉树 - -什么是完全二叉树? - -完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1 ~ $2^{(h-1)}$  个节点。 - -**大家要自己看完全二叉树的定义,很多同学对完全二叉树其实不是真正的懂了。** - -我来举一个典型的例子如题: - - - -相信不少同学最后一个二叉树是不是完全二叉树都中招了。 - -**之前我们刚刚讲过优先级队列其实是一个堆,堆就是一棵完全二叉树,同时保证父子节点的顺序关系。** - -### 二叉搜索树 - -前面介绍的书,都没有数值的,而二叉搜索树是有数值的了,**二叉搜索树是一个有序树**。 - - -* 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; -* 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; -* 它的左、右子树也分别为二叉排序树 - -下面这两棵树都是搜索树 - - - -### 平衡二叉搜索树 - -平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。 - -如图: - - - -最后一棵 不是平衡二叉树,因为它的左右两个子树的高度差的绝对值超过了1。 - -**C++中map、set、multimap,multiset的底层实现都是平衡二叉搜索树**,所以map、set的增删操作时间时间复杂度是logn,注意我这里没有说unordered_map、unordered_set,unordered_map、unordered_map底层实现是哈希表。 - -**所以大家使用自己熟悉的编程语言写算法,一定要知道常用的容器底层都是如何实现的,最基本的就是map、set等等,否则自己写的代码,自己对其性能分析都分析不清楚!** - - -## 二叉树的存储方式 - -**二叉树可以链式存储,也可以顺序存储。** - -那么链式存储方式就用指针, 顺序存储的方式就是用数组。 - -顾名思义就是顺序存储的元素在内存是连续分布的,而链式存储则是通过指针把分布在散落在各个地址的节点串联一起。 - -链式存储如图: - - - -链式存储是大家很熟悉的一种方式,那么我们来看看如何顺序存储呢? - -其实就是用数组来存储二叉树,顺序存储的方式如图: - - - -用数组来存储二叉树如何遍历的呢? - -**如果父节点的数组下标是 i,那么它的左孩子就是 i * 2 + 1,右孩子就是 i * 2 + 2。** - -但是用链式表示的二叉树,更有利于我们理解,所以一般我们都是用链式存储二叉树。 - -**所以大家要了解,用数组依然可以表示二叉树。** - -## 二叉树的遍历方式 - -关于二叉树的遍历方式,要知道二叉树遍历的基本方式都有哪些。 - -一些同学用做了很多二叉树的题目了,可能知道前序、中序、后序遍历,可能知道层序遍历,但是却没有框架。 - -我这里把二叉树的几种遍历方式列出来,大家就可以一一串起来了。 - -二叉树主要有两种遍历方式: -1. 深度优先遍历:先往深走,遇到叶子节点再往回走。 -2. 广度优先遍历:一层一层的去遍历。 - -**这两种遍历是图论中最基本的两种遍历方式**,后面在介绍图论的时候 还会介绍到。 - -那么从深度优先遍历和广度优先遍历进一步拓展,才有如下遍历方式: - -* 深度优先遍历 - * 前序遍历(递归法,迭代法) - * 中序遍历(递归法,迭代法) - * 后序遍历(递归法,迭代法) -* 广度优先遍历 - * 层次遍历(迭代法) - - -在深度优先遍历中:有三个顺序,前序、中序、后序遍历, 有同学总分不清这三个顺序,经常搞混,我这里教大家一个技巧。 - -**这里前、中、后,其实指的就是中间节点的遍历顺序**,只要大家记住 前序、中序、后序指的就是中间节点的位置就可以了。 - -看如下中间节点的顺序,就可以发现,中间节点的顺序就是所谓的遍历方式 - -* 前序遍历:中左右 -* 中序遍历:左中右 -* 后序遍历:左右中 - -大家可以对着如下图,看看自己理解的前后中序有没有问题。 - - - -最后再说一说二叉树中深度优先和广度优先遍历实现方式,我们做二叉树相关题目,经常会使用递归的方式来实现深度优先遍历,也就是实现前序、中序、后序遍历,使用递归是比较方便的。 - -**之前我们讲栈与队列的时候,就说过栈其实就是递归的一种是实现结构**,也就说前序、中序、后序遍历的逻辑其实都是可以借助栈使用非递归的方式来实现的。 - -而广度优先遍历的实现一般使用队列来实现,这也是队列先进先出的特点所决定的,因为需要先进先出的结构,才能一层一层的来遍历二叉树。 - -**这里其实我们又了解了栈与队列的一个应用场景了。** - -具体的实现我们后面都会讲的,这里大家先要清楚这些理论基础。 - -## 二叉树的定义 - -刚刚我们说过了二叉树有两种存储方式顺序存储,和链式存储,顺序存储就是用数组来存,这个定义没啥可说的,我们来看看链式存储的二叉树节点的定义方式。 - - -C++代码如下: - -``` -struct TreeNode { - int val; - TreeNode *left; - TreeNode *right; - TreeNode(int x) : val(x), left(NULL), right(NULL) {} -}; -``` - -大家会发现二叉树的定义 和链表是差不多的,相对于链表 ,二叉树的节点里多了一个指针, 有两个指针,指向左右孩子. - -这里要提醒大家要注意二叉树节点定义的书写方式。 - -**在现场面试的时候 面试官可能要求手写代码,所以数据结构的定义以及简单逻辑的代码一定要锻炼白纸写出来。** - -因为我们在刷leetcode的时候,节点的定义默认都定义好了,真到面试的时候,需要自己写节点定义的时候,有时候会一脸懵逼! - -## 总结 - -二叉树是一种基础数据结构,在算法面试中都是常客,也是众多数据结构的基石。 - -本篇我们介绍了二叉树的种类、存储方式、遍历方式以及定义,比较全面的介绍了二叉树各个方面的重点,帮助大家扫一遍基础。 - -**说道二叉树,就不得不说递归,很多同学对递归都是又熟悉又陌生,递归的代码一般很简短,但每次都是一看就会,一写就废。** - - - -## 其他语言版本 - - -Java: - - -Python: - - -Go: - - - - ------------------------ -* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站视频:[代码随想录](https://space.bilibili.com/525438321) -* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) -
diff --git a/problems/背包理论基础01背包-一维DP.md b/problems/背包理论基础01背包-一维DP.md deleted file mode 100644 index 47f489ea..00000000 --- a/problems/背包理论基础01背包-一维DP.md +++ /dev/null @@ -1,231 +0,0 @@ -

- - - - -

-

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

- -# 动态规划:关于01背包问题,你该了解这些!(滚动数组) - -昨天[动态规划:关于01背包问题,你该了解这些!](https://mp.weixin.qq.com/s/FwIiPPmR18_AJO5eiidT6w)中是用二维dp数组来讲解01背包。 - -今天我们就来说一说滚动数组,其实在前面的题目中我们已经用到过滚动数组了,就是把二维dp降为一维dp,一些录友当时还表示比较困惑。 - -那么我们通过01背包,来彻底讲一讲滚动数组! - -接下来还是用如下这个例子来进行讲解 - -背包最大重量为4。 - -物品为: - -| | 重量 | 价值 | -| --- | --- | --- | -| 物品0 | 1 | 15 | -| 物品1 | 3 | 20 | -| 物品2 | 4 | 30 | - -问背包能背的物品最大价值是多少? - -## 一维dp数组(滚动数组) - -对于背包问题其实状态都是可以压缩的。 - -在使用二维数组的时候,递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); - -**其实可以发现如果把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][j]里的i和j表达的是什么了,i是物品,j是背包容量。 - -**dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少**。 - -一定要时刻记住这里i和j的含义,要不然很容易看懵了。 - -动规五部曲分析如下: - -1. 确定dp数组的定义 - -在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。 - -2. 一维dp数组的递推公式 - -dp[j]为 容量为j的背包所背的最大价值,那么如何推导dp[j]呢? - -dp[j]可以通过dp[j - weight[j]]推导出来,dp[j - weight[i]]表示容量为j - weight[i]的背包所背的最大价值。 - -dp[j - weight[i]] + value[i] 表示 容量为 j - 物品i重量 的背包 加上 物品i的价值。(也就是容量为j的背包,放入物品i了之后的价值即:dp[j]) - -此时dp[j]有两个选择,一个是取自己dp[j],一个是取dp[j - weight[i]] + value[i],指定是取最大的,毕竟是求最大价值, - -所以递归公式为: - -``` -dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); -``` - -可以看出相对于二维dp数组的写法,就是把dp[i][j]中i的维度去掉了。 - -3. 一维dp数组如何初始化 - -**关于初始化,一定要和dp数组的定义吻合,否则到递推公式的时候就会越来越乱**。 - -dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j],那么dp[0]就应该是0,因为背包容量为0所背的物品的最大价值就是0。 - -那么dp数组除了下标0的位置,初始为0,其他下标应该初始化多少呢? - -看一下递归公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); - -dp数组在推导的时候一定是取价值最大的数,如果题目给的价值都是正整数那么非0下标都初始化为0就可以了,如果题目给的价值有负数,那么非0下标就要初始化为负无穷。 - -**这样才能让dp数组在递归公式的过程中取的最大的价值,而不是被初始值覆盖了**。 - -那么我假设物品价值都是大于0的,所以dp数组初始化的时候,都初始为0就可以了。 - -4. 一维dp数组遍历顺序 - -代码如下: - -``` -for(int i = 0; i < weight.size(); i++) { // 遍历物品 - for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量 - dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); - - } -} -``` - -**这里大家发现和二维dp的写法中,遍历背包的顺序是不一样的!** - -二维dp遍历的时候,背包容量是从小到大,而一维dp遍历的时候,背包是从大到小。 - -为什么呢? - -**倒叙遍历是为了保证物品i只被放入一次!**,在[动态规划:关于01背包问题,你该了解这些!](https://mp.weixin.qq.com/s/FwIiPPmR18_AJO5eiidT6w)中讲解二维dp数组初始化dp[0][j]时候已经讲解到过一次。 - -举一个例子:物品0的重量weight[0] = 1,价值value[0] = 15 - -如果正序遍历 - -dp[1] = dp[1 - weight[0]] + value[0] = 15 - -dp[2] = dp[2 - weight[0]] + value[0] = 30 - -此时dp[2]就已经是30了,意味着物品0,被放入了两次,所以不能正序遍历。 - -为什么倒叙遍历,就可以保证物品只放入一次呢? - -倒叙就是先算dp[2] - -dp[2] = dp[2 - weight[0]] + value[0] = 15 (dp数组已经都初始化为0) - -dp[1] = dp[1 - weight[0]] + value[0] = 15 - -所以从后往前循环,每次取得状态不会和之前取得状态重合,这样每种物品就只取一次了。 - -**那么问题又来了,为什么二维dp数组历的时候不用倒叙呢?** - -因为对于二维dp,dp[i][j]都是通过上一层即dp[i - 1][j]计算而来,本层的dp[i][j]并不会被覆盖! - -(如何这里读不懂,大家就要动手试一试了,空想还是不靠谱的,实践出真知!) - -**再来看看两个嵌套for循环的顺序,代码中是先遍历物品嵌套遍历背包容量,那可不可以先遍历背包容量嵌套遍历物品呢?** - -不可以! - -因为一维dp的写法,背包容量一定是要倒序遍历(原因上面已经讲了),如果遍历背包容量放在上一层,那么每个dp[j]就只会放入一个物品,即:背包里只放入了一个物品。 - -(这里如果读不懂,就在回想一下dp[j]的定义,或者就把两个for循环顺序颠倒一下试试!) - -**所以一维dp数组的背包在遍历顺序上和二维其实是有很大差异的!**,这一点大家一定要注意。 - -5. 举例推导dp数组 - -一维dp,分别用物品0,物品1,物品2 来遍历背包,最终得到结果如下: - -![动态规划-背包问题9](https://img-blog.csdnimg.cn/20210110103614769.png) - - - -## 一维dp01背包完整C++测试代码 - -``` -void test_1_wei_bag_problem() { - vector weight = {1, 3, 4}; - vector value = {15, 20, 30}; - int bagWeight = 4; - - // 初始化 - vector dp(bagWeight + 1, 0); - for(int i = 0; i < weight.size(); i++) { // 遍历物品 - for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量 - dp[j] = max(dp[j], dp[j - weight[i]] + value[i]); - } - } - cout << dp[bagWeight] << endl; -} - -int main() { - test_1_wei_bag_problem(); -} - -``` - -可以看出,一维dp 的01背包,要比二维简洁的多! 初始化 和 遍历顺序相对简单了。 - -**所以我倾向于使用一维dp数组的写法,比较直观简洁,而且空间复杂度还降了一个数量级!** - -**在后面背包问题的讲解中,我都直接使用一维dp数组来进行推导**。 - -## 总结 - -以上的讲解可以开发一道面试题目(毕竟力扣上没原题)。 - -就是本文中的题目,要求先实现一个纯二维的01背包,如果写出来了,然后再问为什么两个for循环的嵌套顺序这么写?反过来写行不行?再讲一讲初始化的逻辑。 - -然后要求实现一个一维数组的01背包,最后再问,一维数组的01背包,两个for循环的顺序反过来写行不行?为什么? - -注意以上问题都是在候选人把代码写出来的情况下才问的。 - -就是纯01背包的题目,都不用考01背包应用类的题目就可以看出候选人对算法的理解程度了。 - -**相信大家读完这篇文章,应该对以上问题都有了答案!** - -此时01背包理论基础就讲完了,我用了两篇文章把01背包的dp数组定义、递推公式、初始化、遍历顺序从二维数组到一维数组统统深度剖析了一遍,没有放过任何难点。 - -大家可以发现其实信息量还是挺大的。 - -如果把[动态规划:关于01背包问题,你该了解这些!](https://mp.weixin.qq.com/s/FwIiPPmR18_AJO5eiidT6w)和本篇的内容都理解了,后面我们在做01背包的题目,就会发现非常简单了。 - -不用再凭感觉或者记忆去写背包,而是有自己的思考,了解其本质,代码的方方面面都在自己的掌控之中。 - -即使代码没有通过,也会有自己的逻辑去debug,这样就思维清晰了。 - -接下来就要开始用这两天的理论基础去做力扣上的背包面试题目了,录友们握紧扶手,我们要上高速啦! - -就酱,学算法,认准「代码随想录」,值得你推荐给身边每一位朋友同学们。 - - -## 其他语言版本 - - -Java: - - -Python: - - -Go: - - - - ------------------------ -* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站视频:[代码随想录](https://space.bilibili.com/525438321) -* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) -
diff --git a/problems/背包理论基础01背包-二维DP.md b/problems/背包理论基础01背包-二维DP.md deleted file mode 100644 index 2b334dc9..00000000 --- a/problems/背包理论基础01背包-二维DP.md +++ /dev/null @@ -1,318 +0,0 @@ -

- - - - -

-

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

- -# 背包问题理论基础 - - -这周我们正式开始讲解背包问题! - -背包问题的经典资料当然是:背包九讲。在公众号「代码随想录」后台回复:背包九讲,就可以获得背包九讲的PDF。 - -但说实话,背包九讲对于小白来说确实不太友好,看起来还是有点费劲的,而且都是伪代码理解起来也吃力。 - -对于面试的话,其实掌握01背包,和完全背包,就够用了,最多可以再来一个多重背包。 - -如果这几种背包,分不清,我这里画了一个图,如下: - -![416.分割等和子集1](https://img-blog.csdnimg.cn/20210117171307407.png) - -至于背包九讲其其他背包,面试几乎不会问,都是竞赛级别的了,leetcode上连多重背包的题目都没有,所以题库也告诉我们,01背包和完全背包就够用了。 - -而完全背包又是也是01背包稍作变化而来,即:完全背包的物品数量是无限的。 - -**所以背包问题的理论基础重中之重是01背包,一定要理解透!** - -leetcode上没有纯01背包的问题,都是01背包应用方面的题目,也就是需要转化为01背包问题。 - -**所以我先通过纯01背包问题,把01背包原理讲清楚,后续再讲解leetcode题目的时候,重点就是讲解如何转化为01背包问题了**。 - -之前可能有些录友已经可以熟练写出背包了,但只要把这个文章仔细看完,相信你会意外收获! - -## 01 背包 - -有N件物品和一个最多能被重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。**每件物品只能用一次**,求解将哪些物品装入背包里物品价值总和最大。 - -![动态规划-背包问题](https://img-blog.csdnimg.cn/20210117175428387.jpg) - -这是标准的背包问题,以至于很多同学看了这个自然就会想到背包,甚至都不知道暴力的解法应该怎么解了。 - -这样其实是没有从底向上去思考,而是习惯性想到了背包,那么暴力的解法应该是怎么样的呢? - -每一件物品其实只有两个状态,取或者不取,所以可以使用回溯法搜索出所有的情况,那么时间复杂度就是O(2^n),这里的n表示物品数量。 - -**所以暴力的解法是指数级别的时间复杂度。进而才需要动态规划的解法来进行优化!** - -在下面的讲解中,我举一个例子: - -背包最大重量为4。 - -物品为: - -| | 重量 | 价值 | -| --- | --- | --- | -| 物品0 | 1 | 15 | -| 物品1 | 3 | 20 | -| 物品2 | 4 | 30 | - -问背包能背的物品最大价值是多少? - -以下讲解和图示中出现的数字都是以这个例子为例。 - -## 二维dp数组01背包 - -依然动规五部曲分析一波。 - -1. 确定dp数组以及下标的含义 - -对于背包问题,有一种写法, 是使用二维数组,即**dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少**。 - -只看这个二维数组的定义,大家一定会有点懵,看下面这个图: - -![动态规划-背包问题1](https://img-blog.csdnimg.cn/20210110103003361.png) - -**要时刻记着这个dp数组的含义,下面的一些步骤都围绕这dp数组的含义进行的**,如果哪里看懵了,就来回顾一下i代表什么,j又代表什么。 - -2. 确定递推公式 - -再回顾一下dp[i][j]的含义:从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。 - -那么可以有两个方向推出来dp[i][j], - -* 由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j] -* 由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]); - -3. dp数组如何初始化 - -**关于初始化,一定要和dp数组的定义吻合,否则到递推公式的时候就会越来越乱**。 - -首先从dp[i][j]的定义触发,如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。如图: - -![动态规划-背包问题2](https://img-blog.csdnimg.cn/2021011010304192.png) - -在看其他情况。 - -状态转移方程 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的物品的时候,各个容量的背包所能存放的最大价值。 - -代码如下: - -``` -// 倒叙遍历 -for (int j = bagWeight; j >= weight[0]; j--) { - dp[0][j] = dp[0][j - weight[0]] + value[0]; // 初始化i为0时候的情况 -} -``` - -**大家应该发现,这个初始化为什么是倒叙的遍历的?正序遍历就不行么?** - -正序遍历还真就不行,dp[0][j]表示容量为j的背包存放物品0时候的最大价值,物品0的价值就是15,因为题目中说了**每个物品只有一个!**所以dp[0][j]如果不是初始值的话,就应该都是物品0的价值,也就是15。 - -但如果一旦正序遍历了,那么物品0就会被重复加入多次! 例如代码如下: -``` -// 正序遍历 -for (int j = weight[0]; j <= bagWeight; j++) { - dp[0][j] = dp[0][j - weight[0]] + value[0]; -} -``` - -例如dp[0][1] 是15,到了dp[0][2] = dp[0][2 - 1] + 15; 也就是dp[0][2] = 30 了,那么就是物品0被重复放入了。 - -**所以一定要倒叙遍历,保证物品0只被放入一次!这一点对01背包很重要,后面在讲解滚动数组的时候,还会用到倒叙遍历来保证物品使用一次!** - - -此时dp数组初始化情况如图所示: - -![动态规划-背包问题7](https://img-blog.csdnimg.cn/20210110103109140.png) - -dp[0][j] 和 dp[i][0] 都已经初始化了,那么其他下标应该初始化多少呢? - - -dp[i][j]在推导的时候一定是取价值最大的数,如果题目给的价值都是正整数那么非0下标都初始化为0就可以了,因为0就是最小的了,不会影响取最大价值的结果。 - -如果题目给的价值有负数,那么非0下标就要初始化为负无穷了。例如:一个物品的价值是-2,但对应的位置依然初始化为0,那么取最大值的时候,就会取0而不是-2了,所以要初始化为负无穷。 - -**这样才能让dp数组在递归公式的过程中取最大的价值,而不是被初始值覆盖了**。 - -最后初始化代码如下: - -``` -// 初始化 dp -vector> dp(weight.size() + 1, vector(bagWeight + 1, 0)); -for (int j = bagWeight; j >= weight[0]; j--) { - dp[0][j] = dp[0][j - weight[0]] + value[0]; -} -``` - -**费了这么大的功夫,才把如何初始化讲清楚,相信不少同学平时初始化dp数组是凭感觉来的,但有时候感觉是不靠谱的**。 - -4. 确定遍历顺序 - - -在如下图中,可以看出,有两个遍历的维度:物品与背包重量 - -![动态规划-背包问题3](https://img-blog.csdnimg.cn/2021011010314055.png) - -那么问题来了,**先遍历 物品还是先遍历背包重量呢?** - -**其实都可以!! 但是先遍历物品更好理解**。 - -那么我先给出先遍历物品,然后遍历背包重量的代码。 - -``` -// 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数组里元素的变化 - else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); - - } -} -``` - -**先遍历背包,再遍历物品,也是可以的!(注意我这里使用的二维dp数组)** - -例如这样: - -``` -// weight数组的大小 就是物品个数 -for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量 - for(int i = 1; i < weight.size(); i++) { // 遍历物品 - 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]); - } -} -``` - -为什么也是可以的呢? - -**要理解递归的本质和递推的方向**。 - -dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 递归公式中可以看出dp[i][j]是靠dp[i-1][j]和dp[i - 1][j - weight[i]]推导出来的。 - -dp[i-1][j]和dp[i - 1][j - weight[i]] 都在dp[i][j]的左上角方向(包括正左和正上两个方向),那么先遍历物品,再遍历背包的过程如图所示: - -![动态规划-背包问题5](https://img-blog.csdnimg.cn/202101101032124.png) - -再来看看先遍历背包,再遍历物品呢,如图: - -![动态规划-背包问题6](https://img-blog.csdnimg.cn/20210110103244701.png) - -**大家可以看出,虽然两个for循环遍历的次序不同,但是dp[i][j]所需要的数据就是左上角,根本不影响dp[i][j]公式的推导!** - -但先遍历物品再遍历背包这个顺序更好理解。 - -**其实背包问题里,两个for循环的先后循序是非常有讲究的,理解遍历顺序其实比理解推导公式难多了**。 - -5. 举例推导dp数组 - -来看一下对应的dp数组的数值,如图: - -![动态规划-背包问题4](https://img-blog.csdnimg.cn/20210118163425129.jpg) - -最终结果就是dp[2][4]。 - -建议大家此时自己在纸上推导一遍,看看dp数组里每一个数值是不是这样的。 - -**做动态规划的题目,最好的过程就是自己在纸上举一个例子把对应的dp数组的数值推导一下,然后在动手写代码!** - -很多同学做dp题目,遇到各种问题,然后凭感觉东改改西改改,怎么改都不对,或者稀里糊涂就改过了。 - -主要就是自己没有动手推导一下dp数组的演变过程,如果推导明白了,代码写出来就算有问题,只要把dp数组打印出来,对比一下和自己推导的有什么差异,很快就可以发现问题了。 - - -## 完整C++测试代码 - -```C++ -void test_2_wei_bag_problem1() { - vector weight = {1, 3, 4}; - vector value = {15, 20, 30}; - int bagWeight = 4; - - // 二维数组 - vector> dp(weight.size() + 1, vector(bagWeight + 1, 0)); - - // 初始化 - for (int j = bagWeight; j >= weight[0]; j--) { - dp[0][j] = dp[0][j - weight[0]] + value[0]; - } - - // 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]; - else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); - - } - } - - cout << dp[weight.size() - 1][bagWeight] << endl; -} - -int main() { - test_2_wei_bag_problem1(); -} - -``` - - -以上遍历的过程也可以这么写: - -``` -// 遍历过程 -for(int i = 1; i < weight.size(); i++) { // 遍历物品 - for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量 - if (j - weight[i] >= 0) { - dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); - } - } -} -``` - -这么写打印出来的dp数据这就是这样: - -![动态规划-背包问题8](https://img-blog.csdnimg.cn/2021011010344372.png) - -空出来的0其实是用不上的,版本一 能把完整的dp数组打印出来,出来我用版本一来讲解。 - - -## 总结 - -讲了这么多才刚刚把二维dp的01背包讲完,**这里大家其实可以发现最简单的是推导公式了,推导公式估计看一遍就记下来了,但难就难在如何初始化和遍历顺序上**。 - -可能有的同学并没有注意到初始化 和 遍历顺序的重要性,我们后面做力扣上背包面试题目的时候,大家就会感受出来了。 - -下一篇 还是理论基础,我们再来讲一维dp数组实现的01背包(滚动数组),分析一下和二维有什么区别,在初始化和遍历顺序上又有什么差异,敬请期待! - -就酱,学算法,认准「代码随想录」,值得推荐给身边的朋友同学们,关注后都会发现相见恨晚! - - - - - -## 其他语言版本 - - -Java: - - -Python: - - -Go: - - - - ------------------------ -* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站视频:[代码随想录](https://space.bilibili.com/525438321) -* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) -
From a00f188ddb6e60fd5a7da0042fe20645da746228 Mon Sep 17 00:00:00 2001 From: youngyangyang04 <826123027@qq.com> Date: Fri, 4 Jun 2021 09:33:18 +0800 Subject: [PATCH 75/95] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=A4=B4=E9=83=A8?= =?UTF-8?q?=E5=BA=95=E9=83=A8=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...试流程和注意事项都在这里了.md | 22 ++++++++++--------- ...时了,此时的n究竟是多大?.md | 22 ++++++++++--------- .../前序/上海互联网公司总结.md | 20 +++++++++-------- ...代码模式,什么又是ACM模式?.md | 19 ++++++++-------- problems/前序/代码风格.md | 21 +++++++++--------- ...杂度,你不知道的都在这里!.md | 19 ++++++++-------- ...间复杂度,可能有几个疑问?.md | 20 +++++++++-------- ...了解自己代码的内存消耗么?.md | 22 ++++++++++--------- ...上的代码想在本地编译运行?.md | 18 ++++++++------- .../前序/北京互联网公司总结.md | 22 ++++++++++--------- .../前序/广州互联网公司总结.md | 20 +++++++++-------- .../前序/成都互联网公司总结.md | 22 ++++++++++--------- .../前序/杭州互联网公司总结.md | 22 ++++++++++--------- .../前序/深圳互联网公司总结.md | 20 +++++++++-------- problems/前序/程序员写文档工具.md | 22 ++++++++++--------- problems/前序/程序员简历.md | 17 +++++++------- ...算法的时间与空间复杂度分析.md | 20 +++++++++-------- ...一讲递归算法的时间复杂度!.md | 20 +++++++++-------- 18 files changed, 200 insertions(+), 168 deletions(-) diff --git a/problems/前序/BAT级别技术面试流程和注意事项都在这里了.md b/problems/前序/BAT级别技术面试流程和注意事项都在这里了.md index f8598d3f..fbcdf970 100644 --- a/problems/前序/BAT级别技术面试流程和注意事项都在这里了.md +++ b/problems/前序/BAT级别技术面试流程和注意事项都在这里了.md @@ -1,11 +1,12 @@ - -

- + - +

+

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

+ + 大型互联网企业一般通过几轮技术面试来考察大家的各项能力,一般流程如下: @@ -212,11 +213,12 @@ leetcode是专门针对算法练习的题库,leetcode现在也推出了中文 大家加油! ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - - +
diff --git a/problems/前序/On的算法居然超时了,此时的n究竟是多大?.md b/problems/前序/On的算法居然超时了,此时的n究竟是多大?.md index f640abad..f6218777 100644 --- a/problems/前序/On的算法居然超时了,此时的n究竟是多大?.md +++ b/problems/前序/On的算法居然超时了,此时的n究竟是多大?.md @@ -1,11 +1,12 @@ - -

- + - +

+

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

+ + 一些同学可能对计算机运行的速度还没有概念,就是感觉计算机运行速度应该会很快,那么在leetcode上做算法题目的时候为什么会超时呢? @@ -219,11 +220,12 @@ int main() { 就酱,如果感觉「代码随想录」很干货,就帮忙宣传一波吧,很多录友发现这里之后都感觉相见恨晚! ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - - +
diff --git a/problems/前序/上海互联网公司总结.md b/problems/前序/上海互联网公司总结.md index 40478cb6..386a0a93 100644 --- a/problems/前序/上海互联网公司总结.md +++ b/problems/前序/上海互联网公司总结.md @@ -1,10 +1,11 @@ -

- + - +

+

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

+ # 上海互联网公司总结 @@ -124,11 +125,12 @@ 相对于北京和上海,深圳互联网公司断层很明显,腾讯一家独大,二线三线垂直行业的公司很少,所以说深圳腾讯的员工流动性相对是较低的,因为基本没得选。 ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - - +
diff --git a/problems/前序/什么是核心代码模式,什么又是ACM模式?.md b/problems/前序/什么是核心代码模式,什么又是ACM模式?.md index 70651817..5a19a72a 100644 --- a/problems/前序/什么是核心代码模式,什么又是ACM模式?.md +++ b/problems/前序/什么是核心代码模式,什么又是ACM模式?.md @@ -1,12 +1,12 @@ -

- + - +

+

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

+ --------------------------- 现在很多企业都在牛客上进行面试,**很多录友和我反馈说搞不懂牛客上输入代码的ACM模式**。 什么是ACM输入模式呢? 就是自己构造输入数据格式,把要需要处理的容器填充好,OJ不会给你任何代码,包括include哪些函数都要自己写,最后也要自己控制返回数据的格式。 @@ -115,10 +115,11 @@ int main() { 如果大家有精力的话,也可以去POJ上去刷刷题,POJ是ACM选手首选OJ,输入模式也是ACM模式。 ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - +
diff --git a/problems/前序/代码风格.md b/problems/前序/代码风格.md index e4378b4e..a9eabd0c 100644 --- a/problems/前序/代码风格.md +++ b/problems/前序/代码风格.md @@ -1,13 +1,13 @@ - -

- + - +

+

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

+ + --------------------------- # 看了这么多代码,谈一谈代码风格! @@ -142,10 +142,11 @@ Google规范是 大括号和 控制语句保持同一行的,我个人也很认 就酱,以后我还会陆续分享,关于代码,求职,学习工作之类的内容。 ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - +
diff --git a/problems/前序/关于时间复杂度,你不知道的都在这里!.md b/problems/前序/关于时间复杂度,你不知道的都在这里!.md index 3f5bc156..4ca9eede 100644 --- a/problems/前序/关于时间复杂度,你不知道的都在这里!.md +++ b/problems/前序/关于时间复杂度,你不知道的都在这里!.md @@ -1,12 +1,12 @@ -

- + - +

+

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

+ --------------------------- Carl大胆断言:这可能是你见过对时间复杂度分析最通透的一篇文章了。 @@ -165,10 +165,11 @@ O(2 * n^2 + 10 * n + 1000) < O(3 * n^2),所以说最后省略掉常数项系 ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - +
diff --git a/problems/前序/关于空间复杂度,可能有几个疑问?.md b/problems/前序/关于空间复杂度,可能有几个疑问?.md index 63940116..0208aa91 100644 --- a/problems/前序/关于空间复杂度,可能有几个疑问?.md +++ b/problems/前序/关于空间复杂度,可能有几个疑问?.md @@ -1,11 +1,12 @@ - -

- + - +

+

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

+ + # 空间复杂度分析 @@ -68,10 +69,11 @@ for (int i = 0; i < n; i++) { 至于如何求递归的空间复杂度,我会在专门写一篇文章来介绍的,敬请期待! ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - +
diff --git a/problems/前序/刷了这么多题,你了解自己代码的内存消耗么?.md b/problems/前序/刷了这么多题,你了解自己代码的内存消耗么?.md index df555c3b..6d3b4931 100644 --- a/problems/前序/刷了这么多题,你了解自己代码的内存消耗么?.md +++ b/problems/前序/刷了这么多题,你了解自己代码的内存消耗么?.md @@ -1,12 +1,13 @@ - - -

- + - +

+

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

+ + + 理解代码的内存消耗,最关键是要知道自己所用编程语言的内存管理。 @@ -145,10 +146,11 @@ char型的数据和int型的数据挨在一起,该int数据从地址1开始, 之后也可以有意识的去学习自己所用的编程语言是如何管理内存的,这些也是程序员的内功。 ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - +
diff --git a/problems/前序/力扣上的代码想在本地编译运行?.md b/problems/前序/力扣上的代码想在本地编译运行?.md index 04e19021..f4a9b0f3 100644 --- a/problems/前序/力扣上的代码想在本地编译运行?.md +++ b/problems/前序/力扣上的代码想在本地编译运行?.md @@ -1,10 +1,11 @@ -

- + - +

+

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

+ 很多录友都问过我一个问题,就是力扣上的代码如何在本地编译运行? @@ -62,10 +63,11 @@ int main() { ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - +
diff --git a/problems/前序/北京互联网公司总结.md b/problems/前序/北京互联网公司总结.md index f1c9ad9a..4dcaa691 100644 --- a/problems/前序/北京互联网公司总结.md +++ b/problems/前序/北京互联网公司总结.md @@ -1,11 +1,12 @@ - -

- + - +

+

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

+ + # 北京互联网公司总结 @@ -110,11 +111,12 @@ 就酱,我也会陆续整理其他城市的互联网公司,希望对大家有所帮助。 ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - - +
diff --git a/problems/前序/广州互联网公司总结.md b/problems/前序/广州互联网公司总结.md index 47b7bf77..e9b2af00 100644 --- a/problems/前序/广州互联网公司总结.md +++ b/problems/前序/广州互联网公司总结.md @@ -1,10 +1,11 @@ -

- + - +

+

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

+ # 广州互联网公司总结 @@ -73,11 +74,12 @@ ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - - +
diff --git a/problems/前序/成都互联网公司总结.md b/problems/前序/成都互联网公司总结.md index 2f32849e..2435ccb2 100644 --- a/problems/前序/成都互联网公司总结.md +++ b/problems/前序/成都互联网公司总结.md @@ -1,11 +1,12 @@ - -

- + - +

+

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

+ + # 成都互联网公司总结 @@ -71,11 +72,12 @@ ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - - +
diff --git a/problems/前序/杭州互联网公司总结.md b/problems/前序/杭州互联网公司总结.md index 23cd4183..e2691469 100644 --- a/problems/前序/杭州互联网公司总结.md +++ b/problems/前序/杭州互联网公司总结.md @@ -1,11 +1,12 @@ - -

- + - +

+

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

+ + # 杭州互联网公司总结 @@ -82,11 +83,12 @@ ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - - +
diff --git a/problems/前序/深圳互联网公司总结.md b/problems/前序/深圳互联网公司总结.md index b7d15686..4b68dad6 100644 --- a/problems/前序/深圳互联网公司总结.md +++ b/problems/前序/深圳互联网公司总结.md @@ -1,10 +1,11 @@ -

- + - +

+

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

+ # 深圳互联网公司总结 @@ -76,11 +77,12 @@ * 广发证券,深交所 * 珍爱网(珍爱网是国内知名的婚恋服务网站之一) ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - - +
diff --git a/problems/前序/程序员写文档工具.md b/problems/前序/程序员写文档工具.md index 34f2f777..5530e30f 100644 --- a/problems/前序/程序员写文档工具.md +++ b/problems/前序/程序员写文档工具.md @@ -1,12 +1,13 @@ - - -

- + - +

+

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

+ + + # 程序员应该用什么用具来写文档? @@ -132,10 +133,11 @@ Markdown支持部分html,例如这样 如果还没有掌握markdown的你还在等啥,赶紧使用markdown记录起来吧 ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - +
diff --git a/problems/前序/程序员简历.md b/problems/前序/程序员简历.md index af52df8e..f9a226df 100644 --- a/problems/前序/程序员简历.md +++ b/problems/前序/程序员简历.md @@ -1,12 +1,12 @@ -

- + - +

+

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

+ --------------------------- # 程序员的简历应该这么写!!(附简历模板) @@ -131,9 +131,10 @@ Carl校招社招都拿过大厂的offer,同时也看过很多应聘者的简 就酱,「代码随想录」就是这么干货,Carl多年积累的简历技巧都毫不保留的写出来了,如果感觉对你有帮助,就宣传一波「代码随想录」吧,值得大家的关注! ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - +
diff --git a/problems/前序/递归算法的时间与空间复杂度分析.md b/problems/前序/递归算法的时间与空间复杂度分析.md index c8ef4723..f1501e8a 100644 --- a/problems/前序/递归算法的时间与空间复杂度分析.md +++ b/problems/前序/递归算法的时间与空间复杂度分析.md @@ -1,10 +1,11 @@ -

- + - +

+

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

+ # 递归算法的时间与空间复杂度分析! @@ -263,11 +264,12 @@ int binary_search( int arr[], int l, int r, int x) { ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - - +
diff --git a/problems/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.md b/problems/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.md index cb6aa604..16ba8361 100644 --- a/problems/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.md +++ b/problems/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.md @@ -1,11 +1,12 @@ - -

- + - +

+

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

+ + # 通过一道面试题目,讲一讲递归算法的时间复杂度! @@ -149,10 +150,11 @@ int function3(int x, int n) { 如果认真读完本篇,相信大家对递归算法的有一个新的认识的,同一道题目,同样是递归,效率可是不一样的! ------------------------- -* 微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) -* B站:[代码随想录](https://space.bilibili.com/525438321) + + +----------------------- +* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) +* B站视频:[代码随想录](https://space.bilibili.com/525438321) * 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) - - +
From e5ee38f826a9d230e1f474f1e4130fa564ac7674 Mon Sep 17 00:00:00 2001 From: SkyLazy <627770537@qq.com> Date: Fri, 4 Jun 2021 14:39:03 +0800 Subject: [PATCH 76/95] =?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 java 版本长度为1的时候也要考虑k的奇偶性才能直接return吧 --- problems/1005.K次取反后最大化的数组和.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/1005.K次取反后最大化的数组和.md b/problems/1005.K次取反后最大化的数组和.md index e57e26ad..5539aff8 100644 --- a/problems/1005.K次取反后最大化的数组和.md +++ b/problems/1005.K次取反后最大化的数组和.md @@ -102,7 +102,7 @@ Java: ```java class Solution { public int largestSumAfterKNegations(int[] A, int K) { - if (A.length == 1) return A[0]; + if (A.length == 1) return k % 2 == 0 ? A[0] : -A[0]; Arrays.sort(A); int sum = 0; int idx = 0; From b69ca00d2fc9a024145f6bc6d88de8ea88e3f3ab Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Fri, 4 Jun 2021 01:45:10 -0700 Subject: [PATCH 77/95] =?UTF-8?q?Update=200226.=E7=BF=BB=E8=BD=AC=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0226.翻转二叉树.md | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/problems/0226.翻转二叉树.md b/problems/0226.翻转二叉树.md index f48eefd2..2b628ec4 100644 --- a/problems/0226.翻转二叉树.md +++ b/problems/0226.翻转二叉树.md @@ -230,6 +230,56 @@ class Solution { Python: +> 递归法:前序遍历 +```python +class Solution: + def invertTree(self, root: TreeNode) -> TreeNode: + if not root: + return None + root.left, root.right = root.right, root.left #中 + self.invertTree(root.left) #左 + self.invertTree(root.right) #右 + return root +``` + +> 迭代法:深度优先遍历(前序遍历) +```python +class Solution: + def invertTree(self, root: TreeNode) -> TreeNode: + if not root: + return root + st = [] + st.append(root) + while st: + node = st.pop() + node.left, node.right = node.right, node.left #中 + if node.right: + st.append(node.right) #右 + if node.left: + st.append(node.left) #左 + return root +``` + +> 迭代法:广度优先遍历(层序遍历) +```python +import collections +class Solution: + def invertTree(self, root: TreeNode) -> TreeNode: + queue = collections.deque() #使用deque() + if root: + queue.append(root) + while queue: + size = len(queue) + for i in range(size): + node = queue.popleft() + node.left, node.right = node.right, node.left #节点处理 + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) + return root +``` + Go: ```Go func invertTree(root *TreeNode) *TreeNode { From b655cb2730d1bc60f02d72cfd2918cb4d0789d3f Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Fri, 4 Jun 2021 02:10:07 -0700 Subject: [PATCH 78/95] =?UTF-8?q?Update=200101.=E5=AF=B9=E7=A7=B0=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0101.对称二叉树.md | 72 ++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/problems/0101.对称二叉树.md b/problems/0101.对称二叉树.md index d8797d30..3dba1648 100644 --- a/problems/0101.对称二叉树.md +++ b/problems/0101.对称二叉树.md @@ -360,6 +360,78 @@ Java: Python: +> 递归法 +```python +class Solution: + def isSymmetric(self, root: TreeNode) -> bool: + if not root: + return True + return self.compare(root.left, root.right) + + def compare(self, left, right): + #首先排除空节点的情况 + if left == None and right != None: return False + elif left != None and right == None: return False + elif left == None and right == None: return True + #排除了空节点,再排除数值不相同的情况 + elif left.val != right.val: return False + + #此时就是:左右节点都不为空,且数值相同的情况 + #此时才做递归,做下一层的判断 + outside = self.compare(left.left, right.right) #左子树:左、 右子树:右 + inside = self.compare(left.right, right.left) #左子树:右、 右子树:左 + isSame = outside and inside #左子树:中、 右子树:中 (逻辑处理) + return isSame +``` + +> 迭代法: 使用队列 +```python +import collections +class Solution: + def isSymmetric(self, root: TreeNode) -> bool: + if not root: + return True + queue = collections.deque() + queue.append(root.left) #将左子树头结点加入队列 + queue.append(root.right) #将右子树头结点加入队列 + while queue: #接下来就要判断这这两个树是否相互翻转 + leftNode = queue.popleft() + rightNode = queue.popleft() + if not leftNode and not rightNode: #左节点为空、右节点为空,此时说明是对称的 + continue + + #左右一个节点不为空,或者都不为空但数值不相同,返回false + if not leftNode or not rightNode or leftNode.val != rightNode.val: + return False + queue.append(leftNode.left) #加入左节点左孩子 + queue.append(rightNode.right) #加入右节点右孩子 + queue.append(leftNode.right) #加入左节点右孩子 + queue.append(rightNode.left) #加入右节点左孩子 + return True +``` + +> 迭代法:使用栈 +```python +class Solution: + def isSymmetric(self, root: TreeNode) -> bool: + if not root: + return True + st = [] #这里改成了栈 + st.append(root.left) + st.append(root.right) + while st: + leftNode = st.pop() + rightNode = st.pop() + if not leftNode and not rightNode: + continue + if not leftNode or not rightNode or leftNode.val != rightNode.val: + return False + st.append(leftNode.left) + st.append(rightNode.right) + st.append(leftNode.right) + st.append(rightNode.left) + return True +``` Go: From c44a3165c4333530eac041aa1ede69088ed6462c Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Fri, 4 Jun 2021 03:08:41 -0700 Subject: [PATCH 79/95] =?UTF-8?q?Update=200104.=E4=BA=8C=E5=8F=89=E6=A0=91?= =?UTF-8?q?=E7=9A=84=E6=9C=80=E5=A4=A7=E6=B7=B1=E5=BA=A6.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0104.二叉树的最大深度.md | 105 ++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/problems/0104.二叉树的最大深度.md b/problems/0104.二叉树的最大深度.md index 756afb68..4bf2b261 100644 --- a/problems/0104.二叉树的最大深度.md +++ b/problems/0104.二叉树的最大深度.md @@ -281,6 +281,111 @@ class Solution { Python: +104.二叉树的最大深度 +> 递归法: +```python +class Solution: + def maxDepth(self, root: TreeNode) -> int: + return self.getDepth(root) + + def getDepth(self, node): + if not node: + return 0 + leftDepth = self.getDepth(node.left) #左 + rightDepth = self.getDepth(node.right) #右 + depth = 1 + max(leftDepth, rightDepth) #中 + return depth +``` +> 递归法;精简代码 +```python +class Solution: + def maxDepth(self, root: TreeNode) -> int: + if not root: + return 0 + return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right)) +``` + +> 迭代法: +```python +import collections +class Solution: + def maxDepth(self, root: TreeNode) -> int: + if not root: + return 0 + depth = 0 #记录深度 + queue = collections.deque() + queue.append(root) + while queue: + size = len(queue) + depth += 1 + for i in range(size): + node = queue.popleft() + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) + return depth +``` + +559.N叉树的最大深度 +> 递归法: +```python +class Solution: + def maxDepth(self, root: 'Node') -> int: + if not root: + return 0 + depth = 0 + for i in range(len(root.children)): + depth = max(depth, self.maxDepth(root.children[i])) + return depth + 1 +``` + +> 迭代法: +```python +import collections +class Solution: + def maxDepth(self, root: 'Node') -> int: + queue = collections.deque() + if root: + queue.append(root) + depth = 0 #记录深度 + while queue: + size = len(queue) + depth += 1 + for i in range(size): + node = queue.popleft() + for j in range(len(node.children)): + if node.children[j]: + queue.append(node.children[j]) + return depth +``` + +> 使用栈来模拟后序遍历依然可以 +```python +class Solution: + def maxDepth(self, root: 'Node') -> int: + st = [] + if root: + st.append(root) + depth = 0 + result = 0 + while st: + node = st.pop() + if node != None: + st.append(node) #中 + st.append(None) + depth += 1 + for i in range(len(node.children)): #处理孩子 + if node.children[i]: + st.append(node.children[i]) + + else: + node = st.pop() + depth -= 1 + result = max(result, depth) + return result +``` + Go: From 7bf08e13586b38a14879d1c10668b29ee3145318 Mon Sep 17 00:00:00 2001 From: borninfreedom Date: Sat, 5 Jun 2021 15:28:13 +0800 Subject: [PATCH 80/95] add python codes of binary tree's level order --- problems/0102.二叉树的层序遍历.md | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index 51bd8510..bfb78a43 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -80,6 +80,40 @@ 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: + return [] + + quene = [root] + out_list = [] + + while quene: + in_list = [] + for i in range(len(quene)): + node = quene.pop(0) + in_list.append(node.val) + if node.left: + quene.append(node.left) + if node.right: + quene.append(node.right) + + out_list.append(in_list) + + return out_list +``` + + + javascript代码: ```javascript From 0ebd5f1a812f7d58d52b440f6b2721b8c8db95d7 Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Sat, 5 Jun 2021 18:32:40 +0800 Subject: [PATCH 81/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A077.=20=E7=BB=84?= =?UTF-8?q?=E5=90=88=E4=BC=98=E5=8C=96JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0077.组合优化.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/problems/0077.组合优化.md b/problems/0077.组合优化.md index 31acf4a5..d3e82f09 100644 --- a/problems/0077.组合优化.md +++ b/problems/0077.组合优化.md @@ -147,7 +147,7 @@ public: Java: -``` +```java class Solution { List> result = new ArrayList<>(); LinkedList path = new LinkedList<>(); @@ -220,6 +220,28 @@ func backtrack(n,k,start int,track []int){ } ``` +javaScript: + +```js +var combine = function(n, k) { + const res = [], path = []; + backtracking(n, k, 1); + return res; + function backtracking (n, k, i){ + const len = path.length; + if(len === k) { + res.push(Array.from(path)); + return; + } + for(let a = i; a <= n + len - k + 1; a++) { + path.push(a); + backtracking(n, k, a + 1); + path.pop(); + } + } +}; +``` + From faaa67c993869deac75fd0c36ba59f397aad582b Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Sat, 5 Jun 2021 18:37:44 +0800 Subject: [PATCH 82/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=C2=B7216.=E7=BB=84?= =?UTF-8?q?=E5=90=88=E6=80=BB=E5=92=8CIIIJavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0216.组合总和III.md | 42 ++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md index 0aef7aec..9f75b23d 100644 --- a/problems/0216.组合总和III.md +++ b/problems/0216.组合总和III.md @@ -180,7 +180,7 @@ if (sum > targetSum) { // 剪枝操作 最后C++代码如下: -``` +```c++ class Solution { private: vector> result; // 存放结果集 @@ -262,7 +262,7 @@ class Solution { ``` Python: -```python3 +```py class Solution: def combinationSum3(self, k: int, n: int) -> List[List[int]]: res = [] #存放结果集 @@ -284,6 +284,44 @@ class Solution: Go: +javaScript: + +```js +// 等差数列 +var maxV = k => k * (9 + 10 - k) / 2; +var minV = k => k * (1 + k) / 2; +var combinationSum3 = function(k, n) { + if (k > 9 || k < 1) return []; + // if (n > maxV(k) || n < minV(k)) return []; + // if (n === maxV(k)) return [Array.from({length: k}).map((v, i) => 9 - i)]; + // if (n === minV(k)) return [Array.from({length: k}).map((v, i) => i + 1)]; + + const res = [], path = []; + backtracking(k, n, 1, 0); + return res; + function backtracking(k, n, i, sum){ + const len = path.length; + if (len > k || sum > n) return; + if (maxV(k - len) < n - sum) return; + if (minV(k - len) > n - sum) return; + + if(len === k && sum == n) { + res.push(Array.from(path)); + return; + } + + const min = Math.min(n - sum, 9 + len - k + 1); + + for(let a = i; a <= min; a++) { + path.push(a); + sum += a; + backtracking(k, n, a + 1, sum); + path.pop(); + sum -= a; + } + } +}; +``` From 7cbf0b1fff9675d507a686f4de7c08ef0c3d1394 Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Sat, 5 Jun 2021 18:40:45 +0800 Subject: [PATCH 83/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A017.=E7=94=B5=E8=AF=9D?= =?UTF-8?q?=E5=8F=B7=E7=A0=81=E7=9A=84=E5=AD=97=E6=AF=8D=E7=BB=84=E5=90=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 --- problems/0017.电话号码的字母组合.md | 33 ++++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/problems/0017.电话号码的字母组合.md b/problems/0017.电话号码的字母组合.md index fa135d8d..aefee698 100644 --- a/problems/0017.电话号码的字母组合.md +++ b/problems/0017.电话号码的字母组合.md @@ -137,7 +137,7 @@ for (int i = 0; i < letters.size(); i++) { 关键地方都讲完了,按照[关于回溯算法,你该了解这些!](https://mp.weixin.qq.com/s/gjSgJbNbd1eAA5WkA-HeWw)中的回溯法模板,不难写出如下C++代码: -``` +```c++ // 版本一 class Solution { private: @@ -183,7 +183,7 @@ public: 一些写法,是把回溯的过程放在递归函数里了,例如如下代码,我可以写成这样:(注意注释中不一样的地方) -``` +```c++ // 版本二 class Solution { private: @@ -319,7 +319,7 @@ class Solution: python3: -```python3 +```py class Solution: def letterCombinations(self, digits: str) -> List[str]: self.s = "" @@ -342,6 +342,33 @@ class Solution: Go: +javaScript: + +```js +var letterCombinations = function(digits) { + const k = digits.length; + const map = ["","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]; + if(!k) return []; + if(k === 1) return map[digits].split(""); + + const res = [], path = []; + backtracking(digits, k, 0); + return res; + + function backtracking(n, k, a) { + if(path.length === k) { + res.push(path.join("")); + return; + } + for(const v of map[n[a]]) { + path.push(v); + backtracking(n, k, a + 1); + path.pop(); + } + + } +}; +``` From d6955ebf03d534045271b74b879a937cdc32e0e0 Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Sat, 5 Jun 2021 18:42:38 +0800 Subject: [PATCH 84/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A039.=20=E7=BB=84?= =?UTF-8?q?=E5=90=88=E6=80=BB=E5=92=8CJavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0039.组合总和.md | 44 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/problems/0039.组合总和.md b/problems/0039.组合总和.md index e1023ec9..e3e4a117 100644 --- a/problems/0039.组合总和.md +++ b/problems/0039.组合总和.md @@ -286,30 +286,30 @@ class Solution: ``` Go: -JavaScript +JavaScript: + ```js -var strStr = function (haystack, needle) { - if (needle === '') { - return 0; - } - - let hayslen = haystack.length; - let needlen = needle.length; - - if (haystack === '' || hayslen < needlen) { - return -1; - } - - for (let i = 0; i <= hayslen - needlen; i++) { - if (haystack[i] === needle[0]) { - if (haystack.substr(i, needlen) === needle) { - return i; - } +var combinationSum = function(candidates, target) { + const res = [], path = []; + candidates.sort(); // 排序 + backtracking(0, 0); + return res; + function backtracking(j, sum) { + if (sum > target) return; + if (sum === target) { + res.push(Array.from(path)); + return; + } + for(let i = j; i < candidates.length; i++ ) { + const n = candidates[i]; + if(n > target - sum) continue; + path.push(n); + sum += n; + backtracking(i, sum); + path.pop(); + sum -= n; + } } - if (i === hayslen - needlen) { - return -1; - } - } }; ``` From ece55fe7efe84e4a76e1fd35d3046dd1aa67f2b5 Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Sat, 5 Jun 2021 18:44:08 +0800 Subject: [PATCH 85/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A040.=E7=BB=84=E5=90=88?= =?UTF-8?q?=E6=80=BB=E5=92=8CIIJavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0040.组合总和II.md | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/problems/0040.组合总和II.md b/problems/0040.组合总和II.md index 4d2996f5..a462b524 100644 --- a/problems/0040.组合总和II.md +++ b/problems/0040.组合总和II.md @@ -293,7 +293,7 @@ class Solution { } ``` Python: -```python3 +```py class Solution: def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: res = [] @@ -314,7 +314,39 @@ class Solution: ``` Go: +javaScript: +```js +/** + * @param {number[]} candidates + * @param {number} target + * @return {number[][]} + */ +var combinationSum2 = function(candidates, target) { + const res = []; path = [], len = candidates.length; + candidates.sort(); + backtracking(0, 0); + return res; + function backtracking(sum, i) { + if (sum > target) return; + if (sum === target) { + res.push(Array.from(path)); + return; + } + let f = -1; + for(let j = i; j < len; j++) { + const n = candidates[j]; + if(n > target - sum || n === f) continue; + path.push(n); + sum += n; + f = n; + backtracking(sum, j + 1); + path.pop(); + sum -= n; + } + } +}; +``` ----------------------- From b6b04cc035fa5b82d1a40cb9994f7cdb463bc466 Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Sat, 5 Jun 2021 18:45:22 +0800 Subject: [PATCH 86/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A0131.=E5=88=86=E5=89=B2?= =?UTF-8?q?=E5=9B=9E=E6=96=87=E4=B8=B2JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0131.分割回文串.md | 33 +++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md index c722af37..9d23fd13 100644 --- a/problems/0131.分割回文串.md +++ b/problems/0131.分割回文串.md @@ -292,7 +292,7 @@ class Solution { ``` Python: -```python3 +```py class Solution: def partition(self, s: str) -> List[List[str]]: res = [] @@ -313,7 +313,38 @@ class Solution: Go: +javaScript: +```js +/** + * @param {string} s + * @return {string[][]} + */ +const isPalindrome = (s, l, r) => { + for (let i = l, j = r; i < j; i++, j--) { + if(s[i] !== s[j]) return false; + } + return true; +} + +var partition = function(s) { + const res = [], path = [], len = s.length; + backtracking(0); + return res; + function backtracking(i) { + if(i >= len) { + res.push(Array.from(path)); + return; + } + for(let j = i; j < len; j++) { + if(!isPalindrome(s, i, j)) continue; + path.push(s.substr(i, j - i + 1)); + backtracking(j + 1); + path.pop(); + } + } +}; +``` ----------------------- From 533964af4b31bf1d08f45e626f562616ae12ca8b Mon Sep 17 00:00:00 2001 From: "qingyi.liu" Date: Sat, 5 Jun 2021 18:46:22 +0800 Subject: [PATCH 87/95] =?UTF-8?q?=E6=B7=BB=E5=8A=A093.=E5=A4=8D=E5=8E=9FIP?= =?UTF-8?q?=E5=9C=B0=E5=9D=80JavaScript=C2=B7=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0093.复原IP地址.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/problems/0093.复原IP地址.md b/problems/0093.复原IP地址.md index 3c8e5d9d..a8b9a215 100644 --- a/problems/0093.复原IP地址.md +++ b/problems/0093.复原IP地址.md @@ -338,6 +338,35 @@ class Solution(object): return ans``` ``` +JavaScript: + +```js +/** + * @param {string} s + * @return {string[]} + */ +var restoreIpAddresses = function(s) { + const res = [], path = []; + backtracking(0, 0) + return res; + function backtracking(i) { + const len = path.length; + if(len > 4) return; + if(len === 4 && i === s.length) { + res.push(path.join(".")); + return; + } + for(let j = i; j < s.length; j++) { + const str = s.substr(i, j - i + 1); + if(str.length > 3 || +str > 255) break; + if(str.length > 1 && str[0] === "0") break; + path.push(str); + backtracking(j + 1); + path.pop() + } + } +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From 03ff3ad0cb4359705ffc5ff08059c83c95fbda73 Mon Sep 17 00:00:00 2001 From: borninfreedom Date: Sat, 5 Jun 2021 19:07:12 +0800 Subject: [PATCH 88/95] =?UTF-8?q?=E7=BB=99=E5=85=B6=E4=BB=96=E5=87=A0?= =?UTF-8?q?=E9=81=93=E9=A2=98=E7=9B=AE=E6=B7=BB=E5=8A=A0=E4=BA=86python?= =?UTF-8?q?=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/0102.二叉树的层序遍历.md | 184 +++++++++++++++++++++- 1 file changed, 183 insertions(+), 1 deletion(-) diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md index bfb78a43..c7fdf776 100644 --- a/problems/0102.二叉树的层序遍历.md +++ b/problems/0102.二叉树的层序遍历.md @@ -99,7 +99,7 @@ class Solution: while quene: in_list = [] - for i in range(len(quene)): + for _ in range(len(quene)): node = quene.pop(0) in_list.append(node.val) if node.left: @@ -185,6 +185,43 @@ 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 levelOrderBottom(self, root: TreeNode) -> List[List[int]]: + if not root: + return [] + quene = [root] + out_list = [] + + while quene: + in_list = [] + for _ in range(len(quene)): + node = quene.pop(0) + in_list.append(node.val) + if node.left: + quene.append(node.left) + if node.right: + quene.append(node.right) + + out_list.append(in_list) + + out_list.reverse() + return out_list + +# 执行用时:36 ms, 在所有 Python3 提交中击败了92.00%的用户 +# 内存消耗:15.2 MB, 在所有 Python3 提交中击败了63.76%的用户 +``` + + + javascript代码 ```javascript @@ -246,6 +283,50 @@ 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 rightSideView(self, root: TreeNode) -> List[int]: + if not root: + return [] + + # deque来自collections模块,不在力扣平台时,需要手动写入 + # 'from collections import deque' 导入 + # deque相比list的好处是,list的pop(0)是O(n)复杂度,deque的popleft()是O(1)复杂度 + + quene = deque([root]) + out_list = [] + + while quene: + # 每次都取最后一个node就可以了 + node = quene[-1] + out_list.append(node.val) + + # 执行这个遍历的目的是获取下一层所有的node + for _ in range(len(quene)): + node = quene.popleft() + if node.left: + quene.append(node.left) + if node.right: + quene.append(node.right) + + return out_list + +# 执行用时:36 ms, 在所有 Python3 提交中击败了89.47%的用户 +# 内存消耗:14.6 MB, 在所有 Python3 提交中击败了96.65%的用户 +``` + + + + + javascript代码: ```javascript @@ -309,6 +390,46 @@ 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 averageOfLevels(self, root: TreeNode) -> List[float]: + if not root: + return [] + + quene = deque([root]) + out_list = [] + + while quene: + in_list = [] + + for _ in range(len(quene)): + node = quene.popleft() + in_list.append(node.val) + if node.left: + quene.append(node.left) + if node.right: + quene.append(node.right) + + out_list.append(in_list) + + out_list = map(lambda x: sum(x) / len(x), out_list) + + return out_list + +# 执行用时:56 ms, 在所有 Python3 提交中击败了81.48%的用户 +# 内存消耗:17 MB, 在所有 Python3 提交中击败了89.68%的用户 +``` + + + javascript代码: ```javascript @@ -385,7 +506,68 @@ public: }; ``` +python代码: + +```python +""" +# Definition for a Node. +class Node: + def __init__(self, val=None, children=None): + self.val = val + self.children = children +""" + +class Solution: + def levelOrder(self, root: 'Node') -> List[List[int]]: + if not root: + return [] + + quene = deque([root]) + out_list = [] + + while quene: + in_list = [] + + for _ in range(len(quene)): + node = quene.popleft() + in_list.append(node.val) + if node.children: + # 这个地方要用extend而不是append,我们看下面的例子: + # In [18]: alist=[] + # In [19]: alist.append([1,2,3]) + # In [20]: alist + # Out[20]: [[1, 2, 3]] + # In [21]: alist.extend([4,5,6]) + # In [22]: alist + # Out[22]: [[1, 2, 3], 4, 5, 6] + # 可以看到extend对要添加的list进行了一个解包操作 + # print(root.children),可以得到children是一个包含 + # 孩子节点地址的list,我们使用for遍历quene的时候, + # 希望quene是一个单层list,所以要用extend + # 使用extend的情况,如果print(quene),结果是 + # deque([<__main__.Node object at 0x7f60763ae0a0>]) + # deque([<__main__.Node object at 0x7f607636e6d0>, <__main__.Node object at 0x7f607636e130>, <__main__.Node object at 0x7f607636e310>]) + # deque([<__main__.Node object at 0x7f607636e880>, <__main__.Node object at 0x7f607636ef10>]) + # 可以看到是单层list + # 如果使用append,print(quene)的结果是 + # deque([<__main__.Node object at 0x7f18907530a0>]) + # deque([[<__main__.Node object at 0x7f18907136d0>, <__main__.Node object at 0x7f1890713130>, <__main__.Node object at 0x7f1890713310>]]) + # 可以看到是两层list,这样for的遍历就会报错 + + quene.extend(node.children) + + out_list.append(in_list) + + return out_list + +# 执行用时:60 ms, 在所有 Python3 提交中击败了76.99%的用户 +# 内存消耗:16.5 MB, 在所有 Python3 提交中击败了89.19%的用户 +``` + + + JavaScript代码: + ```JavaScript var levelOrder = function(root) { //每一层可能有2个以上,所以不再使用node.left node.right From 546865ce4c18c00589dad748e9f8c7eaa29ede80 Mon Sep 17 00:00:00 2001 From: LiangDazhu <42199191+LiangDazhu@users.noreply.github.com> Date: Sun, 6 Jun 2021 00:44:21 +0800 Subject: [PATCH 89/95] =?UTF-8?q?Update=200474.=E4=B8=80=E5=92=8C=E9=9B=B6?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added python version code --- problems/0474.一和零.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/problems/0474.一和零.md b/problems/0474.一和零.md index e158ca63..a098b9ef 100644 --- a/problems/0474.一和零.md +++ b/problems/0474.一和零.md @@ -190,7 +190,18 @@ class Solution { ``` Python: - +```python +class Solution: + def findMaxForm(self, strs: List[str], m: int, n: int) -> int: + dp = [[0] * (n + 1) for _ in range(m + 1)] + for str in strs: + oneNum = str.count('1') + zeroNum = str.count('0') + for i in range(m, zeroNum - 1, -1): + for j in range(n, oneNum - 1, -1): + dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1) + return dp[m][n] +``` Go: From d25bdef4a515064542c064abc073f09e29ce104c Mon Sep 17 00:00:00 2001 From: Yang Date: Sat, 5 Jun 2021 20:14:18 -0400 Subject: [PATCH 90/95] =?UTF-8?q?Update=200377.=E7=BB=84=E5=90=88=E6=80=BB?= =?UTF-8?q?=E5=92=8C=E2=85=A3.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Separate Java and Python code --- problems/0377.组合总和Ⅳ.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0377.组合总和Ⅳ.md b/problems/0377.组合总和Ⅳ.md index 6813f13c..c6dc3d42 100644 --- a/problems/0377.组合总和Ⅳ.md +++ b/problems/0377.组合总和Ⅳ.md @@ -163,7 +163,7 @@ class Solution { return dp[target]; } } - +``` Python: From ea6dcc9d8f5962e13bdd9f8034f244bfec450c42 Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Sat, 5 Jun 2021 17:33:44 -0700 Subject: [PATCH 91/95] =?UTF-8?q?Update=200222.=E5=AE=8C=E5=85=A8=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91=E7=9A=84=E8=8A=82=E7=82=B9=E4=B8=AA=E6=95=B0?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0222.完全二叉树的节点个数.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/problems/0222.完全二叉树的节点个数.md b/problems/0222.完全二叉树的节点个数.md index 2e2fed99..91e24247 100644 --- a/problems/0222.完全二叉树的节点个数.md +++ b/problems/0222.完全二叉树的节点个数.md @@ -240,6 +240,71 @@ class Solution { Python: +> 递归法: +```python +class Solution: + def countNodes(self, root: TreeNode) -> int: + return self.getNodesNum(root) + + def getNodesNum(self, cur): + if not cur: + return 0 + leftNum = self.getNodesNum(cur.left) #左 + rightNum = self.getNodesNum(cur.right) #右 + treeNum = leftNum + rightNum + 1 #中 + return treeNum +``` + +> 递归法:精简版 +```python +class Solution: + def countNodes(self, root: TreeNode) -> int: + if not root: + return 0 + return 1 + self.countNodes(root.left) + self.countNodes(root.right) +``` + +> 迭代法: +```python +import collections +class Solution: + def countNodes(self, root: TreeNode) -> int: + queue = collections.deque() + if root: + queue.append(root) + result = 0 + while queue: + size = len(queue) + for i in range(size): + node = queue.popleft() + result += 1 #记录节点数量 + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) + return result +``` + +> 完全二叉树 +```python +class Solution: + def countNodes(self, root: TreeNode) -> int: + if not root: + return 0 + left = root.left + right = root.right + leftHeight = 0 #这里初始为0是有目的的,为了下面求指数方便 + rightHeight = 0 + while left: #求左子树深度 + left = left.left + leftHeight += 1 + while right: #求右子树深度 + right = right.right + rightHeight += 1 + if leftHeight == rightHeight: + return (2 << leftHeight) - 1 #注意(2<<1) 相当于2^2,所以leftHeight初始为0 + return self.countNodes(root.left) + self.countNodes(root.right) + 1 +``` Go: From 6efc66e17597da3038966c690bb75dd4f0e61ad0 Mon Sep 17 00:00:00 2001 From: Baturu <45113401+z80160280@users.noreply.github.com> Date: Sat, 5 Jun 2021 18:13:20 -0700 Subject: [PATCH 92/95] =?UTF-8?q?Update=200110.=E5=B9=B3=E8=A1=A1=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0110.平衡二叉树.md | 56 ++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/problems/0110.平衡二叉树.md b/problems/0110.平衡二叉树.md index 1cd54849..b9d01503 100644 --- a/problems/0110.平衡二叉树.md +++ b/problems/0110.平衡二叉树.md @@ -498,6 +498,62 @@ class Solution { Python: +> 递归法: +```python +class Solution: + def isBalanced(self, root: TreeNode) -> bool: + return True if self.getDepth(root) != -1 else False + + #返回以该节点为根节点的二叉树的高度,如果不是二叉搜索树了则返回-1 + def getDepth(self, node): + if not node: + return 0 + leftDepth = self.getDepth(node.left) + if leftDepth == -1: return -1 #说明左子树已经不是二叉平衡树 + rightDepth = self.getDepth(node.right) + if rightDepth == -1: return -1 #说明右子树已经不是二叉平衡树 + return -1 if abs(leftDepth - rightDepth)>1 else 1 + max(leftDepth, rightDepth) +``` + +> 迭代法: +```python +class Solution: + def isBalanced(self, root: TreeNode) -> bool: + st = [] + if not root: + return True + st.append(root) + while st: + node = st.pop() #中 + if abs(self.getDepth(node.left) - self.getDepth(node.right)) > 1: + return False + if node.right: + st.append(node.right) #右(空节点不入栈) + if node.left: + st.append(node.left) #左(空节点不入栈) + return True + + def getDepth(self, cur): + st = [] + if cur: + st.append(cur) + depth = 0 + result = 0 + while st: + node = st.pop() + if node: + st.append(node) #中 + st.append(None) + depth += 1 + if node.right: st.append(node.right) #右 + if node.left: st.append(node.left) #左 + else: + node = st.pop() + depth -= 1 + result = max(result, depth) + return result +``` + Go: ```Go From d68e8922ceea44b9b066025cbbe61e5762d61216 Mon Sep 17 00:00:00 2001 From: Jack Choi <648074155@qq.com> Date: Sun, 6 Jun 2021 11:05:52 +0800 Subject: [PATCH 93/95] =?UTF-8?q?Update=200027.=E7=A7=BB=E9=99=A4=E5=85=83?= =?UTF-8?q?=E7=B4=A0.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0027.移除元素.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/problems/0027.移除元素.md b/problems/0027.移除元素.md index f0f61d06..f1187db7 100644 --- a/problems/0027.移除元素.md +++ b/problems/0027.移除元素.md @@ -199,7 +199,23 @@ def remove_element(nums, val) i end ``` - +Rust: +```rust +pub fn remove_element(nums: &mut Vec, val: i32) -> &mut Vec { + let mut start: usize = 0; + while start < nums.len() { + if nums[start] == val { + nums.remove(start); + } + start += 1; + } + nums +} +fn main() { + let mut nums = vec![5,1,3,5,2,3,4,1]; + println!("{:?}",remove_element(&mut nums, 5)); +} +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) From 4dda01ba256a0584fbe20a88ceb73335eb27269c Mon Sep 17 00:00:00 2001 From: haofeng <852172305@qq.com> Date: Sun, 6 Jun 2021 11:44:12 +0800 Subject: [PATCH 94/95] =?UTF-8?q?Update=200474.=E4=B8=80=E5=92=8C=E9=9B=B6?= =?UTF-8?q?.md=20=E6=B7=BB=E5=8A=A0=E4=B8=80=E5=92=8C=E9=9B=B6=20python3?= =?UTF-8?q?=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0474.一和零.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/problems/0474.一和零.md b/problems/0474.一和零.md index e158ca63..1e0dc794 100644 --- a/problems/0474.一和零.md +++ b/problems/0474.一和零.md @@ -191,6 +191,31 @@ class Solution { Python: +```python3 +class Solution: + def countBinary(self, s: str) -> (int, int): + zeros, ones = 0, 0 + for c in s: + if c == '0': + zeros += 1 + else: + ones += 1 + return zeros, ones + + def findMaxForm(self, strs: List[str], m: int, n: int) -> int: + dp = [[0]*(n + 1) for _ in range(m + 1)] # 默认初始化0 + # 遍历物品 + for i in range(len(strs)): + # num_zeros = strs[i].count('0') + # num_ones = strs[i].count('1') + num_zeros, num_ones = self.countBinary(strs[i]) + # 遍历背包容量且从后向前遍历! + for j in range(m, num_zeros - 1, -1): + for i in range(n, num_ones - 1, -1): + dp[j][i] = max(dp[j - num_zeros][i - num_ones] + 1, dp[j][i]) + return dp[m][n] +``` + Go: From 9c0fe0ff494aa14ba28816b7f5fec6e6a7b61687 Mon Sep 17 00:00:00 2001 From: haofeng <852172305@qq.com> Date: Sun, 6 Jun 2021 15:55:35 +0800 Subject: [PATCH 95/95] =?UTF-8?q?Update=20=E8=83=8C=E5=8C=85=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E7=90=86=E8=AE=BA=E5=9F=BA=E7=A1=80=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E8=83=8C=E5=8C=85.md=20=E6=B7=BB=E5=8A=A0=20python3=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../背包问题理论基础完全背包.md | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/problems/背包问题理论基础完全背包.md b/problems/背包问题理论基础完全背包.md index 02785ad7..9997dff3 100644 --- a/problems/背包问题理论基础完全背包.md +++ b/problems/背包问题理论基础完全背包.md @@ -179,9 +179,45 @@ int main() { Java: - Python: +```python3 +# 先遍历物品,再遍历背包 +def test_complete_pack1(): + weight = [1, 3, 4] + value = [15, 20, 30] + bag_weight = 4 + + dp = [0]*(bag_weight + 1) + + for i in range(len(weight)): + for j in range(weight[i], bag_weight + 1): + dp[j] = max(dp[j], dp[j - weight[i]] + value[i]) + + print(dp[bag_weight]) + +# 先遍历背包,再遍历物品 +def test_complete_pack2(): + weight = [1, 3, 4] + value = [15, 20, 30] + bag_weight = 4 + + dp = [0]*(bag_weight + 1) + + for j in range(bag_weight + 1): + for i in range(len(weight)): + if j >= weight[i]: dp[j] = max(dp[j], dp[j - weight[i]] + value[i]) + + print(dp[bag_weight]) + + +if __name__ == '__main__': + test_complete_pack1() + test_complete_pack2() +``` + + + Go: