Skip to content

Commit

Permalink
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
Browse files Browse the repository at this point in the history
  • Loading branch information
youngyangyang04 committed Feb 1, 2023
2 parents 7fcbe49 + 316e470 commit 4d262c7
Show file tree
Hide file tree
Showing 31 changed files with 468 additions and 56 deletions.
22 changes: 22 additions & 0 deletions problems/0017.电话号码的字母组合.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,28 @@ class Solution:
for letter in letters:
self.backtracking(digits, index + 1, answer + letter) # 递归至下一层 + 回溯
```
**使用itertools**
```python
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
import itertools
if not digits:
return list()

phoneMap = {
"2": "abc",
"3": "def",
"4": "ghi",
"5": "jkl",
"6": "mno",
"7": "pqrs",
"8": "tuv",
"9": "wxyz",
}

groups = (phoneMap[digit] for digit in digits)
return ["".join(combination) for combination in itertools.product(*groups)]
```


## Go
Expand Down
3 changes: 2 additions & 1 deletion problems/0031.下一个排列.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ class Solution:
Do not return anything, modify nums in-place instead.
"""
length = len(nums)
for i in range(length - 1, -1, -1):
for i in range(length - 2, -1, -1): # 从倒数第二个开始
if nums[i]>=nums[i+1]: continue # 剪枝去重
for j in range(length - 1, i, -1):
if nums[j] > nums[i]:
nums[j], nums[i] = nums[i], nums[j]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@ class Solution:
while left <= right:
middle = left + (right-left) // 2
if nums[middle] >= target: # 寻找左边界,nums[middle] == target的时候更新right
right = middle - 1;
leftBoder = right;
right = middle - 1
leftBoder = right
else:
left = middle + 1
return leftBoder
Expand Down
4 changes: 2 additions & 2 deletions problems/0042.接雨水.md
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ class Solution {
### Python:

双指针法
```python3
```Python
class Solution:
def trap(self, height: List[int]) -> int:
res = 0
Expand Down Expand Up @@ -510,7 +510,7 @@ class Solution:
return result
```
单调栈
```python3
```Python
class Solution:
def trap(self, height: List[int]) -> int:
# 单调栈
Expand Down
20 changes: 20 additions & 0 deletions problems/0062.不同路径.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,26 @@ int uniquePaths(int m, int n){
}
```
滚动数组解法:
```c
int uniquePaths(int m, int n){
int i, j;
// 初始化dp数组
int *dp = (int*)malloc(sizeof(int) * n);
for (i = 0; i < n; ++i)
dp[i] = 1;
for (j = 1; j < m; ++j) {
for (i = 1; i < n; ++i) {
// dp[i]为二维数组解法中dp[i-1][j]。dp[i-1]为二维数组解法中dp[i][j-1]
dp[i] += dp[i - 1];
}
}
return dp[n - 1];
}
```

### Scala

```scala
Expand Down
33 changes: 33 additions & 0 deletions problems/0063.不同路径II.md
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,39 @@ int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obst
}
```
空间优化版本:
```c
int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obstacleGridColSize){
int m = obstacleGridSize;
int n = obstacleGridColSize[0];
int *dp = (int*)malloc(sizeof(int) * n);
int i, j;

// 初始化dp为第一行起始状态。
for (j = 0; j < n; ++j) {
if (obstacleGrid[0][j] == 1)
dp[j] = 0;
else if (j == 0)
dp[j] = 1;
else
dp[j] = dp[j - 1];
}

for (i = 1; i < m; ++i) {
for (j = 0; j < n; ++j) {
if (obstacleGrid[i][j] == 1)
dp[j] = 0;
// 若j为0,dp[j]表示最左边一列,无需改动
// 此处dp[j],dp[j-1]等同于二维dp中的dp[i-1][j]和dp[i][j-1]
else if (j != 0)
dp[j] += dp[j - 1];
}
}

return dp[n - 1];
}
```
### Scala
```scala
Expand Down
27 changes: 27 additions & 0 deletions problems/0093.复原IP地址.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
* 0 <= s.length <= 3000
* s 仅由数字组成

# 算法公开课

**《代码随想录》算法视频公开课:[93.复原IP地址](https://www.bilibili.com/video/BV1XP4y1U73i/),相信结合视频再看本篇题解,更有助于大家对本题的理解**

# 算法公开课

Expand Down Expand Up @@ -429,6 +432,30 @@ class Solution:
return True
```

python3; 简单拼接版本(类似Leetcode131写法):
```python
class Solution:
def restoreIpAddresses(self, s: str) -> List[str]:
global results, path
results = []
path = []
self.backtracking(s,0)
return results

def backtracking(self,s,index):
global results,path
if index == len(s) and len(path)==4:
results.append('.'.join(path)) # 在连接时需要中间间隔符号的话就在''中间写上对应的间隔符
return
for i in range(index,len(s)):
if len(path)>3: break # 剪枝
temp = s[index:i+1]
if (int(temp)<256 and int(temp)>0 and temp[0]!='0') or (temp=='0'):
path.append(temp)
self.backtracking(s,i+1)
path.pop()
```

## Go

```go
Expand Down
42 changes: 41 additions & 1 deletion problems/0102.二叉树的层序遍历.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
* 111.二叉树的最小深度



![我要打十个](https://code-thinking.cdn.bcebos.com/gifs/%E6%88%91%E8%A6%81%E6%89%93%E5%8D%81%E4%B8%AA.gif)




# 102.二叉树的层序遍历

[力扣题目链接](https://leetcode.cn/problems/binary-tree-level-order-traversal/)
Expand Down Expand Up @@ -562,6 +564,45 @@ public class N0107 {
}
```

```java
/**
* 思路和模板相同, 对收集答案的方式做了优化, 最后不需要反转
*/
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
// 利用链表可以进行 O(1) 头部插入, 这样最后答案不需要再反转
LinkedList<List<Integer>> ans = new LinkedList<>();

Queue<TreeNode> q = new LinkedList<>();

if (root != null) q.offer(root);

while (!q.isEmpty()) {
int size = q.size();

List<Integer> temp = new ArrayList<>();

for (int i = 0; i < size; i ++) {
TreeNode node = q.poll();

temp.add(node.val);

if (node.left != null) q.offer(node.left);

if (node.right != null) q.offer(node.right);
}

// 新遍历到的层插到头部, 这样就满足按照层次反序的要求
ans.addFirst(temp);
}

return ans;
}
}
```



go:

```GO
Expand Down Expand Up @@ -3013,4 +3054,3 @@ impl Solution {
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
</a>

34 changes: 34 additions & 0 deletions problems/0106.从中序与后序遍历序列构造二叉树.md
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ public:
};
```

## Python


# 105.从前序与中序遍历序列构造二叉树

[力扣题目链接](https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)
Expand Down Expand Up @@ -650,6 +653,37 @@ class Solution {
```

## Python
```python
class Solution:
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
# 第一步: 特殊情况讨论: 树为空. 或者说是递归终止条件
if not postorder:
return

# 第二步: 后序遍历的最后一个就是当前的中间节点
root_val = postorder[-1]
root = TreeNode(root_val)

# 第三步: 找切割点.
root_index = inorder.index(root_val)

# 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
left_inorder = inorder[:root_index]
right_inorder = inorder[root_index + 1:]

# 第五步: 切割postorder数组. 得到postorder数组的左,右半边.
# ⭐️ 重点1: 中序数组大小一定跟后序数组大小是相同的.
left_postorder = postorder[:len(left_inorder)]
right_postorder = postorder[len(left_inorder): len(postorder) - 1]


# 第六步: 递归
root.left = self.buildTree(left_inorder, left_postorder)
root.right = self.buildTree(right_inorder, right_postorder)

# 第七步: 返回答案
return root
```

105.从前序与中序遍历序列构造二叉树

Expand Down
32 changes: 32 additions & 0 deletions problems/0108.将有序数组转换为二叉搜索树.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,38 @@ class Solution:
return mid_root
```

**迭代**(左闭右开)
```python
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if len(nums) == 0: return None
root = TreeNode() # 初始化
nodeSt = [root]
leftSt = [0]
rightSt = [len(nums)]

while nodeSt:
node = nodeSt.pop() # 处理根节点
left = leftSt.pop()
right = rightSt.pop()
mid = left + (right - left) // 2
node.val = nums[mid]

if left < mid: # 处理左区间
node.left = TreeNode()
nodeSt.append(node.left)
leftSt.append(left)
rightSt.append(mid)

if right > mid + 1: # 处理右区间
node.right = TreeNode()
nodeSt.append(node.right)
leftSt.append(mid + 1)
rightSt.append(right)

return root
```

## Go

递归(隐含回溯)
Expand Down
6 changes: 3 additions & 3 deletions problems/0112.路径总和.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,14 @@ public:
以上代码精简之后如下:

```cpp
class solution {
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if (root == null) return false;
if (!root) return false;
if (!root->left && !root->right && sum == root->val) {
return true;
}
return haspathsum(root->left, sum - root->val) || haspathsum(root->right, sum - root->val);
return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val);
}
};
```
Expand Down
2 changes: 1 addition & 1 deletion problems/0134.加油站.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public:
* 情况一:如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的
* 情况二:rest[i] = gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。
* 情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能这个负数填平,能把这个负数填平的节点就是出发节点。
* 情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点能把这个负数填平,能把这个负数填平的节点就是出发节点。
C++代码如下:
Expand Down
2 changes: 1 addition & 1 deletion problems/0151.翻转字符串里的单词.md
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ class Solution:
while left <= right and s[left] == ' ': #去除开头的空格
left += 1
while left <= right and s[right] == ' ': #去除结尾的空格
right = right-1
right -= 1
tmp = []
while left <= right: #去除单词中间多余的空格
if s[left] != ' ':
Expand Down
Loading

0 comments on commit 4d262c7

Please sign in to comment.