From bd1b40e4bc5f32a5c0175966cdbfc1920afb66ce Mon Sep 17 00:00:00 2001 From: mmdapl <2237221210@qq.com> Date: Wed, 5 May 2021 08:04:14 +0800 Subject: [PATCH] [5.5 add nowcoder coding] --- .DS_Store | Bin 8196 -> 8196 bytes 算法/.DS_Store | Bin 6148 -> 8196 bytes 算法/前端/add.js | 46 -------- 算法/前端/count.js | 31 ------ 算法/前端/duplicates.js | 30 ------ 算法/前端/isUSD.js | 46 -------- 算法/前端/removeWithoutCopy.js | 44 -------- 算法/剑指/Readme.md | 35 +++--- 算法/剑指/二分查找/GetNumberOfK.js | 107 +++++++++++++++++++ 算法/剑指/二分查找/minNumberInRotateArray.js | 35 ++++++ 算法/剑指/分治/Power.js | 38 +++++++ 算法/剑指/排列/PrintMinNumber.js | 35 ++++++ 算法/剑指/排列/reOrderArray.js | 34 ++++++ 算法/剑指/贪心思想/maxProfit.js | 32 +++++- 算法/剑指/链表/EntryNodeOfLoop.js | 21 ++++ 算法/剑指/链表/FindFirstCommonNode.js | 48 +++++++++ 算法/剑指/链表/FindKthToTail.js | 74 +++++++++++++ 算法/剑指/链表/Merge.js | 76 +++++++++++++ 算法/剑指/链表/ReverseList.js | 58 ++++++++++ 算法/剑指/链表/deleteDuplication.js | 81 ++++++++++++++ 算法/剑指/链表/printListFromTailToHead.js | 73 +++++++++++++ 21 files changed, 728 insertions(+), 216 deletions(-) delete mode 100644 算法/前端/add.js delete mode 100644 算法/前端/count.js delete mode 100644 算法/前端/duplicates.js delete mode 100644 算法/前端/isUSD.js delete mode 100644 算法/前端/removeWithoutCopy.js create mode 100644 算法/剑指/二分查找/GetNumberOfK.js create mode 100644 算法/剑指/二分查找/minNumberInRotateArray.js create mode 100644 算法/剑指/分治/Power.js create mode 100644 算法/剑指/排列/PrintMinNumber.js create mode 100644 算法/剑指/排列/reOrderArray.js create mode 100644 算法/剑指/链表/EntryNodeOfLoop.js create mode 100644 算法/剑指/链表/FindFirstCommonNode.js create mode 100644 算法/剑指/链表/FindKthToTail.js create mode 100644 算法/剑指/链表/Merge.js create mode 100644 算法/剑指/链表/ReverseList.js create mode 100644 算法/剑指/链表/deleteDuplication.js create mode 100644 算法/剑指/链表/printListFromTailToHead.js diff --git a/.DS_Store b/.DS_Store index 431c2062f52fa6ac840e704b899d29cdaa205bad..fbe501bb51fddbb57bfd3a569009caa56337e481 100644 GIT binary patch delta 56 zcmV-80LTA?K!iY$PXQLOP`eKS7LyDRE0b*yV6zDkQUa675lXYA6Ji9BfO4}3821E| O5)(Q1A~H}Jr!JsL zC_K)!ucX2|SAYV1qGhU)M=n+9MxV95p%u^yXa%$aS^=%V|DXWQY%a!tb6<_>Rx6+t zIFkzS_k)SbSO~GJP=0lwktqOh6t`tTA9;Y}m?0KI>?)L0_*B`02&p1WF@&OH++=fL zA;hjiMJJ)?B*K|Rn4t(cJ9wrvCs9zSTdjarpkD#b-N$JK8GD85J^A}9@>gr#u3htN z*x+L&-T|-wmPI;B(;hj<_RGlj`>lV)tS9L{<_PE!HR+IS^c%De4-b;qDJ#aFrmB3m zV3P&hrXyejvs>^~gD*eP%lDWU0}P*@Pzezyta)T9WK$P5Vg+0 zu7w!YZW{dbqny;{!{eW^JdxWoSxT8|Tt$A*hjpe7RX$-bwTbBBs%%Zfw~G9j_Nc-(!>bBM7gI%QsheR@U_=En z%lZGk!SDZvC0recRzNF|pnw=%DXkPS@b|Yv+=g>)6Lklb3)^)SN(vg8jss;n4m|n8 k5PcJ-%qfJ}Rfsz%r~4v6pa1*};=dK8D*F6qX@<7^0by>M0|%s`DGz1%>; e6=e9v!tczJ`DHvoRxvO^tOdD*VRJms9A*GFa2ufj diff --git a/算法/前端/add.js b/算法/前端/add.js deleted file mode 100644 index 60b11b8..0000000 --- a/算法/前端/add.js +++ /dev/null @@ -1,46 +0,0 @@ -/* - * @Description: - * @Version: Beta1.0 - * @Author: 【B站&公众号】Rong姐姐好可爱 - * @Date: 2021-04-23 07:50:21 - * @LastEditors: 【B站&公众号】Rong姐姐好可爱 - * @LastEditTime: 2021-04-23 22:05:34 - */ - - - -function add(){ - console.log(arguments); - var args=Array.prototype.slice.call(arguments) - console.log(args) - - - var _add=function(){ - console.log('add',arguments) - args.push(...arguments); - - // 返回函数 - return _add; - } - - console.log(args) - - // 对参数数组做求和处理 - - _add.toString=function(){ - // 设置sum的起始值为0 - return args.reduce((sum,item)=>{ - console.log(sum,item) - return sum+item; - }) - } - // 返回函数 - return _add -} - -let str=add(1,6)(2)(3) -console.log(str) -// console.log(String(add(1,6)(2)(3)) ) -// console.log(add(1)(2)(3)) -// console.log(add(1)(2,3,4)) - diff --git a/算法/前端/count.js b/算法/前端/count.js deleted file mode 100644 index 130b82d..0000000 --- a/算法/前端/count.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * @Description: 字符串中字符出现频率计数 - * @Version: Beta1.0 - * @Author: 【B站&公众号】Rong姐姐好可爱 - * @Date: 2021-04-14 10:21:39 - * @LastEditors: 【B站&公众号】Rong姐姐好可爱 - * @LastEditTime: 2021-04-14 10:22:19 - */ - - -function count(str) { - // 转换为数组后去重 - const originArr=str.split('') - const arr=[...new Set(originArr)]; - let result={}; - for(let index=0;index{ - if(item===value){ - count++ - } - }) - // 对象计数 - result[value]=count - } - - } - return result; -} \ No newline at end of file diff --git a/算法/前端/duplicates.js b/算法/前端/duplicates.js deleted file mode 100644 index c6a6700..0000000 --- a/算法/前端/duplicates.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * @Description: 找出数组 arr 中重复出现过的元素 - * @Version: Beta1.0 - * @Author: 【B站&公众号】Rong姐姐好可爱 - * @Date: 2021-04-14 10:22:51 - * @LastEditors: 【B站&公众号】Rong姐姐好可爱 - * @LastEditTime: 2021-04-14 10:22:51 - */ - - -// 找出数组 arr 中重复出现过的元素 -function duplicates(arr) { - const sortArr=arr.sort(); - - let result=new Array() - - const len=sortArr.length; - - for(let index=0;indexvalue!==item) - // // 输出 - // return result; - - // 每次都和arr中的首个元素去比较 - - const len=arr.length; - - for(let index=0;index @@ -45,15 +45,16 @@ ### 链表 -- 从尾到头打印链表 -- 在O(1)时间内删除链表节点 -- 删除链表中重复的结点 -- 链表中倒数第K个结点 -- 链表中环的入口结点 -- 反转链表 -- 合并两个排序的链表 -- 复杂链表的复制 -- 两个链表的第一个公共结点 +- [【简单】合并两个排序的链表](./链表/Merge.js) +- [【简单】两个链表的第一个公共结点](./链表/FindFirstCommonNode.js) +- [【中等】链表中倒数第K个结点](./链表/FindKthToTail.js) +- [【中等】反转链表](./链表/ReverseList.js) +- [【较难】从尾到头打印链表](./链表/printListFromTailToHead.js) +- ~~在O(1)时间内删除链表节点~~ +- [【较难】删除链表中重复的结点](./链表/deleteDuplication.js) +- 链表中环的入口结点[暂时没思路] +- 【较难】复杂链表的复制[暂时没有思路] + ### 树 @@ -78,31 +79,31 @@ ### 贪心思想 - 剪绳子 -- 股票的最大利润 +- [【LeetCode题目】股票的最大利润](./贪心思想/maxProfit.js) ### 二分查找 -- 旋转数组的最小数字 -- 数字在排序数组中出现的次数 +- [【简单】旋转数组的最小数字](./二分查找/minNumberInRotateArray.js) +- [【中等】数字在排序数组中出现的次数](./二分查找/GetNumberOfK.js) ### 分治 -- 数值的整数次方 +- [【中等】数值的整数次方](./分治/Power.js) ### 搜索 -- 矩阵中的路劲 +- 矩阵中的路径 有难度 - 机器人的运动范围 - 字符串的排列 ### 排列 -- 调整数组顺序使奇数位于偶数前面 -- 把数组排成最小的数 +- [【中等】调整数组顺序使奇数位于偶数前面](./排列/reOrderArray.js) +- [【较难】把数组排成最小的数](./双指针/ReverseSentence.js) - 数组中的逆序对 ### 动态规划 diff --git a/算法/剑指/二分查找/GetNumberOfK.js b/算法/剑指/二分查找/GetNumberOfK.js new file mode 100644 index 0000000..dccea9b --- /dev/null +++ b/算法/剑指/二分查找/GetNumberOfK.js @@ -0,0 +1,107 @@ +/* + * @Description: 【中等】数字在排序数组中出现的次数 + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-03 15:36:38 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-03 15:37:54 + */ + +function GetNumberOfK (data, k) { + // write code here + // 注意数组升序 + + let firstIndex = data.indexOf(k); + let lastIndex = data.lastIndexOf(k); + + if (firstIndex === -1 || lastIndex === -1) { + return 0 + } + + return lastIndex - firstIndex < 0 ? 0 : lastIndex - firstIndex + 1 + + +} + +// 利用二分查找 +function GetNumberOfK (data, k) { + // write code here + // 分两次二分查找,知道重复元素首次和最后一次出现位置,相减就能拿到重复次数了. + + // 左侧二分查找,重复元素第一次出现的索引位置 + const left = leftBinarySearch(data, k); + + + // 右侧二分查找,重复元素最后一次出现的索引位置 + const right = rightBinarySearch(data, k); + + console.log(`left:${left}----> right:${right}`) + return left === -1 && right === -1 ? 0 : right - left + 1 +} + +function rightBinarySearch (data, target) { + if (!data.length) { + return -1 + } + let left = 0; + let right = data.length - 1; + + while (left <= right) { + + let mid = left + Math.floor((right - left) / 2); + + if (target === data[mid]) { + left = mid + 1 + } else if (target < data[mid]) { + // 左侧 + right = mid - 1 + } else if (target > data[mid]) { + // 右侧; + left = mid + 1; + } + } + + // left = right+1; 判断出界 + if (right < 0 || data[right] !== target) { + return -1 + } + return right +} + + +// [left,right] +function leftBinarySearch (data, target) { + if (!data.length) { + return -1 + } + let left = 0; + let right = data.length - 1; + + while (left <= right) { + + let mid = left + Math.floor((right - left) / 2); + + if (target === data[mid]) { + // 左侧收缩 + right = mid - 1; + } else if (target < data[mid]) { + // 左侧 + right = mid - 1 + } else if (target > data[mid]) { + // 右侧; + left = mid + 1; + } + } + + + + // left = right+1; 判断出界 + if (left > data.length || data[left] !== target) { + return -1 + } + return left +} + +module.exports = { + GetNumberOfK: GetNumberOfK +}; \ No newline at end of file diff --git a/算法/剑指/二分查找/minNumberInRotateArray.js b/算法/剑指/二分查找/minNumberInRotateArray.js new file mode 100644 index 0000000..135c099 --- /dev/null +++ b/算法/剑指/二分查找/minNumberInRotateArray.js @@ -0,0 +1,35 @@ +/* + * @Description: 【简单】旋转数组的最小数字 + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-03 15:12:26 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-03 15:31:34 + */ + + +// 找出前者大于后者的数,立即返回 +function minNumberInRotateArray (rotateArray) { + // write code here + + if (rotateArray.length < 0) { + return 0 + } + + for (let index = 0; index < rotateArray.length - 1; index++) { + if (rotateArray[index] > rotateArray[index + 1]) { + return rotateArray[index + 1] + } + } + + // 返回 + return rotateArray[0] +} + +// 考虑二分法 +function minNumberInRotateArray01(array){ + +} +module.exports = { + minNumberInRotateArray: minNumberInRotateArray +}; diff --git a/算法/剑指/分治/Power.js b/算法/剑指/分治/Power.js new file mode 100644 index 0000000..0931321 --- /dev/null +++ b/算法/剑指/分治/Power.js @@ -0,0 +1,38 @@ +/* + * @Description: + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-03 15:43:06 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-03 15:44:38 + */ +function Power (base, exponent) { + // write code here + let result = 1; + + if (exponent > 0) { + // 正数 + while (exponent > 0) { + result *= base; + exponent-- + } + return result; + } else if (exponent < 0) { + // 负数 取反 绝对值 abs + // let abs=Math.abs(exponent) + let abs = -exponent; + while (abs > 0) { + result *= base; + abs-- + } + // 分数处理 + return 1 / result; + + } else { + // 0 返回1 + return result; + } +} +module.exports = { + Power: Power +}; \ No newline at end of file diff --git a/算法/剑指/排列/PrintMinNumber.js b/算法/剑指/排列/PrintMinNumber.js new file mode 100644 index 0000000..9e4b32b --- /dev/null +++ b/算法/剑指/排列/PrintMinNumber.js @@ -0,0 +1,35 @@ +/* + * @Description: 【较难】把数组排成最小的数 + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-05 07:58:03 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-05 07:59:26 + */ + + +// 比较s1,s2的时候,注意比较s1+s2 0) { + for (let index = 0; index < numbers.length - 1; index++) { + + if (parseInt(`${numbers[index]}${numbers[index + 1]}`) >= parseInt(`${numbers[index + 1]}${numbers[index]}`)) { + + // 元素交换 + [numbers[index], numbers[index + 1]] = [numbers[index + 1], numbers[index]] + } + } + len-- + } + + + + return numbers.join('') + +} +module.exports = { + PrintMinNumber: PrintMinNumber +}; \ No newline at end of file diff --git a/算法/剑指/排列/reOrderArray.js b/算法/剑指/排列/reOrderArray.js new file mode 100644 index 0000000..9ba1f5a --- /dev/null +++ b/算法/剑指/排列/reOrderArray.js @@ -0,0 +1,34 @@ +/* + * @Description: 【中等】调整数组顺序使奇数位于偶数前面 + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-03 15:56:06 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-05 07:54:38 + */ + +// 利用空间 +function reOrderArray (array) { + // write code here + // 奇数,偶数; + let odd_arr = [], even_arr = []; + for (let index = 0; index < array.length; index++) { + + if (array[index] % 2 !== 0) { + // 奇数 + odd_arr.push(array[index]) + } else { + // 偶数 + even_arr.push(array[index]) + } + } + + // 拼接 + return odd_arr.concat(even_arr) +} + +// 利用冒泡,遇见偶数往最后放,统一前移 + +module.exports = { + reOrderArray: reOrderArray +}; \ No newline at end of file diff --git a/算法/剑指/贪心思想/maxProfit.js b/算法/剑指/贪心思想/maxProfit.js index 9823450..f655482 100644 --- a/算法/剑指/贪心思想/maxProfit.js +++ b/算法/剑指/贪心思想/maxProfit.js @@ -4,10 +4,10 @@ * @Author: 【B站&公众号】Rong姐姐好可爱 * @Date: 2021-04-29 23:27:18 * @LastEditors: 【B站&公众号】Rong姐姐好可爱 - * @LastEditTime: 2021-04-29 23:27:55 + * @LastEditTime: 2021-05-03 15:00:53 */ /** - * + * 暴力 * @param prices int整型一维数组 * @return int整型 */ @@ -29,6 +29,34 @@ function maxProfit (prices) { // 返回最大值 return max; } + +/** + * 处理买点,卖点 + * @param {number[]} prices + * @return {number} + */ +function maxProfit (prices) { + + // 最大收益为0 其他都不算收益 + let max = 0; + // 定义最小的值为买入 + let minPrice = Infinity + for (let index = 0; index < prices.length; index++) { + let start = prices[index]; + // 处理买点 + if (start < minPrice) { + minPrice = start + } + // 处理卖点 + if (start - minPrice > max) { + // 获取最大收益 + max = start - minPrice + } + } + + // 返回最大值 + return max; +}; module.exports = { maxProfit: maxProfit }; \ No newline at end of file diff --git a/算法/剑指/链表/EntryNodeOfLoop.js b/算法/剑指/链表/EntryNodeOfLoop.js new file mode 100644 index 0000000..af06c47 --- /dev/null +++ b/算法/剑指/链表/EntryNodeOfLoop.js @@ -0,0 +1,21 @@ +/* + * @Description: + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-02 15:58:48 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-02 15:58:58 + */ + + +/*function ListNode(x){ + this.val = x; + this.next = null; +}*/ +function EntryNodeOfLoop (pHead) { + // write code here + +} +module.exports = { + EntryNodeOfLoop: EntryNodeOfLoop +}; \ No newline at end of file diff --git a/算法/剑指/链表/FindFirstCommonNode.js b/算法/剑指/链表/FindFirstCommonNode.js new file mode 100644 index 0000000..e296125 --- /dev/null +++ b/算法/剑指/链表/FindFirstCommonNode.js @@ -0,0 +1,48 @@ +/* + * @Description: 【简单】两个链表的第一个公共结点 + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-02 21:33:19 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-02 21:44:24 + */ + + +/*function ListNode(x){ + this.val = x; + this.next = null; +}*/ +function FindFirstCommonNode (pHead1, pHead2) { + // write code here + // 双重循环,时间复杂度过大,考虑优化 + // while(pHead1!==null){ + // let pHead2_back=pHead2 + // while(pHead2_back!==null){ + // if(pHead1===pHead2_back){ + // return pHead1; + // }else{ + // pHead2=pHead2_back.next; + // } + // } + // // 对pHead2从头开始 + // pHead2_back=pHead2 + // pHead1=pHead1.next; + // } + // return null; + + let p1 = pHead1, p2 = pHead2; + + // 其实,这里有个死循环的问题 + while (p1 !== p2) { + // 不相等,则向前,如果后继结点为空,则回到头结点,重复 + p1 = p1 === null ? pHead1 : p1.next; + p2 = p2 === null ? pHead2 : p2.next; + } + + // 返回公共结点 + return p1; + +} +module.exports = { + FindFirstCommonNode: FindFirstCommonNode +}; \ No newline at end of file diff --git a/算法/剑指/链表/FindKthToTail.js b/算法/剑指/链表/FindKthToTail.js new file mode 100644 index 0000000..2ded71b --- /dev/null +++ b/算法/剑指/链表/FindKthToTail.js @@ -0,0 +1,74 @@ +/* + * @Description: + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-02 15:47:20 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-02 15:55:43 + */ + + +/* + * function ListNode(x){ + * this.val = x; + * this.next = null; + * } + */ +/** + * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 + * + * + * @param pHead ListNode类 + * @param k int整型 + * @return ListNode类 + */ +function FindKthToTail (pHead, k) { + // write code here + // 结点不存在返回空 + if (pHead === null) { + return null; + } + // 遍历链表, + let count = 0; + let pre = pHead; + while (pHead) { + // 将数组进行头插 + count++ + pHead = pHead.next; + } + // 链表长度小于k,返回空 + if (count < k) { + return null; + } + // 再对链表进行遍历 + while (count > k) { + count-- + pre = pre.next; + } + // 返回倒数k个结点 + return pre; +} + +// 上面是有两次while一次计数,一次移动指针找到目标结点 +// 可以利用数组,不能是头插入,还是尾插都行,存储的元素为链表的结点,也就是链表的子链表的头指针 +function FindKthToTail01 (pHead, k) { + + let result = [] + while (pHead !== null) { + // 头插 + result.unshift(pHead); + + // 指针后移 + pHead = pHead.next; + } + // k不合法 + if (result.length < k) { + return null + } + // 用尾插的话,返回 result[result.length-k] + return result[k - 1] +} + +module.exports = { + FindKthToTail: FindKthToTail01 +}; \ No newline at end of file diff --git a/算法/剑指/链表/Merge.js b/算法/剑指/链表/Merge.js new file mode 100644 index 0000000..b526302 --- /dev/null +++ b/算法/剑指/链表/Merge.js @@ -0,0 +1,76 @@ +/* + * @Description: 【简单】合并两个排序的链表 + * @Version: Beta1.0 + * @Author: 【B站&公众号】Rong姐姐好可爱 + * @Date: 2021-05-02 17:18:36 + * @LastEditors: 【B站&公众号】Rong姐姐好可爱 + * @LastEditTime: 2021-05-02 17:30:18 + */ + + +function ListNode (x) { + this.val = x; + this.next = null; +} + +// 注意 两个链表都是单调递增 +function Merge (pHead1, pHead2) { + // write code here + let pre = new ListNode(-1); + let result = pre + while (pHead1 !== null && pHead2 !== null) { + if (pHead1.val >= pHead2.val) { + // 前者大,用后者 + result.next = pHead2; + pHead2 = pHead2.next; + } else if (pHead1.val < pHead2.val) { + // 后者大,用前者 + result.next = pHead1; + pHead1 = pHead1.next; + } + // 后移指针 + result = result.next; + } + if (pHead1 !== null) { + // 链表1没有走完 + result.next = pHead1 + } + + if (pHead2 !== null) { + // 链表2没有走完 + result.next = pHead2; + } + // 返回 注意去掉头结点 + return pre.next; +} + +// 思考递归的做法 没有上面迭代好理解 +function Merge01(pHead1,pHead2){ + + + if(pHead1===null){ + return pHead2 + } + + if(pHead2===null){ + return pHead1 + } + + // 前者大于后者, + if(pHead1.val>=pHead2.val){ + // 记住,pHead2向后, + pHead2.next=Merge01(pHead1,pHead2.next) + return pHead2 + } + + // 前者小于后者 + if(pHead1.val