mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-09 19:44:45 +08:00
Merge branch 'master' into patch-28
This commit is contained in:
@ -17,6 +17,11 @@
|
|||||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||||
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ"><img src="https://img.shields.io/badge/知识星球-代码随想录-blue" alt=""></a>
|
||||||
</p>
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ" target="_blank">
|
||||||
|
<img src="./pics/知识星球.png" width="600"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
# LeetCode 刷题攻略
|
# LeetCode 刷题攻略
|
||||||
|
|
||||||
|
@ -193,40 +193,6 @@ public:
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
使用栈来模拟后序遍历依然可以
|
|
||||||
|
|
||||||
```C++
|
|
||||||
class Solution {
|
|
||||||
public:
|
|
||||||
int maxDepth(TreeNode* root) {
|
|
||||||
stack<TreeNode*> st;
|
|
||||||
if (root != NULL) st.push(root);
|
|
||||||
int depth = 0;
|
|
||||||
int result = 0;
|
|
||||||
while (!st.empty()) {
|
|
||||||
TreeNode* node = st.top();
|
|
||||||
if (node != NULL) {
|
|
||||||
st.pop();
|
|
||||||
st.push(node); // 中
|
|
||||||
st.push(NULL);
|
|
||||||
depth++;
|
|
||||||
if (node->right) st.push(node->right); // 右
|
|
||||||
if (node->left) st.push(node->left); // 左
|
|
||||||
|
|
||||||
} else {
|
|
||||||
st.pop();
|
|
||||||
node = st.top();
|
|
||||||
st.pop();
|
|
||||||
depth--;
|
|
||||||
}
|
|
||||||
result = result > depth ? result : depth;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## 其他语言版本
|
## 其他语言版本
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,7 +131,20 @@ class Solution {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def rob(self, nums: List[int]) -> int:
|
||||||
|
if len(nums) == 0:
|
||||||
|
return 0
|
||||||
|
if len(nums) == 1:
|
||||||
|
return nums[0]
|
||||||
|
dp = [0] * len(nums)
|
||||||
|
dp[0] = nums[0]
|
||||||
|
dp[1] = max(nums[0], nums[1])
|
||||||
|
for i in range(2, len(nums)):
|
||||||
|
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
|
||||||
|
return dp[-1]
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
```Go
|
```Go
|
||||||
|
@ -287,6 +287,25 @@ class Solution {
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
> 动态规划
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def rob(self, root: TreeNode) -> int:
|
||||||
|
result = self.robTree(root)
|
||||||
|
return max(result[0], result[1])
|
||||||
|
|
||||||
|
#长度为2的数组,0:不偷,1:偷
|
||||||
|
def robTree(self, cur):
|
||||||
|
if not cur:
|
||||||
|
return (0, 0) #这里返回tuple, 也可以返回list
|
||||||
|
left = self.robTree(cur.left)
|
||||||
|
right = self.robTree(cur.right)
|
||||||
|
#偷cur
|
||||||
|
val1 = cur.val + left[0] + right[0]
|
||||||
|
#不偷cur
|
||||||
|
val2 = max(left[0], left[1]) + max(right[0], right[1])
|
||||||
|
return (val2, val1)
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ canConstruct("aa", "aab") -> true
|
|||||||
|
|
||||||
## 思路
|
## 思路
|
||||||
|
|
||||||
这道题目和[242.有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)很像,[242.有效的字母异位词](https://mp.weixin.qq.com/s/vM6OszkM6L1Mx2Ralm9Dig)相当于求 字符串a 和 字符串b 是否可以相互组成 ,而这道题目是求 字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。
|
这道题目和[242.有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA)很像,[242.有效的字母异位词](https://mp.weixin.qq.com/s/ffS8jaVFNUWyfn_8T31IdA)相当于求 字符串a 和 字符串b 是否可以相互组成 ,而这道题目是求 字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。
|
||||||
|
|
||||||
本题判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成,但是这里需要注意两点。
|
本题判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成,但是这里需要注意两点。
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ public:
|
|||||||
|
|
||||||
依然是数组在哈希法中的应用。
|
依然是数组在哈希法中的应用。
|
||||||
|
|
||||||
一些同学可能想,用数组干啥,都用map完事了,**其实在本题的情况下,使用map的空间消耗要比数组大一些的,因为map要维护红黑树或者哈希表,而且还要做哈希函数。 所以数组更加简单直接有效!**
|
一些同学可能想,用数组干啥,都用map完事了,**其实在本题的情况下,使用map的空间消耗要比数组大一些的,因为map要维护红黑树或者哈希表,而且还要做哈希函数,是费时的!数据量大的话就能体现出来差别了。 所以数组更加简单直接有效!**
|
||||||
|
|
||||||
代码如下:
|
代码如下:
|
||||||
|
|
||||||
|
@ -206,7 +206,43 @@ class Solution:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
```go
|
||||||
|
func findMaxForm(strs []string, m int, n int) int {
|
||||||
|
// 定义数组
|
||||||
|
dp := make([][]int, m+1)
|
||||||
|
for i,_ := range dp {
|
||||||
|
dp[i] = make([]int, n+1 )
|
||||||
|
}
|
||||||
|
// 遍历
|
||||||
|
for i:=0;i<len(strs);i++ {
|
||||||
|
zeroNum,oneNum := 0 , 0
|
||||||
|
//计算0,1 个数
|
||||||
|
//或者直接strings.Count(strs[i],"0")
|
||||||
|
for _,v := range strs[i] {
|
||||||
|
if v == '0' {
|
||||||
|
zeroNum++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oneNum = len(strs[i])-zeroNum
|
||||||
|
// 从后往前 遍历背包容量
|
||||||
|
for j:= m ; j >= zeroNum;j-- {
|
||||||
|
for k:=n ; k >= oneNum;k-- {
|
||||||
|
// 推导公式
|
||||||
|
dp[j][k] = max(dp[j][k],dp[j-zeroNum][k-oneNum]+1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fmt.Println(dp)
|
||||||
|
}
|
||||||
|
return dp[m][n]
|
||||||
|
}
|
||||||
|
|
||||||
|
func max(a,b int) int {
|
||||||
|
if a > b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
示例 3:
|
示例 3:
|
||||||
输入: amount = 10, coins = [10]
|
输入: amount = 10, coins = [10]
|
||||||
输出: 1
|
输出: 1
|
||||||
|
|
||||||
注意,你可以假设:
|
注意,你可以假设:
|
||||||
|
|
||||||
* 0 <= amount (总金额) <= 5000
|
* 0 <= amount (总金额) <= 5000
|
||||||
@ -206,17 +206,23 @@ class Solution {
|
|||||||
```
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
```python
|
|
||||||
|
|
||||||
|
```python3
|
||||||
class Solution:
|
class Solution:
|
||||||
def change(self, amount: int, coins: List[int]) -> int:
|
def change(self, amount: int, coins: List[int]) -> int:
|
||||||
dp = [0]*(amount + 1)
|
dp = [0]*(amount + 1)
|
||||||
dp[0] = 1
|
dp[0] = 1
|
||||||
|
# 遍历物品
|
||||||
for i in range(len(coins)):
|
for i in range(len(coins)):
|
||||||
|
# 遍历背包
|
||||||
for j in range(coins[i], amount + 1):
|
for j in range(coins[i], amount + 1):
|
||||||
dp[j] += dp[j - coins[i]]
|
dp[j] += dp[j - coins[i]]
|
||||||
return dp[amount]
|
return dp[amount]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,7 +151,30 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
递归
|
||||||
|
```java
|
||||||
|
class Solution {
|
||||||
|
TreeNode pre;// 记录上一个遍历的结点
|
||||||
|
int result = Integer.MAX_VALUE;
|
||||||
|
public int getMinimumDifference(TreeNode root) {
|
||||||
|
if(root==null)return 0;
|
||||||
|
traversal(root);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public void traversal(TreeNode root){
|
||||||
|
if(root==null)return;
|
||||||
|
//左
|
||||||
|
traversal(root.left);
|
||||||
|
//中
|
||||||
|
if(pre!=null){
|
||||||
|
result = Math.min(result,root.val-pre.val);
|
||||||
|
}
|
||||||
|
pre = root;
|
||||||
|
//右
|
||||||
|
traversal(root.right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
```Java
|
```Java
|
||||||
class Solution {
|
class Solution {
|
||||||
TreeNode pre;// 记录上一个遍历的结点
|
TreeNode pre;// 记录上一个遍历的结点
|
||||||
|
@ -156,7 +156,31 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
Java:
|
Java:
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 1.dp[i] 代表当前下表最大连续值
|
||||||
|
* 2.递推公式 if(nums[i+1]>nums[i]) dp[i+1] = dp[i]+1
|
||||||
|
* 3.初始化 都为1
|
||||||
|
* 4.遍历方向,从其那往后
|
||||||
|
* 5.结果推导 。。。。
|
||||||
|
* @param nums
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int findLengthOfLCIS(int[] nums) {
|
||||||
|
int[] dp = new int[nums.length];
|
||||||
|
for (int i = 0; i < dp.length; i++) {
|
||||||
|
dp[i] = 1;
|
||||||
|
}
|
||||||
|
int res = 1;
|
||||||
|
for (int i = 0; i < nums.length - 1; i++) {
|
||||||
|
if (nums[i + 1] > nums[i]) {
|
||||||
|
dp[i + 1] = dp[i] + 1;
|
||||||
|
}
|
||||||
|
res = res > dp[i + 1] ? res : dp[i + 1];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
@ -255,7 +255,18 @@ func min(a, b int) int {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Javascript:
|
||||||
|
```Javascript
|
||||||
|
var minCostClimbingStairs = function(cost) {
|
||||||
|
const dp = [ cost[0], cost[1] ]
|
||||||
|
|
||||||
|
for (let i = 2; i < cost.length; ++i) {
|
||||||
|
dp[i] = Math.min(dp[i -1] + cost[i], dp[i - 2] + cost[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.min(dp[cost.length - 1], dp[cost.length - 2])
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||||
|
@ -184,7 +184,38 @@ class Solution:
|
|||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
|
||||||
|
Javascript:
|
||||||
|
```Javascript
|
||||||
|
var lemonadeChange = function(bills) {
|
||||||
|
let fiveCount = 0
|
||||||
|
let tenCount = 0
|
||||||
|
|
||||||
|
for(let i = 0; i < bills.length; i++) {
|
||||||
|
let bill = bills[i]
|
||||||
|
if(bill === 5) {
|
||||||
|
fiveCount += 1
|
||||||
|
} else if (bill === 10) {
|
||||||
|
if(fiveCount > 0) {
|
||||||
|
fiveCount -=1
|
||||||
|
tenCount += 1
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(tenCount > 0 && fiveCount > 0) {
|
||||||
|
tenCount -= 1
|
||||||
|
fiveCount -= 1
|
||||||
|
} else if(fiveCount >= 3) {
|
||||||
|
fiveCount -= 3
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
};
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||||
|
@ -257,6 +257,83 @@ Java:
|
|||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
|
100.相同的树
|
||||||
|
> 递归法
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
|
||||||
|
return self.compare(p, q)
|
||||||
|
|
||||||
|
def compare(self, tree1, tree2):
|
||||||
|
if not tree1 and tree2:
|
||||||
|
return False
|
||||||
|
elif tree1 and not tree2:
|
||||||
|
return False
|
||||||
|
elif not tree1 and not tree2:
|
||||||
|
return True
|
||||||
|
elif tree1.val != tree2.val: #注意这里我没有使用else
|
||||||
|
return False
|
||||||
|
|
||||||
|
#此时就是:左右节点都不为空,且数值相同的情况
|
||||||
|
#此时才做递归,做下一层的判断
|
||||||
|
compareLeft = self.compare(tree1.left, tree2.left) #左子树:左、 右子树:左
|
||||||
|
compareRight = self.compare(tree1.right, tree2.right) #左子树:右、 右子树:右
|
||||||
|
isSame = compareLeft and compareRight #左子树:中、 右子树:中(逻辑处理)
|
||||||
|
return isSame
|
||||||
|
```
|
||||||
|
|
||||||
|
257.二叉的所有路径
|
||||||
|
> 递归中隐藏着回溯
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def binaryTreePaths(self, root: TreeNode) -> List[str]:
|
||||||
|
result = []
|
||||||
|
path = []
|
||||||
|
if not root:
|
||||||
|
return result
|
||||||
|
self.traversal(root, path, result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def traversal(self, cur, path, result):
|
||||||
|
path.append(cur.val)
|
||||||
|
#这才到了叶子节点
|
||||||
|
if not cur.left and not cur.right:
|
||||||
|
sPath = ""
|
||||||
|
for i in range(len(path)-1):
|
||||||
|
sPath += str(path[i])
|
||||||
|
sPath += "->"
|
||||||
|
sPath += str(path[len(path)-1])
|
||||||
|
result.append(sPath)
|
||||||
|
return
|
||||||
|
if cur.left:
|
||||||
|
self.traversal(cur.left, path, result)
|
||||||
|
path.pop() #回溯
|
||||||
|
if cur.right:
|
||||||
|
self.traversal(cur.right, path, result)
|
||||||
|
path.pop() #回溯
|
||||||
|
```
|
||||||
|
|
||||||
|
> 精简版
|
||||||
|
```python
|
||||||
|
class Solution:
|
||||||
|
def binaryTreePaths(self, root: TreeNode) -> List[str]:
|
||||||
|
result = []
|
||||||
|
path = ""
|
||||||
|
if not root:
|
||||||
|
return result
|
||||||
|
self.traversal(root, path, result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def traversal(self, cur, path, result):
|
||||||
|
path += str(cur.val) #中
|
||||||
|
if not cur.left and not cur.right:
|
||||||
|
result.append(path)
|
||||||
|
return
|
||||||
|
if cur.left:
|
||||||
|
self.traversal(cur.left, path+"->", result) #左 回溯就隐藏在这里
|
||||||
|
if cur.right:
|
||||||
|
self.traversal(cur.right, path+"->", result) #右 回溯就隐藏在这里
|
||||||
|
```
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
|
||||||
|
@ -273,7 +273,40 @@ Python:
|
|||||||
|
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
```go
|
||||||
|
func test_2_wei_bag_problem1(weight, value []int, bagWeight int) int {
|
||||||
|
// 定义dp数组
|
||||||
|
dp := make([][]int, len(weight))
|
||||||
|
for i, _ := range dp {
|
||||||
|
dp[i] = make([]int, bagWeight+1)
|
||||||
|
}
|
||||||
|
// 初始化
|
||||||
|
for j := bagWeight; j >= weight[0]; j-- {
|
||||||
|
dp[0][j] = dp[0][j-weight[0]] + value[0]
|
||||||
|
}
|
||||||
|
// 递推公式
|
||||||
|
for i := 1; i < len(weight); i++ {
|
||||||
|
//正序,也可以倒序
|
||||||
|
for j := weight[i];j<= bagWeight ; j++ {
|
||||||
|
dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dp[len(weight)-1][bagWeight]
|
||||||
|
}
|
||||||
|
|
||||||
|
func max(a,b int) int {
|
||||||
|
if a > b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
weight := []int{1,3,4}
|
||||||
|
value := []int{15,20,30}
|
||||||
|
test_2_wei_bag_problem1(weight,value,4)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
-----------------------
|
-----------------------
|
||||||
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
|
||||||
|
@ -219,7 +219,36 @@ Python:
|
|||||||
|
|
||||||
|
|
||||||
Go:
|
Go:
|
||||||
|
```go
|
||||||
|
func test_1_wei_bag_problem(weight, value []int, bagWeight int) int {
|
||||||
|
// 定义 and 初始化
|
||||||
|
dp := make([]int,bagWeight+1)
|
||||||
|
// 递推顺序
|
||||||
|
for i := 0 ;i < len(weight) ; i++ {
|
||||||
|
// 这里必须倒序,区别二维,因为二维dp保存了i的状态
|
||||||
|
for j:= bagWeight; j >= weight[i] ; j-- {
|
||||||
|
// 递推公式
|
||||||
|
dp[j] = max(dp[j], dp[j-weight[i]]+value[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fmt.Println(dp)
|
||||||
|
return dp[bagWeight]
|
||||||
|
}
|
||||||
|
|
||||||
|
func max(a,b int) int {
|
||||||
|
if a > b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
weight := []int{1,3,4}
|
||||||
|
value := []int{15,20,30}
|
||||||
|
test_1_wei_bag_problem(weight,value,4)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,11 +32,11 @@
|
|||||||
|
|
||||||
看如下两个链表,目前curA指向链表A的头结点,curB指向链表B的头结点:
|
看如下两个链表,目前curA指向链表A的头结点,curB指向链表B的头结点:
|
||||||
|
|
||||||
v
|

|
||||||
|
|
||||||
我们求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 末尾对齐的位置,如图:
|
我们求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 末尾对齐的位置,如图:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
此时我们就可以比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到焦点。
|
此时我们就可以比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到焦点。
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user