mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-10 20:40:39 +08:00
Merge branch 'master' into master
This commit is contained in:
@ -5,10 +5,11 @@
|
|||||||
|
|
||||||
> 1. **介绍**:本项目是一套完整的刷题计划,旨在帮助大家少走弯路,循序渐进学算法,[关注作者](#关于作者)
|
> 1. **介绍**:本项目是一套完整的刷题计划,旨在帮助大家少走弯路,循序渐进学算法,[关注作者](#关于作者)
|
||||||
> 2. **PDF版本** : [「代码随想录」算法精讲 PDF 版本](https://programmercarl.com/other/algo_pdf.html) 。
|
> 2. **PDF版本** : [「代码随想录」算法精讲 PDF 版本](https://programmercarl.com/other/algo_pdf.html) 。
|
||||||
> 3. **刷题顺序** : README已经将刷题顺序排好了,按照顺序一道一道刷就可以。
|
> 3. **最强八股文:**:[代码随想录知识星球精华PDF](https://www.programmercarl.com/other/kstar_baguwen.html)
|
||||||
> 4. **学习社区** : 一起学习打卡/面试技巧/如何选择offer/大厂内推/职场规则/简历修改/技术分享/程序人生。欢迎加入[「代码随想录」知识星球](https://programmercarl.com/other/kstar.html) 。
|
> 4. **刷题顺序** : README已经将刷题顺序排好了,按照顺序一道一道刷就可以。
|
||||||
> 5. **提交代码**:本项目统一使用C++语言进行讲解,但已经有Java、Python、Go、JavaScript等等多语言版本,感谢[这里的每一位贡献者](https://github.com/youngyangyang04/leetcode-master/graphs/contributors),如果你也想贡献代码点亮你的头像,[点击这里](https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A)了解提交代码的方式。
|
> 5. **学习社区** : 一起学习打卡/面试技巧/如何选择offer/大厂内推/职场规则/简历修改/技术分享/程序人生。欢迎加入[「代码随想录」知识星球](https://programmercarl.com/other/kstar.html) 。
|
||||||
> 6. **转载须知** :以下所有文章皆为我([程序员Carl](https://github.com/youngyangyang04))的原创。引用本项目文章请注明出处,发现恶意抄袭或搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!
|
> 6. **提交代码**:本项目统一使用C++语言进行讲解,但已经有Java、Python、Go、JavaScript等等多语言版本,感谢[这里的每一位贡献者](https://github.com/youngyangyang04/leetcode-master/graphs/contributors),如果你也想贡献代码点亮你的头像,[点击这里](https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A)了解提交代码的方式。
|
||||||
|
> 7. **转载须知** :以下所有文章皆为我([程序员Carl](https://github.com/youngyangyang04))的原创。引用本项目文章请注明出处,发现恶意抄袭或搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境!
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="programmercarl.com" target="_blank">
|
<a href="programmercarl.com" target="_blank">
|
||||||
|
@ -142,6 +142,7 @@ public:
|
|||||||
|
|
||||||
### Java
|
### Java
|
||||||
```Java
|
```Java
|
||||||
|
// 版本一
|
||||||
class Solution {
|
class Solution {
|
||||||
public int jump(int[] nums) {
|
public int jump(int[] nums) {
|
||||||
if (nums == null || nums.length == 0 || nums.length == 1) {
|
if (nums == null || nums.length == 0 || nums.length == 1) {
|
||||||
@ -172,7 +173,30 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 版本二
|
||||||
|
class Solution {
|
||||||
|
public int jump(int[] nums) {
|
||||||
|
int result = 0;
|
||||||
|
// 当前覆盖的最远距离下标
|
||||||
|
int end = 0;
|
||||||
|
// 下一步覆盖的最远距离下标
|
||||||
|
int temp = 0;
|
||||||
|
for (int i = 0; i <= end && end < nums.length - 1; ++i) {
|
||||||
|
temp = Math.max(temp, i + nums[i]);
|
||||||
|
// 可达位置的改变次数就是跳跃次数
|
||||||
|
if (i == end) {
|
||||||
|
end = temp;
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Python
|
### Python
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
def jump(self, nums: List[int]) -> int:
|
def jump(self, nums: List[int]) -> int:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||||
|
|
||||||
## 63. 不同路径 II
|
# 63. 不同路径 II
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode-cn.com/problems/unique-paths-ii/)
|
[力扣题目链接](https://leetcode-cn.com/problems/unique-paths-ii/)
|
||||||
|
|
||||||
@ -22,23 +22,22 @@
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
|
* 输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
|
||||||
输出:2
|
* 输出:2
|
||||||
解释:
|
解释:
|
||||||
3x3 网格的正中间有一个障碍物。
|
* 3x3 网格的正中间有一个障碍物。
|
||||||
从左上角到右下角一共有 2 条不同的路径:
|
* 从左上角到右下角一共有 2 条不同的路径:
|
||||||
1. 向右 -> 向右 -> 向下 -> 向下
|
1. 向右 -> 向右 -> 向下 -> 向下
|
||||||
2. 向下 -> 向下 -> 向右 -> 向右
|
2. 向下 -> 向下 -> 向右 -> 向右
|
||||||
|
|
||||||
示例 2:
|
示例 2:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
输入:obstacleGrid = [[0,1],[0,0]]
|
* 输入:obstacleGrid = [[0,1],[0,0]]
|
||||||
输出:1
|
* 输出:1
|
||||||
|
|
||||||
提示:
|
提示:
|
||||||
|
|
||||||
* m == obstacleGrid.length
|
* m == obstacleGrid.length
|
||||||
* n == obstacleGrid[i].length
|
* n == obstacleGrid[i].length
|
||||||
* 1 <= m, n <= 100
|
* 1 <= m, n <= 100
|
||||||
@ -171,7 +170,7 @@ public:
|
|||||||
|
|
||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
Java:
|
### Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
class Solution {
|
class Solution {
|
||||||
@ -199,7 +198,7 @@ class Solution {
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Python:
|
### Python
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
@ -262,7 +261,7 @@ class Solution:
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Go:
|
### Go
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func uniquePathsWithObstacles(obstacleGrid [][]int) int {
|
func uniquePathsWithObstacles(obstacleGrid [][]int) int {
|
||||||
@ -295,8 +294,8 @@ func uniquePathsWithObstacles(obstacleGrid [][]int) int {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Javascript
|
### Javascript
|
||||||
``` Javascript
|
```Javascript
|
||||||
var uniquePathsWithObstacles = function(obstacleGrid) {
|
var uniquePathsWithObstacles = function(obstacleGrid) {
|
||||||
const m = obstacleGrid.length
|
const m = obstacleGrid.length
|
||||||
const n = obstacleGrid[0].length
|
const n = obstacleGrid[0].length
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||||
|
|
||||||
## 96.不同的二叉搜索树
|
# 96.不同的二叉搜索树
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode-cn.com/problems/unique-binary-search-trees/)
|
[力扣题目链接](https://leetcode-cn.com/problems/unique-binary-search-trees/)
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ public:
|
|||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
|
|
||||||
Java:
|
### Java
|
||||||
```Java
|
```Java
|
||||||
class Solution {
|
class Solution {
|
||||||
public int numTrees(int n) {
|
public int numTrees(int n) {
|
||||||
@ -184,7 +184,7 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
### Python
|
||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
def numTrees(self, n: int) -> int:
|
def numTrees(self, n: int) -> int:
|
||||||
@ -196,7 +196,7 @@ class Solution:
|
|||||||
return dp[-1]
|
return dp[-1]
|
||||||
```
|
```
|
||||||
|
|
||||||
Go:
|
### Go
|
||||||
```Go
|
```Go
|
||||||
func numTrees(n int)int{
|
func numTrees(n int)int{
|
||||||
dp:=make([]int,n+1)
|
dp:=make([]int,n+1)
|
||||||
@ -210,7 +210,7 @@ func numTrees(n int)int{
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Javascript:
|
### Javascript
|
||||||
```Javascript
|
```Javascript
|
||||||
const numTrees =(n) => {
|
const numTrees =(n) => {
|
||||||
let dp = new Array(n+1).fill(0);
|
let dp = new Array(n+1).fill(0);
|
||||||
|
@ -574,6 +574,75 @@ var isSymmetric = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TypeScript:
|
||||||
|
|
||||||
|
> 递归法
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function isSymmetric(root: TreeNode | null): boolean {
|
||||||
|
function recur(node1: TreeNode | null, node2: TreeNode | null): boolean {
|
||||||
|
if (node1 === null && node2 === null) return true;
|
||||||
|
if (node1 === null || node2 === null) return false;
|
||||||
|
if (node1.val !== node2.val) return false
|
||||||
|
let isSym1: boolean = recur(node1.left, node2.right);
|
||||||
|
let isSym2: boolean = recur(node1.right, node2.left);
|
||||||
|
return isSym1 && isSym2
|
||||||
|
}
|
||||||
|
if (root === null) return true;
|
||||||
|
return recur(root.left, root.right);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> 迭代法
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 迭代法(队列)
|
||||||
|
function isSymmetric(root: TreeNode | null): boolean {
|
||||||
|
let helperQueue: (TreeNode | null)[] = [];
|
||||||
|
let tempNode1: TreeNode | null,
|
||||||
|
tempNode2: TreeNode | null;
|
||||||
|
if (root !== null) {
|
||||||
|
helperQueue.push(root.left);
|
||||||
|
helperQueue.push(root.right);
|
||||||
|
}
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
tempNode1 = helperQueue.shift()!;
|
||||||
|
tempNode2 = helperQueue.shift()!;
|
||||||
|
if (tempNode1 === null && tempNode2 === null) continue;
|
||||||
|
if (tempNode1 === null || tempNode2 === null) return false;
|
||||||
|
if (tempNode1.val !== tempNode2.val) return false;
|
||||||
|
helperQueue.push(tempNode1.left);
|
||||||
|
helperQueue.push(tempNode2.right);
|
||||||
|
helperQueue.push(tempNode1.right);
|
||||||
|
helperQueue.push(tempNode2.left);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 迭代法(栈)
|
||||||
|
function isSymmetric(root: TreeNode | null): boolean {
|
||||||
|
let helperStack: (TreeNode | null)[] = [];
|
||||||
|
let tempNode1: TreeNode | null,
|
||||||
|
tempNode2: TreeNode | null;
|
||||||
|
if (root !== null) {
|
||||||
|
helperStack.push(root.left);
|
||||||
|
helperStack.push(root.right);
|
||||||
|
}
|
||||||
|
while (helperStack.length > 0) {
|
||||||
|
tempNode1 = helperStack.pop()!;
|
||||||
|
tempNode2 = helperStack.pop()!;
|
||||||
|
if (tempNode1 === null && tempNode2 === null) continue;
|
||||||
|
if (tempNode1 === null || tempNode2 === null) return false;
|
||||||
|
if (tempNode1.val !== tempNode2.val) return false;
|
||||||
|
helperStack.push(tempNode1.left);
|
||||||
|
helperStack.push(tempNode2.right);
|
||||||
|
helperStack.push(tempNode1.right);
|
||||||
|
helperStack.push(tempNode2.left);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## Swift:
|
## Swift:
|
||||||
|
|
||||||
> 递归
|
> 递归
|
||||||
|
@ -246,7 +246,35 @@ var levelOrder = function(root) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function levelOrder(root: TreeNode | null): number[][] {
|
||||||
|
let helperQueue: TreeNode[] = [];
|
||||||
|
let res: number[][] = [];
|
||||||
|
let tempArr: number[] = [];
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
let curNode: TreeNode;
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
curNode = helperQueue.shift()!;
|
||||||
|
tempArr.push(curNode.val);
|
||||||
|
if (curNode.left !== null) {
|
||||||
|
helperQueue.push(curNode.left);
|
||||||
|
}
|
||||||
|
if (curNode.right !== null) {
|
||||||
|
helperQueue.push(curNode.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.push(tempArr);
|
||||||
|
tempArr = [];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
func levelOrder(_ root: TreeNode?) -> [[Int]] {
|
func levelOrder(_ root: TreeNode?) -> [[Int]] {
|
||||||
var res = [[Int]]()
|
var res = [[Int]]()
|
||||||
@ -454,7 +482,31 @@ var levelOrderBottom = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function levelOrderBottom(root: TreeNode | null): number[][] {
|
||||||
|
let helperQueue: TreeNode[] = [];
|
||||||
|
let resArr: number[][] = [];
|
||||||
|
let tempArr: number[] = [];
|
||||||
|
let tempNode: TreeNode;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
tempNode = helperQueue.shift()!;
|
||||||
|
tempArr.push(tempNode.val);
|
||||||
|
if (tempNode.left !== null) helperQueue.push(tempNode.left);
|
||||||
|
if (tempNode.right !== null) helperQueue.push(tempNode.right);
|
||||||
|
}
|
||||||
|
resArr.push(tempArr);
|
||||||
|
tempArr = [];
|
||||||
|
}
|
||||||
|
return resArr.reverse();
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
func levelOrderBottom(_ root: TreeNode?) -> [[Int]] {
|
func levelOrderBottom(_ root: TreeNode?) -> [[Int]] {
|
||||||
var res = [[Int]]()
|
var res = [[Int]]()
|
||||||
@ -657,7 +709,28 @@ var rightSideView = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function rightSideView(root: TreeNode | null): number[] {
|
||||||
|
let helperQueue: TreeNode[] = [];
|
||||||
|
let resArr: number[] = [];
|
||||||
|
let tempNode: TreeNode;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
tempNode = helperQueue.shift()!;
|
||||||
|
if (i === length - 1) resArr.push(tempNode.val);
|
||||||
|
if (tempNode.left !== null) helperQueue.push(tempNode.left);
|
||||||
|
if (tempNode.right !== null) helperQueue.push(tempNode.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resArr;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
func rightSideView(_ root: TreeNode?) -> [Int] {
|
func rightSideView(_ root: TreeNode?) -> [Int] {
|
||||||
var res = [Int]()
|
var res = [Int]()
|
||||||
@ -868,7 +941,32 @@ var averageOfLevels = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function averageOfLevels(root: TreeNode | null): number[] {
|
||||||
|
let helperQueue: TreeNode[] = [];
|
||||||
|
let resArr: number[] = [];
|
||||||
|
let total: number = 0;
|
||||||
|
let tempNode: TreeNode;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
let length = helperQueue.length;
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
tempNode = helperQueue.shift()!;
|
||||||
|
total += tempNode.val;
|
||||||
|
if (tempNode.left) helperQueue.push(tempNode.left);
|
||||||
|
if (tempNode.right) helperQueue.push(tempNode.right);
|
||||||
|
}
|
||||||
|
resArr.push(total / length);
|
||||||
|
total = 0;
|
||||||
|
}
|
||||||
|
return resArr;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
func averageOfLevels(_ root: TreeNode?) -> [Double] {
|
func averageOfLevels(_ root: TreeNode?) -> [Double] {
|
||||||
var res = [Double]()
|
var res = [Double]()
|
||||||
@ -1092,7 +1190,30 @@ var levelOrder = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function levelOrder(root: Node | null): number[][] {
|
||||||
|
let helperQueue: Node[] = [];
|
||||||
|
let resArr: number[][] = [];
|
||||||
|
let tempArr: number[] = [];
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
let curNode: Node;
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
curNode = helperQueue.shift()!;
|
||||||
|
tempArr.push(curNode.val);
|
||||||
|
helperQueue.push(...curNode.children);
|
||||||
|
}
|
||||||
|
resArr.push(tempArr);
|
||||||
|
tempArr = [];
|
||||||
|
}
|
||||||
|
return resArr;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
func levelOrder(_ root: Node?) -> [[Int]] {
|
func levelOrder(_ root: Node?) -> [[Int]] {
|
||||||
var res = [[Int]]()
|
var res = [[Int]]()
|
||||||
@ -1272,7 +1393,34 @@ var largestValues = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function largestValues(root: TreeNode | null): number[] {
|
||||||
|
let helperQueue: TreeNode[] = [];
|
||||||
|
let resArr: number[] = [];
|
||||||
|
let tempNode: TreeNode;
|
||||||
|
let max: number = 0;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
tempNode = helperQueue.shift()!;
|
||||||
|
if (i === 0) {
|
||||||
|
max = tempNode.val;
|
||||||
|
} else {
|
||||||
|
max = max > tempNode.val ? max : tempNode.val;
|
||||||
|
}
|
||||||
|
if (tempNode.left) helperQueue.push(tempNode.left);
|
||||||
|
if (tempNode.right) helperQueue.push(tempNode.right);
|
||||||
|
}
|
||||||
|
resArr.push(max);
|
||||||
|
}
|
||||||
|
return resArr;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
func largestValues(_ root: TreeNode?) -> [Int] {
|
func largestValues(_ root: TreeNode?) -> [Int] {
|
||||||
var res = [Int]()
|
var res = [Int]()
|
||||||
@ -1463,6 +1611,31 @@ var connect = function(root) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
```
|
```
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function connect(root: Node | null): Node | null {
|
||||||
|
let helperQueue: Node[] = [];
|
||||||
|
let preNode: Node, curNode: Node;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
if (i === 0) {
|
||||||
|
preNode = helperQueue.shift()!;
|
||||||
|
} else {
|
||||||
|
curNode = helperQueue.shift()!;
|
||||||
|
preNode.next = curNode;
|
||||||
|
preNode = curNode;
|
||||||
|
}
|
||||||
|
if (preNode.left) helperQueue.push(preNode.left);
|
||||||
|
if (preNode.right) helperQueue.push(preNode.right);
|
||||||
|
}
|
||||||
|
preNode.next = null;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
go:
|
go:
|
||||||
|
|
||||||
```GO
|
```GO
|
||||||
@ -1689,6 +1862,31 @@ var connect = function(root) {
|
|||||||
return root;
|
return root;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function connect(root: Node | null): Node | null {
|
||||||
|
let helperQueue: Node[] = [];
|
||||||
|
let preNode: Node, curNode: Node;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
if (i === 0) {
|
||||||
|
preNode = helperQueue.shift()!;
|
||||||
|
} else {
|
||||||
|
curNode = helperQueue.shift()!;
|
||||||
|
preNode.next = curNode;
|
||||||
|
preNode = curNode;
|
||||||
|
}
|
||||||
|
if (preNode.left) helperQueue.push(preNode.left);
|
||||||
|
if (preNode.right) helperQueue.push(preNode.right);
|
||||||
|
}
|
||||||
|
preNode.next = null;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
go:
|
go:
|
||||||
|
|
||||||
```GO
|
```GO
|
||||||
@ -1933,7 +2131,28 @@ var maxDepth = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function maxDepth(root: TreeNode | null): number {
|
||||||
|
let helperQueue: TreeNode[] = [];
|
||||||
|
let resDepth: number = 0;
|
||||||
|
let tempNode: TreeNode;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
resDepth++;
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
tempNode = helperQueue.shift()!;
|
||||||
|
if (tempNode.left) helperQueue.push(tempNode.left);
|
||||||
|
if (tempNode.right) helperQueue.push(tempNode.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resDepth;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
func maxDepth(_ root: TreeNode?) -> Int {
|
func maxDepth(_ root: TreeNode?) -> Int {
|
||||||
guard let root = root else {
|
guard let root = root else {
|
||||||
@ -2130,7 +2349,29 @@ var minDepth = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function minDepth(root: TreeNode | null): number {
|
||||||
|
let helperQueue: TreeNode[] = [];
|
||||||
|
let resMin: number = 0;
|
||||||
|
let tempNode: TreeNode;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
resMin++;
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
tempNode = helperQueue.shift()!;
|
||||||
|
if (tempNode.left === null && tempNode.right === null) return resMin;
|
||||||
|
if (tempNode.left !== null) helperQueue.push(tempNode.left);
|
||||||
|
if (tempNode.right !== null) helperQueue.push(tempNode.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resMin;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
func minDepth(_ root: TreeNode?) -> Int {
|
func minDepth(_ root: TreeNode?) -> Int {
|
||||||
guard let root = root else {
|
guard let root = root else {
|
||||||
|
@ -598,7 +598,81 @@ var maxDepth = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TypeScript:
|
||||||
|
|
||||||
|
> 二叉树的最大深度:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 后续遍历(自下而上)
|
||||||
|
function maxDepth(root: TreeNode | null): number {
|
||||||
|
if (root === null) return 0;
|
||||||
|
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 前序遍历(自上而下)
|
||||||
|
function maxDepth(root: TreeNode | null): number {
|
||||||
|
function recur(node: TreeNode | null, count: number) {
|
||||||
|
if (node === null) {
|
||||||
|
resMax = resMax > count ? resMax : count;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
recur(node.left, count + 1);
|
||||||
|
recur(node.right, count + 1);
|
||||||
|
}
|
||||||
|
let resMax: number = 0;
|
||||||
|
let count: number = 0;
|
||||||
|
recur(root, count);
|
||||||
|
return resMax;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 层序遍历(迭代法)
|
||||||
|
function maxDepth(root: TreeNode | null): number {
|
||||||
|
let helperQueue: TreeNode[] = [];
|
||||||
|
let resDepth: number = 0;
|
||||||
|
let tempNode: TreeNode;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
resDepth++;
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
tempNode = helperQueue.shift()!;
|
||||||
|
if (tempNode.left) helperQueue.push(tempNode.left);
|
||||||
|
if (tempNode.right) helperQueue.push(tempNode.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resDepth;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> N叉树的最大深度
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 后续遍历(自下而上)
|
||||||
|
function maxDepth(root: TreeNode | null): number {
|
||||||
|
if (root === null) return 0;
|
||||||
|
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 前序遍历(自上而下)
|
||||||
|
function maxDepth(root: TreeNode | null): number {
|
||||||
|
function recur(node: TreeNode | null, count: number) {
|
||||||
|
if (node === null) {
|
||||||
|
resMax = resMax > count ? resMax : count;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
recur(node.left, count + 1);
|
||||||
|
recur(node.right, count + 1);
|
||||||
|
}
|
||||||
|
let resMax: number = 0;
|
||||||
|
let count: number = 0;
|
||||||
|
recur(root, count);
|
||||||
|
return resMax;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## C
|
## C
|
||||||
|
|
||||||
二叉树最大深度递归
|
二叉树最大深度递归
|
||||||
```c
|
```c
|
||||||
int maxDepth(struct TreeNode* root){
|
int maxDepth(struct TreeNode* root){
|
||||||
|
@ -670,7 +670,26 @@ var isBalanced = function (root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TypeScript
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 递归法
|
||||||
|
function isBalanced(root: TreeNode | null): boolean {
|
||||||
|
function getDepth(root: TreeNode | null): number {
|
||||||
|
if (root === null) return 0;
|
||||||
|
let leftDepth: number = getDepth(root.left);
|
||||||
|
if (leftDepth === -1) return -1;
|
||||||
|
let rightDepth: number = getDepth(root.right);
|
||||||
|
if (rightDepth === -1) return -1;
|
||||||
|
if (Math.abs(leftDepth - rightDepth) > 1) return -1;
|
||||||
|
return 1 + Math.max(leftDepth, rightDepth);
|
||||||
|
}
|
||||||
|
return getDepth(root) !== -1;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## C
|
## C
|
||||||
|
|
||||||
递归法:
|
递归法:
|
||||||
```c
|
```c
|
||||||
int getDepth(struct TreeNode* node) {
|
int getDepth(struct TreeNode* node) {
|
||||||
|
@ -404,6 +404,44 @@ var minDepth = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TypeScript
|
||||||
|
|
||||||
|
> 递归法
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function minDepth(root: TreeNode | null): number {
|
||||||
|
if (root === null) return 0;
|
||||||
|
if (root.left !== null && root.right === null) {
|
||||||
|
return 1 + minDepth(root.left);
|
||||||
|
}
|
||||||
|
if (root.left === null && root.right !== null) {
|
||||||
|
return 1 + minDepth(root.right);
|
||||||
|
}
|
||||||
|
return 1 + Math.min(minDepth(root.left), minDepth(root.right));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 迭代法
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function minDepth(root: TreeNode | null): number {
|
||||||
|
let helperQueue: TreeNode[] = [];
|
||||||
|
let resMin: number = 0;
|
||||||
|
let tempNode: TreeNode;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
resMin++;
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
tempNode = helperQueue.shift()!;
|
||||||
|
if (tempNode.left === null && tempNode.right === null) return resMin;
|
||||||
|
if (tempNode.left !== null) helperQueue.push(tempNode.left);
|
||||||
|
if (tempNode.right !== null) helperQueue.push(tempNode.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resMin;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## Swift
|
## Swift
|
||||||
|
|
||||||
> 递归
|
> 递归
|
||||||
|
@ -531,82 +531,63 @@ class solution:
|
|||||||
```go
|
```go
|
||||||
//递归法
|
//递归法
|
||||||
/**
|
/**
|
||||||
* definition for a binary tree node.
|
* Definition for a binary tree node.
|
||||||
* type treenode struct {
|
* type TreeNode struct {
|
||||||
* val int
|
* Val int
|
||||||
* left *treenode
|
* Left *TreeNode
|
||||||
* right *treenode
|
* Right *TreeNode
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
func haspathsum(root *treenode, targetsum int) bool {
|
func hasPathSum(root *TreeNode, targetSum int) bool {
|
||||||
var flage bool //找没找到的标志
|
if root == nil {
|
||||||
if root==nil{
|
return false
|
||||||
return flage
|
|
||||||
}
|
}
|
||||||
pathsum(root,0,targetsum,&flage)
|
|
||||||
return flage
|
targetSum -= root.Val // 将targetSum在遍历每层的时候都减去本层节点的值
|
||||||
}
|
if root.Left == nil && root.Right == nil && targetSum == 0 { // 如果剩余的targetSum为0, 则正好就是符合的结果
|
||||||
func pathsum(root *treenode, sum int,targetsum int,flage *bool){
|
return true
|
||||||
sum+=root.val
|
|
||||||
if root.left==nil&&root.right==nil&&sum==targetsum{
|
|
||||||
*flage=true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if root.left!=nil&&!(*flage){//左节点不为空且还没找到
|
|
||||||
pathsum(root.left,sum,targetsum,flage)
|
|
||||||
}
|
|
||||||
if root.right!=nil&&!(*flage){//右节点不为空且没找到
|
|
||||||
pathsum(root.right,sum,targetsum,flage)
|
|
||||||
}
|
}
|
||||||
|
return hasPathSum(root.Left, targetSum) || hasPathSum(root.Right, targetSum) // 否则递归找
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
113 递归法
|
113. 路径总和 II
|
||||||
|
|
||||||
```go
|
```go
|
||||||
/**
|
/**
|
||||||
* definition for a binary tree node.
|
* Definition for a binary tree node.
|
||||||
* type treenode struct {
|
* type TreeNode struct {
|
||||||
* val int
|
* Val int
|
||||||
* left *treenode
|
* Left *TreeNode
|
||||||
* right *treenode
|
* Right *TreeNode
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
func pathsum(root *treenode, targetsum int) [][]int {
|
func pathSum(root *TreeNode, targetSum int) [][]int {
|
||||||
var result [][]int//最终结果
|
result := make([][]int, 0)
|
||||||
if root==nil{
|
traverse(root, &result, new([]int), targetSum)
|
||||||
return result
|
|
||||||
}
|
|
||||||
var sumnodes []int//经过路径的节点集合
|
|
||||||
haspathsum(root,&sumnodes,targetsum,&result)
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
func haspathsum(root *treenode,sumnodes *[]int,targetsum int,result *[][]int){
|
|
||||||
*sumnodes=append(*sumnodes,root.val)
|
func traverse(node *TreeNode, result *[][]int, currPath *[]int, targetSum int) {
|
||||||
if root.left==nil&&root.right==nil{//叶子节点
|
if node == nil { // 这个判空也可以挪到递归遍历左右子树时去判断
|
||||||
fmt.println(*sumnodes)
|
return
|
||||||
var sum int
|
|
||||||
var number int
|
|
||||||
for k,v:=range *sumnodes{//求该路径节点的和
|
|
||||||
sum+=v
|
|
||||||
number=k
|
|
||||||
}
|
}
|
||||||
tempnodes:=make([]int,number+1)//新的nodes接受指针里的值,防止最终指针里的值发生变动,导致最后的结果都是最后一个sumnodes的值
|
|
||||||
for k,v:=range *sumnodes{
|
targetSum -= node.Val // 将targetSum在遍历每层的时候都减去本层节点的值
|
||||||
tempnodes[k]=v
|
*currPath = append(*currPath, node.Val) // 把当前节点放到路径记录里
|
||||||
|
|
||||||
|
if node.Left == nil && node.Right == nil && targetSum == 0 { // 如果剩余的targetSum为0, 则正好就是符合的结果
|
||||||
|
// 不能直接将currPath放到result里面, 因为currPath是共享的, 每次遍历子树时都会被修改
|
||||||
|
pathCopy := make([]int, len(*currPath))
|
||||||
|
for i, element := range *currPath {
|
||||||
|
pathCopy[i] = element
|
||||||
}
|
}
|
||||||
if sum==targetsum{
|
*result = append(*result, pathCopy) // 将副本放到结果集里
|
||||||
*result=append(*result,tempnodes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if root.left!=nil{
|
|
||||||
haspathsum(root.left,sumnodes,targetsum,result)
|
|
||||||
*sumnodes=(*sumnodes)[:len(*sumnodes)-1]//回溯
|
|
||||||
}
|
|
||||||
if root.right!=nil{
|
|
||||||
haspathsum(root.right,sumnodes,targetsum,result)
|
|
||||||
*sumnodes=(*sumnodes)[:len(*sumnodes)-1]//回溯
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
traverse(node.Left, result, currPath, targetSum)
|
||||||
|
traverse(node.Right, result, currPath, targetSum)
|
||||||
|
*currPath = (*currPath)[:len(*currPath)-1] // 当前节点遍历完成, 从路径记录里删除掉
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -248,6 +248,36 @@ class Solution {
|
|||||||
return valid[s.length()];
|
return valid[s.length()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 回溯法+记忆化
|
||||||
|
class Solution {
|
||||||
|
public boolean wordBreak(String s, List<String> wordDict) {
|
||||||
|
Set<String> wordDictSet = new HashSet(wordDict);
|
||||||
|
int[] memory = new int[s.length()];
|
||||||
|
return backTrack(s, wordDictSet, 0, memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean backTrack(String s, Set<String> wordDictSet, int startIndex, int[] memory) {
|
||||||
|
// 结束条件
|
||||||
|
if (startIndex >= s.length()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (memory[startIndex] != 0) {
|
||||||
|
// 此处认为:memory[i] = 1 表示可以拼出i 及以后的字符子串, memory[i] = -1 表示不能
|
||||||
|
return memory[startIndex] == 1 ? true : false;
|
||||||
|
}
|
||||||
|
for (int i = startIndex; i < s.length(); ++i) {
|
||||||
|
// 处理 递归 回溯 循环不变量:[startIndex, i + 1)
|
||||||
|
String word = s.substring(startIndex, i + 1);
|
||||||
|
if (wordDictSet.contains(word) && backTrack(s, wordDictSet, i + 1, memory)) {
|
||||||
|
memory[startIndex] = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memory[startIndex] = -1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
@ -210,6 +210,71 @@ var evalRPN = function(tokens) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
普通版:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function evalRPN(tokens: string[]): number {
|
||||||
|
let helperStack: number[] = [];
|
||||||
|
let temp: number;
|
||||||
|
let i: number = 0;
|
||||||
|
while (i < tokens.length) {
|
||||||
|
let t: string = tokens[i];
|
||||||
|
switch (t) {
|
||||||
|
case '+':
|
||||||
|
temp = helperStack.pop()! + helperStack.pop()!;
|
||||||
|
helperStack.push(temp);
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
temp = helperStack.pop()!;
|
||||||
|
temp = helperStack.pop()! - temp;
|
||||||
|
helperStack.push(temp);
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
temp = helperStack.pop()! * helperStack.pop()!;
|
||||||
|
helperStack.push(temp);
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
temp = helperStack.pop()!;
|
||||||
|
temp = Math.trunc(helperStack.pop()! / temp);
|
||||||
|
helperStack.push(temp);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
helperStack.push(Number(t));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return helperStack.pop()!;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
优化版:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function evalRPN(tokens: string[]): number {
|
||||||
|
const helperStack: number[] = [];
|
||||||
|
const operatorMap: Map<string, (a: number, b: number) => number> = new Map([
|
||||||
|
['+', (a, b) => a + b],
|
||||||
|
['-', (a, b) => a - b],
|
||||||
|
['/', (a, b) => Math.trunc(a / b)],
|
||||||
|
['*', (a, b) => a * b],
|
||||||
|
]);
|
||||||
|
let a: number, b: number;
|
||||||
|
for (let t of tokens) {
|
||||||
|
if (operatorMap.has(t)) {
|
||||||
|
b = helperStack.pop()!;
|
||||||
|
a = helperStack.pop()!;
|
||||||
|
helperStack.push(operatorMap.get(t)!(a, b));
|
||||||
|
} else {
|
||||||
|
helperStack.push(Number(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return helperStack.pop()!;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
python3
|
python3
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
@ -447,7 +447,63 @@ var countNodes = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## TypeScrpt:
|
||||||
|
|
||||||
|
> 递归法
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function countNodes(root: TreeNode | null): number {
|
||||||
|
if (root === null) return 0;
|
||||||
|
return 1 + countNodes(root.left) + countNodes(root.right);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> 迭代法
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function countNodes(root: TreeNode | null): number {
|
||||||
|
let helperQueue: TreeNode[] = [];
|
||||||
|
let resCount: number = 0;
|
||||||
|
let tempNode: TreeNode;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
tempNode = helperQueue.shift()!;
|
||||||
|
resCount++;
|
||||||
|
if (tempNode.left) helperQueue.push(tempNode.left);
|
||||||
|
if (tempNode.right) helperQueue.push(tempNode.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resCount;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
> 利用完全二叉树性质
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function countNodes(root: TreeNode | null): number {
|
||||||
|
if (root === null) return 0;
|
||||||
|
let left: number = 0,
|
||||||
|
right: number = 0;
|
||||||
|
let curNode: TreeNode | null= root;
|
||||||
|
while (curNode !== null) {
|
||||||
|
left++;
|
||||||
|
curNode = curNode.left;
|
||||||
|
}
|
||||||
|
curNode = root;
|
||||||
|
while (curNode !== null) {
|
||||||
|
right++;
|
||||||
|
curNode = curNode.right;
|
||||||
|
}
|
||||||
|
if (left === right) {
|
||||||
|
return 2 ** left - 1;
|
||||||
|
}
|
||||||
|
return 1 + countNodes(root.left) + countNodes(root.right);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
## C:
|
## C:
|
||||||
|
|
||||||
递归法
|
递归法
|
||||||
```c
|
```c
|
||||||
int countNodes(struct TreeNode* root) {
|
int countNodes(struct TreeNode* root) {
|
||||||
|
@ -563,7 +563,135 @@ var invertTree = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### TypeScript:
|
||||||
|
|
||||||
|
递归法:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 递归法(前序遍历)
|
||||||
|
function invertTree(root: TreeNode | null): TreeNode | null {
|
||||||
|
if (root === null) return root;
|
||||||
|
let tempNode: TreeNode | null = root.left;
|
||||||
|
root.left = root.right;
|
||||||
|
root.right = tempNode;
|
||||||
|
invertTree(root.left);
|
||||||
|
invertTree(root.right);
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 递归法(后序遍历)
|
||||||
|
function invertTree(root: TreeNode | null): TreeNode | null {
|
||||||
|
if (root === null) return root;
|
||||||
|
invertTree(root.left);
|
||||||
|
invertTree(root.right);
|
||||||
|
let tempNode: TreeNode | null = root.left;
|
||||||
|
root.left = root.right;
|
||||||
|
root.right = tempNode;
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 递归法(中序遍历)
|
||||||
|
function invertTree(root: TreeNode | null): TreeNode | null {
|
||||||
|
if (root === null) return root;
|
||||||
|
invertTree(root.left);
|
||||||
|
let tempNode: TreeNode | null = root.left;
|
||||||
|
root.left = root.right;
|
||||||
|
root.right = tempNode;
|
||||||
|
// 因为左右节点已经进行交换,此时的root.left 是原先的root.right
|
||||||
|
invertTree(root.left);
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
迭代法:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 迭代法(栈模拟前序遍历)
|
||||||
|
function invertTree(root: TreeNode | null): TreeNode | null {
|
||||||
|
let helperStack: TreeNode[] = [];
|
||||||
|
let curNode: TreeNode,
|
||||||
|
tempNode: TreeNode | null;
|
||||||
|
if (root !== null) helperStack.push(root);
|
||||||
|
while (helperStack.length > 0) {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
// 入栈操作最好在交换节点之前进行,便于理解
|
||||||
|
if (curNode.right) helperStack.push(curNode.right);
|
||||||
|
if (curNode.left) helperStack.push(curNode.left);
|
||||||
|
tempNode = curNode.left;
|
||||||
|
curNode.left = curNode.right;
|
||||||
|
curNode.right = tempNode;
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 迭代法(栈模拟中序遍历-统一写法形式)
|
||||||
|
function invertTree(root: TreeNode | null): TreeNode | null {
|
||||||
|
let helperStack: (TreeNode | null)[] = [];
|
||||||
|
let curNode: TreeNode | null,
|
||||||
|
tempNode: TreeNode | null;
|
||||||
|
if (root !== null) helperStack.push(root);
|
||||||
|
while (helperStack.length > 0) {
|
||||||
|
curNode = helperStack.pop();
|
||||||
|
if (curNode !== null) {
|
||||||
|
if (curNode.right !== null) helperStack.push(curNode.right);
|
||||||
|
helperStack.push(curNode);
|
||||||
|
helperStack.push(null);
|
||||||
|
if (curNode.left !== null) helperStack.push(curNode.left);
|
||||||
|
} else {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
tempNode = curNode.left;
|
||||||
|
curNode.left = curNode.right;
|
||||||
|
curNode.right = tempNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 迭代法(栈模拟后序遍历-统一写法形式)
|
||||||
|
function invertTree(root: TreeNode | null): TreeNode | null {
|
||||||
|
let helperStack: (TreeNode | null)[] = [];
|
||||||
|
let curNode: TreeNode | null,
|
||||||
|
tempNode: TreeNode | null;
|
||||||
|
if (root !== null) helperStack.push(root);
|
||||||
|
while (helperStack.length > 0) {
|
||||||
|
curNode = helperStack.pop();
|
||||||
|
if (curNode !== null) {
|
||||||
|
helperStack.push(curNode);
|
||||||
|
helperStack.push(null);
|
||||||
|
if (curNode.right !== null) helperStack.push(curNode.right);
|
||||||
|
if (curNode.left !== null) helperStack.push(curNode.left);
|
||||||
|
} else {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
tempNode = curNode.left;
|
||||||
|
curNode.left = curNode.right;
|
||||||
|
curNode.right = tempNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 迭代法(队列模拟层序遍历)
|
||||||
|
function invertTree(root: TreeNode | null): TreeNode | null {
|
||||||
|
const helperQueue: TreeNode[] = [];
|
||||||
|
let curNode: TreeNode,
|
||||||
|
tempNode: TreeNode | null;
|
||||||
|
if (root !== null) helperQueue.push(root);
|
||||||
|
while (helperQueue.length > 0) {
|
||||||
|
for (let i = 0, length = helperQueue.length; i < length; i++) {
|
||||||
|
curNode = helperQueue.shift()!;
|
||||||
|
tempNode = curNode.left;
|
||||||
|
curNode.left = curNode.right;
|
||||||
|
curNode.right = tempNode;
|
||||||
|
if (curNode.left !== null) helperQueue.push(curNode.left);
|
||||||
|
if (curNode.right !== null) helperQueue.push(curNode.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
### C:
|
### C:
|
||||||
|
|
||||||
递归法
|
递归法
|
||||||
```c
|
```c
|
||||||
struct TreeNode* invertTree(struct TreeNode* root){
|
struct TreeNode* invertTree(struct TreeNode* root){
|
||||||
|
@ -348,7 +348,44 @@ MyQueue.prototype.empty = function() {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class MyQueue {
|
||||||
|
private stackIn: number[]
|
||||||
|
private stackOut: number[]
|
||||||
|
constructor() {
|
||||||
|
this.stackIn = [];
|
||||||
|
this.stackOut = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
push(x: number): void {
|
||||||
|
this.stackIn.push(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
pop(): number {
|
||||||
|
if (this.stackOut.length === 0) {
|
||||||
|
while (this.stackIn.length > 0) {
|
||||||
|
this.stackOut.push(this.stackIn.pop()!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.stackOut.pop()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
peek(): number {
|
||||||
|
let temp: number = this.pop();
|
||||||
|
this.stackOut.push(temp);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
empty(): boolean {
|
||||||
|
return this.stackIn.length === 0 && this.stackOut.length === 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
class MyQueue {
|
class MyQueue {
|
||||||
|
|
||||||
|
@ -395,30 +395,102 @@ func maxSlidingWindow(nums []int, k int) []int {
|
|||||||
|
|
||||||
Javascript:
|
Javascript:
|
||||||
```javascript
|
```javascript
|
||||||
|
/**
|
||||||
|
* @param {number[]} nums
|
||||||
|
* @param {number} k
|
||||||
|
* @return {number[]}
|
||||||
|
*/
|
||||||
var maxSlidingWindow = function (nums, k) {
|
var maxSlidingWindow = function (nums, k) {
|
||||||
// 队列数组(存放的是元素下标,为了取值方便)
|
class MonoQueue {
|
||||||
const q = [];
|
queue;
|
||||||
// 结果数组
|
constructor() {
|
||||||
const ans = [];
|
this.queue = [];
|
||||||
for (let i = 0; i < nums.length; i++) {
|
|
||||||
// 若队列不为空,且当前元素大于等于队尾所存下标的元素,则弹出队尾
|
|
||||||
while (q.length && nums[i] >= nums[q[q.length - 1]]) {
|
|
||||||
q.pop();
|
|
||||||
}
|
}
|
||||||
// 入队当前元素下标
|
enqueue(value) {
|
||||||
q.push(i);
|
let back = this.queue[this.queue.length - 1];
|
||||||
// 判断当前最大值(即队首元素)是否在窗口中,若不在便将其出队
|
while (back !== undefined && back < value) {
|
||||||
if (q[0] <= i - k) {
|
this.queue.pop();
|
||||||
q.shift();
|
back = this.queue[this.queue.length - 1];
|
||||||
}
|
}
|
||||||
// 当达到窗口大小时便开始向结果中添加数据
|
this.queue.push(value);
|
||||||
if (i >= k - 1) ans.push(nums[q[0]]);
|
|
||||||
}
|
}
|
||||||
return ans;
|
dequeue(value) {
|
||||||
|
let front = this.front();
|
||||||
|
if (front === value) {
|
||||||
|
this.queue.shift();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
front() {
|
||||||
|
return this.queue[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let helperQueue = new MonoQueue();
|
||||||
|
let i = 0, j = 0;
|
||||||
|
let resArr = [];
|
||||||
|
while (j < k) {
|
||||||
|
helperQueue.enqueue(nums[j++]);
|
||||||
|
}
|
||||||
|
resArr.push(helperQueue.front());
|
||||||
|
while (j < nums.length) {
|
||||||
|
helperQueue.enqueue(nums[j]);
|
||||||
|
helperQueue.dequeue(nums[i]);
|
||||||
|
resArr.push(helperQueue.front());
|
||||||
|
i++, j++;
|
||||||
|
}
|
||||||
|
return resArr;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function maxSlidingWindow(nums: number[], k: number): number[] {
|
||||||
|
/** 单调递减队列 */
|
||||||
|
class MonoQueue {
|
||||||
|
private queue: number[];
|
||||||
|
constructor() {
|
||||||
|
this.queue = [];
|
||||||
|
};
|
||||||
|
/** 入队:value如果大于队尾元素,则将队尾元素删除,直至队尾元素大于value,或者队列为空 */
|
||||||
|
public enqueue(value: number): void {
|
||||||
|
let back: number | undefined = this.queue[this.queue.length - 1];
|
||||||
|
while (back !== undefined && back < value) {
|
||||||
|
this.queue.pop();
|
||||||
|
back = this.queue[this.queue.length - 1];
|
||||||
|
}
|
||||||
|
this.queue.push(value);
|
||||||
|
};
|
||||||
|
/** 出队:只有当队头元素等于value,才出队 */
|
||||||
|
public dequeue(value: number): void {
|
||||||
|
let top: number | undefined = this.top();
|
||||||
|
if (top !== undefined && top === value) {
|
||||||
|
this.queue.shift();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public top(): number | undefined {
|
||||||
|
return this.queue[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const helperQueue: MonoQueue = new MonoQueue();
|
||||||
|
let i: number = 0,
|
||||||
|
j: number = 0;
|
||||||
|
let resArr: number[] = [];
|
||||||
|
while (j < k) {
|
||||||
|
helperQueue.enqueue(nums[j++]);
|
||||||
|
}
|
||||||
|
resArr.push(helperQueue.top()!);
|
||||||
|
while (j < nums.length) {
|
||||||
|
helperQueue.enqueue(nums[j]);
|
||||||
|
helperQueue.dequeue(nums[i]);
|
||||||
|
resArr.push(helperQueue.top()!);
|
||||||
|
j++, i++;
|
||||||
|
}
|
||||||
|
return resArr;
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```Swift
|
```Swift
|
||||||
/// 双向链表
|
/// 双向链表
|
||||||
class DoublyListNode {
|
class DoublyListNode {
|
||||||
|
@ -4,23 +4,22 @@
|
|||||||
</a>
|
</a>
|
||||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||||
|
|
||||||
## 343. 整数拆分
|
# 343. 整数拆分
|
||||||
|
|
||||||
[力扣题目链接](https://leetcode-cn.com/problems/integer-break/)
|
[力扣题目链接](https://leetcode-cn.com/problems/integer-break/)
|
||||||
|
|
||||||
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
|
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
|
||||||
|
|
||||||
示例 1:
|
示例 1:
|
||||||
输入: 2
|
* 输入: 2
|
||||||
输出: 1
|
* 输出: 1
|
||||||
|
* 解释: 2 = 1 + 1, 1 × 1 = 1。
|
||||||
\解释: 2 = 1 + 1, 1 × 1 = 1。
|
|
||||||
|
|
||||||
示例 2:
|
示例 2:
|
||||||
输入: 10
|
* 输入: 10
|
||||||
输出: 36
|
* 输出: 36
|
||||||
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
|
* 解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
|
||||||
说明: 你可以假设 n 不小于 2 且不大于 58。
|
* 说明: 你可以假设 n 不小于 2 且不大于 58。
|
||||||
|
|
||||||
## 思路
|
## 思路
|
||||||
|
|
||||||
@ -193,7 +192,7 @@ public:
|
|||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
|
|
||||||
Java:
|
### Java
|
||||||
```Java
|
```Java
|
||||||
class Solution {
|
class Solution {
|
||||||
public int integerBreak(int n) {
|
public int integerBreak(int n) {
|
||||||
@ -212,7 +211,7 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
### Python
|
||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
def integerBreak(self, n: int) -> int:
|
def integerBreak(self, n: int) -> int:
|
||||||
@ -226,7 +225,8 @@ class Solution:
|
|||||||
dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]))
|
dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]))
|
||||||
return dp[n]
|
return dp[n]
|
||||||
```
|
```
|
||||||
Go:
|
|
||||||
|
### Go
|
||||||
```golang
|
```golang
|
||||||
func integerBreak(n int) int {
|
func integerBreak(n int) int {
|
||||||
/**
|
/**
|
||||||
@ -256,7 +256,7 @@ func max(a,b int) int{
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Javascript:
|
### Javascript
|
||||||
```Javascript
|
```Javascript
|
||||||
var integerBreak = function(n) {
|
var integerBreak = function(n) {
|
||||||
let dp = new Array(n + 1).fill(0)
|
let dp = new Array(n + 1).fill(0)
|
||||||
|
@ -358,6 +358,22 @@ PriorityQueue.prototype.compare = function(index1, index2) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function topKFrequent(nums: number[], k: number): number[] {
|
||||||
|
const countMap: Map<number, number> = new Map();
|
||||||
|
for (let num of nums) {
|
||||||
|
countMap.set(num, (countMap.get(num) || 0) + 1);
|
||||||
|
}
|
||||||
|
// tS没有最小堆的数据结构,所以直接对整个数组进行排序,取前k个元素
|
||||||
|
return [...countMap.entries()]
|
||||||
|
.sort((a, b) => b[1] - a[1])
|
||||||
|
.slice(0, k)
|
||||||
|
.map(i => i[0]);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
|
@ -174,7 +174,7 @@ public:
|
|||||||
```Java
|
```Java
|
||||||
class Solution {
|
class Solution {
|
||||||
public int wiggleMaxLength(int[] nums) {
|
public int wiggleMaxLength(int[] nums) {
|
||||||
if (nums == null || nums.length <= 1) {
|
if (nums.length <= 1) {
|
||||||
return nums.length;
|
return nums.length;
|
||||||
}
|
}
|
||||||
//当前差值
|
//当前差值
|
||||||
|
@ -210,6 +210,45 @@ class Solution {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
二维数组版本(易于理解):
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public boolean canPartition(int[] nums) {
|
||||||
|
int sum = 0;
|
||||||
|
for (int i = 0; i < nums.length; i++) {
|
||||||
|
sum += nums[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sum % 2 == 1)
|
||||||
|
return false;
|
||||||
|
int target = sum / 2;
|
||||||
|
|
||||||
|
//dp[i][j]代表可装物品为0-i,背包容量为j的情况下,背包内容量的最大价值
|
||||||
|
int[][] dp = new int[nums.length][target + 1];
|
||||||
|
|
||||||
|
//初始化,dp[0][j]的最大价值nums[0](if j > weight[i])
|
||||||
|
//dp[i][0]均为0,不用初始化
|
||||||
|
for (int j = nums[0]; j <= target; j++) {
|
||||||
|
dp[0][j] = nums[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
//遍历物品,遍历背包
|
||||||
|
//递推公式:
|
||||||
|
for (int i = 1; i < nums.length; i++) {
|
||||||
|
for (int j = 0; j <= target; j++) {
|
||||||
|
//背包容量可以容纳nums[i]
|
||||||
|
if (j >= nums[i]) {
|
||||||
|
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - nums[i]] + nums[i]);
|
||||||
|
} else {
|
||||||
|
dp[i][j] = dp[i - 1][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[nums.length - 1][target] == target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
Python:
|
Python:
|
||||||
```python
|
```python
|
||||||
class Solution:
|
class Solution:
|
||||||
|
@ -183,28 +183,22 @@ public:
|
|||||||
```java
|
```java
|
||||||
class Solution {
|
class Solution {
|
||||||
public int eraseOverlapIntervals(int[][] intervals) {
|
public int eraseOverlapIntervals(int[][] intervals) {
|
||||||
if (intervals.length < 2) return 0;
|
Arrays.sort(intervals, (a, b) -> {
|
||||||
|
if (a[0] == a[0]) return a[1] - b[1];
|
||||||
Arrays.sort(intervals, new Comparator<int[]>() {
|
return a[0] - b[0];
|
||||||
@Override
|
|
||||||
public int compare(int[] o1, int[] o2) {
|
|
||||||
if (o1[1] != o2[1]) {
|
|
||||||
return Integer.compare(o1[1],o2[1]);
|
|
||||||
} else {
|
|
||||||
return Integer.compare(o1[0],o2[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
int count = 1;
|
int count = 0;
|
||||||
int edge = intervals[0][1];
|
int edge = Integer.MIN_VALUE;
|
||||||
for (int i = 1; i < intervals.length; i++) {
|
for (int i = 0; i < intervals.length; i++) {
|
||||||
if (edge <= intervals[i][0]){
|
if (edge <= intervals[i][0]) {
|
||||||
count ++; //non overlap + 1
|
|
||||||
edge = intervals[i][1];
|
edge = intervals[i][1];
|
||||||
|
} else {
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return intervals.length - count;
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -272,7 +272,8 @@ Python:
|
|||||||
class Solution:
|
class Solution:
|
||||||
def findTargetSumWays(self, nums: List[int], target: int) -> int:
|
def findTargetSumWays(self, nums: List[int], target: int) -> int:
|
||||||
sumValue = sum(nums)
|
sumValue = sum(nums)
|
||||||
if target > sumValue or (sumValue + target) % 2 == 1: return 0
|
#注意边界条件为 target>sumValue or target<-sumValue or (sumValue + target) % 2 == 1
|
||||||
|
if abs(target) > sumValue or (sumValue + target) % 2 == 1: return 0
|
||||||
bagSize = (sumValue + target) // 2
|
bagSize = (sumValue + target) // 2
|
||||||
dp = [0] * (bagSize + 1)
|
dp = [0] * (bagSize + 1)
|
||||||
dp[0] = 1
|
dp[0] = 1
|
||||||
|
@ -267,8 +267,32 @@ var removeDuplicates = function(s) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
function removeDuplicates(s: string): string {
|
||||||
|
const helperStack: string[] = [];
|
||||||
|
let i: number = 0;
|
||||||
|
while (i < s.length) {
|
||||||
|
let top: string = helperStack[helperStack.length - 1];
|
||||||
|
if (top === s[i]) {
|
||||||
|
helperStack.pop();
|
||||||
|
} else {
|
||||||
|
helperStack.push(s[i]);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
let res: string = '';
|
||||||
|
while (helperStack.length > 0) {
|
||||||
|
res = helperStack.pop() + res;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
C:
|
C:
|
||||||
方法一:使用栈
|
方法一:使用栈
|
||||||
|
|
||||||
```c
|
```c
|
||||||
char * removeDuplicates(char * s){
|
char * removeDuplicates(char * s){
|
||||||
//求出字符串长度
|
//求出字符串长度
|
||||||
|
@ -153,6 +153,8 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
|
||||||
|
一维数组版本
|
||||||
```Java
|
```Java
|
||||||
class Solution {
|
class Solution {
|
||||||
public int lastStoneWeightII(int[] stones) {
|
public int lastStoneWeightII(int[] stones) {
|
||||||
@ -173,6 +175,41 @@ class Solution {
|
|||||||
return sum - 2 * dp[target];
|
return sum - 2 * dp[target];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
二维数组版本(便于理解)
|
||||||
|
```Java
|
||||||
|
class Solution {
|
||||||
|
public int lastStoneWeightII(int[] stones) {
|
||||||
|
int sum = 0;
|
||||||
|
for (int s : stones) {
|
||||||
|
sum += s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int target = sum / 2;
|
||||||
|
//初始化,dp[i][j]为可以放0-i物品,背包容量为j的情况下背包中的最大价值
|
||||||
|
int[][] dp = new int[stones.length][target + 1];
|
||||||
|
//dp[i][0]默认初始化为0
|
||||||
|
//dp[0][j]取决于stones[0]
|
||||||
|
for (int j = stones[0]; j <= target; j++) {
|
||||||
|
dp[0][j] = stones[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < stones.length; i++) {
|
||||||
|
for (int j = 1; j <= target; j++) {//注意是等于
|
||||||
|
if (j >= stones[i]) {
|
||||||
|
//不放:dp[i - 1][j] 放:dp[i - 1][j - stones[i]] + stones[i]
|
||||||
|
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - stones[i]] + stones[i]);
|
||||||
|
} else {
|
||||||
|
dp[i][j] = dp[i - 1][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println(dp[stones.length - 1][target]);
|
||||||
|
return (sum - dp[stones.length - 1][target]) - dp[stones.length - 1][target];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
@ -227,7 +227,23 @@ function TreeNode(val, left, right) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class TreeNode {
|
||||||
|
public val: number;
|
||||||
|
public left: TreeNode | null;
|
||||||
|
public right: TreeNode | null;
|
||||||
|
constructor(val?: number, left?: TreeNode, right?: TreeNode) {
|
||||||
|
this.val = val === undefined ? 0 : val;
|
||||||
|
this.left = left === undefined ? null : left;
|
||||||
|
this.right = right === undefined ? null : right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
```Swift
|
```Swift
|
||||||
class TreeNode<T> {
|
class TreeNode<T> {
|
||||||
var value: T
|
var value: T
|
||||||
|
@ -522,7 +522,75 @@ var postorderTraversal = function(root, res = []) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 前序遍历(迭代法)
|
||||||
|
function preorderTraversal(root: TreeNode | null): number[] {
|
||||||
|
let helperStack: (TreeNode | null)[] = [];
|
||||||
|
let res: number[] = [];
|
||||||
|
let curNode: TreeNode | null;
|
||||||
|
if (root === null) return res;
|
||||||
|
helperStack.push(root);
|
||||||
|
while (helperStack.length > 0) {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
if (curNode !== null) {
|
||||||
|
if (curNode.right !== null) helperStack.push(curNode.right);
|
||||||
|
helperStack.push(curNode);
|
||||||
|
helperStack.push(null);
|
||||||
|
if (curNode.left !== null) helperStack.push(curNode.left);
|
||||||
|
} else {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
res.push(curNode.val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 中序遍历(迭代法)
|
||||||
|
function inorderTraversal(root: TreeNode | null): number[] {
|
||||||
|
let helperStack: (TreeNode | null)[] = [];
|
||||||
|
let res: number[] = [];
|
||||||
|
let curNode: TreeNode | null;
|
||||||
|
if (root === null) return res;
|
||||||
|
helperStack.push(root);
|
||||||
|
while (helperStack.length > 0) {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
if (curNode !== null) {
|
||||||
|
if (curNode.right !== null) helperStack.push(curNode.right);
|
||||||
|
helperStack.push(curNode);
|
||||||
|
helperStack.push(null);
|
||||||
|
if (curNode.left !== null) helperStack.push(curNode.left);
|
||||||
|
} else {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
res.push(curNode.val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 后序遍历(迭代法)
|
||||||
|
function postorderTraversal(root: TreeNode | null): number[] {
|
||||||
|
let helperStack: (TreeNode | null)[] = [];
|
||||||
|
let res: number[] = [];
|
||||||
|
let curNode: TreeNode | null;
|
||||||
|
if (root === null) return res;
|
||||||
|
helperStack.push(root);
|
||||||
|
while (helperStack.length > 0) {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
if (curNode !== null) {
|
||||||
|
if (curNode.right !== null) helperStack.push(curNode.right);
|
||||||
|
helperStack.push(curNode);
|
||||||
|
helperStack.push(null);
|
||||||
|
if (curNode.left !== null) helperStack.push(curNode.left);
|
||||||
|
} else {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
res.push(curNode.val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>
|
||||||
|
@ -454,6 +454,61 @@ var postorderTraversal = function(root, res = []) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 前序遍历(迭代法)
|
||||||
|
function preorderTraversal(root: TreeNode | null): number[] {
|
||||||
|
if (root === null) return [];
|
||||||
|
let res: number[] = [];
|
||||||
|
let helperStack: TreeNode[] = [];
|
||||||
|
let curNode: TreeNode = root;
|
||||||
|
helperStack.push(curNode);
|
||||||
|
while (helperStack.length > 0) {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
res.push(curNode.val);
|
||||||
|
if (curNode.right !== null) helperStack.push(curNode.right);
|
||||||
|
if (curNode.left !== null) helperStack.push(curNode.left);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 中序遍历(迭代法)
|
||||||
|
function inorderTraversal(root: TreeNode | null): number[] {
|
||||||
|
let helperStack: TreeNode[] = [];
|
||||||
|
let res: number[] = [];
|
||||||
|
if (root === null) return res;
|
||||||
|
let curNode: TreeNode | null = root;
|
||||||
|
while (curNode !== null || helperStack.length > 0) {
|
||||||
|
if (curNode !== null) {
|
||||||
|
helperStack.push(curNode);
|
||||||
|
curNode = curNode.left;
|
||||||
|
} else {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
res.push(curNode.val);
|
||||||
|
curNode = curNode.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 后序遍历(迭代法)
|
||||||
|
function postorderTraversal(root: TreeNode | null): number[] {
|
||||||
|
let helperStack: TreeNode[] = [];
|
||||||
|
let res: number[] = [];
|
||||||
|
let curNode: TreeNode;
|
||||||
|
if (root === null) return res;
|
||||||
|
helperStack.push(root);
|
||||||
|
while (helperStack.length > 0) {
|
||||||
|
curNode = helperStack.pop()!;
|
||||||
|
res.push(curNode.val);
|
||||||
|
if (curNode.left !== null) helperStack.push(curNode.left);
|
||||||
|
if (curNode.right !== null) helperStack.push(curNode.right);
|
||||||
|
}
|
||||||
|
return res.reverse();
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
Swift:
|
Swift:
|
||||||
|
|
||||||
> 迭代法前序遍历
|
> 迭代法前序遍历
|
||||||
|
@ -270,40 +270,6 @@ func postorderTraversal(root *TreeNode) (res []int) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
javaScript:
|
|
||||||
|
|
||||||
```js
|
|
||||||
|
|
||||||
前序遍历:
|
|
||||||
|
|
||||||
var preorderTraversal = function(root, res = []) {
|
|
||||||
if (!root) return res;
|
|
||||||
res.push(root.val);
|
|
||||||
preorderTraversal(root.left, res)
|
|
||||||
preorderTraversal(root.right, res)
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
中序遍历:
|
|
||||||
|
|
||||||
var inorderTraversal = function(root, res = []) {
|
|
||||||
if (!root) return res;
|
|
||||||
inorderTraversal(root.left, res);
|
|
||||||
res.push(root.val);
|
|
||||||
inorderTraversal(root.right, res);
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
后序遍历:
|
|
||||||
|
|
||||||
var postorderTraversal = function(root, res = []) {
|
|
||||||
if (!root) return res;
|
|
||||||
postorderTraversal(root.left, res);
|
|
||||||
postorderTraversal(root.right, res);
|
|
||||||
res.push(root.val);
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
```
|
|
||||||
Javascript版本:
|
Javascript版本:
|
||||||
|
|
||||||
前序遍历:
|
前序遍历:
|
||||||
@ -358,7 +324,51 @@ var postorderTraversal = function(root) {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
TypeScript:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 前序遍历
|
||||||
|
function preorderTraversal(node: TreeNode | null): number[] {
|
||||||
|
function traverse(node: TreeNode | null, res: number[]): void {
|
||||||
|
if (node === null) return;
|
||||||
|
res.push(node.val);
|
||||||
|
traverse(node.left, res);
|
||||||
|
traverse(node.right, res);
|
||||||
|
}
|
||||||
|
const res: number[] = [];
|
||||||
|
traverse(node, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 中序遍历
|
||||||
|
function inorderTraversal(node: TreeNode | null): number[] {
|
||||||
|
function traverse(node: TreeNode | null, res: number[]): void {
|
||||||
|
if (node === null) return;
|
||||||
|
traverse(node.left, res);
|
||||||
|
res.push(node.val);
|
||||||
|
traverse(node.right, res);
|
||||||
|
}
|
||||||
|
const res: number[] = [];
|
||||||
|
traverse(node, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 后序遍历
|
||||||
|
function postorderTraversal(node: TreeNode | null): number[] {
|
||||||
|
function traverse(node: TreeNode | null, res: number[]): void {
|
||||||
|
if (node === null) return;
|
||||||
|
traverse(node.left, res);
|
||||||
|
traverse(node.right, res);
|
||||||
|
res.push(node.val);
|
||||||
|
}
|
||||||
|
const res: number[] = [];
|
||||||
|
traverse(node, res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
C:
|
C:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
//前序遍历:
|
//前序遍历:
|
||||||
void preOrderTraversal(struct TreeNode* root, int* ret, int* returnSize) {
|
void preOrderTraversal(struct TreeNode* root, int* ret, int* returnSize) {
|
||||||
|
@ -135,7 +135,6 @@ Markdown支持部分html,例如这样
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||||
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
<img src="https://code-thinking-1253855093.file.myqcloud.com/pics/20210924105952.png" width="1000"/>
|
<img src="https://code-thinking-1253855093.file.myqcloud.com/pics/20210924105952.png" width="1000"/>
|
||||||
</a>
|
</a>
|
||||||
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
|
||||||
|
|
||||||
# 动态规划:关于01背包问题,你该了解这些!
|
# 动态规划:关于01背包问题,你该了解这些!
|
||||||
|
|
||||||
这周我们正式开始讲解背包问题!
|
这周我们正式开始讲解背包问题!
|
||||||
|
|
||||||
背包问题的经典资料当然是:背包九讲。在公众号「代码随想录」后台回复:背包九讲,就可以获得背包九讲的PDF。
|
背包问题的经典资料当然是:背包九讲。在公众号「代码随想录」后台回复:背包九讲,就可以获得背包九讲的pdf。
|
||||||
|
|
||||||
但说实话,背包九讲对于小白来说确实不太友好,看起来还是有点费劲的,而且都是伪代码理解起来也吃力。
|
但说实话,背包九讲对于小白来说确实不太友好,看起来还是有点费劲的,而且都是伪代码理解起来也吃力。
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ leetcode上没有纯01背包的问题,都是01背包应用方面的题目,
|
|||||||
|
|
||||||
## 01 背包
|
## 01 背包
|
||||||
|
|
||||||
有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。**每件物品只能用一次**,求解将哪些物品装入背包里物品价值总和最大。
|
有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。**每件物品只能用一次**,求解将哪些物品装入背包里物品价值总和最大。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@ -40,7 +41,7 @@ leetcode上没有纯01背包的问题,都是01背包应用方面的题目,
|
|||||||
|
|
||||||
这样其实是没有从底向上去思考,而是习惯性想到了背包,那么暴力的解法应该是怎么样的呢?
|
这样其实是没有从底向上去思考,而是习惯性想到了背包,那么暴力的解法应该是怎么样的呢?
|
||||||
|
|
||||||
每一件物品其实只有两个状态,取或者不取,所以可以使用回溯法搜索出所有的情况,那么时间复杂度就是$O(2^n)$,这里的n表示物品数量。
|
每一件物品其实只有两个状态,取或者不取,所以可以使用回溯法搜索出所有的情况,那么时间复杂度就是$o(2^n)$,这里的n表示物品数量。
|
||||||
|
|
||||||
**所以暴力的解法是指数级别的时间复杂度。进而才需要动态规划的解法来进行优化!**
|
**所以暴力的解法是指数级别的时间复杂度。进而才需要动态规划的解法来进行优化!**
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ for (int j = 0 ; j < weight[0]; j++) { // 当然这一步,如果把dp数组
|
|||||||
dp[0][j] = 0;
|
dp[0][j] = 0;
|
||||||
}
|
}
|
||||||
// 正序遍历
|
// 正序遍历
|
||||||
for (int j = weight[0]; j <= bagWeight; j++) {
|
for (int j = weight[0]; j <= bagweight; j++) {
|
||||||
dp[0][j] = value[0];
|
dp[0][j] = value[0];
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -135,8 +136,8 @@ dp[0][j] 和 dp[i][0] 都已经初始化了,那么其他下标应该初始化
|
|||||||
|
|
||||||
```
|
```
|
||||||
// 初始化 dp
|
// 初始化 dp
|
||||||
vector<vector<int>> dp(weight.size(), vector<int>(bagWeight + 1, 0));
|
vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));
|
||||||
for (int j = weight[0]; j <= bagWeight; j++) {
|
for (int j = weight[0]; j <= bagweight; j++) {
|
||||||
dp[0][j] = value[0];
|
dp[0][j] = value[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +161,7 @@ for (int j = weight[0]; j <= bagWeight; j++) {
|
|||||||
```
|
```
|
||||||
// weight数组的大小 就是物品个数
|
// weight数组的大小 就是物品个数
|
||||||
for(int i = 1; i < weight.size(); i++) { // 遍历物品
|
for(int i = 1; i < weight.size(); i++) { // 遍历物品
|
||||||
for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量
|
for(int j = 0; j <= bagweight; j++) { // 遍历背包容量
|
||||||
if (j < weight[i]) dp[i][j] = dp[i - 1][j];
|
if (j < weight[i]) dp[i][j] = dp[i - 1][j];
|
||||||
else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
|
else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
|
||||||
|
|
||||||
@ -174,7 +175,7 @@ for(int i = 1; i < weight.size(); i++) { // 遍历物品
|
|||||||
|
|
||||||
```
|
```
|
||||||
// weight数组的大小 就是物品个数
|
// weight数组的大小 就是物品个数
|
||||||
for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量
|
for(int j = 0; j <= bagweight; j++) { // 遍历背包容量
|
||||||
for(int i = 1; i < weight.size(); i++) { // 遍历物品
|
for(int i = 1; i < weight.size(); i++) { // 遍历物品
|
||||||
if (j < weight[i]) dp[i][j] = dp[i - 1][j];
|
if (j < weight[i]) dp[i][j] = dp[i - 1][j];
|
||||||
else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
|
else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
|
||||||
@ -219,32 +220,32 @@ dp[i-1][j]和dp[i - 1][j - weight[i]] 都在dp[i][j]的左上角方向(包括
|
|||||||
主要就是自己没有动手推导一下dp数组的演变过程,如果推导明白了,代码写出来就算有问题,只要把dp数组打印出来,对比一下和自己推导的有什么差异,很快就可以发现问题了。
|
主要就是自己没有动手推导一下dp数组的演变过程,如果推导明白了,代码写出来就算有问题,只要把dp数组打印出来,对比一下和自己推导的有什么差异,很快就可以发现问题了。
|
||||||
|
|
||||||
|
|
||||||
## 完整C++测试代码
|
## 完整c++测试代码
|
||||||
|
|
||||||
```CPP
|
```cpp
|
||||||
void test_2_wei_bag_problem1() {
|
void test_2_wei_bag_problem1() {
|
||||||
vector<int> weight = {1, 3, 4};
|
vector<int> weight = {1, 3, 4};
|
||||||
vector<int> value = {15, 20, 30};
|
vector<int> value = {15, 20, 30};
|
||||||
int bagWeight = 4;
|
int bagweight = 4;
|
||||||
|
|
||||||
// 二维数组
|
// 二维数组
|
||||||
vector<vector<int>> dp(weight.size(), vector<int>(bagWeight + 1, 0));
|
vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
for (int j = weight[0]; j <= bagWeight; j++) {
|
for (int j = weight[0]; j <= bagweight; j++) {
|
||||||
dp[0][j] = value[0];
|
dp[0][j] = value[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// weight数组的大小 就是物品个数
|
// weight数组的大小 就是物品个数
|
||||||
for(int i = 1; i < weight.size(); i++) { // 遍历物品
|
for(int i = 1; i < weight.size(); i++) { // 遍历物品
|
||||||
for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量
|
for(int j = 0; j <= bagweight; j++) { // 遍历背包容量
|
||||||
if (j < weight[i]) dp[i][j] = dp[i - 1][j];
|
if (j < weight[i]) dp[i][j] = dp[i - 1][j];
|
||||||
else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
|
else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << dp[weight.size() - 1][bagWeight] << endl;
|
cout << dp[weight.size() - 1][bagweight] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
@ -267,48 +268,45 @@ int main() {
|
|||||||
|
|
||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
Java:
|
### java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static void main(String[] args) {
|
public static void main(string[] args) {
|
||||||
int[] weight = {1, 3, 4};
|
int[] weight = {1, 3, 4};
|
||||||
int[] value = {15, 20, 30};
|
int[] value = {15, 20, 30};
|
||||||
int bagSize = 4;
|
int bagsize = 4;
|
||||||
testWeightBagProblem(weight, value, bagSize);
|
testweightbagproblem(weight, value, bagsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void testWeightBagProblem(int[] weight, int[] value, int bagSize){
|
public static void testweightbagproblem(int[] weight, int[] value, int bagsize){
|
||||||
int wLen = weight.length, value0 = 0;
|
int wlen = weight.length, value0 = 0;
|
||||||
//定义dp数组:dp[i][j]表示背包容量为j时,前i个物品能获得的最大价值
|
//定义dp数组:dp[i][j]表示背包容量为j时,前i个物品能获得的最大价值
|
||||||
int[][] dp = new int[wLen + 1][bagSize + 1];
|
int[][] dp = new int[wlen + 1][bagsize + 1];
|
||||||
//初始化:背包容量为0时,能获得的价值都为0
|
//初始化:背包容量为0时,能获得的价值都为0
|
||||||
for (int i = 0; i <= wLen; i++){
|
for (int i = 0; i <= wlen; i++){
|
||||||
dp[i][0] = value0;
|
dp[i][0] = value0;
|
||||||
}
|
}
|
||||||
//遍历顺序:先遍历物品,再遍历背包容量
|
//遍历顺序:先遍历物品,再遍历背包容量
|
||||||
for (int i = 1; i <= wLen; i++){
|
for (int i = 1; i <= wlen; i++){
|
||||||
for (int j = 1; j <= bagSize; j++){
|
for (int j = 1; j <= bagsize; j++){
|
||||||
if (j < weight[i - 1]){
|
if (j < weight[i - 1]){
|
||||||
dp[i][j] = dp[i - 1][j];
|
dp[i][j] = dp[i - 1][j];
|
||||||
}else{
|
}else{
|
||||||
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i - 1]] + value[i - 1]);
|
dp[i][j] = math.max(dp[i - 1][j], dp[i - 1][j - weight[i - 1]] + value[i - 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//打印dp数组
|
//打印dp数组
|
||||||
for (int i = 0; i <= wLen; i++){
|
for (int i = 0; i <= wlen; i++){
|
||||||
for (int j = 0; j <= bagSize; j++){
|
for (int j = 0; j <= bagsize; j++){
|
||||||
System.out.print(dp[i][j] + " ");
|
system.out.print(dp[i][j] + " ");
|
||||||
}
|
}
|
||||||
System.out.print("\n");
|
system.out.print("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### python
|
||||||
|
|
||||||
|
|
||||||
Python:
|
|
||||||
```python
|
```python
|
||||||
def test_2_wei_bag_problem1(bag_size, weight, value) -> int:
|
def test_2_wei_bag_problem1(bag_size, weight, value) -> int:
|
||||||
rows, cols = len(weight), bag_size + 1
|
rows, cols = len(weight), bag_size + 1
|
||||||
@ -343,26 +341,26 @@ if __name__ == "__main__":
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Go:
|
### go
|
||||||
```go
|
```go
|
||||||
func test_2_wei_bag_problem1(weight, value []int, bagWeight int) int {
|
func test_2_wei_bag_problem1(weight, value []int, bagweight int) int {
|
||||||
// 定义dp数组
|
// 定义dp数组
|
||||||
dp := make([][]int, len(weight))
|
dp := make([][]int, len(weight))
|
||||||
for i, _ := range dp {
|
for i, _ := range dp {
|
||||||
dp[i] = make([]int, bagWeight+1)
|
dp[i] = make([]int, bagweight+1)
|
||||||
}
|
}
|
||||||
// 初始化
|
// 初始化
|
||||||
for j := bagWeight; j >= weight[0]; j-- {
|
for j := bagweight; j >= weight[0]; j-- {
|
||||||
dp[0][j] = dp[0][j-weight[0]] + value[0]
|
dp[0][j] = dp[0][j-weight[0]] + value[0]
|
||||||
}
|
}
|
||||||
// 递推公式
|
// 递推公式
|
||||||
for i := 1; i < len(weight); i++ {
|
for i := 1; i < len(weight); i++ {
|
||||||
//正序,也可以倒序
|
//正序,也可以倒序
|
||||||
for j := weight[i];j<= bagWeight ; j++ {
|
for j := weight[i];j<= bagweight ; j++ {
|
||||||
dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i])
|
dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dp[len(weight)-1][bagWeight]
|
return dp[len(weight)-1][bagweight]
|
||||||
}
|
}
|
||||||
|
|
||||||
func max(a,b int) int {
|
func max(a,b int) int {
|
||||||
@ -379,19 +377,19 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
javaScript:
|
### javascript
|
||||||
|
|
||||||
```js
|
```js
|
||||||
function testWeightBagProblem (wight, value, size) {
|
function testweightbagproblem (wight, value, size) {
|
||||||
const len = wight.length,
|
const len = wight.length,
|
||||||
dp = Array.from({length: len + 1}).map(
|
dp = array.from({length: len + 1}).map(
|
||||||
() => Array(size + 1).fill(0)
|
() => array(size + 1).fill(0)
|
||||||
);
|
);
|
||||||
|
|
||||||
for(let i = 1; i <= len; i++) {
|
for(let i = 1; i <= len; i++) {
|
||||||
for(let j = 0; j <= size; j++) {
|
for(let j = 0; j <= size; j++) {
|
||||||
if(wight[i - 1] <= j) {
|
if(wight[i - 1] <= j) {
|
||||||
dp[i][j] = Math.max(
|
dp[i][j] = math.max(
|
||||||
dp[i - 1][j],
|
dp[i - 1][j],
|
||||||
value[i - 1] + dp[i - 1][j - wight[i - 1]]
|
value[i - 1] + dp[i - 1][j - wight[i - 1]]
|
||||||
)
|
)
|
||||||
|
@ -210,7 +210,7 @@ int main() {
|
|||||||
|
|
||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
Java:
|
### Java
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
@ -240,7 +240,7 @@ Java:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Python:
|
### Python
|
||||||
```python
|
```python
|
||||||
def test_1_wei_bag_problem():
|
def test_1_wei_bag_problem():
|
||||||
weight = [1, 3, 4]
|
weight = [1, 3, 4]
|
||||||
@ -260,7 +260,7 @@ def test_1_wei_bag_problem():
|
|||||||
test_1_wei_bag_problem()
|
test_1_wei_bag_problem()
|
||||||
```
|
```
|
||||||
|
|
||||||
Go:
|
### Go
|
||||||
```go
|
```go
|
||||||
func test_1_wei_bag_problem(weight, value []int, bagWeight int) int {
|
func test_1_wei_bag_problem(weight, value []int, bagWeight int) int {
|
||||||
// 定义 and 初始化
|
// 定义 and 初始化
|
||||||
@ -292,7 +292,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
javaScript:
|
### javaScript
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
|
||||||
|
@ -183,13 +183,11 @@ private static void testCompletePack(){
|
|||||||
int[] value = {15, 20, 30};
|
int[] value = {15, 20, 30};
|
||||||
int bagWeight = 4;
|
int bagWeight = 4;
|
||||||
int[] dp = new int[bagWeight + 1];
|
int[] dp = new int[bagWeight + 1];
|
||||||
for (int i = 0; i < weight.length; i++){
|
for (int i = 0; i < weight.length; i++){ // 遍历物品
|
||||||
for (int j = 1; j <= bagWeight; j++){
|
for (int j = weight[i]; j <= bagWeight; j++){ // 遍历背包容量
|
||||||
if (j - weight[i] >= 0){
|
|
||||||
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
|
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (int maxValue : dp){
|
for (int maxValue : dp){
|
||||||
System.out.println(maxValue + " ");
|
System.out.println(maxValue + " ");
|
||||||
}
|
}
|
||||||
@ -201,8 +199,8 @@ private static void testCompletePackAnotherWay(){
|
|||||||
int[] value = {15, 20, 30};
|
int[] value = {15, 20, 30};
|
||||||
int bagWeight = 4;
|
int bagWeight = 4;
|
||||||
int[] dp = new int[bagWeight + 1];
|
int[] dp = new int[bagWeight + 1];
|
||||||
for (int i = 1; i <= bagWeight; i++){
|
for (int i = 1; i <= bagWeight; i++){ // 遍历背包容量
|
||||||
for (int j = 0; j < weight.length; j++){
|
for (int j = 0; j < weight.length; j++){ // 遍历物品
|
||||||
if (i - weight[j] >= 0){
|
if (i - weight[j] >= 0){
|
||||||
dp[i] = Math.max(dp[i], dp[i - weight[j]] + value[j]);
|
dp[i] = Math.max(dp[i], dp[i - weight[j]] + value[j]);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user