diff --git a/README.md b/README.md index 58f71049..4fa9100d 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,11 @@

+

+ + + + # LeetCode 刷题攻略 diff --git a/problems/0104.二叉树的最大深度.md b/problems/0104.二叉树的最大深度.md index 812c58ca..463b55d9 100644 --- a/problems/0104.二叉树的最大深度.md +++ b/problems/0104.二叉树的最大深度.md @@ -193,40 +193,6 @@ public: }; ``` -使用栈来模拟后序遍历依然可以 - -```C++ -class Solution { -public: - int maxDepth(TreeNode* root) { - stack 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; - - } -}; -``` - ## 其他语言版本 diff --git a/problems/0198.打家劫舍.md b/problems/0198.打家劫舍.md index 8b46a784..f49857bb 100644 --- a/problems/0198.打家劫舍.md +++ b/problems/0198.打家劫舍.md @@ -131,7 +131,20 @@ class Solution { ``` 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 diff --git a/problems/0337.打家劫舍III.md b/problems/0337.打家劫舍III.md index 58d0e640..0a4b752b 100644 --- a/problems/0337.打家劫舍III.md +++ b/problems/0337.打家劫舍III.md @@ -287,6 +287,25 @@ class Solution { 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: diff --git a/problems/0383.赎金信.md b/problems/0383.赎金信.md index 23e2c5fd..2f3c4f4d 100644 --- a/problems/0383.赎金信.md +++ b/problems/0383.赎金信.md @@ -22,13 +22,13 @@ https://leetcode-cn.com/problems/ransom-note/ 你可以假设两个字符串均只含有小写字母。 -canConstruct("a", "b") -> false -canConstruct("aa", "ab") -> false -canConstruct("aa", "aab") -> true +canConstruct("a", "b") -> false +canConstruct("aa", "ab") -> false +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里面的字符构成,但是这里需要注意两点。 @@ -75,7 +75,7 @@ public: 依然是数组在哈希法中的应用。 -一些同学可能想,用数组干啥,都用map完事了,**其实在本题的情况下,使用map的空间消耗要比数组大一些的,因为map要维护红黑树或者哈希表,而且还要做哈希函数。 所以数组更加简单直接有效!** +一些同学可能想,用数组干啥,都用map完事了,**其实在本题的情况下,使用map的空间消耗要比数组大一些的,因为map要维护红黑树或者哈希表,而且还要做哈希函数,是费时的!数据量大的话就能体现出来差别了。 所以数组更加简单直接有效!** 代码如下: diff --git a/problems/0474.一和零.md b/problems/0474.一和零.md index d60faa98..fd925f76 100644 --- a/problems/0474.一和零.md +++ b/problems/0474.一和零.md @@ -206,7 +206,43 @@ class Solution: ``` 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= 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 +} +``` diff --git a/problems/0518.零钱兑换II.md b/problems/0518.零钱兑换II.md index 7ee8818e..fde5ded5 100644 --- a/problems/0518.零钱兑换II.md +++ b/problems/0518.零钱兑换II.md @@ -33,7 +33,7 @@ 示例 3: 输入: amount = 10, coins = [10] 输出: 1 -  + 注意,你可以假设: * 0 <= amount (总金额) <= 5000 @@ -206,17 +206,23 @@ class Solution { ``` Python: -```python + + +```python3 class Solution: def change(self, amount: int, coins: List[int]) -> int: - dp = [0] * (amount + 1) + dp = [0]*(amount + 1) dp[0] = 1 + # 遍历物品 for i in range(len(coins)): + # 遍历背包 for j in range(coins[i], amount + 1): dp[j] += dp[j - coins[i]] return dp[amount] ``` + + Go: diff --git a/problems/0530.二叉搜索树的最小绝对差.md b/problems/0530.二叉搜索树的最小绝对差.md index 143bd053..03c48d9c 100644 --- a/problems/0530.二叉搜索树的最小绝对差.md +++ b/problems/0530.二叉搜索树的最小绝对差.md @@ -151,7 +151,30 @@ public: 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 class Solution { TreeNode pre;// 记录上一个遍历的结点 diff --git a/problems/0674.最长连续递增序列.md b/problems/0674.最长连续递增序列.md index 46413d98..636ee0cc 100644 --- a/problems/0674.最长连续递增序列.md +++ b/problems/0674.最长连续递增序列.md @@ -156,7 +156,31 @@ public: 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: diff --git a/problems/0746.使用最小花费爬楼梯.md b/problems/0746.使用最小花费爬楼梯.md index 1e8e8038..4238a389 100644 --- a/problems/0746.使用最小花费爬楼梯.md +++ b/problems/0746.使用最小花费爬楼梯.md @@ -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) diff --git a/problems/0860.柠檬水找零.md b/problems/0860.柠檬水找零.md index faee2e56..a18c008d 100644 --- a/problems/0860.柠檬水找零.md +++ b/problems/0860.柠檬水找零.md @@ -184,7 +184,38 @@ class Solution: 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) diff --git a/problems/二叉树中递归带着回溯.md b/problems/二叉树中递归带着回溯.md index 2adb826c..aede1831 100644 --- a/problems/二叉树中递归带着回溯.md +++ b/problems/二叉树中递归带着回溯.md @@ -257,6 +257,83 @@ Java: 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: diff --git a/problems/背包理论基础01背包-1.md b/problems/背包理论基础01背包-1.md index a78d9232..de4508ad 100644 --- a/problems/背包理论基础01背包-1.md +++ b/problems/背包理论基础01背包-1.md @@ -273,7 +273,40 @@ Python: 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) diff --git a/problems/背包理论基础01背包-2.md b/problems/背包理论基础01背包-2.md index e831d88f..1d3f8b03 100644 --- a/problems/背包理论基础01背包-2.md +++ b/problems/背包理论基础01背包-2.md @@ -219,7 +219,36 @@ Python: 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) +} +``` diff --git a/problems/面试题02.07.链表相交.md b/problems/面试题02.07.链表相交.md index 78f34e71..c6779427 100644 --- a/problems/面试题02.07.链表相交.md +++ b/problems/面试题02.07.链表相交.md @@ -32,11 +32,11 @@ 看如下两个链表,目前curA指向链表A的头结点,curB指向链表B的头结点: -![面试题02.07.链表相交_1](https://code-thinking.cdn.bcebos.com/pics/%E9%9D%A2%E8%AF%95%E9%A2%9802.07.%E9%93%BE%E8%A1%A8%E7%9B%B8%E4%BA%A4_1.png)v +![面试题02.07.链表相交_1](https://code-thinking.cdn.bcebos.com/pics/面试题02.07.链表相交_1.png) 我们求出两个链表的长度,并求出两个链表长度的差值,然后让curA移动到,和curB 末尾对齐的位置,如图: -![面试题02.07.链表相交_2](https://code-thinking.cdn.bcebos.com/pics/%E9%9D%A2%E8%AF%95%E9%A2%9802.07.%E9%93%BE%E8%A1%A8%E7%9B%B8%E4%BA%A4_2.png) +![面试题02.07.链表相交_2](https://code-thinking.cdn.bcebos.com/pics/面试题02.07.链表相交_2.png) 此时我们就可以比较curA和curB是否相同,如果不相同,同时向后移动curA和curB,如果遇到curA == curB,则找到焦点。