diff --git a/README.md b/README.md
index e6fd57c..8b24025 100644
--- a/README.md
+++ b/README.md
@@ -376,6 +376,11 @@ LeetCode 与 LintCode 解题记录。此为个人练习仓库,代码中对重
- LeetCode 739. 每日温度
- LintCode 1060. 每日温度
+- [最长重复子数组](src/array/maximum-length-of-repeated-subarray.js)
+
+ - LeetCode 718. 最长重复子数组
+ - LintCode 79. 最长公共子串
+
## 栈
- [最大矩阵](src/stack/maximal-rectangle.js)
diff --git a/src/array/maximum-length-of-repeated-subarray.js b/src/array/maximum-length-of-repeated-subarray.js
new file mode 100644
index 0000000..3826de0
--- /dev/null
+++ b/src/array/maximum-length-of-repeated-subarray.js
@@ -0,0 +1,38 @@
+// 输入:
+// A: [1, 2, 3, 2, 1]
+// B: [3, 2, 1, 4, 7]
+
+const maxLength = function (A, B, addA, addB, len) {
+ addA = (addA > 0) ? addA : 0
+ addB = (addB > 0) ? addB : 0
+ let result = 0
+ let k = 0
+ for (let i = 0; i < len && (k + len - i > result); i++) {
+ if (A[i + addA] === B[i + addB]) {
+ k++
+ } else {
+ k = 0
+ }
+ result = Math.max(result, k)
+ }
+ return result
+}
+
+/**
+ * @param {number[]} A
+ * @param {number[]} B
+ * @return {number}
+ */
+export const findLength = function (A, B) {
+ const ALen = A.length
+ const BLen = B.length
+ let result = 0
+ for (let i = 1; i < ALen + BLen; i++) {
+ if (result >= (ALen + BLen - i)) {
+ return result
+ }
+ const len = Math.min(i, ALen, BLen, (ALen + BLen - i))
+ result = Math.max(maxLength(A, B, ALen - i, i - ALen, len), result)
+ }
+ return result
+}
diff --git a/test/array/maximum-length-of-repeated-subarray.test.js b/test/array/maximum-length-of-repeated-subarray.test.js
new file mode 100644
index 0000000..720e058
--- /dev/null
+++ b/test/array/maximum-length-of-repeated-subarray.test.js
@@ -0,0 +1,5 @@
+import { findLength } from '../../src/array/maximum-length-of-repeated-subarray.js'
+
+test('最长重复子数组', () => {
+ expect(findLength([1, 2, 3, 2, 1], [3, 2, 1, 4, 7])).toBe(3)
+})