Merge branch 'youngyangyang04:master' into master

This commit is contained in:
Mrxulovemingming
2022-05-22 13:09:23 +08:00
committed by GitHub
7 changed files with 44 additions and 60 deletions

View File

@ -112,8 +112,8 @@ public:
};
```
* 时间复杂度$O(n\log n)$ 有一个快排
* 空间复杂度$O(1)$我没有算result数组返回值所需容器占的空间
* 时间复杂度O(nlog n) 有一个快排
* 空间复杂度O(n)有一个快排最差情况(倒序)需要n次递归调用因此确实需要O(n)的栈空间
## 总结

View File

@ -27,7 +27,7 @@
也可以直接看我的B站视频[带你学透回溯算法-组合问题对应力扣题目77.组合)](https://www.bilibili.com/video/BV1ti4y1L7cv#reply3733925949)
# 思路
## 思路
本题这是回溯法的经典题目。
@ -232,7 +232,7 @@ void backtracking(参数) {
**对比一下本题的代码,是不是发现有点像!** 所以有了这个模板,就有解题的大体方向,不至于毫无头绪。
# 总结
## 总结
组合问题是回溯法解决的经典问题我们开始的时候给大家列举一个很形象的例子就是n为100k为50的话直接想法就需要50层for循环。
@ -242,7 +242,7 @@ void backtracking(参数) {
接着用回溯法三部曲,逐步分析了函数参数、终止条件和单层搜索的过程。
# 剪枝优化
## 剪枝优化
我们说过,回溯法虽然是暴力搜索,但也有时候可以有点剪枝优化一下的。
@ -324,7 +324,7 @@ public:
};
```
# 剪枝总结
## 剪枝总结
本篇我们准对求组合问题的回溯法代码做了剪枝优化,这个优化如果不画图的话,其实不好理解,也不好讲清楚。
@ -334,10 +334,10 @@ public:
# 其他语言版本
## 其他语言版本
## Java
### Java
```java
class Solution {
List<List<Integer>> result = new ArrayList<>();
@ -366,6 +366,8 @@ class Solution {
}
```
### Python
Python2:
```python
class Solution(object):
@ -395,7 +397,6 @@ class Solution(object):
return result
```
## Python
```python
class Solution:
def combine(self, n: int, k: int) -> List[List[int]]:
@ -432,7 +433,7 @@ class Solution:
```
## javascript
### javascript
剪枝:
```javascript
@ -456,7 +457,7 @@ const combineHelper = (n, k, startIndex) => {
}
```
## TypeScript
### TypeScript
```typescript
function combine(n: number, k: number): number[][] {
@ -479,7 +480,7 @@ function combine(n: number, k: number): number[][] {
## Go
### Go
```Go
var res [][]int
func combine(n int, k int) [][]int {
@ -534,7 +535,7 @@ func backtrack(n,k,start int,track []int){
}
```
## C
### C
```c
int* path;
int pathTop;
@ -642,7 +643,7 @@ int** combine(int n, int k, int* returnSize, int** returnColumnSizes){
}
```
## Swift
### Swift
```swift
func combine(_ n: Int, _ k: Int) -> [[Int]] {

View File

@ -238,7 +238,7 @@ public:
};
```
# 总结
## 总结
这次我们又深度剖析了一道二叉树的“简单题”大家会发现真正的把题目搞清楚其实并不简单leetcode上accept了和真正掌握了还是有距离的。
@ -248,7 +248,7 @@ public:
如果已经做过这道题目的同学,读完文章可以再去看看这道题目,思考一下,会有不一样的发现!
# 相关题目推荐
## 相关题目推荐
这两道题目基本和本题是一样的只要稍加修改就可以AC。

View File

@ -93,7 +93,7 @@ public:
};
```
* 时间复杂度O(nlog n) ,有一个快排
* 空间复杂度O(1)
* 空间复杂度O(n),有一个快排,最差情况(倒序)时需要n次递归调用。因此确实需要O(n)的栈空间
大家此时会发现如此复杂的一个问题,代码实现却这么简单!

View File

@ -105,8 +105,8 @@ public:
};
```
* 时间复杂度$O(n\log n)$因为有一个快排
* 空间复杂度$O(1)$
* 时间复杂度O(nlog n)因为有一个快排
* 空间复杂度O(1)有一个快排最差情况(倒序)需要n次递归调用因此确实需要O(n)的栈空间
可以看出代码并不复杂

View File

@ -315,6 +315,30 @@ function test () {
test();
```
### TypeScript
```typescript
function testWeightBagProblem(
weight: number[],
value: number[],
size: number
): number {
const goodsNum: number = weight.length;
const dp: number[] = new Array(size + 1).fill(0);
for (let i = 0; i < goodsNum; i++) {
for (let j = size; j >= weight[i]; j--) {
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
}
}
return dp[size];
}
const weight = [1, 3, 4];
const value = [15, 20, 30];
const size = 4;
console.log(testWeightBagProblem(weight, value, size));
```
-----------------------

View File

@ -1,41 +0,0 @@
# 双指针,不计算链表长度
设置指向headA和headB的指针pa、pb分别遍历两个链表每次循环同时更新pa和pb。
* 当链表A遍历完之后即pa为空时将pa指向headB
* 当链表B遍历完之后即pa为空时将pb指向headA
* 当pa与pb相等时即指向同一个节点该节点即为相交起始节点。
* 若链表不相交则pa、pb同时为空时退出循环即如果链表不相交pa与pb在遍历过全部节点后同时指向结尾空节点此时退出循环返回空。
# 证明思路
设链表A不相交部分长度为a链表B不相交部分长度为b两个链表相交部分长度为c。<br>
在pa指向链表A时即pa为空之前pa经过链表A不相交部分和相交部分走过的长度为a+c<br>
pa指向链表B后在移动相交节点之前经过链表B不相交部分走过的长度为b总合为a+c+b。<br>
同理pb走过长度的总合为b+c+a。二者相等即pa与pb可同时到达相交起始节点。 <br>
该方法可避免计算具体链表长度。
```cpp
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//链表为空时,返回空指针
if(headA == nullptr || headB == nullptr) return nullptr;
ListNode* pa = headA;
ListNode* pb = headB;
//pa与pb在遍历过全部节点后,同时指向结尾空节点时退出循环
while(pa != nullptr || pb != nullptr){
//pa为空时将pa指向headB
if(pa == nullptr){
pa = headB;
}
//pa为空时将pb指向headA
if(pb == nullptr){
pb = headA;
}
//pa与pb相等时返回相交起始节点
if(pa == pb){
return pa;
}
pa = pa->next;
pb = pb->next;
}
return nullptr;
}
};
```