From 0b2312ffec67c90a53feb938a6df5444c41fbc1a Mon Sep 17 00:00:00 2001 From: Kelvin Date: Thu, 29 Jul 2021 09:02:15 -0400 Subject: [PATCH 1/7] =?UTF-8?q?Update=200404.=E5=B7=A6=E5=8F=B6=E5=AD=90?= =?UTF-8?q?=E4=B9=8B=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加python3 迭代方法的代码. Q: 我为什么要更改当前已有的递归代码? A: 因为我发现当前版本的递归代码跟Carl哥的逻辑不是特别一样. 我承认解题思路千变万化, 但是个人感觉最好最好还是尽量跟Carl的思路一样, 这样方便初学者阅读不同语言编写出来的代码. --- problems/0404.左叶子之和.md | 56 +++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/problems/0404.左叶子之和.md b/problems/0404.左叶子之和.md index aa758367..2a76a461 100644 --- a/problems/0404.左叶子之和.md +++ b/problems/0404.左叶子之和.md @@ -205,25 +205,51 @@ class Solution { 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 +```python class Solution: def sumOfLeftLeaves(self, root: TreeNode) -> int: - self.res=0 - def areleftleaves(root): - if not root:return - if root.left and (not root.left.left) and (not root.left.right):self.res+=root.left.val - areleftleaves(root.left) - areleftleaves(root.right) - areleftleaves(root) - return self.res + if not root: + return 0 + + left_left_leaves_sum = self.sumOfLeftLeaves(root.left) # 左 + right_left_leaves_sum = self.sumOfLeftLeaves(root.right) # 右 + + cur_left_leaf_val = 0 + if root.left and not root.left.left and not root.left.right: + cur_left_leaf_val = root.left.val # 中 + + return cur_left_leaf_val + left_left_leaves_sum + right_left_leaves_sum ``` + +**迭代** +```python +class Solution: + def sumOfLeftLeaves(self, root: TreeNode) -> int: + """ + Idea: Each time check current node's left node. + If current node don't have one, skip it. + """ + stack = [] + if root: + stack.append(root) + res = 0 + + while stack: + # 每次都把当前节点的左节点加进去. + cur_node = stack.pop() + if cur_node.left and not cur_node.left.left and not cur_node.left.right: + res += cur_node.left.val + + if cur_node.left: + stack.append(cur_node.left) + if cur_node.right: + stack.append(cur_node.right) + + return res +``` + Go: > 递归法 From 2f412e5c7d3b41b66946d92e699330cb7e5e5036 Mon Sep 17 00:00:00 2001 From: Kelvin Date: Thu, 29 Jul 2021 11:18:26 -0400 Subject: [PATCH 2/7] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20513.=E6=89=BE=E6=A0=91?= =?UTF-8?q?=E5=B7=A6=E4=B8=8B=E8=A7=92=E7=9A=84=E5=80=BC=20python=20?= =?UTF-8?q?=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 更改python 递归代码: 上一版本python代码跟卡哥思路不一样, 感觉把不同的解题方法放在这里不方便初学者学习. 所以建议更改. 2. 添加迭代方法代码. --- problems/0513.找树左下角的值.md | 61 +++++++++++++++++++++----- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/problems/0513.找树左下角的值.md b/problems/0513.找树左下角的值.md index 17d15fde..391118ab 100644 --- a/problems/0513.找树左下角的值.md +++ b/problems/0513.找树左下角的值.md @@ -274,8 +274,9 @@ class Solution { Python: + +**递归法 - 回溯** ```python -//递归法 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): @@ -284,17 +285,53 @@ Python: # self.right = right class Solution: def findBottomLeftValue(self, root: TreeNode) -> int: - depth=0 - self.res=[] - def level(root,depth): - if not root:return - if depth==len(self.res): - self.res.append([]) - self.res[depth].append(root.val) - level(root.left,depth+1) - level(root.right,depth+1) - level(root,depth) - return self.res[-1][0] + max_depth = -float("INF") + max_left_value = -float("INF") + + def __traversal(root, left_len): + nonlocal max_depth, max_left_value + + if not root.left and not root.right: + if left_len > max_depth: + max_depth = left_len + max_left_value = root.val + return + + if root.left: + left_len += 1 + __traversal(root.left, left_len) + left_len -= 1 + + if root.right: + left_len += 1 + __traversal(root.right, left_len) + left_len -= 1 + return + + __traversal(root, 0) + + return max_left_value +``` + +**迭代法 - 层序遍历** +```python +class Solution: + def findBottomLeftValue(self, root: TreeNode) -> int: + queue = deque() + if root: + queue.append(root) + result = 0 + while queue: + q_len = len(queue) + for i in range(q_len): + if i == 0: + result = queue[i].val + cur = queue.popleft() + if cur.left: + queue.append(cur.left) + if cur.right: + queue.append(cur.right) + return result ``` Go: From 8c53c48ea87fc2f02934799da6f659a7647eb268 Mon Sep 17 00:00:00 2001 From: Kelvin Date: Thu, 29 Jul 2021 11:21:14 -0400 Subject: [PATCH 3/7] =?UTF-8?q?Revert=20"=E6=9B=B4=E6=96=B0=20513.?= =?UTF-8?q?=E6=89=BE=E6=A0=91=E5=B7=A6=E4=B8=8B=E8=A7=92=E7=9A=84=E5=80=BC?= =?UTF-8?q?=20python=20=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 2f412e5c7d3b41b66946d92e699330cb7e5e5036. --- problems/0513.找树左下角的值.md | 61 +++++--------------------- 1 file changed, 12 insertions(+), 49 deletions(-) diff --git a/problems/0513.找树左下角的值.md b/problems/0513.找树左下角的值.md index 391118ab..17d15fde 100644 --- a/problems/0513.找树左下角的值.md +++ b/problems/0513.找树左下角的值.md @@ -274,9 +274,8 @@ class Solution { Python: - -**递归法 - 回溯** ```python +//递归法 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val=0, left=None, right=None): @@ -285,53 +284,17 @@ Python: # self.right = right class Solution: def findBottomLeftValue(self, root: TreeNode) -> int: - max_depth = -float("INF") - max_left_value = -float("INF") - - def __traversal(root, left_len): - nonlocal max_depth, max_left_value - - if not root.left and not root.right: - if left_len > max_depth: - max_depth = left_len - max_left_value = root.val - return - - if root.left: - left_len += 1 - __traversal(root.left, left_len) - left_len -= 1 - - if root.right: - left_len += 1 - __traversal(root.right, left_len) - left_len -= 1 - return - - __traversal(root, 0) - - return max_left_value -``` - -**迭代法 - 层序遍历** -```python -class Solution: - def findBottomLeftValue(self, root: TreeNode) -> int: - queue = deque() - if root: - queue.append(root) - result = 0 - while queue: - q_len = len(queue) - for i in range(q_len): - if i == 0: - result = queue[i].val - cur = queue.popleft() - if cur.left: - queue.append(cur.left) - if cur.right: - queue.append(cur.right) - return result + depth=0 + self.res=[] + def level(root,depth): + if not root:return + if depth==len(self.res): + self.res.append([]) + self.res[depth].append(root.val) + level(root.left,depth+1) + level(root.right,depth+1) + level(root,depth) + return self.res[-1][0] ``` Go: From 49d55fb1c8c26f668c1676075ac10a21b527ab92 Mon Sep 17 00:00:00 2001 From: Kelvin Date: Thu, 29 Jul 2021 11:25:33 -0400 Subject: [PATCH 4/7] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20513.=E6=89=BE=E6=A0=91?= =?UTF-8?q?=E5=B7=A6=E4=B8=8B=E8=A7=92=E7=9A=84=E5=80=BC=20python=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 上一版本 递归python代码跟题解的方式不同. 个人认为不同方法做出的代码没有必要放在题解里, 建议修改成我提供的python版本. 2. 增加Python3 迭代部分的代码. --- problems/0513.找树左下角的值.md | 66 +++++++++++++++++++------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/problems/0513.找树左下角的值.md b/problems/0513.找树左下角的值.md index 17d15fde..e83fcc18 100644 --- a/problems/0513.找树左下角的值.md +++ b/problems/0513.找树左下角的值.md @@ -274,27 +274,57 @@ class Solution { 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 findBottomLeftValue(self, root: TreeNode) -> int: - depth=0 - self.res=[] - def level(root,depth): - if not root:return - if depth==len(self.res): - self.res.append([]) - self.res[depth].append(root.val) - level(root.left,depth+1) - level(root.right,depth+1) - level(root,depth) - return self.res[-1][0] + max_depth = -float("INF") + max_left_value = -float("INF") + + def __traversal(root, left_len): + nonlocal max_depth, max_left_value + + if not root.left and not root.right: + if left_len > max_depth: + max_depth = left_len + max_left_value = root.val + return + + if root.left: + left_len += 1 + __traversal(root.left, left_len) + left_len -= 1 + + if root.right: + left_len += 1 + __traversal(root.right, left_len) + left_len -= 1 + return + + __traversal(root, 0) + + return max_left_value +``` +**迭代 - 层序遍历** +```python +class Solution: + def findBottomLeftValue(self, root: TreeNode) -> int: + queue = deque() + if root: + queue.append(root) + result = 0 + while queue: + q_len = len(queue) + for i in range(q_len): + if i == 0: + result = queue[i].val + cur = queue.popleft() + if cur.left: + queue.append(cur.left) + if cur.right: + queue.append(cur.right) + return result ``` Go: From 1dd4a529fcc7e7d9fb2de170fbd628d9f2af6f7f Mon Sep 17 00:00:00 2001 From: Kelvin Date: Thu, 29 Jul 2021 13:50:56 -0400 Subject: [PATCH 5/7] =?UTF-8?q?Update=200513.=E6=89=BE=E6=A0=91=E5=B7=A6?= =?UTF-8?q?=E4=B8=8B=E8=A7=92=E7=9A=84=E5=80=BC.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更改变量名称 --- problems/0513.找树左下角的值.md | 34 +++++++++++--------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/problems/0513.找树左下角的值.md b/problems/0513.找树左下角的值.md index e83fcc18..27c6e83c 100644 --- a/problems/0513.找树左下角的值.md +++ b/problems/0513.找树左下角的值.md @@ -280,31 +280,25 @@ Python: class Solution: def findBottomLeftValue(self, root: TreeNode) -> int: max_depth = -float("INF") - max_left_value = -float("INF") - - def __traversal(root, left_len): - nonlocal max_depth, max_left_value + leftmost_val = 0 + def __traverse(root, cur_depth): + nonlocal max_depth, leftmost_val if not root.left and not root.right: - if left_len > max_depth: - max_depth = left_len - max_left_value = root.val - return - + if cur_depth > max_depth: + max_depth = cur_depth + leftmost_val = root.val if root.left: - left_len += 1 - __traversal(root.left, left_len) - left_len -= 1 - + cur_depth += 1 + __traverse(root.left, cur_depth) + cur_depth -= 1 if root.right: - left_len += 1 - __traversal(root.right, left_len) - left_len -= 1 - return - - __traversal(root, 0) + cur_depth += 1 + __traverse(root.right, cur_depth) + cur_depth -= 1 - return max_left_value + __traverse(root, 0) + return leftmost_val ``` **迭代 - 层序遍历** ```python From 440e04fffe7bc5cfacd11653fc6f0d3704382767 Mon Sep 17 00:00:00 2001 From: Kelvin Date: Thu, 29 Jul 2021 15:50:46 -0400 Subject: [PATCH 6/7] =?UTF-8?q?=E6=9B=B4=E6=94=B9=200112.=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E6=80=BB=E5=92=8C.md=20Python3=20=E4=BB=A3=E7=A0=81.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0112.路径总和: 1. 修改了 python3 注释, 更改代码格式. 2. 增加了迭代方法Python3代码. 0113.路径总和-ii: 上一版python3代码的问题: (1)注释一般不用// (2)代码格式有些不规范. (3)内层函数命名也不是特别的informative. 新版本代码修改了上述问题. 本次提交代码均已通过leetcode测试. --- problems/0112.路径总和.md | 113 ++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 41 deletions(-) diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md index ae9a9267..474e17da 100644 --- a/problems/0112.路径总和.md +++ b/problems/0112.路径总和.md @@ -416,6 +416,8 @@ class Solution { Python: 0112.路径总和 + +**递归** ```python # Definition for a binary tree node. # class TreeNode: @@ -424,28 +426,56 @@ Python: # self.left = left # self.right = right -// 递归法 - class Solution: def hasPathSum(self, root: TreeNode, targetSum: int) -> bool: - def isornot(root,targetSum)->bool: - if (not root.left) and (not root.right) and targetSum == 0:return True // 遇到叶子节点,并且计数为0 - if (not root.left) and (not root.right):return False //遇到叶子节点,计数不为0 + def isornot(root, targetSum) -> bool: + if (not root.left) and (not root.right) and targetSum == 0: + return True # 遇到叶子节点,并且计数为0 + if (not root.left) and (not root.right): + return False # 遇到叶子节点,计数不为0 if root.left: - targetSum -= root.left.val //左节点 - if isornot(root.left,targetSum):return True //递归,处理左节点 - targetSum += root.left.val //回溯 + targetSum -= root.left.val # 左节点 + if isornot(root.left, targetSum): return True # 递归,处理左节点 + targetSum += root.left.val # 回溯 if root.right: - targetSum -= root.right.val //右节点 - if isornot(root.right,targetSum):return True //递归,处理右节点 - targetSum += root.right.val //回溯 + targetSum -= root.right.val # 右节点 + if isornot(root.right, targetSum): return True # 递归,处理右节点 + targetSum += root.right.val # 回溯 return False - - if root == None:return False //别忘记处理空TreeNode - else:return isornot(root,targetSum-root.val) + + if root == None: + return False # 别忘记处理空TreeNode + else: + return isornot(root, targetSum - root.val) ``` +**迭代 - 层序遍历** +```python +class Solution: + def hasPathSum(self, root: TreeNode, targetSum: int) -> bool: + if not root: + return False + + stack = [] # [(当前节点,路径数值), ...] + stack.append((root, root.val)) + + while stack: + cur_node, path_sum = stack.pop() + + if not cur_node.left and not cur_node.right and path_sum == targetSum: + return True + + if cur_node.right: + stack.append((cur_node.right, path_sum + cur_node.right.val)) + + if cur_node.left: + stack.append((cur_node.left, path_sum + cur_node.left.val)) + + return False +``` 0113.路径总和-ii + +**递归** ```python # Definition for a binary tree node. # class TreeNode: @@ -453,35 +483,36 @@ class Solution: # self.val = val # self.left = left # self.right = right -//递归法 class Solution: def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]: - path=[] - res=[] - def pathes(root,targetSum): - if (not root.left) and (not root.right) and targetSum == 0: // 遇到叶子节点,并且计数为0 - res.append(path[:]) //找到一种路径,记录到res中,注意必须是path[:]而不是path - return - if (not root.left) and (not root.right):return // 遇到叶子节点直接返回 - if root.left: //左 - targetSum -= root.left.val - path.append(root.left.val) //递归前记录节点 - pathes(root.left,targetSum) //递归 - targetSum += root.left.val //回溯 - path.pop() //回溯 - if root.right: //右 - targetSum -= root.right.val - path.append(root.right.val) //递归前记录节点 - pathes(root.right,targetSum) //递归 - targetSum += root.right.val //回溯 - path.pop() //回溯 - return - - if root == None:return [] //处理空TreeNode - else: - path.append(root.val) //首先处理根节点 - pathes(root,targetSum-root.val) - return res + + def traversal(cur_node, remain): + if not cur_node.left and not cur_node.right and remain == 0: + result.append(path[:]) + return + + if not cur_node.left and not cur_node.right: return + + if cur_node.left: + path.append(cur_node.left.val) + remain -= cur_node.left.val + traversal(cur_node.left, remain) + path.pop() + remain += cur_node.left.val + + if cur_node.right: + path.append(cur_node.right.val) + remain -= cur_node.right.val + traversal(cur_node.right, remain) + path.pop() + remain += cur_node.right.val + + result, path = [], [] + if not root: + return [] + path.append(root.val) + traversal(root, targetSum - root.val) + return result ``` Go: From d21853a3b22763c4d1cbe02ab6a2baba349348cb Mon Sep 17 00:00:00 2001 From: Jack <965555169@qq.com> Date: Fri, 30 Jul 2021 11:07:38 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E6=9B=B4=E6=96=B0718.=20=E6=9C=80=E9=95=BF?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E5=AD=90=E6=95=B0=E7=BB=84=20JavaScript?= =?UTF-8?q?=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0718.最长重复子数组.md | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/problems/0718.最长重复子数组.md b/problems/0718.最长重复子数组.md index 9ee94a3d..959ed39e 100644 --- a/problems/0718.最长重复子数组.md +++ b/problems/0718.最长重复子数组.md @@ -252,6 +252,33 @@ func findLength(A []int, B []int) int { } ``` +JavaScript: + +> 动态规划 + +```javascript +const findLength = (A, B) => { + // A、B数组的长度 + const [m, n] = [A.length, B.length]; + // dp数组初始化,都初始化为0 + const dp = new Array(m + 1).fill(0).map(x => new Array(n + 1).fill(0)); + // 初始化最大长度为0 + let res = 0; + for (let i = 1; i <= m; i++) { + for (let j = 1; j <= n; j++) { + // 遇到A[i - 1] === B[j - 1],则更新dp数组 + if (A[i - 1] === B[j - 1]) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } + // 更新res + res = dp[i][j] > res ? dp[i][j] : res; + } + } + // 遍历完成,返回res + return res; +}; +``` + -----------------------