From 434ba4ed39cc52d86b9aa7d2ae16e507d1eddd44 Mon Sep 17 00:00:00 2001 From: mengyuan Date: Mon, 22 Nov 2021 20:04:35 +0800 Subject: [PATCH 1/8] =?UTF-8?q?update:=20=E5=B9=B3=E8=A1=A1=E4=BA=8C?= =?UTF-8?q?=E5=8F=89=E6=A0=91js=E7=89=88=E6=9C=AC=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0110.平衡二叉树.md | 34 +++++++++++++------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/problems/0110.平衡二叉树.md b/problems/0110.平衡二叉树.md index a06bff0e..a8dbb0db 100644 --- a/problems/0110.平衡二叉树.md +++ b/problems/0110.平衡二叉树.md @@ -606,29 +606,23 @@ func abs(a int)int{ ## JavaScript ```javascript var isBalanced = function(root) { - //还是用递归三部曲 + 后序遍历 左右中 当前左子树右子树高度相差大于1就返回-1 + //还是用递归三部曲 + 后序遍历 左右中 当前左子树右子树高度相差大于1就返回-1 // 1. 确定递归函数参数以及返回值 - const getDepth=function(node){ - // 2. 确定递归函数终止条件 - if(node===null){ - return 0; + const getDepth = function(node) { + // 2. 确定递归函数终止条件 + if(node === null) return 0; + // 3. 确定单层递归逻辑 + let leftDepth = getDepth(node.left); //左子树高度 + let rightDepth = getDepth(node.right); //右子树高度 + if(leftDepth === -1) return -1; + if(rightDepth === -1) return -1; + if(Math.abs(leftDepth - rightDepth) > 1) { + return -1; + } else { + return 1 + Math.max(leftDepth, rightDepth); } - // 3. 确定单层递归逻辑 - let leftDepth=getDepth(node.left);//左子树高度 - if(leftDepth===-1){ - return -1; } - let rightDepth=getDepth(node.right);//右子树高度 - if(rightDepth===-1){ - return -1; - } - if(Math.abs(leftDepth-rightDepth)>1){ - return -1; - }else{ - return 1+Math.max(leftDepth,rightDepth); - } - } - return getDepth(root)===-1?false:true; + return !(getDepth(root) === -1); }; ``` From 407c08457cadf94df46b16bf17231f2fa6d9ec82 Mon Sep 17 00:00:00 2001 From: mengyuan Date: Mon, 22 Nov 2021 20:18:58 +0800 Subject: [PATCH 2/8] =?UTF-8?q?update:=20112.=20=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=80=BB=E5=92=8C=20&&=20=E8=B7=AF=E5=BE=84=E6=80=BB=E5=92=8C-?= =?UTF-8?q?ii=20js=E8=BF=AD=E4=BB=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0112.路径总和.md | 67 ++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md index 054b2340..19f4bcac 100644 --- a/problems/0112.路径总和.md +++ b/problems/0112.路径总和.md @@ -614,6 +614,7 @@ func haspathsum(root *treenode,sumnodes *[]int,targetsum int,result *[][]int){ 0112.路径总和 +**递归** ```javascript /** * @param {treenode} root @@ -643,9 +644,38 @@ let haspathsum = function (root, targetsum) { // return haspathsum(root.left, targetsum - root.val) || haspathsum(root.right, targetsum - root.val); }; ``` +**迭代** +```javascript +let hasPathSum = function(root, targetSum) { + if(root === null) return false; + let nodeArr = [root]; + let valArr = [0]; + while(nodeArr.length) { + let curNode = nodeArr.shift(); + let curVal = valArr.shift(); + curVal += curNode.val; + // 为叶子结点,且和等于目标数,返回true + if (curNode.left === null && curNode.right === null && curVal === targetSum) { + return true; + } + // 左节点,将当前的数值也对应记录下来 + if (curNode.left) { + nodeArr.push(curNode.left); + valArr.push(curVal); + } + // 右节点,将当前的数值也对应记录下来 + if (curNode.right) { + nodeArr.push(curNode.right); + valArr.push(curVal); + } + } + return false; +}; +``` 0113.路径总和-ii +**递归** ```javascript let pathsum = function (root, targetsum) { // 递归法 @@ -677,7 +707,7 @@ let pathsum = function (root, targetsum) { return res; }; ``` -113 路径总和 精简版 +**递归 精简版** ```javascript var pathsum = function(root, targetsum) { //递归方法 @@ -701,6 +731,41 @@ var pathsum = function(root, targetsum) { return resPath; }; ``` +**迭代** +```javascript +let pathSum = function(root, targetSum) { + if(root === null) return []; + let nodeArr = [root]; + let resArr = []; // 记录符合目标和的返回路径 + let tempArr = [[]]; // 对应路径 + let countArr = [0]; //对应和 + while(nodeArr.length) { + let curNode = nodeArr.shift(); + let curVal = countArr.shift(); + let curNodeArr = tempArr.shift(); + curVal += curNode.val; + curNodeArr.push(curNode.val); + // 为叶子结点,且和等于目标数,将此次结果数组push进返回数组中 + if (curNode.left === null && curNode.right === null && curVal === targetSum) { + resArr.push(curNodeArr); + } + // 左节点,将当前的和及对应路径也对应记录下来 + if (curNode.left) { + nodeArr.push(curNode.left); + countArr.push(curVal); + tempArr.push([...curNodeArr]); + } + // 右节点,将当前的和及对应路径也对应记录下来 + if (curNode.right) { + nodeArr.push(curNode.right); + countArr.push(curVal); + tempArr.push([...curNodeArr]); + } + } + return resArr; +}; +``` + From 7cef253757777c2dbb92a7cb164357c4303c022c Mon Sep 17 00:00:00 2001 From: LiHua <1985390347@qq.com> Date: Tue, 23 Nov 2021 18:33:52 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86121.=E4=B9=B0?= =?UTF-8?q?=E5=8D=96=E8=82=A1=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6?= =?UTF-8?q?=E6=9C=BA=E7=9A=84java=E9=A2=98=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0121.买卖股票的最佳时机.md | 64 ++++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md index 3aff6b89..89f0637a 100644 --- a/problems/0121.买卖股票的最佳时机.md +++ b/problems/0121.买卖股票的最佳时机.md @@ -195,23 +195,26 @@ public: ## 其他语言版本 Java: + +> 贪心法: + ```java -// 贪心思路 class Solution { public int maxProfit(int[] prices) { - int minprice = Integer.MAX_VALUE; - int maxprofit = 0; - for (int i = 0; i < prices.length; i++) { - if (prices[i] < minprice) { - minprice = prices[i]; - } else if (prices[i] - minprice > maxprofit) { - maxprofit = prices[i] - minprice; - } + // 找到一个最小的购入点 + int low = Integer.MAX_VALUE; + // res不断更新,直到数组循环完毕 + int res = 0; + for(int i = 0; i < prices.length; i++){ + low = Math.min(prices[i], low); + res = Math.max(prices[i] - low, res); } - return maxprofit; + return res; } } ``` +> 动态规划:版本一 + ```java // 解法1 class Solution { @@ -233,30 +236,27 @@ class Solution { } ``` +> 动态规划:版本二 + ``` java -class Solution { // 动态规划解法 - public int maxProfit(int[] prices) { - // 可交易次数 - int k = 1; - // [天数][交易次数][是否持有股票] - int[][][] dp = new int[prices.length][k + 1][2]; - - // bad case - dp[0][0][0] = 0; - dp[0][0][1] = Integer.MIN_VALUE; - dp[0][1][0] = Integer.MIN_VALUE; - dp[0][1][1] = -prices[0]; - - for (int i = 1; i < prices.length; i++) { - for (int j = k; j >= 1; j--) { - // dp公式 - dp[i][j][0] = Math.max(dp[i - 1][j][0], dp[i - 1][j][1] + prices[i]); - dp[i][j][1] = Math.max(dp[i - 1][j][1], dp[i - 1][j - 1][0] - prices[i]); - } - } - - return dp[prices.length - 1][k][0] > 0 ? dp[prices.length - 1][k][0] : 0; +class Solution { + public int maxProfit(int[] prices) { + int[] dp = new int[2]; + dp[0] = -prices[0]; + dp[1] = 0; + // 可以参考斐波那契问题的优化方式 + // dp[0] 和 dp[1], 其实是第 0 天的数据 + // 所以我们从 i=1 开始遍历数组,一共有 prices.length 天, + // 所以是 i<=prices.length + for (int i = 1; i <= prices.length; i++) { + int temp = dp[0]; + // 前一天持有;或当天买入 + dp[0] = Math.max(temp, -prices[i - 1]); + // 前一天卖出;或当天卖出, 当天要卖出,得前一天持有才行 + dp[1] = Math.max(dp[1], temp + prices[i - 1]); } + return dp[1]; + } } ``` From e6f059f545e560e3b22cd3d9a9f5c76a65fb53bd Mon Sep 17 00:00:00 2001 From: Guanzhong Pan Date: Tue, 23 Nov 2021 10:43:17 +0000 Subject: [PATCH 4/8] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200232.=E7=94=A8?= =?UTF-8?q?=E6=A0=88=E5=AE=9E=E7=8E=B0=E9=98=9F=E5=88=97.md=20C=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0232.用栈实现队列.md | 77 +++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md index 0e4a5d6d..d4933af6 100644 --- a/problems/0232.用栈实现队列.md +++ b/problems/0232.用栈实现队列.md @@ -349,6 +349,83 @@ MyQueue.prototype.empty = function() { }; ``` +C: +```C +/* +1.两个type为int的数组(栈),大小为100 + 第一个栈stackIn用来存放数据,第二个栈stackOut作为辅助用来输出数据 +2.两个指针stackInTop和stackOutTop,分别指向栈顶 +*/ +typedef struct { + int stackInTop, stackOutTop; + int stackIn[100], stackOut[100]; +} MyQueue; + +/* +1.开辟一个队列的大小空间 +2.将指针stackInTop和stackOutTop初始化为0 +3.返回开辟的队列 +*/ +MyQueue* myQueueCreate() { + MyQueue* queue = (MyQueue*)malloc(sizeof(MyQueue)); + queue->stackInTop = 0; + queue->stackOutTop = 0; + return queue; +} + +/* +将元素存入第一个栈中,存入后栈顶指针+1 +*/ +void myQueuePush(MyQueue* obj, int x) { + obj->stackIn[(obj->stackInTop)++] = x; +} + +/* +1.若输出栈为空且当第一个栈中有元素(stackInTop>0时),将第一个栈中元素复制到第二个栈中(stack2[stackTop2++] = stack1[--stackTop1]) +2.将栈顶元素保存 +3.当stackTop2>0时,将第二个栈中元素复制到第一个栈中(stack1[stackTop1++] = stack2[--stackTop2]) +*/ +int myQueuePop(MyQueue* obj) { + //优化:复制栈顶指针,减少对内存的访问次数 + int stackInTop = obj->stackInTop; + int stackOutTop = obj->stackOutTop; + //若输出栈为空 + if(stackOutTop == 0) { + //将第一个栈中元素复制到第二个栈中 + while(stackInTop > 0) { + obj->stackOut[stackOutTop++] = obj->stackIn[--stackInTop]; + } + } + //将第二个栈中栈顶元素(队列的第一个元素)出栈,并保存 + int top = obj->stackOut[--stackOutTop]; + //将输出栈中元素放回输入栈中 + while(stackOutTop > 0) { + obj->stackIn[stackInTop++] = obj->stackOut[--stackOutTop]; + } + //更新栈顶指针 + obj->stackInTop = stackInTop; + obj->stackOutTop = stackOutTop; + //返回队列中第一个元素 + return top; +} + +//返回输入栈中的栈底元素 +int myQueuePeek(MyQueue* obj) { + return obj->stackIn[0]; +} + +//若栈顶指针均为0,则代表队列为空 +bool myQueueEmpty(MyQueue* obj) { + return obj->stackInTop == 0 && obj->stackOutTop == 0; +} + +//将栈顶指针置0 +void myQueueFree(MyQueue* obj) { + obj->stackInTop = 0; + obj->stackOutTop = 0; +} +``` + -----------------------
From 71f1410d8d0d9d71d9208b6a6ee098c70b3d3303 Mon Sep 17 00:00:00 2001 From: LiHua <1985390347@qq.com> Date: Wed, 24 Nov 2021 09:25:23 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BA=86121=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E8=A7=84=E5=88=92=E7=89=88=E6=9C=AC=E4=BA=8C=E7=9A=84?= =?UTF-8?q?=E8=A7=A3=E9=A2=98=E4=BB=A3=E7=A0=81^C=E9=A2=98=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0121.买卖股票的最佳时机.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md index 89f0637a..45b61666 100644 --- a/problems/0121.买卖股票的最佳时机.md +++ b/problems/0121.买卖股票的最佳时机.md @@ -249,11 +249,14 @@ class Solution { // 所以我们从 i=1 开始遍历数组,一共有 prices.length 天, // 所以是 i<=prices.length for (int i = 1; i <= prices.length; i++) { - int temp = dp[0]; // 前一天持有;或当天买入 - dp[0] = Math.max(temp, -prices[i - 1]); + dp[0] = Math.max(dp[0], -prices[i - 1]); + // 如果 dp[0] 被更新,那么 dp[1] 肯定会被更新为正数的 dp[1] + // 而不是 dp[0]+prices[i-1]==0 的0, + // 所以这里使用会改变的dp[0]也是可以的 + // 当然 dp[1] 初始值为 0 ,被更新成 0 也没影响 // 前一天卖出;或当天卖出, 当天要卖出,得前一天持有才行 - dp[1] = Math.max(dp[1], temp + prices[i - 1]); + dp[1] = Math.max(dp[1], dp[0] + prices[i - 1]); } return dp[1]; } From eacf15d7a3a8042eb8c0181c9d7fb8a438f39e17 Mon Sep 17 00:00:00 2001 From: LiHua <1985390347@qq.com> Date: Wed, 24 Nov 2021 09:31:54 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86122=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=A9=BA=E9=97=B4=E7=9A=84java=E9=A2=98=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0122.买卖股票的最佳时机II.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/problems/0122.买卖股票的最佳时机II.md b/problems/0122.买卖股票的最佳时机II.md index d4575bd6..5b117563 100644 --- a/problems/0122.买卖股票的最佳时机II.md +++ b/problems/0122.买卖股票的最佳时机II.md @@ -167,6 +167,25 @@ class Solution { // 动态规划 } ``` +```java +// 优化空间 +class Solution { + public int maxProfit(int[] prices) { + int[] dp=new int[2]; + // 0表示持有,1表示卖出 + dp[0]=-prices[0]; + dp[1]=0; + for(int i=1; i<=prices.length; i++){ + // 前一天持有; 或当天卖出然后买入 + dp[0]=Math.max(dp[0], dp[1]-prices[i-1]); + // 前一天卖出; 或当天卖出,当天卖出,得先持有 + dp[1]=Math.max(dp[1], dp[0]+prices[i-1]); + } + return dp[1]; + } +} +``` + ### Python From 5fc35368c1feba9a87cea44d603ebb8b646e8654 Mon Sep 17 00:00:00 2001 From: LiHua <1985390347@qq.com> Date: Wed, 24 Nov 2021 09:37:18 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E7=BB=9F=E4=B8=80=E4=BA=86123=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=A9=BA=E9=97=B4=E5=86=99=E6=B3=95=E7=9A=84java?= =?UTF-8?q?=E8=A7=A3=E9=A2=98=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0123.买卖股票的最佳时机III.md | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/problems/0123.买卖股票的最佳时机III.md b/problems/0123.买卖股票的最佳时机III.md index 9c269978..db3f0278 100644 --- a/problems/0123.买卖股票的最佳时机III.md +++ b/problems/0123.买卖股票的最佳时机III.md @@ -188,7 +188,7 @@ dp[1] = max(dp[1], dp[0] - prices[i]); 如果dp[1]取dp[1],即保持买入股 ## 其他语言版本 -Java: +### Java ```java // 版本一 @@ -221,25 +221,30 @@ class Solution { // 版本二: 空间优化 class Solution { public int maxProfit(int[] prices) { - int len = prices.length; - int[] dp = new int[5]; - dp[1] = -prices[0]; - dp[3] = -prices[0]; - - for (int i = 1; i < len; i++) { - dp[1] = Math.max(dp[1], dp[0] - prices[i]); - dp[2] = Math.max(dp[2], dp[1] + prices[i]); - dp[3] = Math.max(dp[3], dp[2] - prices[i]); - dp[4] = Math.max(dp[4], dp[3] + prices[i]); + int[] dp=new int[4]; + // 存储两天的状态就行了 + // dp[0]代表第一次买入 + dp[0]=-prices[0]; + // dp[1]代表第一次卖出 + dp[1]=0; + // dp[2]代表第二次买入 + dp[2]=-prices[0]; + // dp[3]代表第二次卖出 + dp[3]=0; + for(int i=1; i<=prices.length; i++){ + // 要么保持不变,要么没有就买,有了就卖 + dp[0]=Math.max(dp[0], -prices[i-1]); + dp[1]=Math.max(dp[1], dp[0]+prices[i-1]); + // 这已经是第二天了,所以得加上前一天卖出去的价格 + dp[2]=Math.max(dp[2], dp[1]-prices[i-1]); + dp[3]=Math.max(dp[3], dp[2]+prices[i-1]); } - - return dp[4]; + return dp[3]; } } ``` - -Python: +### Python > 版本一: ```python @@ -308,7 +313,7 @@ func max(a,b int)int{ -JavaScript: +### JavaScript > 版本一: @@ -347,7 +352,7 @@ const maxProfit = prices => { }; ``` -Go: +### Go > 版本一: ```go @@ -381,5 +386,7 @@ func max(a, b int) int { ``` + + -----------------------
From e9f7683d4679a6126907134ba4c623267b1ba951 Mon Sep 17 00:00:00 2001 From: LiHua <1985390347@qq.com> Date: Wed, 24 Nov 2021 10:11:18 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E4=BA=86188=E4=B8=80?= =?UTF-8?q?=E7=BB=B4=E6=95=B0=E7=BB=84java=E8=A7=A3=E9=A2=98=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0188.买卖股票的最佳时机IV.md | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/problems/0188.买卖股票的最佳时机IV.md b/problems/0188.买卖股票的最佳时机IV.md index 73861b35..0e898b43 100644 --- a/problems/0188.买卖股票的最佳时机IV.md +++ b/problems/0188.买卖股票的最佳时机IV.md @@ -222,19 +222,32 @@ class Solution { //版本三:一维 dp数组 class Solution { public int maxProfit(int k, int[] prices) { - //在版本二的基础上,由于我们只关心前一天的股票买入情况,所以只存储前一天的股票买入情况 - if(prices.length==0)return 0; - int[] dp=new int[2*k+1]; - for (int i = 1; i <2*k ; i+=2) { - dp[i]=-prices[0]; + if(prices.length == 0){ + return 0; } - for (int i = 0; i