add: 只出现一次的数字等
This commit is contained in:
parent
930ff1be11
commit
8239e7afd5
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
Loading…
Reference in New Issue
Block a user