diff --git a/.vscode/settings.json b/.vscode/settings.json
index fe576cb..f139b9e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -11,6 +11,7 @@
"defanging",
"dvdf",
"eleetminicoworoep",
+ "inorder",
"lcci",
"lcof",
"lcov",
@@ -20,6 +21,7 @@
"mincost",
"nums",
"powx",
+ "preorder",
"pwwkew",
"qian",
"subarray",
diff --git a/README.md b/README.md
index 3943e4c..8b62ab9 100644
--- a/README.md
+++ b/README.md
@@ -372,6 +372,11 @@ LeetCode 与 LintCode 解题记录。此为个人练习仓库,代码中对重
- LeetCode 560. 和为K的子数组
- LintCode 838. 子数组和为K
+- [完美数](src/math/perfect-number.js)
+
+ - LeetCode 507. 完美数
+ - LintCode 1199. 完美的数
+
## 堆
- [超级丑数](src/stack/super-ugly-number.js)【未完成】
@@ -411,6 +416,11 @@ LeetCode 与 LintCode 解题记录。此为个人练习仓库,代码中对重
- LeetCode 107. 二叉树的层次遍历 II
- LintCode 70. 二叉树的层次遍历 II
+- [从前序与中序遍历序列构造二叉树](src/tree/construct-binary-tree-from-preorder-and-inorder-traversal.js)
+
+ - LeetCode 105. 从前序与中序遍历序列构造二叉树
+ - LintCode 73. 前序遍历和中序遍历树构造二叉树
+
## 链表
- [合并K个排序链表](src/list/merge-k-sorted-lists.js)
diff --git a/src/math/perfect-number.js b/src/math/perfect-number.js
new file mode 100644
index 0000000..0aa7929
--- /dev/null
+++ b/src/math/perfect-number.js
@@ -0,0 +1,16 @@
+const pn = (p) => { // 欧几里得-欧拉定理
+ return (1 << (p - 1)) * ((1 << p) - 1)
+}
+
+/**
+ * @param {number} num
+ * @return {boolean}
+ */
+export const checkPerfectNumber = function (num) {
+ const primes = [2, 3, 5, 7, 13, 17, 19, 31]
+ for (const prime of primes) {
+ if (pn(prime) === num) return true
+ }
+
+ return false
+}
diff --git a/src/tree/construct-binary-tree-from-preorder-and-inorder-traversal.js b/src/tree/construct-binary-tree-from-preorder-and-inorder-traversal.js
new file mode 100644
index 0000000..661cffc
--- /dev/null
+++ b/src/tree/construct-binary-tree-from-preorder-and-inorder-traversal.js
@@ -0,0 +1,26 @@
+/**
+ * Definition for a binary tree node.
+ */
+function TreeNode (val) {
+ this.val = val
+ this.left = this.right = null
+}
+
+// 前序遍历:根左右
+// 中序遍历:左根右
+
+// 前序遍历知道根、中序遍历知道左边长度。
+
+/**
+ * @param {number[]} preorder
+ * @param {number[]} inorder
+ * @return {TreeNode}
+ */
+export const buildTree = function (preorder, inorder) {
+ if (inorder.length === 0) return null
+ const root = new TreeNode(preorder[0])
+ const index = inorder.indexOf(preorder[0])
+ root.left = buildTree(preorder.slice(1, index + 1), inorder.slice(0, index))
+ root.right = buildTree(preorder.slice(index + 1), inorder.slice(index + 1))
+ return root
+}
diff --git a/test/math/perfect-number.test.js b/test/math/perfect-number.test.js
new file mode 100644
index 0000000..039adce
--- /dev/null
+++ b/test/math/perfect-number.test.js
@@ -0,0 +1,6 @@
+import { checkPerfectNumber } from '../../src/math/perfect-number'
+
+test('完美数', () => {
+ expect(checkPerfectNumber(28)).toBe(true)
+ expect(checkPerfectNumber(2)).toBe(false)
+})
diff --git a/test/tree/construct-binary-tree-from-preorder-and-inorder-traversal.test.js b/test/tree/construct-binary-tree-from-preorder-and-inorder-traversal.test.js
new file mode 100644
index 0000000..81eb30d
--- /dev/null
+++ b/test/tree/construct-binary-tree-from-preorder-and-inorder-traversal.test.js
@@ -0,0 +1,5 @@
+import { buildTree } from '../../src/tree/construct-binary-tree-from-preorder-and-inorder-traversal'
+
+test('从前序与中序遍历序列构造二叉树', () => {
+ expect(buildTree([3, 9, 20, 15, 7], [9, 3, 15, 20, 7])).toEqual({ left: { left: null, right: null, val: 9 }, right: { left: { left: null, right: null, val: 15 }, right: { left: null, right: null, val: 7 }, val: 20 }, val: 3 })
+})