diff --git a/problems/0096.不同的二叉搜索树.md b/problems/0096.不同的二叉搜索树.md index a9631315..56f50d46 100644 --- a/problems/0096.不同的二叉搜索树.md +++ b/problems/0096.不同的二叉搜索树.md @@ -211,6 +211,23 @@ func numTrees(n int)int{ } ``` +Javascript: +```Javascript +const numTrees =(n) => { + let dp = new Array(n+1).fill(0); + dp[0] = 1; + dp[1] = 1; + + for(let i = 2; i <= n; i++) { + for(let j = 1; j <= i; j++) { + dp[i] += dp[j-1] * dp[i-j]; + } + } + + return dp[n]; +}; +``` + ----------------------- diff --git a/problems/0108.将有序数组转换为二叉搜索树.md b/problems/0108.将有序数组转换为二叉搜索树.md index b8861b24..8ec5f3dc 100644 --- a/problems/0108.将有序数组转换为二叉搜索树.md +++ b/problems/0108.将有序数组转换为二叉搜索树.md @@ -209,6 +209,8 @@ public: Java: + +递归: 左闭右开 [left,right) ```Java class Solution { public TreeNode sortedArrayToBST(int[] nums) { @@ -232,6 +234,75 @@ class Solution { ``` +递归: 左闭右闭 [left,right] +```java +class Solution { + public TreeNode sortedArrayToBST(int[] nums) { + TreeNode root = traversal(nums, 0, nums.length - 1); + return root; + } + + // 左闭右闭区间[left, right) + private TreeNode traversal(int[] nums, int left, int right) { + if (left > right) return null; + + int mid = left + ((right - left) >> 1); + TreeNode root = new TreeNode(nums[mid]); + root.left = traversal(nums, left, mid - 1); + root.right = traversal(nums, mid + 1, right); + return root; + } +} +``` +迭代: 左闭右闭 [left,right] +```java +class Solution { + public TreeNode sortedArrayToBST(int[] nums) { + if (nums.length == 0) return null; + + //根节点初始化 + TreeNode root = new TreeNode(-1); + Queue nodeQueue = new LinkedList<>(); + Queue leftQueue = new LinkedList<>(); + Queue rightQueue = new LinkedList<>(); + + // 根节点入队列 + nodeQueue.offer(root); + // 0为左区间下表初始位置 + leftQueue.offer(0); + // nums.size() - 1为右区间下表初始位置 + rightQueue.offer(nums.length - 1); + + while (!nodeQueue.isEmpty()) { + TreeNode currNode = nodeQueue.poll(); + int left = leftQueue.poll(); + int right = rightQueue.poll(); + int mid = left + ((right - left) >> 1); + + // 将mid对应的元素给中间节点 + currNode.val = nums[mid]; + + // 处理左区间 + if (left <= mid - 1) { + currNode.left = new TreeNode(-1); + nodeQueue.offer(currNode.left); + leftQueue.offer(left); + rightQueue.offer(mid - 1); + } + + // 处理右区间 + if (right >= mid + 1) { + currNode.right = new TreeNode(-1); + nodeQueue.offer(currNode.right); + leftQueue.offer(mid + 1); + rightQueue.offer(right); + } + } + return root; + } +} +``` + Python: ```python3 # Definition for a binary tree node. @@ -279,6 +350,36 @@ func sortedArrayToBST(nums []int) *TreeNode { } ``` +JavaScript版本 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {number[]} nums + * @return {TreeNode} + */ +var sortedArrayToBST = function (nums) { + const buildTree = (Arr, left, right) => { + if (left > right) + return null; + + let mid = Math.floor(left + (right - left) / 2); + + let root = new TreeNode(Arr[mid]); + root.left = buildTree(Arr, left, mid - 1); + root.right = buildTree(Arr, mid + 1, right); + return root; + } + return buildTree(nums, 0, nums.length - 1); +}; +``` diff --git a/problems/0115.不同的子序列.md b/problems/0115.不同的子序列.md index d3bc6d97..62af9d0f 100644 --- a/problems/0115.不同的子序列.md +++ b/problems/0115.不同的子序列.md @@ -186,6 +186,40 @@ class Solution: return dp[-1][-1] ``` +Python3: +```python +class SolutionDP2: + """ + 既然dp[i]只用到dp[i - 1]的状态, + 我们可以通过缓存dp[i - 1]的状态来对dp进行压缩, + 减少空间复杂度。 + (原理等同同于滚动数组) + """ + + def numDistinct(self, s: str, t: str) -> int: + n1, n2 = len(s), len(t) + if n1 < n2: + return 0 + + dp = [0 for _ in range(n2 + 1)] + dp[0] = 1 + + for i in range(1, n1 + 1): + # 必须深拷贝 + # 不然prev[i]和dp[i]是同一个地址的引用 + prev = dp.copy() + # 剪枝,保证s的长度大于等于t + # 因为对于任意i,i > n1, dp[i] = 0 + # 没必要跟新状态。 + end = i if i < n2 else n2 + for j in range(1, end + 1): + if s[i - 1] == t[j - 1]: + dp[j] = prev[j - 1] + prev[j] + else: + dp[j] = prev[j] + return dp[-1] +``` + Go: diff --git a/problems/0216.组合总和III.md b/problems/0216.组合总和III.md index bfd798e6..15220464 100644 --- a/problems/0216.组合总和III.md +++ b/problems/0216.组合总和III.md @@ -227,6 +227,44 @@ public: Java: + +模板方法 +```java +class Solution { + List> result = new ArrayList<>(); + LinkedList path = new LinkedList<>(); + + public List> combinationSum3(int k, int n) { + backTracking(n, k, 1, 0); + return result; + } + + private void backTracking(int targetSum, int k, int startIndex, int sum) { + // 减枝 + if (sum > targetSum) { + return; + } + + if (path.size() == k) { + if (sum == targetSum) result.add(new ArrayList<>(path)); + return; + } + + // 减枝 9 - (k - path.size()) + 1 + for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) { + path.add(i); + sum += i; + backTracking(targetSum, k, i + 1, sum); + //回溯 + path.removeLast(); + //回溯 + sum -= i; + } + } +} +``` + +其他方法 ```java class Solution { List> res = new ArrayList<>(); diff --git a/problems/0494.目标和.md b/problems/0494.目标和.md index a0e07a1f..b7da0252 100644 --- a/problems/0494.目标和.md +++ b/problems/0494.目标和.md @@ -306,6 +306,36 @@ func findTargetSumWays(nums []int, target int) int { } ``` +Javascript: +```javascript +const findTargetSumWays = (nums, target) => { + + const sum = nums.reduce((a, b) => a+b); + + if(target > sum) { + return 0; + } + + if((target + sum) % 2) { + return 0; + } + + const halfSum = (target + sum) / 2; + nums.sort((a, b) => a - b); + + let dp = new Array(halfSum+1).fill(0); + dp[0] = 1; + + for(let i = 0; i < nums.length; i++) { + for(let j = halfSum; j >= nums[i]; j--) { + dp[j] += dp[j - nums[i]]; + } + } + + return dp[halfSum]; +}; +``` + ----------------------- diff --git a/problems/0538.把二叉搜索树转换为累加树.md b/problems/0538.把二叉搜索树转换为累加树.md index 06a53ce7..3ecb8195 100644 --- a/problems/0538.把二叉搜索树转换为累加树.md +++ b/problems/0538.把二叉搜索树转换为累加树.md @@ -239,7 +239,70 @@ func RightMLeft(root *TreeNode,sum *int) *TreeNode { } ``` +JavaScript版本 +> 递归 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {TreeNode} + */ +var convertBST = function(root) { + let pre = 0; + const ReverseInOrder = (cur) => { + if(cur) { + ReverseInOrder(cur.right); + cur.val += pre; + pre = cur.val; + ReverseInOrder(cur.left); + } + } + ReverseInOrder(root); + return root; +}; +``` + +> 迭代 + +```javascript +/** + * Definition for a binary tree node. + * function TreeNode(val, left, right) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + */ +/** + * @param {TreeNode} root + * @return {TreeNode} + */ +var convertBST = function (root) { + let pre = 0; + let cur = root; + let stack = []; + while (cur !== null || stack.length !== 0) { + while (cur !== null) { + stack.push(cur); + cur = cur.right; + } + cur = stack.pop(); + cur.val += pre; + pre = cur.val; + cur = cur.left; + } + return root; +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) diff --git a/problems/0617.合并二叉树.md b/problems/0617.合并二叉树.md index f325df64..19b58bd3 100644 --- a/problems/0617.合并二叉树.md +++ b/problems/0617.合并二叉树.md @@ -319,7 +319,7 @@ Python: # self.val = val # self.left = left # self.right = right -//递归法*前序遍历 +# 递归法*前序遍历 class Solution: def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode: if not root1: return root2 // 如果t1为空,合并之后就应该是t2 @@ -328,6 +328,32 @@ class Solution: root1.left = self.mergeTrees(root1.left , root2.left) //左 root1.right = self.mergeTrees(root1.right , root2.right) //右 return root1 //root1修改了结构和数值 + +# 迭代法-覆盖原来的树 +class Solution: + def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode: + if not root1: return root2 + if not root2: return root1 + # 迭代,将树2覆盖到树1 + queue1 = [root1] + queue2 = [root2] + root = root1 + while queue1 and queue2: + root1 = queue1.pop(0) + root2 = queue2.pop(0) + root1.val += root2.val + if not root1.left: # 如果树1左儿子不存在,则覆盖后树1的左儿子为树2的左儿子 + root1.left = root2.left + elif root1.left and root2.left: + queue1.append(root1.left) + queue2.append(root2.left) + + if not root1.right: # 同理,处理右儿子 + root1.right = root2.right + elif root1.right and root2.right: + queue1.append(root1.right) + queue2.append(root2.right) + return root ``` Go: diff --git a/problems/动态规划-股票问题总结篇.md b/problems/动态规划-股票问题总结篇.md index d22132c0..590a8008 100644 --- a/problems/动态规划-股票问题总结篇.md +++ b/problems/动态规划-股票问题总结篇.md @@ -375,12 +375,6 @@ p[i][3] = dp[i - 1][2]; 综上分析,递推代码如下: -```C++ -dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3], dp[i - 1][1]) - prices[i]; -dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]); -dp[i][2] = dp[i - 1][0] + prices[i]; -dp[i][3] = dp[i - 1][2]; -``` ```C++ dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3]- prices[i], dp[i - 1][1]) - prices[i]; dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]); diff --git a/problems/周总结/20201003二叉树周末总结.md b/problems/周总结/20201003二叉树周末总结.md index b7c123bc..0cb8b654 100644 --- a/problems/周总结/20201003二叉树周末总结.md +++ b/problems/周总结/20201003二叉树周末总结.md @@ -40,9 +40,8 @@ public: return isSame; } - bool isSymmetric(TreeNode* root) { - if (root == NULL) return true; - return compare(root->left, root->right); + bool isSymmetric(TreeNode* p, TreeNode* q) { + return compare(p, q); } }; ```