From f7990b703ba835e0e624f8ad3d2bbad14a552b0e Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 12:39:55 +0800 Subject: [PATCH 01/32] =?UTF-8?q?649.Dota2=E5=8F=82=E8=AE=AE=E9=99=A2=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9EJavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0649.Dota2参议院.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/problems/0649.Dota2参议院.md b/problems/0649.Dota2参议院.md index e2900824..cda5dd95 100644 --- a/problems/0649.Dota2参议院.md +++ b/problems/0649.Dota2参议院.md @@ -219,6 +219,31 @@ func predictPartyVictory(senateStr string) string { ## JavaScript ```js +var predictPartyVictory = function(senateStr) { + // R = true表示本轮循环结束后,字符串里依然有R;D同理。 + let R = true, D = true; + // 当flag大于0时,R在D前出现,R可以消灭D。当flag小于0时,D在R前出现,D可以消灭R + let flag = 0; + let senate = senateStr.split(''); + while(R && D){ // 一旦R或者D为false,就结束循环,说明本轮结束后只剩下R或者D了 + R = false; + D = false; + for(let i = 0; i < senate.length; i++){ + if(senate[i] === 'R'){ + if(flag < 0) senate[i] = 0;// 消灭R,R此时为false + else R = true;// 如果没被消灭,本轮循环结束有R + flag++; + } + if(senate[i] === 'D'){ + if(flag > 0) senate[i] = 0; + else D = true; + flag--; + } + } + } + // 循环结束之后,R和D只能有一个为true + return R ? "Radiant" : "Dire"; +}; ``` ----------------------- From 55e185b5e651860f0363cea4a5fdfdbe72ba1310 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 13:06:39 +0800 Subject: [PATCH 02/32] =?UTF-8?q?=E6=9B=B4=E6=96=B0=201207.=E7=8B=AC?= =?UTF-8?q?=E4=B8=80=E6=97=A0=E4=BA=8C=E7=9A=84=E5=87=BA=E7=8E=B0=E6=AC=A1?= =?UTF-8?q?=E6=95=B0=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1207.独一无二的出现次数.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/problems/1207.独一无二的出现次数.md b/problems/1207.独一无二的出现次数.md index 027c9f5a..f18af16c 100644 --- a/problems/1207.独一无二的出现次数.md +++ b/problems/1207.独一无二的出现次数.md @@ -118,7 +118,23 @@ class Solution: Go: JavaScript: - +``` javascript +var uniqueOccurrences = function(arr) { + const count = new Array(2002).fill(0);// -1000 <= arr[i] <= 1000 + for(let i = 0; i < arr.length; i++){ + count[arr[i] + 1000]++;// 防止负数作为下标 + } + // 标记相同频率是否重复出现 + const fre = new Array(1002).fill(false);// 1 <= arr.length <= 1000 + for(let i = 0; i <= 2000; i++){ + if(count[i] > 0){//有i出现过 + if(fre[count[i]] === false) fre[count[i]] = true;//之前未出现过,标记为出现 + else return false;//之前就出现了,重复出现 + } + } + return true; +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) From ff3f31aed05dd05c5740b63415f494b198c8a477 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 16:14:35 +0800 Subject: [PATCH 03/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20283.=20=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E9=9B=B6=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0283.移动零.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/problems/0283.移动零.md b/problems/0283.移动零.md index 3909bcd5..2498bdc3 100644 --- a/problems/0283.移动零.md +++ b/problems/0283.移动零.md @@ -95,6 +95,21 @@ Python: Go: JavaScript: +```javascript +var moveZeroes = function(nums) { + let slow = 0; + for(let fast = 0; fast < nums.length; fast++){ + if(nums[fast] != 0){//找到非0的元素 + nums[slow] = nums[fast];//把非0的元素赋值给数组慢指针指向的索引处的值 + slow++;//慢指针向右移动 + } + } + // 后面的元素全变成 0 + for(let j = slow; j < nums.length; j++){ + nums[j] = 0; + } +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From a1e32680ac4e314969dbf7578caac5b7e80b3aa2 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 16:40:41 +0800 Subject: [PATCH 04/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20463.=E5=B2=9B?= =?UTF-8?q?=E5=B1=BF=E7=9A=84=E5=91=A8=E9=95=BF=20JavaScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0463.岛屿的周长.md | 49 ++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/problems/0463.岛屿的周长.md b/problems/0463.岛屿的周长.md index fd9585d2..e6077456 100644 --- a/problems/0463.岛屿的周长.md +++ b/problems/0463.岛屿的周长.md @@ -120,6 +120,55 @@ Python: Go: JavaScript: +```javascript +//解法一 +var islandPerimeter = function(grid) { + // 上下左右 4 个方向 + const dirx = [-1, 1, 0, 0], diry = [0, 0, -1, 1]; + const m = grid.length, n = grid[0].length; + let res = 0; //岛屿周长 + for(let i = 0; i < m; i++){ + for(let j = 0; j < n; j++){ + if(grid[i][j] === 1){ + for(let k = 0; k < 4; k++){ //上下左右四个方向 + // 计算周边坐标的x,y + let x = i + dirx[k]; + let y = j + diry[k]; + // 四个方向扩展的新位置是水域或者越界就会为周长贡献1 + if(x < 0 // i在边界上 + || x >= m // i在边界上 + || y < 0 // j在边界上 + || y >= n // j在边界上 + || grid[x][y] === 0){ // (x,y)位置是水域 + res++; + continue; + } + } + } + } + } + return res; +}; + +//解法二 +var islandPerimeter = function(grid) { + let sum = 0; // 陆地数量 + let cover = 0; // 相邻数量 + for(let i = 0; i < grid.length; i++){ + for(let j = 0; j = 0 && grid[i-1][j] === 1) cover++; + // 统计左边相邻陆地 + if(j - 1 >= 0 && grid[i][j-1] === 1) cover++; + // 为什么没统计下边和右边? 因为避免重复计算 + } + } + } + return sum * 4 - cover * 2; +}; +``` ----------------------- From 195b8aefddc4266487c2c0894344134d4594bdb0 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 17:23:26 +0800 Subject: [PATCH 05/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E1221.=E5=88=86=E5=89=B2?= =?UTF-8?q?=E5=B9=B3=E8=A1=A1=E5=AD=97=E7=AC=A6=E4=B8=B2=20JavaScript?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1221.分割平衡字符串.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/problems/1221.分割平衡字符串.md b/problems/1221.分割平衡字符串.md index c764e3ff..381ad060 100644 --- a/problems/1221.分割平衡字符串.md +++ b/problems/1221.分割平衡字符串.md @@ -108,6 +108,15 @@ public: ## JavaScript ```js +var balancedStringSplit = function(s) { + let res = 0, total = 0;//res为平衡字符串数量 total为当前"R"字符和"L"字符的数量差 + for(let c of s){// 遍历字符串每个字符 + //因为开始字符数量差就是0,遍历的时候要先改变数量差,否则会影响结果数量 + total += c === 'R' ? 1:-1;//遇到"R",total++;遇到"L",total-- + if(total === 0) res++;//只要"R""L"数量一样就可以算是一个平衡字符串 + } + return res; +}; ``` ----------------------- From 571ce5788e816d59fe6266e95a5eeeba36e965df Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 17:44:58 +0800 Subject: [PATCH 06/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A01356.=20=E5=A6=82?= =?UTF-8?q?=E4=BD=95=E8=AE=A1=E7=AE=97=E4=BA=8C=E8=BF=9B=E5=88=B6=E4=B8=AD?= =?UTF-8?q?1=E7=9A=84=E6=95=B0=E9=87=8F=20JavaScript=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../1356.根据数字二进制下1的数目排序.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/problems/1356.根据数字二进制下1的数目排序.md b/problems/1356.根据数字二进制下1的数目排序.md index 06c29500..c7e856d1 100644 --- a/problems/1356.根据数字二进制下1的数目排序.md +++ b/problems/1356.根据数字二进制下1的数目排序.md @@ -166,6 +166,18 @@ class Solution { ## JavaScript ```js +var sortByBits = function(arr) { + const bitCount = n =>{// 计算n的二进制中1的数量 + let count = 0; + while(n){ + n &= (n - 1);// 清除最低位的1 + count++; + } + return count; + } + // 如果有差,则按bits数排,如果无差,则按原值排 + return arr.sort((a,b) => bitCount(a) - bitCount(b) || a - b); +}; ``` ----------------------- From 16dcd4cd839c17d4417801c6ee1dc59c84aa4c29 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 17:54:30 +0800 Subject: [PATCH 07/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A01365.=20=E6=9C=89?= =?UTF-8?q?=E5=A4=9A=E5=B0=91=E5=B0=8F=E4=BA=8E=E5=BD=93=E5=89=8D=E6=95=B0?= =?UTF-8?q?=E5=AD=97=E7=9A=84=E6=95=B0=E5=AD=97=20JavaScript=E8=A7=A3?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...365.有多少小于当前数字的数字.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/problems/1365.有多少小于当前数字的数字.md b/problems/1365.有多少小于当前数字的数字.md index 5cf6b2d8..cd003f2f 100644 --- a/problems/1365.有多少小于当前数字的数字.md +++ b/problems/1365.有多少小于当前数字的数字.md @@ -155,7 +155,23 @@ class Solution: Go: JavaScript: - +```javascript +var smallerNumbersThanCurrent = function(nums) { + const map = new Map();// 记录数字 nums[i] 有多少个比它小的数字 + const res = nums.slice(0);//深拷贝nums + res.sort((a,b) => a - b); + for(let i = 0; i < res.length; i++){ + if(!map.has(res[i])){// 遇到了相同的数字,那么不需要更新该 number 的情况 + map.set(res[i],i); + } + } + // 此时map里保存的每一个元素数值 对应的 小于这个数值的个数 + for(let i = 0; i < nums.length; i++){ + res[i] = map.get(nums[i]); + } + return res; +}; +``` ----------------------- From a5a088b35fe494205d61479a267205df4692f7cd Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 18:14:07 +0800 Subject: [PATCH 08/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A01382.=20=E5=B0=86?= =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E5=8F=98=E5=B9=B3?= =?UTF-8?q?=E8=A1=A1=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/1382.将二叉搜索树变平衡.md | 23 ++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/problems/1382.将二叉搜索树变平衡.md b/problems/1382.将二叉搜索树变平衡.md index bce58c33..8e1cbe37 100644 --- a/problems/1382.将二叉搜索树变平衡.md +++ b/problems/1382.将二叉搜索树变平衡.md @@ -126,6 +126,29 @@ class Solution: Go: JavaScript: +```javascript +var balanceBST = function(root) { + const res = []; + // 中序遍历转成有序数组 + const travesal = cur => { + if(!cur) return; + travesal(cur.left); + res.push(cur.val); + travesal(cur.right); + } + // 有序数组转成平衡二叉树 + const getTree = (nums, left, right) => { + if(left > right) return null; + let mid = left + ((right - left) >> 1); + let root = new TreeNode(nums[mid]);// 中心位置作为当前节点的值 + root.left = getTree(nums, left, mid - 1);// 递归地将区间[left,mid−1] 作为当前节点的左子树 + root.right = getTree(nums, mid + 1, right);// 递归地将区间[mid+1,right] 作为当前节点的左子树 + return root; + } + travesal(root); + return getTree(res, 0, res.length - 1); +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From 03582efc4a2e8532d48e70e9bbfad78de430ed65 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 18:23:48 +0800 Subject: [PATCH 09/32] =?UTF-8?q?Update=200941.=E6=9C=89=E6=95=88=E7=9A=84?= =?UTF-8?q?=E5=B1=B1=E8=84=89=E6=95=B0=E7=BB=84.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0941.有效的山脉数组.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/problems/0941.有效的山脉数组.md b/problems/0941.有效的山脉数组.md index c4c8ebfa..2073ba59 100644 --- a/problems/0941.有效的山脉数组.md +++ b/problems/0941.有效的山脉数组.md @@ -154,6 +154,16 @@ func validMountainArray(arr []int) bool { ## JavaScript ```js +var validMountainArray = function(arr) { + if(arr.length < 3) return false;// 一定不是山脉数组 + let left = 0, right = arr.length - 1;// 双指针 + // 注意防止越界 + while(left < arr.length && arr[left] < arr[left+1]) left++; + while(right>0 && arr[right-1] > arr[right]) right--; + // 如果left或者right都在起始位置,说明不是山峰 + if(left === right && left !== 0 && right !== arr.length - 1) return true; + return false; +}; ``` ----------------------- From db571bd895e46dce7fb7b4d707dd71719e795060 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 18:35:36 +0800 Subject: [PATCH 10/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A0925.=E9=95=BF=E9=94=AE?= =?UTF-8?q?=E6=8C=89=E5=85=A5=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0925.长按键入.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/problems/0925.长按键入.md b/problems/0925.长按键入.md index 70597508..02dca305 100644 --- a/problems/0925.长按键入.md +++ b/problems/0925.长按键入.md @@ -182,6 +182,34 @@ func isLongPressedName(name string, typed string) bool { ``` JavaScript: +```javascript +var isLongPressedName = function(name, typed) { + let i = 0, j = 0; + const m = name.length, n = typed.length; + while(i < m && j < n){ + if(name[i] === typed[j]){ // 相同则同时向后匹配 + i++; j++; + } else { + if(j === 0) return false; // 如果是第一位就不相同直接返回false + // 判断边界为n-1,若为n会越界,例如name:"kikcxmvzi" typed:"kiikcxxmmvvzzz" + while(j < n - 1 && typed[j] === typed[j-1]) j++; + if(name[i] === typed[j]){ // j跨越重复项之后再次和name[i]匹配,相同则同时向后匹配 + i++; j++; + } else { + return false; + } + } + } + // 说明name没有匹配完 例如 name:"pyplrzzzzdsfa" type:"ppyypllr" + if(i < m) return false; + // 说明type没有匹配完 例如 name:"alex" type:"alexxrrrrssda" + while(j < n) { + if(typed[j] === typed[j-1]) j++; + else return false; + } + return true; +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From 224dc5f5612fb916bb6e97fd1026d2bc2c49bd30 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 18:54:45 +0800 Subject: [PATCH 11/32] =?UTF-8?q?Update=200922.=E6=8C=89=E5=A5=87=E5=81=B6?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E6=95=B0=E7=BB=84II.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0922.按奇偶排序数组II.md | 51 ++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/problems/0922.按奇偶排序数组II.md b/problems/0922.按奇偶排序数组II.md index 5b66247e..05cff32a 100644 --- a/problems/0922.按奇偶排序数组II.md +++ b/problems/0922.按奇偶排序数组II.md @@ -209,6 +209,57 @@ func sortArrayByParityII(nums []int) []int { ## JavaScript ```js +//方法一 +var sortArrayByParityII = function(nums) { + const n = nums.length; + // 分别存放 nums 中的奇数、偶数 + let evenIndex = 0, oddIndex = 0; + // 初始化就确定数组大小,节省开销 + const even = new Array(Math.floor(n/2)); + const odd = new Array(Math.floor(n/2)); + // 把A数组放进偶数数组,和奇数数组 + for(let i = 0; i < n; i++){ + if(nums[i] % 2 === 0) even[evenIndex++] = nums[i]; + else odd[oddIndex++] = nums[i]; + } + // 把奇偶数组重新存回 nums + let index = 0; + for(let i = 0; i < even.length; i++){ + nums[index++] = even[i]; + nums[index++] = odd[i]; + } + return nums; +}; + +//方法二 +var sortArrayByParityII = function(nums) { + const n = nums.length; + const result = new Array(n); + // 偶数下标 和 奇数下标 + let evenIndex = 0, oddIndex = 1; + for(let i = 0; i < n; i++){ + if(nums[i] % 2 === 0) { + result[evenIndex] = nums[i]; + evenIndex += 2; + } else { + result[oddIndex] = nums[i]; + oddIndex += 2; + } + } + return result; +}; + +//方法三 +var sortArrayByParityII = function(nums) { + let oddIndex = 1; + for(let i = 0; i < nums.length; i += 2){ + if(nums[i] % 2 === 1){ // 在偶数位遇到了奇数 + while(nums[oddIndex] % 2 !== 0) oddIndex += 2;// 在奇数位找一个偶数 + [nums[oddIndex], nums[i]] = [nums[i], nums[oddIndex]]; // 解构赋值交换 + } + } + return nums; +}; ``` ----------------------- From 8edca00e487878a00b16a296b35ff9a14fb3cb2f Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 20:37:23 +0800 Subject: [PATCH 12/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E724.=20=E5=AF=BB?= =?UTF-8?q?=E6=89=BE=E6=95=B0=E7=BB=84=E7=9A=84=E4=B8=AD=E5=BF=83=E7=B4=A2?= =?UTF-8?q?=E5=BC=95=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0724.寻找数组的中心索引.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/problems/0724.寻找数组的中心索引.md b/problems/0724.寻找数组的中心索引.md index 991ce647..d5fa48ee 100644 --- a/problems/0724.寻找数组的中心索引.md +++ b/problems/0724.寻找数组的中心索引.md @@ -129,6 +129,17 @@ func pivotIndex(nums []int) int { ## JavaScript ```js +var pivotIndex = function(nums) { + const sum = nums.reduce((a,b) => a + b);//求和 + // 中心索引左半和 中心索引右半和 + let leftSum = 0, rightSum = 0; + for(let i = 0; i < nums.length; i++){ + leftSum += nums[i]; + rightSum = sum - leftSum + nums[i];// leftSum 里面已经有 nums[i],多减了一次,所以加上 + if(leftSum === rightSum) return i; + } + return -1; +}; ``` ----------------------- From 5a10b329da87245d11a46564af8e4cb00c122113 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 20:48:55 +0800 Subject: [PATCH 13/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A0673.=20=E6=9C=80?= =?UTF-8?q?=E9=95=BF=E9=80=92=E5=A2=9E=E5=AD=90=E5=BA=8F=E5=88=97=E7=9A=84?= =?UTF-8?q?=E4=B8=AA=E6=95=B0=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0673.最长递增子序列的个数.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/problems/0673.最长递增子序列的个数.md b/problems/0673.最长递增子序列的个数.md index 653edadf..bf0a2a5a 100644 --- a/problems/0673.最长递增子序列的个数.md +++ b/problems/0673.最长递增子序列的个数.md @@ -337,6 +337,28 @@ func findNumberOfLIS(nums []int) int { ## JavaScript ```js +var findNumberOfLIS = function(nums) { + const len = nums.length; + if(len <= 1) return len; + let dp = new Array(len).fill(1); // i之前(包括i)最长递增子序列的长度为dp[i] + let count = new Array(len).fill(1); // 以nums[i]为结尾的字符串,最长递增子序列的个数为count[i] + let res = 0; + for(let i = 1; i < len; i++){ + for(let j = 0; j < i; j++){ + if(nums[i] > nums[j]){ + if(dp[j] + 1 > dp[i]){ // 第 j 个数字为前一个数字的子序列是否更更长 + dp[i] = dp[j] + 1; //更新 dp[i] + count[i] = count[j]; // 重置count[i] + } else if(dp[j] + 1 === dp[i]){ // 和原来一样长 + count[i] += count[j]; //更新count[i] + } + } + } + } + let max = Math.max(...dp); //扩展运算符找到最大长度 + for(let i = 0; i < len; i++) if(dp[i] === max) res += count[i]; // 累加 + return res; +}; ``` ----------------------- From 93f29ed6d5cce50ccaf057a8a3177318c105b344 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 20:55:52 +0800 Subject: [PATCH 14/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20205.=20=E5=90=8C?= =?UTF-8?q?=E6=9E=84=E5=AD=97=E7=AC=A6=E4=B8=B2=20JavaScript=E8=A7=A3?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0205.同构字符串.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/problems/0205.同构字符串.md b/problems/0205.同构字符串.md index 5d20aa4a..1b4d0e32 100644 --- a/problems/0205.同构字符串.md +++ b/problems/0205.同构字符串.md @@ -119,6 +119,25 @@ func isIsomorphic(s string, t string) bool { ## JavaScript ```js +var isIsomorphic = function(s, t) { + let len = s.length; + if(len === 0) return true; + let maps = new Map(); + let mapt = new Map(); + for(let i = 0, j = 0; i < len; i++, j++){ + if(!maps.has(s[i])){ + maps.set(s[i],t[j]);// maps保存 s[i] 到 t[j]的映射 + } + if(!mapt.has(t[i])){ + mapt.set(t[j],s[i]);// mapt保存 t[j] 到 s[i]的映射 + } + // 无法映射,返回 false + if(maps.get(s[i]) !== t[j] || mapt.get(t[j]) !== s[i]){ + return false; + } + }; + return true; +}; ``` ----------------------- From 6158db21aac6409775a20ffb117ab4c8a39801e7 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 20:57:26 +0800 Subject: [PATCH 15/32] =?UTF-8?q?js=E7=89=88=E6=9C=AC=E7=AC=94=E8=AF=AF?= =?UTF-8?q?=EF=BC=8C=E7=A8=8D=E4=BD=9C=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0205.同构字符串.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/problems/0205.同构字符串.md b/problems/0205.同构字符串.md index 1b4d0e32..478b5290 100644 --- a/problems/0205.同构字符串.md +++ b/problems/0205.同构字符串.md @@ -128,7 +128,7 @@ var isIsomorphic = function(s, t) { if(!maps.has(s[i])){ maps.set(s[i],t[j]);// maps保存 s[i] 到 t[j]的映射 } - if(!mapt.has(t[i])){ + if(!mapt.has(t[j])){ mapt.set(t[j],s[i]);// mapt保存 t[j] 到 s[i]的映射 } // 无法映射,返回 false From 65901bdee41eb6071ca6c03209b114bcf562ffd4 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 21:07:45 +0800 Subject: [PATCH 16/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20234.=20=E5=9B=9E?= =?UTF-8?q?=E6=96=87=E9=93=BE=E8=A1=A8=20JavaScript=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0234.回文链表.md | 36 ++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/problems/0234.回文链表.md b/problems/0234.回文链表.md index 631d2f6b..c93e534e 100644 --- a/problems/0234.回文链表.md +++ b/problems/0234.回文链表.md @@ -284,7 +284,41 @@ class Solution: ## JavaScript ```js - +var isPalindrome = function(head) { + const reverseList = head => {// 反转链表 + let temp = null; + let pre = null; + while(head != null){ + temp = head.next; + head.next = pre; + pre = head; + head = temp; + } + return pre; + } + // 如果为空或者仅有一个节点,返回true + if(!head && !head.next) return true; + let slow = head; + let fast = head; + let pre = head; + while(fast != null && fast.next != null){ + pre = slow; // 记录slow的前一个结点 + slow = slow.next; + fast = fast.next.next; + } + pre.next = null; // 分割两个链表 + // 前半部分 + let cur1 = head; + // 后半部分。这里使用了反转链表 + let cur2 = reverseList(slow); + while(cur1 != null){ + if(cur1.val != cur2.val) return false; + // 注意要移动两个结点 + cur1 = cur1.next; + cur2 = cur2.next; + } + return true; +}; ``` From 227bed3396b3695119d5f1169fb15e4840ce50cb Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 21:12:33 +0800 Subject: [PATCH 17/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20141.=20=E7=8E=AF?= =?UTF-8?q?=E5=BD=A2=E9=93=BE=E8=A1=A8=20JavaScript=E8=A7=A3=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0141.环形链表.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/problems/0141.环形链表.md b/problems/0141.环形链表.md index 34b8d25f..14c21b67 100644 --- a/problems/0141.环形链表.md +++ b/problems/0141.环形链表.md @@ -114,6 +114,17 @@ class Solution: ## JavaScript ```js +var hasCycle = function(head) { + let fast = head; + let slow = head; + // 空链表、单节点链表一定不会有环 + while(fast != null && fast.next != null){ + fast = fast.next.next; // 快指针,一次移动两步 + slow = slow.next; // 慢指针,一次移动一步 + if(fast === slow) return true; // 快慢指针相遇,表明有环 + } + return false; // 正常走到链表末尾,表明没有环 +}; ``` ----------------------- From 66b3cac2c7e62e4ee5c4aae316611b39fac740b2 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 21:23:55 +0800 Subject: [PATCH 18/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E70.=E7=88=AC=E6=A5=BC?= =?UTF-8?q?=E6=A2=AF=E5=AE=8C=E5=85=A8=E8=83=8C=E5=8C=85=E7=89=88=E6=9C=AC?= =?UTF-8?q?=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0070.爬楼梯完全背包版本.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/problems/0070.爬楼梯完全背包版本.md b/problems/0070.爬楼梯完全背包版本.md index 4410dbaf..097ecfdb 100644 --- a/problems/0070.爬楼梯完全背包版本.md +++ b/problems/0070.爬楼梯完全背包版本.md @@ -186,6 +186,20 @@ func climbStairs(n int) int { } ``` +JavaScript: +```javascript +var climbStairs = function(n) { + const dp = new Array(n+1).fill(0); + const weight = [1,2]; + dp[0] = 1; + for(let i = 0; i <= n; i++){ //先遍历背包 + for(let j = 0; j < weight.length; j++){ // 再遍历物品 + if(i >= weight[j]) dp[i] += dp[i-weight[j]]; + } + } + return dp[n]; +}; +``` ----------------------- From f34b2472643b6ebc98b16856b90f25835294c0c1 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 21:34:56 +0800 Subject: [PATCH 19/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E34.=E6=9C=B4=E5=AE=9E?= =?UTF-8?q?=E6=97=A0=E5=8D=8E=E7=9A=84=E4=BA=8C=E5=88=86=E6=9F=A5=E6=89=BE?= =?UTF-8?q?=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...元素的第一个和最后一个位置.md | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md index 68dd797d..33694577 100644 --- a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md +++ b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md @@ -396,6 +396,46 @@ class Solution: ## JavaScript ```js +var searchRange = function(nums, target) { + const getLeftBorder = (nums, target) => { + let left = 0, right = nums.length - 1; + let leftBorder = -2;// 记录一下leftBorder没有被赋值的情况 + while(left <= right){ + let middle = left + ((right - left) >> 1); + if(nums[middle] >= target){ // 寻找左边界,nums[middle] == target的时候更新right + right = middle - 1; + leftBorder = right; + } else { + left = middle + 1; + } + } + return leftBorder; + } + + const getRightBorder = (nums, target) => { + let left = 0, right = nums.length - 1; + let rightBorder = -2; // 记录一下rightBorder没有被赋值的情况 + while (left <= right) { + let middle = left + ((right - left) >> 1); + if (nums[middle] > target) { + right = middle - 1; + } else { // 寻找右边界,nums[middle] == target的时候更新left + left = middle + 1; + rightBorder = left; + } + } + return rightBorder; + } + + let leftBorder = getLeftBorder(nums, target); + let rightBorder = getRightBorder(nums, target); + // 情况一 + if(leftBorder === -2 || rightBorder === -2) return [-1,-1]; + // 情况三 + if (rightBorder - leftBorder > 1) return [leftBorder + 1, rightBorder - 1]; + // 情况二 + return [-1, -1]; +}; ``` ----------------------- From 33c2715b85f48365a7eff33ad488af98c23f169c Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 22:03:18 +0800 Subject: [PATCH 20/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E=2031.=20=E4=B8=8B?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E6=8E=92=E5=88=97=20JavaScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0031.下一个排列.md | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/problems/0031.下一个排列.md b/problems/0031.下一个排列.md index 05321a9a..46568fae 100644 --- a/problems/0031.下一个排列.md +++ b/problems/0031.下一个排列.md @@ -132,6 +132,52 @@ class Solution { ## JavaScript ```js +//卡尔的解法(吐槽一下JavaScript的sort和其他语言的不太一样,只想到了拷贝数组去排序再替换原数组来实现nums的[i + 1, nums.length)升序排序) +var nextPermutation = function(nums) { + for(let i = nums.length - 1; i >= 0; i--){ + for(let j = nums.length - 1; j > i; j--){ + if(nums[j] > nums[i]){ + [nums[j],nums[i]] = [nums[i],nums[j]]; // 交换 + // 深拷贝[i + 1, nums.length)部分到新数组arr + let arr = nums.slice(i+1); + // arr升序排序 + arr.sort((a,b) => a - b); + // arr替换nums的[i + 1, nums.length)部分 + nums.splice(i+1,nums.length - i, ...arr); + return; + } + } + } + nums.sort((a,b) => a - b); // 不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 +}; + +//另一种 +var nextPermutation = function(nums) { + let i = nums.length - 2; + // 从右往左遍历拿到第一个左边小于右边的 i,此时 i 右边的数组是从右往左递增的 + while (i >= 0 && nums[i] >= nums[i+1]){ + i--; + } + if (i >= 0){ + let j = nums.length - 1; + // 从右往左遍历拿到第一个大于nums[i]的数,因为之前nums[i]是第一个小于他右边的数,所以他的右边一定有大于他的数 + while (j >= 0 && nums[j] <= nums[i]){ + j--; + } + // 交换两个数 + [nums[j], nums[i]] = [nums[i], nums[j]]; + } + // 对 i 右边的数进行交换 + // 因为 i 右边的数原来是从右往左递增的,把一个较小的值交换过来之后,仍然维持单调递增特性 + // 此时头尾交换并向中间逼近就能获得 i 右边序列的最小值 + let l = i + 1; + let r = nums.length - 1; + while (l < r){ + [nums[l], nums[r]] = [nums[r], nums[l]]; + l++; + r--; + } +}; ``` ----------------------- From 3ddd1a277b3c18cce0f2b687551da406f9a2a1ce Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 22:53:43 +0800 Subject: [PATCH 21/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A05.=20=E6=9C=80=E9=95=BF?= =?UTF-8?q?=E5=9B=9E=E6=96=87=E5=AD=90=E4=B8=B2=20JavaScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0005.最长回文子串.md | 111 ++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/problems/0005.最长回文子串.md b/problems/0005.最长回文子串.md index c78b827c..5897495f 100644 --- a/problems/0005.最长回文子串.md +++ b/problems/0005.最长回文子串.md @@ -297,6 +297,117 @@ class Solution: ## JavaScript ```js +//动态规划解法 +var longestPalindrome = function(s) { + const len = s.length; + // 布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串,如果是dp[i][j]为true,否则为false + let dp = new Array(len).fill(false).map(() => new Array(len).fill(false)); + // left起始位置 maxlenth回文串长度 + let left = 0, maxlenth = 0; + for(let i = len - 1; i >= 0; i--){ + for(let j = i; j < len; j++){ + // 情况一:下标i 与 j相同,同一个字符例如a,当然是回文子串 j - i == 0 + // 情况二:下标i 与 j相差为1,例如aa,也是文子串 j - i == 1 + // 情况一和情况二 可以合并为 j - i <= 1 + // 情况三:下标:i 与 j相差大于1的时候,例如cabac,此时s[i]与s[j]已经相同了,我们看i到j区间是不是回文子串就看aba是不是回文就可以了,那么aba的区间就是 i+1 与 j-1区间,这个区间是不是回文就看dp[i + 1][j - 1]===true + if(s[i] === s[j] && (j - i <= 1 || dp[i + 1][j - 1])){ + dp[i][j] = true; + } + // 只要 dp[i][j] == true 成立,就表示子串 s[i..j] 是回文,此时记录回文长度和起始位置 + if(dp[i][j] && j - i + 1 > maxlenth) { + maxlenth = j - i + 1; // 回文串长度 + left = i; // 起始位置 + } + } + } + return s.substr(left, maxlenth); // 找到子串 +}; + +//双指针 +var longestPalindrome = function(s) { + let left = 0, right = 0, maxLength = 0; + const extend = (s, i, j, n) => {// s为字符串 i,j为双指针 n为字符串长度 + while(i >= 0 && j < n && s[i] === s[j]){ + if(j - i + 1 > maxLength){ + left = i; // 更新开始位置 + right = j; // 更新结尾位置 + maxLength = j - i + 1; // 更新子串最大长度 + } + // 指针移动 + i--; + j++; + } + } + for(let i = 0; i < s.length; i++){ + extend(s, i, i, s.length); // 以i为中心 + extend(s, i, i + 1, s.length); // 以i和i+1为中心 + } + return s.substr(left, maxLength); +}; + +//Manacher算法 +var longestPalindrome = function(s) { + const len = s.length; + if(len < 2) return s; + let maxLength = 1, index = 0; + //Manacher算法,利用回文对称的性质,根据i在上一个回文中心的臂长里的位置去判断i的回文性 + //需要知道上一个回文中心,以及其臂长 + let center = 0; + //注意这里使用了maxRight的而不是真实的臂长length,因为之后需要判断i在臂长的什么位置 + //如果这里臂长用了length,之后还要 计算i - center 去和 length比较,太繁琐 + let maxRight = 0; + //考虑到回文串的长度是偶数的情况,所以这里预处理一下字符串,每个字符间插入特殊字符,把可能性都化为奇数 + //这个处理把回文串长度的可能性都化为了奇数 + //#c#b#b#a# + //#c#b#a#b#d# + let ss = ""; + for(let i = 0; i < s.length; i++){ + ss += "#"+s[i]; + } + ss += "#"; + //需要维护一个每个位置臂长的信息数组positionLength + const pl = new Array(ss.length).fill(0); + //这里需要注意参考的是i关于center对称的点i'的回文性 + //i' = 2*center - i; + //所以列下情况: + //1.i>maxRight,找不到i',无法参考,自己算自己的 + //2.i<=maxRight: + //2.1 i= pl[i‘],大多少需要尝试扩散 + //2.3 i>maxRight-pl[i'],pl[i']的臂长超过了center的臂长,根据对称性,i中心扩散到MaxRight处, + // s[2*i-maxRight] !== s[MaxRight]必不相等,所以pl[i] = maxRight-i; + //总结就是pl[i] = Math.min(maxRight-i,pl[i']);提示i= 0 && right maxRight){ + center = i; + maxRight = pl[i] + i; + } + if (pl[i] * 2 + 1 > maxLength){ + maxLength = pl[i]*2+1; + index = i - pl[i]; + } + } + return ss.substr(index, maxLength).replace(/#/g,""); +}; ``` ----------------------- From a97988ede289ab6b93c029d14134267027b18651 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 23:07:36 +0800 Subject: [PATCH 22/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A0844.=20=E6=AF=94?= =?UTF-8?q?=E8=BE=83=E5=90=AB=E9=80=80=E6=A0=BC=E7=9A=84=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E4=B8=B2=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0844.比较含退格的字符串.md | 58 ++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/problems/0844.比较含退格的字符串.md b/problems/0844.比较含退格的字符串.md index 74455ace..a3199ebe 100644 --- a/problems/0844.比较含退格的字符串.md +++ b/problems/0844.比较含退格的字符串.md @@ -232,6 +232,64 @@ func backspaceCompare(s string, t string) bool { ``` JavaScript: +```javascript +// 双栈 +var backspaceCompare = function(s, t) { + const arrS = [], arrT = []; // 数组作为栈使用 + for(let char of s){ + char === '#' ? arrS.pop() : arrS.push(char); + } + for(let char of t){ + char === '#' ? arrT.pop() : arrT.push(char); + } + return arrS.join('') === arrT.join(''); // 比较两个字符串是否相等 +}; + +//双栈精简 +var backspaceCompare = function(s, t) { + const getString = s => { + let arrS = []; + for(let char of s){ + char === '#' ? arrS.pop() : arrS.push(char); + } + return arrS.join(''); + } + return getString(s) === getString(t); +}; + +//双指针 +var backspaceCompare = function(s, t) { + let sSkipNum = 0; // 记录s的#数量 + let tSkipNum = 0; // 记录t的#数量 + let i = s.length - 1, j = t.length - 1; + while(true) { + while(i >= 0){ // 从后向前,消除s的# + if(s[i] === '#') sSkipNum++; + else { + if (sSkipNum > 0) sSkipNum--; + else break; + } + i--; + } + while (j >= 0) { // 从后向前,消除t的# + if (t[j] === '#') tSkipNum++; + else { + if (tSkipNum > 0) tSkipNum--; + else break; + } + j--; + } + // 后半部分#消除完了,接下来比较s[i] != t[j] + if (i < 0 || j < 0) break; // s 或者t 遍历到头了 + if (s[i] !== t[j]) return false; + i--;j--; + } + // 说明s和t同时遍历完毕 + if (i == -1 && j == -1) return true; + return false; +}; + +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From 4d4cd5baceadfa6dea2515a80f55a1434e13d86f Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 23:26:57 +0800 Subject: [PATCH 23/32] =?UTF-8?q?=E5=A2=9E=E5=8A=A0841.=20=E9=92=A5?= =?UTF-8?q?=E5=8C=99=E5=92=8C=E6=88=BF=E9=97=B4=20JavaScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0841.钥匙和房间.md | 49 ++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/problems/0841.钥匙和房间.md b/problems/0841.钥匙和房间.md index d281dc5a..055a023c 100644 --- a/problems/0841.钥匙和房间.md +++ b/problems/0841.钥匙和房间.md @@ -220,6 +220,55 @@ func canVisitAllRooms(rooms [][]int) bool { ``` JavaScript: +```javascript +//DFS +var canVisitAllRooms = function(rooms) { + const dfs = (key, rooms, visited) => { + if(visited[key]) return; + visited[key] = 1; + for(let k of rooms[key]){ + // 深度优先搜索遍历 + dfs(k, rooms, visited); + } + } + const visited = new Array(rooms.length).fill(false); + dfs(0, rooms, visited); + //检查是否都访问到了 + for (let i of visited) { + if (!i) { + return false; + } + } + return true; +}; + +//BFS +var canVisitAllRooms = function(rooms) { + const bfs = rooms => { + const visited = new Array(rooms.length).fill(0); // 标记房间是否被访问过 + visited[0] = 1; // 0 号房间开始 + const queue = []; //js数组作为队列使用 + queue.push(0); // 0 号房间开始 + // 广度优先搜索的过程 + while(queue.length !== 0){ + let key = queue[0]; + queue.shift(); + for(let k of rooms[key]){ + if(!visited[k]){ + queue.push(k); + visited[k] = 1; + } + } + } + // 检查房间是不是都遍历过了 + for(let i of visited){ + if(i === 0) return false; + } + return true; + } + return bfs(rooms); +}; +``` ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) From 6a9fa6713a0259a0ff65b9ee10a9d25bb7dc8b3d Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Mon, 27 Sep 2021 23:51:56 +0800 Subject: [PATCH 24/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E132.=20=E5=88=86?= =?UTF-8?q?=E5=89=B2=E5=9B=9E=E6=96=87=E4=B8=B2=20II=20JavaScript=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0132.分割回文串II.md | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/problems/0132.分割回文串II.md b/problems/0132.分割回文串II.md index f9cbd618..4cf86496 100644 --- a/problems/0132.分割回文串II.md +++ b/problems/0132.分割回文串II.md @@ -247,6 +247,42 @@ class Solution: ## JavaScript ```js +var minCut = function(s) { + const len = s.length; + // 二维数组isPalindromic来保存整个字符串的回文情况 + const isPalindromic = new Array(len).fill(false).map(() => new Array(len).fill(false)); + for(let i = len - 1; i >= 0; i--){ + for(let j = i; j < len; j++){ + if(s[i] === s[j] && (j - i <= 1 || isPalindromic[i + 1][j - 1])){ + isPalindromic[i][j] = true; + } + } + } + // dp[i]:范围是[0, i]的回文子串,最少分割次数是dp[i] + const dp = new Array(len).fill(0); + for(let i = 0; i < len; i++) dp[i] = i; // 初始化 dp[i]的最大值其实就是i,也就是把每个字符分割出来 + for(let i = 1; i < len; i++){ + if(isPalindromic[0][i]){ // 判断是不是回文子串 + dp[i] = 0; + continue; + } + /* + 如果要对长度为[0, i]的子串进行分割,分割点为j。 + 那么如果分割后,区间[j + 1, i]是回文子串,那么dp[i] 就等于 dp[j] + 1。 + 这里可能有同学就不明白了,为什么只看[j + 1, i]区间,不看[0, j]区间是不是回文子串呢? + 那么在回顾一下dp[i]的定义: 范围是[0, i]的回文子串,最少分割次数是dp[i]。 + [0, j]区间的最小切割数量,我们已经知道了就是dp[j]。 + 此时就找到了递推关系,当切割点j在[0, i] 之间时候,dp[i] = dp[j] + 1; + 本题是要找到最少分割次数,所以遍历j的时候要取最小的dp[i]。dp[i] = Math.min(dp[i], dp[j] + 1); + */ + for(let j = 0; j < i; j++){ + if(isPalindromic[j + 1][i]){ + dp[i] = Math.min(dp[i], dp[j] + 1); + } + } + } + return dp[len - 1]; +}; ``` ----------------------- From 91d01d610c4c8e75b8d2789240f43a52bf8fe378 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Tue, 28 Sep 2021 00:28:04 +0800 Subject: [PATCH 25/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E42.=20=E6=8E=A5?= =?UTF-8?q?=E9=9B=A8=E6=B0=B4=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0042.接雨水.md | 99 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/problems/0042.接雨水.md b/problems/0042.接雨水.md index 16c788eb..5326dd7f 100644 --- a/problems/0042.接雨水.md +++ b/problems/0042.接雨水.md @@ -534,6 +534,105 @@ class Solution: Go: JavaScript: +```javascript +//双指针 +var trap = function(height) { + const len = height.length; + let sum = 0; + for(let i = 0; i < len; i++){ + // 第一个柱子和最后一个柱子不接雨水 + if(i == 0 || i == len - 1) continue; + let rHeight = height[i]; // 记录右边柱子的最高高度 + let lHeight = height[i]; // 记录左边柱子的最高高度 + for(let r = i + 1; r < len; r++){ + if(height[r] > rHeight) rHeight = height[r]; + } + for(let l = i - 1; l >= 0; l--){ + if(height[l] > lHeight) lHeight = height[l]; + } + let h = Math.min(lHeight, rHeight) - height[i]; + if(h > 0) sum += h; + } + return sum; +}; + +//动态规划 +var trap = function(height) { + const len = height.length; + if(len <= 2) return 0; + const maxLeft = new Array(len).fill(0); + const maxRight = new Array(len).fill(0); + // 记录每个柱子左边柱子最大高度 + maxLeft[0] = height[0]; + for(let i = 1; i < len; i++){ + maxLeft[i] = Math.max(height[i], maxLeft[i - 1]); + } + // 记录每个柱子右边柱子最大高度 + maxRight[len - 1] = height[len - 1]; + for(let i = len - 2; i >= 0; i--){ + maxRight[i] = Math.max(height[i], maxRight[i + 1]); + } + // 求和 + let sum = 0; + for(let i = 0; i < len; i++){ + let count = Math.min(maxLeft[i], maxRight[i]) - height[i]; + if(count > 0) sum += count; + } + return sum; +}; + +//单调栈 js数组作为栈 +var trap = function(height) { + const len = height.length; + if(len <= 2) return 0; // 可以不加 + const st = [];// 存着下标,计算的时候用下标对应的柱子高度 + st.push(0); + let sum = 0; + for(let i = 1; i < len; i++){ + if(height[i] < height[st[st.length - 1]]){ // 情况一 + st.push(i); + } + if (height[i] == height[st[st.length - 1]]) { // 情况二 + st.pop(); // 其实这一句可以不加,效果是一样的,但处理相同的情况的思路却变了。 + st.push(i); + } else { // 情况三 + while (st.length !== 0 && height[i] > height[st[st.length - 1]]) { // 注意这里是while + let mid = st[st.length - 1]; + st.pop(); + if (st.length !== 0) { + let h = Math.min(height[st[st.length - 1]], height[i]) - height[mid]; + let w = i - st[st.length - 1] - 1; // 注意减一,只求中间宽度 + sum += h * w; + } + } + st.push(i); + } + } + return sum; +}; + +//单调栈 简洁版本 只处理情况三 +var trap = function(height) { + const len = height.length; + if(len <= 2) return 0; // 可以不加 + const st = [];// 存着下标,计算的时候用下标对应的柱子高度 + st.push(0); + let sum = 0; + for(let i = 1; i < len; i++){ // 只处理的情况三,其实是把情况一和情况二融合了 + while (st.length !== 0 && height[i] > height[st[st.length - 1]]) { // 注意这里是while + let mid = st[st.length - 1]; + st.pop(); + if (st.length !== 0) { + let h = Math.min(height[st[st.length - 1]], height[i]) - height[mid]; + let w = i - st[st.length - 1] - 1; // 注意减一,只求中间宽度 + sum += h * w; + } + } + st.push(i); + } + return sum; +}; +``` C: From 766af43f4e4409f953b96c27ab7ff252a5802b35 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Tue, 28 Sep 2021 00:38:48 +0800 Subject: [PATCH 26/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E129.=20=E6=B1=82?= =?UTF-8?q?=E6=A0=B9=E8=8A=82=E7=82=B9=E5=88=B0=E5=8F=B6=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E6=95=B0=E5=AD=97=E4=B9=8B=E5=92=8C=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0129.求根到叶子节点数字之和.md | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/problems/0129.求根到叶子节点数字之和.md b/problems/0129.求根到叶子节点数字之和.md index 696042a8..9a671404 100644 --- a/problems/0129.求根到叶子节点数字之和.md +++ b/problems/0129.求根到叶子节点数字之和.md @@ -241,6 +241,48 @@ class Solution: Go: JavaScript: +```javascript +var sumNumbers = function(root) { + const listToInt = path => { + let sum = 0; + for(let num of path){ + // sum * 10 表示进位 + sum = sum * 10 + num; + } + return sum; + } + const recur = root =>{ + if (root.left == null && root.right == null) { + // 当是叶子节点的时候,开始处理 + res += listToInt(path); + return; + } + + if (root.left != null){ + // 注意有回溯 + path.push(root.left.val); + recur(root.left); + path.pop(); + } + if (root.right != null){ + // 注意有回溯 + path.push(root.right.val); + recur(root.right); + path.pop(); + } + return; + }; + const path = new Array(); + let res = 0; + // 如果节点为0,那么就返回0 + if (root == null) return 0; + // 首先将根节点放到集合中 + path.push(root.val); + // 开始递归 + recur(root); + return res; +}; +``` From 46c0b8d596c0d986a2fbe1963d14f7808f15d675 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Tue, 28 Sep 2021 01:02:53 +0800 Subject: [PATCH 27/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E684.=20=E5=86=97?= =?UTF-8?q?=E4=BD=99=E8=BF=9E=E6=8E=A5=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0684.冗余连接.md | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/problems/0684.冗余连接.md b/problems/0684.冗余连接.md index bfbdeba9..654ef469 100644 --- a/problems/0684.冗余连接.md +++ b/problems/0684.冗余连接.md @@ -303,6 +303,43 @@ func findRedundantConnection(edges [][]int) []int { ## JavaScript ```js +const n = 1005; +const father = new Array(n); +// 并查集里寻根的过程 +const find = u => { + return u == father[u] ? u : father[u] = find(father[u]); +}; + +// 将v->u 这条边加入并查集 +const join = (u, v) => { + u = find(u); + v = find(v); + if(u == v) return; + father[v] = u; +}; + +// 判断 u 和 v是否找到同一个根,本题用不上 +const same = (u, v) => { + u = find(u); + v = find(v); + return u == v; +}; + +/** + * @param {number[][]} edges + * @return {number[]} + */ +var findRedundantConnection = function(edges) { + // 并查集初始化 + for(let i = 0; i < n; i++){ + father[i] = i; + } + for(let i = 0; i < edges.length; i++){ + if(same(edges[i][0], edges[i][1])) return edges[i]; + else join(edges[i][0], edges[i][1]); + } + return null; +}; ``` ----------------------- From 5c669a05a1bebe0437616bd441a4147a34abc0cb Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Tue, 28 Sep 2021 01:23:08 +0800 Subject: [PATCH 28/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E685.=20=E5=86=97?= =?UTF-8?q?=E4=BD=99=E8=BF=9E=E6=8E=A5=20II=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0685.冗余连接II.md | 85 +++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/problems/0685.冗余连接II.md b/problems/0685.冗余连接II.md index 404813f3..b7a41372 100644 --- a/problems/0685.冗余连接II.md +++ b/problems/0685.冗余连接II.md @@ -515,6 +515,91 @@ func findRedundantDirectedConnection(edges [][]int) []int { ## JavaScript ```js +const N = 1010; // 如题:二维数组大小的在3到1000范围内 +const father = new Array(N); +let n; // 边的数量 + +// 并查集里寻根的过程 +const find = u => { + return u == father[u] ? u : father[u] = find(father[u]); +}; + +// 将v->u 这条边加入并查集 +const join = (u, v) => { + u = find(u); + v = find(v); + if(u == v) return; + father[v] = u; +}; + +// 判断 u 和 v是否找到同一个根 +const same = (u, v) => { + u = find(u); + v = find(v); + return u == v; +}; + +// 在有向图里找到删除的那条边,使其变成树 +const getRemoveEdge = edges => { + // 初始化并查集 + for (let i = 1; i <= n; i++) { + father[i] = i; + } + for (let i = 0; i < n; i++) { // 遍历所有的边 + if (same(edges[i][0], edges[i][1])) { // 构成有向环了,就是要删除的边 + return edges[i]; + } + join(edges[i][0], edges[i][1]); + } + return []; +} + +// 删一条边之后判断是不是树 +const isTreeAfterRemoveEdge = (edges, deleteEdge) => { + // 初始化并查集 + for (let i = 1; i <= n; i++) { + father[i] = i; + } + for (let i = 0; i < n; i++) { + if (i == deleteEdge) continue; + if (same(edges[i][0], edges[i][1])) { // 构成有向环了,一定不是树 + return false; + } + join(edges[i][0], edges[i][1]); + } + return true; +} + +/** + * @param {number[][]} edges + * @return {number[]} + */ +var findRedundantDirectedConnection = function(edges) { + n = edges.length;// 边的数量 + const inDegree = new Array(n+1).fill(0); // 记录节点入度 + for (let i = 0; i < n; i++) { + inDegree[edges[i][1]]++; // 统计入度 + } + let vec = [];// 记录入度为2的边(如果有的话就两条边) + // 找入度为2的节点所对应的边,注意要倒叙,因为优先返回最后出现在二维数组中的答案 + for (let i = n - 1; i >= 0; i--) { + if (inDegree[edges[i][1]] == 2) { + vec.push(i); + } + } + // 处理图中情况1 和 情况2 + // 如果有入度为2的节点,那么一定是两条边里删一个,看删哪个可以构成树 + if (vec.length > 0) { + if (isTreeAfterRemoveEdge(edges, vec[0])) { + return edges[vec[0]]; + } else { + return edges[vec[1]]; + } + } + // 处理图中情况3 + // 明确没有入度为2的情况,那么一定有有向环,找到构成环的边返回就可以了 + return getRemoveEdge(edges); +}; ``` ----------------------- From 31ac0ef5b3f270a722c79d7fbb90a278ce7bf851 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Tue, 28 Sep 2021 11:10:17 +0800 Subject: [PATCH 29/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E143.=20=E9=87=8D?= =?UTF-8?q?=E6=8E=92=E9=93=BE=E8=A1=A8=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0143.重排链表.md | 104 ++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/problems/0143.重排链表.md b/problems/0143.重排链表.md index 2b4e68b7..07c3bb40 100644 --- a/problems/0143.重排链表.md +++ b/problems/0143.重排链表.md @@ -351,6 +351,110 @@ class Solution: Go: JavaScript: +```javascript +// 方法一 使用数组存储节点 +var reorderList = function(head, s = [], tmp) { + let cur = head; + // list是数组,可以使用下标随机访问 + const list = []; + while(cur != null){ + list.push(cur); + cur = cur.next; + } + cur = head; // 重新回到头部 + let l = 1, r = list.length - 1; // 注意左边是从1开始 + let count = 0; + while(l <= r){ + if(count % 2 == 0){ + // even + cur.next = list[r]; + r--; + } else { + // odd + cur.next = list[l]; + l++; + } + // 每一次指针都需要移动 + cur = cur.next; + count++; + } + // 当是偶数的话,需要做额外处理 + if(list.length % 2 == 0){ + cur.next = list[l]; + cur = cur.next; + } + // 注意结尾要结束一波 + cur.next = null; +} + +// 方法二 使用双端队列的方法来解决 js中运行很慢 +var reorderList = function(head, s = [], tmp) { + // js数组作为双端队列 + const deque = []; + // 这里是取head的下一个节点,head不需要再入队了,避免造成重复 + let cur = head.next; + while(cur != null){ + deque.push(cur); + cur = cur.next; + } + cur = head; // 回到头部 + let count = 0; + while(deque.length !== 0){ + if(count % 2 == 0){ + // even,取出队列右边尾部的值 + cur.next = deque.pop(); + } else { + // odd, 取出队列左边头部的值 + cur.next = deque.shift(); + } + cur = cur.next; + count++; + } + cur.next = null; +} + +//方法三 将链表分割成两个链表,然后把第二个链表反转,之后在通过两个链表拼接成新的链表 +var reorderList = function(head, s = [], tmp) { + const reverseList = head => { + let headNode = new ListNode(0); + let cur = head; + let next = null; + while(cur != null){ + next = cur.next; + cur.next = headNode.next; + headNode.next = cur; + cur = next; + } + return headNode.next; + } + + let fast = head, slow = head; + //求出中点 + while(fast.next != null && fast.next.next != null){ + slow = slow.next; + fast = fast.next.next; + } + //right就是右半部分 12345 就是45 1234 就是34 + let right = slow.next; + //断开左部分和右部分 + slow.next = null; + //反转右部分 right就是反转后右部分的起点 + right = reverseList(right); + //左部分的起点 + let left = head; + //进行左右部分来回连接 + //这里左部分的节点个数一定大于等于右部分的节点个数 因此只判断right即可 + while (right != null) { + let curLeft = left.next; + left.next = right; + left = curLeft; + + let curRight = right.next; + right.next = left; + right = curRight; + } +} +``` ----------------------- From 8605f26bd762cd734e697ba7da9b3085d8f9db4d Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Tue, 28 Sep 2021 11:43:20 +0800 Subject: [PATCH 30/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E127.=20=E5=8D=95?= =?UTF-8?q?=E8=AF=8D=E6=8E=A5=E9=BE=99=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0127.单词接龙.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/problems/0127.单词接龙.md b/problems/0127.单词接龙.md index e38453ef..c52f2ba5 100644 --- a/problems/0127.单词接龙.md +++ b/problems/0127.单词接龙.md @@ -141,6 +141,40 @@ public int ladderLength(String beginWord, String endWord, List wordList) ## Go ## JavaScript +```javascript +var ladderLength = function(beginWord, endWord, wordList) { + // 将wordList转成Set,提高查询速度 + const wordSet = new Set(wordList); + // Set元素个数为0 或者 endWord没有在wordSet出现,直接返回0 + if (wordSet.size === 0 || !wordSet.has(endWord)) return 0; + // 记录word是否访问过 + const visitMap = new Map();// + // 初始化队列 + const queue = []; + queue.push(beginWord); + // 初始化visitMap + visitMap.set(beginWord, 1); + + while(queue.length !== 0){ + let word = queue.shift(); // 删除队首元素,将它的值存放在word + let path = visitMap.get(word); // 这个word的路径长度 + for(let i = 0; i < word.length; i++){ // 遍历单词的每个字符 + for (let c = 97; c <= 122; c++) { // 对应26个字母ASCII值 从'a' 到 'z' 遍历替换 + // 拼串得到新的字符串 + let newWord = word.slice(0, i) + String.fromCharCode(c) + word.slice(i + 1); + if(newWord === endWord) return path + 1; // 找到了end,返回path+1 + // wordSet出现了newWord,并且newWord没有被访问过 + if(wordSet.has(newWord) && !visitMap.has(newWord)) { + // 添加访问信息 + visitMap.set(newWord, path + 1); + queue.push(newWord); + } + } + } + } + return 0; +}; +``` ----------------------- From 09a045de9e0741c26c121ed44e81bd448b090e8f Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Tue, 28 Sep 2021 12:13:43 +0800 Subject: [PATCH 31/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E84.=20=E6=9F=B1?= =?UTF-8?q?=E7=8A=B6=E5=9B=BE=E4=B8=AD=E6=9C=80=E5=A4=A7=E7=9A=84=E7=9F=A9?= =?UTF-8?q?=E5=BD=A2=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0084.柱状图中最大的矩形.md | 75 ++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/problems/0084.柱状图中最大的矩形.md b/problems/0084.柱状图中最大的矩形.md index 57df4161..4e11d966 100644 --- a/problems/0084.柱状图中最大的矩形.md +++ b/problems/0084.柱状图中最大的矩形.md @@ -321,4 +321,79 @@ class Solution: return result ``` +JavaScript: +```javascript +//动态规划 js中运行速度最快 +var largestRectangleArea = function(heights) { + const len = heights.length; + const minLeftIndex = new Array(len); + const maxRigthIndex = new Array(len); + // 记录每个柱子 左边第一个小于该柱子的下标 + minLeftIndex[0] = -1; // 注意这里初始化,防止下面while死循环 + for(let i = 1; i < len; i++) { + let t = i - 1; + // 这里不是用if,而是不断向左寻找的过程 + while(t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t]; + minLeftIndex[i] = t; + } + // 记录每个柱子 右边第一个小于该柱子的下标 + maxRigthIndex[len - 1] = len; // 注意这里初始化,防止下面while死循环 + for(let i = len - 2; i >= 0; i--){ + let t = i + 1; + // 这里不是用if,而是不断向右寻找的过程 + while(t < len && heights[t] >= heights[i]) t = maxRigthIndex[t]; + maxRigthIndex[i] = t; + } + // 求和 + let maxArea = 0; + for(let i = 0; i < len; i++){ + let sum = heights[i] * (maxRigthIndex[i] - minLeftIndex[i] - 1); + maxArea = Math.max(maxArea , sum); + } + return maxArea; +}; + +//单调栈 +var largestRectangleArea = function(heights) { + let maxArea = 0; + const stack = []; + heights = [0,...heights,0]; // 数组头部加入元素0 数组尾部加入元素0 + for(let i = 0; i < heights.length; i++){ + if(heights[i] > heights[stack[stack.length-1]]){ // 情况三 + stack.push(i); + } else if(heights[i] === heights[stack[stack.length-1]]){ // 情况二 + stack.pop(); // 这个可以加,可以不加,效果一样,思路不同 + stack.push(i); + } else { // 情况一 + while(heights[i] < heights[stack[stack.length-1]]){// 当前bar比栈顶bar矮 + const stackTopIndex = stack.pop();// 栈顶元素出栈,并保存栈顶bar的索引 + let w = i - stack[stack.length -1] - 1; + let h = heights[stackTopIndex] + // 计算面积,并取最大面积 + maxArea = Math.max(maxArea, w * h); + } + stack.push(i);// 当前bar比栈顶bar高了,入栈 + } + } + return maxArea; +}; + +//单调栈 简洁 +var largestRectangleArea = function(heights) { + let maxArea = 0; + const stack = []; + heights = [0,...heights,0]; // 数组头部加入元素0 数组尾部加入元素0 + for(let i = 0; i < heights.length; i++){ // 只用考虑情况一 当前遍历的元素heights[i]小于栈顶元素heights[stack[stack.length-1]]]的情况 + while(heights[i] < heights[stack[stack.length-1]]){// 当前bar比栈顶bar矮 + const stackTopIndex = stack.pop();// 栈顶元素出栈,并保存栈顶bar的索引 + let w = i - stack[stack.length -1] - 1; + let h = heights[stackTopIndex] + // 计算面积,并取最大面积 + maxArea = Math.max(maxArea, w * h); + } + stack.push(i);// 当前bar比栈顶bar高了,入栈 + } + return maxArea; +}; +```
From 827cc69b7141a7dedfa2c4363c5d827d81383c47 Mon Sep 17 00:00:00 2001 From: jerryfishcode <91447694+jerryfishcode@users.noreply.github.com> Date: Tue, 28 Sep 2021 12:29:50 +0800 Subject: [PATCH 32/32] =?UTF-8?q?=E6=96=B0=E5=A2=9E52.=20N=E7=9A=87?= =?UTF-8?q?=E5=90=8E=20II=20JavaScript=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0052.N皇后II.md | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/problems/0052.N皇后II.md b/problems/0052.N皇后II.md index 1a34f763..d7d7feb8 100644 --- a/problems/0052.N皇后II.md +++ b/problems/0052.N皇后II.md @@ -101,4 +101,48 @@ public: ``` # 其他语言补充 +JavaScript +```javascript +var totalNQueens = function(n) { + let count = 0; + const backtracking = (n, row, chessboard) => { + if(row === n){ + count++; + return; + } + for(let col = 0; col < n; col++){ + if(isValid(row, col, chessboard, n)) { // 验证合法就可以放 + chessboard[row][col] = 'Q'; // 放置皇后 + backtracking(n, row + 1, chessboard); + chessboard[row][col] = '.'; // 回溯 + } + } + } + const isValid = (row, col, chessboard, n) => { + // 检查列 + for(let i = 0; i < row; i++){ // 这是一个剪枝 + if(chessboard[i][col] === 'Q'){ + return false; + } + } + // 检查 45度角是否有皇后 + for(let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--){ + if(chessboard[i][j] === 'Q'){ + return false; + } + } + // 检查 135度角是否有皇后 + for(let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++){ + if(chessboard[i][j] === 'Q'){ + return false; + } + } + return true; + } + + const chessboard = new Array(n).fill([]).map(() => new Array(n).fill('.')); + backtracking(n, 0, chessboard); + return count; +}; +```