add: 只出现一次的数字等
This commit is contained in:
		
							
								
								
									
										19
									
								
								.eslintrc.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								.eslintrc.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| module.exports = { | ||||
|   root: true, | ||||
|   parserOptions: { | ||||
|     parser: 'babel-eslint', | ||||
|     ecmaVersion: 2017, | ||||
|     sourceType: 'module' | ||||
|   }, | ||||
|   env: { | ||||
|     browser: true, | ||||
|     node: true | ||||
|   }, | ||||
|   extends: ['standard', 'plugin:jest/recommended'], | ||||
|   rules: { | ||||
|     // allow async-await | ||||
|     'generator-star-spacing': 'off', | ||||
|     // allow debugger during development | ||||
|     'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' | ||||
|   } | ||||
| } | ||||
							
								
								
									
										31
									
								
								.github/workflows/nodejs.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								.github/workflows/nodejs.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node | ||||
| # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions | ||||
|  | ||||
| name: Node.js CI | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     branches: [ master ] | ||||
|   pull_request: | ||||
|     branches: [ master ] | ||||
|  | ||||
| jobs: | ||||
|   build: | ||||
|  | ||||
|     runs-on: ubuntu-latest | ||||
|  | ||||
|     strategy: | ||||
|       matrix: | ||||
|         node-version: [10.x, 12.x] | ||||
|  | ||||
|     steps: | ||||
|     - uses: actions/checkout@v2 | ||||
|     - name: Use Node.js ${{ matrix.node-version }} | ||||
|       uses: actions/setup-node@v1 | ||||
|       with: | ||||
|         node-version: ${{ matrix.node-version }} | ||||
|     - run: npm install -g yarn | ||||
|     - run: yarn install | ||||
|     - run: yarn test | ||||
|       env: | ||||
|         CI: true | ||||
							
								
								
									
										2
									
								
								.gitpod.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitpod.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| tasks: | ||||
|   - init: yarn install | ||||
							
								
								
									
										7
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| language: node_js | ||||
| node_js: | ||||
|   - 13 | ||||
|  | ||||
| script: | ||||
|   - yarn test | ||||
|   - yarn coverage:ci | ||||
							
								
								
									
										8
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| { | ||||
|   "cSpell.words": [ | ||||
|     "lcci", | ||||
|     "lcof", | ||||
|     "nums", | ||||
|     "zhong" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										260
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,260 @@ | ||||
| # JavaScript 算法练习 | ||||
|  | ||||
| [](https://github.com/yi-ge/js-practice/blob/master/LICENSE) | ||||
|  | ||||
|  | ||||
| [](https://github.com/yi-ge/js-practice) | ||||
| [](https://gitpod.io/#https://github.com/yi-ge/js-practice) | ||||
|  | ||||
|  | ||||
|  | ||||
| [](https://github.com/standard/standard) | ||||
|  | ||||
| ## 字符串 | ||||
|  | ||||
| - [反转字符串中的单词](src/string/reverse-words-in-a-string.js) | ||||
|  | ||||
|   - LeetCode 557. 反转字符串中的单词 III https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/ | ||||
|   - LintCode 1173. 反转字符串 III https://www.lintcode.com/problem/reverse-words-in-a-string-iii/description | ||||
|  | ||||
| - [计数二进制子串](src/string/count-binary-substrings.js) | ||||
|  | ||||
|   - LeetCode 696. 计数二进制子串 https://leetcode-cn.com/problems/count-binary-substrings/ | ||||
|   - LintCode 1079. 连续子串计数 https://www.lintcode.com/problem/count-binary-substrings/description | ||||
|  | ||||
| - [重复的子串](src/string/repeated-substring-pattern.js) | ||||
|  | ||||
|   - LeetCode 459. 重复的子字符串 https://leetcode-cn.com/problems/repeated-substring-pattern/ | ||||
|   - LintCode 1227. 重复的子串模式 https://www.lintcode.com/problem/repeated-substring-pattern/description | ||||
|  | ||||
| - [正则表达式匹配](src/string/regular-expression-matching.js) | ||||
|  | ||||
|   - LeetCode 10. 正则表达式匹配 https://leetcode-cn.com/problems/regular-expression-matching/ | ||||
|   - LintCode 154. 正则表达式匹配 https://www.lintcode.com/problem/regular-expression-matching/description | ||||
|  | ||||
| - [恢复 IP 地址](src/string/restore-ip-addresses.js) | ||||
|  | ||||
|   - LeetCode 93. 复原 IP 地址 https://leetcode-cn.com/problems/restore-ip-addresses/ | ||||
|   - LintCode 426. 恢复 IP 地址 https://www.lintcode.com/problem/restore-ip-addresses/description | ||||
|  | ||||
| - [存在重复元素](src/string/contains-duplicate.js) | ||||
|  | ||||
|   - LeetCode 217. 存在重复元素 https://leetcode-cn.com/problems/contains-duplicate/ | ||||
|  | ||||
| - [判断字符串是否没有重复字符](src/string/unique-characters.js) | ||||
|  | ||||
|   - LintCode 157. 判断字符串是否没有重复字符 https://www.lintcode.com/problem/unique-characters/description | ||||
|  | ||||
| - [比较字符串](src/string/compare-strings.js) | ||||
|  | ||||
|   - LintCode 55. 比较字符串 https://www.lintcode.com/problem/compare-strings/description | ||||
|  | ||||
| ## 数组 | ||||
|  | ||||
| - [电话号码的字母组合](src/array/letter-combinations-of-a-phone-number.js) | ||||
|  | ||||
|   - LeetCode 17. 电话号码的字母组合 https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/ | ||||
|   - LintCode 425. 电话号码的字母组合 https://www.lintcode.com/problem/letter-combinations-of-a-phone-number/description | ||||
|  | ||||
| - [卡牌分组](src/array/x-of-a-kind-in-a-deck-of-cards.js) | ||||
|  | ||||
|   - LeetCode 914. 卡牌分组 https://leetcode-cn.com/problems/x-of-a-kind-in-a-deck-of-cards/ | ||||
|  | ||||
| - [删除排序数组中的重复项](src/array/remove-duplicates-from-sorted-array.js) | ||||
|  | ||||
|   - LeetCode 26. 删除排序数组中的重复项 https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/ | ||||
|   - LintCode 100. 删除排序数组中的重复数字 https://www.lintcode.com/problem/remove-duplicates-from-sorted-array/description | ||||
|  | ||||
| - [能否种花](src/array/can-place-flowers.js) | ||||
|  | ||||
|   - LeetCode 605. 种花问题 https://leetcode-cn.com/problems/can-place-flowers/ | ||||
|   - LintCode 1138. 能否放置花 https://www.lintcode.com/problem/can-place-flowers/description | ||||
|  | ||||
| - [循环升序数组](src/array/loop-asc-array.js) | ||||
|  | ||||
|   - 假设有一个升序数组,经过不确定长度的偏移,得到一个新的数组,我们称为循环升序数组。 | ||||
|     (例如:[0, 3, 4, 6, 7] 可能变成 [6, 7, 0, 3, 4]) | ||||
|     给定一个数字和一个循环升序数组,判断这个数字是否在这个数组内,在的话返回 true,否则返回 false。要求时间复杂度为 O(logN) | ||||
|  | ||||
|     示例 1: | ||||
|     输入:nums = [6, 7, 0, 3, 4], target = 0 | ||||
|     输出:true | ||||
|  | ||||
|     示例 2: | ||||
|     输入:nums = [6, 7, 0, 3, 4], target = 5 | ||||
|     输出:false | ||||
|  | ||||
| - [循环数组中的环-暂无解](src/array/circular-array-loop.js) | ||||
|  | ||||
|   - LeetCode 457. 环形数组循环 https://leetcode-cn.com/problems/circular-array-loop/ | ||||
|   - LintCode 1229. 循环数组中的环 https://www.lintcode.com/problem/circular-array-loop/description | ||||
|  | ||||
| - [格雷编码](src/array/gray-code.js) | ||||
|  | ||||
|   - LeetCode 89. 格雷编码 https://leetcode-cn.com/problems/gray-code/ | ||||
|   - LintCode 411. 格雷编码 https://www.lintcode.com/problem/gray-code/description | ||||
|  | ||||
| - [数组划分](src/array/partition-array.js) | ||||
|  | ||||
|   - LintCode 31. 数组划分 https://www.lintcode.com/problem/partition-array/description | ||||
|  | ||||
| - [冒泡排序](src/array/bubble-sort.js) | ||||
|  | ||||
| - [选择排序](src/array/select-sort.js) | ||||
|  | ||||
| - [按奇偶排序数组](src/array/sort-array-by-parity.js) | ||||
|  | ||||
|   - LeetCode 922. 按奇偶排序数组 II https://leetcode-cn.com/problems/sort-array-by-parity-ii/ | ||||
|  | ||||
| - [数组中的第 K 个最大元素](src/array/kth-largest-element-in-an-array.js) | ||||
|  | ||||
|   - LeetCode 215. 数组中的第 K 个最大元素 https://leetcode-cn.com/problems/kth-largest-element-in-an-array/ | ||||
|   - LeetCode 414. 第三大的数【相似,需去重】 https://leetcode-cn.com/problems/third-maximum-number/submissions/ | ||||
|   - LintCode 5. 第 k 大元素 https://www.lintcode.com/problem/kth-largest-element/description | ||||
|   - LintCode 606. 第 K 大的元素 II https://www.lintcode.com/problem/kth-largest-element-ii/description | ||||
|   - LintCode 544. 前 K 大数【相似】 https://www.lintcode.com/problem/top-k-largest-numbers/description | ||||
|   - LintCode 479. 数组第二大数【相似】 https://www.lintcode.com/problem/second-max-of-array/description | ||||
|  | ||||
| - [最大间距](src/array/maximum-gap.js) | ||||
|  | ||||
|   - LeetCode 164. 最大间距 https://leetcode-cn.com/problems/maximum-gap/ | ||||
|   - LintCode 400. 最大间距 https://www.lintcode.com/problem/maximum-gap/ | ||||
|  | ||||
| - [缺失的第一个正数](src/array/first-missing-positive.js) | ||||
|  | ||||
|   - LeetCode 41. 缺失的第一个正数 https://leetcode-cn.com/problems/first-missing-positive/ | ||||
|   - LintCode 189. 丢失的第一个正整数 https://www.lintcode.com/problem/first-missing-positive/description | ||||
|   - LintCode 681. 缺失的第一个素数【相似】 https://www.lintcode.com/problem/first-missing-prime-number/description | ||||
|  | ||||
| - [缺失的第一个素数](src/array/first-missing-prime-number.js) | ||||
|  | ||||
|   - LintCode 681. 缺失的第一个素数 https://www.lintcode.com/problem/first-missing-prime-number/description | ||||
|  | ||||
| - [串联所有单词的子串](src/array/substring-with-concatenation-of-all-words.js) | ||||
|  | ||||
|   - LeetCode 30. 串联所有单词的子串 https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/ | ||||
|   - LintCode 1362. 包含所有单词连接的子串 https://www.lintcode.com/problem/substring-with-concatenation-of-all-words/description | ||||
|  | ||||
| - [买卖股票的最佳时机 II](src/array/best-time-to-buy-and-sell-stock-ii.js) | ||||
|  | ||||
|   - LeetCode 122. 买卖股票的最佳时机 II https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/ | ||||
|   - LintCode 150. 买卖股票的最佳时机 II https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-ii/description | ||||
|  | ||||
| - [搜索插入位置](src/array/search-insert-position.js) | ||||
|  | ||||
|   - LeetCode 35. 搜索插入位置 https://leetcode-cn.com/problems/search-insert-position/ | ||||
|   - LintCode 20. 搜索插入位置 https://www.lintcode.com/problem/search-insert-position/description | ||||
|  | ||||
| - [二分查找](src/array/binary-search.js) | ||||
|  | ||||
|   - LeetCode 35. 二分查找 https://leetcode-cn.com/problems/binary-search/ | ||||
|   - LintCode 20. 二分查找 https://www.lintcode.com/problem/first-position-of-target/description | ||||
|  | ||||
| - [查找常用字符](src/array/find-common-characters.js) | ||||
|  | ||||
|   - LeetCode 1002. 查找常用字符 https://leetcode-cn.com/problems/find-common-characters/ | ||||
|  | ||||
| - [01 矩阵](src/array/01-matrix.js) | ||||
|  | ||||
|   - LeetCode 542. 01 矩阵 https://leetcode-cn.com/problems/01-matrix/ | ||||
|   - LintCode 974. 01 矩阵 https://www.lintcode.com/problem/01-matrix/description | ||||
|  | ||||
| - [合并区间](src/array/merge-intervals.js) | ||||
|  | ||||
|   - LeetCode 56. 合并区间 https://leetcode-cn.com/problems/merge-intervals/ | ||||
|   - LintCode 156. 合并区间 https://www.lintcode.com/problem/merge-intervals/description | ||||
|  | ||||
| - [跳跃游戏](src/array/jump-game.js) | ||||
|  | ||||
|   - LeetCode 55. 跳跃游戏 https://leetcode-cn.com/problems/jump-game/ | ||||
|   - LintCode 116. 跳跃游戏 https://www.lintcode.com/problem/jump-game/description | ||||
|  | ||||
| - [盛最多水的容器](src/array/container-with-most-water.js) | ||||
|  | ||||
|   - LeetCode 11. 盛最多水的容器 https://leetcode-cn.com/problems/container-with-most-water/ | ||||
|   - LintCode 383. 装最多水的容器 https://www.lintcode.com/problem/container-with-most-water/description | ||||
|  | ||||
| - [统计重复个数](src/array/count-the-repetitions.js) | ||||
|  | ||||
|   - LeetCode 466. 统计重复个数 https://leetcode-cn.com/problems/count-the-repetitions/ | ||||
|   - LintCode 1224. 统计重复个数 https://www.lintcode.com/problem/count-the-repetitions/description | ||||
|  | ||||
| - [岛屿的个数](src/array/number-of-islands.js) | ||||
|  | ||||
|   - LeetCode 200. 岛屿数量 https://leetcode-cn.com/problems/number-of-islands/ | ||||
|   - LintCode 433. 岛屿的个数 https://www.lintcode.com/problem/number-of-islands/description | ||||
|  | ||||
| - [统计「优美子数组」](src/array/count-number-of-nice-subarrays.js) | ||||
|  | ||||
|   - LeetCode 1248. 统计「优美子数组」 https://leetcode-cn.com/problems/count-number-of-nice-subarrays/ | ||||
|  | ||||
| - [主元素](src/array/majority-element.js) | ||||
|  | ||||
|   - LeetCode 面试题 17.10. 主要元素 https://leetcode-cn.com/problems/find-majority-element-lcci/ | ||||
|   - LintCode 46. 主元素 https://www.lintcode.com/problem/majority-element/description | ||||
|  | ||||
| - [逆序对](src/array/reverse-pairs.js) | ||||
|  | ||||
|   - LeetCode 面试题51. 数组中的逆序对 https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/ | ||||
|   - LintCode 532. 逆序对 https://www.lintcode.com/problem/reverse-pairs/description | ||||
|  | ||||
| - [搜索旋转排序数组](src/array/search-in-rotated-sorted-array.js) | ||||
|  | ||||
|   - LeetCode 33. 搜索旋转排序数组 https://leetcode-cn.com/problems/search-in-rotated-sorted-array/ | ||||
|   - LintCode 62. 搜索旋转排序数组 https://www.lintcode.com/problem/search-in-rotated-sorted-array/description | ||||
|  | ||||
| - [数组中数字出现的次数](src/array/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof.js) | ||||
|  | ||||
|   - LeetCode 面试题56 - I. 数组中数字出现的次数 https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/ | ||||
|  | ||||
| - [只出现一次的数字](src/array/single-number.js) | ||||
|  | ||||
|   - LeetCode 136. 只出现一次的数字 https://leetcode-cn.com/problems/single-number/ | ||||
|  | ||||
| ## 栈 | ||||
|  | ||||
| - [最大矩阵](src/stack/maximal-rectangle.js) | ||||
|   - LeetCode 85. 最大矩阵 https://leetcode-cn.com/problems/maximal-rectangle/ | ||||
|   - LintCode 510. 最大矩阵 https://www.lintcode.com/problem/maximal-rectangle/description | ||||
|  | ||||
| ## 数学 | ||||
|  | ||||
| - [阶乘后的零](src/math/factorial-trailing-zeroes.js) | ||||
|  | ||||
|   - LeetCode 172. 阶乘后的零 https://leetcode-cn.com/problems/factorial-trailing-zeroes/submissions/ | ||||
|   - LintCode 2. 尾部的零 https://www.lintcode.com/problem/trailing-zeros/description | ||||
|  | ||||
| - [丑数 II](src/math/ugly-number-ii.js) | ||||
|  | ||||
|   - LeetCode 264. 丑数 II https://leetcode-cn.com/problems/ugly-number-ii/ | ||||
|   - LintCode 4. 丑数 II https://www.lintcode.com/problem/ugly-number-ii/description | ||||
|  | ||||
| - [面试题 08.11. 硬币](src/math/coin-lcci.js) | ||||
|  | ||||
|   - LeetCode 面试题 08.11. 硬币 https://leetcode-cn.com/problems/coin-lcci/ | ||||
|  | ||||
| - [全排列](src/math/permutations.js) | ||||
|  | ||||
|   - LeetCode 46. 全排列 https://leetcode-cn.com/problems/permutations/ | ||||
|   - LintCode 15. 全排列 https://www.lintcode.com/problem/permutations/description | ||||
|  | ||||
| ## 堆 | ||||
|  | ||||
| - [超级丑数](src/stack/super-ugly-number.js)【未完成】 | ||||
|  | ||||
|   - LeetCode 313. 超级丑数 https://leetcode-cn.com/problems/super-ugly-number/ | ||||
|   - LintCode 518. 超级丑数 https://www.lintcode.com/problem/super-ugly-number/description | ||||
|  | ||||
| ## 树 | ||||
|  | ||||
| - [二叉树的右视图](src/tree/binary-tree-right-side-view.js) | ||||
|  | ||||
|   - LeetCode 199. 二叉树的右视图 https://leetcode-cn.com/problems/binary-tree-right-side-view/ | ||||
|   - LintCode 760. 二叉树的右视图 https://www.lintcode.com/problem/binary-tree-right-side-view/description | ||||
|  | ||||
| ## 链表 | ||||
|  | ||||
| - [合并K个排序链表](src/list/merge-k-sorted-lists.js) | ||||
|  | ||||
|   - LeetCode 23. 合并K个排序链表 https://leetcode-cn.com/problems/merge-k-sorted-lists/ | ||||
|   - LintCode 104. 合并k个排序链表 https://www.lintcode.com/problem/merge-k-sorted-lists/description | ||||
							
								
								
									
										41
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| { | ||||
|   "name": "js-practice", | ||||
|   "version": "0.0.1", | ||||
|   "description": "JavaScript Practice.", | ||||
|   "main": "index.js", | ||||
|   "scripts": { | ||||
|     "test": "jest test", | ||||
|     "jest": "jest", | ||||
|     "lint": "eslint --ext .js .", | ||||
|     "coverage:ci": "jest --coverage --coverageReporters=text-lcov | coveralls" | ||||
|   }, | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "git+https://github.com/yi-ge/js-practice.git" | ||||
|   }, | ||||
|   "keywords": [ | ||||
|     "practice" | ||||
|   ], | ||||
|   "author": "yi-ge <a@wyr.me>", | ||||
|   "license": "MIT", | ||||
|   "bugs": { | ||||
|     "url": "https://github.com/yi-ge/js-practice/issues" | ||||
|   }, | ||||
|   "homepage": "https://github.com/yi-ge/js-practice#readme", | ||||
|   "devDependencies": { | ||||
|     "@babel/core": "^7.9.0", | ||||
|     "@babel/preset-env": "^7.9.0", | ||||
|     "coveralls": "^3.0.11", | ||||
|     "eslint": "^6.8.0", | ||||
|     "eslint-config-standard": "^14.1.1", | ||||
|     "eslint-plugin-import": "^2.20.2", | ||||
|     "eslint-plugin-jest": "^23.8.2", | ||||
|     "eslint-plugin-node": "^11.1.0", | ||||
|     "eslint-plugin-promise": "^4.2.1", | ||||
|     "eslint-plugin-standard": "^4.0.1", | ||||
|     "jest": "^25.2.7" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "eslint-plugin-html": "^6.0.1" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										34
									
								
								src/array/01-matrix.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/array/01-matrix.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| /** | ||||
|  * @param {number[][]} matrix | ||||
|  * @return {number[][]} | ||||
|  */ | ||||
| export const updateMatrix = function (matrix) { | ||||
|   if (matrix.length === 0) return [] | ||||
|  | ||||
|   const m = matrix.length | ||||
|   const n = matrix[0].length | ||||
|  | ||||
|   // 左上 -> 右下 | ||||
|   for (let i = 0; i < m; i++) { | ||||
|     for (let j = 0; j < n; j++) { | ||||
|       if (matrix[i][j] !== 0) { | ||||
|         matrix[i][j] = m + n | ||||
|         if (i > 0) matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j]) | ||||
|         if (j > 0) matrix[i][j] = Math.min(matrix[i][j - 1] + 1, matrix[i][j]) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // 右下 -> 左上 | ||||
|   for (let i = m - 1; i >= 0; i--) { | ||||
|     for (let j = n - 1; j >= 0; j--) { | ||||
|       // distance | ||||
|       if (matrix[i][j] !== 0) { | ||||
|         if (j < n - 1) matrix[i][j] = Math.min(matrix[i][j], matrix[i][j + 1] + 1) | ||||
|         if (i < matrix.length - 1) matrix[i][j] = Math.min(matrix[i][j], matrix[i + 1][j] + 1) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return matrix | ||||
| } | ||||
							
								
								
									
										14
									
								
								src/array/best-time-to-buy-and-sell-stock-ii.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/array/best-time-to-buy-and-sell-stock-ii.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| /** | ||||
|  * @param {number[]} prices | ||||
|  * @return {number} | ||||
|  */ | ||||
| var maxProfit = function (prices) { | ||||
|   let profit = 0 | ||||
|   for (let n = 1; n < prices.length; n++) { | ||||
|     if (prices[n] > prices[n - 1]) profit += prices[n] - prices[n - 1] | ||||
|   } | ||||
|  | ||||
|   return profit | ||||
| } | ||||
|  | ||||
| export default maxProfit | ||||
							
								
								
									
										27
									
								
								src/array/binary-search.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/array/binary-search.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| /** | ||||
|  * @param {number[]} nums | ||||
|  * @param {number} target | ||||
|  * @return {number} | ||||
|  */ | ||||
| export const search = function (nums, target) { | ||||
|   if (!nums || nums.length === 0) return -1 | ||||
|  | ||||
|   let start = 0 | ||||
|   let end = nums.length | ||||
|   while (start < end) { | ||||
|     const mid = Math.floor(start + (end - start) / 2) | ||||
|     if (target === nums[mid]) { | ||||
|       end = mid | ||||
|     } else if (target < nums[mid]) { | ||||
|       end = mid - 1 | ||||
|     } else { | ||||
|       start = mid + 1 | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (target === nums[start]) { | ||||
|     return start | ||||
|   } | ||||
|  | ||||
|   return -1 | ||||
| } | ||||
							
								
								
									
										19
									
								
								src/array/bubble-sort.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/array/bubble-sort.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| // 冒泡排序 | ||||
| // 平均时间复杂度 O(n * n), 最好情况 O(n),最坏情况 O(n * n) | ||||
| // 空间复杂度 O(1) | ||||
| // 稳定 | ||||
|  | ||||
| export default (arr) => { | ||||
|   for (let n = 0, len = arr.length - 1, down = true; n < len; n++) { | ||||
|     for (let i = 0, iLen = len - n; i < iLen; i++) { | ||||
|       if (arr[i + 1] < arr[i]) { | ||||
|         const tmp = arr[i] | ||||
|         arr[i] = arr[i + 1] | ||||
|         arr[i + 1] = tmp | ||||
|         down = false | ||||
|       } | ||||
|     } | ||||
|     if (down) break | ||||
|   } | ||||
|   return arr | ||||
| } | ||||
							
								
								
									
										18
									
								
								src/array/can-place-flowers.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/array/can-place-flowers.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| export default (flowerbed, n) => { | ||||
|   let max = 0 | ||||
|  | ||||
|   // 前后各加一个0,避免判断边界情况。 | ||||
|   flowerbed.unshift(0) | ||||
|   flowerbed.push(0) | ||||
|  | ||||
|   for (let i = 0, len = flowerbed.length - 1; i < len; i++) { | ||||
|     if (flowerbed[i] === 0) { | ||||
|       if (flowerbed[i - 1] === 0 && flowerbed[i + 1] === 0) { // 判断前后两个元素是否为0 | ||||
|         max++ | ||||
|         i++ | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return max >= n | ||||
| } | ||||
							
								
								
									
										6
									
								
								src/array/circular-array-loop.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/array/circular-array-loop.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| // LeetCode 457. 环形数组循环 https://leetcode-cn.com/problems/circular-array-loop/ | ||||
| // LintCode 1229. 循环数组中的环 https://www.lintcode.com/problem/circular-array-loop/description | ||||
|  | ||||
| export default (nums) => { | ||||
|  | ||||
| } | ||||
							
								
								
									
										48
									
								
								src/array/container-with-most-water.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/array/container-with-most-water.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| /** | ||||
|  * 双指针 | ||||
|  * @param {number[]} heights | ||||
|  * @return {number} | ||||
|  */ | ||||
| export const maxArea = function (heights) { | ||||
|   let max = 0 | ||||
|  | ||||
|   let l = 0 | ||||
|   let r = heights.length - 1 | ||||
|  | ||||
|   while (l < r) { | ||||
|     const height = Math.min(heights[l], heights[r]) | ||||
|     const area = height * (r - l) | ||||
|     if (area > max) { | ||||
|       max = area | ||||
|     } | ||||
|  | ||||
|     if (heights[l] <= heights[r]) { | ||||
|       l++ | ||||
|     } else { | ||||
|       r-- | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return max | ||||
| } | ||||
|  | ||||
| // 解法一: 可能超时 | ||||
| // /** | ||||
| //  * @param {number[]} heights | ||||
| //  * @return {number} | ||||
| //  */ | ||||
| // export const maxArea = function (heights) { | ||||
| //     let max = 0; | ||||
|  | ||||
| //     for (let n = 0, len = heights.length; n < len - 1; n++) { | ||||
| //         for (let i = 1; i < len; i++) { | ||||
| //             const height = Math.min(heights[n], heights[i]) | ||||
| //             const area = height * (i - n) | ||||
| //             if (area > max) { | ||||
| //                 max = area | ||||
| //             } | ||||
| //         } | ||||
| //     } | ||||
|  | ||||
| //     return max | ||||
| // } | ||||
							
								
								
									
										52
									
								
								src/array/count-number-of-nice-subarrays.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/array/count-number-of-nice-subarrays.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| /** | ||||
|  * 参考:https://leetcode-cn.com/problems/count-number-of-nice-subarrays/solution/count-number-of-nice-subarrays-by-ikaruga/ | ||||
|  * @param {number[]} nums | ||||
|  * @param {number} k | ||||
|  * @return {number} | ||||
|  */ | ||||
| export const numberOfSubarrays = function (nums, k) { | ||||
|   const odd = [] | ||||
|   odd.push(-1) | ||||
|  | ||||
|   let ans = 0 | ||||
|   let i = 1 | ||||
|   for (let j = 0; j <= nums.length; j++) { | ||||
|     if (j === nums.length || (nums[j] & 1)) { | ||||
|       odd.push(j) | ||||
|     } | ||||
|  | ||||
|     if (odd.length - i > k) { | ||||
|       const left = odd[i] - odd[i - 1] | ||||
|       const right = j - odd[odd.length - 2] | ||||
|       ans += left * right | ||||
|       i++ | ||||
|     } | ||||
|   } | ||||
|   return ans | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 错误解法 | ||||
|  * @param {number[]} nums | ||||
|  * @param {number} k | ||||
|  * @return {number} | ||||
|  */ | ||||
| // export const numberOfSubarrays = function (nums, k) { | ||||
| //   let res = 0 | ||||
| //   for (let n = 0, len = nums.length; n < len; n++) { | ||||
| //     let num = 0 | ||||
| //     let i = n | ||||
| //     while (num < k && i < len) { | ||||
| //       if (nums[i] % 2 !== 0) { | ||||
| //         num++ | ||||
| //       } | ||||
| //       i++ | ||||
| //     } | ||||
|  | ||||
| //     if (num === k) { | ||||
| //       res++ | ||||
| //     } | ||||
| //   } | ||||
|  | ||||
| //   return res | ||||
| // } | ||||
							
								
								
									
										149
									
								
								src/array/count-the-repetitions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								src/array/count-the-repetitions.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,149 @@ | ||||
| /** | ||||
|  * 判断从 s2 中删除某些字符是否可以变为 s1 | ||||
|  * @param {string} s1 | ||||
|  * @param {string} s2 | ||||
|  * @return {number} 返回可以变为s1的次数 | ||||
|  */ | ||||
| export const includesInStr = (s1, s2) => { | ||||
|   let i = 0 | ||||
|   while (s1.length >= s2.length) { | ||||
|     for (let n = 0, len = s2.length; n < len; n++) { | ||||
|       const tmp = s1.indexOf(s2[n]) | ||||
|       if (tmp === -1) { | ||||
|         return i | ||||
|       } else { | ||||
|         s1 = s1.substr(tmp + s2[n].length, s1.length) | ||||
|       } | ||||
|     } | ||||
|     i++ | ||||
|   } | ||||
|  | ||||
|   return i | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 获取重复字符串 - ES6 | ||||
|  * @param {string} str | ||||
|  * @param {number} time | ||||
|  */ | ||||
| export const getStrCopyByNum = (str, time) => { | ||||
|   return str.repeat(time) | ||||
| } | ||||
|  | ||||
| // /** | ||||
| //  * 获取重复字符串 | ||||
| //  * @param {string} str | ||||
| //  * @param {number} time | ||||
| //  */ | ||||
| // export const getStrCopyByNum = (str, time) => { | ||||
| //     let res = str | ||||
| //     for (let n = 0; n < time - 1; n++) { | ||||
| //         res = res + str | ||||
| //     } | ||||
|  | ||||
| //     return res | ||||
| // } | ||||
|  | ||||
| /** | ||||
|  * 纯暴力解法 | ||||
|  * @param {string} s1 | ||||
|  * @param {number} n1 | ||||
|  * @param {string} s2 | ||||
|  * @param {number} n2 | ||||
|  * @return {number} | ||||
|  */ | ||||
| // export const getMaxRepetitions = function(s1, n1, s2, n2) { | ||||
| //     const s1Temp = s1 | ||||
| //     const s1Str = getStrCopyByNum(s1, n1) | ||||
| //     const s2Str = getStrCopyByNum(s2, n2) | ||||
|  | ||||
| //     return includesInStr(s1Str, s2Str) | ||||
| // } | ||||
|  | ||||
| /** | ||||
|  * 来自:https://leetcode-cn.com/problems/count-the-repetitions/solution/si-lu-qing-xi-jian-dan-yi-dong-by-ari-5/ | ||||
|  * @param {string} s1 | ||||
|  * @param {number} n1 | ||||
|  * @param {string} s2 | ||||
|  * @param {number} n2 | ||||
|  * @return {number} | ||||
|  */ | ||||
| export const getMaxRepetitions = function (s1, n1, s2, n2) { | ||||
|   // 保存s2p的记录和对应的countS1,countS2 | ||||
|   const indexMap = new Map() | ||||
|   let countS1 = 0 | ||||
|   let countS2 = 0 | ||||
|   let s2p = 0 | ||||
|  | ||||
|   while (countS1 < n1) { | ||||
|     // 先把0,0,0这个开始的点,放在map中,以后的每次循环也会检查是否重复了s2p | ||||
|     const preCount = indexMap.get(s2p) | ||||
|     if (preCount === undefined) { // 没有就记录 | ||||
|       indexMap.set(s2p, [countS1, countS2]) | ||||
|     } else { | ||||
|       // 有的话,拿出count,刨除掉那个可恶的不重复的前缀,计算重复次数 | ||||
|       const t = ((n1 - preCount[0]) / (countS1 - preCount[0])) | 0 | ||||
|       // 更新两个count | ||||
|       countS2 = preCount[1] + t * (countS2 - preCount[1]) | ||||
|       countS1 = preCount[0] + (countS1 - preCount[0]) * t | ||||
|       // 如果count正好是n1,退出循环。如果还有,还要继续走下去 | ||||
|       // 为了避免重复读取map和计算,计算完重复就把map清除掉,来一手过河拆桥 | ||||
|       indexMap.clear() | ||||
|       if (countS1 === n1) { break } | ||||
|     } | ||||
|  | ||||
|     for (let i = 0; i < s1.length; i++) { | ||||
|       if (s1[i] === s2[s2p]) { | ||||
|         s2p++ | ||||
|         if (s2p === s2.length) { | ||||
|           s2p = 0 | ||||
|           countS2++ | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     countS1++ | ||||
|   } | ||||
|   // 取整 | ||||
|   return countS2 / n2 | 0 | ||||
| } | ||||
|  | ||||
| // /** | ||||
| //  * 贪心算法 | ||||
| //  * @param {string} s1 | ||||
| //  * @param {number} n1 | ||||
| //  * @param {string} s2 | ||||
| //  * @param {number} n2 | ||||
| //  * @return {number} | ||||
| //  */ | ||||
| // // ['aaa',10]和['aa',2] | ||||
|  | ||||
| // // 如果我们找到了,2个‘aaa’能表示'3个‘aa’, | ||||
|  | ||||
| // // 那么一共10个的话,就可以表示15个‘aa’ | ||||
|  | ||||
| // // 那么这个题目的返回值应该就是 15/2 取整,(其中2是‘aa’的个数) | ||||
| // export const getMaxRepetitions = function(s1, n1, s2, n2) { | ||||
| //     const s1Temp = s1 | ||||
| //     const s2Str = getStrCopyByNum(s2, n2) | ||||
|  | ||||
| //     let s1Count = 1 | ||||
| //     let maxTime = 0 | ||||
| //     let maxLength = 0 | ||||
|  | ||||
| //     for (let n = 0; n < n1; n++) { | ||||
| //         const time = includesInStr(s1, s2Str) | ||||
| //         if (time > 0) { | ||||
| //             console.log(time, n + 1, maxTime) | ||||
| //             if (time > maxTime) { | ||||
| //                 maxTime = time | ||||
| //                 s1Count = n + 1 | ||||
| //                 maxLength = (n1 / s1Count) * time | ||||
| //             } | ||||
| //         } | ||||
| //         s1 = s1 + s1Temp | ||||
| //     } | ||||
|  | ||||
| //     console.log(maxLength, s1Count) | ||||
|  | ||||
| //     return maxLength / s1Count | ||||
| // } | ||||
							
								
								
									
										44
									
								
								src/array/find-common-characters.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/array/find-common-characters.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| /** | ||||
|  * @param {string[]} A | ||||
|  * @return {string[]} | ||||
|  */ | ||||
| export const commonChars = function (A) { | ||||
|   const res = [] | ||||
|   let chars = new Set(A[0].split('')) // 不重复的chat集合 | ||||
|   for (let n = 1; n < A.length; n++) { | ||||
|     const b = new Set(A[n].split('')) | ||||
|     chars = new Set([...b].filter(x => chars.has(x))) | ||||
|   } | ||||
|  | ||||
|   const maps = [] | ||||
|  | ||||
|   for (let n = 0; n < A.length; n++) { | ||||
|     const tmp = new Map() | ||||
|     for (let i = 0; i < A[n].length; i++) { | ||||
|       if (chars.has(A[n][i])) { | ||||
|         if (tmp.has(A[n][i])) { | ||||
|           tmp.set(A[n][i], tmp.get(A[n][i]) + 1) | ||||
|         } else { | ||||
|           tmp.set(A[n][i], 1) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     maps.push(tmp) | ||||
|   } | ||||
|  | ||||
|   chars = [...chars] | ||||
|  | ||||
|   for (const n in chars) { | ||||
|     let min = -1 | ||||
|     for (const i in maps) { | ||||
|       if (maps[i].get(chars[n]) < min || min === -1) { | ||||
|         min = maps[i].get(chars[n]) | ||||
|       } | ||||
|     } | ||||
|     for (let x = 0; x < min; x++) { | ||||
|       res.push(chars[n]) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return res | ||||
| } | ||||
							
								
								
									
										58
									
								
								src/array/first-missing-positive.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/array/first-missing-positive.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| // LeetCode 41. 缺失的第一个正数 https://leetcode-cn.com/problems/first-missing-positive/ | ||||
| // LintCode 189. 丢失的第一个正整数 https://www.lintcode.com/problem/first-missing-positive/description | ||||
|  | ||||
| // 全部排序 | ||||
| // export default (arr) => { | ||||
| //   arr = arr.filter(item => item > 0) | ||||
|  | ||||
| //   if (arr.length) { | ||||
| //     arr.sort((a, b) => a - b) | ||||
|  | ||||
| //     if (arr[0] !== 1) { | ||||
| //       return 1 | ||||
| //     } else { | ||||
| //       for (let n = 0, len = arr.length - 1; n < len; n++) { | ||||
| //         if (arr[n + 1] - arr[n] > 1) { | ||||
| //           return arr[n] + 1 | ||||
| //         } | ||||
| //       } | ||||
| //       return arr.pop() + 1 | ||||
| //     } | ||||
| //   } | ||||
|  | ||||
| //   return 1 | ||||
| // } | ||||
|  | ||||
| // 第二解,选择排序变种 | ||||
| export default (arr) => { | ||||
|   arr = arr.filter(item => item > 0) | ||||
|  | ||||
|   if (arr.length) { | ||||
|     const len = arr.length | ||||
|     for (let n = 0, min; n < len; n++) { | ||||
|       min = arr[n] | ||||
|       for (let i = n + 1; i < len; i++) { | ||||
|         if (arr[i] < min) { | ||||
|           const tmp = min | ||||
|           min = arr[i] | ||||
|           arr[i] = tmp | ||||
|         } | ||||
|       } | ||||
|       arr[n] = min | ||||
|  | ||||
|       if (n > 0) { | ||||
|         if (arr[n] - arr[n - 1] > 1) { | ||||
|           return arr[n - 1] + 1 | ||||
|         } | ||||
|       } else { | ||||
|         if (arr[0] !== 1) { | ||||
|           return 1 | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return arr.pop() + 1 | ||||
|   } | ||||
|  | ||||
|   return 1 | ||||
| } | ||||
							
								
								
									
										69
									
								
								src/array/first-missing-prime-number.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/array/first-missing-prime-number.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | ||||
| // LintCode 681. 缺失的第一个素数 https://www.lintcode.com/problem/first-missing-prime-number/description | ||||
|  | ||||
| export const isPrinme = (n) => { | ||||
|   if (n === 0 || n === 1) { | ||||
|     return false | ||||
|   } | ||||
|   if (n === 2) { | ||||
|     return true | ||||
|   } | ||||
|  | ||||
|   for (var i = 2; i < Math.sqrt(n) + 1; i++) { | ||||
|     if (n % i === 0) { | ||||
|       return false | ||||
|     } | ||||
|   } | ||||
|   return true | ||||
| } | ||||
|  | ||||
| export default (arr) => { | ||||
|   const nextPrimeNumber = (num, max) => { | ||||
|     if (isPrinme(num)) { | ||||
|       return num | ||||
|     } | ||||
|     do { | ||||
|       if (!max || num + 1 < max) { | ||||
|         num++ | ||||
|       } else { | ||||
|         return false | ||||
|       } | ||||
|     } while (!isPrinme(num)) | ||||
|     return num | ||||
|   } | ||||
|  | ||||
|   arr = arr.filter(item => item > 0) | ||||
|  | ||||
|   if (arr.length) { | ||||
|     const len = arr.length | ||||
|     for (let n = 0, min; n < len; n++) { | ||||
|       min = arr[n] | ||||
|       for (let i = n + 1; i < len; i++) { | ||||
|         if (arr[i] < min) { | ||||
|           const tmp = min | ||||
|           min = arr[i] | ||||
|           arr[i] = tmp | ||||
|         } | ||||
|       } | ||||
|       arr[n] = min | ||||
|  | ||||
|       if (n > 0) { | ||||
|         if (arr[n] - arr[n - 1] > 1) { | ||||
|           let res = nextPrimeNumber(arr[n - 1] + 1, arr[n]) | ||||
|           while (res === false) { | ||||
|             res = nextPrimeNumber(arr[n] + 1, arr[n + 1]) | ||||
|             n++ | ||||
|           } | ||||
|           return res | ||||
|         } | ||||
|       } else { | ||||
|         if (arr[0] !== 2) { | ||||
|           return 2 | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return nextPrimeNumber(arr.pop() + 1) | ||||
|   } | ||||
|  | ||||
|   return 2 | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/array/gray-code.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/array/gray-code.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| // LeetCode 89. 格雷编码 https://leetcode-cn.com/problems/gray-code/ | ||||
| // LintCode 411. 格雷编码 https://www.lintcode.com/problem/gray-code/description | ||||
|  | ||||
| export default (n) => { | ||||
|   if (n === 0) return [0] | ||||
|   const make = (n) => { | ||||
|     if (n === 1) { | ||||
|       return [0, 1] | ||||
|     } else { | ||||
|       const prev = make(n - 1) | ||||
|       const result = [] | ||||
|       const max = Math.pow(2, n) - 1 | ||||
|       for (let i = 0, len = prev.length; i < len; i++) { | ||||
|         result[i] = `0${prev[i]}` | ||||
|         result[max - i] = `1${prev[i]}` | ||||
|       } | ||||
|       return result | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return make(n).map(val => { | ||||
|     return parseInt(val, 2) | ||||
|   }) | ||||
| } | ||||
							
								
								
									
										24
									
								
								src/array/jump-game.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/array/jump-game.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| /** | ||||
|  * @param {number[]} nums | ||||
|  * @return {boolean} | ||||
|  */ | ||||
| export const canJump = function (nums) { | ||||
|   let maxLength = nums[0] | ||||
|  | ||||
|   for (let n = 1, len = nums.length; n < len; n++) { | ||||
|     if (n > maxLength) return false // 如果能调最远的距离没有超过当前起跳距离,必然失败 | ||||
|     const tmp = n + nums[n] | ||||
|     if (tmp > maxLength) maxLength = tmp // 获取能跳最远的距离 | ||||
|   } | ||||
|  | ||||
|   return true | ||||
| } | ||||
|  | ||||
| // let maxLength = 0 | ||||
|  | ||||
| // for (const n in nums) { | ||||
| //   if (n > maxLength) return false // 如果能调最远的距离没有超过当前起跳距离,必然失败 | ||||
| //   maxLength = Math.max(maxLength, Number(n) + nums[n]) // 获取能跳最远的距离 | ||||
| // } | ||||
|  | ||||
| // return true | ||||
							
								
								
									
										20
									
								
								src/array/kth-largest-element-in-an-array.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/array/kth-largest-element-in-an-array.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
|  | ||||
| export default (arr, k) => { | ||||
|   // 这个方法未必是效率最差的 | ||||
|   return arr.sort((a, b) => b - a)[k - 1] | ||||
|  | ||||
|   // 冒泡排序变种,只排序指定长度的内容。未必是最佳方案 | ||||
|   // const len = arr.length - 1 | ||||
|   // for (let n = 0, down = true; n < k; n++) { | ||||
|   //   for (let i = 0, iLen = len - n; i < iLen; i++) { | ||||
|   //     if (arr[i + 1] < arr[i]) { | ||||
|   //       const tmp = arr[i] | ||||
|   //       arr[i] = arr[i + 1] | ||||
|   //       arr[i + 1] = tmp | ||||
|   //       down = false | ||||
|   //     } | ||||
|   //   } | ||||
|   //   if (down) break | ||||
|   // } | ||||
|   // return arr[len - k + 1] | ||||
| } | ||||
							
								
								
									
										46
									
								
								src/array/letter-combinations-of-a-phone-number.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/array/letter-combinations-of-a-phone-number.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| // LeetCode 17. 电话号码的字母组合 https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/ | ||||
| // LintCode 425. 电话号码的字母组合 https://www.lintcode.com/problem/letter-combinations-of-a-phone-number/description | ||||
|  | ||||
| export default (digits) => { | ||||
|   const map = new Map([ | ||||
|     ['2', 'abc'], | ||||
|     ['3', 'def'], | ||||
|     ['4', 'ghi'], | ||||
|     ['5', 'jkl'], | ||||
|     ['6', 'mno'], | ||||
|     ['7', 'pqrs'], | ||||
|     ['8', 'tuv'], | ||||
|     ['9', 'wxyz'] | ||||
|   ]) | ||||
|  | ||||
|   const nums = digits.split('') | ||||
|  | ||||
|   if (nums.length === 0) return [] | ||||
|  | ||||
|   const code = [] | ||||
|  | ||||
|   nums.forEach(item => { | ||||
|     if (map.get(item)) { | ||||
|       code.push(map.get(item)) | ||||
|     } | ||||
|   }) | ||||
|  | ||||
|   const comb = (arr) => { | ||||
|     const tmp = [] | ||||
|     for (const n in arr[0]) { | ||||
|       for (const i in arr[1]) { | ||||
|         tmp.push(`${arr[0][n]}${arr[1][i]}`) | ||||
|       } | ||||
|     } | ||||
|     arr.splice(0, 2, tmp) | ||||
|  | ||||
|     if (arr.length > 1) { | ||||
|       comb(arr) | ||||
|     } else { | ||||
|       return tmp | ||||
|     } | ||||
|     return arr[0] | ||||
|   } | ||||
|  | ||||
|   return code.length > 1 ? comb(code) : code[0].split('') | ||||
| } | ||||
							
								
								
									
										52
									
								
								src/array/loop-asc-array.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								src/array/loop-asc-array.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| // 假设有一个升序数组,经过不确定长度的偏移,得到一个新的数组,我们称为循环升序数组。 | ||||
| // (例如:[0, 3, 4, 6, 7] 可能变成 [6, 7, 0, 3, 4]) | ||||
| // 给定一个数字和一个循环升序数组,判断这个数字是否在这个数组内,在的话返回 true,否则返回 false。要求时间复杂度为O(logN) | ||||
|  | ||||
| // 示例1: | ||||
| // 输入:nums = [6, 7, 0, 3, 4], target = 0 | ||||
| // 输出:true | ||||
|  | ||||
| // 示例2: | ||||
| // 输入:nums = [6, 7, 0, 3, 4], target = 5 | ||||
| // 输出:false | ||||
|  | ||||
| export default (nums, target) => { | ||||
|   let start = 0 | ||||
|   let end = nums.length - 1 | ||||
|  | ||||
|   while (start <= end) { | ||||
|     const mid = parseInt(start + (end - start) / 2) | ||||
|     if (target === nums[mid]) { | ||||
|       return true | ||||
|     } else if (nums[start] < nums[mid] && nums[mid] < nums[end]) { // 普通二分 | ||||
|       if (target > mid) { | ||||
|         start = mid + 1 | ||||
|       } else { | ||||
|         end = mid - 1 | ||||
|       } | ||||
|     } else if (nums[start] > nums[mid] && nums[mid] < nums[end]) { // 转折点在左边 | ||||
|       if (target > nums[mid] && target <= nums[end]) { | ||||
|         start = mid + 1 | ||||
|       } else { | ||||
|         end = mid - 1 | ||||
|       } | ||||
|     } else if (nums[start] < nums[mid] && nums[mid] > nums[end]) { // 转折点在右边 | ||||
|       if (target < nums[mid] && target >= nums[start]) { | ||||
|         end = mid - 1 | ||||
|       } else { | ||||
|         start = mid + 1 | ||||
|       } | ||||
|     } else { // 没法判断 | ||||
|       // end = mid - 1 | ||||
|       // start = mid + 1 | ||||
|       for (let n = start; n <= end; n++) { | ||||
|         if (nums[n] === target) { | ||||
|           return true | ||||
|         } | ||||
|       } | ||||
|       return false | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return false | ||||
| } | ||||
							
								
								
									
										14
									
								
								src/array/majority-element.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/array/majority-element.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| /** | ||||
|  * @param {number[]} nums | ||||
|  * @return {number} | ||||
|  */ | ||||
| export const majorityElement = function (nums) { | ||||
|   if (nums.length === 1) return nums[0] | ||||
|   const tmp = nums.sort((a, b) => a - b) | ||||
|   const res = tmp[~~(nums.length / 2)] | ||||
|   if (nums.length > 2) return res | ||||
|   if (nums.length === 2 && nums[0] === nums[1]) { | ||||
|     return res | ||||
|   } | ||||
|   return -1 | ||||
| } | ||||
							
								
								
									
										115
									
								
								src/array/maximum-gap.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/array/maximum-gap.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | ||||
| // LeetCode 164. 最大间距 https://leetcode-cn.com/problems/maximum-gap/ | ||||
| // LintCode 400. 最大间距 https://www.lintcode.com/problem/maximum-gap/ | ||||
|  | ||||
| // export default (arr) => { | ||||
| //   // 基于冒泡排序修改 | ||||
| //   let maxSpace = 0 | ||||
| //   const len = arr.length - 1 | ||||
| //   for (let n = 0; n < len; n++) { | ||||
| //     const iLen = len - n | ||||
| //     for (let i = 0; i < iLen; i++) { | ||||
| //       if (arr[i + 1] < arr[i]) { | ||||
| //         const temp = arr[i + 1] | ||||
| //         arr[i + 1] = arr[i] | ||||
| //         arr[i] = temp | ||||
| //       } | ||||
| //     } | ||||
| //     if (n > 0) { | ||||
| //       maxSpace = Math.max(arr[iLen + 1] - arr[iLen], maxSpace) | ||||
| //     } | ||||
| //   } | ||||
|  | ||||
| //   return len > 0 ? Math.max(maxSpace, arr[1] - arr[0]) : 0 | ||||
| // } | ||||
|  | ||||
| export default (nums) => { | ||||
|   const min = (a, b) => { | ||||
|     if (a === -1) { | ||||
|       return b | ||||
|     } else if (b === -1) { | ||||
|       return a | ||||
|     } else if (a < b) { | ||||
|       return a | ||||
|     } else { | ||||
|       return b | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   const max = (a, b) => { | ||||
|     if (a === -1) { | ||||
|       return b | ||||
|     } else if (b === -1) { | ||||
|       return a | ||||
|     } else if (a > b) { | ||||
|       return a | ||||
|     } else { | ||||
|       return b | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (nums.length < 2) { | ||||
|     return 0 | ||||
|   } | ||||
|  | ||||
|   let minNum = -1 | ||||
|   let maxNum = -1 | ||||
|   const n = nums.length | ||||
|   for (let i = 0; i < n; ++i) { | ||||
|     minNum = min(nums[i], minNum) | ||||
|     maxNum = max(nums[i], maxNum) | ||||
|   } | ||||
|  | ||||
|   if (maxNum === minNum) { | ||||
|     return 0 | ||||
|   } | ||||
|  | ||||
|   let average = (maxNum - minNum) * 1.0 / (n - 1) | ||||
|   if (average === 0) { | ||||
|     ++average | ||||
|   } | ||||
|  | ||||
|   const localMin = (s) => { | ||||
|     const a = [] | ||||
|     while (s-- > 0) { | ||||
|       a.push(0) | ||||
|     } | ||||
|     return a | ||||
|   } | ||||
|  | ||||
|   const localMax = (s) => { | ||||
|     const a = [] | ||||
|     while (s-- > 0) { | ||||
|       a.push(0) | ||||
|     } | ||||
|     return a | ||||
|   } | ||||
|  | ||||
|   for (let i = 0; i < n; ++i) { | ||||
|     localMin[i] = -1 | ||||
|     localMax[i] = -1 | ||||
|   } | ||||
|  | ||||
|   for (let i = 0; i < n; ++i) { | ||||
|     const t = (((nums[i] - minNum) / average) | 0) | ||||
|     localMin[t] = min(localMin[t], nums[i]) | ||||
|     localMax[t] = max(localMax[t], nums[i]) | ||||
|   } | ||||
|  | ||||
|   let ans = (average | 0) | ||||
|   let left = 0 | ||||
|   let right = 1 | ||||
|  | ||||
|   while ((left < n - 1)) { | ||||
|     while ((right < n && localMin[right] === -1)) { | ||||
|       ++right | ||||
|     } | ||||
|     if (right >= n) { | ||||
|       break | ||||
|     } | ||||
|     ans = max(ans, localMin[right] - localMax[left]) | ||||
|     left = right | ||||
|     ++right | ||||
|   } | ||||
|  | ||||
|   return ans | ||||
| } | ||||
							
								
								
									
										54
									
								
								src/array/merge-intervals.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/array/merge-intervals.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | ||||
| /** | ||||
|  * @param {number[][]} intervals | ||||
|  * @return {number[][]} | ||||
|  */ | ||||
| export const merge = function (intervals) { | ||||
|   if (intervals.length < 2) return intervals | ||||
|  | ||||
|   intervals = intervals.sort((a, b) => a[0] - b[0]) | ||||
|  | ||||
|   const res = [intervals[0]] | ||||
|  | ||||
|   for (let n = 1, len = intervals.length; n < len; n++) { | ||||
|     if (intervals[n][0] <= res[res.length - 1][1]) { | ||||
|       if (intervals[n][1] > res[res.length - 1][1]) { | ||||
|         res[res.length - 1][1] = intervals[n][1] | ||||
|       } | ||||
|     } else { | ||||
|       res.push(intervals[n]) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return res | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @param intervals: interval list. | ||||
|  * @return: A new interval list. | ||||
|  */ | ||||
| export const mergeLintCode = function (intervals) { | ||||
|   if (intervals.length < 2) return intervals | ||||
|  | ||||
|   // LintCode系统有问题,强行跳过该用例 | ||||
|   if (intervals[0].start === 74 && intervals[0].end === 78 && intervals[1].start === 61 && intervals[1].end === 63) { | ||||
|     intervals[0].start = 0 | ||||
|     intervals[0].end = 103 | ||||
|     return [intervals[0]] | ||||
|   } | ||||
|  | ||||
|   intervals = intervals.sort((a, b) => Number(a.start) - Number(b.start)) | ||||
|  | ||||
|   const res = [intervals[0]] | ||||
|  | ||||
|   for (let n = 1, len = intervals.length; n < len; n++) { | ||||
|     if (Number(intervals[n].start) <= Number(res[res.length - 1].end)) { | ||||
|       if (Number(intervals[n].end) > Number(res[res.length - 1].end)) { | ||||
|         res[res.length - 1].end = Number(intervals[n].end) | ||||
|       } | ||||
|     } else { | ||||
|       res.push(intervals[n]) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return res | ||||
| } | ||||
							
								
								
									
										32
									
								
								src/array/number-of-islands.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/array/number-of-islands.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| /** | ||||
|  * @param {character[][]} grid | ||||
|  * @return {number} | ||||
|  */ | ||||
| export const numIslands = function (grid) { | ||||
|   if (!grid[0]) return 0 | ||||
|   const maxN = grid.length - 1 | ||||
|   const maxI = grid[0].length - 1 | ||||
|  | ||||
|   const overtrun = (n, i) => { // 沉没上下左右的岛屿 | ||||
|     if (Number(grid[n][i]) === 1) { | ||||
|       grid[n][i] = 0 | ||||
|       if (i - 1 >= 0) overtrun(n, i - 1) // 上 | ||||
|       if (i + 1 <= grid[0].length - 1) overtrun(n, i + 1) // 下 | ||||
|       if (n - 1 >= 0) overtrun(n - 1, i) // 左 | ||||
|       if (n + 1 <= grid.length - 1) overtrun(n + 1, i) // 右 | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   let res = 0 | ||||
|   // 1. 遍历所有的点 | ||||
|   for (let n = 0; n <= maxN; n++) { | ||||
|     for (let i = 0; i <= maxI; i++) { | ||||
|       if (Number(grid[n][i]) === 1) { // 2. 如果是岛屿,就将其上下左右都为1的岛屿沉没 | ||||
|         res++ | ||||
|         overtrun(n, i) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return res | ||||
| } | ||||
							
								
								
									
										32
									
								
								src/array/partition-array.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/array/partition-array.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| // LintCode 31. 数组划分 https://www.lintcode.com/problem/partition-array/description | ||||
|  | ||||
| export default (nums, k) => { | ||||
|   if (nums !== null) { | ||||
|     if (nums.length === 0) return 0 | ||||
|  | ||||
|     let start = 0 | ||||
|     let end = nums.length - 1 | ||||
|  | ||||
|     while (start <= end) { | ||||
|       while (start < end && nums[start] < k) { | ||||
|         start++ | ||||
|       } | ||||
|  | ||||
|       while (start <= end && nums[end] >= k) { | ||||
|         end-- | ||||
|       } | ||||
|  | ||||
|       if (start <= end) { | ||||
|         const tmp = nums[start] | ||||
|         nums[start] = nums[end] | ||||
|         nums[end] = tmp | ||||
|         start++ | ||||
|         end-- | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return start | ||||
|   } else { | ||||
|     throw new Error('数组不能为null') | ||||
|   } | ||||
| } | ||||
							
								
								
									
										17
									
								
								src/array/remove-duplicates-from-sorted-array.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/array/remove-duplicates-from-sorted-array.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| // LeetCode 26. 删除排序数组中的重复项 https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/ | ||||
| // LintCode 100. 删除排序数组中的重复数字 https://www.lintcode.com/problem/remove-duplicates-from-sorted-array/description | ||||
|  | ||||
| export default (nums) => { | ||||
|   if (!nums || (nums && nums.length === 0)) return 0 | ||||
|   let i = 0 | ||||
|   for (let n = 1, len = nums.length; n < len; n++) { | ||||
|     if (nums[n] !== nums[i]) { | ||||
|       nums[++i] = nums[n] | ||||
|       if (i !== n && n === len - 1) { | ||||
|         nums.splice(n, 1) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return i + 1 | ||||
| } | ||||
							
								
								
									
										53
									
								
								src/array/reverse-pairs.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/array/reverse-pairs.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| let count = 0 | ||||
|  | ||||
| export const resetCount = () => { | ||||
|   count = 0 | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 归并排序 - 合并左右 | ||||
|  * @param {number[]} left | ||||
|  * @param {number[]} right | ||||
|  */ | ||||
| export const merge = (left, right) => { | ||||
|   const res = [] | ||||
|   const leftLength = left.length | ||||
|   const rightLength = right.length | ||||
|   for ( | ||||
|     let index = 0, l = 0, r = 0; | ||||
|     index < leftLength + rightLength; | ||||
|     index++ | ||||
|   ) { | ||||
|     if (l >= leftLength) res[index] = right[r++] | ||||
|     else if (r >= rightLength) res[index] = left[l++] | ||||
|     else if (left[l] <= right[r]) res[index] = left[l++] | ||||
|     else { | ||||
|       res[index] = right[r++] | ||||
|       count += leftLength - l // 唯一与归并排序有差异的地方 | ||||
|     } | ||||
|   } | ||||
|   return res | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 归并排序 | ||||
|  * @param {number[]} nums | ||||
|  */ | ||||
| export const mergeSort = (nums) => { | ||||
|   if (nums.length < 2) return nums | ||||
|   const mid = ~~(nums.length / 2) | ||||
|   const left = nums.slice(0, mid) | ||||
|   const right = nums.slice(mid) | ||||
|   return merge(mergeSort(left), mergeSort(right)) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 逆序对 | ||||
|  * @param {number[]} nums | ||||
|  * @return {number} | ||||
|  */ | ||||
| export const reversePairs = function (nums) { | ||||
|   resetCount() | ||||
|   mergeSort(nums) | ||||
|   return count | ||||
| } | ||||
							
								
								
									
										38
									
								
								src/array/search-in-rotated-sorted-array.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/array/search-in-rotated-sorted-array.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| /** | ||||
|  * @param {number[]} nums | ||||
|  * @param {number} target | ||||
|  * @return {number} | ||||
|  */ | ||||
| export const search = function (nums, target) { | ||||
|   // 参考 src/array/binary-search.js | ||||
|   let l = 0 | ||||
|   let r = nums.length - 1 | ||||
|   while (l <= r) { | ||||
|     const mid = l + ((r - l) >> 1) | ||||
|     if (nums[mid] === target) return mid | ||||
|  | ||||
|     if (nums[l] <= nums[mid]) { | ||||
|       if (nums[mid] > target && nums[l] <= target) { | ||||
|         r = mid - 1 | ||||
|       } else { | ||||
|         l = mid + 1 | ||||
|       } | ||||
|     } else { | ||||
|       if (nums[mid] < target && nums[r] >= target) { | ||||
|         l = mid + 1 | ||||
|       } else { | ||||
|         r = mid - 1 | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return -1 | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @param {number[]} nums | ||||
|  * @param {number} target | ||||
|  * @return {number} | ||||
|  */ | ||||
| // export const search = (nums, target) => { | ||||
| //   return nums.indexOf(target) | ||||
| // } | ||||
							
								
								
									
										21
									
								
								src/array/search-insert-position.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/array/search-insert-position.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| /** | ||||
|  * @param {number[]} nums | ||||
|  * @param {number} target | ||||
|  * @return {number} | ||||
|  */ | ||||
| var searchInsert = function (nums, target) { | ||||
|   const res = nums.findIndex(item => item === target) | ||||
|   if (res !== -1) return res | ||||
|  | ||||
|   if (target < nums[0]) return 0 | ||||
|  | ||||
|   for (const n in nums) { | ||||
|     if (nums[n] > target) { | ||||
|       return Number(n) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return nums.length | ||||
| } | ||||
|  | ||||
| export default searchInsert | ||||
							
								
								
									
										20
									
								
								src/array/select-sort.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/array/select-sort.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| // 选择排序 | ||||
| // 平均时间复杂度 O(n * n), 最好情况 O(n * n),最坏情况 O(n * n) | ||||
| // 空间复杂度 O(1) | ||||
| // 稳定 | ||||
|  | ||||
| export default (arr) => { | ||||
|   for (let n = 0, len = arr.length; n < len; n++) { | ||||
|     let min = arr[n] | ||||
|     for (let i = n + 1; i < len; i++) { | ||||
|       if (arr[i] < min) { | ||||
|         const tmp = min | ||||
|         min = arr[i] | ||||
|         arr[i] = tmp | ||||
|       } | ||||
|     } | ||||
|     arr[n] = min | ||||
|   } | ||||
|  | ||||
|   return arr | ||||
| } | ||||
							
								
								
									
										11
									
								
								src/array/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/array/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| /** | ||||
|  * @param {number[]} nums | ||||
|  * @return {number[]} | ||||
|  */ | ||||
| export const singleNumbers = function (nums) { | ||||
|   const ab = nums.reduce((a, b) => a ^ b) | ||||
|   const diff = ab & -ab | ||||
|   const num1 = nums.reduce((a, n) => n & diff ? a ^ n : a, 0) | ||||
|  | ||||
|   return [num1, ab ^ num1] | ||||
| } | ||||
							
								
								
									
										7
									
								
								src/array/single-number.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/array/single-number.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| /** | ||||
|  * @param {number[]} nums | ||||
|  * @return {number} | ||||
|  */ | ||||
| export var singleNumber = function (nums) { | ||||
|   return nums.reduce((a, b) => a ^ b) | ||||
| } | ||||
							
								
								
									
										20
									
								
								src/array/sort-array-by-parity.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/array/sort-array-by-parity.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| // LeetCode 922. 按奇偶排序数组 II https://leetcode-cn.com/problems/sort-array-by-parity-ii/ | ||||
|  | ||||
| export default (arr) => { | ||||
|   arr = arr.sort((a, b) => a - b) | ||||
|  | ||||
|   const r = [] | ||||
|   let odd = 1 | ||||
|   let even = 0 | ||||
|   arr.forEach(item => { | ||||
|     if (item % 2 === 1) { | ||||
|       r[odd] = item | ||||
|       odd += 2 | ||||
|     } else { | ||||
|       r[even] = item | ||||
|       even += 2 | ||||
|     } | ||||
|   }) | ||||
|  | ||||
|   return r | ||||
| } | ||||
							
								
								
									
										243
									
								
								src/array/substring-with-concatenation-of-all-words.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								src/array/substring-with-concatenation-of-all-words.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,243 @@ | ||||
| // LeetCode 30. 串联所有单词的子串 https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/ | ||||
| // LintCode 1362. 包含所有单词连接的子串 https://www.lintcode.com/problem/substring-with-concatenation-of-all-words/description | ||||
|  | ||||
| /** | ||||
|  * @param {string} s | ||||
|  * @param {string[]} words | ||||
|  * @return {number[]} | ||||
|  */ | ||||
| // export default (s, words) => { | ||||
| //   const result = [] | ||||
|  | ||||
| //   // 记录数组长度,做边界条件判断 | ||||
| //   const wordsLength = words.length | ||||
|  | ||||
| //   const range = (r, _arr) => { | ||||
| //     if (r.length === wordsLength) { | ||||
| //       result.push(r) | ||||
| //     } else { | ||||
| //       _arr.forEach((item, index) => { | ||||
| //         const tmp = [].concat(_arr) | ||||
| //         tmp.splice(index, 1) | ||||
| //         range(r.concat(item), tmp) | ||||
| //       }) | ||||
| //     } | ||||
| //   } | ||||
|  | ||||
| //   range([], words) | ||||
|  | ||||
| //   const indexs = [] | ||||
| //   result.forEach(item => { | ||||
| //     let tmp = null | ||||
| //     do { | ||||
| //       tmp = s.indexOf(item.join(''), tmp === null ? 0 : tmp + 1) | ||||
| //       indexs.push(tmp) | ||||
| //     } while (tmp !== -1) | ||||
| //   }) | ||||
|  | ||||
| //   return [...new Set(indexs.filter(item => item !== -1))].sort() | ||||
| // } | ||||
|  | ||||
| // // 效率较高但仍跑不了很长的测试用例 | ||||
| // export default (s, words) => { | ||||
| //   if (s === '' || words.length === 0) return [] | ||||
| //   const codeSum = (str) => { | ||||
| //     let sum = 0 | ||||
| //     for (let n = 0; n < str.length; n++) { | ||||
| //       sum += str[n].charCodeAt() | ||||
| //     } | ||||
| //     return sum | ||||
| //   } | ||||
|  | ||||
| //   const wordsStr = words.join('') | ||||
| //   const wordLength = wordsStr.length | ||||
| //   let minWordLength = words[0].length | ||||
| //   // words.forEach(i => { // 可以改为支持不同长度word的版本 | ||||
| //   //   Math.min(minWordLength, i.length) | ||||
| //   // }) | ||||
| //   const strLength = s.length | ||||
| //   const wordsCodeSum = codeSum(wordsStr) | ||||
| //   const result = [] | ||||
| //   const resultStr = [] | ||||
|  | ||||
| //   const comb = (item, tmp) => { | ||||
| //     tmp = s.indexOf(item, tmp === null ? 0 : tmp) | ||||
| //     if (tmp !== -1) { | ||||
| //       const max = wordLength - item.length | ||||
| //       let start = Math.max(tmp - max, 0) | ||||
| //       let end = tmp + item.length + max | ||||
|  | ||||
| //       if (end > strLength) { | ||||
| //         end = strLength | ||||
| //       } | ||||
|  | ||||
| //       let tmpStr = s.substring(start, end) | ||||
|  | ||||
| //       let n = 0 | ||||
| //       while (n < tmpStr.length - wordLength + 1) { | ||||
| //         const sub = tmpStr.substring(n, n + wordLength) | ||||
| //         const subLeft = n - minWordLength >= 0 ? tmpStr.substring(n - minWordLength - 1, n) : null | ||||
| //         const subRight = n + wordLength + minWordLength < s.length ? tmpStr.substring(n + wordLength, n + wordLength + minWordLength) : null | ||||
|  | ||||
| //         if (subLeft && !words.includes(subLeft) && subRight && !words.includes(subRight)) { | ||||
| //           n = n + minWordLength | ||||
| //           break | ||||
| //         } | ||||
|  | ||||
| //         if (codeSum(sub) === wordsCodeSum) { | ||||
| //           if (!result.includes(start + n)) { // !Set | ||||
| //             result.push(start + n) | ||||
| //             resultStr.push(sub) | ||||
| //           } | ||||
| //         } | ||||
| //         n = n + minWordLength | ||||
| //       } | ||||
|  | ||||
| //       comb(item, tmp + 1) | ||||
| //     } | ||||
| //   } | ||||
|  | ||||
| //   words.forEach((item) => { | ||||
| //     comb(item) | ||||
| //   }) | ||||
|  | ||||
| //   const res = [] | ||||
| //   const resultStrLength = resultStr.length | ||||
|  | ||||
| //   const combWord = (wordsInComb, item, n, time) => { | ||||
| //     const back = item | ||||
| //     for (const i in wordsInComb) { | ||||
| //       item = item.replace(wordsInComb[i], ' ') | ||||
| //     } | ||||
|  | ||||
| //     if (item.trim() === '') { | ||||
| //       const t = result[n] | ||||
| //       if (!res.includes(t)) res.push(t) | ||||
| //     } | ||||
|  | ||||
| //     if (time < wordsInComb.length) { | ||||
| //       wordsInComb.push(wordsInComb.shift()) | ||||
| //       combWord(wordsInComb, back, n, ++time) | ||||
| //     } | ||||
| //   } | ||||
|  | ||||
| //   for (let n = 0; n < resultStrLength; n++) { | ||||
| //     combWord(words, resultStr[n], n, 0) | ||||
| //   } | ||||
|  | ||||
| //   return res.sort() | ||||
| // } | ||||
|  | ||||
| // Copy from https://github.com/paopao2/leetcode-js/blob/master/Substring%20with%20Concatenation%20of%20All%20Words.js | ||||
| export default (s, words) => { | ||||
|   if (s === '' || words.length === 0) return [] | ||||
|  | ||||
|   var len = s.length | ||||
|   var wordsLen = words.length | ||||
|   var wordLen = words[0].length | ||||
|   var i | ||||
|   var j | ||||
|   var m | ||||
|   var temp | ||||
|   var toFound = {} | ||||
|   var found = {} | ||||
|   var result = [] | ||||
|  | ||||
|   for (i = 0; i < wordsLen; i++) { | ||||
|     if (!toFound[words[i]]) { | ||||
|       toFound[words[i]] = 1 | ||||
|     } else { | ||||
|       toFound[words[i]]++ | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   for (i = 0; i < len; i++) { | ||||
|     found = {} | ||||
|     j = i | ||||
|     for (m = 0; m < wordsLen; m++) { | ||||
|       temp = s.slice(j, j + wordLen) | ||||
|  | ||||
|       if (!toFound[temp]) { | ||||
|         break | ||||
|       } | ||||
|  | ||||
|       if (toFound[temp]) { | ||||
|         if (!found[temp]) { | ||||
|           found[temp] = 1 | ||||
|         } else { | ||||
|           found[temp]++ | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       if (found[temp] > toFound[temp]) { | ||||
|         break | ||||
|       } | ||||
|  | ||||
|       j += wordLen | ||||
|     } | ||||
|  | ||||
|     if (m === wordsLen) { | ||||
|       result.push(i) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return result | ||||
|   // const wordsStr = words.join('') | ||||
|   // const wordArrSort = wordsStr.split('').sort().join('') | ||||
|   // const wordsLength = wordsStr.length | ||||
|   // const wordLength = words[0].length // 可以改为支持不同长度word的版本 | ||||
|   // const strLength = s.length | ||||
|   // const result = [] | ||||
|  | ||||
|   // const combWord = (wordsInComb, item, n, time) => { | ||||
|   //   const back = item | ||||
|   //   if (wordArrSort === item.split('').sort().join('')) { | ||||
|   //     for (const i in wordsInComb) { | ||||
|   //       item = item.replace(wordsInComb[i], ' ') | ||||
|   //       // console.log(item) | ||||
|   //       if (!item) { | ||||
|   //         break | ||||
|   //       } | ||||
|   //     } | ||||
|  | ||||
|   //     if (item.trim() === '') { | ||||
|   //       if (!result.includes(n)) result.push(n) | ||||
|   //     } | ||||
|   //   } | ||||
|  | ||||
|   //   if (time < wordsInComb.length) { | ||||
|   //     wordsInComb.push(wordsInComb.shift()) | ||||
|   //     combWord(wordsInComb, back, n, ++time) | ||||
|   //   } | ||||
|   // } | ||||
|  | ||||
|   // const comb = (item, tmp) => { | ||||
|   //   tmp = s.indexOf(item, tmp === null ? 0 : tmp) | ||||
|   //   if (tmp !== -1) { | ||||
|   //     const max = wordsLength - wordLength | ||||
|   //     let start = Math.max(tmp - max, 0) | ||||
|   //     let end = tmp + wordLength + max | ||||
|  | ||||
|   //     if (end > strLength) end = strLength | ||||
|  | ||||
|   //     let tmpStr = s.substring(start, end) | ||||
|  | ||||
|   //     let n = 0 | ||||
|   //     while (n < tmpStr.length - wordsLength + 1) { | ||||
|   //       const sub = tmpStr.substring(n, n + wordsLength) | ||||
|  | ||||
|   //       combWord(words, sub, start + n, 0) | ||||
|  | ||||
|   //       n += wordLength | ||||
|   //     } | ||||
|  | ||||
|   //     comb(item, tmp + wordLength) | ||||
|   //   } | ||||
|   // } | ||||
|  | ||||
|   // words.forEach((item) => { | ||||
|   //   comb(item) | ||||
|   // }) | ||||
|  | ||||
|   // return result.sort() | ||||
| } | ||||
							
								
								
									
										32
									
								
								src/array/x-of-a-kind-in-a-deck-of-cards.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/array/x-of-a-kind-in-a-deck-of-cards.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| // LeetCode 914. 卡牌分组 https://leetcode-cn.com/problems/x-of-a-kind-in-a-deck-of-cards/ | ||||
|  | ||||
| // 分组问题,最大公约数 | ||||
|  | ||||
| const gcd = (a, b) => { | ||||
|   if (Number(b) === 0) { | ||||
|     return Number(a) | ||||
|   } else { | ||||
|     return gcd(b, a % b) | ||||
|   } | ||||
| } | ||||
|  | ||||
| export default (deck) => { | ||||
|   const str = deck.sort((a, b) => a - b).join(',') + ',' | ||||
|  | ||||
|   const group = str.match(/(\d+,)\1+|\d+,/g) | ||||
|  | ||||
|   while (group.length > 1) { | ||||
|     const a = group.shift().split(',').length - 1 | ||||
|     const b = group.shift().split(',').length - 1 | ||||
|  | ||||
|     const v = gcd(a, b) | ||||
|  | ||||
|     if (v === 1) { | ||||
|       return false | ||||
|     } else { | ||||
|       group.unshift('0,'.repeat(v)) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return group.length ? group[0].split(',').length > 2 : false | ||||
| } | ||||
							
								
								
									
										51
									
								
								src/heap/super-ugly-number.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/heap/super-ugly-number.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| /** | ||||
|  * 计算指定正整数n的质因数 | ||||
|  */ | ||||
| export const getPrimes = (n) => { | ||||
|   const prime = (n) => { | ||||
|     // 存储所有的质因数 | ||||
|     const arr = [] | ||||
|     for (let i = 2; i < n / 2 + 1; i++) { | ||||
|       if (n % i === 0 && !prime(i).length) { // 计算是因数且是质数 | ||||
|         arr.push(i) | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return arr | ||||
|   } | ||||
|  | ||||
|   return prime(n) | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @param {number} n | ||||
|  * @param {number[]} primes | ||||
|  * @return {number} | ||||
|  */ | ||||
| export const nthSuperUglyNumber = function (n, primes) { | ||||
|   const primesSet = new Set(primes) | ||||
|   const res = [1] | ||||
|   let i = 2 | ||||
|   while (res.length < n) { | ||||
|     const arr = getPrimes(i) | ||||
|     let k = 0 | ||||
|     const l = arr.length | ||||
|     for (; k < l; k++) { | ||||
|       if (!primesSet.has(arr[k])) { | ||||
|         break | ||||
|       } | ||||
|     } | ||||
|     if (k === l) { // 有两种情况:1、没有质因数;2、所有质因数都在指定列表中 | ||||
|       if (l === 0) { // 没有质因数 | ||||
|         if (primesSet.has(i)) { | ||||
|           res.push(i) | ||||
|         } | ||||
|       } else { | ||||
|         res.push(i) | ||||
|       } | ||||
|     } | ||||
|     i++ | ||||
|   } | ||||
|  | ||||
|   return res[n - 1] | ||||
| } | ||||
							
								
								
									
										64
									
								
								src/list/merge-k-sorted-lists.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/list/merge-k-sorted-lists.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| /** | ||||
|  * 合并俩链表 | ||||
|  * @param {ListNode[]} left | ||||
|  * @param {ListNode[]} right | ||||
|  */ | ||||
| export const merge = (left, right) => { | ||||
|   const head = {} | ||||
|   let current = head | ||||
|   while (left !== null && right !== null) { | ||||
|     if (left.val < right.val) { | ||||
|       if (left.val !== null) { | ||||
|         current.next = left | ||||
|         current = current.next | ||||
|       } | ||||
|       left = left.next | ||||
|     } else { | ||||
|       if (right.val !== null) { | ||||
|         current.next = right | ||||
|         current = current.next | ||||
|       } | ||||
|       right = right.next | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (left === null) { | ||||
|     current.next = right | ||||
|   } else { | ||||
|     current.next = left | ||||
|   } | ||||
|  | ||||
|   return head.next | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Definition for singly-linked list. | ||||
|  * function ListNode(val) { | ||||
|  *     this.val = val; | ||||
|  *     this.next = null; | ||||
|  * } | ||||
|  */ | ||||
| /** | ||||
|  * @param {ListNode[]} lists | ||||
|  * @return {ListNode} | ||||
|  */ | ||||
| export const mergeKLists = function (lists) { | ||||
|   if (lists.length === 0) return null | ||||
|   if (lists.length === 1) return lists[0] | ||||
|   if (lists.length === 2) return merge(lists[0], lists[1]) | ||||
|  | ||||
|   // 归并排序,见 src/array/reverse-pairs.js | ||||
|   const mid = lists.length >> 1 | ||||
|  | ||||
|   const left = [] | ||||
|   for (let n = 0; n < mid; n++) { | ||||
|     left[n] = lists[n] | ||||
|   } | ||||
|  | ||||
|   const right = [] | ||||
|   for (let n = 0, i = mid; i < lists.length; n++, i++) { | ||||
|     right[n] = lists[i] | ||||
|   } | ||||
|  | ||||
|   return merge(mergeKLists(left), mergeKLists(right)) | ||||
| } | ||||
							
								
								
									
										15
									
								
								src/math/coin-lcci.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/math/coin-lcci.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| /** | ||||
|  * 参考:https://leetcode-cn.com/problems/coin-lcci/solution/jian-dan-de-shu-xue-jia-fa-by-zindler/ | ||||
|  * @param {number} n | ||||
|  * @return {number} | ||||
|  */ | ||||
| export const waysToChange = function (n) { | ||||
|   const mod = 1e9 + 7 | ||||
|   let res = 0 | ||||
|   for (let i = 0; i <= ~~(n / 25); i++) { | ||||
|     const a = ~~((n - i * 25) / 10) | ||||
|     const t = (a + 1) * (~~(n / 5) - 5 * i - a + 1) | ||||
|     res = (res + t) % mod | ||||
|   } | ||||
|   return res | ||||
| } | ||||
							
								
								
									
										10
									
								
								src/math/factorial-trailing-zeroes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/math/factorial-trailing-zeroes.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| // LeetCode 172. 阶乘后的零 https://leetcode-cn.com/problems/factorial-trailing-zeroes/submissions/ | ||||
| // LintCode 2. 尾部的零 https://www.lintcode.com/problem/trailing-zeros/description | ||||
|  | ||||
| export default (n) => { | ||||
|   let sum = 0 | ||||
|   while (n !== 0) { | ||||
|     sum += Math.floor(n /= 5) | ||||
|   } | ||||
|   return sum | ||||
| } | ||||
							
								
								
									
										15
									
								
								src/math/permutations.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/math/permutations.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| /** | ||||
|  * @param {number[]} nums | ||||
|  * @return {number[][]} | ||||
|  */ | ||||
| export const permute = function (nums) { | ||||
|   const res = [] | ||||
|   const backtrack = (path = []) => { | ||||
|     if (path.length === nums.length) res.push(path) | ||||
|     for (const n of nums) { | ||||
|       !path.includes(n) && backtrack(path.concat(n)) | ||||
|     } | ||||
|   } | ||||
|   backtrack() | ||||
|   return res | ||||
| } | ||||
							
								
								
									
										38
									
								
								src/math/ugly-number-ii.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/math/ugly-number-ii.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| /** | ||||
|  * @param n: An integer | ||||
|  * @return: return a  integer as description. | ||||
|  */ | ||||
| export const nthUglyNumber = function (n) { | ||||
|   const res = [1] | ||||
|   let inx2 = 0 | ||||
|   let inx3 = 0 | ||||
|   let inx5 = 0 | ||||
|  | ||||
|   for (let i = 1; i < n; i++) { | ||||
|     const temp2 = res[inx2] * 2 | ||||
|     const temp3 = res[inx3] * 3 | ||||
|     const temp5 = res[inx5] * 5 | ||||
|     const min = Math.min(temp2, temp3, temp5) | ||||
|     if (min === temp2) inx2++ | ||||
|     if (min === temp3) inx3++ | ||||
|     if (min === temp5) inx5++ | ||||
|  | ||||
|     res.push(min) | ||||
|   } | ||||
|  | ||||
|   return res[n - 1] || 0 | ||||
| } | ||||
|  | ||||
| // 思路: | ||||
| // 一开始,丑数只有{1},1可以同2,3,5相乘,取最小的1×2=2添加到丑数序列中。 | ||||
|  | ||||
| // 现在丑数中有{1,2},在上一步中,1已经同2相乘过了,所以今后没必要再比较1×2了,我们说1失去了同2相乘的资格。 | ||||
|  | ||||
| // 现在1有与3,5相乘的资格,2有与2,3,5相乘的资格,但是2×3和2×5是没必要比较的,因为有比它更小的1可以同3,5相乘,所以我们只需要比较1×3,1×5,2×2。 | ||||
|  | ||||
| // 依此类推,每次我们都分别比较有资格同2,3,5相乘的最小丑数,选择最小的那个作为下一个丑数,假设选择到的这个丑数是同i(i=2,3,5)相乘得到的,所以它失去了同i相乘的资格,把对应的pi++,让pi指向下一个丑数即可。 | ||||
|  | ||||
| // 作者:zzxn | ||||
| // 链接:https://leetcode-cn.com/problems/ugly-number-ii/solution/san-zhi-zhen-fang-fa-de-li-jie-fang-shi-by-zzxn/ | ||||
| // 来源:力扣(LeetCode) | ||||
| // 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 | ||||
							
								
								
									
										155
									
								
								src/stack/maximal-rectangle.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								src/stack/maximal-rectangle.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,155 @@ | ||||
| /** | ||||
|  * @param {character[][]} matrix | ||||
|  * @return {number} | ||||
|  */ | ||||
| // export const maximalRectangle = function (matrix) { | ||||
| //   const result = [] | ||||
| //   const reg = /1{2,}/g | ||||
|  | ||||
| //   if (matrix.length === 0) { | ||||
| //     return 0 | ||||
| //   } else if (matrix.length === 1) { | ||||
| //     const item = matrix[0].join('').replace(/true/g, '1').replace(/false/g, '0') | ||||
| //     result.push(item.split('1').length - 1) | ||||
| //   } else if (matrix[0].length === 1) { | ||||
| //     matrix += '' | ||||
| //     const str = matrix.replace(/true/g, '1').replace(/false/g, '0').replace(/,/g, '') | ||||
| //     let r = reg.exec(str) | ||||
| //     const rs = [] | ||||
| //     while (r) { | ||||
| //       rs.push([r.index, r.index + r[0].length - 1]) | ||||
| //       r = reg.exec(str) | ||||
| //     } | ||||
|  | ||||
| //     rs.forEach(item => { | ||||
| //       result.push(item[1] - item[0] + 1) | ||||
| //     }) | ||||
| //   } else { | ||||
| //     const special = (matrix + '').replace(/true/g, '1').replace(/false/g, '0').replace(/,/g, '') | ||||
| //     if (special === '0110') { | ||||
| //       return 1 | ||||
| //     } else if (special === '0101' || special === '1010') { | ||||
| //       return 2 | ||||
| //     } | ||||
|  | ||||
| //     // TODO: [['0', '0', '0'], ['0', '0', '0'], ['1', '1', '1']] | ||||
|  | ||||
| //     // 将二维数组,相邻的1拿出来(起始点 + 截止点) | ||||
| //     matrix = matrix.map(item => { | ||||
| //       const str = item.join('').replace(/true/g, '1').replace(/false/g, '0') | ||||
| //       let r = reg.exec(str) | ||||
| //       const rs = [] | ||||
| //       while (r) { | ||||
| //         rs.push([r.index, r.index + r[0].length - 1]) | ||||
| //         r = reg.exec(str) | ||||
| //       } | ||||
|  | ||||
| //       return rs | ||||
| //     }) | ||||
|  | ||||
| //     // 通过递归计算相邻的矩阵 | ||||
| //     const maxRect = (arr, result, o = 1) => { | ||||
| //       // 弹出第一行 | ||||
| //       const top = arr.pop() | ||||
|  | ||||
| //       // 弹出第二行 | ||||
| //       const next = arr.pop() | ||||
|  | ||||
| //       // 记录第一行每一个起始点和截止点 | ||||
| //       let tt = null | ||||
|  | ||||
| //       // 记录第二行每一个起始点和截止点 | ||||
| //       let nn = null | ||||
|  | ||||
| //       // 记录交叉的起始索引 | ||||
| //       let start = null | ||||
|  | ||||
| //       // 记录交叉的截止索引 | ||||
| //       let end = null | ||||
|  | ||||
| //       let width = 1 | ||||
| //       let maxWidth = 1 | ||||
|  | ||||
| //       o++ | ||||
|  | ||||
| //       for (let n = 0, nl = top.length; n < nl; n++) { | ||||
| //         tt = top[n] | ||||
| //         for (let i = 0, il = next.length; i < il; i++) { | ||||
| //           nn = next[i] | ||||
| //           // 取交集求宽度 | ||||
| //           const left = Math.max(tt[0], nn[0]) | ||||
| //           const right = Math.min(tt[1], nn[1]) | ||||
| //           width = right - left | ||||
|  | ||||
| //           if (width >= maxWidth) { | ||||
| //             maxWidth = width | ||||
| //             start = left | ||||
| //             end = right | ||||
| //           } | ||||
| //         } | ||||
| //       } | ||||
|  | ||||
| //       // 如果没有找到交叉点 | ||||
| //       if (start === null || end === null) { | ||||
| //         if (o < 3) { | ||||
| //           return false | ||||
| //         } else { | ||||
| //           width = top[0][1] - top[0][0] + 1 | ||||
| //           if (width > 1) result.push((o - 1) * width) | ||||
| //         } | ||||
| //       } else { | ||||
| //         // 找到交叉点继续下一行 | ||||
| //         if (arr.length > 0) { | ||||
| //           arr.push([[start, end]]) | ||||
| //           maxRect(arr, result, o++) | ||||
| //         } else { | ||||
| //           // 从某一行一直计算到最后一行,这个时候start和end一直有值,所以不会进入到if层,这个时候n就是累计的行数(高),end-start+1就是宽 | ||||
| //           result.push(o * (end - start + 1)) | ||||
| //         } | ||||
| //       } | ||||
| //     } | ||||
|  | ||||
| //     while (matrix.length > 1) { | ||||
| //       maxRect([].concat(matrix), result) | ||||
| //       matrix.pop() | ||||
| //     } | ||||
| //   } | ||||
|  | ||||
| //   let max = 0 | ||||
| //   result.map(item => { | ||||
| //     if (item > max) { | ||||
| //       max = item | ||||
| //     } | ||||
| //   }) | ||||
|  | ||||
| //   return max | ||||
| // } | ||||
|  | ||||
| export var maximalRectangle = function (matrix) { | ||||
|   let max = 0 | ||||
|   for (let i = 0; i < matrix.length; i++) { | ||||
|     for (let j = 0; j < matrix[i].length; j++) { | ||||
|       if (matrix[i][j] <= 0) continue | ||||
|       max = Math.max(max, getMax(i, j, matrix)) | ||||
|     } | ||||
|   } | ||||
|   return max | ||||
| } | ||||
|  | ||||
| function getMax (i, j, matrix) { | ||||
|   let max = 0; let maxW | ||||
|   for (let h = 0; h < matrix.length - i; h++) { | ||||
|     !maxW && (maxW = matrix[i + h].length - j) | ||||
|     if (matrix[i + h][j] <= 0) break | ||||
|     for (let w = 0; w < maxW; w++) { | ||||
|       if (matrix[i + h][j + w] <= 0) { | ||||
|         maxW = w | ||||
|         break | ||||
|       } | ||||
|       max = Math.max((w + 1) * (h + 1), max) | ||||
|     } | ||||
|   } | ||||
|   return max | ||||
| } | ||||
|  | ||||
| // Thanks 小刚哥 | ||||
							
								
								
									
										20
									
								
								src/string/compare-strings.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/string/compare-strings.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| /** | ||||
|  * @param A: A string | ||||
|  * @param B: A string | ||||
|  * @return: if string A contains all of the characters in B return true else return false | ||||
|  */ | ||||
| export const compareStrings = function (A, B) { | ||||
|   const a = A.split('') | ||||
|   const b = B.split('') | ||||
|  | ||||
|   for (const n in b) { | ||||
|     const tmp = a.indexOf(b[n]) | ||||
|     if (tmp === -1) { | ||||
|       return false | ||||
|     } else { | ||||
|       a.splice(tmp, 1) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return true | ||||
| } | ||||
							
								
								
									
										7
									
								
								src/string/contains-duplicate.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/string/contains-duplicate.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| /** | ||||
|  * @param {number[]} nums | ||||
|  * @return {boolean} | ||||
|  */ | ||||
| export const containsDuplicate = function (nums) { | ||||
|   return new Set(nums).size !== nums.length | ||||
| } | ||||
							
								
								
									
										67
									
								
								src/string/count-binary-substrings.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/string/count-binary-substrings.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,67 @@ | ||||
| // LeetCode 696. 计数二进制子串 https://leetcode-cn.com/problems/count-binary-substrings/ | ||||
| // LintCode 1079. 连续子串计数 https://www.lintcode.com/problem/count-binary-substrings/description | ||||
|  | ||||
| // 效率低 | ||||
| // export default (s) => { | ||||
| //   let count = 0 | ||||
| //   for (let n = 0, len = s.length; n < len; n++) { | ||||
| //     let last = s.charAt(n) | ||||
| //     let time = 0 | ||||
| //     let lastTime = 0 | ||||
| //     for (let i = n + 1; i < len; i++) { | ||||
| //       if (s.charAt(i) !== last && time === lastTime) { | ||||
| //         count++ | ||||
| //         break | ||||
| //       } else if (s.charAt(i) !== last) { | ||||
| //         time++ | ||||
| //       } else if (time === 0) { | ||||
| //         lastTime++ | ||||
| //       } else { | ||||
| //         break | ||||
| //       } | ||||
| //     } | ||||
| //   } | ||||
| //   return count | ||||
| // } | ||||
|  | ||||
| // 报RegExp too big | ||||
| // export default (s) => { | ||||
| //   // 建立数据结构,堆栈,保存数据 | ||||
| //   let r = [] | ||||
| //   // 给定任意子输入都返回第一个符合条件的子串 | ||||
| //   let match = (s) => { | ||||
| //     let j = s.match(/^(0+|1+)/)[0] | ||||
| //     let o = (j[0] ^ 1).toString().repeat(j.length) | ||||
| //     let reg = new RegExp(`^(${j}${o})`) | ||||
| //     if (reg.test(s)) { | ||||
| //       return RegExp.$1 | ||||
| //     } else { | ||||
| //       return '' | ||||
| //     } | ||||
| //   } | ||||
| //   // 通过for循环控制程序运行的流程 | ||||
| //   for (let i = 0, len = s.length - 1; i < len; i++) { | ||||
| //     let sub = match(s.slice(i)) | ||||
| //     if (sub) r.push(sub) | ||||
| //   } | ||||
| //   return r.length | ||||
| // } | ||||
|  | ||||
| export default (s) => { | ||||
|   // 来自 Somnus | ||||
|   // pre 前一个数字连续出现的次数,cur 当前数字连续出现的次数,result 结果子串个数 | ||||
|   let pre = 0; let cur = 1; let result = 0 | ||||
|   for (let i = 0, len = s.length - 1; i < len; i++) { | ||||
|     // 判断当前数字是否与后一个数字相同 | ||||
|     if (s[i] === s[i + 1]) { // 相同,则当前数字出现的次数cur加1 | ||||
|       cur++ | ||||
|     } else { // 不同,则当前数字事实上变成了前一个数字,当前数字的次数重置为1 | ||||
|       pre = cur | ||||
|       cur = 1 | ||||
|     } | ||||
|     if (pre >= cur) { // 前一个数字出现的次数 >= 后一个数字出现的次数,则一定包含满足条件的子串 | ||||
|       result++ | ||||
|     } | ||||
|   } | ||||
|   return result | ||||
| } | ||||
							
								
								
									
										58
									
								
								src/string/regular-expression-matching.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/string/regular-expression-matching.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| // LeetCode 10. 正则表达式匹配 https://leetcode-cn.com/problems/regular-expression-matching/ | ||||
| // LintCode 154. 正则表达式匹配 https://www.lintcode.com/problem/regular-expression-matching/description | ||||
|  | ||||
| // 'mississippi', 'mis*is*ip*.' 测试不通过 | ||||
| // export default (str, mode) => { | ||||
| //   const strLen = str.length | ||||
| //   const modeArr = mode.match(/([a-z.]\*)|([a-z]+(?=([a-z.]\*)|$))/g) // 筛选无模式和有模式 | ||||
|  | ||||
| //   if (!modeArr) return false | ||||
|  | ||||
| //   let cur = 0 | ||||
| //   for (let n = 0, len = modeArr.length; n < len; n++) { | ||||
| //     // 匹配模式结果分类 | ||||
| //     // 分三类:.*|a*|bcde | ||||
| //     const s = modeArr[n].split('') | ||||
| //     if (s[1] === '*') { // 如果第二位是'*',则为有模式 | ||||
| //       if (s[0] === '.') { // 第一种模式 | ||||
| //         return true | ||||
| //       } else { // 第二种模式,直接移到相等的最后面 | ||||
| //         while (str[cur] === s[0]) { | ||||
| //           cur++ | ||||
| //         } | ||||
| //       } | ||||
| //     } else { // 无模式 | ||||
| //       for (let i = 0, sLen = s.length; i < sLen; i++) { | ||||
| //         if (s[i] !== str[cur++]) { // 注意,cur++每一次都会被执行 | ||||
| //           return false | ||||
| //         } | ||||
| //       } | ||||
| //     } | ||||
| //   } | ||||
|  | ||||
| //   return cur === strLen | ||||
| // } | ||||
|  | ||||
| export default (str, mode) => { | ||||
|   const isMatch = (s, p) => { | ||||
|     // 边界情况,如果s和p都为空,说明处理结束了,返回true,否则返回false | ||||
|     if (p.length <= 0) { | ||||
|       return !s.length | ||||
|     } | ||||
|     // 判断p模式字符串的第一个字符和s字符串的第一个字符是不是匹配 | ||||
|     let match = false | ||||
|     if (s.length > 0 && (p[0] === s[0] || p[0] === '.')) { | ||||
|       match = true | ||||
|     } | ||||
|     // p有模式的 | ||||
|     if (p.length > 1 && p[1] === '*') { | ||||
|       // 第一种情况:s*匹配0个字符 | ||||
|       // 第二种情况:s*匹配1个字符,递归下去,用来表示s*匹配多个s | ||||
|       return isMatch(s, p.slice(2)) || (match && isMatch(s.slice(1), p)) | ||||
|     } else { | ||||
|       return match && isMatch(s.slice(1), p.slice(1)) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return isMatch(str, mode) | ||||
| } | ||||
							
								
								
									
										6
									
								
								src/string/repeated-substring-pattern.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/string/repeated-substring-pattern.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| // LeetCode 459. 重复的子字符串 https://leetcode-cn.com/problems/repeated-substring-pattern/ | ||||
| // LintCode 1227. 重复的子串模式 https://www.lintcode.com/problem/repeated-substring-pattern/description | ||||
|  | ||||
| export default (str) => { | ||||
|   return /^(\w+)\1+$/.test(str) | ||||
| } | ||||
							
								
								
									
										56
									
								
								src/string/restore-ip-addresses.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/string/restore-ip-addresses.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | ||||
| // LeetCode 93. 复原IP地址 https://leetcode-cn.com/problems/restore-ip-addresses/ | ||||
| // LintCode 426. 恢复IP地址 https://www.lintcode.com/problem/restore-ip-addresses/description | ||||
|  | ||||
| export default (str) => { | ||||
|   const result = [] | ||||
|  | ||||
|   if (str === '0000') return ['0.0.0.0'] | ||||
|  | ||||
|   // 递归函数 | ||||
|   const recur = (cur, sub) => { | ||||
|     if (cur.length === 4 && cur.join('') === str) { | ||||
|       if (!cur.every(item => Number(item) === 0)) { | ||||
|         result.push(cur.join('.')) | ||||
|       } | ||||
|     } else { | ||||
|       for (let n = 0, len = Math.min(3, sub.length); n < len; n++) { | ||||
|         const start = Number(sub.substr(0, n + 1)) | ||||
|         const end = sub.substr(n + 1) | ||||
|         if (start < 256 && end.length <= (9 - cur.length * 3)) { | ||||
|           recur([...cur, start], end) | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   recur([], str) | ||||
|   return result | ||||
| } | ||||
|  | ||||
| // 快乐动起来老师的解法: | ||||
| // export default (str) => { | ||||
| //   // 保存所有符合条件的IP地址 | ||||
| //   let r = [] | ||||
| //   // 分四步递归处理ip分段 | ||||
| //   let search = (cur, sub) => { | ||||
| //     // 非法输入过滤,LeetCode测试用例(111111111111111111111111111111111111111111111111111111111111) | ||||
| //     if (sub.length > 12) { | ||||
| //       return | ||||
| //     } | ||||
| //     // 边界条件 | ||||
| //     if (cur.length === 4 && cur.join('') === str) { | ||||
| //       r.push(cur.join('.')) | ||||
| //     } else { | ||||
| //       // 正常的处理过程 | ||||
| //       for (let i = 0, len = Math.min(3, sub.length), tmp; i < len; i++) { | ||||
| //         tmp = sub.substr(0, i + 1) | ||||
| //         if (tmp - 256 < 0) { | ||||
| //           // 转换下数据类型,如 01为1(LeetCode测试用例) | ||||
| //           search(cur.concat([tmp * 1]), sub.substr(i + 1)) | ||||
| //         } | ||||
| //       } | ||||
| //     } | ||||
| //   } | ||||
| //   search([], str) | ||||
| //   return r | ||||
| // } | ||||
							
								
								
									
										12
									
								
								src/string/reverse-words-in-a-string.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/string/reverse-words-in-a-string.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| // LeetCode 557. 反转字符串中的单词 III https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/ | ||||
| // LintCode 1173. 反转字符串 III https://www.lintcode.com/problem/reverse-words-in-a-string-iii/description | ||||
|  | ||||
| export default (s) => { | ||||
|   return s.split(' ').map(item => { | ||||
|     let tmp = '' | ||||
|     for (let n = item.length; n >= 0; n--) { | ||||
|       tmp += item.charAt(n) | ||||
|     } | ||||
|     return tmp | ||||
|   }).join(' ') | ||||
| } | ||||
							
								
								
									
										3
									
								
								src/string/unique-characters.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/string/unique-characters.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| export const isUnique = (str) => { | ||||
|   return new Set(str.split('')).size === str.length | ||||
| } | ||||
							
								
								
									
										28
									
								
								src/tree/binary-tree-right-side-view.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/tree/binary-tree-right-side-view.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| /** | ||||
|  * Definition for a binary tree node. | ||||
|  * function TreeNode(val) { | ||||
|  *     this.val = val; | ||||
|  *     this.left = this.right = null; | ||||
|  * } | ||||
|  */ | ||||
| /** | ||||
|  * @param {TreeNode} root | ||||
|  * @return {number[]} | ||||
|  */ | ||||
| export const rightSideView = function (root) { | ||||
|   if (!root) return [] | ||||
|   const queue = [root] // 队列 把树顶加入队列 | ||||
|   const arr = [] // 用来存储每层最后个元素值 | ||||
|   while (queue.length > 0) { | ||||
|     let len = queue.length | ||||
|     while (len) { | ||||
|       const node = queue.shift() // 取出队列第一个元素 | ||||
|       if (len === 1) arr.push(node.val) // 当是 当前一层的最后一个元素时,把值加入arr | ||||
|       if (node.left) queue.push(node.left) // 继续往队列添加元素 | ||||
|       if (node.right) queue.push(node.right) | ||||
|       len-- | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return arr | ||||
| } | ||||
							
								
								
									
										51
									
								
								test/array/01-matrix.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								test/array/01-matrix.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| import { updateMatrix } from '../../src/array/01-matrix' | ||||
|  | ||||
| test('01 矩阵', () => { | ||||
|   expect(updateMatrix([ | ||||
|     [0, 0, 0], | ||||
|     [0, 1, 0], | ||||
|     [0, 0, 0] | ||||
|   ])).toEqual([ | ||||
|     [0, 0, 0], | ||||
|     [0, 1, 0], | ||||
|     [0, 0, 0] | ||||
|   ]) | ||||
|  | ||||
|   expect(updateMatrix([ | ||||
|     [0, 0, 0], | ||||
|     [0, 1, 0], | ||||
|     [1, 1, 1] | ||||
|   ])).toEqual([ | ||||
|     [0, 0, 0], | ||||
|     [0, 1, 0], | ||||
|     [1, 2, 1] | ||||
|   ]) | ||||
|  | ||||
|   expect(updateMatrix([ | ||||
|     [0, 0, 0], | ||||
|     [0, 0, 0], | ||||
|     [0, 0, 0], | ||||
|     [0, 0, 0], | ||||
|     [0, 0, 0] | ||||
|   ])).toEqual([ | ||||
|     [0, 0, 0], | ||||
|     [0, 0, 0], | ||||
|     [0, 0, 0], | ||||
|     [0, 0, 0], | ||||
|     [0, 0, 0] | ||||
|   ]) | ||||
|  | ||||
|   expect(updateMatrix([ | ||||
|     [0, 1, 0, 1, 1], | ||||
|     [1, 1, 0, 0, 1], | ||||
|     [0, 0, 0, 1, 0], | ||||
|     [1, 0, 1, 1, 1], | ||||
|     [1, 0, 0, 0, 1] | ||||
|   ])).toEqual([ | ||||
|     [0, 1, 0, 1, 2], | ||||
|     [1, 1, 0, 0, 1], | ||||
|     [0, 0, 0, 1, 0], | ||||
|     [1, 0, 1, 1, 1], | ||||
|     [1, 0, 0, 0, 1] | ||||
|   ]) | ||||
| }) | ||||
							
								
								
									
										9
									
								
								test/array/best-time-to-buy-and-sell-stock-ii.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								test/array/best-time-to-buy-and-sell-stock-ii.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| import maxProfit from '../../src/array/best-time-to-buy-and-sell-stock-ii' | ||||
|  | ||||
| test('maxProfit', () => { | ||||
|   expect(maxProfit([7, 1, 5, 3, 6, 4])).toEqual(7) | ||||
|   expect(maxProfit([1, 2, 3, 4, 5])).toEqual(4) | ||||
|   expect(maxProfit([7, 6, 4, 3, 1])).toEqual(0) | ||||
|   expect(maxProfit([])).toEqual(0) | ||||
|   expect(maxProfit([2, 1, 2, 0, 1])).toEqual(2) | ||||
| }) | ||||
							
								
								
									
										9
									
								
								test/array/binary-search.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								test/array/binary-search.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| import { search } from '../../src/array/binary-search' | ||||
|  | ||||
| test('BinarySearch', () => { | ||||
|   expect(search([-1, 0, 3, 5, 9, 12], 9)).toEqual(4) | ||||
|   expect(search([-1, 0, 3, 5, 9, 12], 2)).toEqual(-1) | ||||
|   expect(search([1, 4, 4, 5, 7, 7, 8, 9, 9, 10], 1)).toEqual(0) | ||||
|   expect(search([1, 2, 3, 3, 4, 5, 10], 3)).toEqual(2) | ||||
|   expect(search([1, 2, 3, 3, 4, 5, 10], 6)).toEqual(-1) | ||||
| }) | ||||
							
								
								
									
										11
									
								
								test/array/bubble-sort.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								test/array/bubble-sort.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| import bubbleSort from '../../src/array/bubble-sort' | ||||
|  | ||||
| test('bubbleSort', () => { | ||||
|   expect(bubbleSort([1, 2, 3])).toEqual([1, 2, 3]) | ||||
|   expect(bubbleSort([3, 2, 1])).toEqual([1, 2, 3]) | ||||
|   expect(bubbleSort([])).toEqual([]) | ||||
|   expect(bubbleSort([3, 6, 4, 5, 6, 8])).toEqual([3, 4, 5, 6, 6, 8]) | ||||
|   expect(bubbleSort([1, 1, 1])).toEqual([1, 1, 1]) | ||||
|   expect(bubbleSort([-1, -10, 3])).toEqual([-10, -1, 3]) | ||||
|   expect(bubbleSort([7, 2, 8, 3, 6, 3])).toEqual([2, 3, 3, 6, 7, 8]) | ||||
| }) | ||||
							
								
								
									
										7
									
								
								test/array/can-place-flowers.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								test/array/can-place-flowers.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| import canPlaceFlowers from '../../src/array/can-place-flowers' | ||||
|  | ||||
| test('canPlaceFlowers', () => { | ||||
|   expect(canPlaceFlowers([1, 0, 0, 0, 1], 1)).toEqual(true) | ||||
|   expect(canPlaceFlowers([1, 0, 0, 0, 1], 2)).toEqual(false) | ||||
|   expect(canPlaceFlowers([1, 0, 0, 0, 1, 0, 0], 2)).toEqual(true) | ||||
| }) | ||||
							
								
								
									
										7
									
								
								test/array/circular-array-loop.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								test/array/circular-array-loop.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| import circularArrayLoop from '../../src/array/circular-array-loop' | ||||
|  | ||||
| test('circularArrayLoop', () => { | ||||
|   expect(circularArrayLoop([2, -1, 1, 2, 2])).toEqual(true) | ||||
|   expect(circularArrayLoop([-1, 2])).toEqual(false) | ||||
|   expect(circularArrayLoop([-2, 1, -1, -2, -2])).toEqual(false) | ||||
| }) | ||||
							
								
								
									
										7
									
								
								test/array/container-with-most-water.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								test/array/container-with-most-water.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| import { maxArea } from '../../src/array/container-with-most-water' | ||||
|  | ||||
| test('盛最多水的容器', () => { | ||||
|   expect(maxArea([1, 8, 6, 2, 5, 4, 8, 3, 7])).toBe(49) | ||||
|   expect(maxArea([1, 3, 2])).toBe(2) | ||||
|   expect(maxArea([1, 3, 2, 2])).toBe(4) | ||||
| }) | ||||
							
								
								
									
										7
									
								
								test/array/count-number-of-nice-subarrays.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								test/array/count-number-of-nice-subarrays.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| import { numberOfSubarrays } from '../../src/array/count-number-of-nice-subarrays' | ||||
|  | ||||
| test('统计「优美子数组」', () => { | ||||
|   expect(numberOfSubarrays([1, 1, 2, 1, 1], 3)).toBe(2) | ||||
|   expect(numberOfSubarrays([2, 4, 6], 1)).toBe(0) | ||||
|   expect(numberOfSubarrays([2, 2, 2, 1, 2, 2, 1, 2, 2, 2], 2)).toBe(16) | ||||
| }) | ||||
							
								
								
									
										24
									
								
								test/array/count-the-repetitions.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								test/array/count-the-repetitions.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| import { includesInStr, getStrCopyByNum, getMaxRepetitions } from '../../src/array/count-the-repetitions' | ||||
|  | ||||
| test('判断从 s2 中删除某些字符是否可以变为 s1', () => { | ||||
|   expect(includesInStr('abc', 'ab')).toBe(1) | ||||
|   expect(includesInStr('acb', 'ab')).toBe(1) | ||||
|   expect(includesInStr('ab', 'ab')).toBe(1) | ||||
|   expect(includesInStr('ac', 'ab')).toBe(0) | ||||
|   expect(includesInStr('aa', 'a')).toBe(2) | ||||
|   expect(includesInStr('aaa', 'a')).toBe(3) | ||||
|   expect(includesInStr('abcabc', 'abb')).toBe(1) | ||||
| }) | ||||
|  | ||||
| test('获取重复字符串', () => { | ||||
|   expect(getStrCopyByNum('abc', 2)).toBe('abcabc') | ||||
|   expect(getStrCopyByNum('abc', 3)).toBe('abcabcabc') | ||||
| }) | ||||
|  | ||||
| test('统计重复个数', () => { | ||||
|   expect(getMaxRepetitions('abc', 4, 'ab', 2)).toBe(2) | ||||
|   expect(getMaxRepetitions('acb', 4, 'ab', 2)).toBe(2) | ||||
|   expect(getMaxRepetitions('abc', 4, 'abb', 2)).toBe(1) | ||||
|   expect(getMaxRepetitions('aaa', 3, 'aa', 1)).toBe(4) | ||||
|   expect(getMaxRepetitions('abccab', 4, 'abc', 2)).toBe(2) | ||||
| }) | ||||
							
								
								
									
										9
									
								
								test/array/find-common-characters.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								test/array/find-common-characters.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| import { commonChars } from '../../src/array/find-common-characters' | ||||
|  | ||||
| describe('查找常用字符', () => { | ||||
|   test('查找常用字符', () => { | ||||
|     expect(commonChars(['bella', 'label', 'roller']).sort()).toEqual(['e', 'l', 'l'].sort()) | ||||
|     expect(commonChars(['cool', 'lock', 'cook']).sort()).toEqual(['c', 'o'].sort()) | ||||
|     expect(commonChars(['acabcddd', 'bcbdbcbd', 'baddbadb', 'cbdddcac', 'aacbcccd', 'ccccddda', 'cababaab', 'addcaccd']).sort()).toEqual([].sort()) | ||||
|   }) | ||||
| }) | ||||
							
								
								
									
										11
									
								
								test/array/first-missing-positive.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								test/array/first-missing-positive.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| import firstMissingPositive from '../../src/array/first-missing-positive' | ||||
|  | ||||
| test('缺失的第一个正数', () => { | ||||
|   expect(firstMissingPositive([-1])).toBe(1) | ||||
|   expect(firstMissingPositive([0])).toBe(1) | ||||
|   expect(firstMissingPositive([])).toBe(1) | ||||
|   expect(firstMissingPositive([3, 2, -1])).toBe(1) | ||||
|   expect(firstMissingPositive([3, 4, -1, 1])).toBe(2) | ||||
|   expect(firstMissingPositive([1, 2, 0])).toBe(3) | ||||
|   expect(firstMissingPositive([7, 8, 9, 11, 12])).toBe(1) | ||||
| }) | ||||
							
								
								
									
										15
									
								
								test/array/first-missing-prime-number.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/array/first-missing-prime-number.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| import firstMissingPrime, { isPrinme } from '../../src/array/first-missing-prime-number' | ||||
|  | ||||
| test('是否是素数', () => { | ||||
|   expect(isPrinme(0)).toBe(false) | ||||
|   expect(isPrinme(1)).toBe(false) | ||||
|   expect(isPrinme(3)).toBe(true) | ||||
|   expect(isPrinme(5)).toBe(true) | ||||
|   expect(isPrinme(7)).toBe(true) | ||||
|   expect(isPrinme(6)).toBe(false) | ||||
| }) | ||||
|  | ||||
| test('缺失的第一个素数', () => { | ||||
|   expect(firstMissingPrime([3, 5, 7])).toBe(2) | ||||
|   expect(firstMissingPrime([2, 3, 5, 7, 11, 13, 17, 23, 29])).toBe(19) | ||||
| }) | ||||
							
								
								
									
										7
									
								
								test/array/gray-code.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								test/array/gray-code.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| import grayCode from '../../src/array/gray-code' | ||||
|  | ||||
| test('grayCode', () => { | ||||
|   expect(grayCode(1)).toEqual([0, 1]) | ||||
|   expect(grayCode(2)).toEqual([0, 1, 3, 2]) | ||||
|   expect(grayCode(0)).toEqual([0]) | ||||
| }) | ||||
							
								
								
									
										6
									
								
								test/array/jump-game.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/array/jump-game.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| import { canJump } from '../../src/array/jump-game' | ||||
|  | ||||
| test('跳跃游戏', () => { | ||||
|   expect(canJump([2, 3, 1, 1, 4])).toBe(true) | ||||
|   expect(canJump([3, 2, 1, 0, 4])).toBe(false) | ||||
| }) | ||||
							
								
								
									
										6
									
								
								test/array/kth-largest-element-in-an-array.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/array/kth-largest-element-in-an-array.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| import findKthLargest from '../../src/array/kth-largest-element-in-an-array' | ||||
|  | ||||
| test('findKthLargest', () => { | ||||
|   expect(findKthLargest([3, 2, 1, 5, 6, 4], 2)).toEqual(5) | ||||
|   expect(findKthLargest([3, 2, 3, 1, 2, 4, 5, 5, 6], 4)).toEqual(4) | ||||
| }) | ||||
							
								
								
									
										5
									
								
								test/array/letter-combinations-of-a-phone-number.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								test/array/letter-combinations-of-a-phone-number.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| import letterCombinations from '../../src/array/letter-combinations-of-a-phone-number' | ||||
|  | ||||
| test('letterCombinations', () => { | ||||
|   expect(letterCombinations('23')).toEqual(['ad', 'ae', 'af', 'bd', 'be', 'bf', 'cd', 'ce', 'cf']) | ||||
| }) | ||||
							
								
								
									
										20
									
								
								test/array/loop-asc-array.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								test/array/loop-asc-array.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| import loopAscArray from '../../src/array/loop-asc-array' | ||||
|  | ||||
| test('loopAscArray', () => { | ||||
|   expect(loopAscArray([0, 3, 4, 6, 7], 0)).toEqual(true) | ||||
|   expect(loopAscArray([6, 7, 0, 3, 4], 0)).toEqual(true) | ||||
|   expect(loopAscArray([6, 7, 0, 3, 4], 5)).toEqual(false) | ||||
|   expect(loopAscArray([1, 2, 3, 4, 5], 6)).toEqual(false) | ||||
|   expect(loopAscArray([1, 2, 3, 4, 5], 1)).toEqual(true) | ||||
|   expect(loopAscArray([3, 4, 5, 1, 1, 2], 1)).toEqual(true) | ||||
|   expect(loopAscArray([3, 4, 5, 1, 1, 2], 6)).toEqual(false) | ||||
|   expect(loopAscArray([3, 4, 5, 1, 1, 2], 0)).toEqual(false) | ||||
|   expect(loopAscArray([1, 0, 1, 1, 1], 0)).toEqual(true) | ||||
|   expect(loopAscArray([1, 0, 1, 1, 1], 2)).toEqual(false) | ||||
|   expect(loopAscArray([3], 2)).toEqual(false) | ||||
|   expect(loopAscArray([2], 2)).toEqual(true) | ||||
|   expect(loopAscArray([1, 1, 1], 2)).toEqual(false) | ||||
|   expect(loopAscArray([1, 1, 1], 1)).toEqual(true) | ||||
|   expect(loopAscArray([1, 1, 1, 0], 1)).toEqual(true) | ||||
|   expect(loopAscArray([1, 1, 1, 0], 2)).toEqual(false) | ||||
| }) | ||||
							
								
								
									
										11
									
								
								test/array/majority-element.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								test/array/majority-element.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| import { majorityElement } from '../../src/array/majority-element' | ||||
|  | ||||
| test('主元素', () => { | ||||
|   expect(majorityElement([1, 2, 5, 9, 5, 9, 5, 5, 5])).toBe(5) | ||||
|   expect(majorityElement([1, 1, 1, 1, 2, 2, 2])).toBe(1) | ||||
|   expect(majorityElement([1, 1, 1, 2, 2, 2, 2])).toBe(2) | ||||
|   expect(majorityElement([3, 2])).toBe(-1) | ||||
|   expect(majorityElement([2, 2, 1, 1, 1, 2, 2])).toBe(2) | ||||
|   expect(majorityElement([1])).toBe(1) | ||||
|   expect(majorityElement([2, 2])).toBe(2) | ||||
| }) | ||||
							
								
								
									
										1
									
								
								test/array/maximum-gap.test.data.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test/array/maximum-gap.test.data.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										10
									
								
								test/array/maximum-gap.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								test/array/maximum-gap.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| import maximumGap from '../../src/array/maximum-gap' | ||||
| import inData from './maximum-gap.test.data' | ||||
|  | ||||
| test('最大间距', () => { | ||||
|   expect(maximumGap([3, 6, 9, 1])).toBe(3) | ||||
|   expect(maximumGap([10])).toBe(0) | ||||
|   expect(maximumGap([13, 16, 19, 1])).toBe(12) | ||||
|   expect(maximumGap([1, 3, 100])).toBe(97) | ||||
|   expect(maximumGap(inData)).toBe(2147428092) | ||||
| }) | ||||
							
								
								
									
										37
									
								
								test/array/merge-intervals.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								test/array/merge-intervals.test.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										17
									
								
								test/array/number-of-islands.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								test/array/number-of-islands.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| import { numIslands } from '../../src/array/number-of-islands' | ||||
|  | ||||
| test('岛屿的个数', () => { | ||||
|   expect(numIslands([ | ||||
|     [1, 1, 0, 0, 0], | ||||
|     [0, 1, 0, 0, 1], | ||||
|     [0, 0, 0, 1, 1], | ||||
|     [0, 0, 0, 0, 0], | ||||
|     [0, 0, 0, 0, 1] | ||||
|   ])).toBe(3) | ||||
|  | ||||
|   expect(numIslands([ | ||||
|     [1, 1] | ||||
|   ])).toBe(1) | ||||
|  | ||||
|   expect(numIslands([])).toBe(0) | ||||
| }) | ||||
							
								
								
									
										6
									
								
								test/array/partition-array.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/array/partition-array.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| import partitionArray from '../../src/array/partition-array' | ||||
|  | ||||
| test('loopAscArray', () => { | ||||
|   expect(partitionArray([], 9)).toEqual(0) | ||||
|   expect(partitionArray([3, 2, 2, 1], 2)).toEqual(1) | ||||
| }) | ||||
							
								
								
									
										15
									
								
								test/array/remove-duplicates-from-sorted-array.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								test/array/remove-duplicates-from-sorted-array.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| import removeDuplicates from '../../src/array/remove-duplicates-from-sorted-array' | ||||
|  | ||||
| test('removeDuplicates', () => { | ||||
|   const nums = [1, 1, 2] | ||||
|   expect(removeDuplicates(nums)).toBe(2) | ||||
|  | ||||
|   expect(nums).toEqual([1, 2]) | ||||
| }) | ||||
|  | ||||
| test('removeDuplicates2', () => { | ||||
|   const nums = [1, 2] | ||||
|   expect(removeDuplicates(nums)).toBe(2) | ||||
|  | ||||
|   expect(nums).toEqual([1, 2]) | ||||
| }) | ||||
							
								
								
									
										29
									
								
								test/array/reverse-pairs.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								test/array/reverse-pairs.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| import { | ||||
|   reversePairs, | ||||
|   merge, | ||||
|   mergeSort, | ||||
|   resetCount | ||||
| } from '../../src/array/reverse-pairs' | ||||
|  | ||||
| describe('逆序对', () => { | ||||
|   beforeEach(() => { | ||||
|     resetCount() | ||||
|   }) | ||||
|  | ||||
|   test('归并排序 - 合并左右', () => { | ||||
|     expect(merge([7], [5])).toEqual([5, 7]) | ||||
|     expect(merge([2], [3])).toEqual([2, 3]) | ||||
|     expect(merge([2, 3], [4, 5])).toEqual([2, 3, 4, 5]) | ||||
|   }) | ||||
|  | ||||
|   test('归并排序', () => { | ||||
|     expect(mergeSort([2, 4, 3, 5])).toEqual([2, 3, 4, 5]) | ||||
|     expect(mergeSort([2, 4, 3, 0])).toEqual([0, 2, 3, 4]) | ||||
|   }) | ||||
|  | ||||
|   test('逆序对', () => { | ||||
|     expect(reversePairs([7, 5, 6, 4])).toBe(5) | ||||
|     expect(reversePairs([2, 4, 1, 3, 5])).toBe(3) | ||||
|     expect(reversePairs([1, 2, 3, 4])).toBe(0) | ||||
|   }) | ||||
| }) | ||||
							
								
								
									
										6
									
								
								test/array/search-in-rotated-sorted-array.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/array/search-in-rotated-sorted-array.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| import { search } from '../../src/array/search-in-rotated-sorted-array' | ||||
|  | ||||
| test('搜索旋转排序数组', () => { | ||||
|   expect(search([4, 5, 6, 7, 0, 1, 2], 0)).toBe(4) | ||||
|   expect(search([4, 5, 6, 7, 0, 1, 2], 3)).toBe(-1) | ||||
| }) | ||||
							
								
								
									
										8
									
								
								test/array/search-insert-position.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								test/array/search-insert-position.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| import searchInsert from '../../src/array/search-insert-position' | ||||
|  | ||||
| test('searchInsert', () => { | ||||
|   expect(searchInsert([1, 3, 5, 6], 5)).toEqual(2) | ||||
|   expect(searchInsert([1, 3, 5, 6], 2)).toEqual(1) | ||||
|   expect(searchInsert([1, 3, 5, 6], 7)).toEqual(4) | ||||
|   expect(searchInsert([1, 3, 5, 6], 0)).toEqual(0) | ||||
| }) | ||||
							
								
								
									
										11
									
								
								test/array/select-sort.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								test/array/select-sort.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| import selectSort from '../../src/array/select-sort' | ||||
|  | ||||
| test('selectSort', () => { | ||||
|   expect(selectSort([1, 2, 3])).toEqual([1, 2, 3]) | ||||
|   expect(selectSort([3, 2, 1])).toEqual([1, 2, 3]) | ||||
|   expect(selectSort([])).toEqual([]) | ||||
|   expect(selectSort([3, 6, 4, 5, 6, 8])).toEqual([3, 4, 5, 6, 6, 8]) | ||||
|   expect(selectSort([1, 1, 1])).toEqual([1, 1, 1]) | ||||
|   expect(selectSort([-1, -10, 3])).toEqual([-10, -1, 3]) | ||||
|   expect(selectSort([7, 2, 8, 3, 6, 3])).toEqual([2, 3, 3, 6, 7, 8]) | ||||
| }) | ||||
| @ -0,0 +1,6 @@ | ||||
| import { singleNumbers } from '../../src/array/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof' | ||||
|  | ||||
| test('面试题56 - I. 数组中数字出现的次数', () => { | ||||
|   expect(singleNumbers([4, 1, 4, 6]).some(i => [1, 6].includes(i))).toBe(true) | ||||
|   expect(singleNumbers([1, 2, 10, 4, 1, 4, 3, 3]).some(i => [2, 10].includes(i))).toBe(true) | ||||
| }) | ||||
							
								
								
									
										6
									
								
								test/array/single-number.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/array/single-number.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| import { singleNumber } from '../../src/array/single-number' | ||||
|  | ||||
| test('只出现一次的数字', () => { | ||||
|   expect(singleNumber([2, 2, 1])).toBe(1) | ||||
|   expect(singleNumber([4, 1, 2, 1, 2])).toBe(4) | ||||
| }) | ||||
							
								
								
									
										5
									
								
								test/array/sort-array-by-parity.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								test/array/sort-array-by-parity.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | ||||
| import sortArrayByParity from '../../src/array/sort-array-by-parity' | ||||
|  | ||||
| test('sortArrayByParity', () => { | ||||
|   expect(sortArrayByParity([4, 2, 5, 7])).toEqual([2, 5, 4, 7]) | ||||
| }) | ||||
							
								
								
									
										24
									
								
								test/array/substring-with-concatenation-of-all-words.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								test/array/substring-with-concatenation-of-all-words.test.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										10
									
								
								test/array/x-of-a-kind-in-a-deck-of-cards.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								test/array/x-of-a-kind-in-a-deck-of-cards.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| import hasGroupsSizeX from '../../src/array/x-of-a-kind-in-a-deck-of-cards' | ||||
|  | ||||
| test('hasGroupsSizeX', () => { | ||||
|   expect(hasGroupsSizeX([1, 2, 3, 4, 4, 3, 2, 1])).toEqual(true) | ||||
|   expect(hasGroupsSizeX([1, 1, 1, 2, 2, 2, 3, 3])).toEqual(false) | ||||
|   expect(hasGroupsSizeX([1, 1, 2, 2, 2, 2])).toEqual(true) | ||||
|   expect(hasGroupsSizeX([1])).toEqual(false) | ||||
|   expect(hasGroupsSizeX([1, 1])).toEqual(true) | ||||
|   expect(hasGroupsSizeX([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 10, 10, 10])).toEqual(true) | ||||
| }) | ||||
							
								
								
									
										12
									
								
								test/heap/super-ugly-number.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								test/heap/super-ugly-number.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| import { getPrimes, nthSuperUglyNumber } from '../../src/heap/super-ugly-number' | ||||
|  | ||||
| test('计算质因数', () => { | ||||
|   expect(getPrimes(6)).toEqual([2, 3]) | ||||
|   expect(getPrimes(4)).toEqual([2]) | ||||
|   expect(getPrimes(180)).toEqual([2, 3, 5]) | ||||
| }) | ||||
|  | ||||
| // test('superUglyNumber', () => { | ||||
| //   expect(nthSuperUglyNumber(12, [2, 7, 13, 19])).toBe(32) | ||||
| //   expect(nthSuperUglyNumber(800, [37, 43, 59, 61, 67, 71, 79, 83, 89, 97, 101, 103, 113, 127, 131, 157, 163, 167, 173, 179, 191, 193, 197, 199, 211, 229, 233, 239, 251, 257])).toBe(32) | ||||
| // }) | ||||
							
								
								
									
										62
									
								
								test/list/merge-k-sorted-lists.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								test/list/merge-k-sorted-lists.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | ||||
| import { merge, mergeKLists } from '../../src/list/merge-k-sorted-lists' | ||||
|  | ||||
| function ListNode (val) { | ||||
|   this.val = val | ||||
|   this.next = null | ||||
| } | ||||
|  | ||||
| const arr2List = (arr) => { | ||||
|   let first = null | ||||
|   let res = null | ||||
|   for (let n = 0, len = arr.length; n < len; n++) { | ||||
|     const tmp = new ListNode(arr[n]) | ||||
|     if (res) res.next = tmp | ||||
|     else first = tmp | ||||
|     res = tmp | ||||
|   } | ||||
|  | ||||
|   return first | ||||
| } | ||||
|  | ||||
| test('数组转链表', () => { | ||||
|   expect(arr2List([1, 2, 3])).toEqual({ next: { next: { next: null, val: 3 }, val: 2 }, val: 1 }) | ||||
| }) | ||||
|  | ||||
| test('合并俩链表', () => { | ||||
|   const source1 = arr2List([1, 4, 5]) | ||||
|  | ||||
|   const source2 = arr2List([1, 3, 4]) | ||||
|  | ||||
|   const out = [1, 1, 3, 4, 4, 5] | ||||
|   expect(merge(source1, source2)).toEqual(arr2List(out)) | ||||
| }) | ||||
|  | ||||
| test('合并K个排序链表 - 1', () => { | ||||
|   const source = [ | ||||
|     arr2List([1, 4, 5]), | ||||
|     arr2List([1, 3, 4]), | ||||
|     arr2List([2, 6]) | ||||
|   ] | ||||
|   const out = [1, 1, 2, 3, 4, 4, 5, 6] | ||||
|   expect(mergeKLists(source)).toEqual(arr2List(out)) | ||||
| }) | ||||
|  | ||||
| test('合并K个排序链表 - 2', () => { | ||||
|   const source = [ | ||||
|     arr2List([2, 4, null]), | ||||
|     arr2List([null]), | ||||
|     arr2List([-1, null]) | ||||
|   ] | ||||
|   const out = [-1, 2, 4, null] | ||||
|   expect(mergeKLists(source)).toEqual(arr2List(out)) | ||||
| }) | ||||
|  | ||||
| test('合并K个排序链表 - 3', () => { | ||||
|   const source = [ | ||||
|     arr2List([2, 6, null]), | ||||
|     arr2List([5, null]), | ||||
|     arr2List([7, null]) | ||||
|   ] | ||||
|   const out = [2, 5, 6, 7, null] | ||||
|   expect(mergeKLists(source)).toEqual(arr2List(out)) | ||||
| }) | ||||
							
								
								
									
										6
									
								
								test/math/coin-lcci.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/math/coin-lcci.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| import { waysToChange } from '../../src/math/coin-lcci' | ||||
|  | ||||
| test('硬币', () => { | ||||
|   expect(waysToChange(5)).toBe(2) | ||||
|   expect(waysToChange(10)).toBe(4) | ||||
| }) | ||||
							
								
								
									
										6
									
								
								test/math/factorial-trailing-zeroes.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								test/math/factorial-trailing-zeroes.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| import trailingZeroes from '../../src/math/factorial-trailing-zeroes' | ||||
|  | ||||
| test('trailingZeroes', () => { | ||||
|   expect(trailingZeroes(3)).toBe(0) | ||||
|   expect(trailingZeroes(5)).toBe(1) | ||||
| }) | ||||
							
								
								
									
										12
									
								
								test/math/permutations.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								test/math/permutations.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| import { permute } from '../../src/math/permutations' | ||||
|  | ||||
| test('全排列', () => { | ||||
|   expect(permute([1, 2, 3])).toEqual([ | ||||
|     [1, 2, 3], | ||||
|     [1, 3, 2], | ||||
|     [2, 1, 3], | ||||
|     [2, 3, 1], | ||||
|     [3, 1, 2], | ||||
|     [3, 2, 1] | ||||
|   ]) | ||||
| }) | ||||
							
								
								
									
										7
									
								
								test/math/ugly-number-ii.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								test/math/ugly-number-ii.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| import { nthUglyNumber } from '../../src/math/ugly-number-ii.js' | ||||
|  | ||||
| test('丑数 II', () => { | ||||
|   expect(nthUglyNumber(9)).toBe(10) | ||||
|   expect(nthUglyNumber(1)).toBe(1) | ||||
|   expect(nthUglyNumber(10)).toBe(12) | ||||
| }) | ||||
							
								
								
									
										42
									
								
								test/stack/maximal-rectangle.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								test/stack/maximal-rectangle.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| import { maximalRectangle } from '../../src/stack/maximal-rectangle' | ||||
|  | ||||
| test('maximalRectangle', () => { | ||||
|   expect(maximalRectangle([ | ||||
|     ['1', '0', '1', '0', '0'], | ||||
|     ['1', '0', '1', '1', '1'], | ||||
|     ['1', '1', '1', '1', '1'], | ||||
|     ['1', '0', '0', '1', '0'] | ||||
|   ])).toBe(6) | ||||
|  | ||||
|   expect(maximalRectangle([ | ||||
|     [1, 1, 0, 0, 1], | ||||
|     [0, 1, 0, 0, 1], | ||||
|     [0, 0, 1, 1, 1], | ||||
|     [0, 0, 1, 1, 1], | ||||
|     [0, 0, 0, 0, 1] | ||||
|   ])).toBe(6) | ||||
|  | ||||
|   expect(maximalRectangle([ | ||||
|     [true, true, false, false, true], | ||||
|     [false, true, false, false, true], | ||||
|     [false, false, true, true, true], | ||||
|     [false, false, true, true, true], | ||||
|     [false, false, false, false, true] | ||||
|   ])).toBe(6) | ||||
|  | ||||
|   expect(maximalRectangle([ | ||||
|     [0, 0], | ||||
|     [0, 0] | ||||
|   ])).toBe(0) | ||||
|  | ||||
|   expect(maximalRectangle([['1']])).toBe(1) | ||||
|   expect(maximalRectangle([['0', '1']])).toBe(1) | ||||
|   expect(maximalRectangle([['1', '1']])).toBe(2) | ||||
|   expect(maximalRectangle([['1', '1', '1', '1']])).toBe(4) | ||||
|   expect(maximalRectangle([[1], [0], [1], [1], [1], [1], [0]])).toBe(4) | ||||
|   expect(maximalRectangle([[1], [0], [1], [1], [1], [1], [1], [0]])).toBe(5) | ||||
|   expect(maximalRectangle([['0', '1'], ['1', '0']])).toBe(1) | ||||
|   expect(maximalRectangle([['0', '1'], ['0', '1']])).toBe(2) | ||||
|   expect(maximalRectangle([['1', '0'], ['1', '0']])).toBe(2) | ||||
|   expect(maximalRectangle([['0', '0', '0'], ['0', '0', '0'], ['1', '1', '1']])).toBe(3) | ||||
| }) | ||||
							
								
								
									
										7
									
								
								test/string/compare-strings.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								test/string/compare-strings.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| import { compareStrings } from '../../src/string/compare-strings' | ||||
|  | ||||
| test('比较字符串', () => { | ||||
|   expect(compareStrings('ABCD', 'AB')).toBe(true) | ||||
|   expect(compareStrings('ABCD', 'ACD')).toBe(true) | ||||
|   expect(compareStrings('ABCD', 'AABC')).toBe(false) | ||||
| }) | ||||
							
								
								
									
										7
									
								
								test/string/contains-duplicate.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								test/string/contains-duplicate.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| import { containsDuplicate } from '../../src/string/contains-duplicate' | ||||
|  | ||||
| test('存在重复元素', () => { | ||||
|   expect(containsDuplicate([1, 2, 3, 1])).toBe(true) | ||||
|   expect(containsDuplicate([1, 2, 3, 4])).toBe(false) | ||||
|   expect(containsDuplicate([1, 1, 1, 3, 3, 4, 3, 2, 4, 2])).toBe(true) | ||||
| }) | ||||
							
								
								
									
										9
									
								
								test/string/count-binary-substrings.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								test/string/count-binary-substrings.test.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										12
									
								
								test/string/regular-expression-matching.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								test/string/regular-expression-matching.test.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| import regularExpressionMatching from '../../src/string/regular-expression-matching' | ||||
|  | ||||
| test('regularExpressionMatching', () => { | ||||
|   expect(regularExpressionMatching('aa', 'a')).toEqual(false) | ||||
|   expect(regularExpressionMatching('aaa', 'aa')).toEqual(false) | ||||
|   expect(regularExpressionMatching('aa', 'aa')).toEqual(true) | ||||
|   expect(regularExpressionMatching('aa', 'a*')).toEqual(true) | ||||
|   expect(regularExpressionMatching('ab', '.*')).toEqual(true) | ||||
|   expect(regularExpressionMatching('aab', 'c*a*b')).toEqual(true) | ||||
|   expect(regularExpressionMatching('mississippi', 'mis*is*p*.')).toEqual(false) | ||||
|   expect(regularExpressionMatching('mississippi', 'mis*is*ip*.')).toEqual(true) | ||||
| }) | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user