mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-08 16:54:50 +08:00
Merge branch 'master' of https://github.com/youngyangyang04/leetcode
This commit is contained in:
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -199,7 +199,23 @@ def remove_element(nums, val)
|
||||
i
|
||||
end
|
||||
```
|
||||
|
||||
Rust:
|
||||
```rust
|
||||
pub fn remove_element(nums: &mut Vec<i32>, val: i32) -> &mut Vec<i32> {
|
||||
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)
|
||||
|
@ -286,28 +286,28 @@ class Solution:
|
||||
```
|
||||
Go:
|
||||
|
||||
JavaScript
|
||||
JavaScript:
|
||||
|
||||
```js
|
||||
var strStr = function (haystack, needle) {
|
||||
if (needle === '') {
|
||||
return 0;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (i === hayslen - needlen) {
|
||||
return -1;
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -147,7 +147,7 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
```
|
||||
```java
|
||||
class Solution {
|
||||
List<List<Integer>> result = new ArrayList<>();
|
||||
LinkedList<Integer> 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();
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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 _ 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
|
||||
@ -151,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
|
||||
@ -212,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
|
||||
@ -275,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
|
||||
@ -351,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
|
||||
|
@ -247,6 +247,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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
-----------------------
|
||||
|
@ -131,7 +131,20 @@ class Solution {
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python
|
||||
class Solution:
|
||||
def rob(self, nums: List[int]) -> int:
|
||||
if len(nums) == 0:
|
||||
return 0
|
||||
if len(nums) == 1:
|
||||
return nums[0]
|
||||
dp = [0] * len(nums)
|
||||
dp[0] = nums[0]
|
||||
dp[1] = max(nums[0], nums[1])
|
||||
for i in range(2, len(nums)):
|
||||
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
|
||||
return dp[-1]
|
||||
```
|
||||
|
||||
Go:
|
||||
```Go
|
||||
|
@ -180,7 +180,7 @@ if (sum > targetSum) { // 剪枝操作
|
||||
|
||||
最后C++代码如下:
|
||||
|
||||
```
|
||||
```c++
|
||||
class Solution {
|
||||
private:
|
||||
vector<vector<int>> 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -240,9 +240,103 @@ 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:
|
||||
|
||||
递归版本
|
||||
|
||||
```go
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
//本题直接就是求有多少个节点,无脑存进数组算长度就行了。
|
||||
func countNodes(root *TreeNode) int {
|
||||
if root == nil {
|
||||
return 0
|
||||
}
|
||||
res := 1
|
||||
if root.Right != nil {
|
||||
res += countNodes(root.Right)
|
||||
}
|
||||
if root.Left != nil {
|
||||
res += countNodes(root.Left)
|
||||
}
|
||||
return res
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
JavaScript:
|
||||
|
||||
递归版本
|
||||
|
@ -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 {
|
||||
|
@ -287,6 +287,25 @@ class Solution {
|
||||
|
||||
Python:
|
||||
|
||||
> 动态规划
|
||||
```python
|
||||
class Solution:
|
||||
def rob(self, root: TreeNode) -> int:
|
||||
result = self.robTree(root)
|
||||
return max(result[0], result[1])
|
||||
|
||||
#长度为2的数组,0:不偷,1:偷
|
||||
def robTree(self, cur):
|
||||
if not cur:
|
||||
return (0, 0) #这里返回tuple, 也可以返回list
|
||||
left = self.robTree(cur.left)
|
||||
right = self.robTree(cur.right)
|
||||
#偷cur
|
||||
val1 = cur.val + left[0] + right[0]
|
||||
#不偷cur
|
||||
val2 = max(left[0], left[1]) + max(right[0], right[1])
|
||||
return (val2, val1)
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
@ -163,7 +163,7 @@ class Solution {
|
||||
return dp[target];
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -190,10 +190,59 @@ class Solution {
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
```python3
|
||||
class Solution:
|
||||
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
|
||||
dp = [[0] * (n + 1) for _ in range(m + 1)] # 默认初始化0
|
||||
# 遍历物品
|
||||
for str in strs:
|
||||
ones = str.count('1')
|
||||
zeros = str.count('0')
|
||||
# 遍历背包容量且从后向前遍历!
|
||||
for i in range(m, zeros - 1, -1):
|
||||
for j in range(n, ones - 1, -1):
|
||||
dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1)
|
||||
return dp[m][n]
|
||||
```
|
||||
|
||||
Go:
|
||||
```go
|
||||
func findMaxForm(strs []string, m int, n int) int {
|
||||
// 定义数组
|
||||
dp := make([][]int, m+1)
|
||||
for i,_ := range dp {
|
||||
dp[i] = make([]int, n+1 )
|
||||
}
|
||||
// 遍历
|
||||
for i:=0;i<len(strs);i++ {
|
||||
zeroNum,oneNum := 0 , 0
|
||||
//计算0,1 个数
|
||||
//或者直接strings.Count(strs[i],"0")
|
||||
for _,v := range strs[i] {
|
||||
if v == '0' {
|
||||
zeroNum++
|
||||
}
|
||||
}
|
||||
oneNum = len(strs[i])-zeroNum
|
||||
// 从后往前 遍历背包容量
|
||||
for j:= m ; j >= zeroNum;j-- {
|
||||
for k:=n ; k >= oneNum;k-- {
|
||||
// 推导公式
|
||||
dp[j][k] = max(dp[j][k],dp[j-zeroNum][k-oneNum]+1)
|
||||
}
|
||||
}
|
||||
//fmt.Println(dp)
|
||||
}
|
||||
return dp[m][n]
|
||||
}
|
||||
|
||||
func max(a,b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -151,7 +151,30 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
递归
|
||||
```java
|
||||
class Solution {
|
||||
TreeNode pre;// 记录上一个遍历的结点
|
||||
int result = Integer.MAX_VALUE;
|
||||
public int getMinimumDifference(TreeNode root) {
|
||||
if(root==null)return 0;
|
||||
traversal(root);
|
||||
return result;
|
||||
}
|
||||
public void traversal(TreeNode root){
|
||||
if(root==null)return;
|
||||
//左
|
||||
traversal(root.left);
|
||||
//中
|
||||
if(pre!=null){
|
||||
result = Math.min(result,root.val-pre.val);
|
||||
}
|
||||
pre = root;
|
||||
//右
|
||||
traversal(root.right);
|
||||
}
|
||||
}
|
||||
```
|
||||
```Java
|
||||
class Solution {
|
||||
TreeNode pre;// 记录上一个遍历的结点
|
||||
|
@ -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:
|
||||
|
||||
|
@ -156,7 +156,31 @@ public:
|
||||
|
||||
|
||||
Java:
|
||||
|
||||
```java
|
||||
/**
|
||||
* 1.dp[i] 代表当前下表最大连续值
|
||||
* 2.递推公式 if(nums[i+1]>nums[i]) dp[i+1] = dp[i]+1
|
||||
* 3.初始化 都为1
|
||||
* 4.遍历方向,从其那往后
|
||||
* 5.结果推导 。。。。
|
||||
* @param nums
|
||||
* @return
|
||||
*/
|
||||
public static int findLengthOfLCIS(int[] nums) {
|
||||
int[] dp = new int[nums.length];
|
||||
for (int i = 0; i < dp.length; i++) {
|
||||
dp[i] = 1;
|
||||
}
|
||||
int res = 1;
|
||||
for (int i = 0; i < nums.length - 1; i++) {
|
||||
if (nums[i + 1] > nums[i]) {
|
||||
dp[i + 1] = dp[i] + 1;
|
||||
}
|
||||
res = res > dp[i + 1] ? res : dp[i + 1];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
```
|
||||
|
||||
Python:
|
||||
|
||||
|
@ -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;
|
||||
|
@ -257,6 +257,83 @@ Java:
|
||||
|
||||
Python:
|
||||
|
||||
100.相同的树
|
||||
> 递归法
|
||||
```python
|
||||
class Solution:
|
||||
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
|
||||
return self.compare(p, q)
|
||||
|
||||
def compare(self, tree1, tree2):
|
||||
if not tree1 and tree2:
|
||||
return False
|
||||
elif tree1 and not tree2:
|
||||
return False
|
||||
elif not tree1 and not tree2:
|
||||
return True
|
||||
elif tree1.val != tree2.val: #注意这里我没有使用else
|
||||
return False
|
||||
|
||||
#此时就是:左右节点都不为空,且数值相同的情况
|
||||
#此时才做递归,做下一层的判断
|
||||
compareLeft = self.compare(tree1.left, tree2.left) #左子树:左、 右子树:左
|
||||
compareRight = self.compare(tree1.right, tree2.right) #左子树:右、 右子树:右
|
||||
isSame = compareLeft and compareRight #左子树:中、 右子树:中(逻辑处理)
|
||||
return isSame
|
||||
```
|
||||
|
||||
257.二叉的所有路径
|
||||
> 递归中隐藏着回溯
|
||||
```python
|
||||
class Solution:
|
||||
def binaryTreePaths(self, root: TreeNode) -> List[str]:
|
||||
result = []
|
||||
path = []
|
||||
if not root:
|
||||
return result
|
||||
self.traversal(root, path, result)
|
||||
return result
|
||||
|
||||
def traversal(self, cur, path, result):
|
||||
path.append(cur.val)
|
||||
#这才到了叶子节点
|
||||
if not cur.left and not cur.right:
|
||||
sPath = ""
|
||||
for i in range(len(path)-1):
|
||||
sPath += str(path[i])
|
||||
sPath += "->"
|
||||
sPath += str(path[len(path)-1])
|
||||
result.append(sPath)
|
||||
return
|
||||
if cur.left:
|
||||
self.traversal(cur.left, path, result)
|
||||
path.pop() #回溯
|
||||
if cur.right:
|
||||
self.traversal(cur.right, path, result)
|
||||
path.pop() #回溯
|
||||
```
|
||||
|
||||
> 精简版
|
||||
```python
|
||||
class Solution:
|
||||
def binaryTreePaths(self, root: TreeNode) -> List[str]:
|
||||
result = []
|
||||
path = ""
|
||||
if not root:
|
||||
return result
|
||||
self.traversal(root, path, result)
|
||||
return result
|
||||
|
||||
def traversal(self, cur, path, result):
|
||||
path += str(cur.val) #中
|
||||
if not cur.left and not cur.right:
|
||||
result.append(path)
|
||||
return
|
||||
if cur.left:
|
||||
self.traversal(cur.left, path+"->", result) #左 回溯就隐藏在这里
|
||||
if cur.right:
|
||||
self.traversal(cur.right, path+"->", result) #右 回溯就隐藏在这里
|
||||
```
|
||||
|
||||
Go:
|
||||
|
||||
|
@ -273,7 +273,40 @@ Python:
|
||||
|
||||
|
||||
Go:
|
||||
```go
|
||||
func test_2_wei_bag_problem1(weight, value []int, bagWeight int) int {
|
||||
// 定义dp数组
|
||||
dp := make([][]int, len(weight))
|
||||
for i, _ := range dp {
|
||||
dp[i] = make([]int, bagWeight+1)
|
||||
}
|
||||
// 初始化
|
||||
for j := bagWeight; j >= weight[0]; j-- {
|
||||
dp[0][j] = dp[0][j-weight[0]] + value[0]
|
||||
}
|
||||
// 递推公式
|
||||
for i := 1; i < len(weight); i++ {
|
||||
//正序,也可以倒序
|
||||
for j := weight[i];j<= bagWeight ; j++ {
|
||||
dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i])
|
||||
}
|
||||
}
|
||||
return dp[len(weight)-1][bagWeight]
|
||||
}
|
||||
|
||||
func max(a,b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func main() {
|
||||
weight := []int{1,3,4}
|
||||
value := []int{15,20,30}
|
||||
test_2_wei_bag_problem1(weight,value,4)
|
||||
}
|
||||
```
|
||||
|
||||
-----------------------
|
||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||
|
@ -219,7 +219,36 @@ Python:
|
||||
|
||||
|
||||
Go:
|
||||
```go
|
||||
func test_1_wei_bag_problem(weight, value []int, bagWeight int) int {
|
||||
// 定义 and 初始化
|
||||
dp := make([]int,bagWeight+1)
|
||||
// 递推顺序
|
||||
for i := 0 ;i < len(weight) ; i++ {
|
||||
// 这里必须倒序,区别二维,因为二维dp保存了i的状态
|
||||
for j:= bagWeight; j >= weight[i] ; j-- {
|
||||
// 递推公式
|
||||
dp[j] = max(dp[j], dp[j-weight[i]]+value[i])
|
||||
}
|
||||
}
|
||||
//fmt.Println(dp)
|
||||
return dp[bagWeight]
|
||||
}
|
||||
|
||||
func max(a,b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
|
||||
func main() {
|
||||
weight := []int{1,3,4}
|
||||
value := []int{15,20,30}
|
||||
test_1_wei_bag_problem(weight,value,4)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
Reference in New Issue
Block a user