Skip to content

[pull] master from youngyangyang04:master #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
May 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
21475ad
修正了其中一个错别字
languagege May 9, 2022
7519826
Update 0019.删除链表的倒数第N个节点.md
qingfengpiaoa May 10, 2022
c62d518
fix bug
FizzerYu May 10, 2022
d92aa2c
Add 0112.路径总和.md C语言解法
KingArthur0205 May 10, 2022
cc2c2ad
添加 0977.有序数组的平方.md Scala版本
wzqwtt May 11, 2022
842c042
添加(背包问题理论基础多重背包.md):增加typescript版本
xiaofei-2020 May 11, 2022
871d96a
添加 0209.长度最小的子数组.md Scala版本
wzqwtt May 11, 2022
cb2fea6
添加 0113.路径总和II C语言解法
KingArthur0205 May 11, 2022
c363e9d
添加(0198.打家劫舍.md):增加typescript版本
xiaofei-2020 May 11, 2022
2964855
添加(0213.打家劫舍II.md):增加typescript版本
xiaofei-2020 May 11, 2022
1e9bb56
Merge branch 'youngyangyang04:master' into master
KingArthur0205 May 14, 2022
5da6c06
添加 背包理论肌醇01背包 C语言版本
KingArthur0205 May 14, 2022
4defb3d
Merge branch 'master' of https://github.com/KingArthur0205/leetcode-m…
KingArthur0205 May 14, 2022
a20ac9d
Merge branch 'youngyangyang04:master' into master
KingArthur0205 May 15, 2022
aa22b80
添加 背包理论基础01-2.mc C语言版本
KingArthur0205 May 15, 2022
d15c4af
Merge branch 'master' of https://github.com/KingArthur0205/leetcode-m…
KingArthur0205 May 15, 2022
19abe18
添加 0416.分割等和子集.md C语言版本
KingArthur0205 May 15, 2022
4f94d8a
Merge pull request #1296 from languagege/master
youngyangyang04 May 27, 2022
b4a40a2
Merge pull request #1298 from qingfengpiaoa/master
youngyangyang04 May 27, 2022
5719c00
Merge pull request #1301 from FizzerYu/patch-1
youngyangyang04 May 27, 2022
45a8a6b
Merge branch 'master' into master
youngyangyang04 May 27, 2022
309643e
Merge pull request #1302 from KingArthur0205/master
youngyangyang04 May 27, 2022
7684a1c
Merge pull request #1304 from xiaofei-2020/dp27
youngyangyang04 May 27, 2022
f115be0
Merge pull request #1305 from ZongqinWang/patch01
youngyangyang04 May 27, 2022
bb32a41
Merge pull request #1306 from xiaofei-2020/dp29
youngyangyang04 May 27, 2022
0e3a1bc
Merge pull request #1307 from xiaofei-2020/dp30
youngyangyang04 May 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion problems/0019.删除链表的倒数第N个节点.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

分为如下几步:

* 首先这里我推荐大家使用虚拟头结点,这样方面处理删除实际头结点的逻辑,如果虚拟头结点不清楚,可以看这篇: [链表:听说用虚拟头节点会方便很多?](https://programmercarl.com/0203.移除链表元素.html)
* 首先这里我推荐大家使用虚拟头结点,这样方便处理删除实际头结点的逻辑,如果虚拟头结点不清楚,可以看这篇: [链表:听说用虚拟头节点会方便很多?](https://programmercarl.com/0203.移除链表元素.html)

* 定义fast指针和slow指针,初始值为虚拟头结点,如图:

Expand Down
2 changes: 1 addition & 1 deletion problems/0027.移除元素.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public:

**双指针法(快慢指针法)在数组和链表的操作中是非常常见的,很多考察数组、链表、字符串等操作的面试题,都使用双指针法。**

后序都会一一介绍到,本题代码如下:
后续都会一一介绍到,本题代码如下:

```CPP
// 时间复杂度:O(n)
Expand Down
120 changes: 120 additions & 0 deletions problems/0112.路径总和.md
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,126 @@ func traversal(_ cur: TreeNode?, count: Int) {
}
```

## C
> 0112.路径总和
递归法:
```c
bool hasPathSum(struct TreeNode* root, int targetSum){
// 递归结束条件:若当前节点不存在,返回false
if(!root)
return false;
// 若当前节点为叶子节点,且targetSum-root的值为0。(当前路径上的节点值的和满足条件)返回true
if(!root->right && !root->left && targetSum == root->val)
return true;

// 查看左子树和右子树的所有节点是否满足条件
return hasPathSum(root->right, targetSum - root->val) || hasPathSum(root->left, targetSum - root->val);
}
```

迭代法:
```c
// 存储一个节点以及当前的和
struct Pair {
struct TreeNode* node;
int sum;
};

bool hasPathSum(struct TreeNode* root, int targetSum){
struct Pair stack[1000];
int stackTop = 0;

// 若root存在,则将节点和值封装成一个pair入栈
if(root) {
struct Pair newPair = {root, root->val};
stack[stackTop++] = newPair;
}

// 当栈不为空时
while(stackTop) {
// 出栈栈顶元素
struct Pair topPair = stack[--stackTop];
// 若栈顶元素为叶子节点,且和为targetSum时,返回true
if(!topPair.node->left && !topPair.node->right && topPair.sum == targetSum)
return true;

// 若当前栈顶节点有左右孩子,计算和并入栈
if(topPair.node->left) {
struct Pair newPair = {topPair.node->left, topPair.sum + topPair.node->left->val};
stack[stackTop++] = newPair;
}
if(topPair.node->right) {
struct Pair newPair = {topPair.node->right, topPair.sum + topPair.node->right->val};
stack[stackTop++] = newPair;
}
}
return false;
}
```
> 0113.路径总和 II
```c
int** ret;
int* path;
int* colSize;
int retTop;
int pathTop;

void traversal(const struct TreeNode* const node, int count) {
// 若当前节点为叶子节点
if(!node->right && !node->left) {
// 若当前path上的节点值总和等于targetSum。
if(count == 0) {
// 复制当前path
int *curPath = (int*)malloc(sizeof(int) * pathTop);
memcpy(curPath, path, sizeof(int) * pathTop);
// 记录当前path的长度为pathTop
colSize[retTop] = pathTop;
// 将当前path加入到ret数组中
ret[retTop++] = curPath;
}
return;
}

// 若节点有左/右孩子
if(node->left) {
// 将左孩子的值加入path中
path[pathTop++] = node->left->val;
traversal(node->left, count - node->left->val);
// 回溯
pathTop--;
}
if(node->right) {
// 将右孩子的值加入path中
path[pathTop++] = node->right->val;
traversal(node->right, count - node->right->val);
// 回溯
--pathTop;
}
}

int** pathSum(struct TreeNode* root, int targetSum, int* returnSize, int** returnColumnSizes){
// 初始化数组
ret = (int**)malloc(sizeof(int*) * 1000);
path = (int*)malloc(sizeof(int*) * 1000);
colSize = (int*)malloc(sizeof(int) * 1000);
retTop = pathTop = 0;
*returnSize = 0;

// 若根节点不存在,返回空的ret
if(!root)
return ret;
// 将根节点加入到path中
path[pathTop++] = root->val;
traversal(root, targetSum - root->val);

// 设置返回ret数组大小,以及其中每个一维数组元素的长度
*returnSize = retTop;
*returnColumnSizes = colSize;

return ret;
}
```



-----------------------
Expand Down
23 changes: 23 additions & 0 deletions problems/0198.打家劫舍.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,29 @@ const rob = nums => {
};
```

TypeScript:

```typescript
function rob(nums: number[]): number {
/**
dp[i]: 前i个房屋能偷到的最大金额
dp[0]: nums[0];
dp[1]: max(nums[0], nums[1]);
...
dp[i]: max(dp[i-1], dp[i-2]+nums[i]);
*/
const length: number = nums.length;
if (length === 1) return nums[0];
const dp: number[] = [];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for (let i = 2; i < length; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[length - 1];
};
```




Expand Down
48 changes: 48 additions & 0 deletions problems/0209.长度最小的子数组.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,54 @@ class Solution {
}
}
```
Scala:

滑动窗口:
```scala
object Solution {
def minSubArrayLen(target: Int, nums: Array[Int]): Int = {
var result = Int.MaxValue // 返回结果,默认最大值
var left = 0 // 慢指针,当sum>=target,向右移动
var sum = 0 // 窗口值的总和
for (right <- 0 until nums.length) {
sum += nums(right)
while (sum >= target) {
result = math.min(result, right - left + 1) // 产生新结果
sum -= nums(left) // 左指针移动,窗口总和减去左指针的值
left += 1 // 左指针向右移动
}
}
// 相当于三元运算符,return关键字可以省略
if (result == Int.MaxValue) 0 else result
}
}
```

暴力解法:
```scala
object Solution {
def minSubArrayLen(target: Int, nums: Array[Int]): Int = {
import scala.util.control.Breaks
var res = Int.MaxValue
var subLength = 0
for (i <- 0 until nums.length) {
var sum = 0
Breaks.breakable(
for (j <- i until nums.length) {
sum += nums(j)
if (sum >= target) {
subLength = j - i + 1
res = math.min(subLength, res)
Breaks.break()
}
}
)
}
// 相当于三元运算符
if (res == Int.MaxValue) 0 else res
}
}
```

-----------------------
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
23 changes: 23 additions & 0 deletions problems/0213.打家劫舍II.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,30 @@ const robRange = (nums, start, end) => {
return dp[end]
}
```
TypeScript:

```typescript
function rob(nums: number[]): number {
const length: number = nums.length;
if (length === 0) return 0;
if (length === 1) return nums[0];
return Math.max(robRange(nums, 0, length - 2),
robRange(nums, 1, length - 1));
};
function robRange(nums: number[], start: number, end: number): number {
if (start === end) return nums[start];
const dp: number[] = [];
dp[start] = nums[start];
dp[start + 1] = Math.max(nums[start], nums[start + 1]);
for (let i = start + 2; i <= end; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[end];
}
```

Go:

```go
// 打家劫舍Ⅱ 动态规划
// 时间复杂度O(n) 空间复杂度O(n)
Expand Down
102 changes: 102 additions & 0 deletions problems/0416.分割等和子集.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,108 @@ var canPartition = function(nums) {
};
```


C:
二维dp:
```c
/**
1. dp数组含义:dp[i][j]为背包重量为j时,从[0-i]元素和最大值
2. 递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i])
3. 初始化:dp[i][0]初始化为0。因为背包重量为0时,不可能放入元素。dp[0][j] = nums[0],当j >= nums[0] && j < target时
4. 遍历顺序:先遍历物品,再遍历背包
*/
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

int getSum(int* nums, int numsSize) {
int sum = 0;

int i;
for(i = 0; i < numsSize; ++i) {
sum += nums[i];
}
return sum;
}

bool canPartition(int* nums, int numsSize){
// 求出元素总和
int sum = getSum(nums, numsSize);
// 若元素总和为奇数,则不可能得到两个和相等的子数组
if(sum % 2)
return false;

// 若子数组的和等于target,则nums可以被分割
int target = sum / 2;
// 初始化dp数组
int dp[numsSize][target + 1];
// dp[j][0]都应被设置为0。因为当背包重量为0时,不可放入元素
memset(dp, 0, sizeof(int) * numsSize * (target + 1));

int i, j;
// 当背包重量j大于nums[0]时,可以在dp[0][j]中放入元素nums[0]
for(j = nums[0]; j <= target; ++j) {
dp[0][j] = nums[0];
}

for(i = 1; i < numsSize; ++i) {
for(j = 1; j <= target; ++j) {
// 若当前背包重量j小于nums[i],则其值等于只考虑0到i-1物品时的值
if(j < nums[i])
dp[i][j] = dp[i - 1][j];
// 否则,背包重量等于在背包中放入num[i]/不放入nums[i]的较大值
else
dp[i][j] = MAX(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i]);
}
}
// 判断背包重量为target,且考虑到所有物品时,放入的元素和是否等于target
return dp[numsSize - 1][target] == target;
}
```
滚动数组:
```c
/**
1. dp数组含义:dp[j]为背包重量为j时,其中可放入元素的最大值
2. 递推公式:dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
3. 初始化:均初始化为0即可
4. 遍历顺序:先遍历物品,再后序遍历背包
*/
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

int getSum(int* nums, int numsSize) {
int sum = 0;

int i;
for(i = 0; i < numsSize; ++i) {
sum += nums[i];
}
return sum;
}

bool canPartition(int* nums, int numsSize){
// 求出元素总和
int sum = getSum(nums, numsSize);
// 若元素总和为奇数,则不可能得到两个和相等的子数组
if(sum % 2)
return false;
// 背包容量
int target = sum / 2;

// 初始化dp数组,元素均为0
int dp[target + 1];
memset(dp, 0, sizeof(int) * (target + 1));

int i, j;
// 先遍历物品,后遍历背包
for(i = 0; i < numsSize; ++i) {
for(j = target; j >= nums[i]; --j) {
dp[j] = MAX(dp[j], dp[j - nums[i]] + nums[i]);
}
}

// 查看背包容量为target时,元素总和是否等于target
return dp[target] == target;
}
```

TypeScript:

> 一维数组,简洁
Expand Down
2 changes: 1 addition & 1 deletion problems/0701.二叉搜索树中的插入操作.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ class Solution:
root.right = self.insertIntoBST(root.right, val)

# 返回更新后的以当前root为根节点的新树
return roo
return root
```

**递归法** - 无返回值
Expand Down
Loading