diff --git a/README.md b/README.md
index d178358..00a70af 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,103 @@
+# 北大令狐冲的LeetCode算法小抄Cheatsheet
+首先自报家门，高中开始刷题，算法竞赛保送北大计算机学院，本硕连读毕业后，拿到网易、人人网、阿里、FB等公司offer，最终选择赴美国硅谷参加工作。到现在为止，刷过的算法题已超过**3000道**。
 
-# 算法与数据结构
+废话不多说，直接上干货。祭出我爆肝3个月、增删16次的[《面试常考算法模板Cheatsheet》](https://github.com/ninechapter-algorithm/leetcode-linghu-templete/tree/master/%E4%BB%A4%E7%8B%90%E8%80%81%E5%B8%88%E7%9A%84%E7%AE%97%E6%B3%95%E5%B0%8F%E6%8A%84)，在本仓库第二个文档直接下载。
 
-[位运算面试题总结](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E4%BD%8D%E8%BF%90%E7%AE%97%E9%9D%A2%E8%AF%95%E9%A2%98%E6%80%BB%E7%BB%93.md)
+这套《面试常考算法模板cheatsheet》，代码量不算少，案例也算不上牛逼，但绝对经典，绝对通用！像是二分、双指针、排序算法、二叉树、宽度优先搜索、深度优先搜索的使用条件、时间复杂度、代码模板，我也都整理好了。
 
+## 面试常考算法模板Cheatsheet的用法
 
-[线段树知识点总结](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E7%BA%BF%E6%AE%B5%E6%A0%91%E7%9F%A5%E8%AF%86%E7%82%B9%E6%80%BB%E7%BB%93.md)
+为了让大家能在我的Github得到尽可能多的帮助，这里献上使用方法：
 
-[动态规划十问十答](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E5%8D%81%E9%97%AE%E5%8D%81%E7%AD%94.md)
+1、**先给本仓库点个star**，再背我总结的算法模板（模板都不想花时间背，就别继续看了）
 
-# 算法面试题解
+2、跟着下面目录中的的高频题练习（拿着模板练，一定要学会消化知识，这样才能举一反三）
 
-[Google 面试题 | 原子计数](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E9%A2%98%E8%A7%A3/Google%20%E9%9D%A2%E8%AF%95%E9%A2%98%20%7C%20%E5%8E%9F%E5%AD%90%E8%AE%A1%E6%95%B0.md)
+3、最后在[LintCode](https://www.lintcode.com/problem/?utm_source=sc-gihub-jw)找**大厂高频ladder**进行练习（别bb，拿着模板多刷题一定没错）
+ 
+## 我迭代了8年的算法学习课程-《九章算法班》
 
-[Google 面试题 | 3个非重复子数组最大和](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E9%A2%98%E8%A7%A3/Google%20%E9%9D%A2%E8%AF%95%E9%A2%98%20%7C%203%E4%B8%AA%E9%9D%9E%E9%87%8D%E5%A4%8D%E5%AD%90%E6%95%B0%E7%BB%84%E6%9C%80%E5%A4%A7%E5%92%8C.md)
+2014年我到美国Facebook工作。在硅谷，我发现华人的求职压力特别大，面对很多来自白人、印度人的竞争。为了帮助更多的人能通过Google，Facebook，Ticktok等公司的算法面试，我总结了我10多年来的刷题经验，录制了一套只有9个章节、18小时的[《九章算法班》](https://www.jiuzhang.com/course/71/?utm_source=sc-github-jw)。如今8年过去了，这套课程已经迭代到了50个章节、100多小时，也有数十万的程序员学习过我的这套课程，并找到了年薪百万的工作。
 
-[Google 面试题 | 字典里面的最长单词](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E9%A2%98%E8%A7%A3/Google%20%E9%9D%A2%E8%AF%95%E9%A2%98%20%7C%20%E5%AD%97%E5%85%B8%E9%87%8C%E9%9D%A2%E7%9A%84%E6%9C%80%E9%95%BF%E5%8D%95%E8%AF%8D.md)
+这套[《九章算法班》](https://www.jiuzhang.com/course/71/?utm_source=sc-github-jw)是收费的，但我也可以先看看我总结的免费的B站算法学习视频[《1个月刷爆LeetCode》](https://link.zhihu.com/?target=https%3A//www.bilibili.com/video/BV1i64y1u7Me/)
 
-[Google 面试题 | 找二叉树最底层最左边的节点](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E9%A2%98%E8%A7%A3/Google%20%E9%9D%A2%E8%AF%95%E9%A2%98%20%7C%20%E6%89%BE%E4%BA%8C%E5%8F%89%E6%A0%91%E6%9C%80%E5%BA%95%E5%B1%82%E6%9C%80%E5%B7%A6%E8%BE%B9%E7%9A%84%E8%8A%82%E7%82%B9.md)
+![](pictures/20220908-153017.jpeg)
+## 目录
 
-[Google 面试题 | 合法的IP的地址](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E9%A2%98%E8%A7%A3/Google%20%E9%9D%A2%E8%AF%95%E9%A2%98%20%7C%20%E5%90%88%E6%B3%95%E7%9A%84IP%E7%9A%84%E5%9C%B0%E5%9D%80.md)
+- ### **令狐老师的算法小抄**
+>[面试常考算法模板](https://github.com/ninechapter-algorithm/linghu-algorithm-templete/blob/master/%E4%BB%A4%E7%8B%90%E8%80%81%E5%B8%88%E7%9A%84%E7%AE%97%E6%B3%95%E5%B0%8F%E6%8A%84/%E9%9D%A2%E8%AF%95%E5%B8%B8%E8%80%83%E7%AE%97%E6%B3%95%E6%A8%A1%E6%9D%BF%20Cheat%20Sheet%20V4.3.pdf)
 
-# 系统设计
 
-[如何答好面试中的系统设计题](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%20Syestem%20Design/%E5%A6%82%E4%BD%95%E7%AD%94%E5%A5%BD%E9%9D%A2%E8%AF%95%E4%B8%AD%E7%9A%84%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%E9%A2%98.md)
+>[北大学霸的算法刷题笔记](https://github.com/ninechapter-algorithm/linghu-algorithm-templete/blob/master/%E5%8C%97%E5%A4%A7%E5%AD%A6%E9%9C%B8%E7%9A%84%E7%AE%97%E6%B3%95%E5%88%B7%E9%A2%98%E7%AC%94%E8%AE%B0.pdf)
+
+
+- ### **数据结构**
+
+>[二叉树搜索](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E2%BC%86%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91)
+
+>[二叉树分治](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E4%BA%8C%E5%8F%89%E6%A0%91%E5%88%86%E6%B2%BB)
+
+>[哈希表](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E5%93%88%E5%B8%8C%E8%A1%A8)
+
+>[堆](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E5%A0%86)
+
+>[字典树](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E5%AD%97%E5%85%B8%E6%A0%91)
+
+>[栈](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%A0%88)
+
+>[链表](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E9%93%BE%E8%A1%A8)
+
+
+>[线段树知识点总结](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E7%BA%BF%E6%AE%B5%E6%A0%91%E7%9F%A5%E8%AF%86%E7%82%B9%E6%80%BB%E7%BB%93.md)
+
+
+- ### **算法思维**
+>[新手编程必刷50题](https://github.com/ninechapter-algorithm/linghu-algorithm-templete/blob/master/%E7%BC%96%E7%A8%8B%E6%96%B0%E6%89%8B%E5%BF%85%E5%88%B750%E9%A2%98%20V1.0.docx)
+
+>[二分法](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E9%A2%98/%E4%BA%8C%E5%88%86%E6%B3%95)
+
+>[位运算](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E9%A2%98/%E4%BD%8D%E8%BF%90%E7%AE%97)
+
+>[分治法](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E9%A2%98/%E5%88%86%E6%B2%BB%E6%B3%95)
+
+>[双指针](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E9%A2%98/%E5%8F%8C%E6%8C%87%E9%92%88)
+
+>[字典MAP](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E9%A2%98/%E5%AD%97%E5%85%B8MAP)
+
+>[并查集](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E9%A2%98/%E5%B9%B6%E6%9F%A5%E9%9B%86)
+
+>[排序算法](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E9%A2%98/%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95)
+
+>[贪心算法](https://github.com/ninechapter-algorithm/ninechapter-algorithm/tree/master/%E7%AE%97%E6%B3%95%E6%80%9D%E7%BB%B4%E9%A2%98/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95)
+
+
+
+- ### **动态规划**
+
+>[动态规划十问十答](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E5%8D%81%E9%97%AE%E5%8D%81%E7%AD%94.md)
+
+
+- ### **系统设计**
+
+>[如何答好面试中的系统设计题](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%20Syestem%20Design/%E5%A6%82%E4%BD%95%E7%AD%94%E5%A5%BD%E9%9D%A2%E8%AF%95%E4%B8%AD%E7%9A%84%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%E9%A2%98.md)
+
+- ### **图论**
+>[宽度优先搜索](https://github.com/ninechapter-algorithm/linghu-algorithm-templete/tree/master/%E5%9B%BE%E8%AE%BA/%E5%AE%BD%E5%BA%A6%E4%BC%98%E5%85%88%E6%90%9C%E7%B4%A2)
+
+>[深度优先搜索](https://github.com/ninechapter-algorithm/linghu-algorithm-templete/tree/master/%E5%9B%BE%E8%AE%BA/%E6%B7%B1%E5%BA%A6%E4%BC%98%E5%85%88%E6%90%9C%E7%B4%A2)
+
+- ### **FANNG面试高频题**
+）
+>[算法面试必刷100题](https://github.com/ninechapter-algorithm/linghu-algorithm-templete/blob/master/%E9%AB%98%E9%A2%91/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E5%BF%85%E5%88%B7100%E9%A2%98.xlsx)
+
+>[数组题](https://github.com/ninechapter-algorithm/linghu-algorithm-templete/tree/master/%E9%AB%98%E9%A2%91/%E6%95%B0%E7%BB%84%E9%A2%98)
+
+>[Google 面试题 | 原子计数](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E9%A2%98%E8%A7%A3/Google%20%E9%9D%A2%E8%AF%95%E9%A2%98%20%7C%20%E5%8E%9F%E5%AD%90%E8%AE%A1%E6%95%B0.md)
+
+>[Google 面试题 | 3个非重复子数组最大和](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E9%A2%98%E8%A7%A3/Google%20%E9%9D%A2%E8%AF%95%E9%A2%98%20%7C%203%E4%B8%AA%E9%9D%9E%E9%87%8D%E5%A4%8D%E5%AD%90%E6%95%B0%E7%BB%84%E6%9C%80%E5%A4%A7%E5%92%8C.md)
+
+>[Google 面试题 | 字典里面的最长单词](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E9%A2%98%E8%A7%A3/Google%20%E9%9D%A2%E8%AF%95%E9%A2%98%20%7C%20%E5%AD%97%E5%85%B8%E9%87%8C%E9%9D%A2%E7%9A%84%E6%9C%80%E9%95%BF%E5%8D%95%E8%AF%8D.md)
+
+>[Google 面试题 | 找二叉树最底层最左边的节点](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E9%A2%98%E8%A7%A3/Google%20%E9%9D%A2%E8%AF%95%E9%A2%98%20%7C%20%E6%89%BE%E4%BA%8C%E5%8F%89%E6%A0%91%E6%9C%80%E5%BA%95%E5%B1%82%E6%9C%80%E5%B7%A6%E8%BE%B9%E7%9A%84%E8%8A%82%E7%82%B9.md)
+
+>[Google 面试题 | 合法的IP的地址](https://github.com/ninechapter-algorithm/ninechapter-algorithm/blob/master/%E7%AE%97%E6%B3%95%E9%9D%A2%E8%AF%95%E9%A2%98%E8%A7%A3/Google%20%E9%9D%A2%E8%AF%95%E9%A2%98%20%7C%20%E5%90%88%E6%B3%95%E7%9A%84IP%E7%9A%84%E5%9C%B0%E5%9D%80.md)
diff --git a/pictures/20220221-154912.jpg b/pictures/20220221-154912.jpg
new file mode 100644
index 0000000..a5678bb
Binary files /dev/null and b/pictures/20220221-154912.jpg differ
diff --git a/pictures/20220908-153017.jpeg b/pictures/20220908-153017.jpeg
new file mode 100644
index 0000000..ecb140c
Binary files /dev/null and b/pictures/20220908-153017.jpeg differ
diff --git "a/\344\273\244\347\213\220\350\200\201\345\270\210\347\232\204\347\256\227\346\263\225\345\260\217\346\212\204/\351\235\242\350\257\225\345\270\270\350\200\203\347\256\227\346\263\225\346\250\241\346\235\277 Cheat Sheet V4.3.pdf" "b/\344\273\244\347\213\220\350\200\201\345\270\210\347\232\204\347\256\227\346\263\225\345\260\217\346\212\204/\351\235\242\350\257\225\345\270\270\350\200\203\347\256\227\346\263\225\346\250\241\346\235\277 Cheat Sheet V4.3.pdf"
new file mode 100644
index 0000000..e62367d
Binary files /dev/null and "b/\344\273\244\347\213\220\350\200\201\345\270\210\347\232\204\347\256\227\346\263\225\345\260\217\346\212\204/\351\235\242\350\257\225\345\270\270\350\200\203\347\256\227\346\263\225\346\250\241\346\235\277 Cheat Sheet V4.3.pdf" differ
diff --git "a/\345\205\266\344\273\226/n-gram-map-reduce.md" "b/\345\205\266\344\273\226/n-gram-map-reduce.md"
new file mode 100644
index 0000000..fa7f88b
--- /dev/null
+++ "b/\345\205\266\344\273\226/n-gram-map-reduce.md"
@@ -0,0 +1,46 @@
+# N-Gram (Map Reduce)
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/n-gram-map-reduce/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出若干字符串和数字 N。用 Map Reduce 的方法统计所有 N-Grams 及其出现次数 。以字母为粒度。
+ ### 样例说明
+ 
+ ### 参考代码
+ 遍历每个字符串，从每个位置开始，截取一定长度的子串，记录即可
+```java
+/**
+ * Definition of OutputCollector:
+ * class OutputCollector<K, V> {
+ *     public void collect(K key, V value);
+ *         // Adds a key/value pair to the output buffer
+ * }
+ */
+public class NGram {
+
+    public static class Map {
+        public void map(String _, int n, String str,
+                        OutputCollector<String, Integer> output) {
+            // Write your code here
+            // Output the results into output buffer.
+            // Ps. output.collect(String key, Integer value);
+            for (int index = 0; index < str.length() - n + 1; ++index) {
+                output.collect(str.substring(index, index + n), 1);
+            }
+        }
+    }
+
+    public static class Reduce {
+        public void reduce(String key, Iterator<Integer> values,
+                           OutputCollector<String, Integer> output) {
+            // Write your code here
+            // Output the results into output buffer.
+            // Ps. output.collect(String key, int value);
+            int sum = 0;
+            while (values.hasNext()) {
+                    sum += values.next();
+            }
+            output.collect(key, sum);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\205\266\344\273\226/readme.md" "b/\345\205\266\344\273\226/readme.md"
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ "b/\345\205\266\344\273\226/readme.md"
@@ -0,0 +1 @@
+
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/arithmetic-slices-ii-subsequence.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/arithmetic-slices-ii-subsequence.md"
new file mode 100644
index 0000000..782ea3f
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/arithmetic-slices-ii-subsequence.md"
@@ -0,0 +1,126 @@
+# 等差切片 II - 子序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/arithmetic-slices-ii-subsequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 如果一个数字序列由至少三个元素组成, 并且任何两个相邻元素之间的差值相同, 则称之为等差数列.
+
+比如, 下面这些就是等差数列:
+```
+1,  3,  5,  7,  9
+7,  7,  7,  7
+3, -1, -5, -9
+```
+而下面这个序列就不是等差的:
+```
+1, 1, 2, 5, 7
+```
+
+给定一个数组 `A`, 它的长度为 `N`. 对于任意 `A[P0], A[P1], ..., A[Pk]`, 如果它满足 `0 ≤ P0 < P1 < ... < Pk < N`, 则称它为 `A` 的一个子序列切片.
+
+如果 `A[P0], A[P1], ..., A[Pk]` 是等差的, 则称它是 `A` 的一个等差切片. 注意, 这意味着 k ≥ 2.
+
+返回 `A` 中等差切片的数量.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [2, 4, 6, 8, 10]
+输出: 7
+解释: 
+    所有的等差切片为:
+    [2, 4, 6] 
+    [4, 6, 8] 
+    [2, 6, 10]
+    [6, 8, 10]
+    [2, 4, 6, 8]
+    [4, 6, 8, 10]
+    [2, 4, 6, 8, 10]
+```
+
+**样例 2:**
+
+```
+输入: [1, 2, 3]
+输出: 1
+解释: 只有 [1, 2, 3]
+```
+ ### 参考代码
+ 设定状态:
+
+```
+f[i][d]  表示以 A 中下标为 i 的数结尾的, 公差为 d 的等差切片的数量
+f2[i][d] 表示以 A 中下标为 i 的数结尾的, 长度为 2 的, 公差为 d 的等差切片的数量
+(f2记录的严格来说并不能称为等差切片, 因为长度小于 3, 只是为了描述方便)
+```
+
+状态转移:
+
+```C++
+对于 i, 枚举 0 <= j < i, d = A[i] - A[j]
+f[i][d] += f2[j][d] + f[j][d]   // 以 j 结尾的长度为2的等差切片, 增加了 A[i] 就会变成真正的等差切片
+f2[i][d] += 1                   // A[j], A[i] 组成一个长度为 2 的等差切片
+```
+
+最后答案就是 f 内所有整数的和. 由于公差 d 可能是负数, 可能非常大而且不连续, 所以我们采用哈希表存储.
+```java
+public class Solution {
+    public int numberOfArithmeticSlices(int[] A) {
+        if (A == null || A.length < 3) {
+            return 0;
+        }
+        int N = A.length;
+        Map<Integer, Integer>[] f = new Map[N];
+        Map<Integer, Integer>[] f2 = new Map[N];
+        int ans = 0;
+        for (int i = 0; i < N; i++) {
+            f[i] = new HashMap<>();
+            f2[i] = new HashMap<>();
+            for (int j = 0; j < i; j++) {
+                if (Math.abs((long)A[i] - A[j]) > Integer.MAX_VALUE) {
+                    continue;
+                }
+                int d = A[i] - A[j];
+                
+                int f2_j_d = f2[j].getOrDefault(d, 0);
+                int f_j_d = f[j].getOrDefault(d, 0);
+                int f_i_d = f[i].getOrDefault(d, 0);
+                f[i].put(d, f_i_d + f_j_d + f2_j_d);
+                
+                int f2_i_d = f2[i].getOrDefault(d, 0);
+                f2[i].put(d, f2_i_d + 1);
+            }
+            
+            for (Integer o : f[i].keySet()) {
+                ans += f[i].get(o);
+            }
+        }
+        return ans;
+    }
+}
+
+// version2: 更简洁的写法
+public class Solution {
+    public int numberOfArithmeticSlices(int[] A) {
+        if (A == null || A.length < 3) {
+            return 0;
+        }
+        Map<Integer, Integer>[] map = new Map[A.length];
+        int ans = 0;
+        for (int i = 0; i < A.length; i++) {
+            map[i] = new HashMap<>();
+            for (int j = 0; j < i; j++) {
+                if (Math.abs((long)A[i] - A[j]) > Integer.MAX_VALUE) {
+                    continue;
+                }
+                int d = A[i] - A[j];
+                int map_i_d = map[i].getOrDefault(d, 0);
+                int map_j_d = map[j].getOrDefault(d, 0);
+                map_i_d += map_j_d + 1;
+                map[i].put(d, map_i_d);
+                ans += map_j_d;
+            }
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-ii.md"
new file mode 100644
index 0000000..ec955f7
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-ii.md"
@@ -0,0 +1,42 @@
+# 背包问题 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/backpack-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有 `n` 个物品和一个大小为 `m` 的背包. 给定数组 `A` 表示每个物品的大小和数组 `V` 表示每个物品的价值.
+
+问最多能装入背包的总价值是多大?
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: m = 10, A = [2, 3, 5, 7], V = [1, 5, 2, 4]
+输出: 9
+解释: 装入 A[1] 和 A[3] 可以得到最大价值, V[1] + V[3] = 9 
+```
+
+**样例 2:**
+
+```
+输入: m = 10, A = [2, 3, 8], V = [2, 5, 8]
+输出: 10
+解释: 装入 A[0] 和 A[2] 可以得到最大价值, V[0] + V[2] = 10
+```
+ ### 参考代码
+ 经典的01背包问题, 资源分配型动态规划.
+
+设定 f[i][j] 表示前 i 个物品装入大小为 j 的背包里, 可以获取的最大价值总和. 决策就是第i个物品装不装入背包, 所以状态转移方程就是 `f[i][j] = max(f[i - 1][j], f[i - 1][j - A[i]] + V[i])`
+
+可以使用滚动数组优化空间至 O(m).
+```python
+class Solution:
+    # @param m: An integer m denotes the size of a backpack
+    # @param A & V: Given n items with size A[i] and value V[i]
+    def backPackII(self, m, A, V):
+        # write your code here
+        f = [0 for i in xrange(m+1)]
+        n = len(A)
+        for i in range(n):
+            for j in xrange(m, A[i]-1, -1):
+                f[j] = max(f[j] , f[j-A[i]] + V[i])
+        return f[m]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-iii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-iii.md"
new file mode 100644
index 0000000..449fd22
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-iii.md"
@@ -0,0 +1,46 @@
+# 背包问题 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/backpack-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定 `n` 种物品, 每种物品都有无限个. 第 `i` 个物品的体积为 `A[i]`, 价值为 `V[i]`.
+
+再给定一个容量为 `m` 的背包. 问可以装入背包的最大价值是多少?
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: A = [2, 3, 5, 7], V = [1, 5, 2, 4], m = 10
+输出: 15
+解释: 装入三个物品 1 (A[1] = 3, V[1] = 5), 总价值 15.
+```
+
+**样例 2:**
+
+```
+输入: A = [1, 2, 3], V = [1, 2, 3], m = 5
+输出: 5
+解释: 策略不唯一. 比如, 装入五个物品 0 (A[0] = 1, V[0] = 1).
+```
+ ### 参考代码
+ 类似于最基本的01背包, 我们设定 `f[i][j]` 表示前 `i` 种物品装到容量为 `j` 的背包里, 能获取的最大价值为多少.
+
+比较简单的转移是直接枚举第i种物品取用多少个: `f[i][j] = max{f[i - 1][j - x * A[i]] + x * V[i]}`
+
+但是这样速度较慢, 可以优化成 `f[i][j]` 直接由 `f[i][j - A[i]]` 转移, 并且从小到大枚举 `j`, 这样做的含义就是在已经拿过第 `i` 个物品的之后还可以再拿它. 也就是说: 计算 `f[i][j]` 时, 初始设置为 `f[i - 1][j]`, 然后 `f[i][j] = max(f[i][j], f[i][j - A[i]] + V[i])`
+
+另外, 可以使用滚动数组优化, 使用滚动数组之后也不必要手动设置 `f[i][j] = f[i - 1][j]`, 与01背包使用的滚动数组相反, 这里恰好需要正着枚举容量 `j`, 因而有 `f[j] = max(f[j], f[j - A[i]] + V[i])`
+```python
+class Solution:
+    # @param {int[]} A an integer array
+    # @param {int[]} V an integer array
+    # @param {int} m an integer
+    # @return {int} an array
+    def backPackIII(self, A, V, m):
+        # Write your code here
+        f = [0 for i in xrange(m+1)]
+        for (a, v) in zip(A, V):
+            for j in xrange(a, m+1):
+                if f[j - a] + v > f[j]:
+                    f[j] = f[j - a] + v
+        return f[m]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-iv.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-iv.md"
new file mode 100644
index 0000000..141d43b
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-iv.md"
@@ -0,0 +1,48 @@
+# 背包问题 IV
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/backpack-iv/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出 n 个物品, 以及一个数组, `nums[i]`代表第i个物品的大小, 保证大小均为正数并且没有重复, 正整数 `target` 表示背包的大小, 找到能填满背包的方案数。
+`每一个物品可以使用无数次`
+ ### 样例说明
+ **样例1**
+
+```
+输入: nums = [2,3,6,7] 和 target = 7
+输出: 2
+解释:
+方案有: 
+[7]
+[2, 2, 3]
+```
+
+**样例2**
+
+```
+输入: nums = [2,3,4,5] 和 target = 7
+输出: 3
+解释:
+方案有: 
+[2, 5]
+[3, 4]
+[2, 2, 3]
+```
+ ### 参考代码
+ 效率比较高的版本。时间复杂度 $O(n * target)$
+```python
+class Solution:
+    """
+    @param nums: an integer array and all positive numbers, no duplicates
+    @param target: An integer
+    @return: An integer
+    """
+    def backPackIV(self, nums, target):
+        dp = [0] * (target + 1)
+        dp[0] = 1
+        
+        for num in nums:
+            for i in range(num, target + 1):
+                dp[i] += dp[i - num]
+
+        return dp[target]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-v.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-v.md"
new file mode 100644
index 0000000..a2a9137
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-v.md"
@@ -0,0 +1,41 @@
+# 背包问题 V
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/backpack-v/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出 n 个物品, 以及一个数组, `nums[i]` 代表第i个物品的大小, 保证大小均为正数, 正整数 `target` 表示背包的大小, 找到能填满背包的方案数。
+`每一个物品只能使用一次`
+ ### 样例说明
+ 给出候选物品集合 `[1,2,3,3,7]` 以及 target `7`
+```
+结果的集合为:
+[7]
+[1,3,3]
+```
+返回 `2`
+ ### 参考代码
+ 带一点优化的动态规划。
+
+- 滚动数组。优化了空间。
+- 前缀和。优化了时间。没有必要每次都算到 target 那么多的值。
+```python
+class Solution:
+    """
+    @param nums: an integer array and all positive numbers
+    @param target: An integer
+    @return: An integer
+    """
+    def backPackV(self, nums, target):
+        f = [[0] * (target + 1), [0] * (target + 1)]
+        f[0][0] = 1
+        n = len(nums)
+        prefix_sum = 0
+        for i in range(1, n + 1):
+            f[i % 2][0] = 1
+            prefix_sum += nums[i - 1]
+            for j in range(1, min(target, prefix_sum) + 1):
+                f[i % 2][j] = f[(i - 1) % 2][j]
+                if j >= nums[i - 1]:
+                    f[i % 2][j] += f[(i - 1) % 2][j - nums[i - 1]]
+        
+        return f[n % 2][target]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-vi.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-vi.md"
new file mode 100644
index 0000000..f8178ae
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack-vi.md"
@@ -0,0 +1,26 @@
+# 组合总和 IV
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/backpack-vi/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个都是正整数的数组 `nums`，其中没有重复的数。从中找出所有的和为 `target` 的组合个数。
+ ### 样例说明
+ 
+ ### 参考代码
+ dp求解，dp[i]表示当前和为i的解法个数
+```python
+class Solution:
+    # @param {int[]} nums an integer array and all positive numbers, no duplicates
+    # @param {int} target an integer
+    # @return {int} an integer
+    def backPackVI(self, nums, target):
+        # Write your code here
+        dp = [0 for i in xrange(target + 1)]
+        dp[0] = 1
+        
+        for j in xrange(1, target+1):
+            for a in nums:
+                if j >= a:
+                    dp[j] += dp[j - a]
+
+        return dp[target]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/backpack.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack.md"
new file mode 100644
index 0000000..749e53e
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/backpack.md"
@@ -0,0 +1,43 @@
+# 背包问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/backpack/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>在n个物品中挑选若干物品装入背包，最多能装多满？假设背包的大小为m，每个物品的大小为A[i]</p>
+ ### 样例说明
+ ```
+样例 1:
+	输入:  [3,4,8,5], backpack size=10
+	输出:  9
+
+样例 2:
+	输入:  [2,3,5,7], backpack size=12
+	输出:  12
+	
+```
+ ### 参考代码
+ 传统的背包问题解法。二维动态规划。
+```python
+class Solution:
+    """
+    @param m: An integer m denotes the size of a backpack
+    @param A: Given n items with size A[i]
+    @return: The maximum size
+    """
+    def backPack(self, m, A):
+        n = len(A)
+        f = [[False] * (m + 1) for _ in range(n + 1)]
+        
+        f[0][0] = True
+        for i in range(1, n + 1):
+            f[i][0] = True
+            for j in range(1, m + 1):
+                if j >= A[i - 1]:
+                    f[i][j] = f[i - 1][j] or f[i - 1][j - A[i - 1]]
+                else:
+                    f[i][j] = f[i - 1][j]
+                    
+        for i in range(m, -1, -1):
+            if f[n][i]:
+                return i
+        return 0
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/binary-tree-maximum-path-sum.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/binary-tree-maximum-path-sum.md"
new file mode 100644
index 0000000..e6280bc
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/binary-tree-maximum-path-sum.md"
@@ -0,0 +1,108 @@
+# 二叉树中的最大路径和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-maximum-path-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <span style="line-height: 30px;"><font color="#000000">给出一棵二叉树，</font></span><font color="#000000"><span style="line-height: 30px;">寻找一条路径使其路径和最大，路径可以在任一节点中开始和结束（路径和为两个节点之间所在路径上的节点权值之和）</span></font><br>
+ ### 样例说明
+ ```
+样例 1:
+	输入:  给定一棵树（只有一个节点）:
+	2
+	输出：2
+	
+样例 2:
+	输入:  给定一棵树：
+
+      1
+     / \
+    2   3
+		
+	输出: 6
+
+	
+```
+ ### 参考代码
+ Given a binary tree, find the maximum path sum.&nbsp;<div>The path may start and end at any node in the tree.&nbsp;</div><div><br></div><div>For example:&nbsp;</div><div>Given the below binary tree,&nbsp;</div><div>&nbsp; 1&nbsp;</div><div>&nbsp;/ &nbsp;\&nbsp;</div><div>2 &nbsp; 3&nbsp;</div><div><span style="line-height: 1.42857143;">Return 6.</span><br></div><div><div><br></div><div>详细题解请见九章算法微博：<a href="http://weibo.com/3948019741/BBY7gwi89" target="_blank">http://weibo.com/3948019741/BBY7gwi89</a></div></div>
+
+分治法。
+需要考虑的是，子树中最大的路不一定必过根节点。所以要记录single Path的值。
+见代码注释。
+```java
+public class Solution {
+    private class ResultType {
+        // singlePath: 从root往下走到任意点的最大路径，这条路径可以不包含任何点
+        // maxPath: 从树中任意到任意点的最大路径，这条路径至少包含一个点
+        int singlePath, maxPath; 
+        ResultType(int singlePath, int maxPath) {
+            this.singlePath = singlePath;
+            this.maxPath = maxPath;
+        }
+    }
+
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, Integer.MIN_VALUE);
+        }
+        // Divide
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        // Conquer
+        int singlePath = Math.max(left.singlePath, right.singlePath) + root.val;
+        singlePath = Math.max(singlePath, 0);
+
+        int maxPath = Math.max(left.maxPath, right.maxPath);
+        maxPath = Math.max(maxPath, left.singlePath + right.singlePath + root.val);
+
+        return new ResultType(singlePath, maxPath);
+    }
+
+    public int maxPathSum(TreeNode root) {
+        ResultType result = helper(root);
+        return result.maxPath;
+    }
+}
+
+
+// Version 2:
+// SinglePath也定义为，至少包含一个点。
+public class Solution {
+    /**
+     * @param root: The root of binary tree.
+     * @return: An integer.
+     */
+    private class ResultType {
+        int singlePath, maxPath;
+        ResultType(int singlePath, int maxPath) {
+            this.singlePath = singlePath;
+            this.maxPath = maxPath;
+        }
+    }
+
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(Integer.MIN_VALUE, Integer.MIN_VALUE);
+        }
+        // Divide
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        // Conquer
+        int singlePath =
+            Math.max(0, Math.max(left.singlePath, right.singlePath)) + root.val;
+
+        int maxPath = Math.max(left.maxPath, right.maxPath);
+        maxPath = Math.max(maxPath,
+                           Math.max(left.singlePath, 0) + 
+                           Math.max(right.singlePath, 0) + root.val);
+
+        return new ResultType(singlePath, maxPath);
+    }
+
+    public int maxPathSum(TreeNode root) {
+        ResultType result = helper(root);
+        return result.maxPath;
+    }
+
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/bomb-enemy.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/bomb-enemy.md"
new file mode 100644
index 0000000..e1e38f1
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/bomb-enemy.md"
@@ -0,0 +1,166 @@
+# 炸弹袭击
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/bomb-enemy/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二维矩阵, 每一个格子可能是一堵墙 `W`,或者 一个敌人 `E` 或者空 `0` (数字 '0'), 返回你可以用一个炸弹杀死的最大敌人数. 炸弹会杀死所有在同一行和同一列没有墙阻隔的敌人。 由于墙比较坚固，所以墙不会被摧毁.
+ ### 样例说明
+ **样例1**
+
+```
+输入:
+grid =[
+     "0E00",
+     "E0WE",
+     "0E00"
+]
+输出: 3
+解释:
+把炸弹放在 (1,1) 能杀3个敌人
+```
+
+**样例2**
+
+```
+输入:
+grid =[
+     "0E00",
+     "EEWE",
+     "0E00"
+]
+输出: 2
+解释:
+P把炸弹放在 (0,0) 或 (0,3) 或 (2,0) 或 (2,3) 能杀2个敌人
+```
+ ### 参考代码
+ 预处理出每个点向四个方向能炸到的人数，然后枚举所有点，取最大值即可
+```java
+public class Solution {
+    /**
+     * @param grid Given a 2D grid, each cell is either 'W', 'E' or '0'
+     * @return an integer, the maximum enemies you can kill using one bomb
+     */
+    public int maxKilledEnemies(char[][] grid) {
+        // Write your code here
+        int m = grid.length;
+        int n = m > 0 ? grid[0].length : 0;
+
+        int result = 0, rows = 0;
+        int[] cols = new int[n];
+        for (int i = 0; i < m; ++i) {
+            for (int j = 0; j < n; ++j) {
+                if (j == 0 || grid[i][j-1] == 'W') {
+                    rows = 0;
+                    for (int k = j; k < n && grid[i][k] != 'W'; ++k)
+                        if (grid[i][k] == 'E')
+                            rows += 1;
+                }
+                if (i == 0 || grid[i-1][j] == 'W') {
+                    cols[j] = 0;
+                    for (int k = i; k < m && grid[k][j] != 'W'; ++k)
+                        if (grid[k][j] == 'E')
+                            cols[j] += 1;
+                }
+
+                if (grid[i][j] == '0' && rows + cols[j] > result)
+                    result = rows + cols[j];
+            }
+        }
+        return result;
+    }
+}
+
+// 方法二
+public class Solution {
+    /**
+     * @param grid Given a 2D grid, each cell is either 'W', 'E' or '0'
+     * @return an integer, the maximum enemies you can kill using one bomb
+     */
+    public int maxKilledEnemies(char[][] A) {
+        if (A == null || A.length == 0 || A[0].length == 0) {
+            return 0;
+        }
+        
+        int m = A.length;
+        int n = A[0].length;
+        int[][] up = new int[m][n];
+        int[][] down = new int[m][n];
+        int[][] left = new int[m][n];
+        int[][] right = new int[m][n];
+        int i, j, t;
+        
+        for (i = 0; i < m; ++i) {
+            for (j = 0; j < n; ++j) {
+                up[i][j] = 0;
+                if (A[i][j] != 'W') {
+                    if (A[i][j] == 'E') {
+                        up[i][j] = 1;
+                    }
+                    
+                    if (i - 1 >= 0) {
+                        up[i][j] += up[i-1][j];
+                    }
+                }
+            }
+        }
+        
+        for (i = m - 1; i >= 0; --i) {
+            for (j = 0; j < n; ++j) {
+                down[i][j] = 0;
+                if (A[i][j] != 'W') {
+                    if (A[i][j] == 'E') {
+                        down[i][j] = 1;
+                    }
+                    
+                    if (i + 1 < m) {
+                        down[i][j] += down[i+1][j];
+                    }
+                }
+            }
+        }
+        
+        for (i = 0; i < m; ++i) {
+            for (j = 0; j < n; ++j) {
+                left[i][j] = 0;
+                if (A[i][j] != 'W') {
+                    if (A[i][j] == 'E') {
+                        left[i][j] = 1;
+                    }
+                    
+                    if (j - 1 >= 0) {
+                        left[i][j] += left[i][j-1];
+                    }
+                }
+            }
+        }
+        
+        for (i = 0; i < m; ++i) {
+            for (j = n - 1; j >= 0; --j) {
+                right[i][j] = 0;
+                if (A[i][j] != 'W') {
+                    if (A[i][j] == 'E') {
+                        right[i][j] = 1;
+                    }
+                    
+                    if (j + 1 < n) {
+                        right[i][j] += right[i][j+1];
+                    }
+                }
+            }
+        }
+        
+        int res = 0;
+        for (i = 0; i < m; ++i) {
+            for (j = 0; j < n; ++j) {
+                if (A[i][j] == '0') {
+                    t = up[i][j] + down[i][j] + left[i][j] + right[i][j];
+                    if (t > res) {
+                        res = t;
+                    }
+                }
+            }
+        }
+        
+        return res;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/burst-ballons.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/burst-ballons.md"
new file mode 100644
index 0000000..713e4b5
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/burst-ballons.md"
@@ -0,0 +1,39 @@
+# 吹气球
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/burst-ballons/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有n个气球，编号为`0`到`n-1`，每个气球都有一个分数，存在`nums`数组中。每次吹气球i可以得到的分数为 `nums[left] * nums[i] * nums[right]`，left和right分别表示`i`气球相邻的两个气球。当i气球被吹爆后，其左右两气球即为相邻。要求吹爆所有气球，得到最多的分数。
+ ### 样例说明
+ 
+ ### 参考代码
+ 区间动态规划
+```python
+class Solution:
+    """
+    @param nums: A list of integer
+    @return: An integer, maximum coins
+    """
+    def maxCoins(self, nums):
+        if not nums:
+            return 0
+
+        # [4,1,5] => [1,4,1,5,1]
+        nums = [1, *nums, 1]
+        return self.memo_search(nums, 0, len(nums) - 1, {})
+        
+    def memo_search(self, nums, i, j, memo):
+        if i == j:
+            return 0 
+            
+        if (i, j) in memo:
+            return memo[(i, j)]
+        
+        best = 0
+        for k in range(i + 1, j):
+            left = self.memo_search(nums, i, k, memo)
+            right = self.memo_search(nums, k, j, memo)
+            best = max(best, left + right + nums[i] * nums[k] * nums[j])
+        
+        memo[(i, j)] = best
+        return best
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/burst-balloons.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/burst-balloons.md"
new file mode 100644
index 0000000..4cbeb93
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/burst-balloons.md"
@@ -0,0 +1,63 @@
+# 吹气球
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/burst-balloons/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有n个气球，编号为`0`到`n-1`，每个气球都有一个分数，存在`nums`数组中。每次吹气球i可以得到的分数为 `nums[left] * nums[i] * nums[right]`，left和right分别表示`i`气球相邻的两个气球。当i气球被吹爆后，其左右两气球即为相邻。要求吹爆所有气球，得到最多的分数。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[4, 1, 5, 10]
+输出：270
+解释：
+nums = [4, 1, 5, 10] 吹爆 1, 得分 4 * 1 * 5 = 20
+nums = [4, 5, 10]   吹爆 5, 得分 4 * 5 * 10 = 200 
+nums = [4, 10]   吹爆 4, 得分 1 * 4 * 10 = 40
+nums = [10]   吹爆 10, 得分 1 * 10 * 1 = 10
+总得分 20 + 200 + 40 + 10 = 270
+```
+
+**样例 2:**
+```
+输入：[3,1,5]
+输出：35
+解释：
+nums = [3, 1, 5] 吹爆 1, 得分 3 * 1 * 5 = 15
+nums = [3, 5] 吹爆 3, 得分 1 * 3 * 5 = 15
+nums = [5] 吹爆 5, 得分 1 * 5 * 1 = 5
+总得分 15 + 15 + 5  = 35
+```
+
+ ### 参考代码
+ 使用记忆化搜索的方法。
+memo[i][j] 表示 burst i+1~j-1 这些气球，留下i,j后的最大收益。
+nums 数组需要前后都添加一个1.
+```python
+class Solution:
+    """
+    @param nums: A list of integer
+    @return: An integer, maximum coins
+    """
+    def maxCoins(self, nums):
+        if not nums:
+            return 0
+
+        # [4,1,5] => [1,4,1,5,1]
+        nums = [1, *nums, 1]
+        return self.memo_search(nums, 0, len(nums) - 1, {})
+        
+    def memo_search(self, nums, i, j, memo):
+        if i == j:
+            return 0 
+            
+        if (i, j) in memo:
+            return memo[(i, j)]
+        
+        best = 0
+        for k in range(i + 1, j):
+            left = self.memo_search(nums, i, k, memo)
+            right = self.memo_search(nums, k, j, memo)
+            best = max(best, left + right + nums[i] * nums[k] * nums[j])
+        
+        memo[(i, j)] = best
+        return best
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/calculation-the-sum-of-path.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/calculation-the-sum-of-path.md"
new file mode 100644
index 0000000..8aabc44
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/calculation-the-sum-of-path.md"
@@ -0,0 +1,161 @@
+# 路径数计算
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/calculation-the-sum-of-path/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 输入一个矩阵的长度为 `l`，宽度为 `w`，和三个必经点，问有多少种方法可以从左上角走到右下角（每一步，只能向右或者向下走），输入保证合法，有解。答案对 `1000000007` 取模。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```
+[[python]]
+MOD = 10 ** 9 + 7
+
+"""
+Definition for a point.
+class Point:
+    def __init__(self, a=0, b=0):
+        self.x = a
+        self.y = b
+"""
+
+class Solution:
+    """
+    @param l: The length of the matrix
+    @param w: The width of the matrix
+    @param points: three points 
+    @return: The sum of the paths sum
+    """
+    def calculationTheSumOfPath(self, l, w, points):
+        # preprocessing
+        n, m, pairs = self.preprocessing(l, w, points)
+
+        # state: dp[i][j] 代表从 0,0 走到 i,j 的方案总数
+        dp = [[0] * m for _ in range(n)]
+        
+        # initialization: 第一行第一列方案数为1
+        for i in range(n): 
+            dp[i][0] = 1
+        for i in range(m): 
+            dp[0][i] = 1
+        
+        # function: dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
+        for i in range(1, n):
+            for j in range(1, m):
+                dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % MOD
+        
+        # answer: sort points and multiply nubmer of paths together
+        answer = 1
+        for delta_x, delta_y in pairs:
+            answer = (answer * dp[delta_x][delta_y]) % MOD
+        return answer
+        
+    def preprocessing(self, l, w, original_points):
+        points = [(p.x, p.y) for p in original_points]
+        points.append((l, w))
+        points.sort()
+        
+        prev_x, prev_y = 1, 1
+        n, m = 0, 0
+        pairs = []
+        for x, y in points:
+            pair = (x - prev_x, y - prev_y)
+            pairs.append(pair)
+            n = max(n, pair[0] + 1)
+            m = max(m, pair[1] + 1)
+            prev_x, prev_y = x, y
+        
+        return n, m, pairs
+[[java]]
+/**
+ * Definition for a point.
+ * class Point {
+ *     int x;
+ *     int y;
+ *     Point() { x = 0; y = 0; }
+ *     Point(int a, int b) { x = a; y = b; }
+ * }
+ */
+
+class ResultType {
+    int n, m;
+    List<Point> pairs;
+    public ResultType(int n, int m, List<Point> pairs) {
+        this.n = n;
+        this.m = m;
+        this.pairs = pairs;
+    }
+}
+
+public class Solution {
+    /**
+     * @param l: The length of the matrix
+     * @param w: The width of the matrix
+     * @param points: three points 
+     * @return: The sum of the paths sum
+     */
+    private int MOD = 1000000007;
+    
+    public long calculationTheSumOfPath(int l, int w, Point[] points) {
+        // preprocessing
+        ResultType result = preprocessing(l, w, points);
+        int n = result.n, m = result.m;
+        List<Point> pairs = result.pairs;
+        
+        // state: dp[i][j] 代表从 0,0 走到 i,j 的方案总数
+        int[][] dp = new int[n][m];
+        
+        // initialization: 第一行第一列方案数为1
+        for (int i = 0; i < n; i++) {
+            dp[i][0] = 1;
+        }
+        for (int i = 0; i < m; i++) {
+            dp[0][i] = 1;
+        }
+        
+        // function: dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
+        for (int i = 1; i < n; i++) {
+            for (int j = 1; j < m; j++) {
+                dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % MOD;
+            }
+        }
+            
+        // answer: sort points and multiply nubmer of paths together
+        int answer = 1;
+        for (Point delta: pairs) {
+            answer = (int)((1L * answer * dp[delta.x][delta.y]) % MOD);
+        }
+        
+        return answer;
+    }
+    
+    private ResultType preprocessing(int l, int w, Point[] originalPoints) {
+        List<Point> points = new ArrayList<>();
+        for (int i = 0; i < originalPoints.length; i++) {
+            points.add(new Point(originalPoints[i].x, originalPoints[i].y));
+        }
+        points.add(new Point(l, w));
+        Collections.sort(points, new Comparator<Point>(){
+            public int compare(Point p1, Point p2) {
+                if (p1.x != p2.x) {
+                    return p1.x - p2.x;
+                }
+                return p1.y - p2.y;
+            }
+        });
+        
+        int prevX = 1, prevY = 1;
+        int n = 0, m = 0;
+        List<Point> pairs = new ArrayList<>();
+        for (Point p: points) {
+            Point pair = new Point(p.x - prevX, p.y - prevY);
+            pairs.add(pair);
+            n = Math.max(n, pair.x + 1);
+            m = Math.max(m, pair.y + 1);
+            prevX = p.x;
+            prevY = p.y;
+        }
+        
+        return new ResultType(n, m, pairs);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/can-i-win.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/can-i-win.md"
new file mode 100644
index 0000000..432c492
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/can-i-win.md"
@@ -0,0 +1,99 @@
+# 我能赢吗
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/can-i-win/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在 "100 game" 中, 两位玩家交替使用 1 到 10 的任意一个整数加到一个和中, 谁加完之后, 和达到或者超过了 100 就获胜.
+
+如果我们改变规则, 玩家不能重复使用已经使用过的整数呢？
+
+举个例子, 两个玩家可以轮流从一个共同的数字池 (里面的整数为 1 到 15) 中拿出整数, 拿出之后不放回, 直到某个玩家拿出一个数字之后, 已经拿出的数字之和达到或者超过了 100, 该玩家获胜.
+
+给定两个整数 `maxChoosableInteger` 和 `desiredTotal`, 表示刚开始数字池中有 `1, 2, 3, ..., maxChoosableInteger` 这些数字, 获胜的目标和是 `desiredTotal`. 
+
+判断先手玩家是否必胜, 假设两个玩家都用了最佳策略.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: maxChoosableInteger = 10, desiredTotal = 11
+输出: false
+解释: 
+    无论第一个玩家怎么选都会输. 
+    如果他没选 10, 那么第二个玩家选择 10 就可以取得胜利.
+    如果他选了 10, 那么第二个玩家可以选择任意一个数取得胜利.
+```
+
+**样例 2:**
+
+```
+输入: maxChoosableInteger = 10, desiredTotal = 10
+输出: true
+解释: 第一个玩家直接选择 10 就可以取得胜利.
+```
+ ### 参考代码
+ 这是一道状态压缩动态规划问题. (你也可以不压缩, 使用哈希表, 可能会 MLE 或 TLE)
+
+设定 dp[S] 表示还剩下集合S里的数字时, 先手的人是否有必胜策略.
+
+状态转移很容易想出来: 如果集合 S 中存在一个数 i, 使得拿走 i 之后剩下的集合 T 是必败的, 那么集合 S 就是必胜的状态.
+
+边界状态: 对于集合 S, 我们可以知道已经拿出去的数的和, 如果这个和加上集合 S 中最大的元素会达到或超过 desiredTotal, 那么 S 就是必胜的.
+
+推荐使用记忆化搜索来实现.
+
+状态压缩: 用一个整型表示集合S, 即这个整型的第 i 个二进制位为 1 表示集合 S 含有 i.
+```java
+public class Solution {
+    int[] dp;
+    boolean[] used;
+    public boolean canIWin(int maxChoosableInteger, int desiredTotal) {
+        int sum = (1 + maxChoosableInteger) * maxChoosableInteger / 2;
+        if (sum < desiredTotal) {       //取完所有数，也达不到desiredTotal，无法赢得游戏
+            return false;
+        }
+        if (desiredTotal <= maxChoosableInteger) {     //第一步就可以获得胜利
+            return true;
+        }
+        dp = new int[1 << maxChoosableInteger];
+        Arrays.fill(dp , -1);
+        used = new boolean[maxChoosableInteger + 1];
+
+        return helper(desiredTotal);
+    }
+
+    public boolean helper(int desiredTotal) {
+        if (desiredTotal <= 0) {
+            return false;
+        }
+        int key = format(used);         //把used数组转为十进制表示
+        if (dp[key] == -1) {
+            for (int i = 1; i < used.length; i++) {  //枚举未选择的数
+                if (!used[i]) {
+                    used[i] = true;
+
+                    if (!helper(desiredTotal - i)) {
+                        dp[key] = 1;
+                        used[i] = false;
+                        return true;
+                    }
+                    used[i] = false;
+                }
+            }
+            dp[key] = 0;
+        }
+        return dp[key] == 1;
+    }
+
+
+    public int format(boolean[] used) {
+        int num = 0;
+        for (boolean b : used) {
+            num <<= 1;
+            if (b) {
+                num |= 1;
+            }
+        }
+        return num;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/card-game.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/card-game.md"
new file mode 100644
index 0000000..0774e71
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/card-game.md"
@@ -0,0 +1,62 @@
+# 卡牌游戏
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/card-game/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 现在有一个卡牌游戏，先给出卡牌的数量`n`，再给你两个非负整数`totalProfit`、`totalCost`，然后给出每张卡牌的利润值 `a[i]`和成本值`b[i]`，现在可以从这些卡牌中任意选择若干张牌，组成一个方案，问有多少个方案满足所有选择的卡牌利润和大于`totalProfit`且成本和小于`totalCost`。
+ ### 样例说明
+ **样例 1:**
+```
+输入：n = 2，totalProfit = 3，totalCost = 5，a = [2,3]，b = [2,2] 
+输出：1
+解释：
+此时只有一个合法的方案，就是将两个卡牌都选上，此时a[1]+a[2] = 5 > totalProfit 且 b[1] + b[2] < totalCost，满足题意。
+```
+**样例 2:**
+```
+输入：n = 3，totalProfit = 5，totalCost = 10，a = [6,7,8]，b = [2,3,5]
+输出： 6
+解释：
+假设一个合法方案(i,j)表示选择了第i张卡牌和第j张卡牌。
+则此时合法的方案有：
+(1),(2),(3),(1,2),(1,3),(2,3)
+```
+
+ ### 参考代码
+ 使用记忆化搜索的方法
+时间复杂度 $O(n * totalProfit * totalCost)$
+```python
+BASE = 1000000007
+
+
+class Solution:
+    """
+    @param n: The number of cards
+    @param totalProfit: The totalProfit
+    @param totalCost: The totalCost
+    @param a: The profit of cards
+    @param b: The cost of cards
+    @return: Return the number of legal plan
+    """
+    def numOfPlan(self, n, totalProfit, totalCost, a, b):
+        return self.memo_search(0, n, totalProfit, totalCost, a, b, {})
+        
+    def memo_search(self, index, n, profit, cost, a, b, memo):
+        if profit < 0:
+            profit = -1
+        if cost < 0:
+            return 0
+            
+        if index == n:
+            if 0 > profit and 0 < cost:
+                return 1
+            return 0
+
+        if (index, profit, cost) in memo:
+            return memo[(index, profit, cost)]
+        
+        select = self.memo_search(index + 1, n, profit - a[index], cost - b[index], a, b, memo)
+        unselect = self.memo_search(index + 1, n, profit, cost, a, b, memo)
+        
+        memo[(index, profit, cost)] = (select + unselect) % BASE
+        return memo[(index, profit, cost)]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/climbing-stairs-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/climbing-stairs-ii.md"
new file mode 100644
index 0000000..cba4450
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/climbing-stairs-ii.md"
@@ -0,0 +1,31 @@
+# 爬楼梯 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/climbing-stairs-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 一个小孩爬一个 n 层台阶的楼梯。他可以每次跳 1 步， 2 步 或者 3 步。实现一个方法来统计总共有多少种不同的方式爬到最顶层的台阶。
+
+ ### 样例说明
+ 
+ ### 参考代码
+ 本题采用动态规划的思想，每一步的答案可以由上三步转移而来。
+初始状态和状态转移方程如下：
+$f_0=1,\ f_1 =1,\ f_2=2,f_n=f_{n-1}+f_{n-2}+f_{n-3}(n \geq 3)$
+```java
+public class Solution {
+    /**
+     * @param n an integer
+     * @return an integer
+     */
+    public int climbStairs2(int n) {
+        int[] f = new int[n+1];
+        f[0] = 1;
+        for (int i = 0; i <= n; i++) 
+            for (int j = 1; j <= 3; j++) {
+                if (i >= j) {
+                    f[i] += f[i-j];
+                }
+            }
+        return f[n];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/climbing-stairs.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/climbing-stairs.md"
new file mode 100644
index 0000000..35f1c06
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/climbing-stairs.md"
@@ -0,0 +1,68 @@
+# 爬楼梯
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/climbing-stairs/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>假设你正在爬楼梯，需要n步你才能到达顶部。但每次你只能爬一步或者两步，你能有多少种不同的方法爬到楼顶部？</p>
+ ### 样例说明
+ 
+ ### 参考代码
+ You are climbing a stair case. It takes n steps to reach to the top.
+
+Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
+
+考虑最后一步走1阶还是走2阶。
+方案数Dp[n] = 最后一步走1阶的方案数 + 最后一步走2阶的方案数。
+Dp[n] = Dp[n-1] + Dp[n-2].
+```java
+public class Solution {
+    public int climbStairs(int n) {
+        if (n <= 1) {
+            return n;
+        }
+        int last = 1, lastlast = 1;
+        int now = 0;
+        for (int i = 2; i <= n; i++) {
+            now = last + lastlast;
+            lastlast = last;
+            last = now;
+        }
+        return now;
+    }
+}
+
+// 记忆化搜索
+// 九章硅谷求职算法集训营版本
+public class Solution {
+    /**
+     * @param n: An integer
+     * @return: An integer
+     */
+    int[] result = null;
+
+    void f(int X) {
+         if (result[X] != -1) return;                                                 
+         if (X == 0 || X == 1) {
+            result[X] = 1;
+            return;
+         }
+         
+         f(X - 1);
+         f(X - 2);
+         result[X] = result[X - 1] + result[X - 2];
+    }
+
+    public int climbStairs(int n) {
+        if (n == 0) {
+            return 0;
+        }
+        
+        result  = new int[n + 1];
+        for (int i = 0; i <= n; ++i) {
+            result[i] = -1;
+        }
+        
+        f(n);
+        return result[n];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/coin-change.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/coin-change.md"
new file mode 100644
index 0000000..dabeb8c
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/coin-change.md"
@@ -0,0 +1,49 @@
+# 换硬币
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/coin-change/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出不同面额的硬币以及一个总金额. 写一个方法来计算给出的总金额可以换取的最少的硬币数量. 如果已有硬币的任意组合均无法与总金额面额相等, 那么返回 `-1`.
+ ### 样例说明
+ **样例1**
+```
+输入：
+[1, 2, 5]
+11
+输出： 3
+解释： 11 = 5 + 5 + 1
+```
+**样例2**
+```
+输入： 
+[2]
+3
+输出： -1
+```
+ ### 参考代码
+ 这是一个典型的完全背包问题。
+设dp[i][j]表示使用前i个硬币，总金额为j时需要的最少硬币数量。
+
+$dp[i][j]=max(dp[i-1][j],dp[i-1][j-k*coin[i]]+k) \quad (0\leq k*coin[i] \leq j)$
+```java
+public class Solution {
+    public int coinChange(int[] A, int M) {
+        int[] f = new int[M + 1];
+        int n = A.length;
+        
+        f[0] = 0;
+        int i, j;
+        for (i = 1; i <= M; ++i) {
+            f[i] = -1;
+            for (j = 0; j < n; ++j) {
+                if (i >= A[j] && f[i - A[j]] != -1) {
+                    if (f[i] == -1 || f[i - A[j]] + 1 < f[i]) {
+                        f[i] = f[i - A[j]] + 1;
+                    }
+                }
+            }
+        }
+        
+        return f[M];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/coins-in-a-line-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/coins-in-a-line-ii.md"
new file mode 100644
index 0000000..a0bc42d
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/coins-in-a-line-ii.md"
@@ -0,0 +1,57 @@
+# 硬币排成线 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/coins-in-a-line-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有 `n` 个不同价值的硬币排成一条线。两个参赛者轮流从 **左边** 依次拿走 1 或 2 个硬币，直到没有硬币为止。计算两个人分别拿到的硬币总价值，价值高的人获胜。
+
+请判定 **先手玩家** 必胜还是必败?
+
+若必胜, 返回 `true`, 否则返回 `false`.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [1, 2, 2]
+输出: true
+解释: 先手玩家直接拿走两颗硬币即可.
+```
+
+**样例 2:**
+
+```
+输入: [1, 2, 4]
+输出: false
+解释: 无论先手拿一个还是两个, 后手可以拿完, 然后总价值更高.
+```
+ ### 参考代码
+ 使用九章算法强化班和动态规划专题班中讲到的滚动数组。
+时间复杂度为 $O(n)$，额外空间复杂度为 $O(1)$
+```python
+class Solution:
+    """
+    @param values: a vector of integers
+    @return: a boolean which equals to true if the first player will win
+    """
+    def firstWillWin(self, values):
+        if not values:
+            return False
+            
+        if len(values) <= 2:
+            return True
+            
+        n = len(values)
+        
+        # dynamic programming
+        f = [0] * 3
+        prefix_sum = [0] * 3
+        f[(n - 1) % 3] = prefix_sum[(n - 1) % 3] = values[n - 1]
+
+        # traverse values in reverse order from n-1 to 0
+        for i in range(n - 2, -1, -1):
+            prefix_sum[i % 3] = prefix_sum[(i + 1) % 3] + values[i]
+            f[i % 3] = max(
+                values[i] + prefix_sum[(i + 1) % 3] - f[(i + 1) % 3],
+                values[i] + values[i + 1] + prefix_sum[(i + 2) % 3] - f[(i + 2) % 3],
+            )
+        return f[0] > prefix_sum[0] - f[0]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/coins-in-a-line-iii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/coins-in-a-line-iii.md"
new file mode 100644
index 0000000..1cb5af4
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/coins-in-a-line-iii.md"
@@ -0,0 +1,198 @@
+# 硬币排成线 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/coins-in-a-line-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有 `n` 个硬币排成一条线, 第 `i` 枚硬币的价值为 `values[i]`. 
+
+两个参赛者轮流从任意一边取一枚硬币, 直到没有硬币为止. 拿到硬币总价值更高的获胜.
+
+请判定 **第一个玩家** 会赢还是会输.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [3, 2, 2]
+输出: true
+解释: 第一个玩家在刚开始的时候拿走 3, 然后两个人分别拿到一枚 2.
+```
+
+**样例 2:**
+
+```
+输入: [1, 20, 4]
+输出: false
+解释: 无论第一个玩家在第一轮拿走 1 还是 4, 第二个玩家都可以拿到 20.
+```
+ ### 参考代码
+ 区间动态规划问题, 具体定义状态的方式有很多种, 但是大同小异, 时空复杂度都相似. 这里只介绍 version 1 的具体实现.
+
+设定 dp[i][j] 表示当前剩余硬币的区间为 [i, j] 时, 此时该拿硬币的人能获取的最大值. 
+
+注意, dp[i][j] 并没有包含角色信息, dp[0][values.length - 1] 表示的是先手的人能获得的最大值, 而 dp[1][values.length -1] 表示的则是后手的人能获得的最大值. 需要这样做是因为: 两个人都会采用最优策略.
+
+当前的人的决策就是拿左边还是拿右边, 而下一个人仍然会最优决策, 所以应该是最小值中取最大值:
+
+```C++
+dp[i][j] = max(	                                     // 取max表示当前的人选用最优策略		
+    min(dp[i + 2][j], dp[i + 1][j - 1]) + values[i], // 取min表示下一个人选用最优策略
+    min(dp[i][j - 2], dp[i + 1][j - 1]) + values[j]
+)
+```
+
+几个边界:
+
+```
+i > j : dp[i][j] = 0
+i == j : dp[i][j] = values[i]
+i + 1 == j : dp[i][j] = max(values[i], values[j])
+```
+```java
+// version 1
+public class Solution {
+    /**
+     * @param values: an array of integers
+     * @return: a boolean which equals to true if the first player will win
+     */
+    public boolean firstWillWin(int[] values) {
+        // write your code here
+        int n = values.length;
+        int[][] dp = new int[n + 1][n + 1];
+        boolean[][] flag = new boolean[n + 1][n + 1];
+
+        int sum = 0;
+        for (int now : values)
+            sum += now;
+
+        return sum < 2 * MemorySearch(0, values.length - 1, dp, flag, values);
+    }
+
+    int MemorySearch(int left, int right, int[][] dp, boolean[][] flag, int[] values) {
+
+        if (flag[left][right])
+            return dp[left][right];
+        flag[left][right] = true;
+        if (left > right) {
+            dp[left][right] = 0;
+        } else if (left == right) {
+            dp[left][right] = values[left];
+        } else if (left + 1 == right) {
+            dp[left][right] = Math.max(values[left], values[right]);
+        } else {
+            int pick_left = Math.min(MemorySearch(left + 2, right, dp, flag, values),
+                    MemorySearch(left + 1, right - 1, dp, flag, values)) + values[left];
+            int pick_right = Math.min(MemorySearch(left, right - 2, dp, flag, values),
+                    MemorySearch(left + 1, right - 1, dp, flag, values)) + values[right];
+            dp[left][right] = Math.max(pick_left, pick_right);
+        }
+        return dp[left][right];
+    }
+}
+
+// version 2
+public class Solution {
+    /**
+     * @param values: an array of integers
+     * @return: a boolean which equals to true if the first player will win
+     */
+    public boolean firstWillWin(int[] values) {
+        int n = values.length;
+        int[][] dp = new int[n + 1][n + 1];
+        boolean[][] flag = new boolean[n + 1][n + 1];
+        int[][] sum = new int[n + 1][n + 1];
+        for (int i = 0; i < n; i++) {
+            for (int j = i; j < n; j++) {
+                sum[i][j] = i == j ? values[j] : sum[i][j - 1] + values[j];
+            }
+        }
+        int allsum = 0;
+        for (int now : values)
+            allsum += now;
+
+        return allsum < 2 * MemorySearch(0, values.length - 1, dp, flag, values, sum);
+    }
+
+    int MemorySearch(int left, int right, int[][] dp, boolean[][] flag, int[] values, int[][] sum) {
+        if (flag[left][right])
+            return dp[left][right];
+
+        flag[left][right] = true;
+        if (left > right) {
+            dp[left][right] = 0;
+        } else if (left == right) {
+            dp[left][right] = values[left];
+        } else if (left + 1 == right) {
+            dp[left][right] = Math.max(values[left], values[right]);
+        } else {
+            int cur = Math.min(MemorySearch(left + 1, right, dp, flag, values, sum),
+                    MemorySearch(left, right - 1, dp, flag, values, sum));
+            dp[left][right] = sum[left][right] - cur;
+        }
+        return dp[left][right];
+    }
+}
+
+// 九章动态规划专题班和算法强化班版本
+public class Solution {
+    /**
+     * @param values: an array of integers
+     * @return: a boolean which equals to true if the first player will win
+     */
+    public boolean firstWillWin(int[] A) {
+        // write your code here
+
+        int n = A.length;
+        if (n == 0) {
+            return true;
+        }
+
+        int[][] f = new int[n][n];
+        int i, j, len;
+        // len 1
+        for (i = 0; i < n; ++i) {
+            f[i][i] = A[i];
+        }
+
+        for (len = 2; len <= n; ++len) {
+            for (i = 0; i <= n - len; ++i) {
+                j = i + len - 1;
+                f[i][j] = Math.max(A[i] - f[i + 1][j], A[j] - f[i][j - 1]);
+            }
+        }
+
+        return f[0][n - 1] >= 0;
+    }
+}
+
+// Linpz verision
+public class Solution {
+    /**
+     * @param values: an array of integers
+     * @return: a boolean which equals to true if the first player will win
+     */
+    public boolean firstWillWin(int[] values) {
+        int n = values.length;
+        int[] sum = new int[n + 1];
+        sum[0] = 0;
+        for (int i = 1; i <= n; ++i)
+            sum[i] = sum[i - 1] + values[i - 1];
+
+        // s[i][j] = sum[j + 1] - sum[i];
+
+        int[][] dp = new int[n][n];
+        for (int i = 0; i < n; ++i)
+            dp[i][i] = values[i];
+
+        for (int len = 2; len <= n; ++len) {
+            for (int i = 0; i < n; ++i) {
+                int j = i + len - 1;
+                if (j >= n)
+                    continue;
+                int s = sum[j + 1] - sum[i];
+                dp[i][j] = Math.max(s - dp[i + 1][j], s - dp[i][j - 1]);
+            }
+        }
+
+        return dp[0][n - 1] > sum[n] / 2;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/coins-in-a-line.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/coins-in-a-line.md"
new file mode 100644
index 0000000..839740c
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/coins-in-a-line.md"
@@ -0,0 +1,44 @@
+# 硬币排成线
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/coins-in-a-line/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有 `n` 个硬币排成一条线。两个参赛者轮流从右边依次拿走 1 或 2 个硬币，直到没有硬币为止。拿到最后一枚硬币的人获胜。
+
+请判定 **先手玩家** 必胜还是必败?
+
+若必胜, 返回 `true`, 否则返回 `false`.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 1
+输出: true
+```
+
+**样例 2:**
+
+```
+输入: 4
+输出: true
+解释: 
+先手玩家第一轮拿走一个硬币, 此时还剩三个.
+这时无论后手玩家拿一个还是两个, 下一次先手玩家都可以把剩下的硬币拿完.
+```
+ ### 参考代码
+ 可以证明, 当硬币数目是3的倍数的时候, 先手玩家必败, 否则他必胜.
+
+当硬币数目是3的倍数时, 每一轮先手者拿a个, 后手者拿3-a个即可, 后手必胜.
+
+若不是3的倍数, 先手者可以拿1或2个, 此时剩余硬币个数就变成了3的倍数.
+```cpp
+class Solution {
+public:
+    /**
+     * @param n: An integer
+     * @return: A boolean which equals to true if the first player will win
+     */
+    bool firstWillWin(int n) {
+        return n % 3;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/copy-books-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/copy-books-ii.md"
new file mode 100644
index 0000000..bcffdf8
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/copy-books-ii.md"
@@ -0,0 +1,106 @@
+# 书籍复印 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/copy-books-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定 `n` 本书, 每本书具有相同的页数. 现在有 `k` 个人来复印这些书. 其中第 `i` 个人需要 `times[i]` 分钟来复印一本书. 每个人可以复印任意数量的书. 怎样分配这 `k` 个人的任务, 使得这 `n` 本书能够被尽快复印完?
+
+返回完成复印任务最少需要的分钟数.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: n = 4, times = [3, 2, 4]
+输出: 4
+解释: 第一个人复印 1 本书, 花费 3 分钟. 第二个人复印 2 本书, 花费 4 分钟. 第三个人复印 1 本书, 花费 4 分钟.
+```
+
+**样例 2:**
+
+```
+输入: n = 4, times = [3, 2, 4, 5]
+输出: 4
+解释: 使用与样例 1相同的策略, 第四个人不参与复印.
+```
+ ### 参考代码
+ 可以使用二分或者动态规划解决这道题目. 不过更推荐二分答案的写法, 它更节省空间, 思路简洁, 容易编码.
+
+对于假定的时间上限 `tm` 我们可以使用贪心的思想判断这 `k` 个人能否完成复印 `n` 本书的任务: 每个人都在规定时间内尽可能多地复印, 判断他们复印的总数是否不小于 `n` 即可.
+
+而时间上限 `tm` 与可否完成任务(0或1)这两个量之间具有单调性关系, 所以可以对 `tm` 进行二分查找, 查找最小的 `tm`, 使得任务可以完成.
+```python
+class Solution:
+    """
+    @param n: An integer
+    @param times: an array of integers
+    @return: an integer
+    """
+    def copyBooksII(self, n, times):
+        l = 1 
+        r = min(times) * n 
+        while l < r:
+            mid = (l + r) // 2
+            if self.ok(n, times, mid):
+                r = mid 
+            else:
+                l = mid + 1 
+        return l 
+    
+    def ok(self, n, times, tm):
+        num = 0
+        for i in times:
+            num += tm // i
+        return n <= num
+
+class Solution:
+    # @param n: an integer
+    # @param times: a list of integers
+    # @return: an integer
+    def copyBooksII(self, n, times):
+        # write your code here
+        k = len(times)
+        ans = 0
+        eachTime = []
+        totalTime = []
+        for i in range(k):
+            self.heapAdd(eachTime, totalTime, times[i], 0)
+        for i in range(n):
+            ans = totalTime[0]
+            x = eachTime[0]
+            self.heapDelete(eachTime, totalTime)
+            self.heapAdd(eachTime, totalTime, x, ans+x)
+        ans = 0
+        for i in range(len(totalTime)):
+            ans = max(ans, totalTime[i])
+        return ans
+
+    def heapAdd(self, eachTime, totalTime, et, tt):
+        eachTime.append(et)
+        totalTime.append(tt)
+        n = len(eachTime)-1
+        while n > 0 and eachTime[n]+totalTime[n] < eachTime[(n-1)//2]+totalTime[(n-1)//2]:
+            eachTime[n], eachTime[(n-1)//2] = eachTime[(n-1)//2], eachTime[n]
+            totalTime[n], totalTime[(
+                n-1)//2] = totalTime[(n-1)//2], totalTime[n]
+            n = (n-1)//2
+
+    def heapDelete(self, eachTime, totalTime):
+        n = len(eachTime)-1
+        if n >= 0:
+            eachTime[0] = eachTime[n]
+        if n >= 0:
+            totalTime[0] = totalTime[n]
+        if len(eachTime) > 0:
+            eachTime.pop()
+        if len(totalTime) > 0:
+            totalTime.pop()
+        n = 0
+        while n*2+1 < len(eachTime):
+            t = n*2+1
+            if t+1 < len(eachTime) and eachTime[t+1]+totalTime[t+1] < eachTime[t]+totalTime[t]:
+                t += 1
+            if eachTime[n]+totalTime[n] <= eachTime[t]+totalTime[t]:
+                break
+            eachTime[n], eachTime[t] = eachTime[t], eachTime[n]
+            totalTime[n], totalTime[t] = totalTime[t], totalTime[n]
+            n = t
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/copy-books.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/copy-books.md"
new file mode 100644
index 0000000..9053192
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/copy-books.md"
@@ -0,0 +1,66 @@
+# 书籍复印
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/copy-books/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定 `n` 本书, 第 `i` 本书的页数为 `pages[i]`. 现在有 `k` 个人来复印这些书籍, 而每个人只能复印编号连续的一段的书, 比如一个人可以复印 `pages[0], pages[1], pages[2]`, 但是不可以只复印 `pages[0], pages[2], pages[3]` 而不复印 `pages[1]`.
+
+所有人复印的速度是一样的, 复印一页需要花费一分钟, 并且所有人同时开始复印. 怎样分配这 `k` 个人的任务, 使得这 `n` 本书能够被尽快复印完?
+
+返回完成复印任务最少需要的分钟数.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: pages = [3, 2, 4], k = 2
+输出: 5
+解释: 第一个人复印前两本书, 耗时 5 分钟. 第二个人复印第三本书, 耗时 4 分钟.
+```
+
+**样例 2:**
+
+```
+输入: pages = [3, 2, 4], k = 3
+输出: 4
+解释: 三个人各复印一本书.
+```
+ ### 参考代码
+ 使用九章算法强化班中讲过的基于答案值域的二分法。
+答案的范围在 max(pages)~sum(pages) 之间，每次二分到一个时间 time_limit 的时候，用贪心法从左到右扫描一下 pages，看看需要多少个人来完成抄袭。
+如果这个值 <= k，那么意味着大家花的时间可能可以再少一些，如果 > k 则意味着人数不够，需要降低工作量。
+
+时间复杂度 $O(nlog(sum))$ 是该问题时间复杂度上的最优解法
+```python
+class Solution:
+    """
+    @param pages: an array of integers
+    @param k: An integer
+    @return: an integer
+    """
+    def copyBooks(self, pages, k):
+        if not pages:
+            return 0
+            
+        start, end = max(pages), sum(pages)
+        while start + 1 < end:
+            mid = (start + end) // 2
+            if self.get_least_people(pages, mid) <= k:
+                end = mid
+            else:
+                start = mid
+                
+        if self.get_least_people(pages, start) <= k:
+            return start
+            
+        return end
+        
+    def get_least_people(self, pages, time_limit):
+        count = 0
+        time_cost = 0 
+        for page in pages:
+            if time_cost + page > time_limit:
+                count += 1
+                time_cost = 0
+            time_cost += page
+            
+        return count + 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/copy-list-with-random-pointer.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/copy-list-with-random-pointer.md"
new file mode 100644
index 0000000..eed6917
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/copy-list-with-random-pointer.md"
@@ -0,0 +1,95 @@
+# 复制带随机指针的链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/copy-list-with-random-pointer/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个链表，每个节点包含一个额外增加的随机指针可以指向链表中的任何节点或空的节点。</p><p><span style="line-height: 1.42857143;">返回一个深拷贝的链表。&nbsp;</span></p>
+ ### 样例说明
+ 
+ ### 参考代码
+ A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
+
+Return a deep copy of the list.
+
+深拷贝要对每个点都新建一遍。ALL
+```java
+//HashMap version
+public class Solution {
+    public RandomListNode copyRandomList(RandomListNode head) {
+        if (head == null) {
+            return null;
+        }
+
+        HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
+        RandomListNode dummy = new RandomListNode(0);
+        RandomListNode pre = dummy, newNode;
+        while (head != null) {
+            if (map.containsKey(head)) {
+                newNode = map.get(head);
+            } else {
+                newNode = new RandomListNode(head.label);
+                map.put(head, newNode);
+            }
+            pre.next = newNode;
+
+            if (head.random != null) {
+                if (map.containsKey(head.random)) {
+                    newNode.random = map.get(head.random);
+                } else {
+                    newNode.random = new RandomListNode(head.random.label);
+                    map.put(head.random, newNode.random);
+                }
+            }
+
+            pre = newNode;
+            head = head.next;
+        }
+
+        return dummy.next;
+    }
+}
+
+/*第一遍扫的时候巧妙运用next指针， 开始数组是1->2->3->4  。 然后扫描过程中 先建立copy节点 1->1`->2->2`->3->3`->4->4`, 然后第二遍copy的时候去建立边的copy， 拆分节点, 一边扫描一边拆成两个链表，这里用到两个dummy node。第一个链表变回  1->2->3 , 然后第二变成 1`->2`->3`  */
+//No HashMap version
+public class Solution {
+    private void copyNext(RandomListNode head) {
+        while (head != null) {
+            RandomListNode newNode = new RandomListNode(head.label);
+            newNode.random = head.random;
+            newNode.next = head.next;
+            head.next = newNode;
+            head = head.next.next;
+        }
+    }
+
+    private void copyRandom(RandomListNode head) {
+        while (head != null) {
+            if (head.next.random != null) {
+                head.next.random = head.random.next;
+            }
+            head = head.next.next;
+        }
+    }
+
+    private RandomListNode splitList(RandomListNode head) {
+        RandomListNode newHead = head.next;
+        while (head != null) {
+            RandomListNode temp = head.next;
+            head.next = temp.next;
+            head = head.next;
+            if (temp.next != null) {
+                temp.next = temp.next.next;
+            }
+        }
+        return newHead;
+    }
+
+    public RandomListNode copyRandomList(RandomListNode head) {
+        if (head == null) {
+            return null;
+        }
+        copyNext(head);
+        copyRandom(head);
+        return splitList(head);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/count-numbers-with-unique-digits.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/count-numbers-with-unique-digits.md"
new file mode 100644
index 0000000..252de00
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/count-numbers-with-unique-digits.md"
@@ -0,0 +1,77 @@
+# 计算不同数字整数的个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/count-numbers-with-unique-digits/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定**非负**整数n，计算具有不同数字字符的所有整数，其中$0 \leq x \lt 10^n$。
+ ### 样例说明
+ **样例1**
+```
+输入： 2
+输出： 91
+解释：
+答案应该是0≤x<100范围内的总数，除去[11,22,33,44,55,66,77,88,99]
+```
+**样例2**
+```
+输入： 3
+输出： 739
+```
+ ### 参考代码
+ 对于dp的做法：
+设dp[i]表示i位数时满足题意的数的个数。
+对于第i位，为了使得第i位与前i-1位的数字不一致，我们可以选择数字应该有$10-(i-1)$个，因此转移方程为：$dp[i]=dp[i-1]*(11-i)$
+```java
+//  solution 1
+//DP Solution
+public class Solution {
+    /**
+     * @param n: a non-negative integer
+     * @return: number of numbers with unique digits
+     */
+    public int countNumbersWithUniqueDigits(int n) {
+        // Write your code here 
+        if (n == 0) return 1;
+    	//dp[i]表示i位数时UniqueDigits的数量
+        int[] dp = new int[n + 1];
+        dp[0] = 1;
+        dp[1] = 9;
+        
+        int sum = 10;
+        for (int i = 2; i <= n; i++) {
+            dp[i] = dp[i-1] * (11 - i);
+            //i = 2; dp[2] = dp[1] * 9 
+            /*
+            9表示，在一位数的基础上，添加一个数使他成为一个二位数
+            对于每一个一位数的UniqueDigit有9种添加的方法使之成为二位数的UniqueDigit
+            */
+            sum += dp[i];
+        }
+        return sum;
+    
+    }
+}
+
+// solution 2
+//Math Method
+public class Solution {
+    public int countNumbersWithUniqueDigits(int n) {
+        if (n == 0) {
+            return 1;
+        }
+        if (n > 10) {
+            n = 10;
+        }
+        int ans = 1;
+        int multiple = 9;
+        for (int i = n - 1; i >= 0; i--) {
+            if (i == 0) {
+                ans += multiple;
+            } else {
+                ans += (n - i + 1) * multiple;
+            }
+            multiple = multiple * (10 - n + i - 1);
+        }
+        return ans;
+    } 
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/count-square-submatrices-with-all-ones.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/count-square-submatrices-with-all-ones.md"
new file mode 100644
index 0000000..3ae76d8
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/count-square-submatrices-with-all-ones.md"
@@ -0,0 +1,99 @@
+# 统计全为 1 的正方形子矩阵
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/count-square-submatrices-with-all-ones/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个 m * n 的矩阵，矩阵中的元素不是 0 就是 1，请你统计并返回其中完全由 1 组成的 正方形 子矩阵的个数。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```
+[[python]]
+class Solution:
+    """
+    @param matrix: a matrix
+    @return: return how many square submatrices have all ones
+    """
+    def countSquares(self, matrix):
+        n, m = len(matrix), len(matrix[0])
+        
+        # state: dp[i][j] 表示以 i,j 作为右下角的全1正方形有多少个(最大是多少)
+        # state: left[i][j] 表示 i,j 往左连续的 1 最长多长
+        # state: up[i][j] 表示 i,j 往上连续的 1 最长多长
+        dp = [[0] * m for _ in range(n)]
+        left = [[0] * m for _ in range(n)]
+        up = [[0] * m for _ in range(n)]
+        
+        # initialization: 初始化第一行和第一列
+        for i in range(n):
+            dp[i][0] = left[i][0] = up[i][0] = matrix[i][0]
+        for j in range(m):
+            dp[0][j] = left[0][j] = up[0][j] = matrix[0][j]
+        
+        # function: 如果 matrix[i][j] == 0 那么 dp[i][j] = 0 否则
+        #   dp[i][j] = min(left[i][j - 1], up[i - 1][j], dp[i - 1][j - 1]) + 1
+        #   也可以写作
+        #   dp[i][j] = min(left[i][j], up[i][j], dp[i - 1][j - 1] + 1)
+        for i in range(1, n):
+            for j in range(1, m):
+                if matrix[i][j] == 0:
+                    continue
+                left[i][j] = left[i][j - 1] + 1
+                up[i][j] = up[i - 1][j] + 1
+                dp[i][j] = min(left[i][j - 1], up[i - 1][j], dp[i - 1][j - 1]) + 1
+        
+        # answer: 统计每个位置作为右下角的矩阵有多少个，加起来
+        answer = 0
+        for i in range(n):
+            answer += sum(dp[i])
+        return answer
+[[java]]
+public class Solution {
+    /**
+     * @param matrix: a matrix
+     * @return: return how many square submatrices have all ones
+     */
+    public int countSquares(int[][] matrix) {
+        int n = matrix.length, m = matrix[0].length;
+        
+        // state: dp[i][j] 表示以 i,j 作为右下角的全1正方形有多少个(最大是多少)
+        // state: left[i][j] 表示 i,j 往左连续的 1 最长多长
+        // state: up[i][j] 表示 i,j 往上连续的 1 最长多长
+        int[][] dp = new int[n][m];
+        int[][] left = new int[n][m];
+        int[][] up = new int[n][m];
+        
+        // initialization: 初始化第一行和第一列
+        for (int i = 0; i < n; i++) {
+            dp[i][0] = left[i][0] = up[i][0] = matrix[i][0];
+        }
+        for (int j = 0; j < m; j++) {
+            dp[0][j] = left[0][j] = up[0][j] = matrix[0][j];
+        }
+        
+        // function: 如果 matrix[i][j] == 0 那么 dp[i][j] = 0 否则
+        //   dp[i][j] = min(left[i][j - 1], up[i - 1][j], dp[i - 1][j - 1]) + 1
+        //   也可以写作
+        //   dp[i][j] = min(left[i][j], up[i][j], dp[i - 1][j - 1] + 1)
+        for (int i = 1; i < n; i++) {
+            for (int j = 1; j < m; j++) {
+                if (matrix[i][j] == 0) {
+                    continue;
+                }
+                left[i][j] = left[i][j - 1] + 1;
+                up[i][j] = up[i - 1][j] + 1;
+                dp[i][j] = Math.min(Math.min(left[i][j - 1], up[i - 1][j]), dp[i - 1][j - 1]) + 1;
+            }
+        }
+                
+        // answer: 统计每个位置作为右下角的矩阵有多少个，加起来
+        int answer = 0;
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < m; j++) {
+                answer += dp[i][j];
+            }
+        }
+        
+        return answer;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/create-maximum-number.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/create-maximum-number.md"
new file mode 100644
index 0000000..f332391
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/create-maximum-number.md"
@@ -0,0 +1,66 @@
+# 创建最大数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/create-maximum-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出两个长度分别是`m`和`n`的数组来表示两个大整数，数组的每个元素都是数字`0-9`。从这两个数组当中选出`k`个数字来创建一个最大数，其中`k`满足`k <= m + n`。选出来的数字在创建的最大数里面的位置必须和在原数组内的相对位置一致。返回`k`个数的数组。你应该尽可能的去优化算法的时间复杂度和空间复杂度。
+ ### 样例说明
+ **样例 1:**
+```
+输入：nums1 = [3, 4, 6, 5]， nums2 = [9, 1, 2, 5, 8, 3]，k = 5
+输出：[9, 8, 6, 5, 3]
+解释：
+从第一个数组选择[6, 5]，从第二个数组选择[9, 8, 3]
+```
+**样例 2:**
+```
+输入：nums1 = [6, 7]， nums2 = [6, 0, 4]，k = 5
+输出：[6, 7, 6, 0, 4]
+解释：
+从第一个数组选择[6, 7]，从第二个数组选择[6, 0, 4]
+```
+
+**样例 3:**
+```
+输入：nums1 = [3, 9]， nums2 = [8, 9]，k = 3
+输出：[9, 8, 9]
+解释：
+从第一个数组选择[9]，从第二个数组选择[8, 9]
+```
+
+
+ ### 参考代码
+ 考点：
+* 贪心
+
+题解：
+* 首先取k个数字，分别从两个部分取，所以枚举从两个部分取出数字的数量。
+* 当前数组要取k个数时，贪心的每次将数组前面的数字和尾部比较，尾部较小时，删去即可，直至尾部大于当前时插入。
+* 当两个数组分别选择完毕后，再进入选择，每次比较两数组的大小，取大的数组数组的头部，最后返回列表，然后结束后和当前答案比较更新。
+```python
+class Solution:
+    # @param {int[]} nums1 an integer array of length m with digits 0-9
+    # @param {int[]} nums2 an integer array of length n with digits 0-9
+    # @param {int} k an integer and k <= m + n
+    # @return {int[]} an integer array
+    def maxNumber(self, nums1, nums2, k):
+        # Write your code here
+        len1, len2 = len(nums1), len(nums2)
+        res = []
+        for x in range(max(0, k - len2), min(k, len1) + 1):
+            tmp = self.merge(self.getMax(nums1, x), self.getMax(nums2, k - x))
+            res = max(tmp, res)
+        return res
+
+    def getMax(self, nums, t):
+        ans = []
+        size = len(nums)
+        for x in range(size):
+            while ans and len(ans) + size - x > t and ans[-1] < nums[x]:
+                ans.pop()
+            if len(ans) < t:
+                ans.append(nums[x])
+        return ans
+
+    def merge(self, nums1, nums2):
+        return [max(nums1, nums2).pop(0) for _ in nums1 + nums2]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/decode-ways-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/decode-ways-ii.md"
new file mode 100644
index 0000000..0b8ea67
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/decode-ways-ii.md"
@@ -0,0 +1,70 @@
+# 解码方式 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/decode-ways-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 使用以下映射方式将 A-Z 的消息编码为数字:
+```
+'A' -> 1
+'B' -> 2
+...
+'Z' -> 26
+```
+除此之外, 编码的字符串也可以包含字符 `*`, 它代表了 1 到 9 的数字中的其中一个.给出包含数字和字符 `*` 的编码消息, 返回所有解码方式的数量. 因为结果可能很大, 所以结果需要对 10^9 + 7 取模
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: "*"
+输出: 9
+说明: 你可以译码为 "A", "B", "C", "D", "E", "F", "G", "H", "I".
+```
+
+**样例2**
+
+```plain
+输入: "1*"
+输出: 18
+```
+
+
+ ### 参考代码
+ ```python
+class Solution(object):
+    def numDecodings(self, s):
+        """
+        :type s: str
+        :rtype: int
+        """
+        if s == None:
+            return 0
+        mod = 1000000007
+        n = len(s)
+        f = [0] * (n + 1)
+        f[0] = 1
+        for i in xrange(1, n + 1):
+            if s[i - 1] == '*':
+                f[i] = (f[i] + 9 * f[i - 1]) % mod
+                if i >= 2:
+                    t = 0
+                    if s[i - 2] == '*':
+                        f[i] = (f[i] + 15 * f[i - 2]) % mod
+                    elif s[i - 2] == '1':
+                        f[i] = (f[i] + 9 * f[i - 2]) % mod
+                    elif s[i - 2] == '2':
+                        f[i] = (f[i] + 6 * f[i - 2]) % mod
+            else:
+                if s[i - 1] >= '1' and s[i - 1] <= '9':
+                    f[i] = (f[i] + f[i - 1]) % mod
+                if i >= 2:
+                    if s[i - 2] == '*':
+                        t = 0
+                        if s[i - 1] >= '0' and s[i - 1] <= '6':
+                            f[i] = (f[i] + 2 * f[i - 2]) % mod
+                        elif s[i - 1] >= '7' and s[i - 1] <= '9':
+                            f[i] = (f[i] + f[i - 2]) % mod
+                    else:
+                        twoDigits = int(s[i - 2 : i])
+                        if twoDigits >= 10 and twoDigits <= 26:
+                            f[i] = (f[i] + f[i - 2]) % mod
+        return f[n]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/decode-ways.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/decode-ways.md"
new file mode 100644
index 0000000..8a78db1
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/decode-ways.md"
@@ -0,0 +1,67 @@
+# 解码方法
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/decode-ways/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有一个消息包含`A-Z`通过以下规则编码
+```
+'A' -> 1
+'B' -> 2
+...
+'Z' -> 26
+```
+现在给你一个加密过后的消息，问有几种解码的方式
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "12"
+输出: 2
+解释: 它可以被解码为 AB (1 2) 或 L (12).
+```
+
+**样例 2:**
+
+```
+输入: "10"
+输出: 1
+```
+ ### 参考代码
+ 动态规划.
+
+设定状态: f[i] 表示字符串前i位有多少种解码方案
+
+状态转移方程:
+
+```
+初始化 f 数组为 0
+若字符串中 s[i] 表示的阿拉伯数字在 1~9 范围内, f[i] += f[i-1]
+若s[i-1]和s[i]连起来表示的数字在 10~26 范围内, f[i] += f[i-2] (若i==1, 则f[i] += 1)
+```
+
+边界: f[0] = 1
+
+特判: 
+
+1. 如果字符串以 `'0'` 开头, 则直接返回0.
+2. 如果运算中发现 f[i] == 0, 则说明此处无法解码, 同样直接返回0.
+```python
+class Solution:
+    # @param {string} s a string,  encoded message
+    # @return {int} an integer, the number of ways decoding
+    def numDecodings(self, s):
+        if s == "" or s[0] == '0':
+            return 0
+
+        dp = [1, 1]
+        for i in range(2,len(s) + 1):
+            if 10 <= int(s[i - 2 : i]) <=26 and s[i - 1] != '0':
+                dp.append(dp[i - 1] + dp[i - 2])
+            elif int(s[i-2 : i]) == 10 or int(s[i - 2 : i]) == 20:
+                dp.append(dp[i - 2])
+            elif s[i-1] != '0':
+                dp.append(dp[i-1])
+            else:
+                return 0
+
+        return dp[len(s)]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/dices-sum.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/dices-sum.md"
new file mode 100644
index 0000000..c998038
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/dices-sum.md"
@@ -0,0 +1,47 @@
+# 骰子求和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/dices-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 扔 *n* 个骰子，向上面的数字之和为 *S*。给定 *n*，请列出所有可能的 *S* 值及其相应的概率。
+ ### 样例说明
+ **样例 1：**
+
+```
+输入：n = 1
+输出：[[1, 0.17], [2, 0.17], [3, 0.17], [4, 0.17], [5, 0.17], [6, 0.17]]
+解释：掷一次骰子，向上的数字和可能为1,2,3,4,5,6，出现的概率均为 0.17。
+```
+
+**样例 2：**
+
+```
+输入：n = 2
+输出：[[2,0.03],[3,0.06],[4,0.08],[5,0.11],[6,0.14],[7,0.17],[8,0.14],[9,0.11],[10,0.08],[11,0.06],[12,0.03]]
+解释：掷两次骰子，向上的数字和可能在[2,12]，出现的概率是不同的。
+```
+
+ ### 参考代码
+ ```python
+class Solution:
+    # @param {int} n an integer
+    # @return {tuple[]} a list of tuple(sum, probability)
+    def dicesSum(self, n):
+        # Write your code here
+        results = []
+        f = [[0 for j in xrange(6 * n + 1)] for i in xrange(n + 1)]
+        
+        for i in xrange(1, 7):
+            f[1][i] = 1.0 / 6.0
+        for i in xrange(2, n + 1):
+            for j in xrange(i, 6 * n + 1):
+                for k in xrange(1, 7):
+                    if j > k:
+                        f[i][j] += f[i - 1][j - k]
+                f[i][j] /= 6.0
+
+        for i in xrange(n, 6 * n + 1):
+            results.append((i, f[n][i]))
+
+        return results
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/distinct-subsequences-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/distinct-subsequences-ii.md"
new file mode 100644
index 0000000..00ae3ac
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/distinct-subsequences-ii.md"
@@ -0,0 +1,103 @@
+# 不同的子序列 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/distinct-subsequences-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串 `S`，计算 `S` 的不同非空子序列的个数。
+
+因为结果可能很大，所以返回答案模 `10^9 + 7`.
+ ### 样例说明
+ **示例 1:**
+```
+输入: "abc"
+输出: 7
+解释: 7 个不同的子序列分别是 "a", "b", "c", "ab", "ac", "bc", 以及 "abc"。
+```
+**示例 2:**
+```
+输入: "aba"
+输出: 6
+解释: 6 个不同的子序列分别是 "a", "b", "ab", "ba", "aa" 以及 "aba"。
+```
+**示例 3:**
+```
+输入: "aaa"
+输出: 3
+解释: 3 个不同的子序列分别是 "a", "aa" 以及 "aaa"。
+```
+ ### 参考代码
+ ```
+[[python]]
+MOD = 10 ** 9 + 7
+
+
+class Solution:
+    """
+    @param S: The string s
+    @return: The number of distinct, non-empty subsequences of S.
+    """
+    def distinctSubseqII(self, S):
+        n = len(S)
+        
+        # state: dp[i] 表示以下标 i 作为 subseq 的最后一个字符
+        # 的方案总数
+        dp = [0] * n
+        
+        # initialization: 如果 i 是第一个出现 S[i] 这个字符的位置，那么 dp[i] = 1
+        visited = set()
+        for i in range(n):
+            if S[i] not in visited:
+                dp[i] = 1
+            visited.add(S[i])
+        
+        # function: dp[i] = sigma{dp[j]}, j 到 i - 1 之间没有 S[i]
+        for i in range(n):
+            for j in range(i - 1, -1, -1):
+                dp[i] = (dp[i] + dp[j]) % MOD
+                if S[i] == S[j]:
+                    break
+        
+        # answer: 以所有位置结尾的方案总数之和
+        return sum(dp) %  MOD
+[[java]]
+public class Solution {
+    /**
+     * @param S: The string s
+     * @return: The number of distinct, non-empty subsequences of S.
+     */
+    private int MOD = 1000000007; 
+     
+    public int distinctSubseqII(String S) {
+        int n = S.length();
+        
+        // state: dp[i] 表示以下标 i 作为 subseq 的最后一个字符
+        // 的方案总数
+        int[] dp = new int[n];
+        
+        // initialization: 如果 i 是第一个出现 S.charAt(i) 这个字符的位置，那么 dp[i] = 1
+        Set<Character> visited = new HashSet<>();
+        for (int i = 0; i < n; i++) {
+            if (!visited.contains(S.charAt(i))) {
+                dp[i] = 1;
+            }
+            visited.add(S.charAt(i));
+        }
+        
+        // function: dp[i] = sigma{dp[j]}, j 到 i - 1 之间没有 S[i]
+        for (int i = 0; i < n; i++) {
+            for (int j = i - 1; j >= 0; j--) {
+                dp[i] = (dp[i] + dp[j]) % MOD;
+                if (S.charAt(i) == S.charAt(j)) {
+                    break;
+                }
+            }
+        }
+        
+        // answer: 以所有位置结尾的方案总数之和
+        int answer = 0;
+        for (int i = 0; i < dp.length; i++) {
+            answer = (answer + dp[i]) % MOD;
+        }
+        return answer;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/distinct-subsequences.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/distinct-subsequences.md"
new file mode 100644
index 0000000..effc075
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/distinct-subsequences.md"
@@ -0,0 +1,42 @@
+# 不同的子序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/distinct-subsequences/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定字符串 `S` 和 `T`, 计算 `S` 的所有子序列中有多少个 `T`.
+
+子序列字符串是原始字符串删除一些(或零个)字符之后得到的字符串, 并且要求剩下的字符的相对位置不能改变. (比如 `"ACE"` 是 `ABCDE` 的一个子序列, 而 `"AEC"` 不是)
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: S = "rabbbit", T = "rabbit"
+输出: 3
+解释: 你可以删除 S 中的任意一个 'b', 所以一共有 3 种方式得到 T.
+```
+
+**样例 2:**
+
+```
+输入: S = "abcd", T = ""
+输出: 1
+解释: 只有删除 S 中的所有字符这一种方式得到 T
+```
+ ### 参考代码
+ 多达5种解法与详细解释请参见九章微博：<http://weibo.com/3948019741/BDqR6hMdY>
+```python
+class Solution: 
+    # @param S, T: Two string.
+    # @return: Count the number of distinct subsequences
+    def numDistinct(self, S, T):
+        # write your code here
+        dp = [[0 for j in range(len(T) + 1)] for i in range(len(S) + 1)]
+        for i in range(len(S) + 1):
+   			dp[i][0] = 1
+        for i in xrange(len(S)):
+            for j in xrange(len(T)):
+                if S[i] == T[j]:
+                    dp[i+1][j+1] = dp[i][j+1] + dp[i][j]
+                else:
+                    dp[i+1][j+1] = dp[i][j + 1]
+        return dp[len(S)][len(T)]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/drop-eggs-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/drop-eggs-ii.md"
new file mode 100644
index 0000000..fd9ef1c
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/drop-eggs-ii.md"
@@ -0,0 +1,49 @@
+# 丢鸡蛋II
+
+
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/drop-eggs-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有一个`n`层的建筑。如果一个鸡蛋从第`k`层及以上落下，它会碎掉。如果从低于这一层的任意层落下，都不会碎。
+有`m`个鸡蛋，用最坏的情况下实验次数最少的方法去找到k, 返回最坏情况下所需的实验次数。
+ ### 样例说明
+ 
+ ### 参考代码
+ 动态规划。
+dp[i][j]代表从有i个鸡蛋在第j层需要的最少次数。
+转移方程为
+dp[i][j]=min(dp[i][j],max(dp[i - 1][k - 1], dp[i][j - k]))
+即每次在第k层碎了所转移到的状态，以及第k层没碎所转移到的状态
+```java
+public class Solution {
+    /**
+     * @param m the number of eggs
+     * @param n the umber of floors
+     * @return the number of drops in the worst case
+     */
+    public int dropEggs2(int m, int n) {
+        // Write your code here
+        int[][] dp = new int[m + 1][n + 1];
+
+        for (int i = 1; i <= m; ++i) {
+            dp[i][1] = 1;
+            dp[i][0] = 0;
+        }
+     
+        for (int j = 1; j <= n; ++j)
+            dp[1][j] = j;
+
+        for (int i = 2; i <= m; ++i) {
+            for (int j = 2; j <= n; ++j) {
+                dp[i][j] = Integer.MAX_VALUE;
+                for (int k = 1; k <= j; ++k) {
+                    dp[i][j] = Math.min(dp[i][j],
+                        1 + Math.max(dp[i - 1][k - 1], dp[i][j - k]));
+                }
+            }
+        }
+
+        return dp[m][n];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/drop-eggs.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/drop-eggs.md"
new file mode 100644
index 0000000..6ecbb03
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/drop-eggs.md"
@@ -0,0 +1,38 @@
+# 丢鸡蛋
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/drop-eggs/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 楼有 `n` 层高，鸡蛋若从 *k* 层或以上扔，就会碎。从 *k* 层以下扔，就不会碎。
+
+现在给两个鸡蛋，用最少的扔的次数找到 *k*。返回最坏情况下次数。
+ ### 样例说明
+ **样例 1：**
+```
+输入：100
+输出：14
+```
+**样例 2：**
+```
+输入：10
+输出：4
+```
+ ### 参考代码
+ ```cpp
+class Solution {
+public:
+    /**
+     * @param n an integer
+     * @return an integer
+     */
+    int dropEggs(int n) {
+        // Write your code here
+        long long ans = 0;
+        int x = 0;
+        while (ans < n) {
+            x += 1;
+            ans += x;
+        }
+        return x;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/edit-distance.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/edit-distance.md"
new file mode 100644
index 0000000..c590621
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/edit-distance.md"
@@ -0,0 +1,64 @@
+# 编辑距离
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/edit-distance/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出两个单词word1和word2，计算出将word1 转换为word2的最少操作次数。</p><p>你总共三种操作方法：</p><p></p><ul><li><span style="line-height: 1.42857143;">插入一个字符</span></li><li><span style="line-height: 1.42857143;">删除一个字符</span></li><li><span style="line-height: 1.42857143;">替换一个字符</span><br></li></ul><p></p>
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 
+"horse"
+"ros"
+输出: 3
+解释: 
+horse -> rorse (替换 'h' 为 'r')
+rorse -> rose (删除 'r')
+rose -> ros (删除 'e')
+```
+
+**样例 2:**
+
+```
+输入: 
+"intention"
+"execution"
+输出: 5
+解释: 
+intention -> inention (删除 't')
+inention -> enention (替换 'i' 为 'e')
+enention -> exention (替换 'n' 为 'x')
+exention -> exection (替换 'n' 为 'c')
+exection -> execution (插入 'u')
+```
+ ### 参考代码
+ 使用九章算法强化班，动态规划专题班中讲过的匹配型动态规划
+f[i][j] 代表第一个字符串以i结尾匹配上（编辑成）第二个字符串以j结尾的字符串，最少需要多少次编辑。
+通过去判断i与j的匹配关系来变为更小的状态。
+```
+[[python]]
+class Solution:
+    """
+    @param word1: A string
+    @param word2: A string
+    @return: The minimum number of steps.
+    """
+    def minDistance(self, word1, word2):
+        n, m = len(word1), len(word2)
+        f = [[0] * (m + 1) for _ in range(n + 1)]
+        
+        for i in range(n + 1):
+            f[i][0] = i
+        for j in range(m + 1):
+            f[0][j] = j
+
+        for i in range(1, n + 1):
+            for j in range(1, m + 1):
+                if word1[i - 1] == word2[j - 1]:
+                    f[i][j] = min(f[i - 1][j - 1], f[i - 1][j] + 1, f[i][j - 1] + 1)
+                    # equivalent to f[i][j] = f[i - 1][j - 1]
+                else:
+                    f[i][j] = min(f[i - 1][j - 1], f[i - 1][j], f[i][j - 1]) + 1
+                        
+        return f[n][m]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/frog-jump.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/frog-jump.md"
new file mode 100644
index 0000000..de62761
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/frog-jump.md"
@@ -0,0 +1,74 @@
+# 青蛙跳
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/frog-jump/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 一只青蛙正要过河，这条河分成了 x 个单位，每个单位可能存在石头，青蛙可以跳到石头上，但它不能跳进水里。
+按照顺序给出石头所在的位置，判断青蛙能否到达最后一块石头所在的位置。刚开始时青蛙在第一块石头上，假设青蛙第一次跳只能跳一个单位的长度。
+如果青蛙最后一个跳 k 个单位，那么它下一次只能跳 `k - 1` ，`k` 或者 `k + 1` 个单位。注意青蛙只能向前跳。
+ ### 样例说明
+ **样例 1:**
+```
+给出石头的位置为 [0,1,3,5,6,8,12,17]
+输入:
+[0,1,3,5,6,8,12,17]
+输出:
+true
+
+解释:
+总共8块石头。
+第一块石头在 0 位置，第二块石头在 1 位置，第三块石头在 3 位置等等......
+最后一块石头在 17 位置。
+返回 true。青蛙可以通过跳 1 格到第二块石头，跳 2 格到第三块石头，跳 2 格到第四块石头，跳 3 格到第六块石头，跳 4 格到第七块石头，最后跳 5 格到第八块石头。
+```
+
+**样例 2:**
+```
+给出石头的位置为 `[0,1,2,3,4,8,9,11]`
+输入:
+[0,1,2,3,4,8,9,11]
+输出:
+false
+
+解释:
+返回 false。青蛙没有办法跳到最后一块石头因为第五块石头跟第六块石头的距离太大了。
+```
+ ### 参考代码
+ dp[stone]为set，记录青蛙可以跳的距离。
+状态转移方程为：
+跳k - 1到stone + k - 1:dp[stone + k - 1].add(k - 1)
+跳k到stone + k:dp[stone + k].add(k)
+跳k + 1到stone + k + 1:dp[stone + k + 1].add(k + 1)
+```java
+public class Solution {
+    /**
+     * @param stones a list of stones' positions in sorted ascending order
+     * @return true if the frog is able to cross the river or false
+     */
+    public boolean canCross(int[] stones) {
+        // Write your code here
+        HashMap<Integer, HashSet<Integer>> dp =
+            new HashMap<Integer, HashSet<Integer>>(stones.length);
+        for (int i = 0; i < stones.length; i++) {
+        	dp.put(stones[i], new HashSet<Integer>() );
+        }
+        dp.get(0).add(0);
+
+        for (int i = 0; i < stones.length - 1; ++i) {
+        	int stone = stones[i];
+        	for (int k : dp.get(stone)) {
+                // k - 1
+                if (k - 1 > 0 && dp.containsKey(stone + k - 1))
+                    dp.get(stone + k - 1).add(k - 1);
+                // k
+                if (dp.containsKey(stone + k))
+                    dp.get(stone + k).add(k);
+                // k + 1
+                if (dp.containsKey(stone + k + 1))
+                    dp.get(stone + k + 1).add(k + 1);
+        	}
+        }
+        
+        return !dp.get(stones[stones.length - 1]).isEmpty();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/house-robber-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/house-robber-ii.md"
new file mode 100644
index 0000000..33809f2
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/house-robber-ii.md"
@@ -0,0 +1,52 @@
+# 打劫房屋 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/house-robber-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在上次打劫完一条街道之后，窃贼又发现了一个新的可以打劫的地方，**但这次所有的房子围成了一个圈，这就意味着第一间房子和最后一间房子是挨着的**。每个房子都存放着特定金额的钱。你面临的唯一约束条件是：**相邻的房子装着相互联系的防盗系统，且 当相邻的两个房子同一天被打劫时，该系统会自动报警**。
+
+给定一个非负整数列表，表示每个房子中存放的钱， 算一算，如果今晚去打劫，在不触动报警装置的情况下, 你最多可以得到多少钱 。
+ ### 样例说明
+ **样例1**
+
+```
+输入: nums = [3,6,4]
+输出: 6
+```
+
+**样例2**
+
+```
+输入: nums = [2,3,2,3]
+输出: 6
+```
+
+ ### 参考代码
+ 动态规划
+考虑前若干个房子，记录抢最后一个房子或者不抢最后一个房子能抢到的最多的钱
+然后交叉更新
+```python
+class Solution:
+    # @param nums: A list of non-negative integers.
+    # return: an integer
+    def houseRobber2(self, nums):
+        # write your code here
+        n = len(nums)
+        if n == 0:
+            return 0
+        if n == 1:
+            return nums[0]
+
+        dp = [0] * n
+        
+        dp[0], dp[1] = 0, nums[1]
+        for i in range(2, n):
+            dp[i] = max(dp[i - 2] + nums[i], dp[i - 1])
+
+        answer = dp[n - 1]
+
+        dp[0], dp[1] = nums[0], max(nums[0], nums[1])
+        for i in range(2, n - 1):
+            dp[i] = max(dp[i - 2] + nums[i], dp[i - 1])
+
+        return max(dp[n - 2], answer)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/house-robber-iii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/house-robber-iii.md"
new file mode 100644
index 0000000..08533db
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/house-robber-iii.md"
@@ -0,0 +1,67 @@
+# 打劫房屋 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/house-robber-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在上次打劫完一条街道之后和一圈房屋之后，窃贼又发现了一个新的可以打劫的地方，**但这次所有的房子组成的区域比较奇怪，聪明的窃贼考察地形之后，发现这次的地形是一颗二叉树**。与前两次偷窃相似的是每个房子都存放着特定金额的钱。你面临的唯一约束条件是：**相邻的房子装着相互联系的防盗系统，且当相邻的两个房子同一天被打劫时，该系统会自动报警**。
+
+算一算，如果今晚去打劫，你最多可以得到多少钱，当然在不触动报警装置的情况下。
+ ### 样例说明
+ **样例1**
+
+```
+输入:  {3,2,3,#,3,#,1}
+输出: 7
+解释:
+最多能偷 3 + 3 + 1 = 7.
+  3
+ / \
+2   3
+ \   \ 
+  3   1
+```
+
+**样例2**
+
+```
+输入:  {3,4,5,1,3,#,1}
+输出: 9
+解释:
+最多能偷 4 + 5 = 9.
+    3
+   / \
+  4   5
+ / \   \ 
+1   3   1
+```
+ ### 参考代码
+ 动态规划
+首先枚举是否抢第一个房子
+考虑前若干个房子，记录抢最后一个房子或者不抢最后一个房子能抢到的最多的钱
+然后交叉更新
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        sef.val = val
+        self.left, self.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root, the root of binary tree.
+    # @return {int} The maximum amount of money you can rob tonight
+    def houseRobber3(self, root):
+        # write your code here
+        rob, not_rob = self.visit(root)
+        return max(rob, not_rob)
+        
+    def visit(self, root):
+        if root is None:
+            return 0, 0
+        
+        left_rob, left_not_rob = self.visit(root.left)
+        right_rob, right_not_rob = self.visit(root.right)
+        
+        rob = root.val + left_not_rob + right_not_rob
+        not_rob = max(left_rob, left_not_rob) + max(right_rob, right_not_rob)
+        return rob, not_rob
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/house-robber.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/house-robber.md"
new file mode 100644
index 0000000..ea45f48
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/house-robber.md"
@@ -0,0 +1,46 @@
+# 打劫房屋
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/house-robber/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假设你是一个专业的窃贼，准备沿着一条街打劫房屋。每个房子都存放着特定金额的钱。你面临的唯一约束条件是：相邻的房子装着相互联系的防盗系统，且 **当相邻的两个房子同一天被打劫时，该系统会自动报警**。
+
+给定一个非负整数列表，表示每个房子中存放的钱， 算一算，如果今晚去打劫，**在不触动报警装置的情况下**, 你最多可以得到多少钱 。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [3, 8, 4]
+输出: 8
+解释: 仅仅打劫第二个房子.
+```
+
+**样例 2:**
+
+```
+输入: [5, 2, 1, 3] 
+输出: 8
+解释: 抢第一个和最后一个房子
+```
+ ### 参考代码
+ 使用滚动数组的做法，将每个下标直接 % 3。
+时间复杂度 $O(n)$，空间复杂度 $O(1)$
+```python
+class Solution:
+    """
+    @param A: An array of non-negative integers
+    @return: The maximum amount of money you can rob tonight
+    """
+    def houseRobber(self, A):
+        if not A:
+            return 0
+        if len(A) <= 2:
+            return max(A)
+            
+        f = [0] * 3
+        f[0], f[1] = A[0], max(A[0], A[1])
+        
+        for i in range(2, len(A)):
+            f[i % 3] = max(f[(i - 1) % 3], f[(i - 2) % 3] + A[i])
+            
+        return f[(len(A) - 1) % 3]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/interleaving-string.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/interleaving-string.md"
new file mode 100644
index 0000000..3d12923
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/interleaving-string.md"
@@ -0,0 +1,71 @@
+# 交叉字符串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/interleaving-string/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出三个字符串:*s1*、*s2*、*s3*，判断*s3*是否由*s1*和*s2*交叉构成。
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入:
+"aabcc"
+"dbbca"
+"aadbbcbcac"
+输出:
+true
+```
+**样例 2：**
+```
+输入:
+""
+""
+"1"
+输出:
+false
+```
+**样例 3：**
+```
+输入:
+"aabcc"
+"dbbca"
+"aadbbbaccc"
+输出:
+false
+```
+
+ ### 参考代码
+ 动态规划。
+dp[i][j]代表由s1的前i个字母和s2的前j个字母是否能构成当前i+j个字母。
+然后状态转移即可。（看第i+j+1个是否能被s1的第i+1个构成或被s2的第j+1个构成）
+```java
+public class Solution {
+    public boolean isInterleave(String s1, String s2, String s3) {
+        if (s1.length() + s2.length() != s3.length()) {
+            return false;
+        }
+        
+        boolean [][] interleaved = new boolean[s1.length() + 1][s2.length() + 1];
+        interleaved[0][0] = true;
+        
+        for (int i = 1; i <= s1.length(); i++) {
+            if(s3.charAt(i - 1) == s1.charAt(i - 1) && interleaved[i - 1][0])
+                interleaved[i][0] = true;
+        }
+        
+        for (int j = 1; j <= s2.length(); j++) {
+            if(s3.charAt(j - 1) == s2.charAt(j - 1) && interleaved[0][j - 1])
+                interleaved[0][j] = true;
+        }
+        
+        for (int i = 1; i <= s1.length(); i++) {
+            for (int j = 1; j <= s2.length(); j++) {
+                if(((s3.charAt(i + j - 1) == s1.charAt(i - 1) && interleaved[i - 1][j]))
+                    || ((s3.charAt(i + j - 1)) == s2.charAt(j - 1) && interleaved[i][j - 1]))
+                interleaved[i][j] = true;
+            }
+        }
+        
+        return interleaved[s1.length()][s2.length()];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/jump-game.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/jump-game.md"
new file mode 100644
index 0000000..33c6ad6
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/jump-game.md"
@@ -0,0 +1,69 @@
+# 跳跃游戏
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/jump-game/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个非负整数数组，你最初定位在数组的第一个位置。　　　</p><p>数组中的每个元素代表你在那个位置可以跳跃的最大长度。　　　　</p><p>判断你是否能到达数组的最后一个位置。</p>
+ ### 样例说明
+ ***样例 1***
+```
+输入 : [2,3,1,1,4]
+输出 : true
+```
+
+***样例 2***
+```
+输入 : [3,2,1,0,4]
+输出 : false
+```
+ ### 参考代码
+ Given an array of non-negative integers, you are initially positioned at the first index of the array.
+
+Each element in the array represents your maximum jump length at that position.
+
+Determine if you are able to reach the last index.
+
+For example:
+A = [2,3,1,1,4], return true.
+
+A = [3,2,1,0,4], return false.
+
+```
+[[java]]
+// version 1: Dynamic Programming
+// 这个方法，复杂度是 O(n^2) 可能会超时，但是依然需要掌握。
+public class Solution {
+    public boolean canJump(int[] A) {
+        boolean[] can = new boolean[A.length];
+        can[0] = true;
+        
+        for (int i = 1; i < A.length; i++) {
+            for (int j = 0; j < i; j++) {
+                if (can[j] && j + A[j] >= i) {
+                    can[i] = true;
+                    break;
+                }
+            }
+        }
+        
+        return can[A.length - 1];
+    }
+}
+
+
+// version 2: Greedy
+public class Solution {
+    public boolean canJump(int[] A) {
+        // think it as merging n intervals
+        if (A == null || A.length == 0) {
+            return false;
+        }
+        int farthest = A[0];
+        for (int i = 1; i < A.length; i++) {
+            if (i <= farthest && A[i] + i >= farthest) {
+                farthest = A[i] + i;
+            }
+        }
+        return farthest >= A.length - 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/k-edit-distance.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/k-edit-distance.md"
new file mode 100644
index 0000000..f4de674
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/k-edit-distance.md"
@@ -0,0 +1,234 @@
+# K步编辑
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/k-edit-distance/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个只含有小写字母的字符串的集合以及一个目标串，输出所有可以经过不多于 `k` 次操作得到目标字符串的字符串。
+
+你可以对字符串进行一下的3种操作:
+
+* 加入1个字母
+
+* 删除1个字母
+
+* 替换1个字母
+ ### 样例说明
+ **样例 1:**
+```
+给出字符串 `["abc","abd","abcd","adc"]`，目标字符串为 `"ac"` ，k = `1`
+返回 `["abc","adc"]`
+输入:
+["abc", "abd", "abcd", "adc"]
+"ac"
+1
+输出:
+["abc","adc"]
+
+解释:
+"abc" 去掉 "b"
+"adc" 去掉 "d"
+```
+
+**样例 2:**
+```
+输入:
+["acc","abcd","ade","abbcd"]
+"abc"
+2
+输出:
+["acc","abcd","ade","abbcd"]
+
+解释:
+"acc" 把 "c" 变成 "b"
+"abcd" 去掉 "d"
+"ade" 把 "d" 变成 "b"把 "e" 变成 "c"
+"abbcd" 去掉 "b" 和 "d"
+```
+ ### 参考代码
+ 滚动数组。用字典树对dfs进行优化。
+```java
+// 九章算法强化班版本
+class TrieNode{
+    public TrieNode[] sons;
+    public boolean isWord;
+    public String word;
+    
+    public TrieNode() {
+        int i;
+        sons = new TrieNode[26];
+        for (i = 0; i < 26; ++i) {
+            sons[i] = null;
+        }
+        
+        isWord = false;
+    }
+    
+    static public void Insert(TrieNode p, String word) {
+        int i;
+        char[] s = word.toCharArray();
+        for (i = 0; i < s.length; ++i) {
+            int c = s[i] - 'a';
+            if (p.sons[c] == null) {
+                p.sons[c] = new TrieNode();
+            }
+            
+            p = p.sons[c];
+        }
+        
+        p.isWord = true;
+        p.word = word;
+    }
+}
+
+public class Solution {
+    /**
+     * @param words: a set of stirngs
+     * @param target: a target string
+     * @param k: An integer
+     * @return: output all the strings that meet the requirements
+     */
+     
+    int K;
+    int n;
+    char[] target;
+    List<String> res;
+    
+    // p is the current TrieNode
+    // f[] representss f[Sp][...]
+    void dfs(TrieNode p, int[] f) {
+        int[] newf;
+        int i;
+        if (p.isWord && f[n] <= K) {
+            res.add(p.word);
+        }
+        
+        for (int c = 0; c < 26; ++c) {
+            if (p.sons[c] == null) {
+                continue;
+            }
+            
+            // calc newf
+            newf = new int[n + 1];
+            // newf[...]: f[Sp + c][....]
+            
+            // newf[j] = Math.min(Math.min(f[j], newf[j-1]), f[j-1]) + 1;
+            for (i = 0; i <= n; ++i) {
+                newf[i] = f[i] + 1;
+            }
+            
+            for (i = 1; i <= n; ++i) {
+                newf[i] = Math.min(newf[i], f[i - 1] + 1);
+            }   
+            
+            for (i = 1; i <= n; ++i) {
+                if (target[i - 1] - 'a' == c) {
+                    newf[i] = Math.min(newf[i], f[i - 1]);
+                }
+                
+                newf[i] = Math.min(newf[i - 1] + 1, newf[i]);
+            }
+            
+            dfs(p.sons[c], newf);
+        }
+    }
+     
+    public List<String> kDistance(String[] words, String targets, int k) {
+        res = new ArrayList<String>();
+        K = k;
+        TrieNode root = new TrieNode();
+        int i;
+        for (i = 0; i < words.length; ++i) {
+            TrieNode.Insert(root, words[i]);
+        }
+        
+        target = targets.toCharArray();
+        n = target.length;
+        int[] f = new int[n + 1];
+        for (i = 0; i <= n; ++i) {
+            f[i] = i;
+        }
+        
+        dfs(root, f);
+        return res;
+    }
+}
+
+
+class TrieNode {
+    // Initialize your data structure here.
+    public TrieNode[] children;
+    public boolean hasWord;
+    public String str;
+    
+    // Initialize your data structure here.
+    public TrieNode() {
+        children = new TrieNode[26];
+        for (int i = 0; i < 26; ++i)
+            children[i] = null;
+        hasWord = false;
+    }
+
+    // Adds a word into the data structure.
+    static public void addWord(TrieNode root, String word) {
+        TrieNode now = root;
+        for(int i = 0; i < word.length(); i++) {
+            Character c = word.charAt(i);
+            if (now.children[c - 'a'] == null) {
+                now.children[c - 'a'] = new TrieNode();
+            }
+            now = now.children[c - 'a'];
+        }
+        now.str = word;
+        now.hasWord = true;
+    }
+}
+
+public class Solution {
+    /**
+     * @param words a set of stirngs
+     * @param target a target string
+     * @param k an integer
+     * @return output all the strings that meet the requirements
+     */
+    public List<String> kDistance(String[] words, String target, int k) {
+        // Write your code here
+        TrieNode root = new TrieNode();
+        for (int i = 0; i < words.length; i++)
+            TrieNode.addWord(root, words[i]);
+
+        List<String> result = new ArrayList<String>();
+
+        int n = target.length();
+        int[] dp = new int[n + 1];
+        for (int i = 0; i <= n; ++i)
+            dp[i] = i;
+
+        find(root, result, k, target, dp);
+        return result;
+    }
+
+    public void find(TrieNode node, List<String> result, int k, String target, int[] dp) {
+        int n = target.length();
+        // dp[i] 表示从Trie的root节点走到当前node节点，形成的Prefix
+        // 和 target的前i个字符的最小编辑距离
+        if (node.hasWord && dp[n] <= k) {
+            result.add(node.str);
+        }
+        int[] next = new int[n + 1];
+        for (int i = 0; i <= n; ++i)
+            next[i] = 0;
+
+        for (int i = 0; i < 26; ++i)
+            if (node.children[i] != null) {
+                next[0] = dp[0] + 1;
+                for (int j = 1; j <= n; j++) {
+                    if (target.charAt(j - 1) - 'a' == i) {
+                        next[j] = Math.min(dp[j - 1], Math.min(next[j - 1] + 1, dp[j] + 1));
+                    } else {
+                        next[j] = Math.min(dp[j - 1] + 1, Math.min(next[j - 1] + 1, dp[j] + 1));
+                    }
+                }
+                find(node.children[i], result, k, target, next);
+            }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/largest-divisible-subset.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/largest-divisible-subset.md"
new file mode 100644
index 0000000..29911a7
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/largest-divisible-subset.md"
@@ -0,0 +1,52 @@
+# 最大整除子集
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/largest-divisible-subset/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个由 `无重复的正整数` 组成的集合，找出满足任意两个元素 `(Si, Sj)` 都有 `Si % Sj = 0` 或 `Sj % Si = 0` 成立的最大子集
+ ### 样例说明
+ 
+ ### 参考代码
+ dp。
+首先排序。
+f[i]代表以nums[i]为最大元素的序列最多有多少个。
+然后只要nums[k]%nums[i]=0，则可尝试往f[k]转移。
+但由于时间复杂度为O(N^2), 无法通过，需要进一步优化。
+```java
+public class Solution {
+    public List<Integer> largestDivisibleSubset(int[] nums) {
+        Arrays.sort(nums);
+        int[] f = new int[nums.length];
+        int[] pre = new int[nums.length];
+        for (int i = 0; i < nums.length; i++) {
+            f[i] = 1;
+            pre[i] = i;
+            for (int j = 0; j < i; j++) {
+                if (nums[i] % nums[j] == 0 && f[i] < f[j] + 1) {
+                    f[i] = f[j] + 1;
+                    pre[i] = j;
+                }
+            }
+        }
+        
+        List<Integer> ans = new ArrayList<Integer>();
+        if (nums.length == 0) {
+            return ans;
+        }
+        int max = 0;
+        int max_i = 0;
+        for (int i = 0; i < nums.length; i++) {
+            if (f[i] > max) {
+                max = f[i];
+                max_i = i;
+            }
+        }
+        ans.add(nums[max_i]);
+        while (max_i != pre[max_i]) {
+            max_i = pre[max_i];
+            ans.add(nums[max_i]);
+        }
+        Collections.reverse(ans);
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/longest-common-subsequence.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-common-subsequence.md"
new file mode 100644
index 0000000..55ec45d
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-common-subsequence.md"
@@ -0,0 +1,42 @@
+# 最长公共子序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-common-subsequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出两个字符串，找到最长公共子序列(LCS)，返回LCS的长度。</p>
+ ### 样例说明
+ ```
+样例 1:
+	输入:  "ABCD" and "EDCA"
+	输出:  1
+	
+	解释:
+	LCS 是 'A' 或  'D' 或 'C'
+
+
+样例 2:
+	输入: "ABCD" and "EACB"
+	输出:  2
+	
+	解释: 
+	LCS 是 "AC"
+```
+
+ ### 参考代码
+ 使用九章算法强化班和动态规划专题班中讲的匹配型动态规划
+```python
+class Solution:
+    """
+    @param A: A string
+    @param B: A string
+    @return: The length of longest common subsequence of A and B
+    """
+    def longestCommonSubsequence(self, A, B):
+        n, m = len(A), len(B)
+        f = [[0] * (m + 1) for i in range(n + 1)]
+        for i in range(1, n + 1):
+            for j in range(1, m + 1):
+                f[i][j] = max(f[i][j - 1], f[i - 1][j])
+                if A[i - 1] == B[j - 1]:
+                    f[i][j] = max(f[i][j], f[i - 1][j - 1] + 1)
+        return f[n][m]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/longest-continuous-increasing-subsequence-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-continuous-increasing-subsequence-ii.md"
new file mode 100644
index 0000000..e2fb267
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-continuous-increasing-subsequence-ii.md"
@@ -0,0 +1,79 @@
+# 最长上升连续子序列 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-continuous-increasing-subsequence-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数矩阵. 找出矩阵中的最长连续上升子序列, 返回它的长度.
+
+最长连续上升子序列可以从任意位置开始, 向上/下/左/右移动.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 
+    [
+      [1, 2, 3, 4, 5],
+      [16,17,24,23,6],
+      [15,18,25,22,7],
+      [14,19,20,21,8],
+      [13,12,11,10,9]
+    ]
+输出: 25
+解释: 1 -> 2 -> 3 -> 4 -> 5 -> ... -> 25 (由外向内螺旋)
+```
+
+**样例 2:**
+
+```
+输入: 
+    [
+      [1, 2],
+      [5, 3]
+    ]
+输出: 5
+解释: 1 -> 2 -> 3 -> 5
+```
+ ### 参考代码
+ 使用九章算法强化班，动态规划专题班中讲过的 **序列性动态规划**
+
+我们把二维矩阵打散成为一位数组，数组中每个元素记录二维矩阵中的坐标和高度。
+然后把一位数组按照高度排序。
+
+f[i] 表示第 i 个点结束的最长序列，得到公式：
+```
+f[i] = max{f[j] + 1 |  j < i && j 这个点比 i 要低，且i和j两个点相邻}
+```
+
+最后在 max(f[i]) 就是我们要的结果。
+
+类似的题还有 longest increasing subsequence.
+```python
+class Solution:
+    """
+    @param A: An integer matrix
+    @return: an integer
+    """
+    def longestContinuousIncreasingSubsequence2(self, A):
+        if not A or not A[0]:
+            return 0
+            
+        n, m = len(A), len(A[0])
+        points = []
+        for i in range(n):
+            for j in range(m):
+                points.append((A[i][j], i, j))
+                
+        points.sort()
+        
+        longest_hash = {}
+        for i in range(len(points)):
+            key = (points[i][1], points[i][2])
+            longest_hash[key] = 1
+            for dx, dy in [(1, 0), (0, -1), (-1, 0), (0, 1)]:
+                x, y = points[i][1] + dx, points[i][2] + dy
+                if x < 0 or x >= n or y < 0 or y >= m:
+                    continue
+                if (x, y) in longest_hash and A[x][y] < points[i][0]:
+                    longest_hash[key] = max(longest_hash[key], longest_hash[(x, y)] + 1)
+                    
+        return max(longest_hash.values())
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/longest-continuous-increasing-subsequence.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-continuous-increasing-subsequence.md"
new file mode 100644
index 0000000..fdea9c8
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-continuous-increasing-subsequence.md"
@@ -0,0 +1,46 @@
+# 最长上升连续子序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-continuous-increasing-subsequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组（下标从 0 到 n-1， n 表示整个数组的规模），请找出该数组中的最长上升连续子序列。（最长上升连续子序列可以定义为从右到左或从左到右的序列。）
+ ### 样例说明
+ **样例 1：**
+```
+输入：[5, 4, 2, 1, 3]
+输出：4
+解释：
+给定 [5, 4, 2, 1, 3]，其最长上升连续子序列（LICS）为 [5, 4, 2, 1]，返回 4。
+```
+**样例 2：**
+```
+输入：[5, 1, 2, 3, 4]
+输出：4
+解释：
+给定 [5, 1, 2, 3, 4]，其最长上升连续子序列（LICS）为 [1, 2, 3, 4]，返回 4。
+```
+ ### 参考代码
+ 从左到右求出最长递增和最长递减。
+```python
+class Solution:
+    """
+    @param A: An array of Integer
+    @return: an integer
+    """
+    def longestIncreasingContinuousSubsequence(self, A):
+        if not A:
+            return 0
+        longest, incr, desc = 1, 1, 1
+        for i in range(1, len(A)):
+            if A[i] > A[i - 1]:
+                incr += 1
+                desc = 1
+            elif A[i] < A[i - 1]:
+                incr = 1
+                desc += 1
+            else:
+                incr = 1
+                desc = 1
+            longest = max(longest, max(incr, desc))
+            
+        return longest
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/longest-increasing-continuous-subsequence.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-increasing-continuous-subsequence.md"
new file mode 100644
index 0000000..c3d3cb3
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-increasing-continuous-subsequence.md"
@@ -0,0 +1,91 @@
+# 最长上升连续子序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-increasing-continuous-subsequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组（下标从 0 到 n-1， n 表示整个数组的规模），请找出该数组中的最长上升连续子序列。（最长上升连续子序列可以定义为从右到左或从左到右的序列。）
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    public int longestIncreasingContinuousSubsequence(int[] A) {
+        if (A == null || A.length == 0) {
+            return 0;
+        }
+        
+        int n = A.length;
+        int answer = 1;
+        
+        // from left to right
+        int length = 1; // just A[0] itself
+        for (int i = 1; i < n; i++) {
+            if (A[i] > A[i - 1]) {
+                length++;
+            } else {
+                length = 1;
+            }
+            answer = Math.max(answer, length);
+        }
+        
+        // from right to left
+        length = 1;
+        for (int i = n - 2; i >= 0; i--) {
+            if (A[i] > A[i + 1]) {
+                length++;
+            } else {
+                length = 1;
+            }
+            answer = Math.max(answer, length);
+        }
+        
+        return answer;
+    }
+}
+
+//  方法二
+public class Solution {
+    /**
+     * @param A an array of Integer
+     * @return  an integer
+     */
+    
+    int LIS(int[] A) {
+        int n = A.length;
+        int[] f = new int[n];
+        int i, res = 0;
+        for (i = 0; i < n; ++i) {
+            f[i] = 1;
+            if (i > 0 && A[i-1] < A[i]) {
+                f[i] = f[i-1] + 1;
+            }
+            if (f[i] > res) {
+                res = f[i];
+            }
+        }
+        
+        return res;
+    }
+     
+    public int longestIncreasingContinuousSubsequence(int[] A) {
+        int n = A.length;
+        int r1 = LIS(A);
+        int i = 0, j = n-1, t;
+        while (i < j) {
+            t = A[i];
+            A[i] = A[j];
+            A[j] = t;
+            ++i;
+            --j;
+        }
+        
+        int r2 = LIS(A);
+        
+        if (r1 > r2) {
+            return r1;
+        }
+        else {
+            return r2;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/longest-increasing-subsequence.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-increasing-subsequence.md"
new file mode 100644
index 0000000..170c403
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-increasing-subsequence.md"
@@ -0,0 +1,121 @@
+# 最长上升子序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-increasing-subsequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数序列，找到最长上升子序列（LIS），返回LIS的长度。
+ ### 样例说明
+ ```
+样例 1:
+	输入:  [5,4,1,2,3]
+	输出:  3
+	
+	解释:
+	LIS 是 [1,2,3]
+
+
+样例 2:
+	输入: [4,2,4,5,3,7]
+	输出:  4
+	
+	解释: 
+	LIS 是 [2,4,5,7]
+```
+ ### 参考代码
+ 使用动态规划计算 Longest Increasing Subsequence，并同时打印具体的方案
+```
+[[python]]
+class Solution:
+    """
+    @param nums: The integer array
+    @return: The length of LIS (longest increasing subsequence)
+    """
+    def longestIncreasingSubsequence(self, nums):
+        if nums is None or not nums:
+            return 0
+        
+        # state: dp[i] 表示从左到右跳到i的最长sequence 的长度
+        
+        # initialization: dp[0..n-1] = 1
+        dp = [1] * len(nums)
+        
+        # prev[i] 代表 dp[i] 的最优值是从哪个 dp[j] 算过来的
+        prev = [-1] * len(nums)
+        
+        # function dp[i] = max{dp[j] + 1},  j < i and nums[j] < nums[i]
+        for i in range(len(nums)):
+            for j in range(i):
+                if nums[j] < nums[i] and dp[i] < dp[j] + 1:
+                    dp[i] = dp[j] + 1
+                    prev[i] = j
+        
+        # answer: max(dp[0..n-1])
+        longest, last = 0, -1
+        for i in range(len(nums)):
+            if dp[i] > longest:
+                longest = dp[i]
+                last = i
+        
+        path = []
+        while last != -1:
+            path.append(nums[last])
+            last = prev[last]
+        print(path[::-1])
+        
+        return longest
+[[java]]
+public class Solution {
+    /**
+     * @param nums: An integer array
+     * @return: The length of LIS (longest increasing subsequence)
+     */
+    public int longestIncreasingSubsequence(int[] nums) {
+        if (nums == null || nums.length == 0) {
+            return 0;
+        } 
+        int n = nums.length;
+        
+        // state: 
+        // dp[i] 表示从左到右跳到i的最长sequence 的长度
+        // prev[i] 代表 dp[i] 的最优值是从哪个 dp[j] 算过来的
+        int[] prev = new int[n];
+        int[] dp = new int[n];
+        
+        // initialization: dp[0..n-1] = 1
+        for (int i = 0; i < n; i++) {
+            dp[i] = 1;
+            prev[i] = -1;
+        }
+        
+        // function dp[i] = max{dp[j] + 1},  j < i and nums[j] < nums[i]
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < i; j++) {
+                if (nums[j] < nums[i] && dp[j] + 1 > dp[i]) {
+                    dp[i] = dp[j] + 1;
+                    prev[i] = j;
+                }
+            }
+        }
+        
+        // answer: max(dp[0..n-1])
+        int longest = 0, last = -1;
+        for (int i = 0; i < n; i++) {
+            if (dp[i] > longest) {
+                longest = dp[i];
+                last = i;
+            }
+        }
+        
+        // print solution
+        ArrayList<Integer> path = new ArrayList();
+        while (last != -1) {
+            path.add(nums[last]);
+            last = prev[last];
+        }
+        for (int i = path.size() - 1; i >= 0; i--) {
+            System.out.print(path.get(i) + "-");
+        }
+        
+        return longest;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/longest-palindromic-subsequence.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-palindromic-subsequence.md"
new file mode 100644
index 0000000..4241df4
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-palindromic-subsequence.md"
@@ -0,0 +1,48 @@
+# 最长的回文序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-palindromic-subsequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一字符串 s, 找出在 s 中的最长回文子序列的长度. 你可以假设 s 的最大长度为 `1000`.
+ ### 样例说明
+ **样例1**
+```
+输入： "bbbab"
+输出： 4
+解释：
+一个可能的最长回文序列为 "bbbb"
+```
+**样例2**
+```
+输入： "bbbbb"
+输出： 5
+```
+ ### 参考代码
+ 对于任意字符串，如果头尾字符相同，那么字符串的最长子序列等于去掉首尾的字符串的最长子序列加上首尾；如果首尾字符不同，则最长子序列等于去掉头的字符串的最长子序列和去掉尾的字符串的最长子序列的较大者。
+
+设`dp[i][j]`表示第i到第j个字符间的最长回文序列的长度（i<=j）
+
+状态转移方程：
+
+$dp[i][j]=dp[i+1][j-1] + 2\qquad if(str[i]==str[j])$
+
+$dp[i][j]=max(dp[i+1][j],dp[i][j-1])\quad  if(str[i]!=str[j])$
+```python
+class Solution:
+    """
+    @param s: the maximum length of s is 1000
+    @return: the longest palindromic subsequence's length
+    """
+    def longestPalindromeSubseq(self, s):
+        length = len(s)
+        if length == 0:
+            return 0
+        dp = [[0] * length for _ in range(length)]
+        for i in range(length - 1, -1, -1):
+            dp[i][i] = 1
+            for j in range(i + 1, length):
+                if s[i] == s[j]:
+                    dp[i][j] = dp[i + 1][j - 1] + 2
+                else:
+                    dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
+        return dp[0][length - 1]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/longest-path-on-the-tree.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-path-on-the-tree.md"
new file mode 100644
index 0000000..4342b21
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-path-on-the-tree.md"
@@ -0,0 +1,164 @@
+# 树上最长路径
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-path-on-the-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出由`n`个结点，`n-1`条边组成的一棵树。求这棵树中距离最远的两个结点之间的距离。
+给出三个大小为`n-1`的数组`starts`,`ends`,`lens`,表示第`i`条边是从`starts[i]`连向`ends[i]`，长度为`lens[i]`的无向边。
+ ### 样例说明
+ **Example 1:**
+```
+Input：n=5,starts=[0,0,2,2],ends=[1,2,3,4],lens=[1,2,5,6]
+Output：11
+解释:
+(3→2→4)这条路径长度为`11`，当然(4→2→3)也是一样的。
+```
+
+**Example 2:**
+```
+Input：n=5,starts=[0,0,2,2],ends=[1,2,3,4],lens=[5,2,5,6]
+Output：13
+解释:
+(1→0→2→4)这条路径长度为`13`，当然(4→2→0→1)也是一样的。
+```
+ ### 参考代码
+ ```
+[[python]]
+class Solution:
+    """
+    @param n: The number of nodes
+    @param starts: One point of the edge
+    @param ends: Another point of the edge
+    @param lens: The length of the edge
+    @return: Return the length of longest path on the tree.
+    """
+    def longestPath(self, n, starts, ends, lens):
+        graph = self.build_graph(starts, ends, lens)
+        bfs_order = self.get_bfs_order(graph)
+        return self.find_longest_path(bfs_order, graph)
+        
+    def build_graph(self, starts, ends, lens):
+        n = len(starts) + 1
+        graph = {i: {} for i in range(n)}
+        for i in range(n - 1):
+            graph[starts[i]][ends[i]] = lens[i]
+            graph[ends[i]][starts[i]] = lens[i]
+        return graph
+        
+    def get_bfs_order(self, graph):        
+        n = len(graph)
+        queue, start = [0], 0
+        visited = set([0])
+        while start < len(queue):
+            node = queue[start]
+            for neighbor in graph[node]:
+                if neighbor in visited:
+                    continue
+                visited.add(neighbor)
+                queue.append(neighbor)
+            start += 1
+        
+        return queue
+        
+    def find_longest_path(self, bfs_order, graph):
+        longest_path_to_leaf = {}
+        longest_path = -float('inf')
+        for node in reversed(bfs_order):
+            max_path, second_max_path = -float('inf'), -float('inf')
+            for neighbor in graph[node]:
+                # if neighbor is parent
+                if neighbor not in longest_path_to_leaf:
+                    continue
+                if graph[node][neighbor] + longest_path_to_leaf[neighbor] > max_path:
+                    second_max_path = max_path
+                    max_path = graph[node][neighbor] + longest_path_to_leaf[neighbor]
+                elif graph[node][neighbor] + longest_path_to_leaf[neighbor] > second_max_path:
+                    second_max_path = graph[node][neighbor] + longest_path_to_leaf[neighbor]
+            # if max_path == -float('inf') that means node is a leaf
+            longest_path_to_leaf[node] = max(max_path, 0)
+            longest_path = max(longest_path, longest_path_to_leaf[node])
+            if second_max_path != -float('inf'):
+                longest_path = max(longest_path, max_path + second_max_path)
+        return longest_path
+[[java]]
+public class Solution {
+    /**
+     * @param n: The number of nodes
+     * @param starts: One point of the edge
+     * @param ends: Another point of the edge
+     * @param lens: The length of the edge
+     * @return: Return the length of longest path on the tree.
+     */
+    public int longestPath(int n, int[] starts, int[] ends, int[] lens) {
+        Map<Integer, Map<Integer, Integer>> graph = buildGraph(starts, ends, lens);
+        List<Integer> bfsOrder = getBfsOrder(graph);
+        return findLongestPath(bfsOrder, graph);
+    }
+    
+    private Map<Integer, Map<Integer, Integer>> buildGraph(int[] starts, int[] ends, int[] lens) {
+        int n = starts.length + 1;
+        Map<Integer, Map<Integer, Integer>> graph = new HashMap<>();
+        for (int i = 0; i < n - 1; i++) {
+            if (!graph.containsKey(starts[i])) {
+                graph.put(starts[i], new HashMap<Integer, Integer>());
+            }
+            if (!graph.containsKey(ends[i])) {
+                graph.put(ends[i], new HashMap<Integer, Integer>());
+            }
+            graph.get(starts[i]).put(ends[i], lens[i]);
+            graph.get(ends[i]).put(starts[i], lens[i]);
+        }
+        return graph;
+    }
+    
+    private List<Integer> getBfsOrder(Map<Integer, Map<Integer, Integer>> graph) {
+        int n = graph.size();
+        List<Integer> queue = new ArrayList<>();
+        int start = 0;
+        Set<Integer> visited = new HashSet<>();
+        queue.add(0);
+        visited.add(0);
+        
+        while (start < queue.size()) {
+            int node = queue.get(start);
+            for (int neighbor: graph.getOrDefault(node, new HashMap<>()).keySet()) {
+                if (visited.contains(neighbor)) {
+                    continue;
+                }
+                visited.add(neighbor);
+                queue.add(neighbor);
+            }
+            start++;
+        }
+        
+        return queue;
+    }
+    
+    private int findLongestPath(List<Integer> bfsOrder, Map<Integer, Map<Integer, Integer>> graph) {
+        Map<Integer, Integer> longestPathToLeaf = new HashMap<>();
+        int longestPath = Integer.MIN_VALUE;
+        for (int i = bfsOrder.size() - 1; i >= 0; i--) {
+            int node = bfsOrder.get(i);
+            int maxPath = Integer.MIN_VALUE, secondMaxPath = Integer.MIN_VALUE;
+            for (int neighbor: graph.getOrDefault(node, new HashMap<>()).keySet()) {
+                // if neighbor is parent
+                if (!longestPathToLeaf.containsKey(neighbor)) {
+                    continue;
+                }
+                if (graph.get(node).get(neighbor) + longestPathToLeaf.get(neighbor) > maxPath) {
+                    secondMaxPath = maxPath;
+                    maxPath = graph.get(node).get(neighbor) + longestPathToLeaf.get(neighbor);
+                } else if (graph.get(node).get(neighbor) + longestPathToLeaf.get(neighbor) > secondMaxPath) {
+                    secondMaxPath = graph.get(node).get(neighbor) + longestPathToLeaf.get(neighbor);
+                }
+            }
+            // if maxPath == Integer.MIN_VALUE that means node is a leaf
+            longestPathToLeaf.put(node, Math.max(maxPath, 0));
+            longestPath = Math.max(longestPath, longestPathToLeaf.get(node));
+            if (secondMaxPath != Integer.MIN_VALUE) {
+                longestPath = Math.max(longestPath, maxPath + secondMaxPath);
+            }
+        }
+        return longestPath;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/longest-repeating-subsequence.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-repeating-subsequence.md"
new file mode 100644
index 0000000..ad83439
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-repeating-subsequence.md"
@@ -0,0 +1,66 @@
+# 最长重复子序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-repeating-subsequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个字符串，找到最长的重复子序列的长度，并且这两个子序列不能在相同位置有同一元素。
+比如：在两个子序列中的第i个元素不能在原来的字符串中有相同的下标。
+ ### 样例说明
+ 例1:
+```
+输入:"aab"
+输出:1
+解释:
+两个子序列是a（第一个）和a（第二个）。
+请注意，b不能被视为子序列的一部分，因为它在两者中都是相同的索引。
+```
+
+
+例2:
+```
+输入:"abc"
+输出:0
+解释:
+没有重复的序列
+```
+
+
+例3:
+```
+输入:"aabb"
+输出:2
+解释:
+有两个相同的子序列"ab". 其中第一个子序列是s[0] + s[2], 第二个子序列是s[1]+s[3], 所以重复子序列的长度为2.
+```
+
+ ### 参考代码
+ 动态规划。
+dp[i][j] 代表前i个与前j个匹配的最大长度。
+若字符相同而位置不同，即可转移。
+```java
+public class Solution {
+    /**
+     * @param str a string
+     * @return the length of the longest repeating subsequence
+     */
+    public int longestRepeatingSubsequence(String str) {
+        // Write your code here
+        int n = str.length();
+
+        int[][] dp = new int[n + 1][n + 1];
+
+        for (int i = 0; i <= n; ++i)
+            for (int j = 0; j <= n; ++j)
+                dp[i][j] = 0;
+     
+        for (int i = 1; i <= n; ++i) {
+            for (int j = 1; j <= n; ++j) {
+                if (str.charAt(i - 1) == str.charAt(j - 1) && i != j)
+                    dp[i][j] = dp[i - 1][j - 1] + 1;                               
+                else
+                    dp[i][j] = Math.max(dp[i][j - 1], dp[i - 1][j]);
+            }
+        }
+        return dp[n][n];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/longest-valid-parentheses.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-valid-parentheses.md"
new file mode 100644
index 0000000..6a412c3
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/longest-valid-parentheses.md"
@@ -0,0 +1,75 @@
+# 最长有效括号
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-valid-parentheses/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 30px;">给出一个只包含</span><code style="font-size: 12.6000003814697px; white-space: normal; line-height: 30px;">'('</code><span style="line-height: 30px;">&nbsp;和</span><code style="font-size: 12.6000003814697px; white-space: normal; line-height: 30px;">')'</code><span style="line-height: 30px;">的字符串，找出其中最长的左右括号正确匹配的合法子串。</span><br></p>
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "(()"
+输出: 2
+解释: 最长有效括号子串为 "()"
+```
+
+**样例 2:**
+
+```
+输入: ")()())"
+输出: 4
+解释: 最长有效括号子串为 "()()"
+```
+ ### 参考代码
+ Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.&nbsp;<div><br></div><div>&nbsp;For "(()", the longest valid parentheses substring is "()", which has length = 2.&nbsp;</div><div><br></div><div>&nbsp;Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.</div><div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博:&nbsp;</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/Bxp24fkup" target="_blank">http://weibo.com/3948019741/Bxp24fkup</a></span></font><br></div>
+
+考点：
+* 栈
+* dp
+
+题解：
+
+1.遍历给字符串中的所有字符
+1.1若当前字符s[index]为左括号'('，将当前字符下标index入栈（下标稍后有其他用处），处理下一字符
+1.2若当前字符s[index]为右括号')'，判断当前栈是否为空
+1.2.1若栈为空，则accumulatedLen = 0，当前有效长度为0，处理下一字符（当前字符右括号下标不入栈）
+1.2.2若栈不为空，则出栈（由于仅左括号入栈，则出栈元素对应的字符一定为左括号，可与当前字符右括号配对），判断栈是否为空
+1.2.2.1若栈为空，则maxlen = max(maxlen, index-start+1)，更新当前最大匹配序列长度
+1.2.2.2若栈不为空，则maxlen = max(maxlen, i-栈顶元素值)，更新当前最大匹配序列长度
+```java
+public class Solution {
+    public int longestValidParentheses(String s) {
+
+        if (s == null) {
+            return 0;
+        }
+
+        Stack<Integer> stack = new Stack<Integer>();
+        int maxLen = 0;
+        int accumulatedLen = 0;
+
+        for(int i = 0; i < s.length(); i++) {
+            if (s.charAt(i) == '(') {
+                stack.push(i);
+            } else {
+                if (stack.isEmpty()) {   //如果栈为空，没有左括号可以匹配
+                    accumulatedLen = 0;
+                } else {
+                    int matchedPos = stack.pop(); //从最近的'('作为起点
+                    int matchedLen = i - matchedPos + 1;	//计算两括号间的长度
+
+                    if (stack.isEmpty()) {			//如果栈为空，没有左括号可以匹配
+                        accumulatedLen += matchedLen;	
+                        matchedLen = accumulatedLen;	//更新当前匹配括号序列长度
+                    } else {
+                        matchedLen = i - stack.peek();  
+                    }
+
+                    maxLen = Math.max(maxLen, matchedLen);
+                }
+            }
+        }
+
+        return maxLen;
+   }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/maximal-rectangle.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximal-rectangle.md"
new file mode 100644
index 0000000..898cc38
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximal-rectangle.md"
@@ -0,0 +1,75 @@
+# 最大矩形
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximal-rectangle/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个二维矩阵，权值为`False`和`True`，找到一个最大的矩形，使得里面的值全部为`True`，输出它的面积
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+[
+  [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]
+]
+输出: 6
+```
+
+**样例2**
+
+```plain
+输入:
+[
+    [0,0],
+    [0,0]
+]
+输出: 0
+```
+
+
+ ### 参考代码
+ 采用算法强化班中讲到的单调栈。
+要做这个题之前先做直方图最大矩阵（Largest Rectangle in Histogram） 这个题。
+这个题其实就是包了一层皮而已。一行一行的计算以当前行为矩阵的下边界时，最大矩阵是什么。
+计算某一行为下边界时的情况，就可以转换为直方图最大矩阵问题了。
+```python
+class Solution:
+    """
+    @param matrix: a boolean 2D matrix
+    @return: an integer
+    """
+    def maximalRectangle(self, matrix):
+        if not matrix:
+            return 0
+            
+        max_rectangle = 0
+        heights = [0] * len(matrix[0])
+        for row in matrix:
+            for index, num in enumerate(row):
+                heights[index] = heights[index] + 1 if num else 0
+            max_rectangle = max(
+                max_rectangle,
+                self.find_max_rectangle(heights),
+            )
+
+        return max_rectangle
+
+    def find_max_rectangle(self, heights):
+        indices_stack = []
+        max_rectangle = 0
+        for index, height in enumerate(heights + [-1]):
+            while indices_stack and heights[indices_stack[-1]] >= height:
+                popped = indices_stack.pop(-1)
+                left_bound = indices_stack[-1] if indices_stack else -1
+                max_rectangle = max(
+                    max_rectangle,
+                    (index - left_bound - 1) * heights[popped],
+                )
+            indices_stack.append(index)
+            print(indices_stack)
+        
+        return max_rectangle
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/maximal-square-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximal-square-ii.md"
new file mode 100644
index 0000000..37a97dd
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximal-square-ii.md"
@@ -0,0 +1,74 @@
+# 最大矩阵II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximal-square-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个只有 `0` 和 `1` 组成的二维矩阵，找出最大的一个子矩阵，使得这个矩阵对角线上全是 `1` ，其他位置全是 `0` .
+ ### 样例说明
+ 例1:
+```
+输入:
+[[1,0,1,0,0],[1,0,0,1,0],[1,1,0,0,1],[1,0,0,1,0]]
+输出:
+9
+解释:
+[0,2]->[2,4]
+```
+
+例2:
+```
+输入:
+[[1,0,1,0,1],[1,0,0,1,1],[1,1,1,1,1],[1,0,0,1,0]]
+输出:
+4
+解释:
+[0,2]->[1,3]
+```
+
+
+ ### 参考代码
+ 动态规划，u和l数组分别代表左边三角形的最大值和上方三角形的最大值，而f代表对角线到此点的最大长度。
+直接三者求最小值转移即可。
+```cpp
+class Solution {
+public:
+    /**
+     * @param matrix a matrix of 0 and 1
+     * @return an integer
+     */
+    int maxSquare2(vector<vector<int>> &matrix) {
+        // write your code here
+        int n = matrix.size();
+        if (n == 0)
+            return 0;
+
+        int m = matrix[0].size();
+        if (m == 0)
+            return 0;
+
+        vector<vector<int>> f(n, vector<int>(m, 0));
+        vector<vector<int>> u(n, vector<int>(m, 0));
+        vector<vector<int>> l(n, vector<int>(m, 0));
+
+        int length = 0;
+        for (int i = 0; i < n; ++i)
+            for (int j = 0; j < m; ++j) {
+                if (matrix[i][j] == 0) {
+                    f[i][j] = 0;
+                    u[i][j] = l[i][j] = 1;
+                    if (i > 0)
+                        u[i][j] = u[i - 1][j] + 1;
+                    if (j > 0)
+                        l[i][j] = l[i][j - 1] + 1;
+                } else {
+                    u[i][j] = l[i][j] = 0;
+                    if (i > 0 && j > 0)
+                        f[i][j] = min(f[i - 1][j - 1], min(u[i - 1][j], l[i][j - 1])) + 1;
+                    else 
+                        f[i][j] = 1;
+                }
+                length = max(length, f[i][j]);
+            }
+        return length * length;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/maximal-square.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximal-square.md"
new file mode 100644
index 0000000..d520112
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximal-square.md"
@@ -0,0 +1,73 @@
+# 最大正方形
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximal-square/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个二维01矩阵中找到全为1的最大正方形, 返回它的面积.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+[
+  [1, 0, 1, 0, 0],
+  [1, 0, 1, 1, 1],
+  [1, 1, 1, 1, 1],
+  [1, 0, 0, 1, 0]
+]
+输出: 4
+```
+
+**样例 2:**
+
+```
+输入: 
+[
+  [0, 0, 0],
+  [1, 1, 1]
+]
+输出: 1
+```
+ ### 参考代码
+ ## 算法：dp
+
+非常经典的dp。我们约定$dp[i][j] $ 代表以（i,j）为右下角最大正方形的边长。
+
+* 设定初始边界状态，$dp[0][i]=dp[i][0]=0$
+*  考虑状态的转移，我们发现，如果$matrix[i][j]=0$，那么此时，以这个点为右下角的最大正方形为0，即形成不了正方形。
+* 若$matrix[i][j]=1$，我们考虑$dp[i-1][j],dp[i][j-1],dp[i-1][j-1]$，三者分别为以（i-1，j）为右下，以（i，j-1）为右下，以（i-1，j-1）为右下的最大正方形边长。
+* 我们取三者的min+1，此时一定为合法的并且包含（i，j）最大的边长。即$dp[i][j] = min{dp[i-1][j-1], dp[i-1][j], dp[i][j-1]} + 1$
+* 最后的$ans=max\{dp[i][j]\}^2$
+
+## 复杂度分析
+
+* 时间复杂度$O(n*m)$
+* 空间复杂度$O(m)$
+```python
+class Solution:
+    """
+    @param matrix: a matrix of 0 and 1
+    @return: an integer
+    """
+    def maxSquare(self, matrix):
+        if not matrix or not matrix[0]:
+            return 0
+            
+        n, m = len(matrix), len(matrix[0])
+        
+        # intialization
+        f = [[0] * m, [0] * m]
+        for i in range(m):
+            f[0][i] = matrix[0][i]
+            
+        edge = max(matrix[0])
+        for i in range(1, n):
+            f[i % 2][0] = matrix[i][0]
+            for j in range(1, m):
+                if matrix[i][j]:
+                    f[i % 2][j] = min(f[(i - 1) % 2][j], f[i % 2][j - 1], f[(i - 1) % 2][j - 1]) + 1
+                else:
+                    f[i % 2][j] = 0
+            edge = max(edge, max(f[i % 2]))
+
+        return edge * edge
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-product-subarray.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-product-subarray.md"
new file mode 100644
index 0000000..2294ad0
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-product-subarray.md"
@@ -0,0 +1,115 @@
+# 乘积最大子序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-product-subarray/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>找出一个序列中乘积最大的连续子序列（至少包含一个数）。</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入:[2,3,-2,4]
+输出:6
+```
+
+**样例 2:**
+```
+输入:[-1,2,4,1]
+输出:8
+```
+ ### 参考代码
+ ## 算法：dp
+比较容易想出来的线性dp。由于数据中有正有负，所以我们利用两个dp数组来完成。用f[i]来保存计算到第i个时的最大值，用g[i]来保持计算到第i个时的最小值。
+- 在得出了第i-1的dp值之后，即包含i-1的可能值区间为[g[i-1],f[i-1]]（左闭右闭区间）。我们考虑第i个数的情况。
+- 若nums[i]为正数，可能值区间为[g[i-1]×nums[i],f[i-1]×nums[i]]，和nums[i]。
+- 若nums[i]为负数，可能值区间为[f[i-1]×nums[i],g[i-1]×nums[i]]，和nums[i]。
+- 所以我们直接根据上述的情况，就能得出包含nums[i]的最大值f[i]=max(max(f[i-1]×nums[i], g[i-1]×nums[i]), nums[i])。同理，g[i]=min(min(f[i-1]*×[i], g[i-1]×nums[i]), nums[i])。
+- 最后由于我们要求的是最大值，直接对f数组取最大值即可。
+
+## 复杂度分析
+* 时间复杂度`O(n)`
+  * 枚举了数组的长度 
+* 空间复杂度`O(n)`
+  * 消耗了等长的空间
+```java
+// LeetCode version:
+public class Solution {
+    /**
+     * @param nums: an array of integers
+     * @return: an integer
+     */
+    public int maxProduct(List<Integer> nums) {
+        int[] max = new int[nums.size()];
+        int[] min = new int[nums.size()];
+        
+        min[0] = max[0] = nums.get(0);
+        int result = nums.get(0);
+        for (int i = 1; i < nums.size(); i++) {
+            min[i] = max[i] = nums.get(i);
+            if (nums.get(i) > 0) {
+                max[i] = Math.max(max[i], max[i - 1] * nums.get(i));
+                min[i] = Math.min(min[i], min[i - 1] * nums.get(i));
+            } else if (nums.get(i) < 0) {
+                max[i] = Math.max(max[i], min[i - 1] * nums.get(i));
+                min[i] = Math.min(min[i], max[i - 1] * nums.get(i));
+            }
+            
+            result = Math.max(result, max[i]);
+        }
+        
+        return result;
+    }
+}
+
+// LintCode Version 1:
+public class Solution {
+    /**
+     * @param nums: an array of integers
+     * @return: an integer
+     */
+    public int maxProduct(int[] nums) {
+        int[] max = new int[nums.length];
+        int[] min = new int[nums.length];
+        
+        min[0] = max[0] = nums[0];
+        int result = nums[0];
+        for (int i = 1; i < nums.length; i++) {
+            min[i] = max[i] = nums[i];
+            if (nums[i] > 0) {
+                max[i] = Math.max(max[i], max[i - 1] * nums[i]);
+                min[i] = Math.min(min[i], min[i - 1] * nums[i]);
+            } else if (nums[i] < 0) {
+                max[i] = Math.max(max[i], min[i - 1] * nums[i]);
+                min[i] = Math.min(min[i], max[i - 1] * nums[i]);
+            }
+            
+            result = Math.max(result, max[i]);
+        }
+        
+        return result;
+    }
+}
+
+//LintCode version2: O(1) Space Complexity
+public class Solution {
+    /**
+     * @param nums: an array of integers
+     * @return: an integer
+     */
+    public int maxProduct(int[] nums) {
+        // write your code here
+        if (nums == null || nums.length == 0) {
+            return 0;
+        }
+        int minPre = nums[0], maxPre = nums[0];
+        int max = nums[0], min = nums[0];
+        int res = nums[0];
+        for (int i = 1; i < nums.length; i ++) {
+            max = Math.max(nums[i], Math.max(maxPre * nums[i], minPre * nums[i]));
+            min = Math.min(nums[i], Math.min(maxPre * nums[i], minPre * nums[i]));
+            res = Math.max(res, max);
+            maxPre = max;
+            minPre = min;
+        }
+        return res;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-difference.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-difference.md"
new file mode 100644
index 0000000..4eafd67
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-difference.md"
@@ -0,0 +1,97 @@
+# 最大子数组差
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-difference/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个整数数组，找出两个<b><font color="#e76363">不重叠</font></b>的子数组A和B，使两个子数组和的差的绝对值<strong style="line-height: 1.42857143; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"><font color="#e76363">|SUM(A) - SUM(B)|</font></strong><span style="line-height: 1.42857143;">最大。</span></p><p>返回这个最大的差值。</p>
+ ### 样例说明
+ 
+例1:
+```
+输入:[1, 2, -3, 1]
+输出:6
+解释:
+子数组是 [1,2] 和[-3].所以答案是 6.
+```
+
+例2:
+```
+输入:[0,-1]
+输出:1
+解释:
+子数组是 [0] 和 [-1].所以答案是 1.
+```
+
+
+
+ ### 参考代码
+ dp。
+维护四个数组，当前位置左边的最大子数组和，最小子数组和。当前位置右边的最大子数组和，最小子数组和。
+然后枚举分割线，扫描一下即可。
+```java
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @return: An integer indicate the value of maximum difference between two
+     *          Subarrays
+     */
+    public int maxDiffSubArrays(int[] nums) {
+        // write your code here
+        int size = nums.length;
+        int[] left_max = new int[size];
+        int[] left_min = new int[size];
+        int[] right_max = new int[size];
+        int[] right_min = new int[size];
+        int[] copy = new int[size];
+        /*Get negative copy*/
+        for(int i = 0; i < size; i++){
+            copy[i] = -1 * nums[i];
+        }
+        int max = Integer.MIN_VALUE;
+        int sum = 0;
+        int minSum = 0;
+        /*Forward: get max subarray*/
+        for(int i = 0; i < size; i++){
+            sum += nums[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            left_max[i] = max;
+        }
+        /*Backward: get max subarray*/
+        max = Integer.MIN_VALUE;
+        sum = 0;
+        minSum = 0;
+        for(int i = size - 1; i >= 0; i--){
+            sum += nums[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            right_max[i] = max;
+        }
+        /*Forward: get min subarray*/
+        max = Integer.MIN_VALUE;
+        sum = 0;
+        minSum = 0;
+        for(int i = 0; i < size; i++){
+            sum += copy[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            left_min[i] = -1 * max;
+        }
+        /*Backward: get min subarray*/
+        max = Integer.MIN_VALUE;
+        sum = 0;
+        minSum = 0;
+        for(int i = size - 1; i >= 0; i--){
+            sum += copy[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            right_min[i] = -1 * max;
+        }
+        int diff = 0;
+        for(int i = 0; i < size - 1; i++){
+            diff = Math.max(diff, Math.abs(left_max[i] - right_min[i + 1]));
+            diff = Math.max(diff, Math.abs(left_min[i] - right_max[i + 1]));
+        }
+        return diff;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-ii.md"
new file mode 100644
index 0000000..3725355
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-ii.md"
@@ -0,0 +1,69 @@
+# 最大子数组 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找出两个 *不重叠* 子数组使得它们的和最大。
+每个子数组的数字在数组中的位置应该是连续的。
+返回最大的和。
+ ### 样例说明
+ 
+例1:
+```
+输入:
+[1, 3, -1, 2, -1, 2]
+输出:
+7
+解释:
+最大的子数组为 [1, 3] 和 [2, -1, 2] 或者 [1, 3, -1, 2] 和 [2].
+```
+
+例2:
+```
+输入:
+[5,4]
+输出:
+9
+解释:
+最大的子数组为 [5] 和 [4].
+```
+
+ ### 参考代码
+ <p style="color: rgb(113, 113, 113); font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"></p><p>这个题的思路是，因为 两个subarray 一定不重叠</p><p><span style="background-color: initial;">所以必定存在一条分割线</span><br></p><p><span style="background-color: initial;">分开这两个 subarrays</span><br></p><p><span style="background-color: initial;">所以 最后的部分里：</span><br></p><p>&nbsp; max = Integer.MIN_VALUE;</p><p>&nbsp; &nbsp; &nbsp; &nbsp; for(int i = 0; i &lt; size - 1; i++){</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; max = Math.max(max, left[i] + right[i + 1]);</p><p>&nbsp; &nbsp; &nbsp; &nbsp; }</p><p>&nbsp; &nbsp; &nbsp; &nbsp; return max;</p><p>这里是在枚举 这条分割线的位置</p><p><span style="background-color: initial;">然后 left[] 和 right[] 里分别存的是，某个位置往左的 maximum subarray 和往右的 maximum subarray</span><br></p><p style="color: rgb(113, 113, 113); font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"></p>
+
+```java
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @return: An integer denotes the sum of max two non-overlapping subarrays
+     */
+    public int maxTwoSubArrays(ArrayList<Integer> nums) {
+        // write your code
+        int size = nums.size();
+        int[] left = new int[size];
+        int[] right = new int[size];
+        int sum = 0;
+        int minSum = 0;
+        int max = Integer.MIN_VALUE;
+        for(int i = 0; i < size; i++){
+            sum += nums.get(i);
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            left[i] = max;
+        }
+        sum = 0;
+        minSum = 0;
+        max = Integer.MIN_VALUE;
+        for(int i = size - 1; i >= 0; i--){
+            sum += nums.get(i);
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            right[i] = max;
+        }
+        max = Integer.MIN_VALUE;
+        for(int i = 0; i < size - 1; i++){
+            max = Math.max(max, left[i] + right[i + 1]);
+        }
+        return max;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-iii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-iii.md"
new file mode 100644
index 0000000..c3fdaed
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-iii.md"
@@ -0,0 +1,113 @@
+# 最大子数组 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组和一个整数 *k*，找出 *k* 个**不重叠**子数组使得它们的和最大。每个子数组的数字在数组中的位置应该是**连续**的。
+
+返回最大的和。
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: 
+List = [1,2,3]
+k = 1
+输出: 6
+说明: 1 + 2 + 3 = 6
+```
+
+**样例2**
+
+```plain
+输入:
+List = [-1,4,-2,3,-2,3]
+k = 2
+输出: 8
+说明: 4 + (3 + -2 + 3) = 8
+```
+
+
+ ### 参考代码
+ DP: an array partition into k parts or k operation (like buy and sell stock)
+Use local max and global max
+$localMax[n][k]$ defines max sum, must have nth element for n and partition into k parts.
+$globalMax[n][k]$ defines max sum, may not have nth element for n and partition into k parts.
+```java
+// 方法一 划分类DP
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @param k: An integer denote to find k non-overlapping subarrays
+     * @return: An integer denote the sum of max k non-overlapping subarrays
+     */
+    public int maxSubArray(int[] nums, int k) {
+        if (nums.length < k) {
+            return 0;
+        }
+        int len = nums.length;
+        
+       
+        int[][] globalMax = new int[k + 1][len + 1];
+        int[][] localMax = new int[k + 1][len + 1];
+        
+        for (int i = 1; i <= k; i++) {
+            localMax[i][i-1] = Integer.MIN_VALUE;
+            //小于 i 的数组不能够partition
+            for (int j = i; j <= len; j++) {
+                localMax[i][j] = Math.max(localMax[i][j-1], globalMax[i - 1][j-1]) + nums[j-1];
+                if (j == i)
+                    globalMax[i][j] = localMax[i][j];
+                else
+                    globalMax[i][j] = Math.max(globalMax[i][j-1], localMax[i][j]);
+            }
+        }
+        return globalMax[k][len];
+    }
+    
+}
+
+
+//方法二
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @param k: An integer denote to find k non-overlapping subarrays
+     * @return: An integer denote the sum of max k non-overlapping subarrays
+     */ 
+    public static int maxSubArray(ArrayList<Integer> nums, int k) {
+        // write your code
+        int len = nums.size();
+        int[][] f = new int[k+1][len];
+        for (int i = 1; i < k+1; i++) {
+            int sum = 0;
+            for (int j = 0; j < i; j++) {
+                sum += nums.get(j);
+            }
+            f[i][i-1] = sum;
+        }
+        for (int i = 1; i < len; i++) {
+        	f[1][i] = Math.max(f[1][i-1]+nums.get(i), nums.get(i));
+        }
+        
+        for (int i = 2; i < k+1; i++) {
+            for (int n = i;  n< len; n++) {
+                int curMax = f[i][n-1] + nums.get(n);
+                for (int j = i-2; j < n; j++) {
+                    if ((f[i-1][j] + nums.get(n)) > curMax) {
+                        curMax = f[i-1][j] + nums.get(n);
+                    }
+                }
+                f[i][n] = curMax;
+            }
+        }
+        
+        int res = Integer.MIN_VALUE;
+        for (int i = k-1; i < len; i++){
+            if (f[k][i] > res) {
+                res = f[k][i];
+            }
+        }
+        return res;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-iv.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-iv.md"
new file mode 100644
index 0000000..227191f
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-iv.md"
@@ -0,0 +1,69 @@
+# 最大子序列的和IV
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-iv/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找到长度大于或等于 `k` 的连续子序列使它们的和最大，返回这个最大的和，如果数组中少于k个元素则返回 `0`
+ ### 样例说明
+ 例1:
+```
+输入:
+[-2,2,-3,4,-1,2,1,-5,3]
+5
+输出:
+5
+解释:
+[2,-3,4,-1,2,1]
+sum=5
+```
+
+例2:
+```
+输入:
+[5,-10,4]
+2
+输出:
+-1
+```
+
+
+ ### 参考代码
+ 一维dp即可。
+维护一个前缀和。
+再维护一个前缀合法最小和，
+转移方程如下：
+ result = Math.max(result, sum[i] - min_prefix)
+min_prefix = Math.min(min_prefix, sum[i - k + 1])
+```java
+public class Solution {
+    /**
+     * @param nums an array of integers
+     * @param k an integer
+     * @return the largest sum
+     */
+    public int maxSubarray4(int[] nums, int k) {
+        // Write your code here
+        int n = nums.length;
+        if (n < k)
+            return 0;
+
+        int result = 0;
+        for (int i = 0; i < k; ++i)
+            result += nums[i];
+
+        int[] sum = new int[n + 1];
+        sum[0] = 0;
+        
+        int min_prefix = 0;
+        for (int i = 1; i <= n; ++i) {
+            sum[i] = sum[i - 1] + nums[i - 1];
+            if (i >= k && sum[i] - min_prefix > result) {
+                result = Math.max(result, sum[i] - min_prefix);
+            }
+            if (i >= k) {
+                min_prefix = Math.min(min_prefix, sum[i - k + 1]);
+            }
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-v.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-v.md"
new file mode 100644
index 0000000..aaf70e8
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray-v.md"
@@ -0,0 +1,74 @@
+# 最大子数组 V
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-v/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找到长度在 `k1` 与 `k2` 之间(包括 k1, k2)的子数组并且使它们的和最大，返回这个最大值，如果数组元素个数小于 k1 则返回 0
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+[-2,2,-3,4,-1,2,1,-5,3]
+2
+4
+输出:
+6
+
+解释:
+连续子数组为 `[4,-1,2,1]` 时有最大和 `6`
+```
+
+**样例 2:**
+```
+输入:
+[1,1,2,3]
+5
+10
+输出:
+0
+```
+ ### 参考代码
+ 滑动窗口系列题，deque维护子数组，每一次窗口滑动则：前缀和 - 队头，最后得出最大值。
+```java
+public class Solution {
+    /**
+     * @param nums an array of integers
+     * @param k1 an integer
+     * @param k2 an integer
+     * @return the largest sum
+     */
+    public int maxSubarray5(int[] nums, int k1, int k2) {
+        // Write your code here
+        int n = nums.length;
+        if (n < k1)
+            return 0;
+
+        int result = Integer.MIN_VALUE;
+
+        int[] sum = new int[n + 1];
+        sum[0] = 0;
+        LinkedList<Integer> queue = new LinkedList<Integer>();
+
+        for (int i = 1; i <= n; ++i) {
+            sum[i] = sum[i - 1] + nums[i - 1];
+
+            if (!queue.isEmpty() && queue.getFirst() < i - k2) {
+                queue.removeFirst();
+            }
+            if (i >= k1) {
+                while (!queue.isEmpty() && sum[queue.getLast()] > sum[i - k1]) {
+                    queue.removeLast();
+                }
+                queue.add(i - k1);
+            }
+
+            // [i - k2, i - k1]
+            if (!queue.isEmpty() && sum[i] - sum[queue.getFirst()] > result) {
+                result = Math.max(result, sum[i] - sum[queue.getFirst()]);
+            }
+
+
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray.md"
new file mode 100644
index 0000000..9a42d39
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/maximum-subarray.md"
@@ -0,0 +1,41 @@
+# 最大子数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找到一个具有最大和的子数组，返回其最大和。
+ ### 样例说明
+ **样例1:**
+
+```
+输入：[−2,2,−3,4,−1,2,1,−5,3]
+输出：6
+解释：符合要求的子数组为[4,−1,2,1]，其最大和为 6。
+```
+
+**样例2:**
+
+```
+输入：[1,2,3,4]
+输出：10
+解释：符合要求的子数组为[1,2,3,4]，其最大和为 10。
+```
+ ### 参考代码
+ 使用前缀和的方法，计算每个位置为结尾的 subarray 的最大值是多少。
+```python
+class Solution:
+    """
+    @param nums: A list of integers
+    @return: A integer indicate the sum of max subarray
+    """
+    def maxSubArray(self, nums):
+        #prefix_sum记录前i个数的和，max_Sum记录全局最大值，min_Sum记录前i个数中0-k的最小值
+        min_sum, max_sum = 0, -sys.maxsize
+        prefix_sum = 0
+        
+        for num in nums:
+            prefix_sum += num
+            max_sum = max(max_sum, prefix_sum - min_sum)
+            min_sum = min(min_sum, prefix_sum)
+            
+        return max_sum
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-adjustment-cost.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-adjustment-cost.md"
new file mode 100644
index 0000000..5aba795
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-adjustment-cost.md"
@@ -0,0 +1,72 @@
+# 最小调整代价
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-adjustment-cost/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给一个整数数组，调整每个数的大小，使得相邻的两个数的差不大于一个给定的整数target，调整每个数的代价为调整前后的差的绝对值，求调整代价之和最小是多少。</p>
+ ### 样例说明
+ ```
+样例 1:
+	输入:  [1,4,2,3], target=1
+  输出:  2
+
+样例 2:
+	输入:  [3,5,4,7], target=2
+	输出:  1
+	
+```
+ ### 参考代码
+ f[i][k] 表示第i个数变成k时，前i个数调整的代价和最小值。
+枚举第i-1个数调整成的数字j，再枚举第i个数调整成k.做转移。
+```
+[[python]]
+class Solution:
+    # @param A: An integer array.
+    # @param target: An integer.
+    def MinAdjustmentCost(self, A, target):
+        # write your code here
+        f = [[ sys.maxint for j in xrange(101)] for i in xrange(len(A)+1)]
+        for i in xrange(101):
+            f[0][i] = 0
+        n = len(A)
+        for i in xrange(1,n+1):
+            for j in xrange(101):
+                if f[i-1][j] != sys.maxint:
+                    for k in xrange(101):
+                        if abs(j-k) <= target:
+                            f[i][k] = min(f[i][k], f[i-1][j] + abs(A[i-1]-k))
+        ans = f[n][100]
+        for i in xrange(101):
+            if f[n][i] < ans:
+                ans = f[n][i]       
+
+        return ans
+[[java]]
+public class Solution {
+    /**
+     * @param A: An integer array.
+     * @param target: An integer.
+     */
+    public int MinAdjustmentCost(ArrayList<Integer> A, int target) {
+        // write your code here
+        int n = A.size();
+        int[][] f = new int[n + 1][101];
+        for (int i = 0; i <= n ; ++i)
+            for (int j = 0; j <=100; ++j)
+                f[i][j] = Integer.MAX_VALUE;
+        for (int i = 0; i <= 100; ++i)
+            f[0][i] = 0;
+        for (int i = 1; i <=n; ++i)
+            for (int  j = 0; j <= 100;++j)
+                if (f[i-1][j] != Integer.MAX_VALUE)
+                for (int k = 0; k <= 100; ++k)
+                    if (Math.abs(j-k) <= target)
+                    if (f[i][k] > f[i-1][j] + Math.abs(A.get(i-1)-k))
+                        f[i][k] = f[i-1][j] + Math.abs(A.get(i-1)-k);  
+        int ans = Integer.MAX_VALUE;
+        for (int i = 0; i <= 100; ++i)
+            if (f[n][i] < ans)
+                ans = f[n][i];
+        return ans; 
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-cost-to-merge-stones.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-cost-to-merge-stones.md"
new file mode 100644
index 0000000..b1982ab
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-cost-to-merge-stones.md"
@@ -0,0 +1,102 @@
+# 合并石头的最低成本
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-cost-to-merge-stones/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有 N 堆石头排成一排，第 i 堆中有 stones[i] 块石头。
+
+每次移动（move）需要将连续的 K 堆石头合并为一堆，而这个移动的成本为这 K 堆石头的总数。
+
+找出把所有石头合并成一堆的最低成本。如果不可能，返回 -1 。
+ ### 样例说明
+ 示例 1：
+```
+输入：stones = [3,2,4,1], K = 2
+输出：20
+解释：
+从 [3, 2, 4, 1] 开始。
+合并 [3, 2]，成本为 5，剩下 [5, 4, 1]。
+合并 [4, 1]，成本为 5，剩下 [5, 5]。
+合并 [5, 5]，成本为 10，剩下 [10]。
+总成本 20，这是可能的最小值。
+```
+示例 2：
+```
+输入：stones = [3,2,4,1], K = 3
+输出：-1
+解释：任何合并操作后，都会剩下 2 堆，我们无法再进行合并。所以这项任务是不可能完成的。
+```
+ ### 参考代码
+ 用记忆化搜索实现的 DP。
+`dp[i][j][k]` 代表从 i 合并到 j，最后剩下 k 堆的最小耗费。
+最后答案是 `dp[0][n - 1][1]`。特别的，`dp[i][j][1] = dp[i][j][k] + sum[i][j]`
+```java
+class Solution {
+    public int mergeStones(int[] stones, int K) {
+        int n = stones.length;
+        int[][][] memo = new int[n][n][K + 1];
+        int[][] rangeSum = getRangeSum(stones);
+        
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < n; j++) {
+                for (int k = 1; k <= K; k++) {
+                    memo[i][j][k] = Integer.MAX_VALUE;
+                }
+            }
+        }
+        return memoSearch(rangeSum, 0, n - 1, 1, K, memo);
+    }
+    
+    private int memoSearch(int[][] rangeSum, int left, int right, int k, int K, int[][][] memo) {
+        if (memo[left][right][k] != Integer.MAX_VALUE) {
+            return memo[left][right][k];
+        }
+        
+        if (left == right) {
+            if (k == 1) {
+                return 0;
+            }
+            return -1;
+        }
+        
+        if (k == 1) {
+            int result = memoSearch(rangeSum, left, right, K, K, memo);
+            if (result == -1) {
+                return -1;
+            }
+            return result + rangeSum[left][right];
+        }
+        
+        int minimum = Integer.MAX_VALUE;
+        for (int i = left; i <= right - k + 1; i++) {
+            int first_part = memoSearch(rangeSum, left, i, 1, K, memo);
+            int rest_parts = memoSearch(rangeSum, i + 1, right, k - 1, K, memo);
+            if (first_part == -1 || rest_parts == -1) {
+                continue;
+            }
+            minimum = Math.min(minimum, first_part + rest_parts);
+        }
+        
+        if (minimum == Integer.MAX_VALUE) {
+            minimum = -1;
+        }
+        memo[left][right][k] = minimum;
+        return minimum;
+    }
+    
+    private int[][] getRangeSum(int[] stones) {
+        int[][] rangeSum = new int[stones.length][stones.length];
+        
+        for (int i = 0; i < stones.length; i++) {
+            rangeSum[i][i] = stones[i];
+        }
+        
+        for (int i = stones.length - 1; i >= 0; i--) {
+            for (int j = i + 1; j < stones.length; j++) {
+                rangeSum[i][j] = rangeSum[i][j - 1] + stones[j];
+            }
+        }
+
+        return rangeSum;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-falling-path-sum.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-falling-path-sum.md"
new file mode 100644
index 0000000..60aaa83
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-falling-path-sum.md"
@@ -0,0 +1,90 @@
+# 下降路径最小和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-falling-path-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个**方形**整数数组 A，我们想要得到通过 A 的下降路径的**最小**和。
+
+下降路径可以从第一行中的任何元素开始，并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列。
+ ### 样例说明
+ **样例：**
+
+```
+输入：[[1,2,3],[4,5,6],[7,8,9]]
+输出：12
+解释：
+可能的下降路径有：
+[1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9]
+
+[2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9]
+
+[3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9]
+
+和最小的下降路径是 [1,4,7]，所以答案是 12。
+```
+ ### 参考代码
+ ```
+[[python]]
+class Solution:
+    """
+    @param A: the given array
+    @return: the minimum sum of a falling path
+    """
+    def minFallingPathSum(self, A):
+        n, m = len(A), len(A[0])
+        # state: dp[i][j] 表示从第一行走到 i,j 这个位置的最小路径和
+        dp = [[0] * m, [0] * m]
+        
+        # initialization: dp[0][i] = A[0][i]
+        for i in range(m):
+            dp[0][i] = A[0][i]
+        
+        # function: dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i - 1][j + 1]) + A[i][j]
+        for i in range(1, n):
+            for j in range(0, m):
+                dp[i % 2][j] = dp[(i - 1) % 2][j] + A[i][j]
+                if j - 1 >= 0:
+                    dp[i % 2][j] = min(dp[i % 2][j], dp[(i - 1) % 2][j - 1] + A[i][j])
+                if j + 1 < len(A[0]):
+                    dp[i % 2][j] = min(dp[i % 2][j], dp[(i - 1) % 2][j + 1] + A[i][j]) 
+        
+        # answer
+        return min(dp[(n - 1) % 2])
+[[java]]
+public class Solution {
+    /**
+     * @param A: the given array
+     * @return: the minimum sum of a falling path
+     */
+    public int minFallingPathSum(int[][] A) {
+        int n = A.length, m = A[0].length;
+        // state: dp[i][j] 表示从第一行走到 i,j 这个位置的最小路径和
+        int[][] dp = new int[2][m];
+        
+        // initialization: dp[0][i] = A[0][i]
+        for (int i = 0; i < m; i++) {
+            dp[0][i] = A[0][i];
+        }
+        
+        // function: dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i - 1][j + 1]) + A[i][j]
+        for (int i = 1; i < n; i++) {
+            for (int j = 0; j < m; j++) {
+                dp[i % 2][j] = dp[(i - 1) % 2][j] + A[i][j];
+                if (j - 1 >= 0) {
+                    dp[i % 2][j] = Math.min(dp[i % 2][j], dp[(i - 1) % 2][j - 1] + A[i][j]);
+                }
+                    
+                if (j + 1 < A[0].length) {
+                    dp[i % 2][j] = Math.min(dp[i % 2][j], dp[(i - 1) % 2][j + 1] + A[i][j]);
+                }
+            }
+        }
+            
+        // answer
+        int answer = Integer.MAX_VALUE;
+        for (int i = 0; i < m; i++) {
+            answer = Math.min(answer, dp[(n - 1) % 2][i]);
+        }
+        return answer;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-path-sum.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-path-sum.md"
new file mode 100644
index 0000000..fc47e9f
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/minimum-path-sum.md"
@@ -0,0 +1,47 @@
+# 最小路径和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-path-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">给定一个只含非负整数的m*n网格，找到一条从左上角到右下角的可以使数字和最小的路径。</span><br></p><p><br></p>
+ ### 样例说明
+ ```
+样例 1:
+	输入:  [[1,3,1],[1,5,1],[4,2,1]]
+	输出: 7
+	
+	样例解释：
+	路线为： 1 -> 3 -> 1 -> 1 -> 1。
+
+
+样例 2:
+	输入:  [[1,3,2]]
+	输出:  6
+	
+	解释:  
+	路线是： 1 -> 3 -> 2
+
+```
+ ### 参考代码
+ Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
+
+Note: You can only move either down or right at any point in time.
+
+Dp[i][j] 存储从（0， 0） 到（i, j）的最短路径。
+Dp[i][j] = min(Dp[i-1][j]), Dp[i][j-1]) + grid[i][j];
+```python
+class Solution:
+    """
+    @param grid: a list of lists of integers.
+    @return: An integer, minimizes the sum of all numbers along its path
+    """
+    def minPathSum(self, grid):
+        for i in range(len(grid)):
+            for j in range(len(grid[0])):
+                if i == 0 and j > 0:
+                    grid[i][j] += grid[i][j-1]
+                elif j == 0 and i > 0:
+                    grid[i][j] += grid[i-1][j]
+                elif i > 0 and j > 0:
+                    grid[i][j] += min(grid[i-1][j], grid[i][j-1])
+        return grid[len(grid) - 1][len(grid[0]) - 1]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/modern-ludo-i.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/modern-ludo-i.md"
new file mode 100644
index 0000000..f093966
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/modern-ludo-i.md"
@@ -0,0 +1,116 @@
+# 飞行棋 I
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/modern-ludo-i/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有一个一维的棋盘，起点在棋盘的最左侧，终点在棋盘的最右侧，棋盘上有几个位置是跟其他的位置相连的，即如果A与B相连，则当棋子落在位置A时, 你可以选择是否不投骰子，直接移动棋子从A到B。并且这个连接是单向的，即不能从B移动到A，现在给定这个棋盘的长度`length`和位置的相连情况`connections`，你有一个六面的骰子(点数1-6)，最少需要丢几次才能到达终点。
+ ### 样例说明
+ **样例1**
+
+```
+输入: length = 10 和 connections = [[2, 10]]
+输出: 1
+解释: 
+1->2 (投骰子)
+2->10(直接相连)
+```
+
+**样例2**
+
+```
+输入: length = 15 和 connections = [[2, 8],[6, 9]]
+输出: 2
+解释: 
+1->6 (投骰子)
+6->9 (直接相连)
+9->15(投骰子)
+```
+
+ ### 参考代码
+ 两个队列交替
+```
+[[python]]
+class Solution:
+    def modernLudo(self, length, connections):
+        graph = self.build_graph(length, connections)
+        
+        queue = [1]
+        distance = {1: 0}
+        while queue:
+            next_queue = []
+            for node in queue:
+                for direct_node in graph[node]:
+                    if direct_node in distance:
+                        continue
+                    distance[direct_node] = distance[node]
+                    queue.append(direct_node)
+            for node in queue:
+                for next_node in range(node + 1, min(node + 7, length + 1)):
+                    if next_node in distance:
+                        continue
+                    distance[next_node] = distance[node] + 1
+                    next_queue.append(next_node)
+            queue = next_queue
+                
+        return distance[length]
+
+    def build_graph(self, length, connections):
+        graph = {
+            i: set()
+            for i in range(1, length + 1)
+        }
+        for a, b in connections:
+            graph[a].add(b)
+        return graph
+[[java]]
+public class Solution {
+    public int modernLudo(int length, int[][] connections) {
+        Map<Integer, Set<Integer>> graph = buildGraph(length, connections);
+        
+        List<Integer> queue = new ArrayList<>();
+        queue.add(1);
+        Map<Integer, Integer> distance = new HashMap<>();
+        distance.put(1, 0);
+        
+        while (!queue.isEmpty()) {
+            List<Integer> nextQueue = new ArrayList<>();
+            for (int i = 0; i < queue.size(); i++) {
+                int node = queue.get(i);
+                for (int directNode: graph.get(node)) {
+                    if (distance.containsKey(directNode)) {
+                        continue;
+                    }
+                    distance.put(directNode, distance.get(node));
+                    queue.add(directNode);
+                }
+            }
+            for (int i = 0; i < queue.size(); i++) {
+                int node = queue.get(i);
+                int limit = Math.min(node + 7, length + 1);
+                for (int nextNode = node + 1; nextNode < limit; nextNode++) {
+                    if (distance.containsKey(nextNode)) {
+                        continue;
+                    }
+                    distance.put(nextNode, distance.get(node) + 1);
+                    nextQueue.add(nextNode);
+                }
+            }
+            queue = nextQueue;
+        }
+        
+        return distance.get(length);
+    }
+    
+    private Map<Integer, Set<Integer>> buildGraph(int length, int[][] connections) {
+        Map<Integer, Set<Integer>> graph = new HashMap<>();
+        for (int i = 1; i <= length; i++) {
+            graph.put(i, new HashSet<>());
+        }
+        for (int i = 0; i < connections.length; i++) {
+            int from = connections[i][0];
+            int to = connections[i][1];
+            graph.get(from).add(to);
+        }
+        return graph;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/non-negative-integers-without-consecutive-ones.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/non-negative-integers-without-consecutive-ones.md"
new file mode 100644
index 0000000..ecc0c91
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/non-negative-integers-without-consecutive-ones.md"
@@ -0,0 +1,77 @@
+# 不包括连续1的非负整数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/non-negative-integers-without-consecutive-ones/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定正整数n，找到小于或等于n的**非负**整数的个数，要求它们的二进制表示不包含**连续的1**。
+ ### 样例说明
+ **样例 1:**
+```
+输入：5
+输出：5
+解释：
+以下是非负整数<= 5及其对应的二进制表示：
+0：0
+1：1
+2：10
+3：11
+4：100
+5：101
+其中，只有整数3违反规则（两个连续的1），另外5个满足规则。
+```
+
+
+
+**样例 2:**
+```
+输入：6
+输出：5
+解释：
+以下是非负整数<= 6及其对应的二进制表示：
+0 : 0
+1 : 1
+2 : 10
+3 : 11
+4 : 100
+5 : 101
+6 : 110
+其中，只有整数3和6违反规则（两个连续的1），另外5个满足规则。
+```
+ ### 参考代码
+ 考点：
+* dp
+
+题解：
+* 数字n转化为01字符串,从前向后遍历，f[i]表示当前i为'1'时，i位其右侧01串排列的合法方案。
+* f[i] = f[i - 1] + f[i - 2]，此处求出i位的右侧的01串排列的合法方案，可以由i - 1时尾部加上一个'0'转移到i，可以由i - 2时尾部加上'01'转移到i。
+* 从高位向低位遍历，每次遇到为'1'的位时，加上f[i]即可，遇到连续两个'1'时，返回即可。
+```java
+public class Solution {
+    public int findIntegers(int num) {
+        if (num < 2) {
+            return num + 1;
+        }
+        
+        StringBuilder str = new StringBuilder(Integer.toBinaryString(num)).reverse();
+        int k = str.length();
+        
+        int[] f = new int[k];
+        f[0] = 1;
+        f[1] = 2;
+        for (int i = 2; i < k; i++) {   //f[i]表示当前i为'1'时，i位其右侧01串排列的合法方案。
+            f[i] = f[i - 1] + f[i - 2];	//f[i] = f[i - 1] + f[i - 2]，此处求出i位的右侧的01串排列的合法方案，可以由i - 1时尾部加上一个'0'转移到i，可以由i - 2时尾部加上'01'转移到i。
+        }
+        
+        int ans = 0;
+        for (int i = k - 1; i >= 0; i--) {
+            if (str.charAt(i) == '1') {
+                ans += f[i];			//每次遇到为'1'的位时，加上f[i]即可
+                if (i < k - 1 && str.charAt(i + 1) == '1') {
+                    return ans;
+                }
+            }
+        }
+        ans++;		//加上自身数字
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/palindrome-partitioning-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/palindrome-partitioning-ii.md"
new file mode 100644
index 0000000..4604f63
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/palindrome-partitioning-ii.md"
@@ -0,0 +1,74 @@
+# 分割回文串 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/palindrome-partitioning-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定字符串 `s`, 需要将它分割成一些子串, 使得每个子串都是回文串.
+
+最少需要分割几次?
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "a"
+输出: 0
+解释: "a" 本身就是回文串, 无需分割
+```
+
+**样例 2:**
+
+```
+输入: "aab"
+输出: 1
+解释: 将 "aab" 分割一次, 得到 "aa" 和 "b", 它们都是回文串.
+```
+ ### 参考代码
+ 与 [136. 分割回文串](https://www.lintcode.com/problem/palindrome-partitioning/description?_from=ladder&&fromId=80) 不同, 这道题目不需要求所有方案, 而是求最小次数 -- 最优解问题.
+
+可以看作序列型动态规划问题, 设定 dp[i] 表示原串的前 i 个字符最少分割多少次可以使得到的都是回文子串.
+
+如果 s 前 i 个字符组成的子串本身就是回文串, 则 dp[i] = 0, 否则:
+
+```C++
+dp[i] = min{dp[j] + 1} (j < i 并且 s[j + 1], s[j + 2], ... , s[i] 是回文串)
+```
+
+如果想要是 O($n^2$) 的时间复杂度 (n 是 s 的长度), 需要事先求出来回文串信息, 在状态转移时可以 O(1) 地知道一段子串是否回文的.
+```cpp
+class Solution {
+public:
+    /**
+     * @param s a string
+     * @return an integer
+     */
+    int minCut(string s) {
+        int n = s.length();
+        int f[n + 1];
+        vector<vector<bool>> isPalin(n, vector<bool>(n, false));
+
+        for (int i = 0; i < n; i++) {
+            isPalin[i][i] = true;
+            if (i + 1 < n) {
+                isPalin[i][i + 1] = (s[i] == s[i + 1]);
+            }
+        }
+
+        for (int i = n - 1; i >= 0; i--) {
+            for (int j = i + 2; j < n; j++) {
+                isPalin[i][j] = isPalin[i + 1][j - 1] && (s[i] == s[j]);
+            }
+        }
+
+        f[0] = -1;
+        for (int i = 1; i <= n; i++) {
+            f[i] = i - 1;
+            for (int j = 0; j < i; j++) {
+                if (isPalin[j][i - 1]) {
+                    f[i] = min(f[i], f[j] + 1);
+                }
+            }
+        }
+
+        return f[n];
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/partition-equal-subset-sum.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/partition-equal-subset-sum.md"
new file mode 100644
index 0000000..a7e99a8
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/partition-equal-subset-sum.md"
@@ -0,0 +1,47 @@
+# 划分和相等的子集
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/partition-equal-subset-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一 `只含有正整数` 的 `非空` 数组, 找到这个数组是否可以划分为 `两个` 元素和相等的子集。
+ ### 样例说明
+ 例1:
+```
+输入: nums = [1, 5, 11, 5], 
+输出: true
+解释:
+two subsets: [1, 5, 5], [11]
+```
+例2:
+```
+输入: nums = [1, 2, 3, 9], 
+输出: false
+```
+
+ ### 参考代码
+ 等价与背包问题，能否背到总价值的一半。
+01背包即可。
+```java
+public class Solution {
+    public boolean canPartition(int[] nums) {
+        int len = nums.length;
+        int sum = 0;
+        for(int i = 0; i < len ; i++ ){
+            sum += nums[i];
+        }
+        if(sum % 2 == 1){
+            return false;
+        }
+        sum /= 2;
+        boolean [] dp = new boolean[20000];
+        for(int i = 0; i <=sum ; i ++)
+            dp[i] = false;
+        dp[0] = true;
+        for(int i = 0; i < len; i++){
+            for(int j= sum ; j >= nums[i]; j--){
+                dp[j] |= dp[j - nums[i]];
+            }
+        }
+        return dp[sum];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/perfect-squares.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/perfect-squares.md"
new file mode 100644
index 0000000..2457e73
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/perfect-squares.md"
@@ -0,0 +1,129 @@
+# 完美平方
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/perfect-squares/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个正整数 n, 请问最少多少个完全平方数(比如1, 4, 9...)的和等于n。
+
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 12
+输出: 3
+解释: 4 + 4 + 4
+```
+
+**样例 2:**
+
+```
+输入: 13
+输出: 2
+解释: 4 + 9
+```
+ ### 参考代码
+ # 做法1:
+## 算法：dp
+我们用f[i]表示i最少能被几个完全平方数来表示。
+- 首先我们对dp数组赋予初值，对于每个完全平方数的f=1。
+- 利用记忆化搜索来完成查找。对于i，我们考虑i的前继状态，也就是哪几个状态可以加上一个完全平方数抵达i。
+- 对于所有能够抵达i的状态，取他们的最小值+1即可。
+
+上述过程的状态转移方程为 f[i] = min{f[i], f\[i - j \* j] + 1} (j\*j <= i)
+
+边界: f\[i\*i] = 1
+
+## 复杂度分析
+* 时间复杂度`O(n)`
+  * 枚举了数组的长度
+* 空间复杂度`O(n^(3/2))`
+  * 对于每个数，它的前继状态都有sqrt(i)个，i为这个数的大小。
+  * 所以总的复杂度为sqrt(1)+sqrt(2)+....sqrt(n)约等于O(n^(3/2))
+  * 证明过程太复杂，就不在此给出。
+    
+
+---
+
+# 做法2:
+##算法：数学做法
+涉及[四平方和定理](https://zh.wikipedia.org/wiki/%E5%9B%9B%E5%B9%B3%E6%96%B9%E5%92%8C%E5%AE%9A%E7%90%86)
+参考 <http://www.cnblogs.com/grandyang/p/4800552.html>
+根据四平方和定理，我们可以发现，一个数能被四个数之内的平方和表示。
+* 我们直接循环，判断这个数能否被1~到3个数的平方和表示即可，若不行，直接输出4
+
+## 复杂度分析
+* 时间复杂度`O(n)`
+  * 两重循环的上限为sqrt(n)，相乘即可。
+* 空间复杂度`O(1)`
+  * 消耗了常数的空间
+```java
+///////////////// version 0 DP
+public class Solution {
+    /**
+     * @param n a positive integer
+     * @return an integer
+     */
+    public int numSquares(int n) {
+        // Write your code here
+        int[] dp = new int[n + 1];
+        Arrays.fill(dp, Integer.MAX_VALUE);
+        for (int i = 0; i * i <= n; ++i) {
+            dp[i * i] = 1;
+        }
+
+        for (int i = 0; i <= n; ++i) {
+            for (int j = 1; j * j <= i; ++j) {
+                dp[i] = Math.min(dp[i], dp[i - j * j] + 1);
+            }
+        }
+
+        return dp[n];
+    }
+}
+
+////////////////// version 1 DP 
+public class Solution {
+    /**
+     * @param n a positive integer
+     * @return an integer
+     */
+    public int numSquares(int n) {
+        int[] dp = new int[n + 1];
+        Arrays.fill(dp, Integer.MAX_VALUE);
+        for(int i = 0; i * i <= n; ++i)
+            dp[i * i] = 1;
+
+        for (int i = 0; i <= n; ++i)
+            for (int j = 0; i + j * j <= n; ++j)
+                dp[i + j * j] = Math.min(dp[i] + 1, dp[i + j * j]);
+
+        return dp[n];
+    }
+}
+
+//////////////// version 2  Math
+public class Solution {
+    /**
+     * @param n a positive integer
+     * @return an integer
+     */
+    public int numSquares(int n) {
+        while (n % 4 == 0)
+            n /= 4;
+        if (n % 8 == 7)
+            return 4;
+        for (int i = 0; i * i <= n; ++i) {
+            int j = (int)Math.sqrt(n * 1.0 - i * i);
+            if (i * i + j * j == n) {
+                int res = 0;
+                if (i > 0)
+                    res += 1;
+                if (j > 0)
+                    res += 1;
+                return res;
+            }
+        }
+        return 3;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/post-office-problem.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/post-office-problem.md"
new file mode 100644
index 0000000..5adb7dd
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/post-office-problem.md"
@@ -0,0 +1,150 @@
+# 邮局问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/post-office-problem/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一条直线上有 `n` 个房子, 给定数组 `A`, `A[i]` 表示第 `i` 栋房子的位置. 现在需要选择 `k` 个位置建立邮局. 问这 `n` 栋房子到最近邮局的距离总和最小是多少?
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: A = [1, 2, 3, 4, 5], k = 2
+输出: 3
+解释: 在 2 和 4 建立邮局.
+```
+
+**样例 2:**
+
+```
+输入: A = [1, 2], k = 1
+输出: 1
+解释: 在 1 或 2 建立邮局都可以.
+```
+ ### 参考代码
+ 线性动态规划 (而不是区间动态规划) 
+
+可以按照每个房子最近的邮局, 把 `n` 个房子分成 `k` 段, 而我们要决定的就是这 `k` 段分别是多长. 为了处理方便我们先对房子的位置排序.
+
+设定 f[i][j] 表示前 j 栋房子建立 i 个邮局时的最优解. 对于这个状态我们需要决策的就是 j 之前有多少栋房子共用第 i 个邮局, 故有:
+
+```C++
+f[i][j] = min{f[i - 1][j - x] + sumdis[j - x][j - 1]}
+其中 sumdis[l][r] 表示下标范围为 [l, r] 的房子之间建立一个邮局, 这些房子与该邮局的最短距离
+(注意f[i][j]中的j表示的第j栋房子从1计数, sumdis从0计数)
+```
+
+sumdis数组可以实现预处理出来, 具体算法与中位数的性质有关. 即对于 sumdis[l][r], 直接选择这 r - l + 1 栋房子中, 中间的那一栋建立邮局(如果是偶数栋, 中间的两栋任选一栋), 这时这些房子与邮局的距离之和是最短的.
+
+至于dp的边界: f[i][0] = 0, f[0][j] = INF, 以及 i >= j 时 f[i][j] = 0
+
+另外, 这样的状态定义可以用滚动数组优化空间.
+```cpp
+class Solution {
+public:
+    /**
+     * @param A: an integer array
+     * @param k: An integer
+     * @return: an integer
+     */
+    int postOffice(vector<int> &A, int k) {
+        int n = A.size();
+        if (n <= k) {
+            return 0;
+        }
+        
+        vector<vector<int>> f(k + 1, vector<int>(n + 1, 0x3f3f3f3f));
+        vector<vector<int>> sumdis(n, vector<int>(n, 0));
+        
+        sort(A.begin(), A.end());
+        
+        for (int i = 0; i < n; i++) {
+            for (int j = i; j < n; j++) {
+                int pos = A[(i + j) / 2];
+                for (int k = i; k <= j; k++) {
+                    sumdis[i][j] += abs(A[k] - pos);
+                }
+            }
+        }
+        
+        for (int i = 0; i <= k; i++) {
+            for (int j = 0; j <= i; j++) {
+                f[i][j] = 0;
+            }
+        }
+        
+        for (int i = 1; i <= k; i++) {
+            for (int j = i + 1; j <= n; j++) {
+                for (int x = 1; x <= j; x++) {
+                    f[i][j] = min(f[i][j], f[i - 1][j - x] + sumdis[j - x][j - 1]);
+                }
+            }
+        }
+        
+        return f[k][n];
+    }
+};
+
+class Solution {
+public:
+    /**
+     * @param A an integer array
+     * @param k an integer
+     * @return an integer
+     */
+    int N, P;
+    int f[1500][1500], w[1500][1500], a[1500], K[1500][1500];
+	vector<int> tmp;
+    void init() {
+        int n = tmp.size();
+        a[0] = 0;
+        for (int i = 1; i <= n; i ++) {
+            a[i] = a[i - 1] + tmp[i-1];
+        }
+    }
+
+    int getw(int x, int y)  {
+        int t = (x + y) / 2;
+        return a[y] - a[t] - (y - t) * tmp[t - 1] + (t - x) * tmp[t - 1] - (a[t - 1] - a[x - 1]);
+    }
+
+    void solve(int N, int P) {
+        for (int i = 0; i <= N; i ++) {
+            f[i][i] = 0;
+            K[i][i] = i;
+        }
+		int j;
+        for (int p = 1; p <= N - P; p ++) {
+            for (int i = 0; (j  = i + p) <= N; i ++)
+                f[i][j] = 0x7fffffff / 3;
+            int t;
+            for (int i = 1; (j = i + p) <= N; i ++) {
+                for (int k = K[i][j - 1]; k <= K[i + 1][j]; k ++)
+                    if ((t = f[i - 1][k - 1] + getw(k, j)) < f[i][j]) {
+                        f[i][j] = t;
+                        K[i][j] = k;
+                    }
+            }
+        }
+    }
+
+    void getAns(int k, int r, vector<int>& ret) {
+        if ( k == 0 || r <= 0)
+            return;
+        int p = K[k][r];
+        getAns(k - 1, p - 1, ret);
+        ret.push_back(tmp[(p + r) / 2 - 1]);
+    }
+
+    int postOffice(vector<int>& A, int k) {
+        // Write your code here
+        sort(A.begin(), A.end());
+		tmp = A;
+        int n = A.size();
+        init();
+        solve(n, k);
+
+        vector<int> result;
+        getAns(k, n, result);
+        return f[k][n];
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/profitable-schemes.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/profitable-schemes.md"
new file mode 100644
index 0000000..4cec328
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/profitable-schemes.md"
@@ -0,0 +1,201 @@
+# 盈利计划
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/profitable-schemes/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 帮派里有 G 名成员，他们可能犯下各种各样的罪行。
+
+第 `i` 种犯罪会产生 `profit[i]` 的利润，它要求 `group[i]` 名成员共同参与。
+
+让我们把这些犯罪的任何子集称为盈利计划，该计划至少产生 `P` 的利润。
+
+有多少种方案可以选择？因为答案很大，所以返回它模 `10^9 + 7` 的值。
+ ### 样例说明
+ **示例 1：**
+```
+输入：G = 5, P = 3, group = [2,2], profit = [2,3]
+输出：2
+解释： 
+至少产生 3 的利润，该帮派可以犯下罪 0 和罪 1 ，或仅犯下罪 1 。
+总的来说，有两种方案。
+```
+
+**示例 2:**
+```
+输入：G = 10, P = 5, group = [2,3,5], profit = [6,7,8]
+输出：7
+解释：
+至少产生 5 的利润，只要他们犯其中一种罪就行，所以该帮派可以犯下任何罪行 。
+有 7 种可能的计划：(0)，(1)，(2)，(0,1)，(0,2)，(1,2)，以及 (0,1,2) 。
+```
+ ### 参考代码
+ `dp[i][j][k]` 表示前 i 个 crimes 里，用刚好 j 个人，获得至少 k 的盈利，有多少方案的解法
+```
+[[python]]
+class Solution:
+    """
+    @param G: The people in a gang.
+    @param P: A profitable scheme any subset of these crimes that generates at least P profit.
+    @param group: The i-th crime requires group[i] gang members to participate.
+    @param profit: The i-th crime generates a profit[i].
+    @return: Return how many schemes can be chosen.
+    """
+    def profitableSchemes(self, G, P, group, profit):
+        n = len(group)
+        
+        # state: dp[i][j][k] 前 i 个 crimes 里，用刚好 j 个人，获得至少 k 的盈利，有多少方案
+        dp = [
+            [
+                [0] * (P + 1)
+                for _ in range(G + 1)
+            ]
+            for __ in range(2)
+        ]
+
+        # initialization: 前 0 个 crimes 里，用刚好 0 个人，至少获得 0 的盈利，方案数是1
+        dp[0][0][0] = 1
+            
+        # function:
+        # dp[i][j][k] = dp[i - 1][j][k] // 不执行 crimes[i - 1] 的情况
+        #             + dp[i - 1][j - group[i - 1]][k - profile[i - 1]] // 执行 crimes[i - 1]
+        # 当 k - profile[i - 1] < 0 的时候，直接让这个值 = 0
+        for i in range(1, n + 1):
+            for j in range(G + 1):
+                for k in range(P + 1):
+                    dp[i % 2][j][k] = dp[(i - 1) % 2][j][k]
+                    if j >= group[i - 1]:
+                        prev_k = max(k - profit[i - 1], 0)
+                        dp[i % 2][j][k] += dp[(i - 1) % 2][j - group[i - 1]][prev_k]
+        
+        # answer: sum(dp[n][0..G][P]) 把所有不同的人数能够获得的盈利加起来
+        total = 0
+        for g in range(G + 1):
+            total += dp[n % 2][g][P]
+        return total
+[[java]]
+public class Solution {
+    /**
+     * @param G: The people in a gang.
+     * @param P: A profitable scheme any subset of these crimes that generates at least P profit.
+     * @param group: The i-th crime requires group[i] gang members to participate.
+     * @param profit: The i-th crime generates a profit[i].
+     * @return: Return how many schemes can be chosen.
+     */
+    public int profitableSchemes(int G, int P, int[] group, int[] profit) {
+        int n = group.length;
+        
+        // state: dp[i][j][k] 前 i 个 crimes 里，用刚好 j 个人，获得至少 k 的盈利，有多少方案
+        int[][][] dp = new int[2][G + 1][P + 1];
+        
+        // initialization: 前 0 个 crimes 里，用刚好 0 个人，至少获得 0 的盈利，方案数是1
+        dp[0][0][0] = 1;
+        
+        // function:
+        // dp[i][j][k] = dp[i - 1][j][k] // 不执行 crimes[i - 1] 的情况
+        //             + dp[i - 1][j - group[i - 1]][k - profile[i - 1]] // 执行 crimes[i - 1]
+        // 当 k - profile[i - 1] < 0 的时候，直接让这个值 = 0
+        for (int i = 1; i <= n; i++) {
+            for (int j = 0; j <= G; j++) {
+                for (int k = 0; k <= P; k++) {
+                    dp[i % 2][j][k] = dp[(i - 1) % 2][j][k];
+                    if (j >= group[i - 1]) {
+                        int prevK = Math.max(k - profit[i - 1], 0);
+                        dp[i % 2][j][k] += dp[(i - 1) % 2][j - group[i - 1]][prevK];
+                    }
+                }
+            }
+        }
+           
+        // answer: sum(dp[n][0..G][P]) 把所有不同的人数能够获得的盈利加起来
+        int total = 0;
+        for (int g = 0; g <= G; g++) {
+            total += dp[n % 2][g][P];
+        }
+            
+        return total;
+    }
+}
+```
+`dp[i][j][k]` 表示前 i 个 crimes 里，用小于等于 j 个人，获得至少 k 的盈利，有多少方案的解法
+```
+[[python]]
+class Solution:
+    """
+    @param G: The people in a gang.
+    @param P: A profitable scheme any subset of these crimes that generates at least P profit.
+    @param group: The i-th crime requires group[i] gang members to participate.
+    @param profit: The i-th crime generates a profit[i].
+    @return: Return how many schemes can be chosen.
+    """
+    def profitableSchemes(self, G, P, group, profit):
+        n = len(group)
+        
+        # state: dp[i][j][k] 前 i 个 crimes 里，用小于等于 j 个人，获得至少 k 的盈利，有多少方案
+        dp = [
+            [
+                [0] * (P + 1)
+                for _ in range(G + 1)
+            ]
+            for __ in range(2)
+        ]
+
+        # initialization: 前 0 个 crimes 里，用小于等于 i 个人，至少获得 0 的盈利，方案数是1
+        for i in range(G + 1):
+            dp[0][i][0] = 1
+            
+        # function:
+        # dp[i][j][k] = dp[i - 1][j][k] // 不执行 crimes[i - 1] 的情况
+        #             + dp[i - 1][j - group[i - 1]][k - profile[i - 1]] // 执行 crimes[i - 1]
+        # 当 k - profile[i - 1] < 0 的时候，直接让这个值 = 0
+        for i in range(1, n + 1):
+            for j in range(G + 1):
+                for k in range(P + 1):
+                    dp[i % 2][j][k] = dp[(i - 1) % 2][j][k]
+                    if j >= group[i - 1]:
+                        prev_k = max(k - profit[i - 1], 0)
+                        dp[i % 2][j][k] += dp[(i - 1) % 2][j - group[i - 1]][prev_k]
+        
+        # answer: dp[n][G][P] 前 n 个crimes 里，用小于等于 G 个人，获得至少 P 的盈利，有多少方案
+        return dp[n % 2][G][P]
+[[java]]
+public class Solution {
+    /**
+     * @param G: The people in a gang.
+     * @param P: A profitable scheme any subset of these crimes that generates at least P profit.
+     * @param group: The i-th crime requires group[i] gang members to participate.
+     * @param profit: The i-th crime generates a profit[i].
+     * @return: Return how many schemes can be chosen.
+     */
+    public int profitableSchemes(int G, int P, int[] group, int[] profit) {
+        int n = group.length;
+        
+        // state: dp[i][j][k] 前 i 个 crimes 里，用刚好 j 个人，获得至少 k 的盈利，有多少方案
+        int[][][] dp = new int[2][G + 1][P + 1];
+        
+        // initialization: 前 0 个 crimes 里，用小于等于 i 个人，至少获得 0 的盈利，方案数是1
+        for (int i = 0; i <= G; i++) {
+            dp[0][i][0] = 1;
+        }
+        
+        // function:
+        // dp[i][j][k] = dp[i - 1][j][k] // 不执行 crimes[i - 1] 的情况
+        //             + dp[i - 1][j - group[i - 1]][k - profile[i - 1]] // 执行 crimes[i - 1]
+        // 当 k - profile[i - 1] < 0 的时候，直接让这个值 = 0
+        for (int i = 1; i <= n; i++) {
+            for (int j = 0; j <= G; j++) {
+                for (int k = 0; k <= P; k++) {
+                    dp[i % 2][j][k] = dp[(i - 1) % 2][j][k];
+                    if (j >= group[i - 1]) {
+                        int prevK = Math.max(k - profit[i - 1], 0);
+                        dp[i % 2][j][k] += dp[(i - 1) % 2][j - group[i - 1]][prevK];
+                    }
+                }
+            }
+        }
+           
+        // answer: dp[n][G][P] 前 n 个crimes 里，用小于等于 G 个人，获得至少 P 的盈利，有多少方案
+        return dp[n % 2][G][P];
+    }
+}
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/range-sum-query-2d-immutable.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/range-sum-query-2d-immutable.md"
new file mode 100644
index 0000000..f4cfca5
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/range-sum-query-2d-immutable.md"
@@ -0,0 +1,88 @@
+# 平面范围求和 -不可变矩阵
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/range-sum-query-2d-immutable/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一 二维矩阵,计算由左上角 `(row1, col1)` 和右下角 `(row2, col2)` 划定的矩形内元素和.
+ ### 样例说明
+ **样例1**
+```
+输入：
+[[3,0,1,4,2],[5,6,3,2,1],[1,2,0,1,5],[4,1,0,1,7],[1,0,3,0,5]]
+sumRegion(2, 1, 4, 3)
+sumRegion(1, 1, 2, 2)
+sumRegion(1, 2, 2, 4)
+输出：
+8
+11
+12
+解释：
+给出矩阵
+[
+  [3, 0, 1, 4, 2],
+  [5, 6, 3, 2, 1],
+  [1, 2, 0, 1, 5],
+  [4, 1, 0, 1, 7],
+  [1, 0, 3, 0, 5]
+]
+sumRegion(2, 1, 4, 3) = 2 + 0 + 1 + 1 + 0 + 1 + 0 + 3 + 0 = 8
+sumRegion(1, 1, 2, 2) = 6 + 3 + 2 + 0 = 11
+sumRegion(1, 2, 2, 4) = 3 + 2 + 1 + 0 + 1 + 5 = 12
+```
+**样例2**
+```
+输入：
+[[3,0],[5,6]]
+sumRegion(0, 0, 0, 1)
+sumRegion(0, 0, 1, 1)
+输出：
+3
+14
+解释：
+给出矩阵
+[
+  [3, 0],
+  [5, 6]
+]
+sumRegion(0, 0, 0, 1) = 3 + 0 = 3
+sumRegion(0, 0, 1, 1) = 3 + 0 + 5 + 6 = 14
+```
+ ### 参考代码
+ 不妨设$dp[i][j]$表示$(0,0)$到$(i,j)$的子矩阵和。
+转移方程为：$dp[i][j]=dp[i][j-1]+dp[i][j-1]-dp[i][j]+a[i][j]$
+对于$(row_1,col_1)$到$(row_2,col_2)$的子矩阵和答案为：$dp[row_2+1][col_2+1]-dp[row_1][col_2+1]-dp[row_2+1][col_1]+dp[row_1][col_1]$
+```python
+class NumMatrix(object):
+
+    # @param {int[][]} matrix a 2D matrix
+    def __init__(self, matrix):
+        # Write your code here
+
+        if len(matrix) == 0 or len(matrix[0]) == 0:
+            return 
+        
+        n = len(matrix)
+        m = len(matrix[0])
+        
+        self.dp  = [[0] * (m + 1) for _ in range(n + 1)]
+        for r in range(n):
+            for c in range(m):
+                self.dp[r + 1][c + 1] = self.dp[r + 1][c] + self.dp[r][c + 1] + \
+                    matrix[r][c] - self.dp[r][c]
+
+        
+    # @param {int} row1 an integer
+    # @param {int} col1 an integer
+    # @param {int} row2 an integer
+    # @param {int} row2 an integer
+    # @return {int} the sum of region
+    def sumRegion(self, row1, col1, row2, col2):
+        # Write your code here
+        return self.dp[row2 + 1][col2 + 1] - self.dp[row1][col2 + 1] - \
+            self.dp[row2 + 1][col1] + self.dp[row1][col1]
+        
+
+
+# Your NumMatrix object will be instantiated and called as such:
+# obj = NumMatrix(matrix)
+# param_1 = obj.sumRegion(row1,col1,row2,col2)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/regular-expression-matching.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/regular-expression-matching.md"
new file mode 100644
index 0000000..06d7a69
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/regular-expression-matching.md"
@@ -0,0 +1,101 @@
+# 正则表达式匹配
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/regular-expression-matching/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>实现支持<b><font color="#e76363">'.'</font></b>和<b><font color="#e76363">'*'</font></b>的<span style="line-height: 1.42857143;">正则表达式</span><span style="line-height: 1.42857143;">匹配。</span></p><p>'.'匹配任意一个字母。</p><p>'*'匹配零个或者多个前面的元素。</p><p>匹配应该覆盖整个输入字符串，而不仅仅是一部分。</p><p>需要实现的函数是：bool isMatch(string s, string p)</p>
+<p>isMatch("aa","a") → false</p><p>isMatch("aa","aa") → true</p><p>isMatch("aaa","aa") → false</p><p>isMatch("aa", "a*") → true</p><p>isMatch("aa", ".*") → true</p><p>isMatch("ab", ".*") → true</p><p>isMatch("aab", "c*a*b") →  true</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入："aa"，"a"
+输出：false
+解释：
+无法匹配
+```
+
+**样例 2:**
+```
+输入："aa"，"a*"
+输出：true
+解释：
+'*' 可以重复 a
+```
+
+ ### 参考代码
+ 和 Wildcard Matching 同样模板的代码。
+使用了记忆化搜索（Memoization Search）
+
+考点：
+* 记忆化搜索|| dp
+
+题解：
+* 采用数组memo记录各处字符匹配情况，dfs递归进行搜索，记忆化剪枝
+* 当前p串中有* ，就有两种选择，然后* 可以不去匹配，直接用p串的下一个匹配当前s串字符，或者重复p串的上一个字符匹配。
+* .可以匹配任意字符
+```java
+public class Solution {
+    /**
+     * @param s: A string 
+     * @param p: A string includes "." and "*"
+     * @return: A boolean
+     */
+    public boolean isMatch(String s, String p) {
+        if (s == null || p == null) {
+            return false;
+        }
+        
+        boolean[][] memo = new boolean[s.length()][p.length()];			//记忆搜索结果
+        boolean[][] visited = new boolean[s.length()][p.length()];		//标记是否访问
+        
+        return isMatchHelper(s, 0, p, 0, memo, visited);
+    }
+    
+    private boolean isMatchHelper(String s, int sIndex,
+                                  String p, int pIndex,
+                                  boolean[][] memo,
+                                  boolean[][] visited) {
+        // "" == ""
+        if (pIndex == p.length()) {       //如果p已经匹配完毕
+            return sIndex == s.length();	//根据s是否匹配完毕即可
+        }
+        
+        if (sIndex == s.length()) {		//如果s匹配完毕
+            return isEmpty(p, pIndex);
+        }
+        
+        if (visited[sIndex][pIndex]) {
+            return memo[sIndex][pIndex];
+        }
+        
+        char sChar = s.charAt(sIndex);
+        char pChar = p.charAt(pIndex);
+        boolean match;
+        
+        // consider a* as a bundle
+        if (pIndex + 1 < p.length() && p.charAt(pIndex + 1) == '*') {    	 //如果为'*'，有两种方案
+            match = isMatchHelper(s, sIndex, p, pIndex + 2, memo, visited) ||                //'*'不去匹配字符
+                charMatch(sChar, pChar) && isMatchHelper(s, sIndex + 1, p, pIndex, memo, visited);  //'*'重复前面一个字符去匹配s
+        } else {
+            match = charMatch(sChar, pChar) && 		//如果当前两字符匹配
+                isMatchHelper(s, sIndex + 1, p, pIndex + 1, memo, visited); //继续下一个字符匹配
+        }
+        
+        visited[sIndex][pIndex] = true;    //搜索完成就标记
+        memo[sIndex][pIndex] = match;     //存储搜索结果
+        return match;
+    }
+    
+    private boolean charMatch(char sChar, char pChar) {		//判断两字符是否匹配
+        return sChar == pChar || pChar == '.';
+    }
+    
+    private boolean isEmpty(String p, int pIndex) {    //形如"x*x*"形式
+        for (int i = pIndex; i < p.length(); i += 2) {
+            if (i + 1 >= p.length() || p.charAt(i + 1) != '*') {   //如果不是'*'，无法匹配
+                return false;
+            }
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/russian-doll-envelopes.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/russian-doll-envelopes.md"
new file mode 100644
index 0000000..98bfc33
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/russian-doll-envelopes.md"
@@ -0,0 +1,63 @@
+# 俄罗斯套娃信封
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/russian-doll-envelopes/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一定数量的信封，带有整数对 `(w, h)` 分别代表信封宽度和高度。一个信封的宽高均大于另一个信封时可以放下另一个信封。
+求最大的信封嵌套层数。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[[5,4],[6,4],[6,7],[2,3]]
+输出：3
+解释：
+最大的信封嵌套层数是 3 ([2,3] => [5,4] => [6,7])。
+```
+
+**样例 2:**
+```
+输入：[[4,5],[4,6],[6,7],[2,3],[1,1]]
+输出：4
+解释：
+最大的信封嵌套层数是 4 ([1,1] => [2,3] => [4,5] / [4,6] => [6,7])。
+```
+ ### 参考代码
+ 考点：
+* 贪心
+* dp
+
+题解：
+* 信封存在两个维度，首先贪心按照其中一个维度将信封排序，一个维然后在另度上面寻找最长上升子序列。
+* 此处使用二分优化最长上升子序列，在dp数组中二分查找envelope[1]的位置，当envelope[1]超出范围时会返回-（maxlength+1）需要特殊处理，dp[index] = envelope[1]，当返回的位置为最后为len时，说明插入位置为len，则长度可以+1。
+```java
+public class Solution {
+    /**
+     * @param envelopes a number of envelopes with widths and heights
+     * @return the maximum number of envelopes
+     */
+    public int maxEnvelopes(int[][] envelopes) {
+        // Write your code here
+        if(envelopes == null || envelopes.length == 0 
+            || envelopes[0] == null || envelopes[0].length != 2)
+            return 0;
+        Arrays.sort(envelopes, new Comparator<int[]>(){
+            public int compare(int[] arr1, int[] arr2){
+                if(arr1[0] == arr2[0])
+                    return arr2[1] - arr1[1];
+                else
+                    return arr1[0] - arr2[0];
+            } 
+        });
+        int dp[] = new int[envelopes.length];
+        int len = 0;
+        for(int[] envelope : envelopes){
+            int index = Arrays.binarySearch(dp, 0, len, envelope[1]);
+                if(index < 0)
+                    index = -index - 1;
+            dp[index] = envelope[1];
+            if (index == len)
+                len++;
+        }
+        return len;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/scramble-string.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/scramble-string.md"
new file mode 100644
index 0000000..7af808f
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/scramble-string.md"
@@ -0,0 +1,115 @@
+# 攀爬字符串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/scramble-string/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串 `s1`, 将其递归地分割成两个非空子字符串, 然后可以得到一棵二叉树.
+
+下面是 `s1 = "great"` 可能得到的一棵二叉树: 
+
+```txt
+      great
+     /    \
+    gr    eat
+   / \    /  \
+  g   r  e   at
+             / \
+            a   t
+```
+
+在攀爬字符串的过程中, 我们可以选择其中任意一个非叶节点, 交换该节点的两个子节点.
+
+例如，我们选择了 `"gr"` 节点, 并将该节点的两个子节点进行交换, 并且将祖先节点对应的子串部分也交换, 最终得到了 `"rgeat"`. 我们认为 `"rgeat"` 是 `"great"` 的一个攀爬字符串.
+
+```txt
+      rgeat
+     /    \
+    rg    eat
+   / \    /  \
+  r   g  e   at
+             / \
+            a   t
+```
+
+类似地, 如果我们继续将其节点 `"eat"` 和 `"at"` 的子节点交换, 又可以得到 `"great"` 的一个攀爬字符串 `"rgtae"`.
+
+```txt
+     rgtae
+     /    \
+    rg    tae
+   / \    /  \
+  r   g  ta   e
+         / \
+        t   a
+```
+
+给定两个相同长度的字符串 `s1` 和 `s2`，判断 `s2` 是否为 `s1` 的攀爬字符串.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: s1 = "great", s2 = "rgeat"
+输出: true
+解释: 如同上面描述的.
+```
+
+**样例 2:**
+
+```
+输入: s1 = "a", s2 = "b"
+输出: false
+```
+ ### 参考代码
+ 如果组成 s1 和 s2 的每种字符的数量不同, 可以直接判定为 `false`, 例如样例2的 "a" 和 "b". 以及两个字符串长度不相同也可以直接返回 `false`.
+
+这道题目的重点实际上是找到构造二叉树的方式. 二叉树的构造决定了 `s1` 的哪些部分可以交换位置来得到新的字符串. 下面提供了多个版本算法的代码, 这里只介绍动态规划的思路:
+
+设定状态: `f[l1][r1][l2][r2]` 表示是否可以由 `s1` 的[l1, r1]的子串攀爬得到 `s2` 的[l2, r2]的子串. 决策便是从哪里分割 `s1`, 所以我们枚举分割的点, 于是达到了子问题.
+
+不过需要注意的是, 由于二叉树的子节点可以被交换, 所以 `s2` 可能是被交换过的, 所以完整的状态转移方程是:
+
+```C++
+// 枚举k, 表示从 s1的 [l1, r1] 的第k个字符后分割, 只要有其中一种分割可以得到 s2 即可, 因此是在枚举的 k 中取 或运算
+f[l1][r1][l2][r2] = OR (f[l1][l1 + k - 1][l2][l2 + k - 1] && f[l1 + k][r1][l2 + k][r2]) // 该节点的两个子节点没有交换过
+                    OR (f[l1][l1 + k - 1][r2 - k + 1][r2] && f[l1 + k][r1][l2][r2 - k]) // 该节点的两个子节点交换过
+```
+
+边界状态即: `f[l1][l1][l2][l2] = (s1[l1] == s2[l2])`
+
+注意到 r1 - l1 == r2 - l2, 所以这个四维数组可以被优化掉一维.
+```python
+class Solution:
+    def isScramble(self, s1, s2):
+        n = len(s1)
+        # f[i][j][k] 表示 s1[i : i + k] 攀爬能否得到 s2[j : j + k]
+        f = [[[False] * (n + 1) for _ in range(n)] for _ in range(n)]
+        for i in range(n):
+            for j in range(n):
+                f[i][j][1] = s1[i] == s2[j]
+        for k in range(2, n + 1):
+            for i in range(0, n - k + 1):
+                for j in range(0, n - k + 1):
+                    for t in range(1, k):
+                        if f[i][j][t] and f[i + t][j + t][k - t]:
+                            f[i][j][k] = True
+                            break
+                        if f[i][j + k - t][t] and f[i + t][j][k - t]:
+                            f[i][j][k] = True
+                            break
+        return f[0][0][n]
+        
+class Solution:
+    def isScramble(self, s1, s2):
+        if len(s1) != len(s2):
+            return False
+        if s1 == s2:
+            return True
+        if sorted(list(s1)) != sorted(list(s2)):
+            return False
+        length = len(s1)
+        for i in range(1, length):
+            if self.isScramble(s1[:i], s2[:i]) and self.isScramble(s1[i:], s2[i:]):
+                return True
+            if self.isScramble(s1[:i], s2[length-i:]) and self.isScramble(s1[i:], s2[:length-i]):
+                return True
+        return False
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/stone-game-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/stone-game-ii.md"
new file mode 100644
index 0000000..6af6e62
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/stone-game-ii.md"
@@ -0,0 +1,63 @@
+# 石头游戏 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/stone-game-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有一个石头游戏。在游戏的开始的时候，玩家在 `圈` 中挑选了n堆石头。
+目标是按照下面的规则将石头合并成一堆：
+
+在游戏中的每一步，玩家可以合并两堆相邻的石头为新的一堆石头。分数就是新的石头堆的石头个数。你需要找到最小的总分。
+ ### 样例说明
+ 例1：
+```
+输入：
+[1,1,4,4]
+输出：18
+解释：
+合并第二个和第三个=> [2,4,4]，得分+2
+2.合并前两个=> [6,4]，得分+6
+3.合并最后两个=> [10]，得分+10
+```
+
+例2：
+```
+输入：
+[1,1,1,1]
+输出：8
+解释：
+合并第一个和第二个=> [2,1,1]，得分+2
+2.合并后两个=> [2,2]，得分+2
+3.合并最后两个=> [4]，得分+4
+```
+ ### 参考代码
+ 动态规划。
+dp[i][j]代表从i合并到j的最少花费。
+转移方程为dp[i][j] = min（dp[i][k] + dp[k+1][j] + sum[j + 1] - sum[i]）
+```python
+class Solution:
+    # @param {int[]} A an integer array
+    # @return {int} an integer
+    def stoneGame2(self, A):
+        # Write your code here
+        n = len(A)
+        if n <= 1:
+            return 0
+
+        s = [0]
+        dp = [[sys.maxint for i in xrange(2 * n)] for j in xrange(2 * n)]
+        for i in xrange(2 * n):
+            s.append(s[-1] + A[i % n])
+            dp[i][i] = 0
+
+        for l in xrange(2, 2 * n + 1):
+            for i in xrange(2 * n):
+                j = i + l - 1
+                if j >= 2 * n:
+                    continue
+                for k in xrange(i, j):
+                    dp[i][j] = min(dp[i][k] + dp[k+1][j] + s[j + 1] - s[i], dp[i][j])
+
+        ans = sys.maxint
+        for i in xrange(n):
+            ans = min(ans, dp[i][i + n - 1])
+        return ans
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/stone-game.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/stone-game.md"
new file mode 100644
index 0000000..ef20955
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/stone-game.md"
@@ -0,0 +1,75 @@
+# 石子归并
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/stone-game/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有一个石子归并的游戏。最开始的时候，有n堆石子排成一列，目标是要将所有的石子合并成一堆。合并规则如下：
+
+1. 每一次可以合并相邻位置的两堆石子
+2. 每次合并的代价为所合并的两堆石子的重量之和
+
+求出最小的合并代价。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [3, 4, 3]
+输出: 17
+```
+
+**样例 2:**
+
+```
+输入: [4, 1, 1, 4]
+输出: 18
+解释: 
+  1. 合并第二堆和第三堆 => [4, 2, 4], score = 2
+  2. 合并前两堆 => [6, 4]，score = 8
+  3. 合并剩余的两堆 => [10], score = 18
+```
+ ### 参考代码
+ 使用四边形不等式优化之后的算法，时间复杂度 $O(n^2)$
+记录 cut[i][j] 代表使得 dp[i][j] 获得最优值的那个划分方案（切割位置）
+可以证明（证明太长就不写了） `cut[i][j - 1] <= cut[i][j] <= cut[i + 1][j]`
+```python
+class Solution:
+    """
+    @param A: An integer array
+    @return: An integer
+    """
+    def stoneGame(self, A):
+        n = len(A)
+        if n < 2:
+            return 0
+            
+        # dp[i][j] => minimum cost merge from i to j
+        dp = [[0] * n for _ in range(n)]
+        # cut[i][j] => the best middle point that make dp[i][j] has the minimum cost
+        cut = [[0] * n for _ in range(n)]
+        # range_sum[i][j] => A[i] + A[i + 1] ... + A[j]
+        range_sum = self.get_range_sum(A)
+        
+        for i in range(n - 1):
+            dp[i][i + 1] = A[i] + A[i + 1]
+            cut[i][i + 1] = i
+            
+        # enumerate the range size first, start point second
+        for length in range(3, n + 1):
+            for i in range(n - length + 1):
+                j = i + length - 1
+                dp[i][j] = sys.maxsize
+                for mid in range(cut[i][j - 1], cut[i + 1][j] + 1):
+                    if dp[i][j] > dp[i][mid] + dp[mid + 1][j] + range_sum[i][j]:
+                        dp[i][j] = dp[i][mid] + dp[mid + 1][j] + range_sum[i][j]
+                        cut[i][j] = mid
+        
+        return dp[0][n - 1]
+                    
+    def get_range_sum(self, A):
+        n = len(A)
+        range_sum = [[0] * n for _ in range(len(A))]
+        for i in range(n):
+            range_sum[i][i] = A[i]
+            for j in range(i + 1, n):
+                range_sum[i][j] = range_sum[i][j - 1] + A[j]
+        return range_sum
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/traveling-salesman-problem.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/traveling-salesman-problem.md"
new file mode 100644
index 0000000..aba3fb9
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/traveling-salesman-problem.md"
@@ -0,0 +1,45 @@
+# 旅行商问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/traveling-salesman-problem/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给 `n` 个城市(从 `1` 到 `n`)，城市和无向道路`成本`之间的关系为3元组 `[A, B, C]`（在城市 `A` 和城市 `B` 之间有一条路，成本是 `C`）我们需要从1开始找到的旅行所有城市的付出最小的成本。
+ ### 样例说明
+ 
+ ### 参考代码
+ 如果要保证正确性的最优做法。状态压缩动态规划。
+```python
+class Solution:
+    """
+    @param n: an integer,denote the number of cities
+    @param roads: a list of three-tuples,denote the road between cities
+    @return: return the minimum cost to travel all cities
+    """
+    def minCost(self, n, roads):
+        graph = self.construct_graph(roads, n)
+        state_size = 1 << n
+        f = [
+            [float('inf')] * (n + 1)
+            for _ in range(state_size)
+        ]
+        f[1][1] = 0
+        for state in range(state_size):
+            for i in range(2, n + 1):
+                if state & (1 << (i - 1)) == 0:
+                    continue
+                prev_state = state ^ (1 << (i - 1))
+                for j in range(1, n + 1):
+                    if prev_state & (1 << (j - 1)) == 0:
+                        continue
+                    f[state][i] = min(f[state][i], f[prev_state][j] + graph[j][i])
+        return min(f[state_size - 1])
+        
+    def construct_graph(self, roads, n):
+        graph = {
+            i: {j: float('inf') for j in range(1, n + 1)}
+            for i in range(1, n + 1)
+        }
+        for a, b, c in roads:
+            graph[a][b] = min(graph[a][b], c)
+            graph[b][a] = min(graph[b][a], c)
+        return graph
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/unique-paths-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/unique-paths-ii.md"
new file mode 100644
index 0000000..088180e
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/unique-paths-ii.md"
@@ -0,0 +1,189 @@
+# 不同的路径 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/unique-paths-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ "[不同的路径](http://www.lintcode.com/problem/unique-paths/ "不同的路径")" 的跟进问题：
+
+现在考虑网格中有障碍物，那样将会有多少条不同的路径？
+
+网格中的障碍和空位置分别用 1 和 0 来表示。
+ ### 样例说明
+ 
+ ### 参考代码
+ Follow up for "Unique Paths":
+
+Now consider if some obstacles are added to the grids. How many unique paths would there be?
+
+An obstacle and empty space is marked as 1 and 0 respectively in the grid.
+
+For example,
+There is one obstacle in the middle of a 3x3 grid as illustrated below.
+
+[
+  [0,0,0],
+  [0,1,0],
+  [0,0,0]
+]
+The total number of unique paths is 2.
+
+Note: m and n will be at most 100.
+
+Dp[i][j]表示从开始到（i，j）位置的路径数， Dp[i][j] = Dp[i-1][j] + Dp[i][j-1]
+如果对应位置为 1，则是障碍，Dp[i][j] = 0;
+```java
+public class Solution {
+    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
+        if (obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0) {
+            return 0;
+        }
+        
+        int n = obstacleGrid.length;
+        int m = obstacleGrid[0].length;
+        int[][] paths = new int[n][m];
+        
+        for (int i = 0; i < n; i++) {
+            if (obstacleGrid[i][0] != 1) {
+                paths[i][0] = 1;
+            } else {
+                break;
+            }
+        }
+        
+        for (int i = 0; i < m; i++) {
+            if (obstacleGrid[0][i] != 1) {
+                paths[0][i] = 1; 
+            } else {
+                break;
+            }
+        }
+        
+        for (int i = 1; i < n; i++) {
+            for (int j = 1; j < m; j++) {
+                if (obstacleGrid[i][j] != 1) {
+                    paths[i][j] = paths[i - 1][j] + paths[i][j - 1];
+                } else {
+                    paths[i][j] = 0;
+                }
+            }
+        }
+        
+        return paths[n - 1][m - 1];
+    }
+}
+
+// 方法二
+public class Solution {
+    /**
+     * @param obstacleGrid: A list of lists of integers
+     * @return: An integer
+     */
+    public int uniquePathsWithObstacles(int[][] A) {
+        int m = A.length;
+        if (m == 0) {
+            return 0;
+        }
+        int n = A[0].length;
+        if (n == 0) {
+            return 0;
+        }
+        
+        if (A[0][0] == 1 || A[m-1][n-1] == 1) {
+            return 0;
+        }
+        
+        int[][] f = new int[2][n];
+        int i, j, old, now;
+        now = 0;
+
+        for (i = 0; i < m; ++i) {
+            old = now;
+            now = 1 - now;
+            for (j = 0; j < n; ++j) {
+                f[now][j] = 0;
+                if (A[i][j] == 1) {
+                    f[now][j] = 0;
+                }
+                else {
+                    if (i == 0 && j == 0) {
+                        f[now][j] = 1;
+                    }
+                    if (i > 0) {
+                        f[now][j] += f[old][j];
+                    }
+                    if (j > 0) {
+                        f[now][j] += f[now][j-1];
+                    }
+                }
+            }
+        }
+        
+        return f[now][n-1];
+    }
+}
+
+
+// 记忆化搜索
+// 九章硅谷求职算法集训营版本
+public class Solution {
+    /**
+     * @param obstacleGrid: A list of lists of integers
+     * @return: An integer
+     */
+     
+    int[][] f;
+    int[][] A;
+    int m;
+    int n;
+    
+    void calc(int i, int j) {
+        if (f[i][j] != -1) {
+            return;
+        }
+        
+        if (A[i][j] == 1) {
+            f[i][j] = 0;
+            return;
+        }
+        
+        if (i == 0 && j == 0) {
+            f[i][j] = 1;
+            return;
+        }
+        
+        f[i][j] = 0;
+        if (i > 0) {
+            calc(i - 1, j);
+            f[i][j] += f[i - 1][j];
+        }
+        
+        if (j > 0) {
+            calc(i, j - 1);
+            f[i][j] += f[i][j - 1];
+        }
+    }
+    
+    public int uniquePathsWithObstacles(int[][] AA) {
+        A = AA;
+        m = A.length;
+        if (m == 0) {
+            return 0;
+        }
+        
+        n = A[0].length;
+        if (n == 0) {
+            return 0;
+        }
+        
+        int i, j;
+        f = new int[m][n];
+        for (i = 0; i < m; ++i) {
+            for (j = 0; j < n; ++j) {
+                f[i][j] = -1;
+            }
+        }
+    
+        calc(m - 1, n - 1);
+        return f[m - 1][n - 1];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/unique-paths.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/unique-paths.md"
new file mode 100644
index 0000000..d12b807
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/unique-paths.md"
@@ -0,0 +1,80 @@
+# 不同的路径
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/unique-paths/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有一个机器人的位于一个 *m* × *n* 个网格左上角。
+
+机器人每一时刻只能向下或者向右移动一步。机器人试图达到网格的右下角。
+
+问有多少条不同的路径？
+ ### 样例说明
+ 
+ ### 参考代码
+ A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).
+
+The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).
+
+How many possible unique paths are there?
+
+
+Above is a 3 x 7 grid. How many possible unique paths are there?
+
+Note: m and n will be at most 100.
+
+解法1:
+数学模型：在n-1 + m-1长度的序列中，有n-1个D，和m-1个R组成。
+其中D表示向下，R表示向右。
+因此满足组合数：C(n+m-2, n-1), 从n+m-2个位置中选n-1个位置放D的方案数。
+
+解法2:
+可以用Dp过程来求解：
+Dp[i][j] 表示走到(i,j)的路径数，
+考虑最后一步是从上往下走，还是从左往右走。
+Dp[i][j] = Dp[i-1][j] + Dp[i][j-1];
+```java
+public class Solution {
+    public int uniquePaths(int m, int n) {
+        if (m == 0 || n == 0) {
+            return 1;
+        }
+        
+        int[][] sum = new int[m][n];
+        for (int i = 0; i < m; i++) {
+            sum[i][0] = 1;
+        }
+        for (int i = 0; i < n; i++) {
+            sum[0][i] = 1;
+        }
+        for (int i = 1; i < m; i++) {
+            for (int j = 1; j < n; j++) {
+                sum[i][j] = sum[i - 1][j] + sum[i][j - 1];
+            }
+        }
+        return sum[m - 1][n - 1];
+    }
+}
+
+// 方法二
+public class Solution {
+    /**
+     * @param n, m: positive integer (1 <= n ,m <= 100)
+     * @return an integer
+     */
+    public int uniquePaths(int m, int n) {
+        int[][] f = new int[m][n];
+        int i, j;
+        for (i = 0; i < m; ++i) {
+            for (j = 0; j < n; ++j) {
+                if (i == 0 || j == 0) {
+                    f[i][j] = 1;
+                }
+                else {
+                    f[i][j] = f[i-1][j] + f[i][j-1];
+                }
+            }
+        }
+        
+        return f[m-1][n-1];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/unique-substrings-in-wraparound-string.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/unique-substrings-in-wraparound-string.md"
new file mode 100644
index 0000000..76caa96
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/unique-substrings-in-wraparound-string.md"
@@ -0,0 +1,55 @@
+# 环绕字符串中的唯一子串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/unique-substrings-in-wraparound-string/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 字符串`s`是由字符串`"abcdefghijklmnopqrstuvwxyz"`无限重复环绕形成的，所以`s`看起来像是这样：`"...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd...."`。
+
+现在有另一个字符串`p`。你的任务是找出`p`中有多少互不相同的非空子串出现在`s`中。确切的说，你得到字符串`p`作为输入，你需要输出关于`p`非空子串的数目，这些子串互不相同，并且能在`s`中被找到。
+ ### 样例说明
+ 样例1：
+```
+输入："a"
+输出：1
+说明：字符串"a"的所有非空子串中，只有"a"出现在字符串s中。
+```
+
+样例2：
+```
+输入："cac"
+输出：2
+说明：字符串"cac"的所有非空子串中，"a"和"c"出现在字符串s中。
+```
+
+样例3：
+```
+输入："zab"
+输出：6
+说明：有六个"zab"的非空子串"z"、"a"、"b"、"za"、"ab"、"zab"出现在字符串s中。
+```
+ ### 参考代码
+ 用动态规划来维护以每一个字母为末尾的最长子串长度，长度相加即为答案
+```java
+public class Solution {
+    public int findSubstringInWraproundString(String p) {
+        int []dp=new int[26];
+        for(int i = 0;i < 26;i++)
+        dp[i]=0;
+        int len=p.length();
+        int pos = 0;
+        for(int i = 0;i < len;i++){
+            if(i > 0 && (p.charAt(i) - p.charAt(i-1) == 1 || p.charAt(i) == 'a' && p.charAt(i-1) == 'z')){
+                pos ++;
+            }
+            else{
+                pos = 1;
+            }
+            dp[p.charAt(i) - 'a'] = Math.max(dp[p.charAt(i) - 'a'],pos);
+        }
+        int ans = 0;
+        for(int i = 0;i < 26;i++){
+            ans+=dp[i];
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/word-break-ii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/word-break-ii.md"
new file mode 100644
index 0000000..5dac348
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/word-break-ii.md"
@@ -0,0 +1,67 @@
+# 单词拆分II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-break-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一字串s和单词的字典dict,在字串中增加空格来构建一个句子，并且所有单词都来自字典。
+返回所有有可能的句子。
+ ### 样例说明
+ **样例 1:**
+```
+输入："lintcode"，["de","ding","co","code","lint"]
+输出：["lint code", "lint co de"]
+解释：
+插入一个空格是"lint code"，插入两个空格是 "lint co de"
+```
+
+**样例 2:**
+```
+输入："a"，[]
+输出：[]
+解释：字典为空
+```
+ ### 参考代码
+ 使用记忆化搜索
+```java
+public class Solution {
+    public ArrayList<String> wordBreak(String s, Set<String> dict) {
+        // Note: The Solution object is instantiated only once and is reused by each test case.
+        Map<String, ArrayList<String>> memo = new HashMap<String, ArrayList<String>>();
+        return wordBreakHelper(s, dict, memo);
+    }
+
+    public ArrayList<String> wordBreakHelper(String s,
+                                             Set<String> dict,
+                                             Map<String, ArrayList<String>> memo){
+        if (memo.containsKey(s)) {
+            return memo.get(s);
+        }
+        
+        ArrayList<String> results = new ArrayList<String>();
+        
+        if (s.length() == 0) {
+            return results;
+        }
+        
+        if (dict.contains(s)) {
+            results.add(s);
+        }
+        
+        for (int len = 1; len < s.length(); ++len){
+            String word = s.substring(0, len);
+            if (!dict.contains(word)) {
+                continue;
+            }
+            
+            String suffix = s.substring(len);
+            ArrayList<String> segmentations = wordBreakHelper(suffix, dict, memo);
+            
+            for (String segmentation: segmentations){
+                results.add(word + " " + segmentation);
+            }
+        }
+        
+        memo.put(s, results);
+        return results;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/word-break-iii.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/word-break-iii.md"
new file mode 100644
index 0000000..b9a37d9
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/word-break-iii.md"
@@ -0,0 +1,63 @@
+# 单词拆分 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-break-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个单词表和一条去掉所有空格的句子，根据给出的单词表添加空格, 返回可以构成的句子的数量, 保证构成的句子中所有的单词都可以在单词表中找到.
+ ### 样例说明
+ **样例1**
+```
+输入：
+"CatMat"
+["Cat", "Mat", "Ca", "tM", "at", "C", "Dog", "og", "Do"]
+输出： 3
+解释：
+我们可以有如下三种方式：
+"CatMat" = "Cat" + "Mat"
+"CatMat" = "Ca" + "tM" + "at"
+"CatMat" = "C" + "at" + "Mat"
+```
+**样例2**
+```
+输入：
+"a"
+[]
+输出： 0
+```
+ ### 参考代码
+ 设`dp[i][j]`表示从字典dict中组成子串`str[i:j+1]`有多少种方法。
+转移方程为：$dp[i][j]=\sum_{k=i}^{j}dp[i][k]*dp[k+1][j]$
+```java
+public class Solution {
+    /*
+     * @param : A string
+     * @param : A set of word
+     * @return: the number of possible sentences.
+     */
+    public int wordBreak3(String s, Set<String> dict) {
+        int n = s.length();
+        String lowerS = s.toLowerCase();
+        
+        Set<String> lowerDict = new HashSet<String>();
+        for(String str : dict) {
+            lowerDict.add(str.toLowerCase());
+        }
+        int[][] dp = new int[n][n];
+        for(int i = 0; i < n; i++){
+            for(int j = i; j < n;j++){
+                String sub = lowerS.substring(i, j + 1);
+                if(lowerDict.contains(sub)){
+                    dp[i][j] = 1;
+                }
+            }
+        }
+        for(int i = 0; i < n; i++){
+            for(int j = i; j < n; j++){
+                for(int k = i; k < j; k++){
+                    dp[i][j] += (dp[i][k] * dp[k + 1][j]);
+                }
+            }
+        }
+        return dp[0][n - 1];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\212\250\346\200\201\350\247\204\345\210\222/word-break.md" "b/\345\212\250\346\200\201\350\247\204\345\210\222/word-break.md"
new file mode 100644
index 0000000..1fe67d6
--- /dev/null
+++ "b/\345\212\250\346\200\201\350\247\204\345\210\222/word-break.md"
@@ -0,0 +1,96 @@
+# 单词拆分 I
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-break/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定字符串 s 和单词字典 dict，确定 s 是否可以分成一个或多个以空格分隔的子串，并且这些子串都在字典中存在。
+ ### 样例说明
+ ```
+样例 1:
+	输入:  "lintcode", ["lint", "code"]
+	输出:  true
+
+样例 2:
+	输入: "a", ["a"]
+	输出:  true
+	
+```
+
+
+ ### 参考代码
+ 使用《九章算法班》中讲过的划分型动态规划算法
+- state: `dp[i]` 表示前 i 个字符是否能够被划分为若干个单词
+- function: `dp[i]` = or{`dp[j]` and j + 1~i 是一个单词}
+```
+[[python]]
+class Solution:
+    """
+    @param: s: A string
+    @param: dict: A dictionary of words dict
+    @return: A boolean
+    """
+    def wordBreak(self, s, wordSet):
+        if not s:
+            return True
+            
+        n = len(s)
+        dp = [False] * (n + 1)
+        dp[0] = True
+        
+        max_length = max([
+            len(word)
+            for word in wordSet
+        ]) if wordSet else 0
+        
+        for i in range(1, n + 1):
+            for l in range(1, max_length + 1):
+                if i < l:
+                    break
+                if not dp[i - l]:
+                    continue
+                word = s[i - l:i]
+                if word in wordSet:
+                    dp[i] = True
+                    break
+        
+        return dp[n]
+[[java]]
+public class Solution {
+    /*
+     * @param s: A string
+     * @param dict: A dictionary of words dict
+     * @return: A boolean
+     */
+    public boolean wordBreak(String s, Set<String> dict) {
+        if (s == null) {
+            return true;
+        }
+        
+        int maxLength = 0;
+        for (String word : dict) {
+            maxLength = Math.max(maxLength, word.length());
+        }
+      
+        int n = s.length();
+        boolean[] dp = new boolean[n + 1];
+        dp[0] = true;
+        
+        for (int i = 1; i <= n; i++) {
+            for (int l = 1; l <= maxLength; l++) {
+                if (i < l) {
+                    break;
+                }
+                if (!dp[i - l]) {
+                    continue;
+                }
+                String word = s.substring(i - l, i);
+                if (dict.contains(word)) {
+                    dp[i] = true;
+                    break;
+                }
+            }
+        }
+        
+        return dp[n];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/find-the-connected-component-in-the-undirected-graph.md" "b/\345\233\276\350\256\272/find-the-connected-component-in-the-undirected-graph.md"
new file mode 100644
index 0000000..9440145
--- /dev/null
+++ "b/\345\233\276\350\256\272/find-the-connected-component-in-the-undirected-graph.md"
@@ -0,0 +1,69 @@
+# 找无向图的连通块
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-the-connected-component-in-the-undirected-graph/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 找出无向图中所有的连通块。
+
+图中的每个节点包含一个label属性和一个邻接点的列表。
+
+（一个无向图的连通块是一个子图，其中任意两个顶点通过路径相连，且不与整个图中的其它顶点相连。）
+
+你需要返回 label 集合的列表.
+ ### 样例说明
+ 
+ ### 参考代码
+ > 两种方法, BFS/DFS和并查集
+
+BFS/DFS方法:
+
+一次遍历可遍历一整个连通块, 所以标记好每个点是否访问过, 只遍历未访问过的点, 计数直到所有的点都被访问过, 开始过多少次遍历即可.
+
+---
+
+并查集方法(见C++):
+
+假设有 n 个节点. 初始有 n 个集合, 枚举所有的边, 每次把边的两端点所在集合合并, 最后剩余集合的个数即是连通块个数. 一个集合内部的节点即是一个连通块内的节点.
+```java
+/**
+ * Definition for Undirected graph.
+ * class UndirectedGraphNode {
+ *     int label;
+ *     ArrayList<UndirectedGraphNode> neighbors;
+ *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
+ * };
+ */
+public class Solution {
+    public List<List<Integer>> connectedSet(List<UndirectedGraphNode> nodes) {
+        List<List<Integer>> result = new ArrayList<>();
+        if (nodes == null) {
+            return result;
+        }
+        Set<UndirectedGraphNode> visited = new HashSet<>();
+        for (UndirectedGraphNode curr : nodes) {
+            if (!visited.contains(curr)) {
+                findConnect(curr, result, visited);
+            }
+        }
+        return result;
+    }
+    public void findConnect(UndirectedGraphNode node, List<List<Integer>> result, Set<UndirectedGraphNode> visited) {
+        Queue<UndirectedGraphNode> queue = new LinkedList<>();
+        queue.offer(node);
+        visited.add(node);
+        List<Integer> list = new ArrayList<>();
+        
+        while (!queue.isEmpty()) {
+            UndirectedGraphNode curr = queue.poll();
+            list.add(curr.label);
+            for (UndirectedGraphNode next : curr.neighbors) {
+                if (!visited.contains(next)){
+                    queue.offer(next);
+                    visited.add(next);
+                }
+            }
+        }
+        Collections.sort(list);
+        result.add(list);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock-ii.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock-ii.md"
new file mode 100644
index 0000000..5a3c7d8
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock-ii.md"
@@ -0,0 +1,46 @@
+# 买卖股票的最佳时机 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数组 `prices` 表示一支股票每天的价格. 
+
+你可以完成任意次数的交易, 不过你不能同时参与多个交易 (也就是说, 如果你已经持有这支股票, 在再次购买之前, 你必须先卖掉它).
+
+设计一个算法求出最大的利润.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [2, 1, 2, 0, 1]
+输出: 2
+解释: 
+    1. 在第 2 天以 1 的价格买入, 然后在第 3 天以 2 的价格卖出, 利润 1
+    2. 在第 4 天以 0 的价格买入, 然后在第 5 天以 1 的价格卖出, 利润 1
+    总利润 2.
+```
+
+**样例 2:**
+
+```
+输入: [4, 3, 2, 1]
+输出: 0
+解释: 不进行任何交易, 利润为0.
+```
+ ### 参考代码
+ 贪心法: 只要相邻的两天股票的价格是上升的, 我们就进行一次交易, 获得一定利润.
+
+这样的策略不一定是最小的交易次数, 但是一定会得到最大的利润.
+```java
+public class Solution {
+    public int maxProfit(int[] prices) {
+        int profit = 0;
+        for (int i = 0; i < prices.length - 1; i++) {
+            int diff = prices[i + 1] - prices[i];
+            if (diff > 0) {
+                profit += diff;
+            }
+        }
+        return profit;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock-iii.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock-iii.md"
new file mode 100644
index 0000000..a25880f
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock-iii.md"
@@ -0,0 +1,142 @@
+# 买卖股票的最佳时机 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>假设你有一个数组，它的第i个元素是一支给定的股票在第i天的价格。<span style="line-height: 1.42857143;">设计一个算法来找到最大的利润。你最多可以完成两笔交易。</span></p>
+ ### 样例说明
+ ***样例 1***
+```
+输入 : [4,4,6,1,1,4,2,5]
+输出 : 6
+```
+ ### 参考代码
+ Say you have an array for which the ith element is the price of a given stock on day i.
+
+Design an algorithm to find the maximum profit. You may complete at most two transactions.
+
+Note:
+You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
+```java
+// 动态规划专题班版本
+public class Solution {
+    /**
+     * @param prices: Given an integer array
+     * @return: Maximum profit
+     */
+    public int maxProfit(int[] prices) {
+        // write your code here
+        int n = prices.length;
+        if (n == 0) {
+            return 0;
+        }
+        int [][]dp = new int[n + 1][5 + 1];
+        
+        for (int k = 1; k <= 5; k++) {
+            dp[0][k] = Integer.MIN_VALUE;
+        }
+        dp[0][1] = 0;
+        for (int i = 1; i <= n; i++) {
+            // 手中未持有股票
+            for (int j = 1; j <= 5; j += 2) {
+                // 前一天也未持有
+                dp[i][j] = dp[i - 1][j];
+                if (j > 1 && i > 1 && dp[i - 1][j - 1] != Integer.MIN_VALUE) {
+                    //                            前一天持有，今天卖了获利。
+                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + prices[i - 1] - prices[i - 2]);
+                }
+            }
+            // 手中持有股票
+            for (int j = 2; j <= 5; j += 2) {
+                //前一天未持有，今天买进
+                dp[i][j] = dp[i - 1][j - 1];
+                if (i > 1 && dp[i - 1][j] != Integer.MIN_VALUE) {
+                    //                            前一天持有了，计算今天的利润
+                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j] + prices[i - 1] - prices[i - 2]);
+                }
+            }
+        }
+        
+        int res = 0;
+        for (int j = 1; j <= 5; j += 2) {
+            res = Math.max(res, dp[n][j]);
+        }
+        return res;
+    }
+}
+
+// 方法二
+class Solution {
+    /**
+     * @param k: An integer
+     * @param prices: Given an integer array
+     * @return: Maximum profit
+     */
+    private int update(int a, int b, int delta) {
+        if (b == Integer.MIN_VALUE) {
+            return a;
+        }
+        
+        if (b + delta > a) {
+            return b + delta;
+        }
+        
+        return a;
+    }  
+     
+    public int maxProfit(int K, int[] prices) {
+        int n = prices.length;
+        int i, j, k;
+        if (K == 0) {
+            return 0;
+        }
+        
+        if (K >= n - 1) {
+            j = 0;
+            for (i = 1; i < n; ++i) {
+                if (prices[i] > prices[i - 1]) {
+                    j += prices[i] - prices[i - 1];
+                }
+            }
+            
+            return j;
+        }
+        
+        int[][] f = new int[n+1][2*K+1];
+        for (i = 0; i <= n; ++i) {
+            for (j = 0; j <= 2*K; ++j) {
+                f[i][j] = Integer.MIN_VALUE;
+            }
+        }
+        
+        f[0][0] = 0;
+        for (i = 1; i <= n; ++i) {
+            int delta;
+            if (i == 1) {
+                delta = 0;
+            }
+            else {
+                delta = prices[i-1] - prices[i - 2];
+            }
+            
+            f[i][0] = update(f[i][0], f[i-1][0], 0);
+            for (j = 1; j <= 2 * K; j += 2) {
+                if (i > 1) f[i][j] = update(f[i][j], f[i-1][j], delta);
+                if (i > 1) f[i][j] = update(f[i][j], f[i-1][j-1], delta);
+            }
+            
+            for (j = 2; j <= 2 * K; j += 2) {
+                f[i][j] = update(f[i][j], f[i-1][j], 0);
+                if (i > 1) f[i][j] = update(f[i][j], f[i-1][j-1], delta);
+                if (i > 1) f[i][j] = update(f[i][j], f[i-1][j-2], delta);
+            }
+        }
+        
+        int res = Integer.MIN_VALUE;
+        for (j = 2; j <= 2 * K; j += 2) {
+            res = update(res, f[n][j], 0);
+        }
+        
+        return res;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock-iv.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock-iv.md"
new file mode 100644
index 0000000..80aa31a
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock-iv.md"
@@ -0,0 +1,218 @@
+# 买卖股票的最佳时机 IV
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iv/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定数组 `prices`, 其中第 `i` 个元素代表某只股票在第 `i` 天第价格.
+
+**你最多可以完成 `k` 笔交易.** 问最大的利润是多少?
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: k = 2, prices = [4, 4, 6, 1, 1, 4, 2 ,5]
+输出: 6
+解释: 以 4 买入, 以 6 卖出. 然后再以 1 买入, 以 5 卖出. 利润为 2 + 4 = 6.
+```
+
+**样例 2:**
+
+```
+输入: k = 1, prices = [3, 2, 1]
+输出: 0
+解释: 不进行交易
+```
+ ### 参考代码
+ 假设一共有 n 天, 那么这 n 天最多能够完成 n / 2 比交易, 也就是说, 当 k * 2 >= n 时, 就变成了 [买卖股票的最佳时机 II](https://www.jiuzhang.com/solution/best-time-to-buy-and-sell-stock-ii/), 反之, 我们可以作为动态规划问题解决:
+
+定义:
+
+- globalbest[i][j] 表示前i天，至多进行j次交易时的最大获益
+- mustsell[i][j] 表示前i天，至多进行j次交易，并且第i天卖出手中的股票时的最大获益
+
+状态转移:
+
+- `mustsell[i][j] = max(globalbest[i - 1][j - 1], mustsell[i - 1][j]) + prices[i] - prices[i - 1]`
+- `globalbest[i][j] = max(globalbest[i - 1][j], mustsell[i][j])`
+
+边界: `mustsell[0][i] = globalbest[0][i] = 0`
+
+优化: 滚动数组优化两个状态的空间至一维数组.
+```java
+// 动态规划专题班版本
+class Solution {
+    /**
+     * @param prices: Given an integer array
+     * @return: Maximum profit
+     */
+
+    public int maxProfit(int K, int[] P) {
+        int n = P.length;
+        if (n == 0) {
+            return 0;
+        }
+
+        int i, j, k;
+        if (K > n / 2) {
+            // best time to buy and sell stock ii
+            int tmp = 0;
+            for (i = 0; i < n - 1; ++i) {
+                tmp += Math.max(0, P[i + 1] - P[i]);
+            }
+
+            return tmp;
+        }
+
+        int[][] f = new int[n + 1][2 * K + 1 + 1];
+        for (k = 1; k <= 2 * K + 1; ++k) {
+            f[0][k] = Integer.MIN_VALUE; // impossible
+        }
+
+        f[0][1] = 0;
+        for (i = 1; i <= n; ++i) {
+            // 阶段1, 3, .. 2 * K + 1: f[i][j] = max{f[i-1][j], f[i-1][j-1] + Pi-1 – Pi-2}
+            for (j = 1; j <= 2 * K + 1; j += 2) {
+                f[i][j] = f[i - 1][j];
+                if (j > 1 && i > 1 && f[i - 1][j - 1] != Integer.MIN_VALUE) {
+                    f[i][j] = Math.max(f[i][j], f[i - 1][j - 1] + P[i - 1] - P[i - 2]);
+                }
+            }
+
+            // 阶段2, 4.., 2K: f[i][j] = max{f[i-1][j] + Pi-1 – Pi-2, f[i-1][j-1]}
+            for (j = 2; j <= 2 * K + 1; j += 2) {
+                f[i][j] = f[i - 1][j - 1];
+                if (i > 1 && f[i - 1][j] != Integer.MIN_VALUE) {
+                    f[i][j] = Math.max(f[i][j], f[i - 1][j] + P[i - 1] - P[i - 2]);
+                }
+            }
+        }
+
+        int res = 0;
+        for (j = 1; j <= 2 * K + 1; j += 2) {
+            res = Math.max(res, f[n][j]);
+        }
+
+        return res;
+    }
+}
+
+// version 2
+class Solution {
+    /**
+     * @param k:      An integer
+     * @param prices: Given an integer array
+     * @return: Maximum profit
+     */
+    public int maxProfit(int k, int[] prices) {
+        // write your code here
+        if (k == 0) {
+            return 0;
+        }
+        if (k >= prices.length / 2) {
+            int profit = 0;
+            for (int i = 1; i < prices.length; i++) {
+                if (prices[i] > prices[i - 1]) {
+                    profit += prices[i] - prices[i - 1];
+                }
+            }
+            return profit;
+        }
+        int n = prices.length;
+        int[][] mustsell = new int[n + 1][n + 1]; // mustSell[i][j] 表示前i天，至多进行j次交易，第i天必须sell的最大获益
+        int[][] globalbest = new int[n + 1][n + 1]; // globalbest[i][j] 表示前i天，至多进行j次交易，第i天可以不sell的最大获益
+
+        mustsell[0][0] = globalbest[0][0] = 0;
+        for (int i = 1; i <= k; i++) {
+            mustsell[0][i] = globalbest[0][i] = 0;
+        }
+
+        for (int i = 1; i < n; i++) {
+            int gainorlose = prices[i] - prices[i - 1];
+            mustsell[i][0] = 0;
+            for (int j = 1; j <= k; j++) {
+                mustsell[i][j] = Math.max(globalbest[(i - 1)][j - 1] + gainorlose, mustsell[(i - 1)][j] + gainorlose);
+                globalbest[i][j] = Math.max(globalbest[(i - 1)][j], mustsell[i][j]);
+            }
+        }
+        return globalbest[(n - 1)][k];
+    }
+};
+
+// 方法二
+class Solution {
+    /**
+     * @param k:      An integer
+     * @param prices: Given an integer array
+     * @return: Maximum profit
+     */
+    private int update(int a, int b, int delta) {
+        if (b == Integer.MIN_VALUE) {
+            return a;
+        }
+
+        if (b + delta > a) {
+            return b + delta;
+        }
+
+        return a;
+    }
+
+    public int maxProfit(int K, int[] prices) {
+        int n = prices.length;
+        int i, j, k;
+        if (K == 0) {
+            return 0;
+        }
+
+        if (K >= n - 1) {
+            j = 0;
+            for (i = 1; i < n; ++i) {
+                if (prices[i] > prices[i - 1]) {
+                    j += prices[i] - prices[i - 1];
+                }
+            }
+
+            return j;
+        }
+
+        int[][] f = new int[n + 1][2 * K + 1];
+        for (i = 0; i <= n; ++i) {
+            for (j = 0; j <= 2 * K; ++j) {
+                f[i][j] = Integer.MIN_VALUE;
+            }
+        }
+
+        f[0][0] = 0;
+        for (i = 1; i <= n; ++i) {
+            int delta;
+            if (i == 1) {
+                delta = 0;
+            } else {
+                delta = prices[i - 1] - prices[i - 2];
+            }
+
+            f[i][0] = update(f[i][0], f[i - 1][0], 0);
+            for (j = 1; j <= 2 * K; j += 2) {
+                if (i > 1)
+                    f[i][j] = update(f[i][j], f[i - 1][j], delta);
+                if (i > 1)
+                    f[i][j] = update(f[i][j], f[i - 1][j - 1], delta);
+            }
+
+            for (j = 2; j <= 2 * K; j += 2) {
+                f[i][j] = update(f[i][j], f[i - 1][j], 0);
+                if (i > 1)
+                    f[i][j] = update(f[i][j], f[i - 1][j - 1], delta);
+                if (i > 1)
+                    f[i][j] = update(f[i][j], f[i - 1][j - 2], delta);
+            }
+        }
+
+        int res = Integer.MIN_VALUE;
+        for (j = 2; j <= 2 * K; j += 2) {
+            res = update(res, f[n][j], 0);
+        }
+
+        return res;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock.md"
new file mode 100644
index 0000000..dca8fe7
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/best-time-to-buy-and-sell-stock.md"
@@ -0,0 +1,53 @@
+# 买卖股票的最佳时机
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <span style="line-height: 1.42857143;">假设有一个数组，它的第i个元素是一支给定的股票在第i天的价格。</span><span style="line-height: 1.42857143;">如果你最多只允许完成一次交易(例如,一次买卖股票),设计一个算法来找出最大利润。</span>
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: [3, 2, 3, 1, 2]
+输出: 1
+说明：你可以在第三天买入，第四天卖出，利润是 2 - 1 = 1
+```
+
+**样例2**
+
+```plain
+输入: [1, 2, 3, 4, 5]
+输出: 4
+说明：你可以在第0天买入，第四天卖出，利润是 5 - 1 = 4
+```
+
+**样例3**
+
+```plain
+输入: [5, 4, 3, 2, 1]
+输出: 0
+说明：你可以不进行任何操作然后也得不到任何利润
+```
+
+
+ ### 参考代码
+ Say you have an array for which the ith element is the price of a given stock on day i.
+
+If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
+```java
+public class Solution {
+    public int maxProfit(int[] prices) {
+        if (prices == null || prices.length == 0) {
+            return 0;
+        }
+
+        int min = Integer.MAX_VALUE;  //just remember the smallest price
+        int profit = 0;
+        for (int i : prices) {
+            min = i < min ? i : min;
+            profit = (i - min) > profit ? i - min : profit;
+        }
+
+        return profit;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-zigzag-level-order-traversal.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-zigzag-level-order-traversal.md"
new file mode 100644
index 0000000..fd40965
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-zigzag-level-order-traversal.md"
@@ -0,0 +1,83 @@
+# 二叉树的锯齿形层次遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-zigzag-level-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树，返回其节点值的锯齿形层次遍历（先从左往右，下一层再从右往左，层与层之间交替进行）&nbsp;</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入:{1,2,3}
+输出:[[1],[3,2]]
+解释:
+    1
+   / \
+  2   3
+它将被序列化为 {1,2,3}
+```
+**样例 2:**
+```
+输入:{3,9,20,#,#,15,7}
+输出:[[3],[20,9],[15,7]]
+解释:
+    3
+   / \
+  9  20
+    /  \
+   15   7
+它将被序列化为 {3,9,20,#,#,15,7}
+```
+
+ ### 参考代码
+ 层序遍历完之后，看层数，偶数层reverse一下即可。
+```java
+public class Solution {
+    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
+        List<List<Integer>> result = new ArrayList<List<Integer>>();
+
+        if (root == null) {
+            return result;
+        }
+
+        Stack<TreeNode> currLevel = new Stack<TreeNode>();
+        Stack<TreeNode> nextLevel = new Stack<TreeNode>();
+        Stack<TreeNode> tmp;
+        
+        currLevel.push(root);
+        boolean normalOrder = true;
+
+        while (!currLevel.isEmpty()) {
+            ArrayList<Integer> currLevelResult = new ArrayList<Integer>();
+
+            while (!currLevel.isEmpty()) {
+                TreeNode node = currLevel.pop();
+                currLevelResult.add(node.val);
+
+                if (normalOrder) {
+                    if (node.left != null) {
+                        nextLevel.push(node.left);
+                    }
+                    if (node.right != null) {
+                        nextLevel.push(node.right);
+                    }
+                } else {
+                    if (node.right != null) {
+                        nextLevel.push(node.right);
+                    }
+                    if (node.left != null) {
+                        nextLevel.push(node.left);
+                    }
+                }
+            }
+
+            result.add(currLevelResult);
+            tmp = currLevel;
+            currLevel = nextLevel;
+            nextLevel = tmp;
+            normalOrder = !normalOrder;
+        }
+
+        return result;
+
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/build-post-office-ii.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/build-post-office-ii.md"
new file mode 100644
index 0000000..79d3887
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/build-post-office-ii.md"
@@ -0,0 +1,221 @@
+# 邮局的建立 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/build-post-office-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个二维的网格，每一格可以代表墙 `2` ，房子 `1`，以及空 `0` (用数字0,1,2来表示)，在网格中找到一个位置去建立邮局，使得所有的房子到邮局的距离和是最小的。
+返回所有房子到邮局的最小距离和，如果没有地方建立邮局，则返回`-1`.
+ ### 样例说明
+ **样例 1:**
+```
+输入：[[0,1,0,0,0],[1,0,0,2,1],[0,1,0,0,0]]
+输出：8
+解释： 在(1,1)处建立邮局，所有房子到邮局的距离和是最小的。
+```
+
+**样例 2:**
+```
+输入：[[0,1,0],[1,0,1],[0,1,0]]
+输出：4
+解释：在(1,1)处建立邮局，所有房子到邮局的距离和是最小的。
+```
+ ### 参考代码
+ 考点：
+* bfs
+
+题解：
+* 本题采用bfs，首次遍历网格，对空地处进行bfs，搜索完成后如果存在房屋没有被vis标记则改空地不可以设置房屋。
+* 朴素的bfs搜索过程中，sun+=dist;实现当前点距离和的更新。
+* now.dis+1每次实现当前两点间距离的更新。
+```java
+class Coordinate {
+    int x, y;
+    public Coordinate(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+}
+
+public class Solution {
+    public int EMPTY = 0;
+    public int HOUSE = 1;
+    public int WALL = 2;
+    public int[][] grid;
+    public int n, m;
+    public int[] deltaX = {0, 1, -1, 0};
+    public int[] deltaY = {1, 0, 0, -1};
+    
+    private List<Coordinate> getCoordinates(int type) {
+        List<Coordinate> coordinates = new ArrayList<>();
+        
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < m; j++) {
+                if (grid[i][j] == type) {
+                    coordinates.add(new Coordinate(i, j));
+                }
+            }
+        }
+        
+        return coordinates;
+    }
+    
+    private void setGrid(int[][] grid) {
+        n = grid.length;
+        m = grid[0].length;
+        this.grid = grid;
+    }
+    
+    private boolean inBound(Coordinate coor) {
+        if (coor.x < 0 || coor.x >= n) {
+            return false;
+        }
+        if (coor.y < 0 || coor.y >= m) {
+            return false;
+        }
+        return grid[coor.x][coor.y] == EMPTY;
+    }
+
+    /**
+     * @param grid a 2D grid
+     * @return an integer
+     */
+    public int shortestDistance(int[][] grid) {
+        if (grid == null || grid.length == 0 || grid[0].length == 0) {
+            return -1;
+        }
+        
+        // set n, m, grid
+        setGrid(grid);
+        
+        List<Coordinate> houses = getCoordinates(HOUSE);
+        int[][] distanceSum = new int[n][m];
+        int[][] visitedTimes = new int[n][m];
+        for (Coordinate house : houses) {
+            bfs(house, distanceSum, visitedTimes);
+        }
+        
+        int shortest = Integer.MAX_VALUE;
+        List<Coordinate> empties = getCoordinates(EMPTY);
+        for (Coordinate empty : empties) {
+            if (visitedTimes[empty.x][empty.y] != houses.size()) {
+                continue;
+            }
+            
+            shortest = Math.min(shortest, distanceSum[empty.x][empty.y]);
+        }
+        
+        if (shortest == Integer.MAX_VALUE) {
+            return -1;
+        }
+        return shortest;
+    }
+    
+    private void bfs(Coordinate start,
+                     int[][] distanceSum,
+                     int[][] visitedTimes) {
+        Queue<Coordinate> queue = new LinkedList<>();
+        boolean[][] hash = new boolean[n][m];
+        
+        queue.offer(start);
+        hash[start.x][start.y] = true;
+        
+        int steps = 0;
+        while (!queue.isEmpty()) {
+            steps++;
+            int size = queue.size();
+            for (int temp = 0; temp < size; temp++) {
+                Coordinate coor = queue.poll();
+                for (int i = 0; i < 4; i++) {
+                    Coordinate adj = new Coordinate(
+                        coor.x + deltaX[i],
+                        coor.y + deltaY[i]
+                    );
+                    if (!inBound(adj)) {
+                        continue;
+                    }
+                    if (hash[adj.x][adj.y]) {
+                        continue;
+                    }
+                    queue.offer(adj);
+                    hash[adj.x][adj.y] = true;
+                    distanceSum[adj.x][adj.y] += steps;
+                    visitedTimes[adj.x][adj.y]++;
+                } // direction
+            } // for temp
+        } // while
+    }
+}
+
+//version 硅谷算法班
+public class Solution {
+    /**
+     * @param grid: a 2D grid
+     * @return: An integer
+     */
+    public int shortestDistance(int[][] grid) {
+        // write your code here
+        if (grid == null || grid.length == 0 || grid[0].length == 0) {
+            return -1;
+        }
+
+        int ans = Integer.MAX_VALUE;
+
+        for (int i = 0; i < grid.length; i++) {
+            for (int j = 0; j < grid[0].length; j++) {
+                if (grid[i][j] == 0) {
+                    ans = Math.min(ans, bfs(grid, i, j));
+                }
+            }
+        }
+        return ans == Integer.MAX_VALUE ? -1 : ans;
+    }
+
+    private int bfs(int[][] grid, int sx, int sy) {
+        Queue<Integer> qx = new LinkedList<>();
+        Queue<Integer> qy = new LinkedList<>();
+        boolean[][] v = new boolean[grid.length][grid[0].length];
+
+        qx.offer(sx);
+        qy.offer(sy);
+        v[sx][sy] = true;
+
+        int[] dx = {1, -1, 0, 0};
+        int[] dy = {0, 0, 1, -1};
+
+        int dist = 0;
+        int sum = 0;
+
+        while (!qx.isEmpty()) {
+            dist++;
+            int size = qx.size();
+            for (int i = 0; i < size; i++) {
+                int cx = qx.poll();
+                int cy = qy.poll();
+                for (int k = 0; k < 4; k++) {
+                    int nx = cx + dx[k];
+                    int ny = cy + dy[k];
+                    if (0 <= nx && nx < grid.length && 0 <= ny && ny < grid[0].length && !v[nx][ny]) {
+                        v[nx][ny] = true;
+
+                        if (grid[nx][ny] == 1) {
+                            sum += dist;
+                        }
+                        if (grid[nx][ny] == 0) {
+                            qx.offer(nx);
+                            qy.offer(ny);
+                        }
+                    }
+                }
+            }
+        }
+
+        for (int i = 0; i < grid.length; i++) {
+            for (int j = 0; j < grid[0].length; j++) {
+                if (grid[i][j] == 1 && !v[i][j]) {
+                    return Integer.MAX_VALUE;
+                }
+            }
+        }
+        return sum;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-binary-tree-to-linked-lists-by-depth.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-binary-tree-to-linked-lists-by-depth.md"
new file mode 100644
index 0000000..8373b33
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-binary-tree-to-linked-lists-by-depth.md"
@@ -0,0 +1,124 @@
+# 将二叉树按照层级转化为链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-binary-tree-to-linked-lists-by-depth/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，设计一个算法为每一层的节点建立一个链表。也就是说，如果一棵二叉树有 `D` 层，那么你需要创建 `D` 条链表。
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,2,3,4}
+输出: [1->null,2->3->null,4->null]
+解释: 
+        1
+       / \
+      2   3
+     /
+    4
+```
+
+**样例 2:**
+
+```
+输入: {1,#,2,3}
+输出: [1->null,2->null,3->null]
+解释: 
+    1
+     \
+      2
+     /
+    3
+```
+ ### 参考代码
+ 考点：
+* 搜索遍历
+
+题解：采用基本的bfs搜索实现层序遍历即可。分别使用DFS和BFS两种解法解决这个问题。时间复杂度都是O(n)。
+```python
+# BFS 解法
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+Definition for singly-linked list.
+class ListNode:
+    def __init__(self, x):
+        self.val = x
+        self.next = None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @return {ListNode[]} a lists of linked list
+    def binaryTreeToLists(self, root):
+        result = []
+        if root is None:
+            return result
+            
+        import Queue
+        queue = Queue.Queue()
+        
+        queue.put(root)
+        
+        dummy = ListNode(0)
+        
+        lastNode = None
+        
+        while not queue.empty():
+            dummy.next = None
+            lastNode = dummy
+            size = queue.qsize()
+            for i in xrange(size):
+                head = queue.get()
+                lastNode.next = ListNode(head.val)
+                lastNode = lastNode.next
+
+                if head.left is not None:
+                    queue.put(head.left)
+                if head.right is not None:
+                    queue.put(head.right)
+        
+            result.append(dummy.next)
+        
+        return result
+    
+
+
+# DFS 解法
+
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+Definition for singly-linked list.
+class ListNode:
+    def __init__(self, x):
+        self.val = x
+        self.next = None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @return {ListNode[]} a lists of linked list
+    def binaryTreeToLists(self, root):
+        # Write your code here
+        result = []
+        self.dfs(root, 1, result)
+        return result
+
+    def dfs(self, root, depth, result):
+        if root is None:
+            return
+        node = ListNode(root.val)
+        if len(result) < depth:
+            result.append(node)
+        else:
+            node.next = result[depth-1]
+            result[depth-1] = node
+        
+        self.dfs(root.right, depth + 1, result)
+        self.dfs(root.left, depth + 1, result)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/knight-shortest-path-ii.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/knight-shortest-path-ii.md"
new file mode 100644
index 0000000..89aacce
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/knight-shortest-path-ii.md"
@@ -0,0 +1,70 @@
+# 骑士的最短路径II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/knight-shortest-path-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个 `n * m` 的棋盘中(二维矩阵中 0 表示空 1 表示有障碍物)，骑士的初始位置是 `(0, 0)` ，他想要达到 `(n - 1, m - 1)` 这个位置，骑士只能从左边走到右边。找出骑士到目标位置所需要走的最短路径并返回其长度，如果骑士无法达到则返回 `-1`.
+ ### 样例说明
+ 例1:
+```
+输入:
+[[0,0,0,0],[0,0,0,0],[0,0,0,0]]
+输出:
+3
+解释:
+[0,0]->[2,1]->[0,2]->[2,3]
+```
+
+例2:
+```
+输入:
+[[0,1,0],[0,0,1],[0,0,0]]
+输出:
+-1
+```
+
+
+
+ ### 参考代码
+ 简单动态规划。
+每个点都有至多4个前缀点，直接求最小值转移即可。
+```java
+public class Solution {
+    /**
+     * @param grid a chessboard included 0 and 1
+     * @return the shortest path
+     */
+    public int shortestPath2(boolean[][] grid) {
+        // Write your code here
+        int n = grid.length;
+        if (n == 0)
+            return -1;
+        int m = grid[0].length;
+        if (m == 0)
+            return -1;
+
+        int[][] f = new int[n][m];
+        for (int i = 0; i < n; ++i)
+            for (int j = 0; j < m; ++j)
+                f[i][j] = Integer.MAX_VALUE;
+
+        f[0][0] = 0;
+        for (int j = 1; j < m; ++j)
+          for (int i = 0; i < n; ++i)
+            if (!grid[i][j]) {
+                if (i >= 1 && j >= 2 && f[i - 1][j - 2] != Integer.MAX_VALUE)
+                    f[i][j] = Math.min(f[i][j], f[i - 1][j - 2] + 1);
+                if (i + 1 < n && j >= 2 && f[i + 1][j - 2] != Integer.MAX_VALUE)
+                    f[i][j] = Math.min(f[i][j], f[i + 1][j - 2] + 1);
+                if (i >= 2 && j >= 1 && f[i - 2][j - 1] != Integer.MAX_VALUE)
+                    f[i][j] = Math.min(f[i][j], f[i - 2][j - 1] + 1);
+                if (i + 2 < n && j >= 1 && f[i + 2][j - 1] != Integer.MAX_VALUE)
+                    f[i][j] = Math.min(f[i][j], f[i + 2][j - 1] + 1);
+            }
+
+        if (f[n - 1][m - 1] == Integer.MAX_VALUE)
+            return -1;
+
+        return f[n - 1][m - 1];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/knight-shortest-path.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/knight-shortest-path.md"
new file mode 100644
index 0000000..20c5442
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/knight-shortest-path.md"
@@ -0,0 +1,144 @@
+# 骑士的最短路线
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/knight-shortest-path/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定骑士在棋盘上的 `初始` 位置(一个2进制矩阵 `0` 表示空 `1` 表示有障碍物)，找到到达 `终点` 的最短路线，返回路线的长度。如果骑士不能到达则返回 `-1` 。
+ ### 样例说明
+ **例1:**
+```
+输入:
+[[0,0,0],
+ [0,0,0],
+ [0,0,0]]
+source = [2, 0] destination = [2, 2] 
+输出: 2
+解释:
+[2,0]->[0,1]->[2,2]
+```
+
+
+**例2:**
+```
+输入:
+[[0,1,0],
+ [0,0,1],
+ [0,0,0]]
+source = [2, 0] destination = [2, 2] 
+输出:-1
+```
+
+ ### 参考代码
+ 使用九章算法班中讲的 BFS。用 distance hash 来记录距离。
+```
+[[python]]
+"""
+Definition for a point.
+class Point:
+    def __init__(self, a=0, b=0):
+        self.x = a
+        self.y = b
+"""
+
+DIRECTIONS = [
+    (-2, -1), (-2, 1), (-1, 2), (1, 2),
+    (2, 1), (2, -1), (1, -2), (-1, -2),
+]
+
+class Solution:
+        
+    """
+    @param grid: a chessboard included 0 (false) and 1 (true)
+    @param source: a point
+    @param destination: a point
+    @return: the shortest path 
+    """
+    def shortestPath(self, grid, source, destination):
+        queue = collections.deque([(source.x, source.y)])
+        distance = {(source.x, source.y): 0}
+
+        while queue:
+            x, y = queue.popleft()
+            if (x, y) == (destination.x, destination.y):
+                return distance[(x, y)]
+            for dx, dy in DIRECTIONS:
+                next_x, next_y = x + dx, y + dy
+                if (next_x, next_y) in distance:
+                    continue
+                if not self.is_valid(next_x, next_y, grid):
+                    continue
+                distance[(next_x, next_y)] = distance[(x, y)] + 1
+                queue.append((next_x, next_y))
+        return -1
+        
+    def is_valid(self, x, y, grid):
+        n, m = len(grid), len(grid[0])
+
+        if x < 0 or x >= n or y < 0 or y >= m:
+            return False
+            
+        return not grid[x][y]
+[[java]]
+/**
+ * Definition for a point.
+ * class Point {
+ *     int x;
+ *     int y;
+ *     Point() { x = 0; y = 0; }
+ *     Point(int a, int b) { x = a; y = b; }
+ * }
+ */
+
+public class Solution {
+    public static final int[] dx = {1, 1, -1, -1, 2, 2, -2, -2};
+    public static final int[] dy = {2, -2, 2, -2, 1, -1, 1, -1};
+    /**
+     * @param grid: a chessboard included 0 (false) and 1 (true)
+     * @param source: a point
+     * @param destination: a point
+     * @return: the shortest path 
+     */
+    public int shortestPath(boolean[][] grid, Point source, Point destination) {
+        if (grid == null || grid.length == 0
+                || grid[0] == null || grid[0].length == 0) {
+            return -1;
+        }
+        
+        Queue<Point> queue = new ArrayDeque();
+        Map<Integer, Integer> distance = new HashMap();
+        
+        int n = grid.length, m = grid[0].length;
+        queue.offer(source);
+        distance.put(source.x * m + source.y, 0);
+        
+        while (!queue.isEmpty()) {
+            Point point = queue.poll();
+            if (point.x == destination.x && point.y == destination.y) {
+                return distance.get(point.x * m + point.y);
+            }
+            
+            for (int i = 0; i < 8; i++) {
+                int adjX = point.x + dx[i];
+                int adjY = point.y + dy[i];
+                if (!isValid(adjX, adjY, grid)) {
+                    continue;
+                }
+                if (distance.containsKey(adjX * m + adjY)) {
+                    continue;
+                }
+                
+                distance.put(adjX * m + adjY, distance.get(point.x * m + point.y) + 1);
+                queue.offer(new Point(adjX, adjY));
+            }
+        }
+        
+        return -1;
+    }
+    
+    private boolean isValid(int x, int y, boolean[][] grid) {
+        if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length) {
+            return false;
+        }
+        return !grid[x][y];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-difference.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-difference.md"
new file mode 100644
index 0000000..4eafd67
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-difference.md"
@@ -0,0 +1,97 @@
+# 最大子数组差
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-difference/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个整数数组，找出两个<b><font color="#e76363">不重叠</font></b>的子数组A和B，使两个子数组和的差的绝对值<strong style="line-height: 1.42857143; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"><font color="#e76363">|SUM(A) - SUM(B)|</font></strong><span style="line-height: 1.42857143;">最大。</span></p><p>返回这个最大的差值。</p>
+ ### 样例说明
+ 
+例1:
+```
+输入:[1, 2, -3, 1]
+输出:6
+解释:
+子数组是 [1,2] 和[-3].所以答案是 6.
+```
+
+例2:
+```
+输入:[0,-1]
+输出:1
+解释:
+子数组是 [0] 和 [-1].所以答案是 1.
+```
+
+
+
+ ### 参考代码
+ dp。
+维护四个数组，当前位置左边的最大子数组和，最小子数组和。当前位置右边的最大子数组和，最小子数组和。
+然后枚举分割线，扫描一下即可。
+```java
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @return: An integer indicate the value of maximum difference between two
+     *          Subarrays
+     */
+    public int maxDiffSubArrays(int[] nums) {
+        // write your code here
+        int size = nums.length;
+        int[] left_max = new int[size];
+        int[] left_min = new int[size];
+        int[] right_max = new int[size];
+        int[] right_min = new int[size];
+        int[] copy = new int[size];
+        /*Get negative copy*/
+        for(int i = 0; i < size; i++){
+            copy[i] = -1 * nums[i];
+        }
+        int max = Integer.MIN_VALUE;
+        int sum = 0;
+        int minSum = 0;
+        /*Forward: get max subarray*/
+        for(int i = 0; i < size; i++){
+            sum += nums[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            left_max[i] = max;
+        }
+        /*Backward: get max subarray*/
+        max = Integer.MIN_VALUE;
+        sum = 0;
+        minSum = 0;
+        for(int i = size - 1; i >= 0; i--){
+            sum += nums[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            right_max[i] = max;
+        }
+        /*Forward: get min subarray*/
+        max = Integer.MIN_VALUE;
+        sum = 0;
+        minSum = 0;
+        for(int i = 0; i < size; i++){
+            sum += copy[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            left_min[i] = -1 * max;
+        }
+        /*Backward: get min subarray*/
+        max = Integer.MIN_VALUE;
+        sum = 0;
+        minSum = 0;
+        for(int i = size - 1; i >= 0; i--){
+            sum += copy[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            right_min[i] = -1 * max;
+        }
+        int diff = 0;
+        for(int i = 0; i < size - 1; i++){
+            diff = Math.max(diff, Math.abs(left_max[i] - right_min[i + 1]));
+            diff = Math.max(diff, Math.abs(left_min[i] - right_max[i + 1]));
+        }
+        return diff;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/path-sum.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/path-sum.md"
new file mode 100644
index 0000000..064ddd5
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/path-sum.md"
@@ -0,0 +1,36 @@
+# 路径和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/path-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定二叉树和求和，确定树是否具有根到叶路径，使得沿路径的所有值相加等于给定的总和。
+ ### 样例说明
+ 
+ ### 参考代码
+ 使用深度搜索的方法，当搜索到叶子节点时，比较与目标和的值，若相同，则结果为真，若搜索完毕没有出现目标和，返回假
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+
+public class Solution {
+    /**
+     * @param root: the tree
+     * @param sum: the sum
+     * @return:  if the tree has a root-to-leaf path 
+     */
+    public boolean pathSum(TreeNode root, int sum) {
+        // Write your code here.
+        if (root == null) return false;
+        else if (root.val == sum && root.left == null && root.right == null) return true;
+        else return pathSum(root.left, sum - root.val) || pathSum(root.right, sum - root.val);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/remove-substrings.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/remove-substrings.md"
new file mode 100644
index 0000000..a43ea92
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/remove-substrings.md"
@@ -0,0 +1,70 @@
+# 移除子串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-substrings/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个字符串 `s` 以及 `n` 个子串。你可以从字符串 s 中移除 n 个子串中的任意一个，使得剩下来s的长度最小，输出这个最小长度。
+ ### 样例说明
+ 例1:
+```
+输入:
+"ccdaabcdbb"
+["ab","cd"]
+输出:
+2
+解释: 
+ccdaabcdbb -> ccdacdbb -> cabb -> cb (length = 2)
+```
+
+例2:
+```
+输入:
+"abcabd"
+["ab","abcd"]
+输出:
+0
+解释: 
+abcabd -> abcd -> "" (length = 0)
+```
+
+ ### 参考代码
+ 利用bfs。
+在可以删除的每一个地方，尝试删除。
+```cpp
+class Solution {
+public:
+    /**
+     * @param s a string
+     * @param dict a set of n substrings
+     * @return the minimum length
+     */
+    int minLength(string& s, set<string>& dict) {
+        // Write your code here
+        queue<string> que;
+        unordered_set<string> hash;
+    
+        int min = s.size();
+        que.push(s);
+        hash.insert(s);
+
+        while (!que.empty()) {
+            string s = que.front();
+            que.pop();
+            for (auto& sub : dict) {
+                int found = s.find(sub);
+                while (found != -1) {
+                    string new_s = s.substr(0, found) +
+                        s.substr(found + sub.size(), s.size() - found - sub.size());
+                    if (hash.find(new_s) == hash.end()) {
+                        if (new_s.size() < min)
+                            min = new_s.size();
+                        que.push(new_s);
+                        hash.insert(new_s);
+                    }
+                    found = s.find(sub, found + 1);
+                }
+            }
+        }
+        return min;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/route-between-two-nodes-in-graph.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/route-between-two-nodes-in-graph.md"
new file mode 100644
index 0000000..21c13d8
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/route-between-two-nodes-in-graph.md"
@@ -0,0 +1,68 @@
+# 图中两个点之间的路线
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/route-between-two-nodes-in-graph/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一张有向图，设计一个算法判断两个点 `s` 与 `t` 之间是否存在路线。
+ ### 样例说明
+ 如下图:
+```
+	A----->B----->C
+	 \     |
+	  \    |
+	   \   |
+	    \  v
+	     ->D----->E
+			 
+样例 1:
+输入:s = B and t = E,
+输出:true
+
+样例 2:
+输入:s = D and t = C,
+输出:false
+```
+ ### 参考代码
+ ```java
+/**
+ * Definition for Directed graph.
+ * class DirectedGraphNode {
+ *     int label;
+ *     ArrayList<DirectedGraphNode> neighbors;
+ *     DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }
+ * };
+ */
+public class Solution {
+   /**
+     * @param graph: A list of Directed graph node
+     * @param s: the starting Directed graph node
+     * @param t: the terminal Directed graph node
+     * @return: a boolean value
+     */
+    public boolean hasRoute(ArrayList<DirectedGraphNode> graph,
+                                 DirectedGraphNode s, DirectedGraphNode t) {
+        if (s == t)
+            return true;
+
+        HashSet<DirectedGraphNode> visited = new HashSet<DirectedGraphNode>();
+        Queue<DirectedGraphNode> queue = new LinkedList<DirectedGraphNode>();
+        
+        queue.offer(s);
+        visited.add(s);
+        while (!queue.isEmpty()) {
+            DirectedGraphNode node = queue.poll();
+            for (int i = 0; i < node.neighbors.size(); i++) {
+                if (visited.contains(node.neighbors.get(i))) {
+                    continue;
+                }
+                visited.add(node.neighbors.get(i));
+                queue.offer(node.neighbors.get(i));
+                if (node.neighbors.get(i) == t) {
+                    return true;
+                }
+            }
+        }
+        
+        return false;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/search-graph-nodes.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/search-graph-nodes.md"
new file mode 100644
index 0000000..cca0ddf
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/search-graph-nodes.md"
@@ -0,0 +1,95 @@
+# 搜索图中节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/search-graph-nodes/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一张 `无向图`，一个 `节点` 以及一个 `目标值`，返回距离这个节点最近 且 值为目标值的节点，如果不能找到则返回 `NULL`。
+在给出的参数中, 我们用 `map` 来存节点的值
+
+ ### 样例说明
+ 例1:
+```
+输入:
+{1,2,3,4#2,1,3#3,1,2#4,1,5#5,4}
+[3,4,5,50,50]
+1
+50
+输出:
+4
+解释:
+2------3  5
+ \     |  | 
+  \    |  |
+   \   |  |
+    \  |  |
+      1 --4
+Give a node 1, target is 50
+
+there a hash named values which is [3,4,10,50,50], represent:
+Value of node 1 is 3
+Value of node 2 is 4
+Value of node 3 is 10
+Value of node 4 is 50
+Value of node 5 is 50
+
+Return node 4
+```
+
+例2:
+```
+输入:
+{1,2#2,1}
+[0,1]
+1
+1
+输出:
+2
+```
+
+ ### 参考代码
+ 朴素bfs即可。
+```java
+/**
+ * Definition for graph node.
+ * class GraphNode {
+ *     int label;
+ *     ArrayList<UndirectedGraphNode> neighbors;
+ *     UndirectedGraphNode(int x) { 
+ *         label = x; neighbors = new ArrayList<UndirectedGraphNode>(); 
+ *     }
+ * };
+ */
+public class Solution {
+    /**
+     * @param graph a list of Undirected graph node
+     * @param values a hash mapping, <UndirectedGraphNode, (int)value>
+     * @param node an Undirected graph node
+     * @param target an integer
+     * @return the a node
+     */
+    public UndirectedGraphNode searchNode(ArrayList<UndirectedGraphNode> graph,
+                                          Map<UndirectedGraphNode, Integer> values,
+                                          UndirectedGraphNode node,
+                                          int target) {
+        // Write your code here
+        Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
+        Set<UndirectedGraphNode> hash = new HashSet<UndirectedGraphNode>();
+
+        queue.offer(node);
+        hash.add(node);
+
+        while (!queue.isEmpty()) {
+            UndirectedGraphNode head = queue.poll();
+            if (values.get(head) == target) {
+                return head;
+            }
+            for (UndirectedGraphNode nei : head.neighbors) {
+                if (!hash.contains(nei)){
+                    queue.offer(nei);
+                    hash.add(nei);
+                }
+            }
+        }
+        return null;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/shortest-path-to-the-destination.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/shortest-path-to-the-destination.md"
new file mode 100644
index 0000000..d69d5ef
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/shortest-path-to-the-destination.md"
@@ -0,0 +1,98 @@
+# 目的地的最短路径
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/shortest-path-to-the-destination/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定表示地图上坐标的2D数组，地图上只有值`0,1,2`.`0`表示可以通过，`1`表示不可通过，`2`表示目标位置。从坐标`[0,0]`开始，你只能上，下，左，右移动。找到可以到达目的地的最短路径，并返回路径的长度。
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+[
+ [0, 0, 0],
+ [0, 0, 1],
+ [0, 0, 2]
+]
+输出: 4
+说明: [0,0] -> [1,0] -> [2,0] -> [2,1] -> [2,2]
+```
+
+**样例2**
+
+```plain
+输入:
+[
+    [0,1],
+    [0,1],
+    [0,0],
+    [0,2]
+]
+输出: 4
+说明: [0,0] -> [1,0] -> [2,0] -> [3,0] -> [3,1]
+```
+
+
+ ### 参考代码
+ 使用双向宽度优先搜索的版本
+```python
+from collections import deque
+
+DIRECTIONS = [
+    (1, 0),
+    (0, -1),
+    (-1, 0),
+    (0, 1),
+]
+
+
+class Solution:
+    """
+    @param targetMap: 
+    @return: nothing
+    """
+    def shortestPath(self, targetMap):
+        queue1 = deque([(0, 0)])
+        target_x, target_y = self.find_target(targetMap)
+        queue2 = deque([(target_x, target_y)])
+        visited = {(0, 0): 1, (target_x, target_y): 2}
+        
+        distance = 0
+        while queue1 or queue2:
+            found = self.extend_to_next_level(targetMap, queue1, visited, 1)
+            if found:
+                return distance
+            distance += 1
+            found = self.extend_to_next_level(targetMap, queue2, visited, 2)
+            if found:
+                return distance
+            distance += 1
+        return -1
+        
+    def extend_to_next_level(self, targetMap, queue, visited, flag):
+        for _ in range(len(queue)):
+            x, y = queue.popleft()
+            if visited.get((x, y)) == 3 - flag:
+                return True
+            for delta_x, delta_y in DIRECTIONS:
+                _x = x + delta_x
+                _y = y + delta_y
+                if not self.is_valid(_x, _y, targetMap):
+                    continue
+                if visited.get((_x, _y)) == flag:
+                    continue
+                queue.append((_x, _y))
+                visited[(_x, _y)] = flag
+        return False
+        
+    def is_valid(self, x, y, targetMap):
+        if not 0 <= x < len(targetMap) or not 0 <= y < len(targetMap[0]):
+            return False
+        return targetMap[x][y] != 1
+        
+    def find_target(self, targetMap):
+        for i, row in enumerate(targetMap):
+            for j, num in enumerate(row):
+                if num == 2:
+                    return i, j
+        return -1, -1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/shortest-path-visiting-all-nodes.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/shortest-path-visiting-all-nodes.md"
new file mode 100644
index 0000000..1b0c52b
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/shortest-path-visiting-all-nodes.md"
@@ -0,0 +1,60 @@
+# 访问所有节点的最短路径
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/shortest-path-visiting-all-nodes/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出 `graph` 为有 N 个节点（编号为 `0, 1, 2, ..., N-1`）的无向连通图。 
+
+`graph.length = N`，且只有节点 `i` 和 `j` 连通时，`j != i` 在列表 `graph[i]` 中恰好出现一次。
+
+返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止，也可以多次重访节点，并且可以重用边。
+ ### 样例说明
+ **样例 1:**
+```
+输入：graph = [[1,2,3],[0],[0],[0]]
+输出：4
+解释：
+一个可能的路径为 [1,0,2,0,3]
+```
+**样例 2:**
+```
+输入：graph = [[1],[0,2,4],[1,3,4],[2],[1,2]]
+输出：4
+解释：
+一个可能的路径为 [0,1,4,2,3]
+```
+ ### 参考代码
+ 注意题目中的节点个数是 <= 12 的，这是突破口。
+可以使用状态压缩的方式记录有哪些点被访问过了。
+存在 BFS Queue 中的是一个二元组 `<visited, stop_at>`
+
+1. visited 可以理解为是一个 boolean 数组，但是为了更方便查询，我们用二进制的方式来表示 visited。
+也就是说，如果所有点都没有被访问过，visited = 0，如果只访问了标号0和2的点，那么 visited = (101)2 = 5
+每次访问一个新的点只需要让 `visited | 1 << node` 即可算出新的 visited。
+2. stop_at 记录的是访问了 visited 这些点以后，停在哪儿了。
+```python
+from collections import deque
+
+
+class Solution:
+    def shortestPathLength(self, graph: List[List[int]]) -> int:
+        queue = deque([])
+        distance = {}
+        n = len(graph)
+        for start in range(n):
+            state = (1 << start, start)
+            queue.append(state)
+            distance[state] = 0
+            
+        while queue:
+            visited, stop_at = queue.popleft()
+            for neighbor in graph[stop_at]:
+                _visited = visited | (1 << neighbor)
+                if (_visited, neighbor) in distance:
+                    continue
+                queue.append((_visited, neighbor))
+                distance[(_visited, neighbor)] = distance[(visited, stop_at)] + 1
+                if _visited == (1 << n) - 1:
+                    return distance[(_visited, neighbor)]
+                
+        return 0
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/similar-string-groups.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/similar-string-groups.md"
new file mode 100644
index 0000000..6811ce8
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/similar-string-groups.md"
@@ -0,0 +1,186 @@
+# 相似字符串组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/similar-string-groups/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 如果我们交换字符串 X 中的两个不同位置的字母，使得它和字符串 Y 相等，那么称 X 和 Y 两个字符串相似。
+
+例如，"tars" 和 "rats" 是相似的 (交换 0 与 2 的位置)； "rats" 和 "arts" 也是相似的，但是 "star" 不与 "tars"，"rats"，或 "arts" 相似。
+
+总之，它们通过相似性形成了两个关联组：{"tars", "rats", "arts"} 和 {"star"}。注意，"tars" 和 "arts" 是在同一组中，即使它们并不相似。形式上，对每个组而言，要确定一个单词在组中，只需要这个词和该组中至少一个单词相似。
+
+我们给出了一个不包含重复的字符串列表 A。列表中的每个字符串都是 A 中其它所有字符串的一个字母异位词。请问 A 中有多少个相似字符串组？
+ ### 样例说明
+ **样例 1:**
+```
+输入: ["tars","rats","arts","star"]
+输出: 2
+```
+
+**样例 2:**
+```
+输入: ["omv","ovm"]
+输出:1
+```
+ ### 参考代码
+ 找连通块的个数。BFS 也可以做。
+只需要 for 每个单词，从每个单词出发标记 相似单词，看看一共标记几次即可。
+这里有一个 tricky 的地方是，在找相似单词的时候，有两种做法：
+- 做法1: 交换两个位置，然后看看在 wordSet 里有没有出现 $O(L^3)$
+- 做法2: for wordSet 里的每个单词看看字符不同的位置是不是 2 个 $O(NL)$
+
+其中 N 是单词个数，L是单词长度，这两个方法不一定哪个好，可以比较 $N$ 和 $L^2$ 的大小来决定使用哪个。
+
+```
+[[python]]
+class Solution:
+    def numSimilarGroups(self, strs):
+        word_set = set(strs)
+        visited = set()
+        
+        similar_set = 0
+        for word in strs:
+            if word in visited:
+                continue
+            similar_set += 1
+            self.mark_similar_set(word, word_set, visited)
+        
+        return similar_set
+        
+    def mark_similar_set(self, word, word_set, visited):
+        from collections import deque
+        queue = deque([word])
+        visited.add(word)
+        while queue:
+            word = queue.popleft()
+            for neighbor in self.get_neighbor_words(word, word_set):
+                if neighbor in visited:
+                    continue
+                queue.append(neighbor)
+                visited.add(neighbor)
+        
+    def get_neighbor_words(self, word, word_set):
+        if len(word) ** 2 < len(word_set):
+            return self.get_neighbor_words1(word, word_set)
+        return self.get_neighbor_words2(word, word_set)
+        
+    def get_neighbor_words1(self, word, word_set):
+        # O(L^3)
+        n = len(word)
+        chars = list(word)
+        neighbor_words = []
+        for i in range(n):
+            for j in range(i + 1, n):
+                chars[i], chars[j] = chars[j], chars[i]
+                anagram = ''.join(chars)
+                if anagram in word_set:
+                    neighbor_words.append(anagram)
+                chars[i], chars[j] = chars[j], chars[i]
+        return neighbor_words    
+
+    def get_neighbor_words2(self, word, word_set):
+        # O(N*L)
+        neighbors = []
+        for neighbor in word_set:
+            if self.is_similar(word, neighbor):
+                neighbors.append(neighbor)
+        return neighbors
+
+    def is_similar(self, word1, word2):
+        diff = 0
+        for c1, c2 in zip(word1, word2):
+            if c1 != c2:
+                diff += 1
+        return diff == 2
+[[java]]
+public class Solution {
+    /**
+     * @param A: a string array
+     * @return: the number of groups 
+     */
+    public int numSimilarGroups(String[] strs) {
+        Set<String> wordSet = new HashSet<>();
+        Set<String> visited = new HashSet<>();
+        for (int i = 0; i < strs.length; i++) {
+            wordSet.add(strs[i]);
+        }
+        
+        int similarSet = 0;
+        for (String word : strs) {
+            if (visited.contains(word)) {
+                continue;
+            }
+            similarSet += 1;
+            markSimilarSet(word, wordSet, visited);
+        }
+        
+        return similarSet;
+    }
+    
+    private void markSimilarSet(String word, Set<String> wordSet, Set<String> visited) {
+        Queue<String> queue = new ArrayDeque<>();
+        queue.offer(word);
+        visited.add(word);
+        while (!queue.isEmpty()) {
+           word = queue.poll();
+            for (String neighbor : getNeighborWords(word, wordSet)) {
+                if (visited.contains(neighbor)) {
+                    continue;
+                }
+                queue.offer(neighbor);
+                visited.add(neighbor);
+            }
+        }
+    }
+    
+    private List<String> getNeighborWords(String word, Set<String> wordSet) {
+        if (word.length() * word.length() < wordSet.size()) {
+            return getNeighborWords1(word, wordSet);
+        } 
+        return getNeighborWords2(word, wordSet);
+    }
+    
+    private List<String> getNeighborWords1(String word, Set<String> wordSet) {
+        int n = word.length();
+        char[] chars = word.toCharArray();
+        List<String> neighbors = new ArrayList<>();
+        for (int i = 0; i < n; i++) {
+            for (int j = i + 1; j < n; j++) {
+                char temp = chars[i];
+                chars[i] = chars[j];
+                chars[j] = temp;
+                String anagram = String.valueOf(chars);
+                if (wordSet.contains(anagram)) {
+                    neighbors.add(anagram);
+                }
+                temp = chars[i];
+                chars[i] = chars[j];
+                chars[j] = temp;
+            }
+        }
+        
+        return neighbors;
+    }
+    
+    private List<String> getNeighborWords2(String word, Set<String> wordSet) {
+        List<String> neighbors = new ArrayList<>();
+        for (String neighbor : wordSet) {
+            if (isSimilar(word, neighbor)) {
+                neighbors.add(neighbor);
+            }
+        }
+        
+        return neighbors;
+    }
+    
+    private boolean isSimilar(String word1, String word2) {
+        int diff = 0;
+        for (int i = 0; i < word1.length(); i++) {
+            if (word1.charAt(i) != word2.charAt(i)) {
+                diff++;
+            }
+        }
+        
+        return diff == 2;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/six-degrees.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/six-degrees.md"
new file mode 100644
index 0000000..24ee10c
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/six-degrees.md"
@@ -0,0 +1,82 @@
+# 六度问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/six-degrees/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 六度分离是一个哲学问题，说的是每个人每个东西可以通过六步或者更少的步数建立联系。
+
+现在给你一个友谊关系，查询两个人可以通过几步相连，如果不相连返回 `-1`
+ ### 样例说明
+ **样例1**
+
+```
+输入: {1,2,3#2,1,4#3,1,4#4,2,3} 和 s = 1, t = 4 
+输出: 2
+解释:
+    1------2-----4
+     \          /
+      \        /
+       \--3--/
+```
+
+**样例2**
+
+```
+输入: {1#2,4#3,4#4,2,3} 和 s = 1, t = 4
+输出: -1
+解释:
+    1      2-----4
+                 /
+               /
+              3
+```
+ ### 参考代码
+ 直接用bfs进行搜索，找答案
+```java
+/**
+ * Definition for Undirected graph.
+ * class UndirectedGraphNode {
+ *     int label;
+ *     List<UndirectedGraphNode> neighbors;
+ *     UndirectedGraphNode(int x) { 
+ *         label = x;
+ *         neighbors = new ArrayList<UndirectedGraphNode>(); 
+ *     }
+ * };
+ */
+public class Solution {
+    /**
+     * @param graph a list of Undirected graph node
+     * @param s, t two Undirected graph nodes
+     * @return an integer
+     */
+    public int sixDegrees(List<UndirectedGraphNode> graph,
+                          UndirectedGraphNode s,
+                          UndirectedGraphNode t) {
+        // Write your code here
+        if (s == t)
+            return 0;
+
+        Map<UndirectedGraphNode, Integer> visited = new HashMap<UndirectedGraphNode, Integer>();
+        Queue<UndirectedGraphNode> queue = new LinkedList<UndirectedGraphNode>();
+        
+        queue.offer(s);
+        visited.put(s, 0);
+        while (!queue.isEmpty()) {
+            UndirectedGraphNode node = queue.poll();
+            int step = visited.get(node);
+            for (int i = 0; i < node.neighbors.size(); i++) {
+                if (visited.containsKey(node.neighbors.get(i))) {
+                    continue;
+                }
+                visited.put(node.neighbors.get(i), step + 1);
+                queue.offer(node.neighbors.get(i));
+                if (node.neighbors.get(i) == t) {
+                    return step + 1;
+                }
+            }
+        }
+        
+        return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sliding-puzzle-ii.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sliding-puzzle-ii.md"
new file mode 100644
index 0000000..2cf3402
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sliding-puzzle-ii.md"
@@ -0,0 +1,341 @@
+# 滑动拼图 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sliding-puzzle-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个3x3的网格中，放着编号1到8的8块板，以及一块编号为0的空格。
+一次**移动**可以把空格0与上下左右四邻接之一的板子交换。
+给定初始和目标的板子排布，返回到目标排布最少的移动次数。
+如果不能从初始排布移动到目标排布，返回-1.
+ ### 样例说明
+ **样例1 ：**
+```
+输入:
+[
+ [2,8,3],
+ [1,0,4],
+ [7,6,5]
+]
+[
+ [1,2,3],
+ [8,0,4],
+ [7,6,5]
+]
+输出:
+4
+
+解释:
+[                 [
+ [2,8,3],          [2,0,3],
+ [1,0,4],   -->    [1,8,4],
+ [7,6,5]           [7,6,5]
+]                 ]
+
+[                 [
+ [2,0,3],          [0,2,3],
+ [1,8,4],   -->    [1,8,4],
+ [7,6,5]           [7,6,5]
+]                 ]
+
+[                 [
+ [0,2,3],          [1,2,3],
+ [1,8,4],   -->    [0,8,4],
+ [7,6,5]           [7,6,5]
+]                 ]
+
+[                 [
+ [1,2,3],          [1,2,3],
+ [0,8,4],   -->    [8,0,4],
+ [7,6,5]           [7,6,5]
+]                 ]
+```
+
+**样例 2：**
+```
+输入:
+[[2,3,8],[7,0,5],[1,6,4]]
+[[1,2,3],[8,0,4],[7,6,5]]
+输出:
+-1
+```
+ ### 参考代码
+ 使用单向 BFS 算法
+```
+[[java]]
+public class Solution {
+    /**
+     * @param init_state: the initial state of chessboard
+     * @param final_state: the final state of chessboard
+     * @return: return an integer, denote the number of minimum moving
+     */
+    public int minMoveStep(int[][] init_state, int[][] final_state) {
+        String source = matrixToString(init_state);
+        String target = matrixToString(final_state);
+        
+        Queue<String> queue = new LinkedList<>();
+        Map<String, Integer> distance = new HashMap<>();
+        
+        queue.offer(source);
+        distance.put(source, 0);
+        
+        while (!queue.isEmpty()) {
+            String curt = queue.poll();
+            if (curt.equals(target)) {
+                return distance.get(curt);
+            }
+            
+            for (String next : getNext(curt)) {
+                if (distance.containsKey(next)) {
+                    continue;
+                }
+                queue.offer(next);
+                distance.put(next, distance.get(curt) + 1);
+            }
+        }
+        
+        return -1;
+    }
+    
+    public String matrixToString(int[][] state) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                sb.append(state[i][j]);
+            }
+        }
+        return sb.toString();
+    }
+    
+    public List<String> getNext(String state) {
+        List<String> states = new ArrayList<>();
+        int[] dx = {0, 1, -1, 0};
+        int[] dy = {1, 0, 0, -1};
+        
+        int zeroIndex = state.indexOf('0');
+        int x = zeroIndex / 3;
+        int y = zeroIndex % 3;
+        
+        for (int i = 0; i < 4; i++) {
+            int x_ = x + dx[i];
+            int y_ = y + dy[i];
+            if (x_ < 0 || x_ >= 3 || y_ < 0 || y_ >= 3) {
+                continue;
+            }
+            
+            char[] chars = state.toCharArray();
+            chars[x * 3 + y] = chars[x_ * 3 + y_];
+            chars[x_ * 3 + y_] = '0';
+            states.add(new String(chars));
+        }
+        
+        return states;
+    }
+}
+[[python]]
+class Solution:
+    def get_next(self, state):
+        states = []
+        dirction = ((0, 1), (1, 0), (-1, 0), (0, -1))
+        
+        zero_index = state.find('0')
+        x, y = zero_index // 3, zero_index % 3
+        
+        for i in range(4):
+            x_, y_ = x + dirction[i][0], y + dirction[i][1]
+            if 0 <= x_ < 3 and 0 <= y_ < 3:
+                next_state = list(state)
+                next_state[x * 3 + y] = next_state[x_ * 3 + y_]
+                next_state[x_ * 3 + y_] = '0'
+                states.append("".join(next_state))
+        return states
+    
+    def minMoveStep(self, init_state, final_state):
+        source = self.matrix_to_string(init_state)
+        target = self.matrix_to_string(final_state)
+
+        from collections import deque
+        queue = deque([source])
+        distance = {source: 0}
+        
+        while queue:
+            curt = queue.popleft()
+            if curt == target:
+                return distance[curt]
+                
+            for next in self.get_next(curt):
+                if next in distance:
+                    continue
+                
+                queue.append(next)
+                distance[next] = distance[curt] + 1
+        
+        return -1
+        
+    def matrix_to_string(self, state):
+        str_list = []
+        for i in range(3):
+            for j in range(3):
+                str_list.append(str(state[i][j]))
+        return "".join(str_list)
+```
+
+使用双向 BFS 算法。可以把这份代码当模板背诵。
+
+```
+[[java]]
+public class Solution {
+    /**
+     * @param init_state: the initial state of chessboard
+     * @param final_state: the final state of chessboard
+     * @return: return an integer, denote the number of minimum moving
+     */
+    public int minMoveStep(int[][] init_state, int[][] final_state) {
+        String source = matrixToString(init_state);
+        String target = matrixToString(final_state);
+        
+        if (source.equals(target)) {
+            return 0;
+        }
+        
+        Queue<String> forwardQueue = new ArrayDeque<>();
+        Set<String> forwardSet = new HashSet<>();
+        forwardQueue.offer(source);
+        forwardSet.add(source);
+
+        Queue<String> backwardQueue = new ArrayDeque<>();
+        Set<String> backwardSet = new HashSet<>();
+        backwardQueue.offer(target);
+        backwardSet.add(target);
+        
+        int steps = 0;
+        while (!forwardQueue.isEmpty() && !backwardQueue.isEmpty()) {
+            steps++;
+            if (extendQueue(forwardQueue, forwardSet, backwardSet)) {
+                return steps;
+            }
+            
+            steps++;
+            if (extendQueue(backwardQueue, backwardSet, forwardSet)) {
+                return steps;
+            }
+        }
+        
+        return -1;
+    }
+    
+    private boolean extendQueue(Queue<String> queue,
+                                Set<String> set,
+                                Set<String> targetSet) {
+        int size = queue.size();
+        for (int i = 0; i < size; i++) {
+            String curt = queue.poll();
+            for (String next : getNext(curt)) {
+                if (set.contains(next)) {
+                    continue;
+                }
+                if (targetSet.contains(next)) {
+                    return true;
+                }
+                queue.offer(next);
+                set.add(next);
+            }
+        }
+        return false;
+    }
+    
+    public String matrixToString(int[][] state) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                sb.append(state[i][j]);
+            }
+        }
+        return sb.toString();
+    }
+    
+    public List<String> getNext(String state) {
+        List<String> states = new ArrayList<>();
+        int[] dx = {0, 1, -1, 0};
+        int[] dy = {1, 0, 0, -1};
+        
+        int zeroIndex = state.indexOf('0');
+        int x = zeroIndex / 3;
+        int y = zeroIndex % 3;
+        
+        for (int i = 0; i < 4; i++) {
+            int x_ = x + dx[i];
+            int y_ = y + dy[i];
+            if (x_ < 0 || x_ >= 3 || y_ < 0 || y_ >= 3) {
+                continue;
+            }
+            
+            char[] chars = state.toCharArray();
+            chars[x * 3 + y] = chars[x_ * 3 + y_];
+            chars[x_ * 3 + y_] = '0';
+            states.add(new String(chars));
+        }
+        
+        return states;
+    }
+}
+[[python]]
+class Solution:
+    
+    def minMoveStep(self, init_state, final_state):
+        source = self.matrix_to_string(init_state)
+        target = self.matrix_to_string(final_state)
+
+        from collections import deque
+        forward_queue = deque([source])
+        forward_set = set([source])
+        
+        backward_queue = deque([target])
+        backward_set = set([target])
+        
+        steps = 0
+        while forward_queue and backward_queue:
+            steps += 1
+            if self.extend_queue(forward_queue, forward_set, backward_set):
+                return steps
+                
+            steps += 1
+            if self.extend_queue(backward_queue, backward_set, forward_set):
+                return steps
+        
+        return -1
+        
+    def extend_queue(self, queue, source_set, target_set):
+        for i in range(len(queue)):
+            curt = queue.popleft()
+            for next in self.get_next(curt):
+                if next in source_set:
+                    continue
+                if next in target_set:
+                    return True
+                queue.append(next)
+                source_set.add(next)
+                
+        return False
+    
+    def matrix_to_string(self, state):
+        str_list = []
+        for i in range(3):
+            for j in range(3):
+                str_list.append(str(state[i][j]))
+        return "".join(str_list)
+        
+    def get_next(self, state):
+        states = []
+        dirction = ((0, 1), (1, 0), (-1, 0), (0, -1))
+        
+        zero_index = state.find('0')
+        x, y = zero_index // 3, zero_index % 3
+        
+        for i in range(4):
+            x_, y_ = x + dirction[i][0], y + dirction[i][1]
+            if 0 <= x_ < 3 and 0 <= y_ < 3:
+                next_state = list(state)
+                next_state[x * 3 + y] = next_state[x_ * 3 + y_]
+                next_state[x_ * 3 + y_] = '0'
+                states.append("".join(next_state))
+        return states
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/surrounded-regions.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/surrounded-regions.md"
new file mode 100644
index 0000000..ced44fa
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/surrounded-regions.md"
@@ -0,0 +1,59 @@
+# 被围绕的区域
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/surrounded-regions/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个二维的矩阵，包含 `'X'` 和 `'O'`, 找到所有被 `'X'` 围绕的区域，并用 `'X'` 替换其中所有的 `'O'`。
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  X X X X
+  X O O X
+  X X O X
+  X O X X
+输出: 
+  X X X X
+  X X X X
+  X X X X
+  X O X X
+```
+
+**样例 2:**
+
+```
+输入: 
+  X X X X
+  X O O X
+  X O O X
+  X O X X
+输出: 
+  X X X X
+  X O O X
+  X O O X
+  X O X X
+```
+ ### 参考代码
+ 高频题班的版本，使用 BFS 的方法
+先把从边界开始的 O 都标记为 W，这样非 W 的地方就全都需要标记为 X
+```python
+// version: 高频题班
+class Solution:
+    # @param {list[list[str]]} board a 2D board containing 'X' and 'O'
+    # @return nothing 
+    def surroundedRegions(self, board):
+        # Write your code here
+        if not any(board):
+            return
+
+        n, m = len(board), len(board[0])
+        q = [ij for k in range(max(n,m)) for ij in ((0, k), (n-1, k), (k, 0), (k, m-1))]
+        while q:
+            i, j = q.pop()
+            if 0 <= i < n and 0 <= j < m and board[i][j] == 'O':
+                board[i][j] = 'W'
+                q += (i, j-1), (i, j+1), (i-1, j), (i+1, j)
+
+        board[:] = [['XO'[c == 'W'] for c in row] for row in board]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/the-maze-iii.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/the-maze-iii.md"
new file mode 100644
index 0000000..1381f73
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/the-maze-iii.md"
@@ -0,0 +1,133 @@
+# 迷宫III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/the-maze-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在迷宫中有一个球，里面有空的空间和墙壁。球可以通过滚`up (u)`、`down (d)`、`left (l)`或右`right (r)`来穿过空的空间，`但它不会停止滚动直到撞到墙上`。当球停止时，它可以选择下一个方向。在这个迷宫里还有一个洞。如果球滚到洞里，球就会掉进洞里。
+给定球的位置、洞的位置和迷宫，找出球如何通过移动`最短距离`落入洞内。距离是由球从起始位置(被排除)到洞(包括)所走过的空空间的数量来定义的。`用“u”、“d”、“l”和“r”来输出移动的方向`。由于可能有几种不同的最短路径，所以你应该输出字母顺序中（移动顺序中）最短的方法。如果球打不进洞，输出“impossible”。
+迷宫由二维数组表示。1表示墙和0表示空的空间。你可以假设迷宫的边界都是墙。球和孔坐标用行和列的坐标表示。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+[[0,0,0,0,0],[1,1,0,0,1],[0,0,0,0,0],[0,1,0,0,1],[0,1,0,0,0]]
+[4,3]
+[0,1]
+
+输出:
+"lul"
+```
+**样例 2:**
+```
+输入:
+[[0,0,0,0,0],[1,1,0,0,1],[0,0,0,0,0],[0,1,0,0,1],[0,1,0,0,0]]
+[0,0]
+[1,1]
+[2,2]
+[3,3]
+输出:
+"impossible"
+```
+
+ ### 参考代码
+ 使用 BFS 算法。BFS 的每一步拓展一直走到撞墙为止。因为和最后要求的步数计算方法不同，所以一个点可能会被重复更新。
+重复更新当且仅当发现一条更优路径，就重新放到队列里继续拓展。直到没有任何的节点能被更新，就退出。
+```java
+public class Solution {
+    class Point {
+        int x, y;
+        public Point(int x, int y) {
+            this.x = x;
+            this.y = y;
+        }
+    }
+    
+    class DistAndPath implements Comparable<DistAndPath> {
+        int dist;
+    	String path;
+    	
+    	public DistAndPath(int dist, String path) {
+    		this.dist = dist;
+    		this.path = path;
+    	}
+    	
+    	public int compareTo(DistAndPath other) {
+    	    if (this.dist != other.dist) {
+    	        return this.dist - other.dist;
+    	    }
+    	    
+    	    return path.compareTo(other.path);
+    	}
+    }
+    
+    public int[] dx = {0, 1, 0, -1};
+    public int[] dy = {1, 0, -1, 0};
+    public String[] directStr = {"r", "d", "l", "u"};
+
+    /**
+     * @param maze: the maze
+     * @param ball: the ball position
+     * @param hole: the hole position
+     * @return: the lexicographically smallest way
+     */
+    public String findShortestWay(int[][] maze, int[] ball, int[] hole) {
+        if (maze == null || maze.length == 0 || maze[0] == null || maze[0].length == 0) {
+            return "impossible";
+        }
+        
+        int n = maze.length;
+        int m = maze[0].length;
+        
+        DistAndPath[][] cost = new DistAndPath[n][m];
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < m; j++) {
+                cost[i][j] = new DistAndPath(Integer.MAX_VALUE, "");
+            }
+        }
+    
+        cost[ball[0]][ball[1]].dist = 0;
+ 
+        Queue<Point> queue = new LinkedList<>();
+        queue.offer(new Point(ball[0], ball[1]));
+        
+        while (!queue.isEmpty()) {
+            Point curt = queue.poll();
+            for (int d = 0; d < 4; d++) {
+                Point next = new Point(curt.x, curt.y);
+                DistAndPath dp = new DistAndPath(cost[curt.x][curt.y].dist, cost[curt.x][curt.y].path + directStr[d]);
+                while (!isWall(maze, next.x + dx[d], next.y + dy[d])) {
+                    next.x += dx[d];
+                    next.y += dy[d];
+                    dp.dist += 1;
+                    
+                    if (next.x == hole[0] && next.y == hole[1]) {
+                        break;
+                    }
+                }
+                if (cost[next.x][next.y].compareTo(dp) > 0) {
+                    cost[next.x][next.y] = dp;
+                    if (next.x != hole[0] || next.y != hole[1]) {
+                        queue.offer(next);
+                    }
+                }
+            }
+        }
+        
+        if (cost[hole[0]][hole[1]].dist == Integer.MAX_VALUE) {
+            return "impossible";
+        }
+        
+        return cost[hole[0]][hole[1]].path;
+    }
+    
+    private boolean isWall(int[][] maze, int x, int y) {
+        int n = maze.length;
+        int m = maze[0].length;
+        
+        if (x < 0 || x >= n || y < 0 || y >= m) {
+            return true;
+        }
+        
+        return maze[x][y] == 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/topological-sorting.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/topological-sorting.md"
new file mode 100644
index 0000000..9dac726
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/topological-sorting.md"
@@ -0,0 +1,105 @@
+# 拓扑排序
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/topological-sorting/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个有向图，图节点的拓扑排序定义如下:
+
+- 对于图中的每一条有向边 `A -> B` , 在拓扑排序中A一定在B之前.
+- 拓扑排序中的第一个节点可以是图中的任何一个没有其他节点指向它的节点.
+
+针对给定的有向图找到任意一种拓扑排序的顺序.
+ ### 样例说明
+ 
+ ### 参考代码
+ 使用 BFS 的版本。
+```
+[[python]]
+"""
+Definition for a Directed graph node
+class DirectedGraphNode:
+    def __init__(self, x):
+        self.label = x
+        self.neighbors = []
+"""
+
+class Solution:
+    """
+    @param graph: A list of Directed graph node
+    @return: Any topological order for the given graph.
+    """
+    def topSort(self, graph):
+        node_to_indegree = self.get_indegree(graph)
+
+        # bfs
+        order = []
+        start_nodes = [n for n in graph if node_to_indegree[n] == 0]
+        queue = collections.deque(start_nodes)
+        while queue:
+            node = queue.popleft()
+            order.append(node)
+            for neighbor in node.neighbors:
+                node_to_indegree[neighbor] -= 1
+                if node_to_indegree[neighbor] == 0:
+                    queue.append(neighbor)
+                
+        return order
+    
+    def get_indegree(self, graph):
+        node_to_indegree = {x: 0 for x in graph}
+
+        for node in graph:
+            for neighbor in node.neighbors:
+                node_to_indegree[neighbor] += 1
+                
+        return node_to_indegree
+[[java]]
+/**
+ * Definition for Directed graph.
+ * class DirectedGraphNode {
+ *     int label;
+ *     ArrayList<DirectedGraphNode> neighbors;
+ *     DirectedGraphNode(int x) { label = x; neighbors = new ArrayList<DirectedGraphNode>(); }
+ * };
+ */
+
+public class Solution {
+    /*
+     * @param graph: A list of Directed graph node
+     * @return: Any topological order for the given graph.
+     */
+    public ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
+        ArrayList<DirectedGraphNode> order = new ArrayList<>();
+        Map<DirectedGraphNode, Integer> indegree = new HashMap<>();
+        for (DirectedGraphNode node : graph) {
+            for (DirectedGraphNode neighbor : node.neighbors) {
+                if (indegree.containsKey(neighbor)) {
+                    indegree.put(neighbor, indegree.get(neighbor) + 1);
+                } else {
+                    indegree.put(neighbor, 1);
+                }
+            }
+        }
+        
+        Queue<DirectedGraphNode> queue = new ArrayDeque<>();
+        for (DirectedGraphNode node : graph) {
+            if (!indegree.containsKey(node)) {
+                queue.offer(node);
+                order.add(node);
+            }
+        }
+        
+        while (!queue.isEmpty()) {
+            DirectedGraphNode node = queue.poll();
+            for (DirectedGraphNode neighbor : node.neighbors) {
+                indegree.put(neighbor, indegree.get(neighbor) - 1);
+                if (indegree.get(neighbor) == 0) {
+                    order.add(neighbor);
+                    queue.offer(neighbor);
+                }
+            }
+        }
+        
+        return order;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/tree.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/tree.md"
new file mode 100644
index 0000000..5f99cb0
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/tree.md"
@@ -0,0 +1,77 @@
+# 树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出两个list x，y，代表x[i]与y[i]之间有一条边，整个边集构成一棵树，`1`为根，现在有个list a,b，表示询问节点a[i]与b[i]是什么关系，如果a[i]与b[i]是兄弟，即有同一个父节点，输出`1`，如果a[i]与b[i]是父子关系，输出`2`，否则输出`0`。
+ ### 样例说明
+ **样例 1:**
+```
+输入； x = [1,1], y = [2,3], a =[1,2], b = [2,3]
+输出：[2,1]
+解释：1与2是父子关系，2与3是兄弟关系，它们的共同父节点为1。
+```
+
+
+**样例 2：**
+```
+输入：x = [1,1,2], y =[2,3,4], a = [1,2,1], b = [2,3,4]
+输出：[2,1,0]。
+解释：1与2是父子关系，2与3是兄弟关系，它们的共同父节点为1，1与4不是兄弟关系也不是父子关系。
+```
+
+ ### 参考代码
+ 两个考点：
+
+1. 是否知道怎么根据边来构图和存储图（邻接表）
+2. 是否知道可以通过 BFS 来确定父子关系
+
+```
+[[python]]
+class Solution:
+    """
+    @param x: The x
+    @param y: The y
+    @param a: The a
+    @param b: The b
+    @return: The Answer
+    """
+    def tree(self, x, y, a, b):
+        graph = self.build_graph(x, y)
+        parent = self.build_tree(graph)
+        
+        results = []
+        for u, v in zip(a, b):
+            if parent[u] == parent[v]:
+                results.append(1)
+            elif parent[u] == v or parent[v] == u:
+                results.append(2)
+            else:
+                results.append(0)
+        return results
+    
+    def build_graph(self, x, y):
+        graph = {}
+        for u, v in zip(x, y):
+            if u not in graph:
+                graph[u] = set()
+            if v not in graph:
+                graph[v] = set()
+            graph[u].add(v)
+            graph[v].add(u)
+        return graph
+        
+    def build_tree(self, graph):
+        from collections import deque
+        visited = set([1])
+        queue = deque([1])
+        parent = {1: None}
+        while queue:
+            node = queue.popleft()
+            for neighbor in graph[node]:
+                if neighbor in visited:
+                    continue
+                visited.add(neighbor)
+                queue.append(neighbor)
+                parent[neighbor] = node
+        return parent
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/nearest-exit.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/walls-and-gates.md"
similarity index 54%
rename from "\351\242\230\350\247\243/nearest-exit.md"
rename to "\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/walls-and-gates.md"
index edff3db..422ab01 100644
--- "a/\351\242\230\350\247\243/nearest-exit.md"
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/walls-and-gates.md"
@@ -1,61 +1,87 @@
-# Nearest Exit
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/nearest-exit/?utm_source=sc-github-wzz)
+# 墙和门
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/walls-and-gates/?utm_source=sc-github-wzz)
  ## 题目描述
- 1789
+ 您将获得一个使用这三个可能值初始化的 m×n 2D 网格。
+`-1` - 墙壁或障碍物。 
+`0` - 门。 
+`INF` - Infinity是一个空房间。我们使用值 `2 ^ 31 - 1 = 2147483647` 来表示INF，您可以假设到门的距离小于 `2147483647`。
+在代表每个空房间的网格中填入到距离最近门的距离。如果不可能到达门口，则应填入 `INF`。
  ### 样例说明
- 1789
+ **样例1**
+```
+输入：
+[[2147483647,-1,0,2147483647],[2147483647,2147483647,2147483647,-1],[2147483647,-1,2147483647,-1],[0,-1,2147483647,2147483647]]
+输出：
+[[3,-1,0,1],[2,2,1,-1],[1,-1,2,-1],[0,-1,3,4]]
+解释：
+2D网络为：
+INF  -1  0  INF
+INF INF INF  -1
+INF  -1 INF  -1
+  0  -1 INF INF
+答案为：
+  3  -1   0   1
+  2   2   1  -1
+  1  -1   2  -1
+  0  -1   3   4
+```
+**样例2**
+```
+输入：
+[[0,-1],[2147483647,2147483647]]
+输出：
+[[0,-1],[1,2]]
+```
  ### 参考代码
- <p><br></p>
+ 用bfs来解决此问题。
+一开始将所有的门push到队列中，然后bfs遍历整张图即可。
 ```java
-// version: 高频题班
-public class Solution {
-    /**
-     * @param rooms m x n 2D grid
-     * @return nothing
-     */
-    static final int INF = 2147483647;
-    int n, m;
-
-    public void wallsAndGates(int[][] rooms) {
-        // Write your code here
-        n = rooms.length;
-        if (n == 0) {
-            return;
-        }
-        m = rooms[0].length;
-
-        int dx[] = {0, 1, 0, -1};
-        int dy[] = {1, 0, -1, 0};
-
-        Queue<Integer> qx = new LinkedList<>();
-        Queue<Integer> qy = new LinkedList<>();
-
-        for (int i = 0; i < n; i++) {
-            for (int j = 0; j < m; j++) {
-                if (rooms[i][j] == 0) {
-                    qx.offer(i);
-                    qy.offer(j);
-                }
-            }
-        }
-
-        while (!qx.isEmpty()) {
-            int cx = qx.poll();
-            int cy = qy.poll();
-
-            for (int i = 0; i < 4; i++) {
-                int nx = cx + dx[i];
-                int ny = cy + dy[i];
-                if (0 <= nx && nx < n && 0 <= ny && ny < m
-                        && rooms[nx][ny] == INF) {
-                    qx.offer(nx);
-                    qy.offer(ny);
-                    rooms[nx][ny] = rooms[cx][cy] + 1;
-                }
-            }
-        }
-    }
-
+// version: 高频题班
+public class Solution {
+    /**
+     * @param rooms m x n 2D grid
+     * @return nothing
+     */
+
+    public void wallsAndGates(int[][] rooms) {
+        // Write your code here
+        int n = rooms.length;
+        if (n == 0) {
+            return;
+        }
+        int m = rooms[0].length;
+
+        int dx[] = {0, 1, 0, -1};
+        int dy[] = {1, 0, -1, 0};
+
+        Queue<Integer> qx = new LinkedList<>();
+        Queue<Integer> qy = new LinkedList<>();
+
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < m; j++) {
+                if (rooms[i][j] == 0) {
+                    qx.offer(i);
+                    qy.offer(j);
+                }
+            }
+        }
+
+        while (!qx.isEmpty()) {
+            int cx = qx.poll();
+            int cy = qy.poll();
+
+            for (int i = 0; i < 4; i++) {
+                int nx = cx + dx[i];
+                int ny = cy + dy[i];
+                if (0 <= nx && nx < n && 0 <= ny && ny < m
+                        && rooms[nx][ny] == Integer.MAX_VALUE) {
+                    qx.offer(nx);
+                    qy.offer(ny);
+                    rooms[nx][ny] = rooms[cx][cy] + 1;
+                }
+            }
+        }
+    }
 }
 ```
  更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder-ii.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder-ii.md"
new file mode 100644
index 0000000..8f902ca
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder-ii.md"
@@ -0,0 +1,110 @@
+# 单词接龙 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-ladder-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出两个单词（*start*和*end*）和一个字典，找出所有从*start*到*end*的最短转换序列。
+
+变换规则如下：
+
+1. 每次只能改变一个字母。
+2. 变换过程中的中间单词必须在字典中出现。
+
+ ### 样例说明
+ **样例 1:**
+```
+输入：start = "a"，end = "c"，dict =["a","b","c"]
+输出：[["a","c"]]
+解释：
+"a"->"c"
+```
+
+**样例 2:**
+```
+输入：start ="hit"，end = "cog"，dict =["hot","dot","dog","lot","log"]
+输出：[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]
+解释：
+1."hit"->"hot"->"dot"->"dog"->"cog"
+2."hit"->"hot"->"lot"->"log"->"cog"
+第一个序列的字典序小于第二个。
+```
+ ### 参考代码
+ end -> start : bfs
+start -> end : dfs
+```java
+public class Solution {
+    public List<List<String>> findLadders(String start, String end,
+            Set<String> dict) {
+        List<List<String>> ladders = new ArrayList<List<String>>();
+        Map<String, List<String>> map = new HashMap<String, List<String>>();
+        Map<String, Integer> distance = new HashMap<String, Integer>();
+
+        dict.add(start);
+        dict.add(end);
+ 
+        bfs(map, distance, end, start, dict);
+        
+        List<String> path = new ArrayList<String>();
+        
+        dfs(ladders, path, start, end, distance, map);
+
+        return ladders;
+    }
+
+    void dfs(List<List<String>> ladders, List<String> path, String crt,
+            String end, Map<String, Integer> distance,
+            Map<String, List<String>> map) {
+        path.add(crt);
+        if (crt.equals(end)) {
+            ladders.add(new ArrayList<String>(path));
+        } else {
+            for (String next : map.get(crt)) {
+                if (distance.containsKey(next) && distance.get(crt) == distance.get(next) + 1) { 
+                    dfs(ladders, path, next, end, distance, map);
+                }
+            }           
+        }
+        path.remove(path.size() - 1);
+    }
+
+    void bfs(Map<String, List<String>> map, Map<String, Integer> distance,
+            String start, String end, Set<String> dict) {
+        Queue<String> q = new LinkedList<String>();
+        q.offer(start);
+        distance.put(start, 0);
+        for (String s : dict) {
+            map.put(s, new ArrayList<String>());
+        }
+        
+        while (!q.isEmpty()) {
+            String crt = q.poll();
+
+            List<String> nextList = expand(crt, dict);
+            for (String next : nextList) {
+                map.get(next).add(crt);
+                if (!distance.containsKey(next)) {
+                    distance.put(next, distance.get(crt) + 1);
+                    q.offer(next);
+                }
+            }
+        }
+    }
+
+    List<String> expand(String crt, Set<String> dict) {
+        List<String> expansion = new ArrayList<String>();
+
+        for (int i = 0; i < crt.length(); i++) {
+            for (char ch = 'a'; ch <= 'z'; ch++) {
+                if (ch != crt.charAt(i)) {
+                    String expanded = crt.substring(0, i) + ch
+                            + crt.substring(i + 1);
+                    if (dict.contains(expanded)) {
+                        expansion.add(expanded);
+                    }
+                }
+            }
+        }
+
+        return expansion;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder.md"
new file mode 100644
index 0000000..f6f8157
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder.md"
@@ -0,0 +1,70 @@
+# 单词接龙
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-ladder/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出两个单词（*start*和*end*）和一个字典，找出从*start*到*end*的最短转换序列，输出最短序列的长度。
+
+变换规则如下：
+
+1. 每次只能改变一个字母。
+2. 变换过程中的中间单词必须在字典中出现。(起始单词和结束单词不需要出现在字典中)
+ ### 样例说明
+ **样例 1:**
+```
+输入：start = "a"，end = "c"，dict =["a","b","c"]
+输出：2
+解释：
+"a"->"c"
+```
+
+
+**样例 2:**
+```
+输入：start ="hit"，end = "cog"，dict =["hot","dot","dog","lot","log"]
+输出：5
+解释：
+"hit"->"hot"->"dot"->"dog"->"cog"
+```
+ ### 参考代码
+ 使用分层遍历的BFS版本。
+```python
+class Solution:
+    """
+    @param: start: a string
+    @param: end: a string
+    @param: dict: a set of string
+    @return: An integer
+    """
+    def ladderLength(self, start, end, dict):
+        dict.add(end)
+        queue = collections.deque([start])
+        visited = set([start])
+        
+        distance = 0
+        while queue:
+            distance += 1
+            for i in range(len(queue)):
+                word = queue.popleft()
+                if word == end:
+                    return distance
+                
+                for next_word in self.get_next_words(word):
+                    if next_word not in dict or next_word in visited:
+                        continue
+                    queue.append(next_word)
+                    visited.add(next_word) 
+
+        return 0
+        
+    # O(26 * L^2)
+    # L is the length of word
+    def get_next_words(self, word):
+        words = []
+        for i in range(len(word)):
+            left, right = word[:i], word[i + 1:]
+            for char in 'abcdefghijklmnopqrstuvwxyz':
+                if word[i] == char:
+                    continue
+                words.append(left + char + right)
+        return words
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/zombie-in-matrix.md" "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/zombie-in-matrix.md"
new file mode 100644
index 0000000..09e94b3
--- /dev/null
+++ "b/\345\233\276\350\256\272/\345\256\275\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/zombie-in-matrix.md"
@@ -0,0 +1,180 @@
+# 僵尸矩阵
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/zombie-in-matrix/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个二维网格，每一个格子都有一个值，`2` 代表墙，`1` 代表僵尸，`0` 代表人类(数字 0, 1, 2)。僵尸每天可以将上下左右最接近的人类感染成僵尸，但不能穿墙。将所有人类感染为僵尸需要多久，如果不能感染所有人则返回 `-1`。
+ ### 样例说明
+ 例1:
+```
+输入:
+[[0,1,2,0,0],
+ [1,0,0,2,1],
+ [0,1,0,0,0]]
+输出:
+2
+```
+
+例2:
+```
+输入:
+[[0,0,0],
+ [0,0,0],
+ [0,0,1]]
+输出:
+4
+```
+
+ ### 参考代码
+ 多源点bfs。
+从所有的源点出发，往外感染即可。
+```java
+class Coordinate {
+    int x, y;
+    public Coordinate(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+}
+
+public class Solution {
+    public int PEOPLE = 0;
+    public int ZOMBIE = 1;
+    public int WALL = 2;
+    
+    public int[] deltaX = {1, 0, 0, -1};
+    public int[] deltaY = {0, 1, -1, 0};
+     
+    /**
+     * @param grid a 2D integer grid
+     * @return an integer
+     */
+    public int zombie(int[][] grid) {
+        if (grid == null || grid.length == 0 || grid[0].length == 0) {
+            return 0;
+        }
+        
+        int n = grid.length;
+        int m = grid[0].length;
+        
+        // initialize the queue & count people
+        int people = 0;
+        Queue<Coordinate> queue = new LinkedList<>();
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < m; j++) {
+                if (grid[i][j] == PEOPLE) {
+                    people++;
+                } else if (grid[i][j] == ZOMBIE) {
+                    queue.offer(new Coordinate(i, j));
+                }
+            }
+        }
+        
+        // corner case
+        if (people == 0) {
+            return 0;
+        }
+        
+        // bfs
+        int days = 0;
+        while (!queue.isEmpty()) {
+            days++;
+            int size = queue.size();
+            for (int i = 0; i < size; i++) {
+                Coordinate zb = queue.poll();
+                for (int direction = 0; direction < 4; direction++) {
+                    Coordinate adj = new Coordinate(
+                        zb.x + deltaX[direction],
+                        zb.y + deltaY[direction]
+                    );
+                    
+                    if (!isPeople(adj, grid)) {
+                        continue;
+                    }
+                    
+                    grid[adj.x][adj.y] = ZOMBIE;
+                    people--;
+                    if (people == 0) {
+                        return days;
+                    }
+                    queue.offer(adj);
+                }
+            }
+        }
+        
+        return -1;
+    }
+    
+    private boolean isPeople(Coordinate coor, int[][] grid) {
+        int n = grid.length;
+        int m = grid[0].length;
+        
+        if (coor.x < 0 || coor.x >= n) {
+            return false;
+        }
+        if (coor.y < 0 || coor.y >= m) {
+            return false;
+        }
+        return (grid[coor.x][coor.y] == PEOPLE);
+    }
+}
+
+//version 硅谷算法班
+public class Solution {
+    /**
+     * @param grid: a 2D integer grid
+     * @return: an integer
+     */
+    public int zombie(int[][] grid) {
+        // write your code here
+        if (grid == null || grid.length == 0 || grid[0].length == 0) {
+            return 0;
+        }
+        Queue<Integer> qx = new LinkedList<>();
+        Queue<Integer> qy = new LinkedList<>();
+        boolean[][] v = new boolean[grid.length][grid[0].length];
+
+        for (int i = 0; i < grid.length; i++) {
+            for (int j = 0; j < grid[0].length; j++) {
+                if (grid[i][j] == 1) {
+                    qx.offer(i);
+                    qy.offer(j);
+                    v[i][j] = true;
+                }
+            }
+        }
+
+        int[] dx = {1, -1, 0, 0};
+        int[] dy = {0, 0, 1, -1};
+
+        int dist = 0;
+        while (!qx.isEmpty()) {
+            dist++;
+            int size = qx.size();
+            for (int i = 0; i < size; i++) {
+                int cx = qx.poll();
+                int cy = qy.poll();
+                for (int k = 0; k < 4; k++) {
+                    int nx = cx + dx[k];
+                    int ny = cy + dy[k];
+                    if (0 <= nx && nx < grid.length && 0 <= ny && ny < grid[0].length && grid[nx][ny] == 0 && !v[nx][ny]) {
+                        qx.offer(nx);
+                        qy.offer(ny);
+                        v[nx][ny] = true;
+                    }
+                }
+            }
+        }
+        dist--;
+
+        for (int i = 0; i < grid.length; i++) {
+            for (int j = 0; j < grid[0].length; j++) {
+                if (grid[i][j] == 0 && !v[i][j]) {
+                    return -1;
+                }
+            }
+        }
+
+        return dist;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/add-operators.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/add-operators.md"
new file mode 100644
index 0000000..76d3653
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/add-operators.md"
@@ -0,0 +1,86 @@
+# 添加运算符
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/add-operators/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个仅包含数字 `0` - `9` 的字符串和一个目标值，返回在数字之间添加了 **二元** 运算符(不是一元)`+`, `-` 或 `*` 之后所有能得到目标值的情况。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param num a string contains only digits 0-9
+     * @param target an integer
+     * @return return all possibilities
+     */
+    public List<String> addOperators(String num, int target) {
+        // Write your code here
+        List<String> results = new ArrayList<String>();
+        if (num == null || num.length() == 0) {
+            return results;
+        }
+        helper(results, "", num, target, 0, 0, 0);
+        return results;
+    }
+    public void helper(List<String> results, String path, String num, int target, int pos, long eval, long multed){
+        if (pos == num.length()){
+            if(target == eval)
+                results.add(path);
+            return;
+        }
+        for (int i = pos; i < num.length(); i++) {
+            if (i != pos && num.charAt(pos) == '0') {
+                break;
+            }
+            long cur = Long.parseLong(num.substring(pos, i + 1));
+            if (pos == 0) {
+                helper(results, path + cur, num, target, i + 1, cur, cur);
+            } else {
+                helper(results, path + "+" + cur, num, target, i + 1, eval + cur , cur);
+                helper(results, path + "-" + cur, num, target, i + 1, eval -cur, -cur);
+                helper(results, path + "*" + cur, num, target, i + 1, eval - multed + multed * cur, multed * cur );
+            }
+        }
+    }
+}
+
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param num    a string contains only digits 0-9
+     * @param target an integer
+     * @return return all possibilities
+     */
+
+    void dfs(String num, int target, int start, String str, long sum, long lastF, List<String> ans) {
+        if (start == num.length()) {
+            if (sum == target) {
+                ans.add(str);
+            }
+            return;
+        }
+        for (int i = start; i < num.length(); i++) {
+            long x = Long.parseLong(num.substring(start, i + 1));
+
+            if (start == 0) {
+                dfs(num, target, i + 1, "" + x, x, x, ans);
+            } else {
+                dfs(num, target, i + 1, str + "*" + x, sum - lastF + lastF * x, lastF * x, ans);
+                dfs(num, target, i + 1, str + "+" + x, sum + x, x, ans);
+                dfs(num, target, i + 1, str + "-" + x, sum - x, -x, ans);
+            }
+            if (x == 0) {
+                break;
+            }
+        }
+    }
+
+    public List<String> addOperators(String num, int target) {
+        // Write your code here
+        List<String> ans = new ArrayList<>();
+        dfs(num, target, 0, "", 0, 0, ans);
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/balanced-binary-tree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/balanced-binary-tree.md"
new file mode 100644
index 0000000..cee5a4e
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/balanced-binary-tree.md"
@@ -0,0 +1,81 @@
+# 平衡二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/balanced-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个二叉树,确定它是高度平衡的。对于这个问题,一棵高度平衡的二叉树的定义是：一棵二叉树中每个节点的两个子树的深度相差不会超过1。&nbsp;<br></p>
+ ### 样例说明
+ ```
+样例  1:
+	输入: tree = {1,2,3}
+	输出: true
+	
+	样例解释:
+	如下，是一个平衡的二叉树。
+		  1  
+		 / \                
+		2  3
+
+	
+样例  2:
+	输入: tree = {3,9,20,#,#,15,7}
+	输出: true
+	
+	样例解释:
+	如下，是一个平衡的二叉树。
+		  3  
+		 / \                
+		9  20                
+		  /  \                
+		 15   7 
+
+	
+样例  2:
+	输入: tree = {1,#,2,3,4}
+	输出: false
+	
+	样例解释:
+	如下，是一个不平衡的二叉树。1的左右子树高度差2
+		  1  
+		   \                
+		   2                
+		  /  \                
+		 3   4
+	
+```
+
+ ### 参考代码
+ Given a binary tree, determine if it is height-balanced.
+
+For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
+
+在树上做一次DFS，计算以每个点为根的子树高度。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root: The root of binary tree.
+    @return: True if this Binary tree is Balanced, or false.
+    """
+    def isBalanced(self, root):
+        balanced, _ = self.validate(root)
+        return balanced
+        
+    def validate(self, root):
+        if root is None:
+            return True, 0
+            
+        balanced, leftHeight = self.validate(root.left)
+        if not balanced:
+            return False, 0
+        balanced, rightHeight = self.validate(root.right)
+        if not balanced:
+            return False, 0
+            
+        return abs(leftHeight - rightHeight) <= 1, max(leftHeight, rightHeight) + 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-longest-consecutive-sequence-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-longest-consecutive-sequence-ii.md"
new file mode 100644
index 0000000..4e74d6b
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-longest-consecutive-sequence-ii.md"
@@ -0,0 +1,94 @@
+# 二叉树的最长连续子序列 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-longest-consecutive-sequence-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一棵二叉树，找到最长连续序列(单调且相邻节点值相差为1)路径的长度(节点数)。
+路径起点跟终点可以为二叉树的任意节点。
+ ### 样例说明
+ **例1:**
+```
+输入:
+{1,2,0,3}
+输出:
+4
+解释:
+    1
+   / \
+  2   0
+ /
+3
+0-1-2-3
+```
+
+**例2:**
+```
+输入:
+{3,2,2}
+输出:
+2
+解释:
+    3
+   / \
+  2   2
+2-3
+```
+
+
+ ### 参考代码
+ ```java
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+class ResultType {
+    public int max_length, max_down, max_up;
+    ResultType(int len, int down, int up) {
+        max_length = len;
+        max_down = down;
+        max_up = up;    
+    }
+}
+
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive2(TreeNode root) {
+        // Write your code here
+        return helper(root).max_length;
+    }
+    
+    ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, 0, 0);
+        }
+
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        int down = 0, up = 0;
+        if (root.left != null && root.left.val + 1 == root.val)
+            down = Math.max(down, left.max_down + 1);
+
+        if (root.left != null && root.left.val - 1 == root.val)
+            up = Math.max(up, left.max_up + 1);
+
+        if (root.right != null && root.right.val + 1 == root.val)
+            down = Math.max(down, right.max_down + 1);
+
+        if (root.right != null && root.right.val - 1 == root.val)
+            up = Math.max(up, right.max_up + 1);
+
+        int len = down + 1 + up;
+        len = Math.max(len, Math.max(left.max_length, right.max_length));
+
+        return new ResultType(len, down, up);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-longest-consecutive-sequence-iii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-longest-consecutive-sequence-iii.md"
new file mode 100644
index 0000000..43f671f
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-longest-consecutive-sequence-iii.md"
@@ -0,0 +1,83 @@
+# 二叉树的最长连续子序列III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-longest-consecutive-sequence-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 这题是 `二叉树的最长连续子序列II` 的后续。
+给出一棵 `k叉树`，找到最长连续序列路径的长度.
+路径的开头跟结尾可以是树的任意节点。
+ ### 样例说明
+ 例1:
+```
+输入:
+5<6<7<>,5<>,8<>>,4<3<>,5<>,31<>>>
+输出:
+5
+解释:
+     5
+   /   \
+  6     4
+ /|\   /|\
+7 5 8 3 5 31
+
+返回 5, // 3-4-5-6-7
+```
+
+例2:
+```
+输入:
+1<>
+输出:
+1
+```
+
+
+ ### 参考代码
+ 从根结点开始dfs，每次搜相邻的相差1的结点，跟新即可
+```java
+/**
+ * Definition for a multi tree node.
+ * public class MultiTreeNode {
+ *     int val;
+ *     List<TreeNode> children;
+ *     MultiTreeNode(int x) { val = x; }
+ * }
+ */
+ class ResultType {
+    public int max_len, max_down, max_up;
+    ResultType(int len, int down, int up) {
+        max_len = len;
+        max_down = down;
+        max_up = up;    
+    }
+}
+
+public class Solution {
+    /**
+     * @param root the root of k-ary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive3(MultiTreeNode root) {
+        // Write your code here
+        return helper(root).max_len;
+    }
+    
+    ResultType helper(MultiTreeNode root) {
+        if (root == null) {
+            return new ResultType(0, 0, 0);
+        }
+
+        int down = 0, up = 0, max_len = 1;
+        for (MultiTreeNode node : root.children) {
+            ResultType type = helper(node);
+            if (node.val + 1 == root.val)
+                down = Math.max(down, type.max_down + 1);
+            if (node.val - 1 == root.val)
+                up = Math.max(up, type.max_up + 1);
+            max_len = Math.max(max_len, type.max_len);
+        }
+
+        max_len = Math.max(down + 1 + up, max_len);
+        return new ResultType(max_len, down, up);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-longest-consecutive-sequence.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-longest-consecutive-sequence.md"
new file mode 100644
index 0000000..807f962
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-longest-consecutive-sequence.md"
@@ -0,0 +1,161 @@
+# 二叉树最长连续序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-longest-consecutive-sequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，找到最长连续路径的长度。
+这条路径是指 任何的节点序列中的起始节点到树中的任一节点都必须遵循 父-子 联系。最长的连续路径必须是从父亲节点到孩子节点（`不能逆序`）。
+
+ ### 样例说明
+ **样例1:**
+
+```
+输入:
+{1,#,3,2,4,#,#,#,5}
+输出:3
+说明:
+这棵树如图所示
+   1
+    \
+     3
+    / \
+   2   4
+        \
+         5
+最长连续序列是3-4-5，所以返回3.
+```
+
+**样例2:**
+
+```
+输入:
+{2,#,3,2,#,1,#}
+输出:2
+说明:
+这棵树如图所示：
+   2
+    \
+     3
+    / 
+   2    
+  / 
+ 1
+最长连续序列是2-3，而不是3-2-1，所以返回2.
+```
+
+
+ ### 参考代码
+ dfs搜索即可
+```java
+// version 1: Traverse + Divide Conquer
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive(TreeNode root) {
+        return helper(root, null, 0);
+    }
+    
+    private int helper(TreeNode root, TreeNode parent, int lengthWithoutRoot) {
+        if (root == null) {
+            return 0;
+        }
+        
+        int length = (parent != null && parent.val + 1 == root.val)
+            ? lengthWithoutRoot + 1
+            : 1;
+        int left = helper(root.left, root, length);
+        int right = helper(root.right, root, length);
+        return Math.max(length, Math.max(left, right));
+    }
+}
+
+// version 2: Another Traverse + Divide Conquer 
+public class Solution {
+    private int longest;
+    
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive(TreeNode root) {
+        longest = 0;
+        helper(root);
+        return longest;
+    }
+    
+    private int helper(TreeNode root) {
+        if (root == null) {
+            return 0;
+        }
+        
+        int left = helper(root.left);
+        int right = helper(root.right);
+        
+        int subtreeLongest = 1; // at least we have root
+        if (root.left != null && root.val + 1 == root.left.val) {
+            subtreeLongest = Math.max(subtreeLongest, left + 1);
+        }
+        if (root.right != null && root.val + 1 == root.right.val) {
+            subtreeLongest = Math.max(subtreeLongest, right + 1);
+        }
+        
+        if (subtreeLongest > longest) {
+            longest = subtreeLongest;
+        }
+        return subtreeLongest;
+    }
+}
+
+// version 3: Divide Conquer
+public class Solution {
+    private class ResultType {
+        int maxInSubtree;
+        int maxFromRoot;
+        public ResultType(int maxInSubtree, int maxFromRoot) {
+            this.maxInSubtree = maxInSubtree;
+            this.maxFromRoot = maxFromRoot;
+        }
+    }
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive(TreeNode root) {
+        return helper(root).maxInSubtree;
+    }
+    
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, 0);
+        }
+        
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+        
+        // 1 is the root itself.
+        ResultType result = new ResultType(0, 1);
+        
+        if (root.left != null && root.val + 1 == root.left.val) {
+            result.maxFromRoot = Math.max(
+                result.maxFromRoot,
+                left.maxFromRoot + 1
+            );
+        }
+        
+        if (root.right != null && root.val + 1 == root.right.val) {
+            result.maxFromRoot = Math.max(
+                result.maxFromRoot,
+                right.maxFromRoot + 1
+            );
+        }
+        
+        result.maxInSubtree = Math.max(
+            result.maxFromRoot,
+            Math.max(left.maxInSubtree, right.maxInSubtree)
+        );
+        
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-maximum-node.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-maximum-node.md"
new file mode 100644
index 0000000..0841bb5
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-maximum-node.md"
@@ -0,0 +1,67 @@
+# 二叉树的最大节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-maximum-node/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在二叉树中寻找值最大的节点并返回。
+ ### 样例说明
+ **样例1:**
+
+```
+输入:
+{1,-5,3,1,2,-4,-5}
+输出: 3
+说明:
+这棵树如下所示：
+     1
+   /   \
+ -5     3
+ / \   /  \
+1   2 -4  -5
+```
+
+**样例 2**
+
+```plain
+输入:
+{10,-5,2,0,3,-4,-5}
+输出: 10
+说明:
+这棵树如下所示：
+     10
+   /   \
+ -5     2
+ / \   /  \
+0   3 -4  -5 
+```
+
+
+ ### 参考代码
+ 树上基本遍历
+```java
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the max ndoe
+     */
+    public TreeNode maxNode(TreeNode root) {
+        // Write your code here
+        if (root == null)
+            return root;
+
+        TreeNode left = maxNode(root.left);
+        TreeNode right = maxNode(root.right);
+        return max(root, max(left, right));
+    }
+
+    TreeNode max(TreeNode a, TreeNode b) {
+        if (a == null)
+            return b;
+        if (b == null)
+            return a;
+        if (a.val > b.val) {
+            return a;
+        }
+        return b;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-maximum-path-sum-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-maximum-path-sum-ii.md"
new file mode 100644
index 0000000..691a9cb
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-maximum-path-sum-ii.md"
@@ -0,0 +1,57 @@
+# 二叉树的最大路径和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-maximum-path-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，找出从根节点出发的路径中，和最大的一条。
+
+这条路径可以在任何二叉树中的节点结束，但是必须包含至少一个点（也就是根了）。
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,2,3}
+输出: 4
+解释: 
+    1
+   / \
+  2   3
+1+3=4
+```
+
+**样例 2:**
+
+```
+输入: {1,-1,-1}
+输出: 1
+解释:
+    1
+   / \
+  -1 -1 
+```
+ ### 参考代码
+ 如果从动态规划的角度思考, 可以是这样的:
+
+- 状态: f[i] 表示从节点i往下走得到的最大路径和
+- 状态转移方程: f[i] = max{f[lc[i]], f[rc[i]], 0} + val[i]
+
+不过这道题目是二叉树, 比经典的数字三角形要简单, 无需记忆化/定义额外空间储存答案.
+
+一次递归遍历整棵二叉树即可.
+```java
+public class Solution {
+    /**
+     * @param root the root of binary tree.
+     * @return an integer
+     */
+    public int maxPathSum2(TreeNode root) {
+        if (root == null) {
+            return Integer.MIN_VALUE;
+        }
+
+        int left = maxPathSum2(root.left);
+        int right = maxPathSum2(root.right);
+        return root.val + Math.max(0, Math.max(left, right));
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-maximum-path-sum.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-maximum-path-sum.md"
new file mode 100644
index 0000000..e6280bc
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-maximum-path-sum.md"
@@ -0,0 +1,108 @@
+# 二叉树中的最大路径和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-maximum-path-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <span style="line-height: 30px;"><font color="#000000">给出一棵二叉树，</font></span><font color="#000000"><span style="line-height: 30px;">寻找一条路径使其路径和最大，路径可以在任一节点中开始和结束（路径和为两个节点之间所在路径上的节点权值之和）</span></font><br>
+ ### 样例说明
+ ```
+样例 1:
+	输入:  给定一棵树（只有一个节点）:
+	2
+	输出：2
+	
+样例 2:
+	输入:  给定一棵树：
+
+      1
+     / \
+    2   3
+		
+	输出: 6
+
+	
+```
+ ### 参考代码
+ Given a binary tree, find the maximum path sum.&nbsp;<div>The path may start and end at any node in the tree.&nbsp;</div><div><br></div><div>For example:&nbsp;</div><div>Given the below binary tree,&nbsp;</div><div>&nbsp; 1&nbsp;</div><div>&nbsp;/ &nbsp;\&nbsp;</div><div>2 &nbsp; 3&nbsp;</div><div><span style="line-height: 1.42857143;">Return 6.</span><br></div><div><div><br></div><div>详细题解请见九章算法微博：<a href="http://weibo.com/3948019741/BBY7gwi89" target="_blank">http://weibo.com/3948019741/BBY7gwi89</a></div></div>
+
+分治法。
+需要考虑的是，子树中最大的路不一定必过根节点。所以要记录single Path的值。
+见代码注释。
+```java
+public class Solution {
+    private class ResultType {
+        // singlePath: 从root往下走到任意点的最大路径，这条路径可以不包含任何点
+        // maxPath: 从树中任意到任意点的最大路径，这条路径至少包含一个点
+        int singlePath, maxPath; 
+        ResultType(int singlePath, int maxPath) {
+            this.singlePath = singlePath;
+            this.maxPath = maxPath;
+        }
+    }
+
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, Integer.MIN_VALUE);
+        }
+        // Divide
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        // Conquer
+        int singlePath = Math.max(left.singlePath, right.singlePath) + root.val;
+        singlePath = Math.max(singlePath, 0);
+
+        int maxPath = Math.max(left.maxPath, right.maxPath);
+        maxPath = Math.max(maxPath, left.singlePath + right.singlePath + root.val);
+
+        return new ResultType(singlePath, maxPath);
+    }
+
+    public int maxPathSum(TreeNode root) {
+        ResultType result = helper(root);
+        return result.maxPath;
+    }
+}
+
+
+// Version 2:
+// SinglePath也定义为，至少包含一个点。
+public class Solution {
+    /**
+     * @param root: The root of binary tree.
+     * @return: An integer.
+     */
+    private class ResultType {
+        int singlePath, maxPath;
+        ResultType(int singlePath, int maxPath) {
+            this.singlePath = singlePath;
+            this.maxPath = maxPath;
+        }
+    }
+
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(Integer.MIN_VALUE, Integer.MIN_VALUE);
+        }
+        // Divide
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        // Conquer
+        int singlePath =
+            Math.max(0, Math.max(left.singlePath, right.singlePath)) + root.val;
+
+        int maxPath = Math.max(left.maxPath, right.maxPath);
+        maxPath = Math.max(maxPath,
+                           Math.max(left.singlePath, 0) + 
+                           Math.max(right.singlePath, 0) + root.val);
+
+        return new ResultType(singlePath, maxPath);
+    }
+
+    public int maxPathSum(TreeNode root) {
+        ResultType result = helper(root);
+        return result.maxPath;
+    }
+
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-path-sum-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-path-sum-ii.md"
new file mode 100644
index 0000000..fa5ff2d
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-path-sum-ii.md"
@@ -0,0 +1,44 @@
+# 二叉树的路径和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-path-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树和一个目标值，设计一个算法找到二叉树上的和为该目标值的所有路径。路径可以从任何节点出发和结束，但是需要是一条一直往下走的路线。也就是说，路径上的节点的层级是逐个递增的。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @param {int} target an integer
+    # @return {int[][]} all valid paths
+    def binaryTreePathSum2(self, root, target):
+        # Write your code here
+        result = []
+        path = []
+        if root is None:
+            return result
+        self.dfs(root, path, result, 0,  target)
+        return result
+
+    def dfs(self, root, path, result, l, target):
+        if root is None:
+            return
+        path.append(root.val)
+        tmp = target
+        for i in xrange(l , -1, -1):
+            tmp -= path[i]
+            if tmp == 0:
+                result.append(path[i:])
+
+        self.dfs(root.left, path, result, l + 1, target)
+        self.dfs(root.right, path, result, l + 1, target)
+
+        path.pop()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-path-sum-iii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-path-sum-iii.md"
new file mode 100644
index 0000000..5ba4597
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-path-sum-iii.md"
@@ -0,0 +1,94 @@
+# 二叉树的路径和 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-path-sum-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树和一个目标值，找到二叉树上所有的和为该目标值的路径。路径可以从二叉树的任意节点出发，任意节点结束。
+
+ ### 样例说明
+ **样例 1:**
+
+```plain
+输入：{1,2,3,4},6
+输出：[[2, 4],[2, 1, 3],[3, 1, 2],[4, 2]]
+解释：
+该树如下：
+    1
+   / \
+  2   3
+ /
+4
+```
+
+**样例 2:**
+
+```plain
+输入：{1,2,3,4},3
+输出：[[1,2],[2,1],[3]]
+解释：
+该树如下：
+    1
+   / \
+  2   3
+ /
+4
+```
+ ### 参考代码
+ 使用dfs搜索的办法进行查找，可以进行相关的嵌套，从而达到结果
+```java
+/**
+ * Definition of ParentTreeNode:
+ * 
+ * class ParentTreeNode {
+ *     public int val;
+ *     public ParentTreeNode parent, left, right;
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @param target an integer
+     * @return all valid paths
+     */
+    public List<List<Integer>> binaryTreePathSum3(ParentTreeNode root, int target) {
+        // Write your code here
+        List<List<Integer>> results = new ArrayList<List<Integer>>();
+        dfs(root, target, results);
+        return results;
+    }
+    
+    public void dfs(ParentTreeNode root, int target, List<List<Integer>> results) {
+        if (root == null)
+            return;
+
+        List<Integer> path = new ArrayList<Integer>();
+        findSum(root, null, target, path, results);
+
+        dfs(root.left, target, results);
+        dfs(root.right, target, results);
+    }
+
+    public void findSum(ParentTreeNode root, ParentTreeNode father, int target,
+                 List<Integer> path, List<List<Integer>> results) {
+        path.add(root.val);
+        target -= root.val;
+        
+        if (target == 0) {
+            ArrayList<Integer> tmp = new ArrayList<Integer>();
+            Collections.addAll(tmp,  new  Integer[path.size()]); 
+            Collections.copy(tmp, path); 
+            results.add(tmp);
+        }
+
+        if (root.parent != null && root.parent != father)
+            findSum(root.parent, root, target, path, results);
+
+        if (root.left != null && root.left  != father)
+            findSum(root.left, root, target, path, results);
+
+        if (root.right != null && root.right != father)
+            findSum(root.right, root, target, path, results);
+
+        path.remove(path.size() - 1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-path-sum.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-path-sum.md"
new file mode 100644
index 0000000..60beeae
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/binary-tree-path-sum.md"
@@ -0,0 +1,80 @@
+# 二叉树的路径和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-path-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，找出所有路径中各节点相加总和等于给定 `目标值` 的路径。
+
+一个有效的路径，指的是从根节点到叶节点的路径。
+ ### 样例说明
+ **样例1:**
+
+```plain
+输入:
+{1,2,4,2,3}
+5
+输出: [[1, 2, 2],[1, 4]]
+说明:
+这棵树如下图所示：
+	     1
+	    / \
+	   2   4
+	  / \
+	 2   3
+对于目标总和为5，很显然1 + 2 + 2 = 1 + 4 = 5
+```
+
+**样例2:**
+
+```plain
+输入:
+{1,2,4,2,3}
+3
+输出: []
+说明:
+这棵树如下图所示：
+	     1
+	    / \
+	   2   4
+	  / \
+	 2   3
+注意到题目要求我们寻找从根节点到叶子节点的路径。
+1 + 2 + 2 = 5, 1 + 2 + 3 = 6, 1 + 4 = 5 
+这里没有合法的路径满足和等于3.
+```
+
+
+ ### 参考代码
+ ```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @param {int} target an integer
+    # @return {int[][]} all valid paths
+    def binaryTreePathSum(self, root, target):
+        # Write your code here
+        result = []
+        path = []
+        self.dfs(root, path, result, 0,  target)
+
+        return result
+
+    def dfs(self, root, path, result, len, target):
+        if root is None:
+            return
+        path.append(root.val)
+        len += root.val
+
+        if root.left is None and root.right is None and len == target:
+            result.append(path[:])
+
+        self.dfs(root.left, path, result, len, target)
+        self.dfs(root.right, path, result, len, target)
+
+        path.pop()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/clone-binary-tree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/clone-binary-tree.md"
new file mode 100644
index 0000000..61bf058
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/clone-binary-tree.md"
@@ -0,0 +1,65 @@
+# 克隆二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/clone-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 深度复制一个二叉树。
+
+给定一个二叉树，返回一个他的 **克隆品** 。
+ ### 样例说明
+ **样例1:**
+
+```plain
+输入: {1,2,3,4,5}
+输出: {1,2,3,4,5}
+解释：
+样例中二叉树如下所示:
+     1
+   /  \
+  2    3
+ / \
+4   5
+```
+
+**样例2:**
+
+```plain
+输入: {1,2,3}
+输出: {1,2,3}
+解释：
+样例中二叉树如下所示:
+   1
+ /  \
+2    3
+```
+
+
+ ### 参考代码
+ 这题采用dfs（深度优先搜索）的方法，从根节点开始，一步步的去复制这一颗树。每次去复制他的左节点和右节点即可。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of binary tree
+     * @return root of new tree
+     */
+    public TreeNode cloneTree(TreeNode root) {
+        // Write your code here
+        if (root == null)
+            return null; //搜到了空节点，直接返回
+        TreeNode clone_root = new TreeNode(root.val); //创造当前深度的“根”
+        clone_root.left = cloneTree(root.left);  //左子树
+        clone_root.right = cloneTree(root.right); //右子树
+        return clone_root;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/clone-graph.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/clone-graph.md"
new file mode 100644
index 0000000..7e9e4c5
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/clone-graph.md"
@@ -0,0 +1,63 @@
+# 克隆图
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/clone-graph/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 克隆一张无向图. 无向图的每个节点包含一个 `label` 和一个列表 `neighbors`. 保证每个节点的 `label` 互不相同.
+
+你的程序需要返回一个经过深度拷贝的新图. 新图和原图具有同样的结构, 并且对新图的任何改动不会对原图造成任何影响.
+ ### 样例说明
+ **样例1**
+```
+输入:
+{1,2,4#2,1,4#4,1,2}
+输出: 
+{1,2,4#2,1,4#4,1,2}
+解释:
+1------2  
+ \     |  
+  \    |  
+   \   |  
+    \  |  
+      4   
+```
+ ### 参考代码
+ 使用宽度优先搜索 BFS 的版本。
+
+第一步：找到所有的点
+第二步：复制所有的点，将映射关系存起来
+第三步：找到所有的边，复制每一条边
+```python
+class Solution:
+    def cloneGraph(self, node):
+        root = node
+        if node is None:
+            return node
+            
+        # use bfs algorithm to traverse the graph and get all nodes.
+        nodes = self.getNodes(node)
+        
+        # copy nodes, store the old->new mapping information in a hash map
+        mapping = {}
+        for node in nodes:
+            mapping[node] = UndirectedGraphNode(node.label)
+        
+        # copy neighbors(edges)
+        for node in nodes:
+            new_node = mapping[node]
+            for neighbor in node.neighbors:
+                new_neighbor = mapping[neighbor]
+                new_node.neighbors.append(new_neighbor)
+        
+        return mapping[root]
+        
+    def getNodes(self, node):
+        q = collections.deque([node])
+        result = set([node])
+        while q:
+            head = q.popleft()
+            for neighbor in head.neighbors:
+                if neighbor not in result:
+                    result.add(neighbor)
+                    q.append(neighbor)
+        return result
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combination-sum-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combination-sum-ii.md"
new file mode 100644
index 0000000..ed21885
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combination-sum-ii.md"
@@ -0,0 +1,71 @@
+# 数字组合 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/combination-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数组 `num` 和一个整数 `target`. 找到 `num` 中所有的数字之和为 `target` 的组合.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: num = [7,1,2,5,1,6,10], target = 8
+输出: [[1,1,6],[1,2,5],[1,7],[2,6]]
+```
+
+**样例 2:**
+
+```
+输入: num = [1,1,1], target = 2
+输出: [[1,1]]
+解释: 解集不能包含重复的组合
+```
+ ### 参考代码
+ 使用回溯法搜索所有可能的组合. 很基础的题目, 有多种不同的写法, 再次不多赘述.
+
+有一个显而易见的小优化: 我们在搜索的过程中会记录已经选择的数字的和, 如果这个和超过了 target, 停止搜索. 除此之外还有很多可以优化的细节, 慢慢探索吧!
+
+另外, 这个题目还可以有非递归的形式: 用一个整型的 `num.length` 个二进制位表示一个组合, 第 i 位为 1 表示这个组合内含有 `num[i]`. 这样可以从0自增这个整型来达到枚举所有组合的效果. 避免了递归的开销 (但是也不一定比递归快, 因为递归可以有优化, 而这样枚举就只能老老实实把所有的组合都查看一遍)
+```java
+public class Solution {
+    /**
+     * @param num: Given the candidate numbers
+     * @param target: Given the target number
+     * @return: All the combinations that sum to target
+     */
+    public List<List<Integer>> combinationSum2(int[] candidates,
+            int target) {
+        List<List<Integer>> results = new ArrayList<>();
+        if (candidates == null || candidates.length == 0) {
+            return results;
+        }
+
+        Arrays.sort(candidates);
+        List<Integer> combination = new ArrayList<Integer>();
+        helper(candidates, 0, combination, target, results);
+
+        return results;
+    }
+
+    private void helper(int[] candidates,
+                        int startIndex,
+                        List<Integer> combination,
+                        int target,
+                        List<List<Integer>> results) {
+        if (target == 0) {
+            results.add(new ArrayList<Integer>(combination));
+            return;
+        }
+
+        for (int i = startIndex; i < candidates.length; i++) {
+            if (i != startIndex && candidates[i] == candidates[i - 1]) {
+                continue;
+            }
+            if (target < candidates[i]) {
+                break;
+            }
+            combination.add(candidates[i]);
+            helper(candidates, i + 1, combination, target - candidates[i], results);
+            combination.remove(combination.size() - 1);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combination-sum-iv.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combination-sum-iv.md"
new file mode 100644
index 0000000..fb12e7d
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combination-sum-iv.md"
@@ -0,0 +1,54 @@
+# 组合总和 IV
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/combination-sum-iv/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个都是正整数的数组 `nums`，其中没有重复的数。从中找出所有的和为 `target` 的组合个数。
+ ### 样例说明
+ **样例1**
+
+```
+输入: nums = [1, 2, 4] 和 target = 4
+输出: 6
+解释:
+可能的所有组合有：
+[1, 1, 1, 1]
+[1, 1, 2]
+[1, 2, 1]
+[2, 1, 1]
+[2, 2]
+[4]
+```
+
+**样例2**
+
+```
+输入: nums = [1, 2] 和 target = 4
+输出: 5
+解释:
+可能的所有组合有：
+[1, 1, 1, 1]
+[1, 1, 2]
+[1, 2, 1]
+[2, 1, 1]
+[2, 2]
+```
+ ### 参考代码
+ ```cpp
+class Solution {
+public:
+    int combinationSum4(vector<int>& nums, int target) {
+        int n = nums.size();
+        int f[target+1];
+        memset(f, 0, sizeof(f));
+        
+        f[0] = 1;
+        for (int i = 1; i <= target; i++) {
+            for (int j = 0; j < n; j++) 
+            if (i - nums[j] >= 0){
+                f[i] += f[i-nums[j]];
+            }
+        }
+        return f[target];
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combination-sum.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combination-sum.md"
new file mode 100644
index 0000000..14ff8f3
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combination-sum.md"
@@ -0,0 +1,123 @@
+# 数字组合
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/combination-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个候选数字的集合 `candidates` 和一个目标值 `target`. 找到 `candidates` 中所有的和为 `target` 的组合.
+
+在同一个组合中, `candidates` 中的某个数字不限次数地出现.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: candidates = [2, 3, 6, 7], target = 7
+输出: [[7], [2, 2, 3]]
+```
+
+**样例 2:**
+
+```
+输入: candidates = [1], target = 3
+输出: [[1, 1, 1]]
+```
+ ### 参考代码
+ ```java
+// version 1: Remove duplicates & generate a new array
+public class Solution {
+    /**
+     * @param candidates: A list of integers
+     * @param target:An integer
+     * @return: A list of lists of integers
+     */
+    public List<List<Integer>> combinationSum(int[] candidates, int target) {
+        List<List<Integer>> results = new ArrayList<>();
+        if (candidates == null || candidates.length == 0) {
+            return results;
+        }
+        
+        int[] nums = removeDuplicates(candidates);
+        
+        dfs(nums, 0, new ArrayList<Integer>(), target, results);
+        
+        return results;
+    }
+    
+    private int[] removeDuplicates(int[] candidates) {
+        Arrays.sort(candidates);
+        
+        int index = 0;
+        for (int i = 0; i < candidates.length; i++) {
+            if (candidates[i] != candidates[index]) {
+                candidates[++index] = candidates[i];
+            }
+        }
+        
+        int[] nums = new int[index + 1];
+        for (int i = 0; i < index + 1; i++) {
+            nums[i] = candidates[i];
+        }
+        
+        return nums;
+    }
+    
+    private void dfs(int[] nums,
+                     int startIndex,
+                     List<Integer> combination,
+                     int remainTarget,
+                     List<List<Integer>> results) {
+        if (remainTarget == 0) {
+            results.add(new ArrayList<Integer>(combination));
+            return;
+        }
+        
+        for (int i = startIndex; i < nums.length; i++) {
+            if (remainTarget < nums[i]) {
+                break;
+            }
+            combination.add(nums[i]);
+            dfs(nums, i, combination, remainTarget - nums[i], results);
+            combination.remove(combination.size() - 1);
+        }
+    }
+}
+
+// version 2: reuse candidates array
+public class Solution {
+    public  List<List<Integer>> combinationSum(int[] candidates, int target) {
+        List<List<Integer>> result = new ArrayList<>();
+        if (candidates == null) {
+            return result;
+        }
+
+        List<Integer> combination = new ArrayList<>();
+        Arrays.sort(candidates);
+        helper(candidates, 0, target, combination, result);
+
+        return result;
+    }
+
+     void helper(int[] candidates,
+                 int index,
+                 int target,
+                 List<Integer> combination,
+                 List<List<Integer>> result) {
+        if (target == 0) {
+            result.add(new ArrayList<Integer>(combination));
+            return;
+        }
+
+        for (int i = index; i < candidates.length; i++) {
+            if (candidates[i] > target) {
+                break;
+            }
+
+            if (i != 0 && candidates[i] == candidates[i - 1]) {
+                continue;
+            }
+
+            combination.add(candidates[i]);
+            helper(candidates, i, target - candidates[i], combination, result);
+            combination.remove(combination.size() - 1);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combinations.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combinations.md"
new file mode 100644
index 0000000..3938c0e
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/combinations.md"
@@ -0,0 +1,61 @@
+# 组合
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/combinations/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个整数 `n` 和 `k`. 返回从 `1, 2, ... , n` 中选出 `k` 个数的所有可能的组合.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: n = 4, k = 2
+输出: [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
+```
+
+**样例 2:**
+
+```
+输入: n = 4, k = 1
+输出: [[1],[2],[3],[4]]
+```
+ ### 参考代码
+ Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
+
+For example,
+If n = 4 and k = 2, a solution is:
+
+[
+  [2,4],
+  [3,4],
+  [2,3],
+  [1,2],
+  [1,3],
+  [1,4],
+]
+```java
+public class Solution {
+    public List<List<Integer>> combine(int n, int k) {
+        List<List<Integer>> rst = new ArrayList<List<Integer>>();
+        List<Integer> solution = new ArrayList<Integer>();
+        
+        helper(rst, solution, n, k, 1);
+        return rst;
+    }
+    
+    private void helper(List<List<Integer>> rst, List<Integer> solution, 
+        int n, int k, int start) {
+        if (solution.size() == k){
+            rst.add(new ArrayList(solution));
+            return;
+        }
+        
+        for(int i = start; i<= n; i++){
+            solution.add(i);
+            
+            // the new start should be after the next number after i
+            helper(rst, solution, n, k, i + 1); 
+            solution.remove(solution.size() - 1);
+        }
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/continuous-subarray-sum-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/continuous-subarray-sum-ii.md"
new file mode 100644
index 0000000..a71b61d
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/continuous-subarray-sum-ii.md"
@@ -0,0 +1,64 @@
+# 连续子数组求和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/continuous-subarray-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数循环数组（头尾相接），请找出一个连续的子数组，使得该子数组的和最大。输出答案时，请分别返回第一个数字和最后一个数字的值。
+
+如果多个答案，请返回其中任意一个。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [3, 1, -100, -3, 4]
+输出: [4, 1]
+```
+
+**样例 2:**
+
+```
+输入: [1,-1]
+输出: [0, 0]
+```
+ ### 参考代码
+ 分两种情况讨论：
+
+1. 最大数组仍然是中间的某一段
+2. 最大数组是去掉了中间的一段之后剩下的部分
+
+第一种情况用传统的最大子数组做法走一遍(参考[题解](https://www.jiuzhang.com/solution/continuous-subarray-sum))。第二种做法稍微想一下就可以证明中间被去掉的那一段是整个数组的 minimum subarray。
+所以求一遍 minimum subarray 之后，比较两种情况, 取最优解即可
+
+需要特殊考虑 minimum subarray 是取了所有数的情况。
+```python
+class Solution:
+    """
+    @param: A: An integer array
+    @return: A list of integers includes the index of the first number and the index of the last number
+    """
+    def continuousSubarraySumII(self, A):
+        max_start, max_end, max_sum = self.find_maximum_subarray(A)
+        min_start, min_end, min_sum = self.find_maximum_subarray([-a for a in A])
+        min_sum = -min_sum  # *-1 after reuse find maximum array
+        
+        total = sum(A)
+        if max_sum >= total - min_sum or min_end - min_start + 1 == len(A):
+            return [max_start, max_end]
+        
+        return [min_end + 1, min_start - 1]
+        
+    def find_maximum_subarray(self, nums):
+        max_sum = -sys.maxsize
+        curt_sum, start = 0, 0
+        max_range = []
+        
+        for index, num in enumerate(nums):
+            if curt_sum < 0:
+                curt_sum = 0
+                start = index
+            curt_sum += num
+            if curt_sum > max_sum:
+                max_sum = curt_sum
+                max_range = [start, index]
+                
+        return max_range[0], max_range[1], max_sum
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/continuous-subarray-sum.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/continuous-subarray-sum.md"
new file mode 100644
index 0000000..db9bed2
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/continuous-subarray-sum.md"
@@ -0,0 +1,64 @@
+# 连续子数组求和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/continuous-subarray-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，请找出一个连续子数组，使得该子数组的和最大。输出答案时，请分别返回第一个数字和最后一个数字的下标。（如果存在多个答案，请返回字典序最小的）
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [-3, 1, 3, -3, 4]
+输出: [1, 4]
+```
+
+**样例 2:**
+
+```
+输入: [0, 1, 0, 1]
+输出: [0, 3]
+解释: 字典序最小.
+```
+ ### 参考代码
+ 枚举即可, 枚举的过程中维护以当前元素结尾的最大和.
+
+每次循环把当前元素加到这个和中, 在加上之前判断: 
+
+- 如果这个和是负数, 则放弃之前的元素, 把和置为0, 区间左端点设为当前元素
+- 如果是正数, 则直接累加.
+
+同时, 在枚举的过程中维护答案.
+
+详细过程见C++注释
+```java
+public class Solution {
+    /**
+     * @param A an integer array
+     * @return  A list of integers includes the index of the first number and the index of the last number
+     */
+    public ArrayList<Integer> continuousSubarraySum(int[] A) {
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        result.add(0);
+        result.add(0);
+
+        int len = A.length;
+        int start = 0, end = 0;
+        int sum = 0;
+        int ans = -0x7fffffff;
+        for (int i = 0; i < len; i++) {
+            if (sum < 0) {
+                sum = A[i];
+                start = end = i;
+            } else {
+                sum += A[i];
+                end = i;
+            }
+            if (sum > ans) {
+                ans = sum;
+                result.set(0, start);
+                result.set(1, end);
+            }
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-array-to-binary-search-tree-with-minimal-height.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-array-to-binary-search-tree-with-minimal-height.md"
new file mode 100644
index 0000000..820d42e
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-array-to-binary-search-tree-with-minimal-height.md"
@@ -0,0 +1,57 @@
+# 把排序数组转换为高度最小的二叉搜索树。
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-sorted-array-to-binary-search-tree-with-minimal-height/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个排序数组（从小到大），将其转换为一棵高度最小的二叉搜索树。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[]
+输出：{}
+解释：二叉搜索树为空
+```
+
+**样例 2:**
+```
+输入：[1,2,3,4,5,6,7]
+输出： {4,2,6,1,3,5,7}
+解释：
+拥有最小高度的二叉搜索树
+
+         4
+       /   \
+      2     6
+     / \    / \
+    1   3  5   7
+```
+ ### 参考代码
+ 每次取middle作为根，左半边是左子树，右半边是右子树。
+递归处理左右两边。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param A: a list of integer
+    @return: a tree node
+    """
+    def sortedArrayToBST(self, A):
+        return self.convert(A, 0, len(A) - 1)
+        
+    def convert(self, A, start, end):
+        if start > end:
+            return None
+        if start == end:
+            return TreeNode(A[start])
+        
+        mid = (start + end) // 2
+        root = TreeNode(A[mid])
+        root.left = self.convert(A, start, mid - 1)
+        root.right = self.convert(A, mid + 1, end)
+        return root
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-array-to-binary-search-tree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-array-to-binary-search-tree.md"
new file mode 100644
index 0000000..08ffca7
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-array-to-binary-search-tree.md"
@@ -0,0 +1,62 @@
+# 有序数组转换为二叉搜索树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-sorted-array-to-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数组，其中元素按升序排序，将其转换为高度平衡的BST。
+
+对于这个问题，高度平衡的二叉树被定义为二叉树，其中每个节点的两个子树的深度从不相差超过1。
+ ### 样例说明
+ **样例 1:**
+```
+输入: [-10,-3,0,5,9],
+输出: [0,-3,9,-10,#,5],
+解释:
+针对该数组的其中一个解为 [0,-3,9,-10,null,5], 其对应的平衡BST树如下:
+      0
+     / \
+   -3   9
+   /   /
+ -10  5
+```
+
+
+**样例 2:**
+```
+输入: [1,3]
+输出: [3,1]
+解释:
+针对该数组的其中一个解为 [3,1], 其对应的平衡BST树如下:
+  3
+ / 
+1   
+```
+
+
+
+ ### 参考代码
+ 考点：
+* 递归
+* BST
+
+题解：每次选择一个区间的中点作为当前区间的根，然后对左右子树依次构造。
+```java
+public class Solution {
+    private TreeNode buildTree(int[] num, int start, int end) {
+        if (start > end) {
+            return null;
+        }
+
+        TreeNode node = new TreeNode(num[(start + end) / 2]);
+        node.left = buildTree(num, start, (start + end) / 2 - 1);
+        node.right = buildTree(num, (start + end) / 2 + 1, end);
+        return node;
+    }
+
+    public TreeNode sortedArrayToBST(int[] num) {
+        if (num == null) {
+            return null;
+        }
+        return buildTree(num, 0, num.length - 1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/convert-sorted-list-to-balanced-bst.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-list-to-balanced-bst.md"
similarity index 100%
rename from "\351\242\230\350\247\243/convert-sorted-list-to-balanced-bst.md"
rename to "\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-list-to-balanced-bst.md"
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-list-to-binary-search-tree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-list-to-binary-search-tree.md"
new file mode 100644
index 0000000..39760da
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/convert-sorted-list-to-binary-search-tree.md"
@@ -0,0 +1,123 @@
+# 有序链表转换为二叉搜索树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-sorted-list-to-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个所有元素以升序排序的单链表，将它转换成一棵高度平衡的二叉搜索树</p>
+ ### 样例说明
+ ```
+样例 1:
+	输入: array = 1->2->3
+	输出:
+		 2  
+		/ \
+		1  3
+		
+样例 2:
+	输入: 2->3->6->7
+	输出:
+		 3
+		/ \
+	       2   6
+		     \
+		      7
+
+	解释:
+	可能会有多个符合要求的结果，返回任意一个即可。
+```
+ ### 参考代码
+ Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
+
+高度平衡，所以将链表从中间分开，左边是左子树，右边是右子树。
+```cpp
+// version 1: (Recommend)
+class Solution {
+public:
+    /**
+     * @param head: The first node of linked list.
+     * @return: a tree node
+     */
+    TreeNode *sortedListToBST(ListNode *head) {
+        if (head == NULL) {
+            return NULL;
+        }
+        int size = getListSize(head);
+        return convertHelper(head, size);
+    }
+    
+    int getListSize(ListNode *head) {
+        int size = 0;
+        while (head != NULL) {
+            head = head->next;
+            size++;
+        }
+        return size;
+    }
+    
+    TreeNode *convertHelper(ListNode *&head, int size) {
+        if (size == 0) {
+            return NULL;
+        }
+        
+        TreeNode *root = new TreeNode(0);
+        root->left = convertHelper(head, size / 2);
+        root->val = head->val; head = head->next;
+        root->right = convertHelper(head, size - size / 2 - 1);
+        return root;
+    }
+};
+
+// version 2:
+struct ResultType {
+    TreeNode *tree;
+    ListNode *next;
+};
+
+class Solution {
+public:
+    /**
+     * @param head: The first node of linked list.
+     * @return: a tree node
+     */
+    TreeNode *sortedListToBST(ListNode *head) {
+        if (head == NULL) {
+            return NULL;
+        }
+        
+        int size = getListSize(head);
+        ResultType result = convertHelper(head, size);
+        return result.tree;
+    }
+    
+    int getListSize(ListNode *head) {
+        int size = 0;
+        while (head != NULL) {
+            head = head->next;
+            size++;
+        }
+        return size;
+    }
+    
+    ResultType convertHelper(ListNode *head, int size) {
+        ResultType result;
+        
+        if (size == 1) {
+            result.tree = new TreeNode(head->val);
+            result.next = head->next;
+            return result;
+        }
+        
+        ResultType left = convertHelper(head, size / 2);
+        result.tree = new TreeNode(left.next->val);
+        result.tree->left = left.tree;
+        if (left.next->next == NULL || size - size / 2 - 1 == 0) {
+            result.tree->right = NULL;
+            result.next = left.next->next;
+            return result;
+        }
+        ResultType right = convertHelper(left.next->next, size - size / 2 - 1);
+        result.tree->right = right.tree;
+        result.next = right.next;
+        return result;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/decode-string.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/decode-string.md"
new file mode 100644
index 0000000..811190c
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/decode-string.md"
@@ -0,0 +1,51 @@
+# 字符串解码
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/decode-string/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个表达式 `s`，此表达式包括数字，字母以及方括号。在方括号前的数字表示方括号内容的重复次数(括号内的内容可以是字符串或另一个表达式)，请将这个表达式展开成一个字符串。
+ ### 样例说明
+ **样例1**
+
+```
+输入: S = abc3[a]
+输出: "abcaaa"
+```
+
+**样例2**
+
+```
+输入: S = 3[2[ad]3[pf]]xyz
+输出: "adadpfpfpfadadpfpfpfadadpfpfpfxyz"
+```
+
+ ### 参考代码
+ 把所有字符一个个放到 stack 里， 如果碰到了 `]`，就从 stack 找到对应的字符串和重复次数，decode 之后再放回 stack 里
+```python
+class Solution:
+    """
+    @param s: an expression includes numbers, letters and brackets
+    @return: a string
+    """
+    def expressionExpand(self, s):
+        stack = []
+        for c in s:
+            if c != ']':
+                stack.append(c)
+                continue
+                
+            strs = []
+            while stack and stack[-1] != '[':
+                strs.append(stack.pop())
+            
+            # skip '['
+            stack.pop()
+            
+            repeats = 0
+            base = 1
+            while stack and stack[-1].isdigit():
+                repeats += (ord(stack.pop()) - ord('0')) * base
+                base *= 10
+            stack.append(''.join(reversed(strs)) * repeats)
+        
+        return ''.join(stack)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/driving-problem.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/driving-problem.md"
new file mode 100644
index 0000000..750f690
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/driving-problem.md"
@@ -0,0 +1,78 @@
+# 开车问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/driving-problem/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有一条路长为`L`，宽为`W`，在路中有一些圆形障碍物，半径1，有一辆圆形的车，半径2，问车是否能通过这条路。你可以把路面当成二维坐标上的一个矩形，四个点为`(0,0),(0,W),(L,0),(L,W)`,现在你需要从`x=0`出发，到`x=L`，不允许与障碍物接触,且车的所有部分都在`y=0`到`y=W`之间，不允许接触。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+8 8
+输出:
+yes
+
+解释:
+给出`L=8`，`W=8`，障碍物坐标为`[[1,1],[6,6]]`。返回`yes`。
+车的圆心可以从（0,5)到(2,5)到(5,2)到(8,2)，所以返回yes。
+```
+
+**样例 2:**
+```
+输入:
+8 6
+输出:
+no
+
+解释:
+给出`L=8`，`W=6`，障碍物坐标为`[[1,1]]`,返回`no`。
+不管如何驾驶，车总会与障碍物相切或者相交，这都是不被允许的。
+```
+ ### 参考代码
+ 这个题的思路是把 y=0 和 y=w 也看做障碍，然后如果两个障碍物之间无法通过车辆，则连一条线，相当于一个路障。然后如果说 y=0 和 y=w 最终通过路障连通起来了，说车无论如何也找不到一条路径可以穿过这条连起来的路障，否则就说明可以找到一个缺口从 x=0 开到 x=L
+
+找连通性的问题，自然就是 BFS 最拿手的了。
+
+```
+[[python]]
+OBSTACLE_MIN_DISTANCE = 6
+BOUND_MIN_DISTANCE = 5
+
+class Solution:
+    """
+    @param L: the length
+    @param W: the width
+    @param p:  the obstacle coordinates
+    @return: yes or no
+    """
+    def drivingProblem(self, L, W, obstacles):
+        from collections import deque
+        
+        # consider the upper & bottom line y=W, y=0, all obstacles
+        # as nodes in a graph, if the car can not pass between two
+        # nodes, we connect the two nodes with an edge in the graph.
+        # the car can pass the road only if we CANNOT find a path
+        # from start node y=W to the end node y=0
+        
+        queue = deque([(None, W)])
+        visited = set([(None, W)])
+        while queue:
+            x, y = queue.popleft()
+            # y <= 5 means (x, y) can connect the end node y=0
+            if y <= BOUND_MIN_DISTANCE:
+                return "no"
+            for obstacle in obstacles:
+                if (obstacle[0], obstacle[1]) in visited:
+                    continue
+                if not self.is_connected(x, y, obstacle[0], obstacle[1]):
+                    continue
+                queue.append((obstacle[0], obstacle[1]))
+                visited.add((obstacle[0], obstacle[1]))
+        return "yes"
+    
+    def is_connected(self, x1, y1, x2, y2):
+        if x1 is None:
+            return abs(y1 - y2) <= BOUND_MIN_DISTANCE
+        # check the distance between (x1, y1) and (x2, y2) <= 6
+        # 6 = 2 x (car radius + obstacle radius)
+        return abs(x1 - x2) ** 2 + abs(y1 - y2) ** 2 <= OBSTACLE_MIN_DISTANCE ** 2  
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/expression-evaluation.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/expression-evaluation.md"
new file mode 100644
index 0000000..51c0ba6
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/expression-evaluation.md"
@@ -0,0 +1,149 @@
+# 表达式求值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/expression-evaluation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个用字符串表示的表达式数组，求出这个表达式的值。
+
+ ### 样例说明
+ **样例 1:**
+```
+对于表达式 `2*6-(23+7)/(1+2)`,
+输入:
+["2", "*", "6", "-", "(","23", "+", "7", ")", "/", "(", "1", "+", "2", ")"]
+输出:
+2
+```
+
+**样例 2:**
+```
+对于表达式 `4-(2-3)*2+5/5`,
+输入:
+["4", "-", "(", "2","-", "3", ")", "*", "2", "+", "5", "/", "5"]
+输出:
+7
+```
+ ### 参考代码
+ 把表达式转为反波兰表达式，存入单调栈，根据优先级，弹出并进行计算
+```java
+class TreeNode {
+	public int val;
+	public String s;
+	public TreeNode left, right;
+
+	public TreeNode(int val, String ss) {
+		this.val = val;
+		this.s = ss;
+		this.left = this.right = null;
+	}
+
+}
+
+public class Solution {
+
+	int get(String a, Integer base) {
+		if (a.equals("+") || a.equals("-"))
+			return 1 + base;
+		if (a.equals("*") || a.equals("/"))
+			return 2 + base;
+
+		return Integer.MAX_VALUE;
+	}
+
+	void dfs(TreeNode root, ArrayList<String> as) {
+		if(root==null)
+			return;
+		if (root.left != null)
+			dfs(root.left, as);
+		
+		if (root.right != null)
+			dfs(root.right, as);
+		as.add(root.s);
+	}
+
+	public int evaluateExpression(String[] expression) {
+		// write your code here
+		Stack<TreeNode> stack = new Stack<TreeNode>();
+		TreeNode root = null;
+		int val = 0;
+		Integer base = 0;
+		for (int i = 0; i <= expression.length; i++) {
+			if(i != expression.length)
+			{
+				
+				if (expression[i].equals("(")) {
+					base += 10;
+					continue;
+				}
+				if (expression[i].equals(")")) {
+					base -= 10;
+					continue;
+				}
+				val = get(expression[i], base);
+
+			}
+			TreeNode right = i == expression.length ? new TreeNode(
+					Integer.MIN_VALUE, "") : new TreeNode(val,
+					expression[i]);
+			while (!stack.isEmpty()) {
+				if (right.val <= stack.peek().val) {
+					TreeNode nodeNow = stack.pop();
+
+					if (stack.isEmpty()) {
+						right.left = nodeNow;
+
+					} else {
+						TreeNode left = stack.peek();
+						if (left.val < right.val) {
+							right.left = nodeNow;
+						} else {
+							left.right = nodeNow;
+						}
+					}
+				} else {
+					break;
+				}
+			}
+			stack.push(right);
+		}
+
+		ArrayList<String> reversepolish = new ArrayList<String>();
+		dfs(stack.peek().left, reversepolish);
+		String[] str = new String[reversepolish.size()];
+		reversepolish.toArray(str);
+		//System.out.println(as);
+		
+		return evalreversepolish(str);
+	}
+
+	int evalreversepolish(String[] tokens) {
+		int returnValue = 0;
+		String operators = "+-*/";
+
+		Stack<String> stack = new Stack<String>();
+
+		for (String ss : tokens) {
+			if (!operators.contains(ss)) {
+				stack.push(ss);
+			} else {
+				int a = Integer.valueOf(stack.pop());
+				int b = Integer.valueOf(stack.pop());
+				if (ss.equals("+")) {
+					stack.push(String.valueOf(a + b));
+				} else if (ss.equals("-")) {
+					stack.push(String.valueOf(b - a));
+				} else if (ss.equals("*")) {
+					stack.push(String.valueOf(a * b));
+				} else if (ss.equals("/")) {
+					stack.push(String.valueOf(b / a));
+				}
+			}
+		}
+		if(stack.isEmpty())
+			returnValue = 0;
+		else 
+			returnValue = Integer.valueOf(stack.pop());
+
+		return returnValue;
+	}
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/factorization.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/factorization.md"
new file mode 100644
index 0000000..8b1e759
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/factorization.md"
@@ -0,0 +1,98 @@
+# 因式分解
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/factorization/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 一个非负数可以被视为其因数的乘积。编写一个函数来返回整数 n 的因数所有可能组合。
+ ### 样例说明
+ **样例1**
+```
+输入：8
+输出： [[2,2,2],[2,4]]
+解释： 8 = 2 x 2 x 2 = 2 x 4
+```
+**样例2**
+```
+输入：1 
+输出： []
+```
+ ### 参考代码
+ 使用dfs解决问题。
+使用List来保存当前已用因数，进入dfs时在最后一位添加一个因数，从dfs中返回时删除最后一个元素。
+当dfs至num=1时，将当前的list存入答案。
+```java
+public class Solution {
+    /**
+     * @param n an integer
+     * @return a list of combination
+     */
+    public List<List<Integer>> getFactors(int n) {
+        // write your code here
+        List<List<Integer>> result = new ArrayList<List<Integer>>();
+        helper(result, new ArrayList<Integer>(), n, 2);
+        return result;
+    }
+
+    public void helper(List<List<Integer>> result, List<Integer> item, int n, int start) {
+        if (n <= 1) {
+            if (item.size() > 1) {
+                result.add(new ArrayList<Integer>(item));
+            }
+            return;
+        }
+    
+        for (int i = start; i <= Math.sqrt(n); ++i) {
+            if (n % i == 0) {
+                item.add(i);
+                helper(result, item, n / i, i);
+                item.remove(item.size()-1);
+            }
+        } 
+        if (n >= start) {
+            item.add(n);
+            helper(result, item, 1, n);
+            item.remove(item.size() - 1);
+        }
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param n an integer
+     * @return a list of combination
+     */
+
+    List<List<Integer>> ans = new ArrayList<>();
+    List<Integer> path = new ArrayList<>();
+
+    void dfs(int start, int remain) {
+        if (remain == 1) {
+            if (path.size() != 1) {
+                ans.add(new ArrayList<>(path)); //deep copy
+            }
+            return;
+        }
+
+        for (int i = start; i <= remain; i++) {
+            if (i > remain / i) {
+                break;
+            }
+            if (remain % i == 0) {
+                path.add(i);                  //进栈
+                dfs(i, remain / i);
+                path.remove(path.size() - 1); //出栈
+            }
+        }
+
+        path.add(remain);
+        dfs(remain, 1);
+        path.remove(path.size() - 1);
+    }
+
+    public List<List<Integer>> getFactors(int n) {
+        // write your code here
+        dfs(2, n);
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/find-the-missing-number-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/find-the-missing-number-ii.md"
new file mode 100644
index 0000000..ed03ebc
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/find-the-missing-number-ii.md"
@@ -0,0 +1,72 @@
+# 寻找丢失的数 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-the-missing-number-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个由 1 - `n` 的整数随机组成的一个字符串序列，其中丢失了一个整数，请找到它。
+ ### 样例说明
+ **样例1**
+
+```
+输入: n = 20 和 str = 19201234567891011121314151618
+输出: 17
+解释:
+19'20'1'2'3'4'5'6'7'8'9'10'11'12'13'14'15'16'18
+```
+
+**样例2**
+
+```
+输入: n = 6 和 str = 56412
+输出: 3
+解释:
+5'6'4'1'2
+```
+ ### 参考代码
+ dfs求解，首先考虑搜索大的数字，这样搜索速度能快一些
+```java
+public class Solution {
+    /**
+     * @param n an integer
+     * @param str a string with number from 1-n
+     *            in random order and miss one number
+     * @return an integer
+     */   
+    public boolean flag = false;
+    public int ans = 0;
+    public int findMissing2(int n, String str) {
+        boolean[] happen = new boolean[n + 1];
+        dfs(0, n, str, happen);
+        return ans;
+    }
+    
+    public void dfs(int i, int n, String s, boolean[] happen) {
+        if (i >= s.length() || flag) {
+        	if (!flag)
+            for (int k = 1; k <= n; k++) {
+                if (!happen[k]) {
+                    ans = k;
+                }
+            }
+        	flag = true;
+            return;
+        }
+        int sum = s.charAt(i) - '0';
+        int j = i;
+        if (sum == 0) {
+            return;
+        }
+        while (sum <= n) {
+            if (!happen[sum]) {
+                happen[sum] = true;
+                dfs(j+1, n, s, happen);
+                happen[sum] = false;
+            }
+            j++;
+            if (j >= s.length()) {
+                break;
+            }
+            sum = sum * 10 + (s.charAt(j) - '0');
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-2d-vector.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-2d-vector.md"
new file mode 100644
index 0000000..14c48a9
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-2d-vector.md"
@@ -0,0 +1,58 @@
+# 摊平二维向量
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/flatten-2d-vector/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个迭代器来实现摊平二维向量的功能
+ ### 样例说明
+ 例1:
+```
+输入:[[1,2],[3],[4,5,6]]
+输出:[1,2,3,4,5,6]
+```
+例2:
+```
+输入:[[7,9],[5]]
+输出:[7,9,5]
+```
+
+ ### 参考代码
+ 记录横纵坐标。这个版本的代码复杂一些，但是无所谓 next 和 hasNext 的调用顺序和次数。
+```python
+class Vector2D(object):
+
+    # @param vec2d {List[List[int]]}
+    def __init__(self, vec2d):
+        self.vec2d = vec2d
+        self.row, self.col = 0, -1
+        self.next_elem = None
+
+    # @return {int} a next element
+    def next(self):
+        if self.next_elem is None:
+            self.hasNext()
+            
+        temp, self.next_elem = self.next_elem, None
+        return temp
+
+    # @return {boolean} true if it has next element
+    # or false
+    def hasNext(self):
+        if self.next_elem:
+            return True
+        
+        self.col += 1
+        while self.row < len(self.vec2d) and self.col >= len(self.vec2d[self.row]):
+            self.row += 1
+            self.col = 0
+            
+        if self.row < len(self.vec2d) and self.col < len(self.vec2d[self.row]):
+            self.next_elem = self.vec2d[self.row][self.col]
+            return True
+            
+        return False
+        
+
+# Your Vector2D object will be instantiated and called as such:
+# i, v = Vector2D(vec2d), []
+# while i.hasNext(): v.append(i.next())
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-binary-tree-to-linked-list.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-binary-tree-to-linked-list.md"
new file mode 100644
index 0000000..287e8ce
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-binary-tree-to-linked-list.md"
@@ -0,0 +1,74 @@
+# 将二叉树拆成链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/flatten-binary-tree-to-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一棵二叉树按照前序遍历拆解成为一个 `假链表`。所谓的假链表是说，用二叉树的 *right* 指针，来表示链表中的 *next* 指针。
+ ### 样例说明
+ **样例 1：**
+```
+输入：{1,2,5,3,4,#,6}
+输出：{1,#,2,#,3,#,4,#,5,#,6}
+解释：
+     1
+    / \
+   2   5
+  / \   \
+ 3   4   6
+ 
+1
+\
+ 2
+  \
+   3
+    \
+     4
+      \
+       5
+        \
+         6
+```
+**样例 2：**
+```
+输入：{1}
+输出：{1}
+解释：
+         1
+         1
+```
+
+ ### 参考代码
+ 使用 Divide & Conquer
+分治函数 return 这个 tree 的最后一个点。> 引用文本
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param root: a TreeNode, the root of the binary tree
+    @return: nothing
+    """
+    def flatten(self, root):
+        self.flatten_and_return_last_node(root)
+        
+    # restructure and return last node in preorder
+    def flatten_and_return_last_node(self, root):
+        if root is None:
+            return None
+            
+        left_last = self.flatten_and_return_last_node(root.left)
+        right_last = self.flatten_and_return_last_node(root.right)
+        
+        # connect 
+        if left_last is not None:
+            left_last.right = root.right
+            root.right = root.left
+            root.left = None
+            
+        return right_last or left_last or root
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-list.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-list.md"
new file mode 100644
index 0000000..cbb6f53
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-list.md"
@@ -0,0 +1,101 @@
+# 列表扁平化
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/flatten-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个列表，该列表中的每个元素要么是个列表，要么是整数。将其变成一个只包含整数的简单列表。
+ ### 样例说明
+ ```
+样例  1:
+	输入: [[1,1],2,[1,1]]
+	输出:[1,1,2,1,1] 
+	
+	样例解释:
+	将其变成一个只包含整数的简单列表。
+
+
+样例 2:
+	输入: [1,2,[1,2]]
+	输出:[1,2,1,2]
+	
+	样例解释: 
+	将其变成一个只包含整数的简单列表。
+	
+样例 3:
+	输入:[4,[3,[2,[1]]]]
+	输出:[4,3,2,1]
+	
+	样例解释: 
+	将其变成一个只包含整数的简单列表。
+	
+```
+
+ ### 参考代码
+ 递归处理，每碰到列表就递归处理，每碰到一个数字就添加进答案数组中。
+
+复杂度O(n)
+```java
+/**
+ * // This is the interface that allows for creating nested lists.
+ * // You should not implement it, or speculate about its implementation
+ * public interface NestedInteger {
+ *
+ *     // @return true if this NestedInteger holds a single integer,
+ *     // rather than a nested list.
+ *     public boolean isInteger();
+ *
+ *     // @return the single integer that this NestedInteger holds,
+ *     // if it holds a single integer
+ *     // Return null if this NestedInteger holds a nested list
+ *     public Integer getInteger();
+ *
+ *     // @return the nested list that this NestedInteger holds,
+ *     // if it holds a nested list
+ *     // Return null if this NestedInteger holds a single integer
+ *     public List<NestedInteger> getList();
+ * }
+ */
+public class Solution {
+
+    // @param nestedList a list of NestedInteger
+    // @return a list of integer
+    public List<Integer> flatten(List<NestedInteger> nestedList) {
+        // Write your code here
+        List<Integer> result = new ArrayList<Integer>();
+        for (NestedInteger ele : nestedList)
+            if (ele.isInteger())
+                result.add(ele.getInteger());
+            else
+                result.addAll(flatten(ele.getList()));
+        return result;
+    }
+}
+
+//non-recursive version
+public class Solution {
+
+    // @param nestedList a list of NestedInteger
+    // @return a list of integer
+    public List<Integer> flatten(List<NestedInteger> nestedList) {
+        boolean isFlat = true;
+        List<NestedInteger> ls = nestedList;
+        while (isFlat) {
+            isFlat = false;
+            List<NestedInteger> newLs = new ArrayList<>();
+            for (NestedInteger ni : ls) {
+                if (ni.isInteger()) {
+                    newLs.add(ni);
+                } else {
+                    newLs.addAll(ni.getList());
+                    isFlat = true;
+                }
+            }
+            ls = newLs;
+        }
+        List<Integer> r = new ArrayList<>();
+        for (NestedInteger ni : ls) {
+            r.add(ni.getInteger());
+        }
+        return r;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/flatten-nested-iterate.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-nested-iterate.md"
similarity index 100%
rename from "\351\242\230\350\247\243/flatten-nested-iterate.md"
rename to "\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-nested-iterate.md"
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-nested-list-iterator.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-nested-list-iterator.md"
new file mode 100644
index 0000000..2df3bf0
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flatten-nested-list-iterator.md"
@@ -0,0 +1,68 @@
+# 摊平嵌套的列表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/flatten-nested-list-iterator/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个嵌套的列表，实现一个迭代器将其摊平。
+一个列表的每个元素可能是整数或者一个列表。
+ ### 样例说明
+ **样例1**
+
+```
+输入: list = [[1,1],2,[1,1]]
+输出: [1,1,2,1,1]
+```
+
+**样例2**
+
+```
+输入: list = [1,[4,[6]]]
+输出: [1,4,6]
+```
+ ### 参考代码
+ 直接枚举列表中的每个数字，然后将这些数字依次放到另一个数组中返回
+```java
+import java.util.Iterator;
+
+public class NestedIterator implements Iterator<Integer> {
+
+    private Stack<NestedInteger> stack;
+    
+    private void pushListToStack(List<NestedInteger> nestedList) {
+        Stack<NestedInteger> temp = new Stack<>();
+        for (NestedInteger nested : nestedList) {
+            temp.push(nested);
+        }
+        
+        while (!temp.isEmpty()) {
+            stack.push(temp.pop());
+        }
+    }
+    
+    public NestedIterator(List<NestedInteger> nestedList) {
+        stack = new Stack<>();
+        pushListToStack(nestedList);
+    }
+
+    // @return {int} the next element in the iteration
+    @Override
+    public Integer next() {
+        if (!hasNext()) {
+            return null;
+        }
+        return stack.pop().getInteger();
+    }
+
+    // @return {boolean} true if the iteration has more element or false
+    @Override
+    public boolean hasNext() {
+        while (!stack.isEmpty() && !stack.peek().isInteger()) {
+            pushListToStack(stack.pop().getList());
+        }
+        
+        return !stack.isEmpty();
+    }
+    
+    @Override
+    public void remove() {}
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flip-game-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flip-game-ii.md"
new file mode 100644
index 0000000..bfbc410
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/flip-game-ii.md"
@@ -0,0 +1,101 @@
+# 翻转游戏II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/flip-game-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 翻转游戏：给定一个只包含两种字符的字符串：`+`和`-`，你和你的小伙伴轮流翻转`"++"`变成`"--"`。当一个人无法采取行动时游戏结束，另一个人将是赢家。
+
+编写一个函数判断是否能够保证先手胜利。
+ ### 样例说明
+ **样例1**
+
+```
+输入: s = "++++"
+输出: true
+解释:
+先手可以通过翻转中间的"++"使字符串变成"+--+"来保证胜利。.
+```
+
+**样例2**
+
+```
+输入: s = "+++++"
+输出: false 
+解释:
+先手赢不了啊，后手都有应对的方法
+"+++--" --> "+----"
+"++--+" --> "----+"
+```
+
+ ### 参考代码
+ ```java
+// 方法一 搜索
+public class Solution {
+    public boolean canWin(String s) {
+        boolean[] state = new boolean[s.length()];
+        for (int i = 0; i < s.length(); i++) {
+            if (s.charAt(i) == '+') {
+                state[i] = true;
+            } else {
+                state[i] = false;
+            }
+        }
+        return search(state);
+    }
+    public boolean search(boolean[] state) {
+        for (int i = 0; i < state.length - 1; i++) {
+            if (state[i] && state[i + 1]) {
+                state[i] = false;
+                state[i + 1] = false;
+                if (!search(state)) {
+                    state[i] = true;
+                    state[i + 1] = true;
+                    return true;
+                } else {
+                    state[i] = true;
+                    state[i + 1] = true;
+                }
+            }
+        }
+        return false;
+    }
+}
+
+
+// 方法二 nim 博弈
+public class Solution {
+    public boolean canWin(String s) {
+        int[] nim = new int[s.length() + 1];
+        boolean[] happen = new boolean[s.length() + 1];
+        for (int i = 2; i <= s.length(); i++) {
+            for (int j = 0; j < i - j - 1; j++) {
+                happen[nim[j] ^ nim[i - j - 2]] = true;
+            }
+            boolean nimEmpty = true;
+            for (int j = 0; j <= s.length(); j++) {
+                if (!happen[j] && nimEmpty) {
+                    nimEmpty = false;
+                    nim[i] = j;
+                } else {
+                    happen[j] = false;
+                }
+            }
+        }
+        int ans = 0;
+        int len = 0;
+        s = s + "-";
+        for (int i = 0; i < s.length(); i++) {
+            if (s.charAt(i) == '+') {
+                len++;
+            } else {
+                ans = ans ^ nim[len];
+                len = 0;
+            }
+        }
+        if (ans == 0) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/increasing-subsequences.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/increasing-subsequences.md"
new file mode 100644
index 0000000..c954055
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/increasing-subsequences.md"
@@ -0,0 +1,92 @@
+# 升序子序列。
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/increasing-subsequences/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找到所有不同的可能的升序子序列，一个升序子序列的长度至少应为2。
+ ### 样例说明
+ 例1:
+```
+输入:
+[4,6,7,7]
+输出:
+[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]
+```
+
+例2:
+```
+输入:
+[65,21,-44,31,-8]
+输出:
+[[-44,-8],[-44,31],[21,31]]
+```
+
+ ### 参考代码
+ 类似 subsets & subsets II 的做法。
+区别在于，对于重复情况的判断要复杂一些。
+时间复杂度当然是 $O(n * 2^n)$ 啦
+```java
+public class Solution {
+    /**
+     * @param nums: an integer array
+     * @return: all the different possible increasing subsequences of the given array
+     */
+    public List<List<Integer>> findSubsequences(int[] nums) {
+        List<List<Integer>> results = new ArrayList<>();
+        if (nums == null || nums.length == 0) {
+            return results;
+        }
+        
+        boolean[] visited = new boolean[nums.length];
+        int[] prev = getPrev(nums);
+        dfs(nums, 0, visited, prev, new ArrayList<>(), results);
+        
+        return results;
+    }
+    
+    private int[] getPrev(int[] nums) {
+        Map<Integer, Integer> hash = new HashMap<>();
+        int[] prev = new int[nums.length];
+        for (int i = 0; i < nums.length; i++) {
+            if (hash.containsKey(nums[i])) {
+                prev[i] = hash.get(nums[i]);
+            } else {
+                prev[i] = -1;
+            }
+            hash.put(nums[i], i);
+        }
+        
+        return prev;
+    }
+    
+    private void dfs(int[] nums,
+                     int index,
+                     boolean[] visited,
+                     int[] prev,
+                     List<Integer> subsequence,
+                     List<List<Integer>> results) {
+        if (subsequence.size() > 1) {
+            results.add(new ArrayList<>(subsequence));
+        }
+                
+        for (int i = index; i < nums.length; i++) {
+            // if it's non increasing, continue
+            if (subsequence.size() > 0 && nums[i] < nums[index - 1]) {
+                continue;
+            }
+            
+            // if it's not the first number of the same value after last selected number
+            // and the last same value number is not selected, continue
+            if (prev[i] != -1 && visited[prev[i]] == false
+                    && (subsequence.size() == 0 || index - 1 < prev[i])) {
+                continue;
+            }
+            
+            subsequence.add(nums[i]);
+            visited[i] = true;
+            dfs(nums, i + 1, visited, prev, subsequence, results);
+            visited[i] = false;
+            subsequence.remove(subsequence.size() - 1);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/k-edit-distance.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/k-edit-distance.md"
new file mode 100644
index 0000000..f4de674
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/k-edit-distance.md"
@@ -0,0 +1,234 @@
+# K步编辑
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/k-edit-distance/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个只含有小写字母的字符串的集合以及一个目标串，输出所有可以经过不多于 `k` 次操作得到目标字符串的字符串。
+
+你可以对字符串进行一下的3种操作:
+
+* 加入1个字母
+
+* 删除1个字母
+
+* 替换1个字母
+ ### 样例说明
+ **样例 1:**
+```
+给出字符串 `["abc","abd","abcd","adc"]`，目标字符串为 `"ac"` ，k = `1`
+返回 `["abc","adc"]`
+输入:
+["abc", "abd", "abcd", "adc"]
+"ac"
+1
+输出:
+["abc","adc"]
+
+解释:
+"abc" 去掉 "b"
+"adc" 去掉 "d"
+```
+
+**样例 2:**
+```
+输入:
+["acc","abcd","ade","abbcd"]
+"abc"
+2
+输出:
+["acc","abcd","ade","abbcd"]
+
+解释:
+"acc" 把 "c" 变成 "b"
+"abcd" 去掉 "d"
+"ade" 把 "d" 变成 "b"把 "e" 变成 "c"
+"abbcd" 去掉 "b" 和 "d"
+```
+ ### 参考代码
+ 滚动数组。用字典树对dfs进行优化。
+```java
+// 九章算法强化班版本
+class TrieNode{
+    public TrieNode[] sons;
+    public boolean isWord;
+    public String word;
+    
+    public TrieNode() {
+        int i;
+        sons = new TrieNode[26];
+        for (i = 0; i < 26; ++i) {
+            sons[i] = null;
+        }
+        
+        isWord = false;
+    }
+    
+    static public void Insert(TrieNode p, String word) {
+        int i;
+        char[] s = word.toCharArray();
+        for (i = 0; i < s.length; ++i) {
+            int c = s[i] - 'a';
+            if (p.sons[c] == null) {
+                p.sons[c] = new TrieNode();
+            }
+            
+            p = p.sons[c];
+        }
+        
+        p.isWord = true;
+        p.word = word;
+    }
+}
+
+public class Solution {
+    /**
+     * @param words: a set of stirngs
+     * @param target: a target string
+     * @param k: An integer
+     * @return: output all the strings that meet the requirements
+     */
+     
+    int K;
+    int n;
+    char[] target;
+    List<String> res;
+    
+    // p is the current TrieNode
+    // f[] representss f[Sp][...]
+    void dfs(TrieNode p, int[] f) {
+        int[] newf;
+        int i;
+        if (p.isWord && f[n] <= K) {
+            res.add(p.word);
+        }
+        
+        for (int c = 0; c < 26; ++c) {
+            if (p.sons[c] == null) {
+                continue;
+            }
+            
+            // calc newf
+            newf = new int[n + 1];
+            // newf[...]: f[Sp + c][....]
+            
+            // newf[j] = Math.min(Math.min(f[j], newf[j-1]), f[j-1]) + 1;
+            for (i = 0; i <= n; ++i) {
+                newf[i] = f[i] + 1;
+            }
+            
+            for (i = 1; i <= n; ++i) {
+                newf[i] = Math.min(newf[i], f[i - 1] + 1);
+            }   
+            
+            for (i = 1; i <= n; ++i) {
+                if (target[i - 1] - 'a' == c) {
+                    newf[i] = Math.min(newf[i], f[i - 1]);
+                }
+                
+                newf[i] = Math.min(newf[i - 1] + 1, newf[i]);
+            }
+            
+            dfs(p.sons[c], newf);
+        }
+    }
+     
+    public List<String> kDistance(String[] words, String targets, int k) {
+        res = new ArrayList<String>();
+        K = k;
+        TrieNode root = new TrieNode();
+        int i;
+        for (i = 0; i < words.length; ++i) {
+            TrieNode.Insert(root, words[i]);
+        }
+        
+        target = targets.toCharArray();
+        n = target.length;
+        int[] f = new int[n + 1];
+        for (i = 0; i <= n; ++i) {
+            f[i] = i;
+        }
+        
+        dfs(root, f);
+        return res;
+    }
+}
+
+
+class TrieNode {
+    // Initialize your data structure here.
+    public TrieNode[] children;
+    public boolean hasWord;
+    public String str;
+    
+    // Initialize your data structure here.
+    public TrieNode() {
+        children = new TrieNode[26];
+        for (int i = 0; i < 26; ++i)
+            children[i] = null;
+        hasWord = false;
+    }
+
+    // Adds a word into the data structure.
+    static public void addWord(TrieNode root, String word) {
+        TrieNode now = root;
+        for(int i = 0; i < word.length(); i++) {
+            Character c = word.charAt(i);
+            if (now.children[c - 'a'] == null) {
+                now.children[c - 'a'] = new TrieNode();
+            }
+            now = now.children[c - 'a'];
+        }
+        now.str = word;
+        now.hasWord = true;
+    }
+}
+
+public class Solution {
+    /**
+     * @param words a set of stirngs
+     * @param target a target string
+     * @param k an integer
+     * @return output all the strings that meet the requirements
+     */
+    public List<String> kDistance(String[] words, String target, int k) {
+        // Write your code here
+        TrieNode root = new TrieNode();
+        for (int i = 0; i < words.length; i++)
+            TrieNode.addWord(root, words[i]);
+
+        List<String> result = new ArrayList<String>();
+
+        int n = target.length();
+        int[] dp = new int[n + 1];
+        for (int i = 0; i <= n; ++i)
+            dp[i] = i;
+
+        find(root, result, k, target, dp);
+        return result;
+    }
+
+    public void find(TrieNode node, List<String> result, int k, String target, int[] dp) {
+        int n = target.length();
+        // dp[i] 表示从Trie的root节点走到当前node节点，形成的Prefix
+        // 和 target的前i个字符的最小编辑距离
+        if (node.hasWord && dp[n] <= k) {
+            result.add(node.str);
+        }
+        int[] next = new int[n + 1];
+        for (int i = 0; i <= n; ++i)
+            next[i] = 0;
+
+        for (int i = 0; i < 26; ++i)
+            if (node.children[i] != null) {
+                next[0] = dp[0] + 1;
+                for (int j = 1; j <= n; j++) {
+                    if (target.charAt(j - 1) - 'a' == i) {
+                        next[j] = Math.min(dp[j - 1], Math.min(next[j - 1] + 1, dp[j] + 1));
+                    } else {
+                        next[j] = Math.min(dp[j - 1] + 1, Math.min(next[j - 1] + 1, dp[j] + 1));
+                    }
+                }
+                find(node.children[i], result, k, target, next);
+            }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/k-sum-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/k-sum-ii.md"
new file mode 100644
index 0000000..6598672
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/k-sum-ii.md"
@@ -0,0 +1,85 @@
+# k数和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/k-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定n个不同的正整数，整数k（1<span style="line-height: 1.42857143;">&lt;=&nbsp;</span><span style="line-height: 1.42857143;">k &lt;= n）以及一个目标数字。　　　　</span></p><p>在这n个数里面找出K个数，使得这K个数的和等于目标数字，你需要找出所有满足要求的方案。</p>
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [1,2,3,4], k = 2, target = 5
+输出:  [[1,4],[2,3]]
+```
+
+**样例 2:**
+
+```
+输入: [1,3,4,6], k = 3, target = 8
+输出:  [[1,3,4]]	
+```
+ ### 参考代码
+ 使用九章算法班上讲的模板
+```
+[[python]]
+class Solution:
+    """
+    @param: A: an integer array
+    @param: k: a postive integer <= length(A)
+    @param: targer: an integer
+    @return: A list of lists of integer
+    """
+    def kSumII(self, A, k, target):
+        A = sorted(A)
+        subsets = []
+        self.dfs(A, 0, k, target, [], subsets)
+        return subsets
+        
+    def dfs(self, A, index, k, target, subset, subsets):
+        if k == 0 and target == 0:
+            subsets.append(list(subset))
+            return
+        
+        if k == 0 or target <= 0:
+            return
+        
+        for i in range(index, len(A)):
+            subset.append(A[i])
+            self.dfs(A, i + 1, k - 1, target - A[i], subset, subsets)
+            subset.pop()
+
+[[java]]
+public class Solution {
+    /*
+     * @param A: an integer array
+     * @param k: a postive integer <= length(A)
+     * @param target: an integer
+     * @return: A list of lists of integer
+     */
+    public List<List<Integer>> kSumII(int[] A, int k, int target) {
+        Arrays.sort(A);
+        List<List<Integer>> subsets = new ArrayList();
+        
+        dfs(A, 0, k, target, new ArrayList<Integer>(), subsets);
+        
+        return subsets;
+    }
+    
+    private void dfs(int[] A, int index, int k, int target,
+                     List<Integer> subset,
+                     List<List<Integer>> subsets) {
+        if (k == 0 && target == 0) {
+            subsets.add(new ArrayList<Integer>(subset));
+            return;
+        }
+        if (k == 0 || target <= 0) {
+            return;
+        }
+        
+        for (int i = index; i < A.length; i++) {
+            subset.add(A[i]);
+            dfs(A, i + 1, k - 1, target - A[i], subset, subsets);
+            subset.remove(subset.size() - 1);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/k-sum.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/k-sum.md"
new file mode 100644
index 0000000..7a98b39
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/k-sum.md"
@@ -0,0 +1,138 @@
+# K数之和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/k-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定 *n* 个不同的正整数，整数 *k*（*k* <= *n*）以及一个目标数字 *target*。　
+在这 *n* 个数里面找出 *k* 个数，使得这 *k* 个数的和等于目标数字，求问有多少种方案？
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+List = [1,2,3,4]
+k = 2
+target = 5
+输出: 2
+说明: 1 + 4 = 2 + 3 = 5
+```
+
+**样例2**
+
+```plain
+输入:
+List = [1,2,3,4,5]
+k = 3
+target = 6
+输出: 1
+说明: 只有这一种方案。 1 + 2 + 3 = 6
+```
+
+
+ ### 参考代码
+ 采用动态规划（dp）的思想，进行状态转移，记录数字和和出现次数之间的关系。
+用$dp[i][j][k]$表示前$i$个数里选$j$个和为$k$的方案数。
+```java
+public class Solution {
+    /**
+     * @param A: an integer array.
+     * @param k: a positive integer (k <= length(A))
+     * @param target: a integer
+     * @return an integer
+     */
+    public int  kSum(int A[], int k, int target) {
+        int n = A.length;
+        int[][][] f = new int[n + 1][k + 1][target + 1];
+        for (int i = 0; i < n + 1; i++) {
+            f[i][0][0] = 1;
+        }
+        for (int i = 1; i <= n; i++) {
+            for (int j = 1; j <= k && j <= i; j++) {
+                for (int t = 1; t <= target; t++) {
+                    f[i][j][t] = 0;
+                    if (t >= A[i - 1]) {
+                        f[i][j][t] = f[i - 1][j - 1][t - A[i - 1]];
+                    }
+                    f[i][j][t] += f[i - 1][j][t];
+                } // for t
+            } // for j
+        } // for i
+        return f[n][k][target];
+    }
+}
+
+// 九章动态规划专题班
+// 打印所有方案版本
+public class Solution {
+    /**
+     * @param A: An integer array
+     * @param k: A positive integer (k <= length(A))
+     * @param target: An integer
+     * @return: An integer
+     */
+     
+    int[] res;
+    int tot;
+    int[] A;
+    int K;
+    int[][][] f;
+    
+    void printAnswer(int i, int j, int k) {
+        if (j == 0) {
+            for (int h = 0; h < K; ++h) {
+                System.out.print(res[h]);
+                if (h == K - 1) {
+                    System.out.println("=" + tot);
+                }
+                else {
+                    System.out.print("+");
+                }
+            }
+            
+            return;
+        }
+        
+        if (f[i - 1][j][k] > 0) {
+            printAnswer(i - 1, j, k);
+        }
+        
+        if (j > 0 && k >= A[i - 1] && f[i - 1][j - 1][k - A[i - 1]] > 0) {
+            res[j - 1] = A[i - 1];
+            printAnswer(i - 1, j - 1, k - A[i - 1]);
+        }
+    }
+    
+    public int kSum(int[] AA, int KK, int T) {
+        K = KK;
+        A = AA;
+        int n = A.length;
+        res = new int[K];
+        tot = T;
+        f = new int[n + 1][K + 1][T + 1];
+        int i, j, k;
+        for (j = 0; j <= K; ++j) {
+            for (k = 0; k <= T; ++k) {
+                f[0][j][k] = 0;
+            }
+        }
+        
+        f[0][0][0] = 1;
+        for (i = 1; i <= n; ++i) {
+            for (j = 0; j <= K; ++j) {
+                for (k = 0; k <= T; ++k) {
+                    // not using A[i - 1]
+                    f[i][j][k] = f[i - 1][j][k];
+                    
+                    // using A[i - 1]
+                    if (j > 0 && k >= A[i - 1]) {
+                        f[i][j][k] += f[i - 1][j - 1][k - A[i - 1]];
+                    }
+                }
+            }
+        }
+        
+        printAnswer(n, K, T);
+        
+        return f[n][K][T];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/keys-and-rooms.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/keys-and-rooms.md"
new file mode 100644
index 0000000..85eca8a
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/keys-and-rooms.md"
@@ -0,0 +1,56 @@
+# 钥匙和房间
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/keys-and-rooms/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有 `N` 个房间，开始时你位于 `0` 号房间。每个房间有不同的号码：`0，1，2，...，N-1`，并且房间里可能有一些钥匙能使你进入下一个房间。
+
+在形式上，对于每个房间 `i` 都有一个钥匙列表 `rooms[i]`，每个钥匙 `rooms[i][j]`由 `[0,1，...，N-1]` 中的一个整数表示，其中 `N = rooms.length`。 钥匙 `rooms[i][j] = v` 可以打开编号为 `v` 的房间。
+
+最初，除 `0` 号房间外的其余所有房间都被锁住。
+
+你可以自由地在房间之间来回走动。
+
+如果能进入每个房间返回 `true`，否则返回 `false`。
+ ### 样例说明
+ **样例 1:**
+```
+输入: rooms = [[1],[2],[3],[]]
+输出: true
+解释:  
+我们从 0 号房间开始，拿到钥匙 1。
+之后我们去 1 号房间，拿到钥匙 2。
+然后我们去 2 号房间，拿到钥匙 3。
+最后我们去了 3 号房间。
+由于我们能够进入每个房间，我们返回 true。
+```
+**样例 2:**
+```
+输入: rooms = [[1,3],[3,0,1],[2],[0]]
+输出: false
+解释: 
+我们不能进入 2 号房间。
+```
+ ### 参考代码
+ 看看从0出发能否连通所有的点。
+找连通性问题用 BFS
+
+```
+[[python]]
+class Solution:
+    """
+    @param rooms: a list of keys rooms[i]
+    @return: can you enter every room
+    """
+    def canVisitAllRooms(self, rooms):
+        from collections import deque
+        queue = deque([0])
+        visited = set([0])
+        while queue:
+            room_id = queue.popleft()
+            for next_room_id in rooms[room_id]:
+                if next_room_id in visited:
+                    continue
+                queue.append(next_room_id)
+                visited.add(next_room_id)
+        return len(visited) == len(rooms)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/letter-combinations-of-a-phone-number-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/letter-combinations-of-a-phone-number-ii.md"
new file mode 100644
index 0000000..80395a0
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/letter-combinations-of-a-phone-number-ii.md"
@@ -0,0 +1,77 @@
+# Letter Combinations of a Phone Number II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/letter-combinations-of-a-phone-number-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一些不包含`0`和`1`的数字字符串和一个字典，对于每个数字字符串，每个数字代表一个字母，请返回字典中可以匹配的字母组合的数量。
+
+如果可以用一个数字字符串可以表示出一个单词的前缀，我们认为他们之间是匹配的。
+
+下图的手机按键图，就表示了每个数字可以代表的字母。
+
+1|2<br />ABC|3<br />DEF
+:--:|:--:|:--:
+**4**<br />**GHI**|**5**<br />**JKL**|**6**<br />**MNO**
+**7**<br />**PQRS**|**8**<br />**TUV**|**9**<br />**WXYZ**
+ ### 样例说明
+ 
+ ### 参考代码
+ 这个题不需要 DFS，只需要建 Trie 就行。
+存在 Trie 里的不是单词，而是单词转成数字之后的字符串。
+比如词典里有 `["a", "abc", "de", "fg"]`，存在 Trie 里的就是 `["2", "222", "33", "34"]`
+之后的话 for queries 里的每个 query，在 Trie 里沿着 query 走到对应的节点上看一下计数就行。
+
+```
+[[python]]
+REVERSE_KEYBOARD = {
+    "a": "2", "b": "2", "c": "2",
+    "d": "3", "e": "3", "f": "3",
+    "g": "4", "h": "4", "i": "4",
+    "j": "5", "k": "5", "l": "5",
+    "m": "6", "n": "6", "o": "6",
+    "p": "7", "q": "7", "r": "7", "s": "7",
+    "t": "8", "u": "8", "v": "8",
+    "w": "9", "x": "9", "y": "9", "z": "9",
+}
+
+class TrieNode:
+    
+    def __init__(self):
+        self.word_count = 0
+        self.children = {}
+        
+    def add(self, word):
+        node = self
+        for char in word:
+            if char not in node.children:
+                node.children[char] = TrieNode()
+            node = node.children[char]
+            node.word_count += 1
+    
+    
+class Solution:
+    """
+    @param queries: the queries
+    @param dict: the words
+    @return: return the queries' answer
+    """
+    def letterCombinationsII(self, queries, dict):
+        root = TrieNode()
+        for word in dict:
+            digit_word = ''.join([
+                REVERSE_KEYBOARD[c]
+                for c in word
+            ])
+            root.add(digit_word)
+            
+        results = []
+        for query in queries:
+            node = root
+            for char in query:
+                if char not in node.children:
+                    node = None
+                    break
+                node = node.children[char]
+            results.append(node.word_count if node else 0)
+            
+        return results
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/letter-combinations-of-a-phone-number.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/letter-combinations-of-a-phone-number.md"
new file mode 100644
index 0000000..39f4bbe
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/letter-combinations-of-a-phone-number.md"
@@ -0,0 +1,67 @@
+# 电话号码的字母组合
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/letter-combinations-of-a-phone-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个不包含`0`和`1`的数字字符串，每个数字代表一个字母，请返回其所有可能的字母组合。
+
+下图的手机按键图，就表示了每个数字可以代表的字母。
+
+1|2<br />ABC|3<br />DEF
+:--:|:--:|:--:
+**4**<br />**GHI**|**5**<br />**JKL**|**6**<br />**MNO**
+**7**<br />**PQRS**|**8**<br />**TUV**|**9**<br />**WXYZ**
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "23"
+输出: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
+解释: 
+'2' 可以是 'a', 'b' 或 'c'
+'3' 可以是 'd', 'e' 或 'f'
+```
+
+**样例 2:**
+
+```
+输入: "5"
+输出: ["j", "k", "l"]
+```
+ ### 参考代码
+ 使用深度优先搜索算法。
+```
+KEYBOARD = {
+    '2': 'abc',
+    '3': 'def',
+    '4': 'ghi',
+    '5': 'jkl',
+    '6': 'mno',
+    '7': 'pqrs',
+    '8': 'tuv',
+    '9': 'wxyz',
+}
+
+class Solution:
+    """
+    @param digits: A digital string
+    @return: all posible letter combinations
+    """
+    def letterCombinations(self, digits):
+        if not digits:
+            return []
+            
+        results = []
+        self.dfs(digits, 0, [], results)
+        
+        return results
+    
+    def dfs(self, digits, index, chars, results):
+        if index == len(digits):
+            results.append(''.join(chars))
+            return
+        
+        for letter in KEYBOARD[digits[index]]:
+            chars.append(letter)
+            self.dfs(digits, index + 1, chars, results)
+            chars.pop()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/longest-consecutive-sequence.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/longest-consecutive-sequence.md"
new file mode 100644
index 0000000..0f53a11
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/longest-consecutive-sequence.md"
@@ -0,0 +1,88 @@
+# 最长连续序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-consecutive-sequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个未排序的整数数组，找出最长连续序列的长度。</p>
+ ### 样例说明
+ ***样例 1***
+```
+输入 : [100, 4, 200, 1, 3, 2]
+输出 : 4
+解释 : 这个最长的连续序列是 [1, 2, 3, 4]. 返回所求长度 4
+```
+ ### 参考代码
+ Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
+
+For example,
+Given [100, 4, 200, 1, 3, 2],
+The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.
+
+Your algorithm should run in O(n) complexity.
+```java
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @return an integer
+     */
+    public int longestConsecutive(int[] nums) {
+        HashSet<Integer> set = new HashSet<>();
+        for (int i = 0; i < nums.length; i++) {
+            set.add(nums[i]);
+        }
+        
+        int longest = 0;
+        for (int i = 0; i < nums.length; i++) {
+            int down = nums[i] - 1;
+            while (set.contains(down)) {
+                set.remove(down);
+                down--;
+            }
+            
+            int up = nums[i] + 1;
+            while (set.contains(up)) {
+                set.remove(up);
+                up++;
+            }
+            
+            longest = Math.max(longest, up - down - 1);
+        }
+        
+        return longest;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @return an integer
+     */
+    public int longestConsecutive(int[] num) {
+        // write you code here
+        Set<Integer> set = new HashSet<>();
+        for (int item : num) {
+            set.add(item);
+        }
+
+        int ans = 0;
+        for (int item : num) {
+            if (set.contains(item)) {
+                set.remove(item);
+
+                int l = item - 1;
+                int r = item + 1;
+                while (set.contains(l)) {
+                    set.remove(l);
+                    l--;
+                }
+                while (set.contains(r)) {
+                    set.remove(r);
+                    r++;
+                }
+                ans = Math.max(ans, r - l - 1);
+            }
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-depth-of-binary-tree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-depth-of-binary-tree.md"
new file mode 100644
index 0000000..937e43c
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-depth-of-binary-tree.md"
@@ -0,0 +1,53 @@
+# 二叉树的最大深度
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-depth-of-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，找出其最大深度。
+
+二叉树的深度为根节点到最远叶子节点的距离。
+ ### 样例说明
+ **样例  1:**
+
+```
+输入: tree = {}
+输出: 0	
+样例解释: 空树的深度是0。
+```
+**样例  2:**
+
+```
+输入: tree = {1,2,3,#,#,4,5}
+输出: 3
+样例解释: 树表示如下，深度是3
+   1
+  / \                
+ 2   3                
+    / \                
+   4   5
+它将被序列化为{1,2,3,#,#,4,5}
+```
+
+ ### 参考代码
+ Given a binary tree, find its maximum depth.
+
+The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.<div><br></div><div>详细解答请至九章微博：<a href="http://weibo.com/3948019741/BBY7gwi89" target="_blank">http://weibo.com/3948019741/BBY7gwi89</a></div>
+
+简单的树的遍历，点i为根的树高度，等于高度最大的子树的高度+1。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root: The root of binary tree.
+    @return: An integer
+    """ 
+    def maxDepth(self, root):
+        if root is None:
+            return 0
+        return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-difference.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-difference.md"
new file mode 100644
index 0000000..4eafd67
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-difference.md"
@@ -0,0 +1,97 @@
+# 最大子数组差
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-difference/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个整数数组，找出两个<b><font color="#e76363">不重叠</font></b>的子数组A和B，使两个子数组和的差的绝对值<strong style="line-height: 1.42857143; font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"><font color="#e76363">|SUM(A) - SUM(B)|</font></strong><span style="line-height: 1.42857143;">最大。</span></p><p>返回这个最大的差值。</p>
+ ### 样例说明
+ 
+例1:
+```
+输入:[1, 2, -3, 1]
+输出:6
+解释:
+子数组是 [1,2] 和[-3].所以答案是 6.
+```
+
+例2:
+```
+输入:[0,-1]
+输出:1
+解释:
+子数组是 [0] 和 [-1].所以答案是 1.
+```
+
+
+
+ ### 参考代码
+ dp。
+维护四个数组，当前位置左边的最大子数组和，最小子数组和。当前位置右边的最大子数组和，最小子数组和。
+然后枚举分割线，扫描一下即可。
+```java
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @return: An integer indicate the value of maximum difference between two
+     *          Subarrays
+     */
+    public int maxDiffSubArrays(int[] nums) {
+        // write your code here
+        int size = nums.length;
+        int[] left_max = new int[size];
+        int[] left_min = new int[size];
+        int[] right_max = new int[size];
+        int[] right_min = new int[size];
+        int[] copy = new int[size];
+        /*Get negative copy*/
+        for(int i = 0; i < size; i++){
+            copy[i] = -1 * nums[i];
+        }
+        int max = Integer.MIN_VALUE;
+        int sum = 0;
+        int minSum = 0;
+        /*Forward: get max subarray*/
+        for(int i = 0; i < size; i++){
+            sum += nums[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            left_max[i] = max;
+        }
+        /*Backward: get max subarray*/
+        max = Integer.MIN_VALUE;
+        sum = 0;
+        minSum = 0;
+        for(int i = size - 1; i >= 0; i--){
+            sum += nums[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            right_max[i] = max;
+        }
+        /*Forward: get min subarray*/
+        max = Integer.MIN_VALUE;
+        sum = 0;
+        minSum = 0;
+        for(int i = 0; i < size; i++){
+            sum += copy[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            left_min[i] = -1 * max;
+        }
+        /*Backward: get min subarray*/
+        max = Integer.MIN_VALUE;
+        sum = 0;
+        minSum = 0;
+        for(int i = size - 1; i >= 0; i--){
+            sum += copy[i];
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            right_min[i] = -1 * max;
+        }
+        int diff = 0;
+        for(int i = 0; i < size - 1; i++){
+            diff = Math.max(diff, Math.abs(left_max[i] - right_min[i + 1]));
+            diff = Math.max(diff, Math.abs(left_min[i] - right_max[i + 1]));
+        }
+        return diff;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-ii.md"
new file mode 100644
index 0000000..3725355
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-ii.md"
@@ -0,0 +1,69 @@
+# 最大子数组 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找出两个 *不重叠* 子数组使得它们的和最大。
+每个子数组的数字在数组中的位置应该是连续的。
+返回最大的和。
+ ### 样例说明
+ 
+例1:
+```
+输入:
+[1, 3, -1, 2, -1, 2]
+输出:
+7
+解释:
+最大的子数组为 [1, 3] 和 [2, -1, 2] 或者 [1, 3, -1, 2] 和 [2].
+```
+
+例2:
+```
+输入:
+[5,4]
+输出:
+9
+解释:
+最大的子数组为 [5] 和 [4].
+```
+
+ ### 参考代码
+ <p style="color: rgb(113, 113, 113); font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"></p><p>这个题的思路是，因为 两个subarray 一定不重叠</p><p><span style="background-color: initial;">所以必定存在一条分割线</span><br></p><p><span style="background-color: initial;">分开这两个 subarrays</span><br></p><p><span style="background-color: initial;">所以 最后的部分里：</span><br></p><p>&nbsp; max = Integer.MIN_VALUE;</p><p>&nbsp; &nbsp; &nbsp; &nbsp; for(int i = 0; i &lt; size - 1; i++){</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; max = Math.max(max, left[i] + right[i + 1]);</p><p>&nbsp; &nbsp; &nbsp; &nbsp; }</p><p>&nbsp; &nbsp; &nbsp; &nbsp; return max;</p><p>这里是在枚举 这条分割线的位置</p><p><span style="background-color: initial;">然后 left[] 和 right[] 里分别存的是，某个位置往左的 maximum subarray 和往右的 maximum subarray</span><br></p><p style="color: rgb(113, 113, 113); font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"></p>
+
+```java
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @return: An integer denotes the sum of max two non-overlapping subarrays
+     */
+    public int maxTwoSubArrays(ArrayList<Integer> nums) {
+        // write your code
+        int size = nums.size();
+        int[] left = new int[size];
+        int[] right = new int[size];
+        int sum = 0;
+        int minSum = 0;
+        int max = Integer.MIN_VALUE;
+        for(int i = 0; i < size; i++){
+            sum += nums.get(i);
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            left[i] = max;
+        }
+        sum = 0;
+        minSum = 0;
+        max = Integer.MIN_VALUE;
+        for(int i = size - 1; i >= 0; i--){
+            sum += nums.get(i);
+            max = Math.max(max, sum - minSum);
+            minSum = Math.min(sum, minSum);
+            right[i] = max;
+        }
+        max = Integer.MIN_VALUE;
+        for(int i = 0; i < size - 1; i++){
+            max = Math.max(max, left[i] + right[i + 1]);
+        }
+        return max;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-iii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-iii.md"
new file mode 100644
index 0000000..c3fdaed
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-iii.md"
@@ -0,0 +1,113 @@
+# 最大子数组 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组和一个整数 *k*，找出 *k* 个**不重叠**子数组使得它们的和最大。每个子数组的数字在数组中的位置应该是**连续**的。
+
+返回最大的和。
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: 
+List = [1,2,3]
+k = 1
+输出: 6
+说明: 1 + 2 + 3 = 6
+```
+
+**样例2**
+
+```plain
+输入:
+List = [-1,4,-2,3,-2,3]
+k = 2
+输出: 8
+说明: 4 + (3 + -2 + 3) = 8
+```
+
+
+ ### 参考代码
+ DP: an array partition into k parts or k operation (like buy and sell stock)
+Use local max and global max
+$localMax[n][k]$ defines max sum, must have nth element for n and partition into k parts.
+$globalMax[n][k]$ defines max sum, may not have nth element for n and partition into k parts.
+```java
+// 方法一 划分类DP
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @param k: An integer denote to find k non-overlapping subarrays
+     * @return: An integer denote the sum of max k non-overlapping subarrays
+     */
+    public int maxSubArray(int[] nums, int k) {
+        if (nums.length < k) {
+            return 0;
+        }
+        int len = nums.length;
+        
+       
+        int[][] globalMax = new int[k + 1][len + 1];
+        int[][] localMax = new int[k + 1][len + 1];
+        
+        for (int i = 1; i <= k; i++) {
+            localMax[i][i-1] = Integer.MIN_VALUE;
+            //小于 i 的数组不能够partition
+            for (int j = i; j <= len; j++) {
+                localMax[i][j] = Math.max(localMax[i][j-1], globalMax[i - 1][j-1]) + nums[j-1];
+                if (j == i)
+                    globalMax[i][j] = localMax[i][j];
+                else
+                    globalMax[i][j] = Math.max(globalMax[i][j-1], localMax[i][j]);
+            }
+        }
+        return globalMax[k][len];
+    }
+    
+}
+
+
+//方法二
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @param k: An integer denote to find k non-overlapping subarrays
+     * @return: An integer denote the sum of max k non-overlapping subarrays
+     */ 
+    public static int maxSubArray(ArrayList<Integer> nums, int k) {
+        // write your code
+        int len = nums.size();
+        int[][] f = new int[k+1][len];
+        for (int i = 1; i < k+1; i++) {
+            int sum = 0;
+            for (int j = 0; j < i; j++) {
+                sum += nums.get(j);
+            }
+            f[i][i-1] = sum;
+        }
+        for (int i = 1; i < len; i++) {
+        	f[1][i] = Math.max(f[1][i-1]+nums.get(i), nums.get(i));
+        }
+        
+        for (int i = 2; i < k+1; i++) {
+            for (int n = i;  n< len; n++) {
+                int curMax = f[i][n-1] + nums.get(n);
+                for (int j = i-2; j < n; j++) {
+                    if ((f[i-1][j] + nums.get(n)) > curMax) {
+                        curMax = f[i-1][j] + nums.get(n);
+                    }
+                }
+                f[i][n] = curMax;
+            }
+        }
+        
+        int res = Integer.MIN_VALUE;
+        for (int i = k-1; i < len; i++){
+            if (f[k][i] > res) {
+                res = f[k][i];
+            }
+        }
+        return res;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-iv.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-iv.md"
new file mode 100644
index 0000000..227191f
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-iv.md"
@@ -0,0 +1,69 @@
+# 最大子序列的和IV
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-iv/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找到长度大于或等于 `k` 的连续子序列使它们的和最大，返回这个最大的和，如果数组中少于k个元素则返回 `0`
+ ### 样例说明
+ 例1:
+```
+输入:
+[-2,2,-3,4,-1,2,1,-5,3]
+5
+输出:
+5
+解释:
+[2,-3,4,-1,2,1]
+sum=5
+```
+
+例2:
+```
+输入:
+[5,-10,4]
+2
+输出:
+-1
+```
+
+
+ ### 参考代码
+ 一维dp即可。
+维护一个前缀和。
+再维护一个前缀合法最小和，
+转移方程如下：
+ result = Math.max(result, sum[i] - min_prefix)
+min_prefix = Math.min(min_prefix, sum[i - k + 1])
+```java
+public class Solution {
+    /**
+     * @param nums an array of integers
+     * @param k an integer
+     * @return the largest sum
+     */
+    public int maxSubarray4(int[] nums, int k) {
+        // Write your code here
+        int n = nums.length;
+        if (n < k)
+            return 0;
+
+        int result = 0;
+        for (int i = 0; i < k; ++i)
+            result += nums[i];
+
+        int[] sum = new int[n + 1];
+        sum[0] = 0;
+        
+        int min_prefix = 0;
+        for (int i = 1; i <= n; ++i) {
+            sum[i] = sum[i - 1] + nums[i - 1];
+            if (i >= k && sum[i] - min_prefix > result) {
+                result = Math.max(result, sum[i] - min_prefix);
+            }
+            if (i >= k) {
+                min_prefix = Math.min(min_prefix, sum[i - k + 1]);
+            }
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-v.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-v.md"
new file mode 100644
index 0000000..aaf70e8
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray-v.md"
@@ -0,0 +1,74 @@
+# 最大子数组 V
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray-v/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找到长度在 `k1` 与 `k2` 之间(包括 k1, k2)的子数组并且使它们的和最大，返回这个最大值，如果数组元素个数小于 k1 则返回 0
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+[-2,2,-3,4,-1,2,1,-5,3]
+2
+4
+输出:
+6
+
+解释:
+连续子数组为 `[4,-1,2,1]` 时有最大和 `6`
+```
+
+**样例 2:**
+```
+输入:
+[1,1,2,3]
+5
+10
+输出:
+0
+```
+ ### 参考代码
+ 滑动窗口系列题，deque维护子数组，每一次窗口滑动则：前缀和 - 队头，最后得出最大值。
+```java
+public class Solution {
+    /**
+     * @param nums an array of integers
+     * @param k1 an integer
+     * @param k2 an integer
+     * @return the largest sum
+     */
+    public int maxSubarray5(int[] nums, int k1, int k2) {
+        // Write your code here
+        int n = nums.length;
+        if (n < k1)
+            return 0;
+
+        int result = Integer.MIN_VALUE;
+
+        int[] sum = new int[n + 1];
+        sum[0] = 0;
+        LinkedList<Integer> queue = new LinkedList<Integer>();
+
+        for (int i = 1; i <= n; ++i) {
+            sum[i] = sum[i - 1] + nums[i - 1];
+
+            if (!queue.isEmpty() && queue.getFirst() < i - k2) {
+                queue.removeFirst();
+            }
+            if (i >= k1) {
+                while (!queue.isEmpty() && sum[queue.getLast()] > sum[i - k1]) {
+                    queue.removeLast();
+                }
+                queue.add(i - k1);
+            }
+
+            // [i - k2, i - k1]
+            if (!queue.isEmpty() && sum[i] - sum[queue.getFirst()] > result) {
+                result = Math.max(result, sum[i] - sum[queue.getFirst()]);
+            }
+
+
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray.md"
new file mode 100644
index 0000000..9a42d39
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subarray.md"
@@ -0,0 +1,41 @@
+# 最大子数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subarray/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找到一个具有最大和的子数组，返回其最大和。
+ ### 样例说明
+ **样例1:**
+
+```
+输入：[−2,2,−3,4,−1,2,1,−5,3]
+输出：6
+解释：符合要求的子数组为[4,−1,2,1]，其最大和为 6。
+```
+
+**样例2:**
+
+```
+输入：[1,2,3,4]
+输出：10
+解释：符合要求的子数组为[1,2,3,4]，其最大和为 10。
+```
+ ### 参考代码
+ 使用前缀和的方法，计算每个位置为结尾的 subarray 的最大值是多少。
+```python
+class Solution:
+    """
+    @param nums: A list of integers
+    @return: A integer indicate the sum of max subarray
+    """
+    def maxSubArray(self, nums):
+        #prefix_sum记录前i个数的和，max_Sum记录全局最大值，min_Sum记录前i个数中0-k的最小值
+        min_sum, max_sum = 0, -sys.maxsize
+        prefix_sum = 0
+        
+        for num in nums:
+            prefix_sum += num
+            max_sum = max(max_sum, prefix_sum - min_sum)
+            min_sum = min(min_sum, prefix_sum)
+            
+        return max_sum
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-submatrix.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-submatrix.md"
new file mode 100644
index 0000000..fc07053
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-submatrix.md"
@@ -0,0 +1,110 @@
+# 最大子矩阵
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-submatrix/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个大小为 `n x n` 的矩阵，里面元素为 `正整数` 和 `负整数` ，找到具有最大和的子矩阵。
+ ### 样例说明
+ **样例1**
+
+```
+输入:
+matrix = [
+    [1,3,-1],
+    [2,3,-2],
+    [-1,-2,-3]
+]
+输出: 9
+解释:
+具有最大和的子矩阵是:
+[
+    [1,3],
+    [2,3]
+]
+```
+
+**样例2**
+
+```
+输入:
+matrix = [
+    [1,1,1],
+    [1,1,1],
+    [1,1,1]
+]
+输出: 9
+解释:
+具有最大和的子矩阵是:
+[
+    [1,1,1],
+    [1,1,1],
+    [1,1,1]
+]
+```
+ ### 参考代码
+ 枚举子矩阵的上下边界 up & down, 然后将这之间的数压缩为一个一维数组（降维攻击），剩下的任务就是一维数组如何求 Maximum Subarray 了。
+```java
+public class Solution {
+  int n, m;
+  
+  /**
+   * @param matrix: the given matrix
+   * @return: the largest possible sum
+   */
+  public int maxSubmatrix(int[][] matrix) {
+    if (matrix == null || matrix.length == 0) {
+      return 0;
+    }
+    if (matrix[0] == null || matrix[0].length == 0) {
+      return 0;
+    }
+    
+    n = matrix.length;
+    m = matrix[0].length;
+    
+    int[][] prefixColSum = getPrefixColSum(matrix);
+    
+    int max = Integer.MIN_VALUE;
+    for (int up = 0; up < n; up++) {
+      for (int down = up; down < n; down++) {
+        int[] arr = compression(matrix, up, down, prefixColSum);
+        max = Math.max(max, maximumSubarray(arr));
+      }
+    }
+    
+    return max;
+  };
+  
+  private int maximumSubarray(int[] arr) {
+    int min = 0, max = Integer.MIN_VALUE, sum = 0;
+    
+    for (int i = 0; i < m; i++) {
+      sum += arr[i];
+      max = Math.max(max, sum - min);
+      min = Math.min(min, sum);
+    }
+    
+    return max;
+  }
+  
+  private int[] compression(int[][] matrix, int up, int down, int[][] prefixColSum) {
+    int[] arr = new int[m];
+    for (int i = 0; i < m; i++) {
+      arr[i] = prefixColSum[down + 1][i] - prefixColSum[up][i];
+    }
+    
+    return arr;
+  }
+  
+  private int[][] getPrefixColSum(int[][] matrix) {
+    int[][] sum = new int[n + 1][m];
+    
+    for (int i = 0; i < n; i++) {
+      for (int j = 0; j < m; j++) {
+        sum[i + 1][j] = sum[i][j] + matrix[i][j];
+      }
+    }
+    
+    return sum;
+  }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subtree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subtree.md"
new file mode 100644
index 0000000..28599fa
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/maximum-subtree.md"
@@ -0,0 +1,64 @@
+# 最大子树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-subtree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一棵二叉树，找二叉树中的一棵子树，他的所有节点之和最大。
+
+返回这棵子树的根节点。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+{1,-5,2,0,3,-4,-5}
+输出:3
+说明
+这棵树如下所示：
+     1
+   /   \
+ -5     2
+ / \   /  \
+0   3 -4  -5
+以3为根的子树（只有3一个节点）的和是最大的，所以返回3。
+```
+
+**样例 2:**
+
+```
+输入:
+{1}
+输出:1
+说明:
+这棵树如下所示：
+   1
+这棵树只有整体这一个子树，所以返回1.
+```
+ ### 参考代码
+ 以每个点为根节点root（即每一个子树），找到左子树的节点x和与右子树的节点和y。如果root.val + x.val + y.val > 当前已知最大值，就更新答案。
+```python
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @return {int} the maximum weight node
+    import sys
+    maximum_weight = 0
+    result = None
+
+    def findSubtree(self, root):
+        # Write your code here
+        self.helper(root)
+
+        return self.result
+
+    def helper(self, root):
+        if root is None:
+            return 0
+
+        left_weight = self.helper(root.left)
+        right_weight = self.helper(root.right)
+        
+        if left_weight + right_weight + root.val >= self.maximum_weight or self.result is None:
+            self.maximum_weight = left_weight + right_weight + root.val
+            self.result = root
+
+        return left_weight + right_weight + root.val
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/minimum-depth-of-binary-tree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/minimum-depth-of-binary-tree.md"
new file mode 100644
index 0000000..73217da
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/minimum-depth-of-binary-tree.md"
@@ -0,0 +1,75 @@
+# 二叉树的最小深度
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-depth-of-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，找出其最小深度。
+
+二叉树的最小深度为根节点到最近叶子节点的最短路径上的节点数量。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {}
+输出: 0
+```
+
+**样例 2:**
+
+```
+输入:  {1,#,2,3}
+输出: 3	
+解释:
+	1
+	 \ 
+	  2
+	 /
+	3    
+它将被序列化为 {1,#,2,3}
+```
+
+**样例 3:**
+
+```
+输入:  {1,2,3,#,#,4,5}
+输出: 2	
+解释: 
+      1
+     / \ 
+    2   3
+       / \
+      4   5  
+它将被序列化为 {1,2,3,#,#,4,5}
+```
+ ### 参考代码
+ Given a binary tree, find its minimum depth.
+
+The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
+
+考点：
+* 二叉树遍历
+* 搜索
+
+
+题解：直接搜索给出的二叉树即可。
+```java
+public class Solution {
+    public int minDepth(TreeNode root) {
+        if (root == null) {
+            return 0;
+        }
+        return getMin(root);
+    }
+
+    public int getMin(TreeNode root){
+        if (root == null) {
+            return Integer.MAX_VALUE;
+        }
+
+        if (root.left == null && root.right == null) {
+            return 1;
+        }
+
+        return Math.min(getMin(root.left), getMin(root.right)) + 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/minimum-subarray.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/minimum-subarray.md"
new file mode 100644
index 0000000..3748850
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/minimum-subarray.md"
@@ -0,0 +1,43 @@
+# 最小子数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-subarray/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个整数数组，找到一个具有最小和的连续子数组。返回其最小和。</p>
+ ### 样例说明
+ **样例 1**
+```
+输入：[1, -1, -2, 1]
+输出：-3
+```
+**样例 2**
+```
+输入：[1, -1, -2, 1, -4]
+输出：-6
+```
+ ### 参考代码
+ 定义两位数组
+第一个比较大小确定当前位置的元素能否为sunArray的起点
+第二个记录前 i 个元素能构成sunArray的最小和
+```java
+public class Solution {
+    /*
+     * @param nums: a list of integers
+     * @return: A integer indicate the sum of minimum subarray
+     */
+    public int minSubArray(List<Integer> nums) {
+        // write your code here
+        if (nums == null || nums.size() == 0) {
+            return 0;
+        }
+        int n = nums.size();
+        int []localMin = new int[n]; 
+        int []golbalMin = new int[n];
+        localMin[0] = golbalMin[0] = nums.get(0);
+        for(int i = 1; i < n; i++){
+            localMin[i] = Math.min(localMin[i - 1] + nums.get(i), nums.get(i)); //比较判断是否从一个新的元素开始找SubArray
+            golbalMin[i] = Math.min(golbalMin[i - 1], localMin[i]);// 前 i 位元素可以构成的最小subArray之和
+        }
+        return golbalMin[n - 1];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/minimum-subtree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/minimum-subtree.md"
new file mode 100644
index 0000000..dc2e710
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/minimum-subtree.md"
@@ -0,0 +1,105 @@
+# 最小子树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-subtree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树, 找到和为最小的子树, 返回其根节点。输入输出数据范围都在int内。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+{1,-5,2,1,2,-4,-5}
+输出:1
+说明
+这棵树如下所示：
+     1
+   /   \
+ -5     2
+ / \   /  \
+1   2 -4  -5 
+整颗树的和是最小的，所以返回根节点1.
+```
+
+**样例 2:**
+
+```
+输入:
+{1}
+输出:1
+说明:
+这棵树如下所示：
+   1
+这棵树只有整体这一个子树，所以返回1.
+```
+
+
+ ### 参考代码
+ 使用 Divide Conquer + Traverse 的方法。
+```
+[[python]]
+class Solution:
+    def findSubtree(self, root):
+        self.minimum_weight = float('inf')
+    	self.minimum_subtree_root = None
+        self.getTreeSum(root)
+
+        return self.minimum_subtree_root
+
+    # 得到 root 为根的二叉树的所有节点之和
+    # 顺便打个擂台求出 minimum subtree
+    def getTreeSum(self, root):
+        if root is None:
+            return 0
+
+        left_weight = self.getTreeSum(root.left)
+        right_weight = self.getTreeSum(root.right)
+        root_weight = left_weight + right_weight + root.val
+        
+        if root_weight < self.minimum_weight:
+            self.minimum_weight = root_weight
+            self.minimum_subtree_root = root
+
+        return root_weight
+[[java]]
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+
+public class Solution {
+    private int minSum;
+    private TreeNode minRoot;
+    
+    /**
+     * @param root: the root of binary tree
+     * @return: the root of the minimum subtree
+     */
+    public TreeNode findSubtree(TreeNode root) {
+        minSum = Integer.MAX_VALUE;
+        minRoot = null;
+        getSum(root);
+        return minRoot;
+    }
+    
+    private int getSum(TreeNode root) {
+        if (root == null) {
+            return 0;
+        }
+        
+        int sum = getSum(root.left) + getSum(root.right) + root.val;
+        if (sum < minSum) {
+            minSum = sum;
+            minRoot = root;
+        }
+        
+        return sum;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/n-queens-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/n-queens-ii.md"
new file mode 100644
index 0000000..d185cfc
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/n-queens-ii.md"
@@ -0,0 +1,71 @@
+# N皇后问题 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/n-queens-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>根据n皇后问题，现在返回n皇后不同的解决方案的数量而不是具体的放置布局。</p>
+ ### 样例说明
+ 例1:
+```
+输入: n=1
+输出: 1
+解释:
+1:
+1
+```
+
+例2:
+```
+输入: n=4
+输出: 2
+解释:
+1:
+0 0 1 0
+1 0 0 0
+0 0 0 1
+0 1 0 0
+2:
+0 1 0 0 
+0 0 0 1
+1 0 0 0
+0 0 1 0
+```
+
+ ### 参考代码
+ dfs暴力搜索即可
+```java
+public class Solution {
+    public static int sum;
+    public int totalNQueens(int n) {
+        sum = 0;
+        int[] usedColumns = new int[n];
+        placeQueen(usedColumns, 0);
+        return sum;
+    }
+    public void placeQueen(int[] usedColumns, int row) {
+        int n = usedColumns.length;
+        
+        if (row == n) {
+            sum ++;
+            return;
+        }
+        
+        for (int i = 0; i < n; i++) {
+            if (isValid(usedColumns, row, i)) {
+                usedColumns[row] = i;
+                placeQueen(usedColumns, row + 1);
+            }
+        }
+    }
+    public boolean isValid(int[] usedColumns, int row, int col) {
+        for (int i = 0; i < row; i++) {
+            if (usedColumns[i] == col) {
+                return false;
+            }
+            if ((row - i) == Math.abs(col-usedColumns[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/n-queens.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/n-queens.md"
new file mode 100644
index 0000000..7e5056d
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/n-queens.md"
@@ -0,0 +1,108 @@
+# N皇后问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/n-queens/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">n皇后问题是将n个皇后放置在n*n的棋盘上，皇后彼此之间不能相互攻击(任意两个皇后不能位于同一行，同一列，同一斜线)。</span><br></p><p>给定一个整数n，返回所有不同的n皇后问题的解决方案。</p><p>每个解决方案包含一个明确的n皇后放置布局，其中“Q”和“.”分别表示一个女王和一个空位置。</p>
+ ### 样例说明
+ 
+例1:
+```
+输入:1
+输出:
+   [["Q"]]
+
+
+```
+
+例2:
+```
+输入:4
+输出:
+[
+  // Solution 1
+  [".Q..",
+   "...Q",
+   "Q...",
+   "..Q."
+  ],
+  // Solution 2
+  ["..Q.",
+   "Q...",
+   "...Q",
+   ".Q.."
+  ]
+]
+
+```
+
+ ### 参考代码
+ 暴力搜索，尝试可以放置的地点，返回每个方案即可
+```java
+class Solution {
+    /**
+     * Get all distinct N-Queen solutions
+     * @param n: The number of queens
+     * @return: All distinct solutions
+     * For example, A string '...Q' shows a queen on forth position
+     */
+    List<List<String>> solveNQueens(int n) {
+        List<List<String>> results = new ArrayList<>();
+        if (n <= 0) {
+            return results;
+        }
+        
+        search(results, new ArrayList<Integer>(), n);
+        return results;
+    }
+    
+    /*
+     * results store all of the chessboards
+     * cols store the column indices for each row
+     */
+    private void search(List<List<String>> results,
+                        List<Integer> cols,
+                        int n) {
+        if (cols.size() == n) {
+            results.add(drawChessboard(cols));
+            return;
+        }
+        
+        for (int colIndex = 0; colIndex < n; colIndex++) {
+            if (!isValid(cols, colIndex)) {
+                continue;
+            }
+            cols.add(colIndex);
+            search(results, cols, n);
+            cols.remove(cols.size() - 1);
+        }
+    }
+    
+    private List<String> drawChessboard(List<Integer> cols) {
+        List<String> chessboard = new ArrayList<>();
+        for (int i = 0; i < cols.size(); i++) {
+            StringBuilder sb = new StringBuilder();
+            for (int j = 0; j < cols.size(); j++) {
+                sb.append(j == cols.get(i) ? 'Q' : '.');
+            }
+            chessboard.add(sb.toString());
+        }
+        return chessboard;
+    }
+    
+    private boolean isValid(List<Integer> cols, int column) {
+        int row = cols.size();
+        for (int rowIndex = 0; rowIndex < cols.size(); rowIndex++) {
+            if (cols.get(rowIndex) == column) {
+                return false;
+            }
+            if (rowIndex + cols.get(rowIndex) == row + column) {
+                return false;
+            }
+            if (rowIndex - cols.get(rowIndex) == row - column) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/nested-list-weight-sum.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/nested-list-weight-sum.md"
new file mode 100644
index 0000000..203763c
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/nested-list-weight-sum.md"
@@ -0,0 +1,120 @@
+# 嵌套列表的加权和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/nested-list-weight-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个嵌套的整数列表, 返回列表中所有整数由它们的深度加权后的总和. 每一个元素可能是一个整数或一个列表(其元素也可能是整数或列表)
+ ### 样例说明
+ 例1:
+```
+输入: the list [[1,1],2,[1,1]], 
+输出: 10. 
+解释:
+four 1's at depth 2, one 2 at depth 1, 4 * 1 * 2 + 1 * 2 * 1 = 10
+```
+例2:
+```
+输入: the list [1,[4,[6]]], 
+输出: 27. 
+解释:
+one 1 at depth 1, one 4 at depth 2, and one 6 at depth 3; 1 + 4 * 2 + 6 * 3 = 27
+```
+
+ ### 参考代码
+ dfs按照深度带权求和
+```java
+// 递归
+/**
+ * // This is the interface that allows for creating nested lists.
+ * // You should not implement it, or speculate about its implementation
+ * public interface NestedInteger {
+ *
+ *     // @return true if this NestedInteger holds a single integer,
+ *     // rather than a nested list.
+ *     public boolean isInteger();
+ *
+ *     // @return the single integer that this NestedInteger holds,
+ *     // if it holds a single integer
+ *     // Return null if this NestedInteger holds a nested list
+ *     public Integer getInteger();
+ *
+ *     // @return the nested list that this NestedInteger holds,
+ *     // if it holds a nested list
+ *     // Return null if this NestedInteger holds a single integer
+ *     public List<NestedInteger> getList();
+ * }
+ */
+public class Solution {
+    
+    public int depthSum(List<NestedInteger> nestedList) {
+        return helper(nestedList, 1);
+    }
+ 
+    public int helper(List<NestedInteger> nestedList, int depth){
+        if (nestedList == null || nestedList.size() == 0)
+            return 0;
+
+        int sum = 0;
+        for(NestedInteger ele : nestedList) {
+            if (ele.isInteger()) {
+                sum += ele.getInteger() * depth;
+            } else {
+                sum += helper(ele.getList(), depth + 1);
+            }
+        }
+ 
+        return sum;
+    }
+}
+
+// 非递归
+/**
+ * // This is the interface that allows for creating nested lists.
+ * // You should not implement it, or speculate about its implementation
+ * public interface NestedInteger {
+ *
+ *     // @return true if this NestedInteger holds a single integer,
+ *     // rather than a nested list.
+ *     public boolean isInteger();
+ *
+ *     // @return the single integer that this NestedInteger holds,
+ *     // if it holds a single integer
+ *     // Return null if this NestedInteger holds a nested list
+ *     public Integer getInteger();
+ *
+ *     // @return the nested list that this NestedInteger holds,
+ *     // if it holds a nested list
+ *     // Return null if this NestedInteger holds a single integer
+ *     public List<NestedInteger> getList();
+ * }
+ */
+public class Solution {
+    public int depthSum(List<NestedInteger> nestedList) {
+        // Write your code here
+        if (nestedList == null || nestedList.size() == 0) {
+            return 0;
+        }
+        int sum = 0;
+        Queue<NestedInteger> queue = new LinkedList<NestedInteger>();
+        for (NestedInteger nestedInt : nestedList) {
+            queue.offer(nestedInt);
+        }
+
+        int depth = 0;
+        while (!queue.isEmpty()) {
+            int size = queue.size();
+            depth++;
+            for (int i = 0; i < size; i++) {
+                NestedInteger nestedInt = queue.poll();
+                if (nestedInt.isInteger()) {
+                    sum += nestedInt.getInteger() * depth;
+                } else {
+                    for (NestedInteger innerInt : nestedInt.getList()) {
+                        queue.offer(innerInt);
+                    }
+                }
+            }
+        }
+        return sum;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/next-permutation-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/next-permutation-ii.md"
new file mode 100644
index 0000000..260f50e
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/next-permutation-ii.md"
@@ -0,0 +1,108 @@
+# 下一个排列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/next-permutation-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个若干整数的排列，给出按正数大小进行字典序从小到大排序后的下一个排列。
+
+如果没有下一个排列，则输出字典序最小的序列。
+ ### 样例说明
+ **样例 1:**
+```
+输入:1,2,3
+输出:1,3,2
+```
+
+**样例 2:**
+```
+输入:3,2,1
+输出:1,2,3
+```
+
+**样例 3:**
+```
+输入:1,1,5
+输出:1,5,1
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param num: an array of integers
+     * @return: return nothing (void), do not return anything, modify num in-place instead
+     */
+     
+    public void reverse(int[] num, int start, int end) {
+        for (int i = start, j = end; i < j; i++, j--) {
+            int temp = num[i];
+            num[i] = num[j];
+            num[j] = temp;
+        }
+    }
+    
+    public void nextPermutation(int[] num) {
+        // find the last increase index
+        int index = -1;
+        for (int i = num.length - 2; i >= 0; i--) {
+            if (num[i] < num[i + 1]) {
+                index = i;
+                break;
+            }
+        }
+        if (index == -1) {
+            reverse(num, 0, num.length - 1);
+            return;
+        }
+        
+        // find the first bigger one
+        int biggerIndex = index + 1;
+        for (int i = num.length - 1; i > index; i--) {
+            if (num[i] > num[index]) {
+                biggerIndex = i;
+                break;
+            }
+        }
+
+        // swap them to make the permutation bigger
+        int temp = num[index];
+        num[index] = num[biggerIndex];
+        num[biggerIndex] = temp;
+        
+        // reverse the last part
+        reverse(num, index + 1, num.length - 1);
+    }
+}
+
+// 写法二：
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @return: A list of integers that's next permuation
+     */
+    public void swapItem(int[] nums, int i, int j) {
+    	int temp = nums[i];
+		nums[i] = nums[j];
+		nums[j] = temp;
+	}
+	public void swapList(int[] nums, int i, int j) {
+		while (i < j) {
+			swapItem(nums, i, j);
+			i ++; j --;
+		}
+	}
+    public void nextPermutation(int[] nums) {
+		int len = nums.length;
+		if ( len <= 1)
+			return;
+		int i = len - 1;
+		while (i > 0 && nums[i] <= nums[i - 1]) {
+			i --;
+		}
+		if (i != 0) {
+			int j = len - 1;
+			while (nums[j] <= nums[i - 1]) j--;
+			swapItem(nums, j, i-1);
+		}
+		swapList(nums, i, len - 1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/next-permutation.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/next-permutation.md"
new file mode 100644
index 0000000..6e65810
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/next-permutation.md"
@@ -0,0 +1,49 @@
+# 下一个排列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/next-permutation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组来表示排列，找出其之后的一个排列。
+ ### 样例说明
+ 例1:
+```
+输入:[1]
+输出:[1]
+```
+
+
+例2:
+```
+输入:[1,3,2,3]
+输出:[1,3,3,2]
+```
+
+例3:
+```
+输入:[4,3,2,1]
+输出:[1,2,3,4]
+```
+
+ ### 参考代码
+ 从最后一个位置开始，找到一个上升点，上升点之前的无需改动。
+然后，翻转上升点之后的降序。
+在降序里，找到第一个比上升点大的，交换位置。
+```python
+class Solution:
+    # @param num :  a list of integer
+    # @return : a list of integer
+    def nextPermutation(self, num):
+        # write your code here
+        for i in range(len(num)-2, -1, -1):
+            if num[i] < num[i+1]:
+                break
+        else:
+            num.reverse()
+            return num
+        for j in range(len(num)-1, i, -1):
+            if num[j] > num[i]:
+                num[i], num[j] = num[j], num[i]
+                break
+        for j in range(0, (len(num) - i)//2):
+            num[i+j+1], num[len(num)-j-1] = num[len(num)-j-1], num[i+j+1]
+        return num
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/number-of-islands.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/number-of-islands.md"
new file mode 100644
index 0000000..e624bdf
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/number-of-islands.md"
@@ -0,0 +1,299 @@
+# 岛屿的个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/number-of-islands/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个 01 矩阵，求不同的岛屿的个数。
+
+0 代表海，1 代表岛，如果两个 1 相邻，那么这两个 1 属于同一个岛。我们只考虑上下左右为相邻。
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入：
+[
+  [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]
+]
+输出：
+3
+```
+**样例 2：**
+```
+输入：
+[
+  [1,1]
+]
+输出：
+1
+```
+ ### 参考代码
+ 用九章算法班中讲到的 BFS 模板。
+```
+[[python]]
+from collections import deque
+
+DIRECTIONS = [(1, 0), (0, -1), (-1, 0), (0, 1)]
+
+class Solution:
+    """
+    @param grid: a boolean 2D matrix
+    @return: an integer
+    """
+    def numIslands(self, grid):
+        if not grid or not grid[0]:
+            return 0
+            
+        islands = 0
+        visited = set()
+        for i in range(len(grid)):
+            for j in range(len(grid[0])):
+                if grid[i][j] and (i, j) not in visited:
+                    self.bfs(grid, i, j, visited)
+                    islands += 1
+                    
+        return islands                    
+    
+    def bfs(self, grid, x, y, visited):
+        queue = deque([(x, y)])
+        visited.add((x, y))
+        while queue:
+            x, y = queue.popleft()
+            for delta_x, delta_y in DIRECTIONS:
+                next_x = x + delta_x
+                next_y = y + delta_y
+                if not self.is_valid(grid, next_x, next_y, visited):
+                    continue
+                queue.append((next_x, next_y))
+                visited.add((next_x, next_y))
+
+    def is_valid(self, grid, x, y, visited):
+        n, m = len(grid), len(grid[0])
+        if not (0 <= x < n and 0 <= y < m):
+            return False
+        if (x, y) in visited:
+            return False
+        return grid[x][y]
+
+# LeetCode 的用户请用下面的代码，因为 LeetCode 上的输入是 2D string array 而不是 boolean array
+# from collections import deque
+
+# class Solution:
+#     """
+#     @param grid: a boolean 2D matrix
+#     @return: an integer
+#     """
+#     def numIslands(self, grid):
+#         if not grid or not grid[0]:
+#             return 0
+        
+#         islands = 0
+#         for i in range(len(grid)):
+#             for j in range(len(grid[0])):
+#                 if grid[i][j] == '1':
+#                     self.bfs(grid, i, j)
+#                     islands += 1
+                    
+#         return islands                    
+    
+#     def bfs(self, grid, x, y):
+#         queue = deque([(x, y)])
+#         grid[x][y] = '0'
+#         while queue:
+#             x, y = queue.popleft()
+#             for delta_x, delta_y in [(1, 0), (0, -1), (-1, 0), (0, 1)]:
+#                 next_x = x + delta_x
+#                 next_y = y + delta_y
+#                 if not self.is_valid(grid, next_x, next_y):
+#                     continue
+#                 queue.append((next_x, next_y))
+#                 grid[next_x][next_y] = '0'
+                
+#     def is_valid(self, grid, x, y):
+#         n, m = len(grid), len(grid[0])
+#         return 0 <= x < n and 0 <= y < m and grid[x][y] == '1'
+[[java]]
+class Coordinate {
+    int x, y;
+    public Coordinate(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+}
+
+public class Solution {
+    /**
+     * @param grid a boolean 2D matrix
+     * @return an integer
+     */
+    int[] deltaX = {0, 1, -1, 0};
+    int[] deltaY = {1, 0, 0, -1};
+    public int numIslands(boolean[][] grid) {
+        if (grid == null || grid.length == 0) {
+            return 0;
+        }
+        if (grid[0] == null || grid[0].length == 0) {
+            return 0;
+        }
+        
+        int islands = 0;
+        int n = grid.length, m = grid[0].length;
+        boolean[][] visited = new boolean[n][m];
+        
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < m; j++) {
+                if (grid[i][j] && !visited[i][j]) {
+                    bfs(grid, i, j, visited);
+                    islands++;
+                }
+            }
+        }
+        
+        return islands;
+    }
+    
+    private void bfs(boolean[][] grid, int x, int y, boolean[][] visited) {
+        Queue<Coordinate> queue = new ArrayDeque<>();
+        queue.offer(new Coordinate(x, y));
+        visited[x][y] = true;
+        
+        while (!queue.isEmpty()) {
+            Coordinate coor = queue.poll();
+            for (int direction = 0; direction < 4; direction++) {
+                int newX = coor.x + deltaX[direction];
+                int newY = coor.y + deltaY[direction];
+                if (!isVaild(grid, newX, newY, visited)) {
+                    continue;
+                }
+                queue.offer(new Coordinate(newX, newY));
+                visited[newX][newY] = true;
+            }
+        }
+    }
+    
+    private boolean isVaild(boolean[][] grid, int x, int y, boolean[][] visited) {
+        int n = grid.length, m = grid[0].length;
+        if (x < 0 || x >= n || y < 0 || y >= m) {
+            return false;
+        }
+        if (visited[x][y]) {
+            return false;
+        }
+        return grid[x][y];
+    }
+}
+```
+
+也可以使用 DFS 的方法进行搜索。
+DFS 分为两类：
+
+1. 找所有路径的
+2. 找所有节点的
+
+第一类一般需要回溯，也就是把一个东西标记为使用过以后要把他标记回来。这样才能找到所有的路径。
+第二类不需要回溯，因为只需要把所有连通的节点都标记一下即可。
+
+DFS 来做这道题目虽然可以在 LintCode / LeetCode 等题库拿到 AC，但是在面试中并不推荐，因为 DFS 的深度可能会比较深，容易导致 StackOverflow。
+
+```
+[[python]]
+class Solution:
+    """
+    @param grid: a boolean 2D matrix
+    @return: an integer
+    """
+    def numIslands(self, grid):
+        if not grid or not grid[0]:
+            return 0
+        
+        n, m = len(grid), len(grid[0])
+        visited = [[False] * m for _ in range(n)]
+        
+        islands = 0
+        for row in range(n):
+            for col in range(m):
+                if self.is_island(grid, row, col, visited):
+                    visited[row][col] = True
+                    self.dfs(grid, row, col, visited)
+                    islands += 1
+                    
+        return islands
+        
+    def is_island(self, grid, x, y, visited):
+        n, m = len(grid), len(grid[0])
+        if not (0 <= x < n and 0 <= y < m):
+            return False
+        if not grid[x][y]:
+            return False
+        return not visited[x][y]
+
+    def dfs(self, grid, x, y, visited):
+        dx = [1, 0, -1, 0]
+        dy = [0, 1, 0, -1]
+        for direction in range(4):
+            newx = x + dx[direction]
+            newy = y + dy[direction]
+            
+            if self.is_island(grid, newx, newy, visited):
+                visited[newx][newy] = True
+                self.dfs(grid, newx, newy, visited)
+                # no backtracking
+[[java]]
+public class Solution {
+    /**
+     * @param grid: a boolean 2D matrix
+     * @return: an integer
+     */
+    public int numIslands(boolean[][] grid) {
+        if (grid == null || grid.length == 0) {
+            return 0;
+        }
+        if (grid[0] == null || grid[0].length == 0) {
+            return 0;
+        }
+        
+        int n = grid.length, m = grid[0].length;
+        boolean[][] visited = new boolean[n][m];
+        
+        int islands = 0;
+        for (int row = 0; row < n; row++) {
+            for (int col = 0; col < m; col++) {
+                if (isIsland(grid, row, col, visited)) {
+                    visited[row][col] = true;
+                    dfs(grid, row, col, visited);
+                    islands++;
+                }
+            }
+        }
+        return islands;
+    }
+    
+    private boolean isIsland(boolean[][] grid, int x, int y, boolean[][] visited) {
+        int n = grid.length, m = grid[0].length;
+        if (x < 0 || x >= n || y < 0 || y >= m) {
+            return false;
+        }
+        if (!grid[x][y]) {
+            return false;
+        }
+        return !visited[x][y];
+    }
+    
+    private void dfs(boolean[][] grid, int x, int y, boolean[][] visited) {
+        int[] dx = new int[]{1, 0, -1, 0};
+        int[] dy = new int[]{0, 1, 0, -1};
+        for (int direction = 0; direction < 4; direction++) {
+            int newX = x + dx[direction];
+            int newY = y + dy[direction];
+            
+            if (isIsland(grid, newX, newY, visited)) {
+                visited[newX][newY] = true;
+                dfs(grid, newX, newY, visited);
+            }
+        }
+        // no backtracking
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/palindrome-partitioning.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/palindrome-partitioning.md"
new file mode 100644
index 0000000..44afc80
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/palindrome-partitioning.md"
@@ -0,0 +1,148 @@
+# 分割回文串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/palindrome-partitioning/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定字符串 `s`, 需要将它分割成一些子串, 使得每个子串都是回文串.
+
+返回所有可能的分割方案.
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "a"
+输出: [["a"]]
+解释: 字符串里只有一个字符, 也就只有一种分割方式 (就是它本身)
+```
+
+**样例 2:**
+
+```
+输入: "aab"
+输出: [["aa", "b"], ["a", "a", "b"]]
+解释: 有两种分割的方式.
+    1. 将 "aab" 分割成 "aa" 和 "b", 它们都是回文的.
+    2. 将 "aab" 分割成 "a", "a" 和 "b", 它们全都是回文的.
+```
+ ### 参考代码
+ 使用回溯法枚举所有可能的分割方案即可.
+
+关于判断回文串, 最简单的可以写一个函数, 遍历一次字符串即可. 但是这样效率不高, 可以先预处理一下, 可以使用动态规划或者Manacher算法.
+```java
+// version 1: shorter but slower
+public class Solution {
+    /**
+     * @param s: A string
+     * @return: A list of lists of string
+     */
+    public List<List<String>> partition(String s) {
+        List<List<String>> results = new ArrayList<>();
+        if (s == null || s.length() == 0) {
+            return results;
+        }
+        
+        List<String> partition = new ArrayList<String>();
+        helper(s, 0, partition, results);
+        
+        return results;
+    }
+    
+    private void helper(String s,
+                        int startIndex,
+                        List<String> partition,
+                        List<List<String>> results) {
+        if (startIndex == s.length()) {
+            results.add(new ArrayList<String>(partition));
+            return;
+        }
+        
+        for (int i = startIndex; i < s.length(); i++) {
+            String subString = s.substring(startIndex, i + 1);
+            if (!isPalindrome(subString)) {
+                continue;
+            }
+            partition.add(subString);
+            helper(s, i + 1, partition, results);
+            partition.remove(partition.size() - 1);
+        }
+    }
+    
+    private boolean isPalindrome(String s) {
+        for (int i = 0, j = s.length() - 1; i < j; i++, j--) {
+            if (s.charAt(i) != s.charAt(j)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+
+// version 2: longer but faster
+public class Solution {
+    List<List<String>> results;
+    boolean[][] isPalindrome;
+    
+    /**
+     * @param s: A string
+     * @return: A list of lists of string
+     */
+    public List<List<String>> partition(String s) {
+        results = new ArrayList<>();
+        if (s == null || s.length() == 0) {
+            return results;
+        }
+        
+        getIsPalindrome(s);
+        
+        helper(s, 0, new ArrayList<Integer>());
+        
+        return results;
+    }
+    
+    private void getIsPalindrome(String s) {
+        int n = s.length();
+        isPalindrome = new boolean[n][n];
+        
+        for (int i = 0; i < n; i++) {
+            isPalindrome[i][i] = true;
+        }
+        for (int i = 0; i < n - 1; i++) {
+            isPalindrome[i][i + 1] = (s.charAt(i) == s.charAt(i + 1));
+        }
+        
+        for (int i = n - 3; i >= 0; i--) {
+            for (int j = i + 2; j < n; j++) {
+                isPalindrome[i][j] = isPalindrome[i + 1][j - 1] && s.charAt(i) == s.charAt(j);
+            }
+        }
+    }
+    
+    private void helper(String s,
+                        int startIndex,
+                        List<Integer> partition) {
+        if (startIndex == s.length()) {
+            addResult(s, partition);
+            return;
+        }
+        
+        for (int i = startIndex; i < s.length(); i++) {
+            if (!isPalindrome[startIndex][i]) {
+                continue;
+            }
+            partition.add(i);
+            helper(s, i + 1, partition);
+            partition.remove(partition.size() - 1);
+        }
+    }
+    
+    private void addResult(String s, List<Integer> partition) {
+        List<String> result = new ArrayList<>();
+        int startIndex = 0;
+        for (int i = 0; i < partition.size(); i++) {
+            result.add(s.substring(startIndex, partition.get(i) + 1));
+            startIndex = partition.get(i) + 1;
+        }
+        results.add(result);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/pascals-triangle.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/pascals-triangle.md"
new file mode 100644
index 0000000..83b5471
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/pascals-triangle.md"
@@ -0,0 +1,76 @@
+# 杨辉三角
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/pascals-triangle/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个非负整数 *numRows，*生成杨辉三角的前 *numRows* 行。
+
+![图片](https://media-cdn.jiuzhang.com/markdown/images/7/6/60e49d2e-9ffa-11e9-a15b-0242ac110002.jpg)
+
+在杨辉三角中，每个数是它左上方和右上方的数的和。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 5
+输出:
+[
+     [1],
+    [1,1],
+   [1,2,1],
+  [1,3,3,1],
+ [1,4,6,4,1]
+]
+```
+
+**样例 2:**
+
+```
+输入: 3
+输出:
+[
+     [1],
+    [1,1],
+   [1,2,1]
+]
+```
+
+
+ ### 参考代码
+ ```java
+class Solution {
+    public List<List<Integer>> generate(int numRows) {
+        List<List<Integer>> triangle = new ArrayList<List<Integer>>();
+
+        // First base case; if user requests zero rows, they get zero rows.
+        if (numRows == 0) {
+            return triangle;
+        }
+
+        // Second base case; first row is always [1].
+        triangle.add(new ArrayList<>());
+        triangle.get(0).add(1);
+
+        for (int rowNum = 1; rowNum < numRows; rowNum++) {
+            List<Integer> row = new ArrayList<>();
+            List<Integer> prevRow = triangle.get(rowNum-1);
+
+            // The first row element is always 1.
+            row.add(1);
+
+            // Each triangle element (other than the first and last of each row)
+            // is equal to the sum of the elements above-and-to-the-left and
+            // above-and-to-the-right.
+            for (int j = 1; j < rowNum; j++) {
+                row.add(prevRow.get(j-1) + prevRow.get(j));
+            }
+
+            // The last row element is always 1.
+            row.add(1);
+
+            triangle.add(row);
+        }
+
+        return triangle;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/path-sum-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/path-sum-ii.md"
new file mode 100644
index 0000000..1f6853c
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/path-sum-ii.md"
@@ -0,0 +1,89 @@
+# 路径总和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/path-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树和一个目标和，找到所有从根节点到叶子节点路径总和等于给定目标和的路径。
+
+ ### 样例说明
+ **样例 1:**
+```
+输入: root = {5,4,8,11,#,13,4,7,2,#,#,5,1}, sum = 22
+              5
+             / \
+            4   8
+           /   / \
+          11  13  4
+         /  \    / \
+        7    2  5   1
+输出: [[5,4,11,2],[5,8,4,5]]
+解释:
+两条路径之和为 22：
+5 + 4 + 11 + 2 = 22
+5 + 8 + 4 + 5 = 22
+```
+**样例 2:**
+```
+输入: root = {10,6,7,5,2,1,8,#,9}, sum = 18
+              10
+             /  \
+            6    7
+          /  \   / \
+          5  2   1  8
+           \ 
+            9 
+输出: [[10,6,2],[10,7,1]]
+解释:
+两条路径之和为 18：
+10 + 6 + 2 = 18
+10 + 7 + 1 = 18
+```
+ ### 参考代码
+ Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.
+
+For example:
+Given the below binary tree and sum = 22,
+              5
+             / \
+            4   8
+           /   / \
+          11  13  4
+         /  \    / \
+        7    2  5   1
+return
+[
+   [5,4,11,2],
+   [5,8,4,5]
+]
+```java
+public class Solution {
+    public ArrayList<ArrayList<Integer>> pathSum(TreeNode root, int sum) {
+        ArrayList<ArrayList<Integer>> rst = new ArrayList<ArrayList<Integer>>();
+        ArrayList<Integer> solution = new ArrayList<Integer>();
+
+        findSum(rst, solution, root, sum);
+        return rst;
+    }
+
+    private void findSum(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> solution, TreeNode root, int sum){
+        if (root == null) {
+            return;
+        }
+
+        sum -= root.val;
+
+        if (root.left == null && root.right == null) {
+            if (sum == 0){
+                solution.add(root.val);
+                result.add(new ArrayList<Integer>(solution));
+                solution.remove(solution.size()-1);
+            }
+            return;
+        }
+
+        solution.add(root.val);
+        findSum(result, solution, root.left, sum);
+        findSum(result, solution, root.right, sum);
+        solution.remove(solution.size()-1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/permutation-sequence.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/permutation-sequence.md"
new file mode 100644
index 0000000..6653542
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/permutation-sequence.md"
@@ -0,0 +1,64 @@
+# 第k个排列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/permutation-sequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定 *n* 和 *k*，求n的全排列中字典序第k个排列.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: n = 3, k = 4
+输出: "231"
+解释: 
+n = 3时, 全排列如下:
+"123", "132", "213", "231", "312", "321"
+```
+
+**样例 2:**
+
+```
+输入: n = 1, k = 1
+输出: "1"
+```
+ ### 参考代码
+ 康拓展开的应用, 模板题.
+
+康拓展开, 计算排列与字典序排名的映射关系.
+
+[维基百科 康拓展开](https://zh.wikipedia.org/wiki/%E5%BA%B7%E6%89%98%E5%B1%95%E5%BC%80)
+```java
+public class Solution {
+
+    public String getPermutation(int n, int k) {
+        StringBuilder sb = new StringBuilder();
+        boolean[] used = new boolean[n];
+
+        k = k - 1;
+        int factor = 1;
+        for (int i = 1; i < n; i++) {
+            factor *= i;
+        }
+
+        for (int i = 0; i < n; i++) {
+            int index = k / factor;
+            k = k % factor;
+            for (int j = 0; j < n; j++) {
+                if (used[j] == false) {
+                    if (index == 0) {
+                        used[j] = true;
+                        sb.append((char) ('0' + j + 1));
+                        break;
+                    } else {
+                        index--;
+                    }
+                }
+            }
+            if (i < n - 1) {
+                factor = factor / (n - 1 - i);
+            }
+        }
+
+        return sb.toString();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/permutations-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/permutations-ii.md"
new file mode 100644
index 0000000..addeca5
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/permutations-ii.md"
@@ -0,0 +1,75 @@
+# 带重复元素的排列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/permutations-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个具有重复数字的列表，找出列表所有**不同**的排列。
+ ### 样例说明
+ **样例 1：**
+```
+输入：[1,1]
+输出：
+[
+  [1,1]
+]
+```
+**样例 2：**
+```
+输入：[1,2,2]
+输出：
+[
+  [1,2,2],
+  [2,1,2],
+  [2,2,1]
+]
+```
+ ### 参考代码
+ 使用排列式深度优先搜索算法。
+
+和没有重复元素的 Permutation 一题相比，只加了两句话：
+
+1. Arrays.sort(nums)  // 排序这样所有重复的数
+2. if (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]) { continue; } // 跳过会造成重复的情况
+```java
+public class Solution {
+    /*
+     * @param :  A list of integers
+     * @return: A list of unique permutations
+     */
+    public List<List<Integer>> permuteUnique(int[] nums) {
+        List<List<Integer>> results = new ArrayList<>();
+        if (nums == null) {
+            return results;
+        }
+        
+        Arrays.sort(nums);
+        dfs(nums, new boolean[nums.length], new ArrayList<Integer>(), results);
+        
+        return results;
+    }
+    
+    private void dfs(int[] nums,
+                     boolean[] visited,
+                     List<Integer> permutation,
+                     List<List<Integer>> results) {
+        if (nums.length == permutation.size()) {
+            results.add(new ArrayList<Integer>(permutation));
+            return;
+        }
+        
+        for (int i = 0; i < nums.length; i++) {
+            if (visited[i]) {
+                continue;
+            }
+            if (i > 0 && nums[i] == nums[i - 1] && !visited[i - 1]) {
+                continue;
+            }
+            
+            permutation.add(nums[i]);
+            visited[i] = true;
+            dfs(nums, visited, permutation, results);
+            visited[i] = false;
+            permutation.remove(permutation.size() - 1);
+        }
+    }
+ };
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/permutations.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/permutations.md"
new file mode 100644
index 0000000..c6c757e
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/permutations.md"
@@ -0,0 +1,98 @@
+# 全排列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/permutations/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数字列表，返回其所有可能的排列。
+ ### 样例说明
+ **样例 1：**
+```
+输入：[1]
+输出：
+[
+  [1]
+]
+```
+**样例 2：**
+```
+输入：[1,2,3]
+输出：
+[
+  [1,2,3],
+  [1,3,2],
+  [2,1,3],
+  [2,3,1],
+  [3,1,2],
+  [3,2,1]
+]
+```
+ ### 参考代码
+ 使用深度优先搜索算法。
+使用 visited 数组记录某个数是否被放到 permutation 里了。
+```
+[[java]]
+public class Solution {
+    /*
+     * @param nums: A list of integers.
+     * @return: A list of permutations.
+     */
+    public List<List<Integer>> permute(int[] nums) {
+        List<List<Integer>> results = new ArrayList<>();
+        if (nums == null) {
+            return results;
+        }
+        
+        dfs(nums, new boolean[nums.length], new ArrayList<Integer>(), results);
+        
+        return results;
+    }
+    
+    private void dfs(int[] nums,
+                     boolean[] visited,
+                     List<Integer> permutation,
+                     List<List<Integer>> results) {
+        if (nums.length == permutation.size()) {
+            results.add(new ArrayList<Integer>(permutation));
+            return;
+        }
+        
+        for (int i = 0; i < nums.length; i++) {
+            if (visited[i]) {
+                continue;
+            }
+            
+            permutation.add(nums[i]);
+            visited[i] = true;
+            dfs(nums, visited, permutation, results);
+            visited[i] = false;
+            permutation.remove(permutation.size() - 1);
+        }
+    }
+}
+[[python]]
+class Solution:
+    """
+    @param: nums: A list of integers.
+    @return: A list of permutations.
+    """
+    def permute(self, nums):
+        if not nums:
+            return [[]]
+            
+        permutations = []
+        self.dfs(nums, [], set(), permutations)
+        return permutations
+        
+    def dfs(self, nums, permutation, visited, permutations):
+        if len(nums) == len(permutation):
+            permutations.append(list(permutation))
+            return
+        
+        for num in nums:
+            if num in visited:
+                continue
+            permutation.append(num)
+            visited.add(num)
+            self.dfs(nums, permutation, visited, permutations)
+            visited.remove(num)
+            permutation.pop()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/populating-next-right-pointers-in-each-node-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/populating-next-right-pointers-in-each-node-ii.md"
new file mode 100644
index 0000000..91220cd
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/populating-next-right-pointers-in-each-node-ii.md"
@@ -0,0 +1,55 @@
+# 填充每个结点的右结点指针II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/populating-next-right-pointers-in-each-node-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一棵二叉树：</p><pre>    struct TreeLinkNode {
+      TreeLinkNode *left;
+      TreeLinkNode *right;
+      TreeLinkNode *next;
+    }</pre><p>填充每个结点指向其同层右边下一个结点的指针next。如果右边没有下一个结点，则next指针指向NULL。</p><p>初始时，所有的next指针全部指向NULL。</p>
+ ### 样例说明
+ 
+ ### 参考代码
+ Follow up for problem "Populating Next Right Pointers in Each Node".&nbsp;<div>What if the given tree could be any binary tree? Would your previous solution still work?&nbsp;</div><div>Note:&nbsp;<span style="line-height: 1.42857143;">&nbsp;You may only use constant extra space.&nbsp;</span></div><div><span style="line-height: 1.42857143;"><br></span></div><div><span style="line-height: 1.42857143;">For example,&nbsp;</span></div><div><span style="line-height: 1.42857143;">Given the following binary tree,&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp; &nbsp; 1&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp; &nbsp;/  \&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp;2 &nbsp; 3&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; / \ &nbsp; &nbsp;\&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp;4 &nbsp;5 &nbsp; &nbsp;7&nbsp;</span></div><div><span style="line-height: 1.42857143;">After calling your function, the tree should look like:&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp; &nbsp; &nbsp; 1 -&gt; NULL</span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp; &nbsp; / &nbsp; &nbsp;\&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp; 2 &nbsp;-&gt; 3 -&gt; NULL&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; / &nbsp; &nbsp;\ &nbsp; &nbsp; &nbsp;\&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp;4-&gt; 5 -&gt; 7 -&gt; NULL</span></div><div><span style="line-height: 1.42857143;"><br></span></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博：</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/BsC0Q9jY7" target="_blank">http://weibo.com/3948019741/BsC0Q9jY7</a></span></font><span style="line-height: 1.42857143;"><br></span></div>
+```java
+public class Solution {
+    public void connect(TreeLinkNode root) {
+        if (root == null) {
+            return;
+        }
+
+        TreeLinkNode parent = root;
+        TreeLinkNode pre;
+        TreeLinkNode next;
+        while (parent != null) {
+            pre = null;
+            next = null;
+            while (parent != null) {
+                if (next == null){
+                    next = (parent.left != null) ? parent.left: parent.right;
+                }
+
+                if (parent.left != null){
+                    if (pre != null) {
+                        pre.next = parent.left;
+                        pre = pre.next;
+                    } else {
+                        pre = parent.left;
+                    }
+                }
+
+                if (parent.right != null) {
+                    if (pre != null) {
+                        pre.next = parent.right;
+                        pre = pre.next;
+                    } else {
+                        pre = parent.right;
+                    }
+                }
+                parent = parent.next;
+            }
+            parent = next;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/prime-factorization.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/prime-factorization.md"
new file mode 100644
index 0000000..ab8480b
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/prime-factorization.md"
@@ -0,0 +1,42 @@
+# 分解质因数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/prime-factorization/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一个整数分解为若干质因数之乘积。
+ ### 样例说明
+ **样例 1：**
+```
+输入：10
+输出：[2, 5]
+```
+**样例 2：**
+```
+输入：660
+输出：[2, 2, 3, 5, 11]
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param num an integer
+     * @return an integer array
+     */
+    public List<Integer> primeFactorization(int num) {
+        List<Integer> factors = new ArrayList<Integer>();
+
+        for (int i = 2; i * i <= num; i++) {
+            while (num % i == 0) {
+                num = num / i;
+                factors.add(i);
+            }
+        }
+        
+        if (num != 1) {
+            factors.add(num);
+        }
+        
+        return factors;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/reconstruct-itinerary.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/reconstruct-itinerary.md"
new file mode 100644
index 0000000..d5aac41
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/reconstruct-itinerary.md"
@@ -0,0 +1,44 @@
+# 重新安排行程
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reconstruct-itinerary/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个机票的字符串二维数组 [from, to]，子数组中的两个成员分别表示飞机出发和降落的机场地点，对该行程进行重新规划排序。所有这些机票都属于一个从JFK（肯尼迪国际机场）出发的先生，所以该行程必须从 JFK 出发。
+ ### 样例说明
+ **示例1**
+```
+输入： [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]]
+输出： ["JFK", "MUC", "LHR", "SFO", "SJC"].
+```
+**示例2**
+```
+输入：[["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]
+输出：["JFK","ATL","JFK","SFO","ATL","SFO"].
+解释：另一种有效的行程是 ["JFK","SFO","ATL","JFK","ATL","SFO"]。但是它自然排序更大更靠后。
+```
+ ### 参考代码
+ 使用优先队列存储从一个机场出发可以到达的所有机场，再进行DFS找出答案
+```java
+public class Solution {
+    public List<String> findItinerary(String[][] tickets) {
+        Map<String, PriorityQueue<String>> hashmap = new HashMap<String, PriorityQueue<String>>();
+        List<String> list = new ArrayList<String>();
+        String cur = "JFK";
+        int length = tickets.length;
+        for (int i = 0; i < length; i++) {
+            if (!hashmap.containsKey(tickets[i][0])) {
+                hashmap.put(tickets[i][0], new PriorityQueue<String>());
+            }
+            hashmap.get(tickets[i][0]).add(tickets[i][1]);
+        }
+        dfs(cur, hashmap, list);
+        Collections.reverse(list);
+        return list;
+    }
+    public void dfs(String cur, Map<String, PriorityQueue<String>> hashmap, List<String> list) {
+        while (hashmap.containsKey(cur) && !hashmap.get(cur).isEmpty()) {
+            dfs(hashmap.get(cur).poll(), hashmap, list);
+        }
+        list.add(cur);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/recover-binary-search-tree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/recover-binary-search-tree.md"
new file mode 100644
index 0000000..c9bc940
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/recover-binary-search-tree.md"
@@ -0,0 +1,90 @@
+# 恢复二叉搜索树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/recover-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一棵二叉搜索树中, 只有两个节点是被交换的. 找到这些节点并交换, 如果没有节点被交换就返回原来的树的根节点.
+ ### 样例说明
+ **样例1**
+
+```
+输入： {4,5,2,1,3}
+输出： {4,2,5,1,3}
+解释：
+给出的二叉搜索树：
+    4
+   / \
+  5   2
+ / \
+1   3
+返回：
+    4
+   / \
+  2   5
+ / \
+1   3
+```
+
+**样例2**
+
+```
+输入： {1,2,5,4,3}
+输出： {4,2,5,1,3}
+解释：
+给出的二叉搜索树：
+    1
+   / \
+  2   5
+ / \
+4   3
+返回：
+    4
+   / \
+  2   5
+ / \
+1   3
+```
+
+
+ ### 参考代码
+ Two elements of a binary search tree (BST) are swapped by mistake.&nbsp;<div>Recover the tree without changing its structure.&nbsp;</div><div><br></div><div>Note:&nbsp;</div><div>A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?<div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博：<a href="http://weibo.com/3948019741/BErgRBUCb" target="_blank">&nbsp;http://weibo.com/3948019741/BErgRBUCb</a></span><br></div></div>
+```java
+/**
+ * Definition for binary tree
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    private TreeNode firstElement = null;
+    private TreeNode secondElement = null;
+    private TreeNode lastElement = new TreeNode(Integer.MIN_VALUE); 
+    
+    private void traverse(TreeNode root) {
+        if (root == null) {
+            return;
+        }
+        traverse(root.left);
+        if (firstElement == null && root.val < lastElement.val) {
+            firstElement = lastElement;
+        }
+        if (firstElement != null && root.val < lastElement.val) {
+            secondElement = root;
+        }
+        lastElement = root;
+        traverse(root.right);
+    }
+    
+    public void recoverTree(TreeNode root) {
+        // traverse and get two elements
+        traverse(root);
+        // swap
+        int temp = firstElement.val;
+        firstElement.val = secondElement.val;
+        secondElement.val = temp;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/remove-node-in-binary-search-tree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/remove-node-in-binary-search-tree.md"
new file mode 100644
index 0000000..ee86872
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/remove-node-in-binary-search-tree.md"
@@ -0,0 +1,146 @@
+# 删除二叉查找树的节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-node-in-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一棵具有不同节点值的二叉查找树，删除树中与给定值相同的节点。如果树中没有相同值的节点，就不做任何处理。你应该保证处理之后的树仍是<span style="line-height: 1.42857143;">二叉查找树。</span></p>
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: 
+Tree = {5,3,6,2,4}
+k = 3
+输出: {5,2,6,#,4} 或 {5,4,6,2}
+说明:
+给定了以下二叉搜索树:
+    5
+   / \
+  3   6
+ / \
+2   4
+移去3，你可以返回:
+    5
+   / \
+  2   6
+   \
+    4
+或
+    5
+   / \
+  4   6
+ /
+2
+```
+
+**样例2**
+
+```plain
+输入: 
+Tree = {5,3,6,2,4}
+k = 4
+输出: {5,3,6,2}
+说明:
+给定了以下二叉搜索树:
+    5
+   / \
+  3   6
+ / \
+2   4
+移去4，你应该返回
+    5
+   / \
+  3   6
+ /
+2
+```
+
+
+ ### 参考代码
+ Remove Node in Binary Search Tree
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of the binary search tree.
+     * @param value: Remove the node with given value.
+     * @return: The root of the binary search tree after removal.
+     */
+    public TreeNode removeNode(TreeNode root, int value) {
+        TreeNode dummy = new TreeNode(0);
+        dummy.left = root;
+        
+        TreeNode parent = findNode(dummy, root, value);
+        TreeNode node;
+        if (parent.left != null && parent.left.val == value) {
+            node = parent.left;
+        } else if (parent.right != null && parent.right.val == value) {
+            node = parent.right;
+        } else {
+            return dummy.left;
+        }
+        
+        deleteNode(parent, node);
+        
+        return dummy.left;
+    }
+    
+    private TreeNode findNode(TreeNode parent, TreeNode node, int value) {
+        if (node == null) {
+            return parent;
+        }
+        
+        if (node.val == value) {
+            return parent;
+        }
+        if (value < node.val) {
+            return findNode(node, node.left, value);
+        } else {
+            return findNode(node, node.right, value);
+        }
+    }
+    
+    private void deleteNode(TreeNode parent, TreeNode node) {
+        if (node.right == null) {
+            if (parent.left == node) {
+                parent.left = node.left;
+            } else {
+                parent.right = node.left;
+            }
+        } else {
+            TreeNode temp = node.right;
+            TreeNode father = node;
+            
+            while (temp.left != null) {
+                father = temp;
+                temp = temp.left;
+            }
+            
+            if (father.left == temp) {
+                father.left = temp.right;
+            } else {
+                father.right = temp.right;
+            }
+            
+            if (parent.left == node) {
+                parent.left = temp;
+            } else {
+                parent.right = temp;
+            }
+            
+            temp.left = node.left;
+            temp.right = node.right;
+        }
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/string-permutation-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/string-permutation-ii.md"
new file mode 100644
index 0000000..fec7aad
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/string-permutation-ii.md"
@@ -0,0 +1,67 @@
+# 字符串的不同排列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/string-permutation-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个字符串，找到它的所有排列，注意同一个字符串不要打印两次。
+
+ ### 样例说明
+ **样例 1：**
+```
+输入："abb"
+输出：
+["abb", "bab", "bba"]
+```
+**样例 2：**
+```
+输入："aabb"
+输出：
+["aabb", "abab", "baba", "bbaa", "abba", "baab"]
+```
+ ### 参考代码
+ 用递归的办法
+```
+[[python]]
+class Solution:
+    """
+    @param str: A string
+    @return: all permutations
+    """
+    def stringPermutation2(self, str):
+        chars = sorted(list(str))
+        visited = [False] * len(chars)
+        permutations = []
+        self.dfs(chars, visited, [], permutations) 
+        return permutations
+
+    # 递归的定义: 找到所有 permutation 开头的排列
+    def dfs(self, chars, visited, permutation, permutations):
+        # 递归的出口：当我找到一个完整的排列
+        if len(chars) == len(permutation):
+            permutations.append(''.join(permutation))
+            return    
+        
+        # 递归的拆解：基于当前的前缀，下一个字符放啥
+        for i in range(len(chars)):
+            # 同一个位置上的字符用过不能在用
+            if visited[i]:
+                continue
+            # 去重：不同位置的同样的字符，必须按照顺序用。
+            # a' a" b
+            # => a' a" b => √
+            # => a" a' b => x
+            # 不能跳过一个a选下一个a
+            if i > 0 and chars[i] == chars[i - 1] and not visited[i - 1]:
+                continue
+
+            # make changes
+            visited[i] = True
+            permutation.append(chars[i])
+
+            # 找到所有 permutation 开头的排列
+            # 找到所有 "a" 开头的
+            self.dfs(chars, visited, permutation, permutations)
+
+            # backtracking
+            permutation.pop()
+            visited[i] = False
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/subsets-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/subsets-ii.md"
new file mode 100644
index 0000000..6026b25
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/subsets-ii.md"
@@ -0,0 +1,52 @@
+# 子集 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/subsets-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个可能具有重复数字的列表，返回其所有可能的子集。
+ ### 样例说明
+ **样例 1：**
+```
+输入：[0]
+输出：
+[
+  [],
+  [0]
+]
+```
+**样例 2：**
+```
+输入：[1,2,2]
+输出：
+[
+  [2],
+  [1],
+  [1,2,2],
+  [2,2],
+  [1,2],
+  []
+]
+```
+ ### 参考代码
+ 九章算法班中的方法
+```python
+class Solution:
+    """
+    @param nums: A set of numbers.
+    @return: A list of lists. All valid subsets.
+    """
+    def subsetsWithDup(self, nums):
+        nums = sorted(nums)
+        subsets = []
+        self.dfs(nums, 0, [], subsets)
+        return subsets
+        
+    def dfs(self, nums, index, subset, subsets):
+        subsets.append(list(subset))
+        
+        for i in range(index, len(nums)):
+            if i > index and nums[i] == nums[i - 1]:
+                continue
+            subset.append(nums[i])
+            self.dfs(nums, i + 1, subset, subsets)
+            subset.pop()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/subsets.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/subsets.md"
new file mode 100644
index 0000000..3fd8663
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/subsets.md"
@@ -0,0 +1,71 @@
+# 子集
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/subsets/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个含不同整数的集合，返回其所有的子集。
+ ### 样例说明
+ **样例 1：**
+```
+输入：[0]
+输出：
+[
+  [],
+  [0]
+]
+```
+**样例 2：**
+```
+输入：[1,2,3]
+输出：
+[
+  [3],
+  [1],
+  [2],
+  [1,2,3],
+  [1,3],
+  [2,3],
+  [1,2],
+  []
+]
+```
+ ### 参考代码
+ 使用组合类搜索的专用深度优先搜索算法。
+一层一层的决策每个数要不要放到最后的集合里。
+```java
+public class Solution {
+    /**
+     * @param nums: A set of numbers
+     * @return: A list of lists
+     */
+    public List<List<Integer>> subsets(int[] nums) {
+        List<List<Integer>> results = new ArrayList<>();
+        Arrays.sort(nums);
+        dfs(nums, 0, new ArrayList<Integer>(), results);
+        return results;
+    }
+    
+    // 1. 递归的定义
+    // 以 subset 开头的，配上 nums 以 index 开始的数所有组合放到 results 里
+    private void dfs(int[] nums,
+                     int index,
+                     List<Integer> subset,
+                     List<List<Integer>> results) {
+        // 3. 递归的出口
+        if (index == nums.length) {
+            results.add(new ArrayList<Integer>(subset));
+            return;
+        }
+        
+        // 2. 递归的拆解
+        // (如何进入下一层)
+        
+        // 选了 nums[index]
+        subset.add(nums[index]);
+        dfs(nums, index + 1, subset, results);
+        
+        // 不选 nums[index]
+        subset.remove(subset.size() - 1);
+        dfs(nums, index + 1, subset, results);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/subtree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/subtree.md"
new file mode 100644
index 0000000..efbfb0d
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/subtree.md"
@@ -0,0 +1,83 @@
+# 子树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/subtree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有两个不同大小的二叉树： `T1` 有上百万的节点； `T2` 有好几百的节点。请设计一种算法，判定 `T2` 是否为 `T1`的子树。
+
+ ### 样例说明
+ **样例 1：**
+```
+输入：{1,2,3,#,#,4},{3,4}
+输出：true
+解释：
+下面的例子中 T2 是 T1 的子树：
+
+           1                3
+          / \              / 
+    T1 = 2   3      T2 =  4
+            /
+           4
+```
+**样例 2：**
+```
+输入：{1,2,3,#,#,4},{3,#,4}
+输出：false
+解释：
+下面的例子中 T2 不是 T1 的子树：
+
+           1               3
+          / \               \
+    T1 = 2   3       T2 =    4
+            /
+           4
+```
+ ### 参考代码
+ 考点：
+* 搜索遍历
+
+题解：首先判断两树根节点开始是否相同，如果不相同，就从T1的子树和T2当前节点递归搜索。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param T1, T2: The roots of binary tree.
+     * @return: True if T2 is a subtree of T1, or false.
+     */
+    public boolean isSubtree(TreeNode T1, TreeNode T2) {
+        if (T2 == null) {
+            return true;
+        }
+        if (T1 == null) {
+            return false;
+        }
+        
+        if (isEqual(T1, T2)) {
+            return true;
+        }
+        if (isSubtree(T1.left, T2) || isSubtree(T1.right, T2)) {
+            return true;
+        }
+        return false;
+    }
+    
+    private boolean isEqual(TreeNode T1, TreeNode T2) {
+        if (T1 == null || T2 == null) {
+            return T1 == T2;
+        }
+        if (T1.val != T2.val) {
+            return false;
+        }
+        return isEqual(T1.left, T2.left) && isEqual(T1.right, T2.right);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sudoku-solver.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sudoku-solver.md"
new file mode 100644
index 0000000..3a8a40d
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sudoku-solver.md"
@@ -0,0 +1,163 @@
+# 数独
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sudoku-solver/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 编写一个程序，通过填充空单元来解决数独难题。
+空单元由数字`0`表示。
+你可以认为只有一个唯一的解决方案。
+ ### 样例说明
+ **样例 1：**
+```
+给定的数独谜题:
+```
+![](http://lintcode-media.s3.amazonaws.com/problem/250px-Sudoku-by-L2G-20050714.svg.png)
+```
+返回结果：
+```
+![](http://lintcode-media.s3.amazonaws.com/problem/250px-Sudoku-by-L2G-20050714_solution.svg.png)
+ ### 参考代码
+ 详细题解，请见九章微博：http://weibo.com/3948019741/BullK0fYo
+
+采用递归+回溯模板来解决此问题：
+1. 判定DFS的退出条件。
+
+    (1) y越界，应该往下一行继续解。
+
+  （2）x越界，代表数独解完，应该返回。
+
+2. DFS的主体部分：
+
+    把9个可能的值遍历一次，如果是OK的（使用独立 的Valid函数来判定行，列，BLOCK是否符合），继续DFS，否则回溯。
+
+3. 最后的返回值：
+
+    如果所有的可能性遍历都没有找到TRUE，最后应该返回FALSE，也就是当前情况无解。这个时候DFS会自动回溯到上一层再查找别的可能解。
+```java
+public class Solution {
+    public void solveSudoku(char[][] board){
+        solve(board);
+    }
+
+    public boolean solve(char[][] board) {
+        for(int i = 0; i < 9; i++) {
+            for(int j = 0; j < 9; j++){
+                if(board[i][j] != '.'){
+                    continue;
+                }
+                for(int k = 1; k <= 9; k++){
+                    board[i][j] = (char) (k + '0');
+                    if (isValid(board, i, j) && solve(board)){
+                        return true;
+                    }
+                    board[i][j] = '.';
+                }
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    
+     public boolean isValid(char[][] board, int a, int b){
+        Set<Character> contained = new HashSet<Character>();
+        for(int j=0;j<9;j++){
+            if(contained.contains(board[a][j])) return false;
+            if(board[a][j]>'0' && board[a][j]<='9')
+                contained.add(board[a][j]);
+        }
+            
+        
+    
+        contained = new HashSet<Character>();
+        for(int j=0;j<9;j++){
+            if (contained.contains(board[j][b])) {
+                return false;
+            }
+            if (board[j][b]>'0' && board[j][b]<='9') {
+                contained.add(board[j][b]);
+            }
+        }
+        
+    
+        contained = new HashSet<Character>();
+        for (int m = 0; m < 3; m++) {
+            for (int n = 0; n < 3; n++){
+                int x = a / 3 * 3 + m, y = b / 3 * 3 + n;
+                if (contained.contains(board[x][y])) {
+                    return false;
+                }
+                if (board[x][y] > '0' && board[x][y] <= '9') {
+                        contained.add(board[x][y]);
+                }
+            } 
+        }
+    
+        return true;
+    }
+}
+
+// 九章硅谷求职算法集训营版本
+public class Solution {
+    boolean[][] row = new boolean[9][9 + 1];
+    boolean[][] col = new boolean[9][9 + 1];
+    boolean[][][] block = new boolean[3][3][9 + 1];
+    public void solveSudoku(int[][] board){
+        int i, j, k;
+        for (i = 0; i < 9; ++i) {
+            for (j = 1; j <= 9; ++j) {
+                row[i][j] = col[i][j] = false;
+            }
+        }
+
+        for (i = 0; i < 3; ++i) {
+            for (j = 0; j < 3; ++j) {
+                for (k = 1; k <= 9; ++k) {
+                    block[i][j][k] = false;
+                }
+            }
+        }
+
+        for (i = 0; i < 9; ++i) {
+            for (j = 0; j < 9; ++j) {
+                if (board[i][j] != 0) {
+                    k = board[i][j];
+                    row[i][k] = col[j][k] = true;
+                    block[i / 3][j / 3][k] = true;
+                }
+            }
+        }
+
+        solve(board, 0, 0);
+    }
+
+    public boolean solve(int[][] board, int i, int j) {
+        if (i == 9) {
+            return true;
+        }
+
+        if (j == 9) {
+            return solve(board, i + 1, 0);
+        }
+
+        if (board[i][j] != 0) {
+            return solve(board, i, j + 1);
+        }
+
+        int k;
+        for (k = 1; k <= 9; ++k) {
+            if (!row[i][k] && !col[j][k] && !block[i/3][j/3][k]) {
+                row[i][k] = col[j][k] = block[i/3][j/3][k] = true;
+                board[i][j] = k;
+                if (solve(board, i, j + 1)) {
+                    return true;
+                }
+                
+                board[i][j] = 0;
+                row[i][k] = col[j][k] = block[i/3][j/3][k] = false;
+            }
+        }
+
+        return false;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sum-of-left-leaves.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sum-of-left-leaves.md"
new file mode 100644
index 0000000..4f753ae
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sum-of-left-leaves.md"
@@ -0,0 +1,74 @@
+# 左叶子的和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sum-of-left-leaves/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 找出给定二叉树中，所有左叶子的值之和。
+ ### 样例说明
+ **样例1**
+```
+输入：
+{3,9,20,#,#,15,7}
+输出：24
+
+解释：这棵二叉树中，有两个左叶子结点，它们的值分别为9和15。因此返回24。
+    3
+   / \
+  9  20
+    /  \
+   15   7
+```
+
+**样例 2:**
+```
+输入:
+{1,#,2,#,3}
+输出:
+0
+
+解释:
+1
+  \
+    2
+      \
+       3
+```
+ ### 参考代码
+ 递归遍历二叉树的节点，判断当前节点是否有左儿子，进而判断左儿子是否为叶子节点。
+```java
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    public int sumOfLeftLeaves(TreeNode root) {
+        if(root == null) {
+            return 0;
+        }
+        int sum = 0;
+        if(root.left != null)
+        {
+            TreeNode left = root.left;
+            //如果左儿子为叶子节点
+            if(left.left == null && left.right == null) {
+                sum += left.val;
+            }
+            //否则继续递归遍历左子树
+            else {
+                sum += sumOfLeftLeaves(left);
+            }
+        }
+        //递归遍历右子树
+        if(root.right != null)
+        {
+            TreeNode right = root.right;
+            sum += sumOfLeftLeaves(right);
+        }
+        return sum;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sum-root-to-leaf-numbers.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sum-root-to-leaf-numbers.md"
new file mode 100644
index 0000000..e78a13f
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/sum-root-to-leaf-numbers.md"
@@ -0,0 +1,68 @@
+# 根节点到叶节点求和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sum-root-to-leaf-numbers/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定仅包含来自`0-9`的数字的二叉树，每个根到叶路径可以表示数字。举个例子：root-to-leaf路径`1-> 2-> 3`，它代表数字`123`，找到所有根到叶的数的总和
+ ### 样例说明
+ **样例1**
+
+```
+输入: {1,2,3}
+输出: 25
+解释:
+    1
+   / \
+  2   3
+路径 1->2 表示数字 12.
+路径 1->3 表示数字 13.
+因此, sum = 12 + 13 = 25.
+```
+
+**样例2**
+
+```
+输入: {4,9,0,5,1}
+输出: 1026
+解释:
+    4
+   / \
+  9   0
+ / \
+5   1
+路径 4->9->5 表示数字 495.
+路径 4->9->1 表示数字 491.
+路径 4->0 表示数字 40.
+因此, sum = 495 + 491 + 40 = 1026.
+```
+ ### 参考代码
+ Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.&nbsp;<div>An example is the root-to-leaf path 1-&gt;2-&gt;3 which represents the number 123.&nbsp;
+</div><div>Find the total sum of all root-to-leaf numbers.&nbsp;</div><div><br></div><div>For example,&nbsp;</div><div>&nbsp; 1&nbsp;</div><div>&nbsp;/ \&nbsp;</div><div>2 &nbsp;3&nbsp;</div><div><br></div><div>The root-to-leaf path 1-&gt;2 represents the number 12.&nbsp;</div><div>The root-to-leaf path 1-&gt;3 represents the number 13.&nbsp;</div><div><br></div><div>&nbsp;Return the sum = 12 + 13 = 25.</div><div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博：</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/BBFgh84Bn" target="_blank">http://weibo.com/3948019741/BBFgh84Bn</a></span></font><br></div>
+```java
+/**
+ * Definition for binary tree
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    public int sumNumbers(TreeNode root) {
+        return dfs(root, 0);
+    }
+
+    private int dfs(TreeNode root, int prev){
+        if(root == null) {
+            return 0;
+        }
+
+        int sum = root.val + prev * 10;
+        if(root.left == null && root.right == null) {
+            return sum;
+        }
+
+        return dfs(root.left, sum) + dfs(root.right, sum);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/symmetric-binary-tree.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/symmetric-binary-tree.md"
new file mode 100644
index 0000000..8413443
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/symmetric-binary-tree.md"
@@ -0,0 +1,61 @@
+# 对称二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/symmetric-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一颗二叉树，判断是否是对称二叉树
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,2,3,4,4,3}
+输出：true
+解释：
+
+         1
+        / \
+       2   2
+      / \ / \
+      3 4 4 3
+
+是一个对称的二叉树。
+```
+**样例 2:**
+```
+输入：{1,2,2,#,3,#,3}
+输出：false
+解释：
+
+         1
+        / \
+        2  2
+        \   \
+         3   3
+
+不是对称的二叉树。
+```
+ ### 参考代码
+ 递归地判断是否有对应结点
+```python
+1"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root, the root of binary tree.
+    @return true if it is a mirror of itself, or false.
+    """
+    def help(self, p, q):
+        if p == None and q == None: return True
+        if p and q and p.val == q.val:
+            return self.help(p.right, q.left) and self.help(p.left, q.right)
+        return False
+    
+    def isSymmetric(self, root):
+        # Write your code here
+        if root:
+            return self.help(root.left, root.right)
+        return True
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/target-sum.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/target-sum.md"
new file mode 100644
index 0000000..6c537c0
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/target-sum.md"
@@ -0,0 +1,98 @@
+# 目标和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/target-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个非负整数的列表a1,a2,...an，再给定一个目标S。现在用`+`和`-`两种运算，对于每一个整数，选择一个作为它前面的符号。
+
+找出有多少种方法，使得这些整数的和正好等于S。
+ ### 样例说明
+ 例1:
+```
+输入: nums为 [1, 1, 1, 1, 1], S 为 3. 
+输出: 5
+解释: 
+
+-1+1+1+1+1 = 3
++1-1+1+1+1 = 3
++1+1-1+1+1 = 3
++1+1+1-1+1 = 3
++1+1+1+1-1 = 3
+
+有5种方法让和为3.
+```
+
+例2:
+```
+输入: nums 为 [], S 为 3. 
+输出: 0
+解释: 
+没有方法能让和为3
+```
+
+ ### 参考代码
+ 用DFS搜索所有的可能，或利用动态规划记录状态来搜索
+```java
+// DP 解法
+public class Solution {
+    public int findTargetSumWays(int[] nums, int S) {
+        int sum = 0;
+        for (int a : nums) {
+            sum += a;
+        }
+        if (sum < Math.abs(S)) {
+            return 0;
+        }
+
+        //init for dp
+        int doubleSum = sum << 1;
+        int[][] dp = new int[nums.length][doubleSum + 1];
+        if (nums[0] == 0) {
+            dp[0][sum] = 2;
+        } else {
+            dp[0][sum - nums[0]] = 1;
+            dp[0][sum + nums[0]] = 1;
+        }
+
+        //dp
+        for (int i = 1; i < nums.length; i++) {
+            for (int j = 0; j <= doubleSum; j++) {
+                if (j - nums[i] >= 0) {
+                    dp[i][j] += dp[i - 1][j - nums[i]];
+                }
+                if (j + nums[i] <= doubleSum) {
+                    dp[i][j] += dp[i - 1][j + nums[i]];
+                }
+            }
+        }
+
+        return dp[nums.length - 1][S + sum];
+    }
+}
+
+// DFS解法
+public class Solution {
+    int answer = 0;
+
+    public int findTargetSumWays(int[] nums, int S) {
+        int[] s = new int[nums.length];
+        s[nums.length - 1] = nums[nums.length - 1];
+        for (int i = nums.length - 2; i >= 0; i--) {
+            s[i] = s[i + 1] + nums[i];
+        }
+
+        dfsHelper(nums, S, 0, 0, s);
+        return answer;
+    }
+
+    public void dfsHelper(int[] nums, int S, int index, int currSum, int[] s) {
+        if (index == nums.length) {
+            if (currSum == S) {
+                answer++;
+            }
+        } else if (Math.abs(S - currSum) <= s[index]) {
+            dfsHelper(nums, S, index + 1, currSum + nums[index], s);
+            dfsHelper(nums, S, index + 1, currSum - nums[index], s);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/triangle.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/triangle.md"
new file mode 100644
index 0000000..0c5c60f
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/triangle.md"
@@ -0,0 +1,68 @@
+# 数字三角形
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/triangle/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数字三角形，找到从顶部到底部的最小路径和。每一步可以移动到下面一行的相邻数字上。
+
+ ### 样例说明
+ **样例 1**
+
+```
+输入下列数字三角形：
+[
+     [2],
+    [3,4],
+   [6,5,7],
+  [4,1,8,3]
+]
+输出： 11
+解释： 从顶到底部的最小路径和为11 ( 2 + 3 + 5 + 1 = 11)。
+```
+
+**样例 2**
+
+```
+输入下列数字三角形：
+[
+     [2],
+    [3,2],
+   [6,5,7],
+  [4,4,8,1]
+]
+输出： 12
+解释： 从顶到底部的最小路径和为12 ( 2 + 2 + 7 + 1 = 12)。
+```
+
+
+ ### 参考代码
+ 使用记忆化搜索的版本
+时间复杂度 $O(n^2)$
+空间复杂度 $O(n^2)$（额外耗费的空间）
+```python
+class Solution:
+    """
+    @param triangle: a list of lists of integers
+    @return: An integer, minimum path sum
+    """
+    def minimumTotal(self, triangle):
+        return self.divide_conquer(triangle, 0, 0, {})
+        
+    # 函数返回从 x, y 出发，走到最底层的最短路径值
+    # memo 中 key 为二元组 (x, y)
+    # memo 中 value 为从 x, y 走到最底层的最短路径值
+    def divide_conquer(self, triangle, x, y, memo):
+        if x == len(triangle):
+            return 0
+            
+        # 如果找过了，就不要再找了，直接把之前找到的值返回
+        if (x, y) in memo:
+            return memo[(x, y)]
+
+        left = self.divide_conquer(triangle, x + 1, y, memo)
+        right = self.divide_conquer(triangle, x + 1, y + 1, memo)
+        
+        # 在 return 之前先把这次找到的最短路径值记录下来
+        # 避免之后重复搜索
+        memo[(x, y)] = min(left, right) + triangle[x][y]
+        return memo[(x, y)]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/webpage-crawler.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/webpage-crawler.md"
new file mode 100644
index 0000000..ce95687
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/webpage-crawler.md"
@@ -0,0 +1,104 @@
+# 网页爬虫
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/webpage-crawler/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个网页爬虫，去模拟爬取`http://www.wikipedia.org/`页面，让我们简化这个问题，使用存储url替代存储网页的内容。
+
+你的爬虫应该做：
+1. 调用 `HtmlHelper.parseUrls(url)` 从当前给出的这个url对用的网页内容中获取所有的urls
+2. 只爬取wikipedia的界面，这个界面内容由LintCode模拟
+3. 相同的页面不重复爬取
+4. 初始的url为：`http://www.wikipedia.org/`
+ ### 样例说明
+ 
+ ### 参考代码
+ ```python
+"""
+class HtmlHelper:
+    # @param (string)
+    # @return (list)
+    @classmethod
+    def parseUrls(url):
+        # Get all urls from a webpage of given url. 
+"""
+
+import threading
+
+class Solution:
+    """
+    @param url(string): a url of root page
+    @return (list): all urls
+    """
+    def crawler(self, url):
+        self.queue = [url]
+        self.urlSet = set([url])
+        self.threads = []
+        
+        self.bfs()
+        
+        for thread in self.threads:
+            thread.join()
+        
+        return list(self.urlSet)
+    
+    def bfs(self):
+        while len(self.queue):
+            url = self.queue.pop(0)
+            sub_urls = HtmlHelper.parseUrls(url)
+            for sub_url in sub_urls:
+                if not "wikipedia" in sub_url:
+                    continue
+                if sub_url in self.urlSet:
+                    continue
+                self.urlSet.add(sub_url)
+                self.queue.append(sub_url)
+                if threading.activeCount() < 3:
+                    thread = threading.Thread(target = self.bfs, args = (self, ))
+                    self.threads.append(thread)
+                    thread.start()
+
+"""
+class HtmlHelper:
+    # @param (string)
+    # @return (list)
+    @classmethod
+    def parseUrls(url):
+        # Get all urls from a webpage of given url. 
+"""
+
+import threading
+
+class Solution:
+    """
+    @param url(string): a url of root page
+    @return (list): all urls
+    """
+    def crawler(self, url):
+        self.urlSet = set([url])        
+        self.threads = []
+        
+        self.dfs(url)
+        
+        for thread in self.threads:
+            thread.join()
+        
+        return list(self.urlSet)
+        
+        
+    def dfs(self, url):
+        subUrls = HtmlHelper.parseUrls(url)
+        for subUrl in subUrls:
+            if not "wikipedia" in subUrl:
+                continue
+            if subUrl in self.urlSet:
+                continue
+            
+            self.urlSet.add(subUrl)
+            if threading.activeCount() < 3:
+                newThread = threading.Thread(target = self.dfs,
+                    args = (subUrl, )) # 需要加个逗号....
+                self.threads.append(newThread)
+                newThread.start()
+            else:
+                self.dfs(subUrl)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/wildcard-matching.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/wildcard-matching.md"
new file mode 100644
index 0000000..8d3590a
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/wildcard-matching.md"
@@ -0,0 +1,148 @@
+# 通配符匹配
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/wildcard-matching/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 判断两个可能包含通配符“？”和“*”的字符串是否匹配。匹配规则如下：
+
+- '?' 可以匹配任何单个字符。
+- '*' 可以匹配任意字符串（包括空字符串）。
+
+两个串完全匹配才算匹配成功。
+
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+"aa"
+"a"
+输出: false
+```
+
+**输出2**
+
+```plain
+输入:
+"aa"
+"aa"
+输出: true
+```
+
+**输出3**
+
+```plain
+输入:
+"aaa"
+"aa"
+输出: false
+```
+
+**输出4**
+
+```plain
+输入:
+"aa"
+"*"
+输出: true
+说明: '*' 可以替换任何字符串
+```
+
+**输出5**
+
+```plain
+输入:
+"aa"
+"a*"
+输出: true
+```
+
+**样例6**
+
+```plain
+输入:
+"ab"
+"?*"
+输出: true
+说明: '?' -> 'a' '*' -> 'b'
+```
+
+**样例7**
+
+```plain
+输入:
+"aab"
+"c*a*b"
+输出: false
+```
+
+
+ ### 参考代码
+ 使用深度优先搜索 + 记忆化的版本。
+
+用一个二维的 boolean 数组来当记忆化数组，记录 s 从 sIndex 开始的后缀 能够匹配上 p 从 pIndex 开始的后缀
+```java
+public class Solution {
+    /**
+     * @param s: A string 
+     * @param p: A string includes "?" and "*"
+     * @return: is Match?
+     */
+    public boolean isMatch(String s, String p) {
+        if (s == null || p == null) {
+            return false;
+        }
+        
+        boolean[][] memo = new boolean[s.length()][p.length()];
+        boolean[][] visited = new boolean[s.length()][p.length()];
+        return isMatchHelper(s, 0, p, 0, memo, visited);
+    }
+    
+    private boolean isMatchHelper(String s, int sIndex,
+                                  String p, int pIndex,
+                                  boolean[][] memo,
+                                  boolean[][] visited) {
+        // 如果 p 从pIdex开始是空字符串了，那么 s 也必须从 sIndex 是空才能匹配上
+        if (pIndex == p.length()) {
+            return sIndex == s.length();
+        }
+        
+        // 如果 s 从 sIndex 是空，那么p 必须全是 * 
+        if (sIndex == s.length()) {
+            return allStar(p, pIndex);
+        }
+        
+        if (visited[sIndex][pIndex]) {
+            return memo[sIndex][pIndex];
+        }
+        
+        char sChar = s.charAt(sIndex);
+        char pChar = p.charAt(pIndex);
+        boolean match;
+        
+        if (pChar == '*') {
+            match = isMatchHelper(s, sIndex, p, pIndex + 1, memo, visited) ||
+                isMatchHelper(s, sIndex + 1, p, pIndex, memo, visited);
+        } else {
+            match = charMatch(sChar, pChar) &&
+                isMatchHelper(s, sIndex + 1, p, pIndex + 1, memo, visited);
+        }
+        
+        visited[sIndex][pIndex] = true;
+        memo[sIndex][pIndex] = match;
+        return match;
+    }
+    
+    private boolean charMatch(char sChar, char pChar) {
+        return (sChar == pChar || pChar == '?');
+    }
+    
+    private boolean allStar(String p, int pIndex) {
+        for (int i = pIndex; i < p.length(); i++) {
+            if (p.charAt(i) != '*') {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-break-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-break-ii.md"
new file mode 100644
index 0000000..5dac348
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-break-ii.md"
@@ -0,0 +1,67 @@
+# 单词拆分II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-break-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一字串s和单词的字典dict,在字串中增加空格来构建一个句子，并且所有单词都来自字典。
+返回所有有可能的句子。
+ ### 样例说明
+ **样例 1:**
+```
+输入："lintcode"，["de","ding","co","code","lint"]
+输出：["lint code", "lint co de"]
+解释：
+插入一个空格是"lint code"，插入两个空格是 "lint co de"
+```
+
+**样例 2:**
+```
+输入："a"，[]
+输出：[]
+解释：字典为空
+```
+ ### 参考代码
+ 使用记忆化搜索
+```java
+public class Solution {
+    public ArrayList<String> wordBreak(String s, Set<String> dict) {
+        // Note: The Solution object is instantiated only once and is reused by each test case.
+        Map<String, ArrayList<String>> memo = new HashMap<String, ArrayList<String>>();
+        return wordBreakHelper(s, dict, memo);
+    }
+
+    public ArrayList<String> wordBreakHelper(String s,
+                                             Set<String> dict,
+                                             Map<String, ArrayList<String>> memo){
+        if (memo.containsKey(s)) {
+            return memo.get(s);
+        }
+        
+        ArrayList<String> results = new ArrayList<String>();
+        
+        if (s.length() == 0) {
+            return results;
+        }
+        
+        if (dict.contains(s)) {
+            results.add(s);
+        }
+        
+        for (int len = 1; len < s.length(); ++len){
+            String word = s.substring(0, len);
+            if (!dict.contains(word)) {
+                continue;
+            }
+            
+            String suffix = s.substring(len);
+            ArrayList<String> segmentations = wordBreakHelper(suffix, dict, memo);
+            
+            for (String segmentation: segmentations){
+                results.add(word + " " + segmentation);
+            }
+        }
+        
+        memo.put(s, results);
+        return results;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-break.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-break.md"
new file mode 100644
index 0000000..1fe67d6
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-break.md"
@@ -0,0 +1,96 @@
+# 单词拆分 I
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-break/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定字符串 s 和单词字典 dict，确定 s 是否可以分成一个或多个以空格分隔的子串，并且这些子串都在字典中存在。
+ ### 样例说明
+ ```
+样例 1:
+	输入:  "lintcode", ["lint", "code"]
+	输出:  true
+
+样例 2:
+	输入: "a", ["a"]
+	输出:  true
+	
+```
+
+
+ ### 参考代码
+ 使用《九章算法班》中讲过的划分型动态规划算法
+- state: `dp[i]` 表示前 i 个字符是否能够被划分为若干个单词
+- function: `dp[i]` = or{`dp[j]` and j + 1~i 是一个单词}
+```
+[[python]]
+class Solution:
+    """
+    @param: s: A string
+    @param: dict: A dictionary of words dict
+    @return: A boolean
+    """
+    def wordBreak(self, s, wordSet):
+        if not s:
+            return True
+            
+        n = len(s)
+        dp = [False] * (n + 1)
+        dp[0] = True
+        
+        max_length = max([
+            len(word)
+            for word in wordSet
+        ]) if wordSet else 0
+        
+        for i in range(1, n + 1):
+            for l in range(1, max_length + 1):
+                if i < l:
+                    break
+                if not dp[i - l]:
+                    continue
+                word = s[i - l:i]
+                if word in wordSet:
+                    dp[i] = True
+                    break
+        
+        return dp[n]
+[[java]]
+public class Solution {
+    /*
+     * @param s: A string
+     * @param dict: A dictionary of words dict
+     * @return: A boolean
+     */
+    public boolean wordBreak(String s, Set<String> dict) {
+        if (s == null) {
+            return true;
+        }
+        
+        int maxLength = 0;
+        for (String word : dict) {
+            maxLength = Math.max(maxLength, word.length());
+        }
+      
+        int n = s.length();
+        boolean[] dp = new boolean[n + 1];
+        dp[0] = true;
+        
+        for (int i = 1; i <= n; i++) {
+            for (int l = 1; l <= maxLength; l++) {
+                if (i < l) {
+                    break;
+                }
+                if (!dp[i - l]) {
+                    continue;
+                }
+                String word = s.substring(i - l, i);
+                if (dict.contains(word)) {
+                    dp[i] = true;
+                    break;
+                }
+            }
+        }
+        
+        return dp[n];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-count.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-count.md"
new file mode 100644
index 0000000..963dfa5
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-count.md"
@@ -0,0 +1,48 @@
+# 单词计数 (Map Reduce版本)
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-count/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 使用 map reduce 来计算单词频率
+https://hadoop.apache.org/docs/r1.2.1/mapred_tutorial.html#Example%3A+WordCount+v1.0
+
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/**
+ * Definition of OutputCollector:
+ * class OutputCollector<K, V> {
+ *     public void collect(K key, V value);
+ *         // Adds a key/value pair to the output buffer
+ * }
+ */
+public class WordCount {
+
+    public static class Map {
+        public void map(String key, String value, OutputCollector<String, Integer> output) {
+            // Write your code here
+            // Output the results into output buffer.
+            // Ps. output.collect(String key, int value);
+            StringTokenizer tokenizer = new StringTokenizer(value);
+            while (tokenizer.hasMoreTokens()) {
+                String word = tokenizer.nextToken();
+                output.collect(word, 1);
+            }
+        }
+    }
+
+    public static class Reduce {
+        public void reduce(String key, Iterator<Integer> values,
+                           OutputCollector<String, Integer> output) {
+            // Write your code here
+            // Output the results into output buffer.
+            // Ps. output.collect(String key, int value);
+            int sum = 0;
+            while (values.hasNext()) {
+                    sum += values.next();
+            }
+            output.collect(key, sum);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder-ii.md"
new file mode 100644
index 0000000..8f902ca
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder-ii.md"
@@ -0,0 +1,110 @@
+# 单词接龙 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-ladder-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出两个单词（*start*和*end*）和一个字典，找出所有从*start*到*end*的最短转换序列。
+
+变换规则如下：
+
+1. 每次只能改变一个字母。
+2. 变换过程中的中间单词必须在字典中出现。
+
+ ### 样例说明
+ **样例 1:**
+```
+输入：start = "a"，end = "c"，dict =["a","b","c"]
+输出：[["a","c"]]
+解释：
+"a"->"c"
+```
+
+**样例 2:**
+```
+输入：start ="hit"，end = "cog"，dict =["hot","dot","dog","lot","log"]
+输出：[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"]]
+解释：
+1."hit"->"hot"->"dot"->"dog"->"cog"
+2."hit"->"hot"->"lot"->"log"->"cog"
+第一个序列的字典序小于第二个。
+```
+ ### 参考代码
+ end -> start : bfs
+start -> end : dfs
+```java
+public class Solution {
+    public List<List<String>> findLadders(String start, String end,
+            Set<String> dict) {
+        List<List<String>> ladders = new ArrayList<List<String>>();
+        Map<String, List<String>> map = new HashMap<String, List<String>>();
+        Map<String, Integer> distance = new HashMap<String, Integer>();
+
+        dict.add(start);
+        dict.add(end);
+ 
+        bfs(map, distance, end, start, dict);
+        
+        List<String> path = new ArrayList<String>();
+        
+        dfs(ladders, path, start, end, distance, map);
+
+        return ladders;
+    }
+
+    void dfs(List<List<String>> ladders, List<String> path, String crt,
+            String end, Map<String, Integer> distance,
+            Map<String, List<String>> map) {
+        path.add(crt);
+        if (crt.equals(end)) {
+            ladders.add(new ArrayList<String>(path));
+        } else {
+            for (String next : map.get(crt)) {
+                if (distance.containsKey(next) && distance.get(crt) == distance.get(next) + 1) { 
+                    dfs(ladders, path, next, end, distance, map);
+                }
+            }           
+        }
+        path.remove(path.size() - 1);
+    }
+
+    void bfs(Map<String, List<String>> map, Map<String, Integer> distance,
+            String start, String end, Set<String> dict) {
+        Queue<String> q = new LinkedList<String>();
+        q.offer(start);
+        distance.put(start, 0);
+        for (String s : dict) {
+            map.put(s, new ArrayList<String>());
+        }
+        
+        while (!q.isEmpty()) {
+            String crt = q.poll();
+
+            List<String> nextList = expand(crt, dict);
+            for (String next : nextList) {
+                map.get(next).add(crt);
+                if (!distance.containsKey(next)) {
+                    distance.put(next, distance.get(crt) + 1);
+                    q.offer(next);
+                }
+            }
+        }
+    }
+
+    List<String> expand(String crt, Set<String> dict) {
+        List<String> expansion = new ArrayList<String>();
+
+        for (int i = 0; i < crt.length(); i++) {
+            for (char ch = 'a'; ch <= 'z'; ch++) {
+                if (ch != crt.charAt(i)) {
+                    String expanded = crt.substring(0, i) + ch
+                            + crt.substring(i + 1);
+                    if (dict.contains(expanded)) {
+                        expansion.add(expanded);
+                    }
+                }
+            }
+        }
+
+        return expansion;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder.md"
new file mode 100644
index 0000000..f6f8157
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-ladder.md"
@@ -0,0 +1,70 @@
+# 单词接龙
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-ladder/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出两个单词（*start*和*end*）和一个字典，找出从*start*到*end*的最短转换序列，输出最短序列的长度。
+
+变换规则如下：
+
+1. 每次只能改变一个字母。
+2. 变换过程中的中间单词必须在字典中出现。(起始单词和结束单词不需要出现在字典中)
+ ### 样例说明
+ **样例 1:**
+```
+输入：start = "a"，end = "c"，dict =["a","b","c"]
+输出：2
+解释：
+"a"->"c"
+```
+
+
+**样例 2:**
+```
+输入：start ="hit"，end = "cog"，dict =["hot","dot","dog","lot","log"]
+输出：5
+解释：
+"hit"->"hot"->"dot"->"dog"->"cog"
+```
+ ### 参考代码
+ 使用分层遍历的BFS版本。
+```python
+class Solution:
+    """
+    @param: start: a string
+    @param: end: a string
+    @param: dict: a set of string
+    @return: An integer
+    """
+    def ladderLength(self, start, end, dict):
+        dict.add(end)
+        queue = collections.deque([start])
+        visited = set([start])
+        
+        distance = 0
+        while queue:
+            distance += 1
+            for i in range(len(queue)):
+                word = queue.popleft()
+                if word == end:
+                    return distance
+                
+                for next_word in self.get_next_words(word):
+                    if next_word not in dict or next_word in visited:
+                        continue
+                    queue.append(next_word)
+                    visited.add(next_word) 
+
+        return 0
+        
+    # O(26 * L^2)
+    # L is the length of word
+    def get_next_words(self, word):
+        words = []
+        for i in range(len(word)):
+            left, right = word[:i], word[i + 1:]
+            for char in 'abcdefghijklmnopqrstuvwxyz':
+                if word[i] == char:
+                    continue
+                words.append(left + char + right)
+        return words
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-search-ii.md" "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-search-ii.md"
new file mode 100644
index 0000000..945c6f3
--- /dev/null
+++ "b/\345\233\276\350\256\272/\346\267\261\345\272\246\344\274\230\345\205\210\346\220\234\347\264\242/word-search-ii.md"
@@ -0,0 +1,97 @@
+# 单词搜索 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-search-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个由小写字母组成的矩阵和一个字典。找出所有同时在字典和矩阵中出现的单词。一个单词可以从矩阵中的任意位置开始，可以向左/右/上/下四个相邻方向移动。一个字母在一个单词中只能被使用一次。且字典中不存在重复单词</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：["doaf","agai","dcan"]，["dog","dad","dgdg","can","again"]
+输出：["again","can","dad","dog"]
+解释：
+  d o a f
+  a g a i
+  d c a n
+矩阵中查找，返回 ["again","can","dad","dog"]。
+```
+
+**样例 2:**
+```
+输入：["a"]，["b"]
+输出：[]
+解释：
+ a
+矩阵中查找，返回 []。
+```
+ ### 参考代码
+ 不用 Trie，直接使用哈希表的方法
+```python
+DIRECTIONS = [(0, -1), (0, 1), (-1, 0), (1, 0)]
+
+class Solution:
+    """
+    @param board: A list of lists of character
+    @param words: A list of string
+    @return: A list of string
+    """
+    def wordSearchII(self, board, words):
+        if board is None or len(board) == 0:
+            return []
+        
+        # pre-process
+        # 预处理
+        word_set = set(words)
+        prefix_set = set()
+        for word in words:
+            for i in range(len(word)):
+                prefix_set.add(word[:i + 1])
+        
+        result = set()
+        for i in range(len(board)):
+            for j in range(len(board[0])):
+                c = board[i][j]
+                self.search(
+                    board,
+                    i,
+                    j,
+                    board[i][j],
+                    word_set,
+                    prefix_set,
+                    set([(i, j)]),
+                    result,
+                )
+                
+        return list(result)
+        
+    def search(self, board, x, y, word, word_set, prefix_set, visited, result):
+        if word not in prefix_set:
+            return
+        
+        if word in word_set:
+            result.add(word)
+        
+        for delta_x, delta_y in DIRECTIONS:
+            x_ = x + delta_x
+            y_ = y + delta_y
+            
+            if not self.inside(board, x_, y_):
+                continue
+            if (x_, y_) in visited:
+                continue
+            
+            visited.add((x_, y_))
+            self.search(
+                board,
+                x_,
+                y_,
+                word + board[x_][y_],
+                word_set,
+                prefix_set,
+                visited,
+                result,
+            )
+            visited.remove((x_, y_))
+            
+    def inside(self, board, x, y):
+        return 0 <= x < len(board) and 0 <= y < len(board[0])
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/balanced-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/balanced-binary-tree.md"
new file mode 100644
index 0000000..cee5a4e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/balanced-binary-tree.md"
@@ -0,0 +1,81 @@
+# 平衡二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/balanced-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个二叉树,确定它是高度平衡的。对于这个问题,一棵高度平衡的二叉树的定义是：一棵二叉树中每个节点的两个子树的深度相差不会超过1。&nbsp;<br></p>
+ ### 样例说明
+ ```
+样例  1:
+	输入: tree = {1,2,3}
+	输出: true
+	
+	样例解释:
+	如下，是一个平衡的二叉树。
+		  1  
+		 / \                
+		2  3
+
+	
+样例  2:
+	输入: tree = {3,9,20,#,#,15,7}
+	输出: true
+	
+	样例解释:
+	如下，是一个平衡的二叉树。
+		  3  
+		 / \                
+		9  20                
+		  /  \                
+		 15   7 
+
+	
+样例  2:
+	输入: tree = {1,#,2,3,4}
+	输出: false
+	
+	样例解释:
+	如下，是一个不平衡的二叉树。1的左右子树高度差2
+		  1  
+		   \                
+		   2                
+		  /  \                
+		 3   4
+	
+```
+
+ ### 参考代码
+ Given a binary tree, determine if it is height-balanced.
+
+For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
+
+在树上做一次DFS，计算以每个点为根的子树高度。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root: The root of binary tree.
+    @return: True if this Binary tree is Balanced, or false.
+    """
+    def isBalanced(self, root):
+        balanced, _ = self.validate(root)
+        return balanced
+        
+    def validate(self, root):
+        if root is None:
+            return True, 0
+            
+        balanced, leftHeight = self.validate(root.left)
+        if not balanced:
+            return False, 0
+        balanced, rightHeight = self.validate(root.right)
+        if not balanced:
+            return False, 0
+            
+        return abs(leftHeight - rightHeight) <= 1, max(leftHeight, rightHeight) + 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/count-of-smaller-numbers-after-self.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/count-of-smaller-numbers-after-self.md"
new file mode 100644
index 0000000..552bf5f
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/count-of-smaller-numbers-after-self.md"
@@ -0,0 +1,94 @@
+# 比自己小的元素个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/count-of-smaller-numbers-after-self/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组`nums`，返回一个新的`counts`数组。counts[i]表示：nums[i]右侧比它小的数的个数。
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: [5, 2, 6, 1]
+输出: [2, 1, 1, 0]
+说明:
+5的右侧有2个元素比它小 (2 and 1).
+2的右侧有1个元素比它小 (1).
+6的右侧有1个元素比它小 (1).
+1的右侧有0个元素比它小.
+```
+
+**样例2**
+
+```plain
+输入: [1, 2, 3, 4]
+输出: [0, 0, 0, 0]
+```
+
+
+ ### 参考代码
+ 真正的 $nlogn$ 的算法
+首先使用离散化将原来的数组变为对应的 order 数组。这样就不会有负数，也不会有特别大的数。
+如：`[1, 1000, -100, 10, 100]`，将每个数替换为在整个数组中对应的排序。如，1是从小到大第2个，那么就替换为 2。
+替换之后得到数组 `[2, 5, 1, 3, 4]`。
+
+接着在用 Binary Indexed Tree 来统计每个数右边有多少个数比他小，只需要从右到左遍历这个数组，一边把数丢到 BIT 里一边计算就行了。
+```java
+public class Solution {
+    /**
+     * @param nums: a list of integers
+     * @return: return a list of integers
+     */
+    public List<Integer> countSmaller(int[] nums) {
+        if (nums == null || nums.length == 0) {
+            return new ArrayList<Integer>();
+        }
+        
+        discretization(nums);
+
+        // build bit array
+        int[] bit = new int[nums.length + 1];
+        int[] count = new int[nums.length];
+        
+        for (int i = nums.length - 1; i >= 0; i--) {
+            count[i] = getSum(bit, nums[i] - 1);
+            update(bit, nums[i]);
+        }
+        
+        List<Integer> result = new ArrayList<Integer>();
+        for (int i = 0; i < count.length; i++) {
+            result.add(count[i]);
+        }
+        
+        return result;
+    }
+    
+    // this is nlogn
+    // sort the orignal array and mapping the number to 
+    // the order in the sorted array;
+    private void discretization(int[] nums) {
+        int[] sorted = nums.clone();
+        Arrays.sort(sorted);
+        
+        for (int i = 0; i < nums.length; i++) {
+            nums[i] = Arrays.binarySearch(sorted, nums[i]) + 1;
+        }
+    }
+    
+    private void update(int[] bit, int index) {
+        for (int i = index; i < bit.length; i = i + lowbit(i)) {
+            bit[i]++;
+        }
+    }
+    
+    private int getSum(int[] bit, int index) {
+        int sum = 0;
+        for (int i = index; i > 0; i = i - lowbit(i)) {
+            sum += bit[i];
+        }
+        return sum;
+    }
+    
+    private int lowbit(int x) {
+        return x & (-x);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/data-stream-median.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/data-stream-median.md"
new file mode 100644
index 0000000..c7ba84e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/data-stream-median.md"
@@ -0,0 +1,52 @@
+# 数据流中位数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/data-stream-median/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 数字是不断进入数组的，在每次添加一个新的数进入数组的同时返回当前新数组的中位数。
+ ### 样例说明
+ 
+ ### 参考代码
+ 把比 median 小的放在 maxheap 里，把比 median 大的放在 minheap 里。median 单独放在一个变量里。
+每次新增一个数的时候，先根据比当前的 median 大还是小丢到对应的 heap 里。
+丢完以后，再处理左右两边的平衡性:
+
+1. 如果左边太少了，就把 median 丢到左边，从右边拿一个最小的出来作为 median。
+2. 如果右边太少了，就把 median 丢到右边，从左边拿一个最大的出来作为新的 median。
+```python
+import heapq
+
+
+class Solution:
+    """
+    @param nums: A list of integers
+    @return: the median of numbers
+    """
+    def medianII(self, nums):
+        if not nums:
+            return []
+            
+        self.median = nums[0]
+        self.maxheap = []
+        self.minheap = []
+        
+        medians = [nums[0]]
+        for num in nums[1:]:
+            self.add(num)
+            medians.append(self.median)
+            
+        return medians
+
+    def add(self, num):
+        if num < self.median:
+            heapq.heappush(self.maxheap, -num)
+        else:
+            heapq.heappush(self.minheap, num)
+            
+        # balanace
+        if len(self.maxheap) > len(self.minheap):
+            heapq.heappush(self.minheap, self.median)
+            self.median = -heapq.heappop(self.maxheap)
+        elif len(self.maxheap) + 1 < len(self.minheap):
+            heapq.heappush(self.maxheap, -self.median)
+            self.median = heapq.heappop(self.minheap)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/find-median-from-data-stream.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/find-median-from-data-stream.md"
new file mode 100644
index 0000000..718c924
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/find-median-from-data-stream.md"
@@ -0,0 +1,73 @@
+# 数据流中位数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-median-from-data-stream/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 数字是不断进入数组的，在每次添加一个新的数进入数组的同时返回当前新数组的中位数。
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: [1,2,3,4,5]
+输出: [1,1,2,2,3]
+样例说明：
+[1] 和 [1,2] 的中位数是 1.
+[1,2,3] 和 [1,2,3,4] 的中位数是 2.
+[1,2,3,4,5] 的中位数是 3.
+```
+
+**样例2**
+
+```plain
+输入: [4,5,1,3,2,6,0]
+输出: [4,4,4,3,3,3,3]
+样例说明：
+[4], [4,5] 和 [4,5,1] 的中位数是 4.
+[4,5,1,3], [4,5,1,3,2], [4,5,1,3,2,6] 和 [4,5,1,3,2,6,0] 的中位数是 3.
+```
+
+
+ ### 参考代码
+ 把比 median 小的放在 maxheap 里，把比 median 大的放在 minheap 里。median 单独放在一个变量里。
+每次新增一个数的时候，先根据比当前的 median 大还是小丢到对应的 heap 里。
+丢完以后，再处理左右两边的平衡性:
+
+如果左边太少了，就把 median 丢到左边，从右边拿一个最小的出来作为 median。
+如果右边太少了，就把 median 丢到右边，从左边拿一个最大的出来作为新的 median。
+```python
+import heapq
+
+
+class Solution:
+    """
+    @param nums: A list of integers
+    @return: the median of numbers
+    """
+    def medianII(self, nums):
+        if not nums:
+            return []
+            
+        self.median = nums[0]
+        self.maxheap = []
+        self.minheap = []
+        
+        medians = [nums[0]]
+        for num in nums[1:]:
+            self.add(num)
+            medians.append(self.median)
+            
+        return medians
+
+    def add(self, num):
+        if num < self.median:
+            heapq.heappush(self.maxheap, -num)
+        else:
+            heapq.heappush(self.minheap, num)
+            
+        # balanace
+        if len(self.maxheap) > len(self.minheap):
+            heapq.heappush(self.minheap, self.median)
+            self.median = -heapq.heappop(self.maxheap)
+        elif len(self.maxheap) + 1 < len(self.minheap):
+            heapq.heappush(self.maxheap, -self.median)
+            self.median = heapq.heappop(self.minheap)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/implement-queue-by-two-stacks.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/implement-queue-by-two-stacks.md"
new file mode 100644
index 0000000..6e9bc8e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/implement-queue-by-two-stacks.md"
@@ -0,0 +1,79 @@
+# 用栈实现队列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/implement-queue-by-two-stacks/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">正如标题所述，你需要使用两个栈来实现队列的一些操作。</span><br></p><p>队列应支持push(element)，pop() 和 top()，其中pop是弹出队列中的第一个(最前面的)元素。</p><p>pop和top方法都应该返回第一个元素的值。<br></p>
+ ### 样例说明
+ **例1:**
+
+```
+输入:
+    push(1)
+    pop()    
+    push(2)
+    push(3)
+    top()    
+    pop()     
+输出:
+    1
+    2
+    2
+```
+
+**例2:**
+
+```
+输入:
+    push(1)
+    push(2)
+    push(2)
+    push(3)
+    push(4)
+    push(5)
+    push(6)
+    push(7)
+    push(1)
+输出:
+[]
+```
+
+
+ ### 参考代码
+ push加入到栈中
+top即从A栈出到B栈，执行完之后，B栈push出栈顶元素，作为返回值，然后继续入站栈，最后B栈出，返回A栈。
+pop即从A栈出到B栈，执行完之后，B栈push出栈顶元素，然后B栈依次出，返回A栈。
+```java
+public class MyQueue {
+    private Stack<Integer> stack1;
+    private Stack<Integer> stack2;
+
+    public MyQueue() {
+       stack1 = new Stack<Integer>();
+       stack2 = new Stack<Integer>();
+    }
+    
+    private void stack2ToStack1(){
+        while(! stack2.isEmpty()){
+            stack1.push(stack2.pop());
+        }
+    }
+    
+    public void push(int element) {
+        stack2.push(element);
+    }
+
+    public int pop() {
+        if(stack1.empty() == true){
+            this.stack2ToStack1();
+        }
+        return stack1.pop();
+    }
+
+    public int top() {
+        if(stack1.empty() == true){
+            this.stack2ToStack1();
+        }
+        return stack1.peek();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/implement-stack-by-two-queues.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/implement-stack-by-two-queues.md"
new file mode 100644
index 0000000..1b9626c
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/implement-stack-by-two-queues.md"
@@ -0,0 +1,83 @@
+# 双队列实现栈
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/implement-stack-by-two-queues/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 利用两个队列来实现一个栈的功能
+ ### 样例说明
+ 例1:
+```
+输入：
+push(1)
+pop()
+push(2)
+isEmpty() // return false
+top() // return 2
+pop()
+isEmpty() // return true
+```
+
+例2:
+```
+输入：
+isEmpty()
+
+```
+ ### 参考代码
+ 通过另一队列的进出，可以将此队列改造为栈，实现栈的基本操作
+```java
+class Stack {
+    private Queue<Integer> queue1;
+    private Queue<Integer> queue2;
+    
+    public Stack() {
+        queue1 = new LinkedList<Integer>();
+        queue2 = new LinkedList<Integer>();
+    }
+    
+    private void moveItems() {
+        while (queue1.size() != 1) {
+            queue2.offer(queue1.poll());
+        }
+    }
+    
+    private void swapQueues() {
+        Queue<Integer> temp = queue1;
+        queue1 = queue2;
+        queue2 = temp;
+    }
+    
+    /**
+     * push a new item into the stack
+     */
+    public void push(int value) {
+        queue1.offer(value);
+    }
+    
+    /**
+     * return the top of the stack
+     */
+    public int top() {
+        moveItems();
+        int item = queue1.poll();
+        swapQueues();
+        queue1.offer(item);
+        return item;
+    }
+    
+    /**
+     * pop the top of the stack and return it
+     */
+    public void pop() {
+        moveItems();
+        queue1.poll();
+        swapQueues();
+    }
+    
+    /**
+     * check the stack is empty or not.
+     */
+    public boolean isEmpty() {
+        return queue1.isEmpty();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/kth-largest-element-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/kth-largest-element-ii.md"
new file mode 100644
index 0000000..0740e00
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/kth-largest-element-ii.md"
@@ -0,0 +1,41 @@
+# 第K大的元素 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-largest-element-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 找到数组中第K大的元素，N远大于K。请注意你需要找的是数组排序后的第 k 个最大的元素，而不是第 k 个不同的元素
+ ### 样例说明
+ **例1:**
+```
+输入:[9,3,2,4,8],3
+输出:4
+
+```
+**例2:**
+```
+输入:[1,2,3,4,5,6,8,9,10,7],10
+输出:1
+
+```
+
+ ### 参考代码
+ 利用优先队列求第k大元素
+```java
+class Solution {
+    /**
+     * @param nums an integer unsorted array
+     * @param k an integer from 1 to n
+     * @return the kth largest element
+     */
+    public int kthLargestElement2(int[] nums, int k) {
+        // Write your code here
+        PriorityQueue<Integer> q = new PriorityQueue<Integer>(k);
+        for (int num : nums) {
+            q.offer(num);
+            if (q.size() > k) {
+                q.poll();
+            }
+        }
+        return q.peek();
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/kth-largest-element.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/kth-largest-element.md"
new file mode 100644
index 0000000..adebf60
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/kth-largest-element.md"
@@ -0,0 +1,75 @@
+# 第k大元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-largest-element/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在数组中找到第 k 大的元素。
+
+ ### 样例说明
+ **样例 1：**
+```
+输入：
+n = 1, nums = [1,3,4,2]
+输出：
+4
+```
+**样例 2：**
+```
+输入：
+n = 3, nums = [9,3,2,4,8]
+输出：
+4
+```
+ ### 参考代码
+ 九章算法强化班里讲过的标准 Parition 模板。
+```java
+class Solution {
+    /*
+     * @param k : description of k
+     * @param nums : array of nums
+     * @return: description of return
+     */
+    public int kthLargestElement(int k, int[] nums) {
+        if (nums == null || nums.length == 0 || k < 1 || k > nums.length){
+            return -1;
+        }
+        return partition(nums, 0, nums.length - 1, nums.length - k);
+    }
+    
+    private int partition(int[] nums, int start, int end, int k) {
+        if (start >= end) {
+            return nums[k];
+        }
+        
+        int left = start, right = end;
+        int pivot = nums[(start + end) / 2];
+        
+        while (left <= right) {
+            while (left <= right && nums[left] < pivot) {
+                left++;
+            }
+            while (left <= right && nums[right] > pivot) {
+                right--;
+            }
+            if (left <= right) {
+                swap(nums, left, right);
+                left++;
+                right--;
+            }
+        }
+        
+        if (k <= right) {
+            return partition(nums, start, right, k);
+        }
+        if (k >= left) {
+            return partition(nums, left, end, k);
+        }
+        return nums[k];
+    }    
+    
+    private void swap(int[] nums, int i, int j) {
+        int tmp = nums[i];
+        nums[i] = nums[j];
+        nums[j] = tmp;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/kth-largest-in-n-arrays.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/kth-largest-in-n-arrays.md"
new file mode 100644
index 0000000..4cb7ca3
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/kth-largest-in-n-arrays.md"
@@ -0,0 +1,95 @@
+# N数组第K大元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-largest-in-n-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在N个数组中找到第K大元素
+ ### 样例说明
+ 例1:
+```
+输入:
+k = 3, [[9,3,2,4,7],[1,2,3,4,8]]
+输出:
+7
+解释:
+第三大的元素为 7。
+
+```
+例2:
+```
+输入:
+k = 2, [[9,3,2,4,8],[1,2,3,4,2]]
+输出:
+8
+解释:
+最大的元素为 9，第二大的元素为 8，第三大的元素为 4 等等。
+
+```
+
+ ### 参考代码
+ 对每个数组排序，然后将每个数组的最小元素加入到优先队列中，每次从优先队列中pop出一个元素，然后push进同组的下一个元素，直到第k个
+```java
+import java.util.Comparator;  
+import java.util.PriorityQueue;  
+import java.util.Queue; 
+
+class Node {
+    public int value, from_id, index;
+    public Node(int _v, int _id, int _i) {
+        this.value = _v;
+        this.from_id = _id;
+        this.index = _i;
+    }
+}
+
+public class Solution {
+    /**
+     * @param arrays a list of array
+     * @param k an integer
+     * @return an integer, K-th largest element in N arrays
+     */
+    public int KthInArrays(int[][] arrays, int k) {
+        // Write your code here
+        Queue<Node> queue =  new PriorityQueue<Node>(k, new Comparator<Node>() {  
+                public int compare(Node o1, Node o2) {  
+                    if (o1.value > o2.value)
+                        return -1;
+                    else if (o1.value < o2.value)
+                        return 1;
+                    else
+                        return 0;
+                }
+            }); 
+
+        int n = arrays.length;
+        int i;
+        for (i = 0; i < n; ++i) {
+            Arrays.sort(arrays[i]);
+            
+            if (arrays[i].length > 0) {
+                int from_id = i;
+                int index = arrays[i].length - 1;
+                int value = arrays[i][index];
+                queue.add(new Node(value, from_id, index));
+            }
+        }
+
+        for (i  = 0; i < k; ++i) {
+            Node temp = queue.poll();
+            int from_id = temp.from_id;
+            int index = temp.index;
+            int value = temp.value;
+            
+            if (i == k - 1)
+                return value;
+            
+            if (index > 0) {
+                index --;
+                value = arrays[from_id][index];
+                queue.add(new Node(value, from_id, index));
+            }
+        }
+
+        return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/kth-smallest-number-in-sorted-matrix.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/kth-smallest-number-in-sorted-matrix.md"
new file mode 100644
index 0000000..648cc29
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/kth-smallest-number-in-sorted-matrix.md"
@@ -0,0 +1,67 @@
+# 排序矩阵中的从小到大第k个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-smallest-number-in-sorted-matrix/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个排序矩阵中找从小到大的第 *k* 个整数。
+
+排序矩阵的定义为：每一行递增，每一列也递增。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+[
+  [1 ,5 ,7],
+  [3 ,7 ,8],
+  [4 ,8 ,9],
+]
+k = 4
+输出: 5
+```
+
+**样例 2:**
+
+```
+输入: 
+[
+  [1, 2],
+  [3, 4]
+]
+k = 3
+输出: 3
+```
+ ### 参考代码
+ 使用 heapq
+注意 visited 不能开成一个二维数组，因为那样会增加时间复杂度。比如 K=1 的时候，理应 O(1) 的时间返回。开一个二维数组的耗费显然不只是 O(1) 的
+```python
+import heapq
+
+class Solution:
+    """
+    @param matrix: a matrix of integers
+    @param k: An integer
+    @return: the kth smallest number in the matrix
+    """
+    def kthSmallest(self, matrix, k):
+        n = len(matrix)
+        if n == 0:
+            return None
+        
+        m = len(matrix[0])
+        if m == 0:
+            return None
+            
+        minheap = [(matrix[0][0], 0, 0)]
+        visited = set([0])
+        num = None
+        for _ in range(k):
+            num, x, y = heapq.heappop(minheap)
+            if x + 1 < n and (x + 1) * m + y not in visited:
+                heapq.heappush(minheap, (matrix[x + 1][y], x + 1, y))
+                visited.add((x + 1) * m + y)
+            if y + 1 < m and x * m + y + 1 not in visited:
+                heapq.heappush(minheap, (matrix[x][y + 1], x, y + 1))
+                visited.add(x * m + y + 1)
+
+        return num
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/kth-smallest-sum-in-two-sorted-arrays.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/kth-smallest-sum-in-two-sorted-arrays.md"
new file mode 100644
index 0000000..65d5444
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/kth-smallest-sum-in-two-sorted-arrays.md"
@@ -0,0 +1,168 @@
+# 两个排序数组和的第K小
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-smallest-sum-in-two-sorted-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个排好序的数组 *A*, *B*，定义集合 *sum* = *a* + *b* ，其中a来自A数组，b来自B数组，求 *sum* 中第k小的元素
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+a = [1, 7, 11]
+b = [2, 4, 6]
+k = 3
+输出: 7
+说明: 满足条件的所有的和有[3, 5, 7, 9, 11, 13, 13, 15, 17]，其中第三个是7.
+```
+
+**样例2**
+
+```plain
+输入:
+a = [1, 7, 11]
+b = [2, 4, 6]
+k = 4
+输出: 9
+说明: 满足条件的所有的和有[3, 5, 7, 9, 11, 13, 13, 15, 17]，其中第四个是9.
+```
+
+**样例3**
+
+```plain
+输入:
+a = [1, 7, 11]
+b = [2, 4, 6]
+k = 8
+输出: 15
+说明: 满足条件的所有的和有[3, 5, 7, 9, 11, 13, 13, 15, 17]，其中第八个是15.
+```
+
+
+ ### 参考代码
+ 类似于 Kth smallest in sorted matrix 一题。
+使用 heapq
+我们把行和列分别定为两个数组，就可以形成一个排好序的矩阵
+```java
+// 方法一
+class Pair {
+    public int x, y, sum;
+    public Pair(int x, int y, int val) {
+        this.x = x;
+        this.y = y;
+        this.sum = val;
+    }
+}
+class PairComparator implements Comparator<Pair> {
+    public int compare(Pair a, Pair b) {
+        return a.sum - b.sum;
+    }
+}
+
+public class Solution {
+    /**
+     * @param A an integer arrays sorted in ascending order
+     * @param B an integer arrays sorted in ascending order
+     * @param k an integer
+     * @return an integer
+     */
+    public int kthSmallestSum(int[] A, int[] B, int k) {
+        int[] dx = new int[]{0, 1};
+        int[] dy = new int[]{1, 0};
+        boolean[][] hash = new boolean[A.length][B.length];
+        PriorityQueue<Pair> minHeap = new PriorityQueue<Pair>(k, new PairComparator());
+        minHeap.add(new Pair(0, 0, A[0] + B[0]));
+
+        for(int i = 0; i < k - 1; i ++){
+            Pair cur = minHeap.poll();
+            for(int j = 0; j < 2; j ++){
+                int next_x = cur.x + dx[j];
+                int next_y = cur.y + dy[j];
+                Pair next_Pair = new Pair(next_x, next_y, 0);
+                if(next_x < A.length && next_y < B.length &&  !hash[next_x][next_y]){
+                    hash[next_x][next_y] = true;
+                    next_Pair.sum = A[next_x] + B[next_y];
+                    minHeap.add(next_Pair);
+                }
+            }
+        }
+        return minHeap.peek().sum;
+    }
+}
+
+//方法二:
+class Pair implements Comparable<Pair> {
+    int x;
+    int y;
+    int sum;
+    Pair(int x, int y, int sum) {
+        this.x = x;
+        this.y = y;
+        this.sum = sum;
+    }
+    @Override
+    public int compareTo(Pair another) {
+        if (this.sum == another.sum) {
+            return 0;
+        }
+        return this.sum < another.sum ? -1 : 1;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        } else if (!(obj instanceof Pair)) {
+            return false;
+        }
+        Pair another = (Pair) obj;
+        return this.x == another.x && this.y == another.y;
+    }
+    @Override
+    public int hashCode() {
+        return x * 101 + y;
+    }
+}
+public class Solution {
+    /**
+     * @param A an integer arrays sorted in ascending order
+     * @param B an integer arrays sorted in ascending order
+     * @param k an integer
+     * @return an integer
+     */
+    int[] dx = {1, 0};
+    int[] dy = {0, 1};
+    public int kthSmallestSum(int[] A, int[] B, int k) {
+        if (A.length == 0 && B.length == 0) {
+            return 0; 
+        } else if (A.length == 0) {
+            return B[k];
+        } else if (B.length == 0) {
+            return A[k];
+        }
+        HashSet<Pair> isVisited = new HashSet<Pair>();
+        PriorityQueue<Pair> minHeap = new PriorityQueue<Pair>();
+        Pair p;
+        Pair nextP;
+        p = new Pair(0, 0, A[0] + B[0]);
+        minHeap.offer(p);
+        isVisited.add(p);
+        int nextX;
+        int nextY;
+        int nextSum;
+        for (int count = 0; count < k - 1; count++) {
+            p = minHeap.poll();
+            for (int i = 0; i < 2; i++) {
+                nextX = p.x + dx[i];
+                nextY = p.y + dy[i];
+                nextP = new Pair(nextX, nextY, 0);
+                if (nextX >= 0 && nextX < A.length && nextY >= 0 && nextY < B.length && !isVisited.contains(nextP)) {
+                    nextSum = A[nextX] + B[nextY];
+                    nextP.sum = nextSum;
+                    minHeap.offer(nextP);
+                    isVisited.add(nextP);
+                }
+            }
+        }
+        return minHeap.peek().sum;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/largest-number.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/largest-number.md"
new file mode 100644
index 0000000..b0fc90a
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/largest-number.md"
@@ -0,0 +1,50 @@
+# 最大数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/largest-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一组非负整数，重新排列他们的顺序把他们组成一个最大的整数。
+ ### 样例说明
+ **样例 1:**
+```
+输入:[1, 20, 23, 4, 8]
+输出:"8423201"
+```
+**样例 2:**
+```
+输入:[4, 6, 65]
+输出:"6654"
+```
+
+ ### 参考代码
+ ```java
+class NumbersComparator implements Comparator<String> {
+	@Override
+	public int compare(String s1, String s2) {
+		return (s2 + s1).compareTo(s1 + s2);
+	}
+}
+
+public class Solution {
+    
+    public String largestNumber(int[] nums) {
+        String[] strs = new String[nums.length];
+        for (int i = 0; i < nums.length; i++) {
+            strs[i] = Integer.toString(nums[i]);
+        }
+        Arrays.sort(strs, new NumbersComparator());
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < strs.length; i++) {
+            sb.append(strs[i]);
+        }
+        String result = sb.toString();
+        int index = 0;
+        while (index < result.length() && result.charAt(index) == '0') {
+            index++;
+        }
+        if (index == result.length()) {
+            return "0";
+        }
+        return result.substring(index);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/moving-average-from-data-stream.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/moving-average-from-data-stream.md"
new file mode 100644
index 0000000..aee0823
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/moving-average-from-data-stream.md"
@@ -0,0 +1,40 @@
+# 数据流滑动窗口平均值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/moving-average-from-data-stream/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一串整数流和窗口大小，计算滑动窗口中所有整数的平均值。
+ ### 样例说明
+ **样例1 :**
+```
+MovingAverage m = new MovingAverage(3);
+m.next(1) = 1 // 返回 1.00000
+m.next(10) = (1 + 10) / 2 // 返回 5.50000
+m.next(3) = (1 + 10 + 3) / 3 // 返回 4.66667
+m.next(5) = (10 + 3 + 5) / 3 // 返回 6.00000
+```
+ ### 参考代码
+ 使用队列
+```java
+public class MovingAverage {
+
+    private Queue<Integer> que;
+    private double sum = 0;
+    private int size;
+
+    /** Initialize your data structure here. */
+    public MovingAverage(int size) {
+        que = new LinkedList<Integer>();
+        this.size = size;
+    }
+    
+    public double next(int val) {
+        // Write your code here
+        sum += val;
+        if (que.size() == size) {
+            sum = sum - que.poll();
+        }
+        que.offer(val);
+        return sum / que.size();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/print-numbers-by-recursion.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/print-numbers-by-recursion.md"
new file mode 100644
index 0000000..5eb89fb
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/print-numbers-by-recursion.md"
@@ -0,0 +1,48 @@
+# 用递归打印数字
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/print-numbers-by-recursion/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 用递归的方法找到从1到最大的N位整数。
+ ### 样例说明
+ **样例 1:**
+```
+输入 : N = 1 
+输出 :[1,2,3,4,5,6,7,8,9]
+```
+**样例 2:**
+```
+输入 : N = 2 
+输出 :[[1,2,3,4,5,6,7,8,9,10,11,12,...,99]
+```
+
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param n: An integer.
+     * return : An array storing 1 to the largest number with n digits.
+     */
+    public List<Integer> numbersByRecursion(int n) {
+        // write your code here
+        ArrayList<Integer> res = new ArrayList<>();
+        num(n, 0, res);
+        return res;
+    }
+    
+    public void num(int n, int ans,ArrayList<Integer> res){
+        
+        if(n == 0){
+            if(ans > 0){
+                res.add(ans);
+            }
+            return;
+        }
+        
+        int i;
+        for(i = 0; i <= 9; i++){
+            num(n - 1, ans * 10 + i, res);
+        }
+        
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/range-sum-query-2d-mutable.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/range-sum-query-2d-mutable.md"
new file mode 100644
index 0000000..b86ca08
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/range-sum-query-2d-mutable.md"
@@ -0,0 +1,101 @@
+# 范围矩阵元素和-可变的
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/range-sum-query-2d-mutable/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二维数组(矩阵), 需要查询它的某个子矩阵的元素的和, 同时矩阵内的元素可以被改变.
+
+你需要实现三个方法:
+
+- `NumMatrix(matrix)` 类的构造方法
+- `sumRegion(row1, col1, row2, col2)` 返回处于 (row1, col1) 为左上角, (row2, col2) 为右下角的子矩阵内的元素的和
+- `update(row, col, val)` 把 (row, col) 位置的元素更新为 `val`
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  NumMatrix(
+    [[3,0,1,4,2],
+     [5,6,3,2,1],
+     [1,2,0,1,5],
+     [4,1,0,1,7],
+     [1,0,3,0,5]]
+  )
+  sumRegion(2,1,4,3)
+  update(3,2,2)
+  sumRegion(2,1,4,3)
+输出: 
+  8
+  10
+```
+
+**样例 2:**
+
+```
+输入: 
+  NumMatrix([[1]])
+  sumRegion(0, 0, 0, 0)
+  update(0, 0, -1)
+  sumRegion(0, 0, 0, 0)
+输出: 
+  1
+  -1
+```
+ ### 参考代码
+ Binary Indexed Tree - 2D 版本
+```java
+public class NumMatrix {
+    private int[][] arr, bit;
+    int n, m;
+    
+    /**
+     * @return: nothing
+     */
+    public NumMatrix(int[][] matrix) {
+        n = matrix.length;
+        m = matrix[0].length;
+        arr = new int[n][m];
+        bit = new int[n + 1][m + 1];
+        
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < m; j++) {
+                update(i, j, matrix[i][j]);
+            }
+        }
+    }
+    
+    public void update(int row, int col, int val) {
+        int delta = val - arr[row][col];
+        arr[row][col] = val;
+        
+        for (int i = row + 1; i <= n; i = i + lowbit(i)) {
+            for (int j = col + 1; j <= m; j = j + lowbit(j)) {
+                bit[i][j] += delta;
+            }
+        }
+    }
+    
+    public int sumRegion(int row1, int col1, int row2, int col2) {
+        return (
+            prefixSum(row2, col2) -
+            prefixSum(row2, col1 - 1) -
+            prefixSum(row1 - 1, col2) +
+            prefixSum(row1 - 1, col1 - 1)
+        );
+    }
+    
+    private int prefixSum(int row, int col) {
+        int sum = 0;
+        for (int i = row + 1; i > 0; i = i - lowbit(i)) {
+            for (int j = col + 1; j > 0; j = j - lowbit(j)) {
+                sum += bit[i][j];
+            }
+        }
+        return sum;
+    }
+    
+    private int lowbit(int x) {
+        return x & (-x);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/range-sum-query-mutable.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/range-sum-query-mutable.md"
new file mode 100644
index 0000000..66b67fc
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/range-sum-query-mutable.md"
@@ -0,0 +1,82 @@
+# 可变范围求和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/range-sum-query-mutable/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组 `nums`, 然后你需要实现两个函数:
+
+- `update(i, val)` 将数组下标为i的元素修改为val
+- `sumRange(l, r)` 返回数组下标在$[l, r]$区间的元素的和
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  nums = [1, 3, 5]
+  sumRange(0, 2)
+  update(1, 2)
+  sumRange(0, 2)
+输出: 
+  9
+  8
+```
+
+**样例 2:**
+
+```
+输入: 
+  nums = [0, 9, 5, 7, 3]
+  sumRange(4, 4)
+  sumRange(2, 4)
+  update(4, 5)
+  update(1, 7)
+  update(0, 8)
+  sumRange(1, 2)
+输出: 
+  3
+  15
+  12
+```
+ ### 参考代码
+ 使用 Binary Indexed Tree（树状数组）
+```java
+public class NumArray {
+    private int[] arr, bit;
+    
+    /**
+     * @return: nothing
+     */
+    public NumArray(int[] nums) {
+        arr = new int[nums.length];
+        bit = new int[nums.length + 1];
+        
+        for (int i = 0; i < nums.length; i++) {
+            update(i, nums[i]);
+        }
+    }
+    
+    public void update(int index, int val) {
+        int delta = val - arr[index];
+        arr[index] = val;
+        
+        for (int i = index + 1; i <= arr.length; i = i + lowbit(i)) {
+            bit[i] += delta;
+        }
+    }
+    
+    public int getPrefixSum(int index) {
+        int sum = 0;
+        for (int i = index + 1; i > 0; i = i - lowbit(i)) {
+            sum += bit[i];
+        }
+        return sum;
+    }
+    
+    private int lowbit(int x) {
+        return x & (-x);
+    }
+
+    public int sumRange(int left, int right) {
+        return getPrefixSum(right) - getPrefixSum(left - 1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-build-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-build-ii.md"
new file mode 100644
index 0000000..5dde1bc
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-build-ii.md"
@@ -0,0 +1,60 @@
+# 线段树的构造 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/segment-tree-build-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 线段树是一棵二叉树，他的每个节点包含了两个额外的属性`start`和`end`用于表示该节点所代表的区间。`start`和`end`都是整数，并按照如下的方式赋值:
+
+- 根节点的 `start` 和 `end` 由 `build` 方法所给出。
+- 对于节点 A 的左儿子，有 `start=A.left, end=(A.left + A.right) / 2`。
+- 对于节点 A 的右儿子，有 `start=(A.left + A.right) / 2 + 1, end=A.right`。
+- 如果 `start` 等于 `end`, 那么该节点是叶子节点，不再有左右儿子。
+
+对于给定数组实现`build`方法, 线段树的每个节点储存区间最大值, 返回根节点.
+ ### 样例说明
+ ```
+输入: [3,2,1,4]
+解释: 
+这颗线段树将会是
+          [0,3](max=4)
+          /          \
+       [0,1]         [2,3]    
+      (max=3)       (max=4)
+      /   \          /    \    
+   [0,0]  [1,1]    [2,2]  [3,3]
+  (max=3)(max=2)  (max=1)(max=4)
+ ### 参考代码
+ 模板题, 递归构造线段树即可. 注意内存要分配在堆上, 而不是栈上.
+
+Python代码为Python2版本
+```python
+"""
+Definition of SegmentTreeNode:
+class SegmentTreeNode:
+    def __init__(self, start, end, max):
+        self.start, self.end, self.max = start, end, max
+        self.left, self.right = None, None
+"""
+
+class Solution:	
+    # @oaram A: a list of integer
+    # @return: The root of Segment Tree
+    def build(self, A):
+        return self.buildTree(0, len(A)-1, A)
+
+    def buildTree(self, start, end, A):
+        if start > end:
+            return None
+
+        node = SegmentTreeNode(start, end, A[start])
+        if start == end:
+            return node
+
+        mid = (start + end) / 2
+        node.left = self.buildTree(start, mid, A)
+        node.right = self.buildTree(mid + 1, end, A)
+        if node.left is not None and node.left.max > node.max:
+            node.max = node.left.max
+        if node.right is not None and node.right.max > node.max:
+            node.max = node.right.max
+        return node
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-build.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-build.md"
new file mode 100644
index 0000000..ed26a49
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-build.md"
@@ -0,0 +1,65 @@
+# 线段树的构造
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/segment-tree-build/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 线段树是一棵二叉树，他的每个节点包含了两个额外的属性`start`和`end`用于表示该节点所代表的区间。start和end都是整数，并按照如下的方式赋值:
+
+- 根节点的 _start_ 和 _end_ 由 `build` 方法所给出。
+- 对于节点 A 的左儿子，有 `start=A.start, end=(A.start + A.end) / 2`。
+- 对于节点 A 的右儿子，有 `start=(A.start + A.end) / 2 + 1, end=A.end`。
+- 如果 _start_ 等于 _end_, 那么该节点是叶子节点，不再有左右儿子。
+
+实现一个 `build` 方法，接受 _start_ 和 _end_ 作为参数, 然后构造一个代表区间 `[start, end]` 的线段树，返回这棵线段树的根。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[1,4]
+输出："[1,4][1,2][3,4][1,1][2,2][3,3][4,4]"
+解释：
+	               [1,  4]
+	             /        \
+	      [1,  2]           [3, 4]
+	      /     \           /     \
+	   [1, 1]  [2, 2]     [3, 3]  [4, 4]
+```
+**样例 2:**
+```
+输入：[1,6]
+输出："[1,6][1,3][4,6][1,2][3,3][4,5][6,6][1,1][2,2][4,4][5,5]"
+解释：
+	       [1,  6]
+             /        \
+      [1,  3]           [4,  6]
+      /     \           /     \
+   [1, 2]  [3,3]     [4, 5]   [6,6]
+   /    \           /     \
+[1,1]   [2,2]     [4,4]   [5,5]
+```
+ ### 参考代码
+ 考点：
+* 线段树
+* 二分
+
+题解：递归过程按照左子树范围为(start, (start + end) / 2)，右子树范围为((start + end) / 2 + 1, end)建树即可。
+```python
+"""
+Definition of SegmentTreeNode:
+class SegmentTreeNode:
+    def __init__(self, start, end):
+        this.start, this.end = start, end
+        this.left, this.right = None, None
+"""
+
+class Solution:	
+    # @param start, end: Denote an segment / interval
+    # @return: The root of Segment Tree
+    def build(self, start, end):
+        if start > end:
+            return None
+        root = SegmentTreeNode(start, end)
+        if start == end:
+            return root
+        root.left = self.build(start, (start + end) / 2)
+        root.right = self.build((start + end) / 2 + 1, end)
+        return root
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-modify.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-modify.md"
new file mode 100644
index 0000000..7470bb4
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-modify.md"
@@ -0,0 +1,87 @@
+# 线段树的修改
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/segment-tree-modify/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 对于一棵 **最大线段树**, 每个节点包含一个额外的 `max` 属性，用于存储该节点所代表区间的最大值。
+
+设计一个 `modify` 的方法，接受三个参数 `root`、 `index` 和 `value`。该方法将 _root_ 为根的线段树中 [_start_, _end_] = [_index_, _index_] 的节点修改为了新的 _value_ ，并确保在修改后，线段树的每个节点的 _max_ 属性仍然具有正确的值。
+ ### 样例说明
+ **样例 1:**
+```
+输入："[1,4,max=3][1,2,max=2][3,4,max=3][1,1,max=2][2,2,max=1][3,3,max=0][4,4,max=3]",2,4
+输出："[1,4,max=4][1,2,max=4][3,4,max=3][1,1,max=2][2,2,max=4][3,3,max=0][4,4,max=3]"
+解释：
+线段树:
+
+	                      [1, 4, max=3]
+	                    /                \
+	        [1, 2, max=2]                [3, 4, max=3]
+	       /              \             /             \
+	[1, 1, max=2], [2, 2, max=1], [3, 3, max=0], [4, 4, max=3]
+
+如何调用modify(root, 2, 4), 可以得到:
+
+	                      [1, 4, max=4]
+	                    /                \
+	        [1, 2, max=4]                [3, 4, max=3]
+	       /              \             /             \
+	[1, 1, max=2], [2, 2, max=4], [3, 3, max=0], [4, 4, max=3]
+```
+
+
+**样例 2:**
+```
+输入："[1,4,max=3][1,2,max=2][3,4,max=3][1,1,max=2][2,2,max=1][3,3,max=0][4,4,max=3]",4,0
+输出："[1,4,max=4][1,2,max=4][3,4,max=0][1,1,max=2][2,2,max=4][3,3,max=0][4,4,max=0]"
+解释：
+线段树:
+
+	                      [1, 4, max=3]
+	                    /                \
+	        [1, 2, max=2]                [3, 4, max=3]
+	       /              \             /             \
+	[1, 1, max=2], [2, 2, max=1], [3, 3, max=0], [4, 4, max=3]
+如果调用modify(root, 4, 0), 可以得到:
+	
+	                      [1, 4, max=2]
+	                    /                \
+	        [1, 2, max=2]                [3, 4, max=0]
+	       /              \             /             \
+	[1, 1, max=2], [2, 2, max=1], [3, 3, max=0], [4, 4, max=0]
+```
+ ### 参考代码
+ 考点：
+* 线段树
+
+题解：按照区间自上向下查询区间，然后修改叶子节点，再自下向上合并修改各节点信息。
+```python
+"""
+Definition of SegmentTreeNode:
+class SegmentTreeNode:
+    def __init__(self, start, end, max):
+        this.start, this.end, this.max = start, end, max
+        this.left, this.right = None, None
+"""
+
+class Solution:	
+    """
+    @param root, index, value: The root of segment tree and 
+    @ change the node's value with [index, index] to the new given value
+    @return: nothing
+    """
+    def modify(self, root, index, value):
+        # write your code here
+        if root is None:
+            return
+
+        if root.start == root.end:
+            root.max = value
+            return
+    
+        if root.left.end >= index:
+            self.modify(root.left, index, value)
+        else:
+            self.modify(root.right, index, value)
+        
+        root.max = max(root.left.max, root.right.max)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-query-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-query-ii.md"
new file mode 100644
index 0000000..e036fa0
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-query-ii.md"
@@ -0,0 +1,86 @@
+# 线段树查询 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/segment-tree-query-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 对于一个数组，我们可以对其建立一棵 `线段树`, 每个结点存储一个额外的值 `count` 来代表这个结点所指代的数组区间内的元素个数. (数组中并不一定每个位置上都有元素)
+
+实现一个 `query` 的方法，该方法接受三个参数 `root`, `start` 和 `end`, 分别代表线段树的根节点和需要查询的区间，找到数组中在区间[*start*, *end*]内的元素个数。
+ ### 样例说明
+ **样例 1:**
+```
+输入："[0,3,count=3][0,1,count=1][2,3,count=2][0,0,count=1][1,1,count=0][2,2,count=1][3,3,count=1]",[[1, 1], [1, 2], [2, 3], [0, 2]]
+输出：[0,1,2,2]
+解释：
+对应的线段树为：
+
+	                     [0, 3, count=3]
+	                     /             \
+	          [0,1,count=1]             [2,3,count=2]
+	          /         \               /            \
+	   [0,0,count=1] [1,1,count=0] [2,2,count=1], [3,3,count=1]
+
+Input : query(1,1), Output: 0
+
+Input : query(1,2), Output: 1
+
+Input : query(2,3), Output: 2
+
+Input : query(0,2), Output: 2
+```
+
+
+
+**样例 2:**
+```
+输入："[0,3,count=3][0,1,count=1][2,3,count=2][0,0,count=1][1,1,count=0][2,2,count=0][3,3,count=1]",[[1, 1], [1, 2], [2, 3], [0, 2]]
+输出：[0,0,1,1]
+解释：
+对应的线段树为：
+
+	                     [0, 3, count=2]
+	                     /             \
+	          [0,1,count=1]             [2,3,count=1]
+	          /         \               /            \
+	   [0,0,count=1] [1,1,count=0] [2,2,count=0], [3,3,count=1]
+
+Input : query(1,1), Output: 0
+
+Input : query(1,2), Output: 0
+
+Input : query(2,3), Output: 1
+
+Input : query(0,2), Output: 1
+```
+
+ ### 参考代码
+ 考点：
+* 线段树
+
+题解：递归实现线段树自上向下的区间查询，自下向上的合并统计即可。
+```python
+"""
+Definition of SegmentTreeNode:
+class SegmentTreeNode:
+    def __init__(self, start, end, count):
+        this.start, this.end, this.count = start, end, count
+        this.left, this.right = None, None
+"""
+
+class Solution:	
+    # @param root, start, end: The root of segment tree and 
+    #                          an segment / interval
+    # @return: The count number in the interval [start, end] 
+    def query(self, root, start, end):
+        # write your code here
+        if root is None:
+            return 0
+
+        if root.start > end or root.end < start:
+            return 0
+    
+        if start <= root.start and root.end <= end:
+            return root.count
+        
+        return self.query(root.left, start, end) + \
+                   self.query(root.right, start, end)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-query.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-query.md"
new file mode 100644
index 0000000..4b98557
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/segment-tree-query.md"
@@ -0,0 +1,68 @@
+# 线段树的查询
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/segment-tree-query/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 对于一个有n个数的整数数组，在对应的线段树中, 根节点所代表的区间为0-n-1, 每个节点有一个额外的属性`max`，值为该节点所代表的数组区间start到end内的最大值。
+
+为SegmentTree设计一个 `query` 的方法，接受3个参数`root`, `start`和`end`，线段树root所代表的数组中子区间[start, end]内的最大值。
+ ### 样例说明
+ **样例 1:**
+```
+输入："[0,3,max=4][0,1,max=4][2,3,max=3][0,0,max=1][1,1,max=4][2,2,max=2][3,3,max=3]",1,2
+输出：4
+解释：
+对于数组 [1, 4, 2, 3], 对应的线段树为 :
+
+	                  [0, 3, max=4]
+	                 /             \
+	          [0,1,max=4]        [2,3,max=3]
+	          /         \        /         \
+	   [0,0,max=1] [1,1,max=4] [2,2,max=2], [3,3,max=3]
+[1,2]区间最大值为4
+```
+
+
+**样例 2:**
+```
+输入："[0,3,max=4][0,1,max=4][2,3,max=3][0,0,max=1][1,1,max=4][2,2,max=2][3,3,max=3]",2,3
+输出：3
+解释：
+对于数组 [1, 4, 2, 3], 对应的线段树为 :
+
+	                  [0, 3, max=4]
+	                 /             \
+	          [0,1,max=4]        [2,3,max=3]
+	          /         \        /         \
+	   [0,0,max=1] [1,1,max=4] [2,2,max=2], [3,3,max=3]
+[2,3]区间最大值为3
+```
+ ### 参考代码
+ 考点：
+* 线段树
+
+题解：
+线段树为二叉树，如果查询区间位于当前区间之中，返回max值即可，如果超出范围，返回极小值即可，继续向左右搜索。
+```python
+"""
+Definition of SegmentTreeNode:
+class SegmentTreeNode:
+    def __init__(self, start, end, max):
+        this.start, this.end, this.max = start, end, max
+        this.left, this.right = None, None
+"""
+
+class Solution:	
+    # @param root, start, end: The root of segment tree and 
+    #                          an segment / interval
+    # @return: The maximum number in the interval [start, end]
+    def query(self, root, start, end):
+        # write your code here
+        if root.start > end or root.end < start:
+            return -0x7fffff
+    
+        if start <= root.start and root.end <= end:
+            return root.max
+        
+        return max(self.query(root.left, start, end), \
+                   self.query(root.right, start, end))
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/sequence-reconstruction.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/sequence-reconstruction.md"
new file mode 100644
index 0000000..bc3c5de
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/sequence-reconstruction.md"
@@ -0,0 +1,189 @@
+# 序列重构
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sequence-reconstruction/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 判断是否序列 `org` 能唯一地由 `seqs`重构得出. `org`是一个由从1到n的正整数排列而成的序列，$1 \leq n \leq 10^4$。 重构表示组合成`seqs`的一个最短的父序列 (意思是，一个最短的序列使得所有 `seqs`里的序列都是它的子序列). 
+判断是否有且仅有一个能从 `seqs`重构出来的序列，并且这个序列是`org`。
+ ### 样例说明
+ 例1:
+```
+输入:org = [1,2,3], seqs = [[1,2],[1,3]]
+输出: false
+解释:
+[1,2,3] 并不是唯一可以被重构出的序列，还可以重构出 [1,3,2]
+```
+例2:
+```
+输入: org = [1,2,3], seqs = [[1,2]]
+输出: false
+解释:
+能重构出的序列只有 [1,2].
+```
+例3:
+```
+输入: org = [1,2,3], seqs = [[1,2],[1,3],[2,3]]
+输出: true
+解释:
+序列 [1,2], [1,3], 和 [2,3] 可以唯一重构出 [1,2,3].
+```
+例4:
+```
+输入:org = [4,1,5,2,6,3], seqs = [[5,2,6,3],[4,1,5,2]]
+输出:true
+```
+
+ ### 参考代码
+ 九章算法班里讲过的拓扑排序喽
+只要保证 queue 里最多同时只有一个元素即可。
+所以这是 queue 用 list 然后每次 pop 也可以，反正只有一个数。
+```
+[[python]]
+class Solution:
+    """
+    @param org: a permutation of the integers from 1 to n
+    @param seqs: a list of sequences
+    @return: true if it can be reconstructed only one or false
+    """
+    def sequenceReconstruction(self, org, seqs):
+        graph = self.build_graph(seqs)
+        topo_order = self.topological_sort(graph)
+        return topo_order == org
+            
+    def build_graph(self, seqs):
+        # initialize graph
+        graph = {}
+        for seq in seqs:
+            for node in seq:
+                if node not in graph:
+                    graph[node] = set()
+        
+        for seq in seqs:
+            for i in range(1, len(seq)):
+                graph[seq[i - 1]].add(seq[i])
+
+        return graph
+    
+    def get_indegrees(self, graph):
+        indegrees = {
+            node: 0
+            for node in graph
+        }
+        
+        for node in graph:
+            for neighbor in graph[node]:
+                indegrees[neighbor] += 1
+                
+        return indegrees
+        
+    def topological_sort(self, graph):
+        indegrees = self.get_indegrees(graph)
+        
+        queue = []
+        for node in graph:
+            if indegrees[node] == 0:
+                queue.append(node)
+        
+        topo_order = []
+        while queue:
+            if len(queue) > 1:
+                # there must exist more than one topo orders
+                return None
+                
+            node = queue.pop()
+            topo_order.append(node)
+            for neighbor in graph[node]:
+                indegrees[neighbor] -= 1
+                if indegrees[neighbor] == 0:
+                    queue.append(neighbor)
+                    
+        if len(topo_order) == len(graph):
+            return topo_order
+            
+        return None
+[[java]]
+public class Solution {
+    /**
+     * @param org: a permutation of the integers from 1 to n
+     * @param seqs: a list of sequences
+     * @return: true if it can be reconstructed only one or false
+     */
+    public boolean sequenceReconstruction(int[] org, int[][] seqs) {
+        Map<Integer, Set<Integer>> graph = buildGraph(seqs);
+        List<Integer> topoOrder = getTopoOrder(graph);
+        
+        if (topoOrder == null || topoOrder.size() != org.length) {
+            return false;
+        }
+        for (int i = 0; i < org.length; i++) {
+            if (org[i] != topoOrder.get(i)) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    private Map<Integer, Set<Integer>> buildGraph(int[][] seqs) {
+        Map<Integer, Set<Integer>> graph = new HashMap();
+        for (int[] seq : seqs) {
+            for (int i = 0; i < seq.length; i++) {
+                if (!graph.containsKey(seq[i])) {
+                    graph.put(seq[i], new HashSet<Integer>());
+                }
+            }
+        }
+        for (int[] seq : seqs) {
+            for (int i = 1; i < seq.length; i++) {
+                graph.get(seq[i - 1]).add(seq[i]);
+            }
+        }
+        return graph;
+    }
+    
+    private Map<Integer, Integer> getIndegrees(Map<Integer, Set<Integer>> graph) {
+        Map<Integer, Integer> indegrees = new HashMap();
+        for (Integer node : graph.keySet()) {
+            indegrees.put(node, 0);
+        }
+        for (Integer node : graph.keySet()) {
+            for (Integer neighbor : graph.get(node)) {
+                indegrees.put(neighbor, indegrees.get(neighbor) + 1);
+            }
+        }
+        return indegrees;
+    }
+    
+    private List<Integer> getTopoOrder(Map<Integer, Set<Integer>> graph) {
+        Map<Integer, Integer> indegrees = getIndegrees(graph);
+        Queue<Integer> queue = new LinkedList();
+        List<Integer> topoOrder = new ArrayList();
+        
+        for (Integer node : graph.keySet()) {
+            if (indegrees.get(node) == 0) {
+                queue.offer(node);
+                topoOrder.add(node);
+            }
+        }
+        
+        while (!queue.isEmpty()) {
+            if (queue.size() > 1) {
+                return null;
+            }
+            
+            Integer node = queue.poll();
+            for (Integer neighbor : graph.get(node)) {
+                indegrees.put(neighbor, indegrees.get(neighbor) - 1);
+                if (indegrees.get(neighbor) == 0) {
+                    queue.offer(neighbor);
+                    topoOrder.add(neighbor);
+                }
+            }
+        }
+        
+        if (graph.size() == topoOrder.size()) {
+            return topoOrder;
+        }
+        
+        return null;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/add-binary.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/add-binary.md"
new file mode 100644
index 0000000..6d02617
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/add-binary.md"
@@ -0,0 +1,90 @@
+# 二进制求和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/add-binary/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个二进制字符串，返回他们的和（用二进制表示）。
+ ### 样例说明
+ **样例 1：**
+```
+输入：
+a = "0", b = "0"
+输出：
+"0"
+```
+**样例 2：**
+```
+输入：
+a = "11", b = "1"
+输出：
+"100"
+```
+ ### 参考代码
+ Given two binary strings, return their sum (also a binary string).
+
+For example,
+a = "11"
+b = "1"
+Return "100".
+```java
+public class Solution {
+    public String addBinary(String a, String b) {
+        if(a.length() < b.length()){
+            String tmp = a;
+            a = b;
+            b = tmp;
+        }
+        
+        int pa = a.length()-1;
+        int pb = b.length()-1;
+        int carries = 0;
+        String rst = "";
+        
+        while(pb >= 0){
+            int sum = (int)(a.charAt(pa) - '0') + (int)(b.charAt(pb) - '0') + carries;
+            rst = String.valueOf(sum % 2) + rst;
+            carries = sum / 2;
+            pa --;
+            pb --;
+        }
+        
+        while(pa >= 0){
+            int sum = (int)(a.charAt(pa) - '0') + carries;
+            rst = String.valueOf(sum % 2) + rst;
+            carries = sum / 2;
+            pa --;
+        }       
+        
+        if (carries == 1)
+            rst = "1" + rst;
+        return rst;
+    }
+}
+
+
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param a a number
+     * @param b a number
+     * @return the result
+     */
+    public String addBinary(String a, String b) {
+        // Write your code here
+        String ans = "";
+
+        int carry = 0;
+        for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
+            int sum = carry;
+            sum += (i >= 0) ? a.charAt(i) - '0' : 0;
+            sum += (j >= 0) ? b.charAt(j) - '0' : 0;
+            ans = (sum % 2) + ans;
+            carry = sum / 2;
+        }
+        if (carry != 0) {
+            ans = carry + ans;
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/balanced-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/balanced-binary-tree.md"
new file mode 100644
index 0000000..cee5a4e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/balanced-binary-tree.md"
@@ -0,0 +1,81 @@
+# 平衡二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/balanced-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个二叉树,确定它是高度平衡的。对于这个问题,一棵高度平衡的二叉树的定义是：一棵二叉树中每个节点的两个子树的深度相差不会超过1。&nbsp;<br></p>
+ ### 样例说明
+ ```
+样例  1:
+	输入: tree = {1,2,3}
+	输出: true
+	
+	样例解释:
+	如下，是一个平衡的二叉树。
+		  1  
+		 / \                
+		2  3
+
+	
+样例  2:
+	输入: tree = {3,9,20,#,#,15,7}
+	输出: true
+	
+	样例解释:
+	如下，是一个平衡的二叉树。
+		  3  
+		 / \                
+		9  20                
+		  /  \                
+		 15   7 
+
+	
+样例  2:
+	输入: tree = {1,#,2,3,4}
+	输出: false
+	
+	样例解释:
+	如下，是一个不平衡的二叉树。1的左右子树高度差2
+		  1  
+		   \                
+		   2                
+		  /  \                
+		 3   4
+	
+```
+
+ ### 参考代码
+ Given a binary tree, determine if it is height-balanced.
+
+For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
+
+在树上做一次DFS，计算以每个点为根的子树高度。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root: The root of binary tree.
+    @return: True if this Binary tree is Balanced, or false.
+    """
+    def isBalanced(self, root):
+        balanced, _ = self.validate(root)
+        return balanced
+        
+    def validate(self, root):
+        if root is None:
+            return True, 0
+            
+        balanced, leftHeight = self.validate(root.left)
+        if not balanced:
+            return False, 0
+        balanced, rightHeight = self.validate(root.right)
+        if not balanced:
+            return False, 0
+            
+        return abs(leftHeight - rightHeight) <= 1, max(leftHeight, rightHeight) + 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-representation.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-representation.md"
new file mode 100644
index 0000000..56d4aac
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-representation.md"
@@ -0,0 +1,65 @@
+# 二进制表示
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-representation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数将其转换为二进制（均用字符串表示），如果这个数的小数部分不能在 32 个字符之内来精确地表示，则返回 `"ERROR"`。
+ ### 样例说明
+ 
+ ### 参考代码
+ 我们需要把整数和小数部分分离，整数部分按照短除法进行进制转换，小数部分按照$*2$看整数部分法进行进制转换，注意的是，如果乘32次都没有结束，直接返回ERROR
+```java
+public class Solution {
+    /**
+     *@param n: Given a decimal number that is passed in as a string
+     *@return: A string
+     */
+     
+    private String parseInteger(String str) {
+        int n = Integer.parseInt(str);
+        if (str.equals("") || str.equals("0")) {
+            return "0";
+        }
+        String binary = "";
+        while (n != 0) {
+            binary = Integer.toString(n % 2) + binary;
+            n = n / 2;
+        }
+        return binary;
+    }
+    
+    private String parseFloat(String str) {
+        double d = Double.parseDouble("0." + str);
+        String binary = "";
+        HashSet<Double> set = new HashSet<Double>();
+        while (d > 0) {
+            if (binary.length() > 32 || set.contains(d)) {
+                return "ERROR";
+            }
+            set.add(d);
+            d = d * 2;
+            if (d >= 1) {
+                binary = binary + "1";
+                d = d - 1;
+            } else {
+                binary = binary + "0";
+            }
+        }
+        return binary;
+    }
+    
+    public String binaryRepresentation(String n) {
+        if (n.indexOf('.') == -1) {
+            return parseInteger(n);
+        }
+        String[] params = n.split("\\.");
+        String flt = parseFloat(params[1]);
+        if (flt == "ERROR") {
+            return flt;
+        }
+        if (flt.equals("0") || flt.equals("")) {
+            return parseInteger(params[0]);
+        }
+        return parseInteger(params[0]) + "." + flt;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-search-tree-iterator.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-search-tree-iterator.md"
new file mode 100644
index 0000000..b65f59b
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-search-tree-iterator.md"
@@ -0,0 +1,89 @@
+# 二叉查找树迭代器
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-search-tree-iterator/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计实现一个带有下列属性的二叉查找树的迭代器：
+next()返回BST中下一个最小的元素
+- 元素按照递增的顺序被访问（比如中序遍历）
+- `next()`和`hasNext()`的询问操作要求**均摊**时间复杂度是O(*1*)
+ ### 样例说明
+ **样例 1:**
+
+```
+输入：{10,1,11,#,6,#,12}
+输出：[1, 6, 10, 11, 12]
+解释：
+二叉查找树如下 :
+  10
+  /\
+ 1 11
+  \  \
+   6  12
+可以返回二叉查找树的中序遍历 [1, 6, 10, 11, 12]
+```
+
+**样例 2:**
+
+``` 
+输入：{2,1,3}
+输出：[1,2,3]
+解释：
+二叉查找树如下 :
+  2
+ / \
+1   3
+可以返回二叉查找树的中序遍历 [1,2,3]
+```
+ ### 参考代码
+ 这是一个非常通用的利用 stack 进行 Binary Tree Iterator 的写法。
+
+stack 中保存一路走到当前节点的所有节点，stack.peek() 一直指向 iterator 指向的当前节点。
+因此判断有没有下一个，只需要判断 stack 是否为空
+获得下一个值，只需要返回 stack.peek() 的值，并将 stack 进行相应的变化，挪到下一个点。
+
+挪到下一个点的算法如下：
+
+1. 如果当前点存在右子树，那么就是右子树中“一路向西”最左边的那个点
+2. 如果当前点不存在右子树，则是走到当前点的路径中，第一个左拐的点
+
+访问所有节点用时O(n)，所以均摊下来访问每个节点的时间复杂度时O(1)
+```java
+public class BSTIterator {
+    private Stack<TreeNode> stack = new Stack<>();
+    
+    // @param root: The root of binary tree.
+    public BSTIterator(TreeNode root) {
+        while (root != null) {
+            stack.push(root);
+            root = root.left;
+        }
+    }
+
+    //@return: True if there has next node, or false
+    public boolean hasNext() {
+        return !stack.isEmpty();
+    }
+    
+    //@return: return next node
+    public TreeNode next() {
+        TreeNode curt = stack.peek();
+        TreeNode node = curt;
+        
+        // move to the next node
+        if (node.right == null) {
+            node = stack.pop();
+            while (!stack.isEmpty() && stack.peek().right == node) {
+                node = stack.pop();
+            }
+        } else {
+            node = node.right;
+            while (node != null) {
+                stack.push(node);
+                node = node.left;
+            }
+        }
+        
+        return curt;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/binary-search.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-search.md"
similarity index 100%
rename from "\351\242\230\350\247\243/binary-search.md"
rename to "\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-search.md"
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-flipping.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-flipping.md"
new file mode 100644
index 0000000..9500772
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-flipping.md"
@@ -0,0 +1,67 @@
+# 二叉树翻转
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-flipping/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，其中所有右节点要么是具有兄弟节点的叶节点(有一个共享相同父节点的左节点)或空白，将其倒置并将其转换为树，其中原来的右节点变为左叶子节点。返回新的根节点。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the new root
+     */
+    public TreeNode upsideDownBinaryTree(TreeNode root) {
+        // Write your code here     
+        if (root == null || root.left == null) {
+            return root;
+        }
+        TreeNode new_root = upsideDownBinaryTree(root.left);
+        root.left.left = root.right;
+        root.left.right = root;
+        root.right = null;
+        root.left = null;
+        return new_root;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the new root
+     */
+
+    TreeNode dfs(TreeNode cur) {
+        if (cur.left == null) {
+            return cur;
+        }
+        TreeNode newRoot = dfs(cur.left);
+        cur.left.right = cur;
+        cur.left.left = cur.right;
+        cur.left = null;            // important
+        cur.right = null;
+        return newRoot;
+    }
+
+    public TreeNode upsideDownBinaryTree(TreeNode root) {
+        // Write your code here
+        if (root == null) {
+            return null;
+        }
+        return dfs(root);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-inorder-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-inorder-traversal.md"
new file mode 100644
index 0000000..722c465
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-inorder-traversal.md"
@@ -0,0 +1,70 @@
+# 二叉树的中序遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-inorder-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树,返回其中序遍历</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3}
+输出：[2,1,3]
+解释：
+   1
+  / \
+ 2   3
+它将被序列化为{1,2,3}
+中序遍历
+```
+**样例 2:**
+```
+输入：{1,#,2,3}
+输出：[1,3,2]
+解释：
+1
+ \
+  2
+ /
+3
+它将被序列化为{1,#,2,3}
+中序遍历
+```
+ ### 参考代码
+ 考点：
+* 二叉树的中序遍历
+* 搜索
+
+题解：按照左根右的次序遍历二叉树，搜索左子树，存入当前点，搜索右子树。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of binary tree.
+     * @return: Inorder in ArrayList which contains node values.
+     */
+    public ArrayList<Integer> inorderTraversal(TreeNode root) {
+        Stack<TreeNode> stack = new Stack<TreeNode>();
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        TreeNode curt = root;
+        while (curt != null || !stack.empty()) {
+            while (curt != null) {
+                stack.add(curt);
+                curt = curt.left;
+            }
+            curt = stack.pop();
+            result.add(curt.val);
+            curt = curt.right;
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-leaf-sum.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-leaf-sum.md"
new file mode 100644
index 0000000..7808d97
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-leaf-sum.md"
@@ -0,0 +1,53 @@
+# 二叉树叶子节点之和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-leaf-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 计算二叉树的叶子节点之和
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,4}
+输出：7
+解释：
+    1
+   / \
+  2   3
+ /
+4
+3+4=7
+```
+**样例 2:**
+```
+输入：{1,#,3}
+输出：3
+解释：
+    1
+      \
+       3
+```
+ ### 参考代码
+ 递归求和即可
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root the root of the binary tree
+    # @return {int} an integer
+    def leafSum(self, root):
+        # Write your code here
+        p = []
+        self.dfs(root, p)
+        return sum(p)
+    def dfs(self, root, p):
+        if root is None:
+            return
+        if root.left is None and root.right is None:
+            p.append(root.val)
+        self.dfs(root.left, p)
+        self.dfs(root.right, p)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-leaves-order-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-leaves-order-traversal.md"
new file mode 100644
index 0000000..b418649
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-leaves-order-traversal.md"
@@ -0,0 +1,78 @@
+# 二叉树叶子顺序遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-leaves-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，像这样收集树节点：收集并移除所有叶子，重复，直到树为空。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return collect and remove all leaves
+     */
+    public List<List<Integer>> findLeaves(TreeNode root) {
+        // Write your code here
+        List<List<Integer>> results = new ArrayList<List<Integer>>();
+        dfs(root, results);
+        return results;
+    }
+
+    int dfs(TreeNode root, List<List<Integer>> results) {
+        if (root == null) {
+            return 0;
+        }
+        int level = Math.max(dfs(root.left, results), dfs(root.right, results)) + 1;
+        int size = results.size();
+        if (level > size) {
+            results.add(new ArrayList<Integer>());
+        }
+        results.get(level - 1).add(root.val);
+        return level;
+    }   
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return collect and remove all leaves
+     */
+
+    int dfs(TreeNode cur, Map<Integer, List<Integer>> depth) {
+        if (cur == null) {
+            return 0;
+        }
+        int d = Math.max(dfs(cur.left, depth), dfs(cur.right, depth)) + 1;
+
+        depth.putIfAbsent(d, new ArrayList<>());
+        depth.get(d).add(cur.val);
+        return d;
+    }
+
+    public List<List<Integer>> findLeaves(TreeNode root) {
+        // Write your code here
+        List<List<Integer>> ans = new ArrayList<>();
+
+        Map<Integer, List<Integer>> depth = new HashMap<>();
+        int max_depth = dfs(root, depth);
+
+        for (int i = 1; i <= max_depth; i++) {
+            ans.add(depth.get(i));
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-level-order-traversal-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-level-order-traversal-ii.md"
new file mode 100644
index 0000000..70cefe9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-level-order-traversal-ii.md"
@@ -0,0 +1,83 @@
+# 二叉树的层次遍历 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-level-order-traversal-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树，返回其节点值从底向上的层次序遍历（按从叶节点所在层到根节点所在的层遍历，然后逐层从左往右遍历）</p>
+ ### 样例说明
+ 例1:
+```
+输入:
+{1,2,3}
+输出:
+[[2,3],[1]]
+解释:
+    1
+   / \
+  2   3
+它将被序列化为 {1,2,3}
+层次遍历
+```
+例2:
+```
+输入:
+{3,9,20,#,#,15,7}
+输出:
+[[15,7],[9,20],[3]]
+解释:
+    3
+   / \
+  9  20
+    /  \
+   15   7
+它将被序列化为 {3,9,20,#,#,15,7}
+层次遍历
+```
+
+ ### 参考代码
+ 利用队列层序遍历整棵树，最后翻转一下即可。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of binary tree.
+     * @return: buttom-up level order a list of lists of integer
+     */
+    public List<List<Integer>> levelOrderBottom(TreeNode root) {
+        List<List<Integer>> result = new ArrayList<>();
+        if (root == null) {
+            return result;
+        }
+        Queue<TreeNode> queue = new LinkedList<TreeNode>();
+        queue.offer(root);
+        
+        while (!queue.isEmpty()) {
+            int size = queue.size();
+            List<Integer> level = new ArrayList<>();
+            for (int i = 0; i < size; i++) {
+                TreeNode head = queue.poll();
+                level.add(head.val);
+                if (head.left != null) {
+                    queue.offer(head.left);
+                }
+                if (head.right != null) {
+                    queue.offer(head.right);
+                }
+            }
+            result.add(level);
+        }
+        
+        Collections.reverse(result);
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-level-order-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-level-order-traversal.md"
new file mode 100644
index 0000000..a215eb6
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-level-order-traversal.md"
@@ -0,0 +1,67 @@
+# 二叉树的层次遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-level-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一棵二叉树，返回其节点值的层次遍历（逐层从左往右访问）
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3}
+输出：[[1],[2,3]]
+解释：
+   1
+  / \
+ 2   3
+它将被序列化为{1,2,3}
+层次遍历
+```
+**样例 2:**
+```
+输入：{1,#,2,3}
+输出：[[1],[2],[3]]
+解释：
+1
+ \
+  2
+ /
+3
+它将被序列化为{1,#,2,3}
+层次遍历
+```
+
+ ### 参考代码
+ 用一个队列的方法。
+```python
+from collections import deque
+
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param root: The root of binary tree.
+    @return: Level order a list of lists of integer
+    """
+    def levelOrder(self, root):
+        if root is None:
+            return []
+            
+        queue = deque([root])
+        result = []
+        while queue:
+            level = []
+            for _ in range(len(queue)):
+                node = queue.popleft()
+                level.append(node.val)
+                if node.left:
+                    queue.append(node.left)
+                if node.right:
+                    queue.append(node.right)
+            result.append(level)
+        return result
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-level-sum.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-level-sum.md"
new file mode 100644
index 0000000..9f058ee
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-level-sum.md"
@@ -0,0 +1,64 @@
+# 二叉树的某层节点之和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-level-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一棵二叉树和一个整数代表树的某层深度。
+计算二叉树的某层节点之和。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,4,5,6,7,#,#,8,#,#,#,#,9},2
+输出：5 
+解释：
+     1
+   /   \
+  2     3
+ / \   / \
+4   5 6   7
+   /       \
+  8         9
+2+3=5
+```
+**样例 2:**
+```
+输入：{1,2,3,4,5,6,7,#,#,8,#,#,#,#,9},3
+输出：22
+解释：
+     1
+   /   \
+  2     3
+ / \   / \
+4   5 6   7
+   /       \
+  8         9
+4+5+6+7=22
+```
+ ### 参考代码
+ 递归遍历树，答案加上对应层的值即可
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root the root of the binary tree
+    # @param {int} level the depth of the target level
+    # @return {int} an integer
+    def levelSum(self, root, level):
+        # Write your code here
+        p = []
+        self.dfs(root, p, 1, level)
+        return sum(p)
+    def dfs(self, root, p, dep, level):
+        if root is None:
+            return
+        if dep == level:
+            p.append(root.val)
+            return
+
+        self.dfs(root.left, p, dep+1, level)
+        self.dfs(root.right, p, dep+1, level)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-longest-consecutive-sequence-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-longest-consecutive-sequence-ii.md"
new file mode 100644
index 0000000..4e74d6b
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-longest-consecutive-sequence-ii.md"
@@ -0,0 +1,94 @@
+# 二叉树的最长连续子序列 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-longest-consecutive-sequence-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一棵二叉树，找到最长连续序列(单调且相邻节点值相差为1)路径的长度(节点数)。
+路径起点跟终点可以为二叉树的任意节点。
+ ### 样例说明
+ **例1:**
+```
+输入:
+{1,2,0,3}
+输出:
+4
+解释:
+    1
+   / \
+  2   0
+ /
+3
+0-1-2-3
+```
+
+**例2:**
+```
+输入:
+{3,2,2}
+输出:
+2
+解释:
+    3
+   / \
+  2   2
+2-3
+```
+
+
+ ### 参考代码
+ ```java
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+class ResultType {
+    public int max_length, max_down, max_up;
+    ResultType(int len, int down, int up) {
+        max_length = len;
+        max_down = down;
+        max_up = up;    
+    }
+}
+
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive2(TreeNode root) {
+        // Write your code here
+        return helper(root).max_length;
+    }
+    
+    ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, 0, 0);
+        }
+
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        int down = 0, up = 0;
+        if (root.left != null && root.left.val + 1 == root.val)
+            down = Math.max(down, left.max_down + 1);
+
+        if (root.left != null && root.left.val - 1 == root.val)
+            up = Math.max(up, left.max_up + 1);
+
+        if (root.right != null && root.right.val + 1 == root.val)
+            down = Math.max(down, right.max_down + 1);
+
+        if (root.right != null && root.right.val - 1 == root.val)
+            up = Math.max(up, right.max_up + 1);
+
+        int len = down + 1 + up;
+        len = Math.max(len, Math.max(left.max_length, right.max_length));
+
+        return new ResultType(len, down, up);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-longest-consecutive-sequence-iii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-longest-consecutive-sequence-iii.md"
new file mode 100644
index 0000000..43f671f
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-longest-consecutive-sequence-iii.md"
@@ -0,0 +1,83 @@
+# 二叉树的最长连续子序列III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-longest-consecutive-sequence-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 这题是 `二叉树的最长连续子序列II` 的后续。
+给出一棵 `k叉树`，找到最长连续序列路径的长度.
+路径的开头跟结尾可以是树的任意节点。
+ ### 样例说明
+ 例1:
+```
+输入:
+5<6<7<>,5<>,8<>>,4<3<>,5<>,31<>>>
+输出:
+5
+解释:
+     5
+   /   \
+  6     4
+ /|\   /|\
+7 5 8 3 5 31
+
+返回 5, // 3-4-5-6-7
+```
+
+例2:
+```
+输入:
+1<>
+输出:
+1
+```
+
+
+ ### 参考代码
+ 从根结点开始dfs，每次搜相邻的相差1的结点，跟新即可
+```java
+/**
+ * Definition for a multi tree node.
+ * public class MultiTreeNode {
+ *     int val;
+ *     List<TreeNode> children;
+ *     MultiTreeNode(int x) { val = x; }
+ * }
+ */
+ class ResultType {
+    public int max_len, max_down, max_up;
+    ResultType(int len, int down, int up) {
+        max_len = len;
+        max_down = down;
+        max_up = up;    
+    }
+}
+
+public class Solution {
+    /**
+     * @param root the root of k-ary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive3(MultiTreeNode root) {
+        // Write your code here
+        return helper(root).max_len;
+    }
+    
+    ResultType helper(MultiTreeNode root) {
+        if (root == null) {
+            return new ResultType(0, 0, 0);
+        }
+
+        int down = 0, up = 0, max_len = 1;
+        for (MultiTreeNode node : root.children) {
+            ResultType type = helper(node);
+            if (node.val + 1 == root.val)
+                down = Math.max(down, type.max_down + 1);
+            if (node.val - 1 == root.val)
+                up = Math.max(up, type.max_up + 1);
+            max_len = Math.max(max_len, type.max_len);
+        }
+
+        max_len = Math.max(down + 1 + up, max_len);
+        return new ResultType(max_len, down, up);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-longest-consecutive-sequence.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-longest-consecutive-sequence.md"
new file mode 100644
index 0000000..807f962
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-longest-consecutive-sequence.md"
@@ -0,0 +1,161 @@
+# 二叉树最长连续序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-longest-consecutive-sequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，找到最长连续路径的长度。
+这条路径是指 任何的节点序列中的起始节点到树中的任一节点都必须遵循 父-子 联系。最长的连续路径必须是从父亲节点到孩子节点（`不能逆序`）。
+
+ ### 样例说明
+ **样例1:**
+
+```
+输入:
+{1,#,3,2,4,#,#,#,5}
+输出:3
+说明:
+这棵树如图所示
+   1
+    \
+     3
+    / \
+   2   4
+        \
+         5
+最长连续序列是3-4-5，所以返回3.
+```
+
+**样例2:**
+
+```
+输入:
+{2,#,3,2,#,1,#}
+输出:2
+说明:
+这棵树如图所示：
+   2
+    \
+     3
+    / 
+   2    
+  / 
+ 1
+最长连续序列是2-3，而不是3-2-1，所以返回2.
+```
+
+
+ ### 参考代码
+ dfs搜索即可
+```java
+// version 1: Traverse + Divide Conquer
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive(TreeNode root) {
+        return helper(root, null, 0);
+    }
+    
+    private int helper(TreeNode root, TreeNode parent, int lengthWithoutRoot) {
+        if (root == null) {
+            return 0;
+        }
+        
+        int length = (parent != null && parent.val + 1 == root.val)
+            ? lengthWithoutRoot + 1
+            : 1;
+        int left = helper(root.left, root, length);
+        int right = helper(root.right, root, length);
+        return Math.max(length, Math.max(left, right));
+    }
+}
+
+// version 2: Another Traverse + Divide Conquer 
+public class Solution {
+    private int longest;
+    
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive(TreeNode root) {
+        longest = 0;
+        helper(root);
+        return longest;
+    }
+    
+    private int helper(TreeNode root) {
+        if (root == null) {
+            return 0;
+        }
+        
+        int left = helper(root.left);
+        int right = helper(root.right);
+        
+        int subtreeLongest = 1; // at least we have root
+        if (root.left != null && root.val + 1 == root.left.val) {
+            subtreeLongest = Math.max(subtreeLongest, left + 1);
+        }
+        if (root.right != null && root.val + 1 == root.right.val) {
+            subtreeLongest = Math.max(subtreeLongest, right + 1);
+        }
+        
+        if (subtreeLongest > longest) {
+            longest = subtreeLongest;
+        }
+        return subtreeLongest;
+    }
+}
+
+// version 3: Divide Conquer
+public class Solution {
+    private class ResultType {
+        int maxInSubtree;
+        int maxFromRoot;
+        public ResultType(int maxInSubtree, int maxFromRoot) {
+            this.maxInSubtree = maxInSubtree;
+            this.maxFromRoot = maxFromRoot;
+        }
+    }
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive(TreeNode root) {
+        return helper(root).maxInSubtree;
+    }
+    
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, 0);
+        }
+        
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+        
+        // 1 is the root itself.
+        ResultType result = new ResultType(0, 1);
+        
+        if (root.left != null && root.val + 1 == root.left.val) {
+            result.maxFromRoot = Math.max(
+                result.maxFromRoot,
+                left.maxFromRoot + 1
+            );
+        }
+        
+        if (root.right != null && root.val + 1 == root.right.val) {
+            result.maxFromRoot = Math.max(
+                result.maxFromRoot,
+                right.maxFromRoot + 1
+            );
+        }
+        
+        result.maxInSubtree = Math.max(
+            result.maxFromRoot,
+            Math.max(left.maxInSubtree, right.maxInSubtree)
+        );
+        
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-maximum-node.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-maximum-node.md"
new file mode 100644
index 0000000..0841bb5
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-maximum-node.md"
@@ -0,0 +1,67 @@
+# 二叉树的最大节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-maximum-node/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在二叉树中寻找值最大的节点并返回。
+ ### 样例说明
+ **样例1:**
+
+```
+输入:
+{1,-5,3,1,2,-4,-5}
+输出: 3
+说明:
+这棵树如下所示：
+     1
+   /   \
+ -5     3
+ / \   /  \
+1   2 -4  -5
+```
+
+**样例 2**
+
+```plain
+输入:
+{10,-5,2,0,3,-4,-5}
+输出: 10
+说明:
+这棵树如下所示：
+     10
+   /   \
+ -5     2
+ / \   /  \
+0   3 -4  -5 
+```
+
+
+ ### 参考代码
+ 树上基本遍历
+```java
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the max ndoe
+     */
+    public TreeNode maxNode(TreeNode root) {
+        // Write your code here
+        if (root == null)
+            return root;
+
+        TreeNode left = maxNode(root.left);
+        TreeNode right = maxNode(root.right);
+        return max(root, max(left, right));
+    }
+
+    TreeNode max(TreeNode a, TreeNode b) {
+        if (a == null)
+            return b;
+        if (b == null)
+            return a;
+        if (a.val > b.val) {
+            return a;
+        }
+        return b;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-maximum-path-sum-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-maximum-path-sum-ii.md"
new file mode 100644
index 0000000..691a9cb
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-maximum-path-sum-ii.md"
@@ -0,0 +1,57 @@
+# 二叉树的最大路径和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-maximum-path-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，找出从根节点出发的路径中，和最大的一条。
+
+这条路径可以在任何二叉树中的节点结束，但是必须包含至少一个点（也就是根了）。
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,2,3}
+输出: 4
+解释: 
+    1
+   / \
+  2   3
+1+3=4
+```
+
+**样例 2:**
+
+```
+输入: {1,-1,-1}
+输出: 1
+解释:
+    1
+   / \
+  -1 -1 
+```
+ ### 参考代码
+ 如果从动态规划的角度思考, 可以是这样的:
+
+- 状态: f[i] 表示从节点i往下走得到的最大路径和
+- 状态转移方程: f[i] = max{f[lc[i]], f[rc[i]], 0} + val[i]
+
+不过这道题目是二叉树, 比经典的数字三角形要简单, 无需记忆化/定义额外空间储存答案.
+
+一次递归遍历整棵二叉树即可.
+```java
+public class Solution {
+    /**
+     * @param root the root of binary tree.
+     * @return an integer
+     */
+    public int maxPathSum2(TreeNode root) {
+        if (root == null) {
+            return Integer.MIN_VALUE;
+        }
+
+        int left = maxPathSum2(root.left);
+        int right = maxPathSum2(root.right);
+        return root.val + Math.max(0, Math.max(left, right));
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-maximum-path-sum.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-maximum-path-sum.md"
new file mode 100644
index 0000000..e6280bc
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-maximum-path-sum.md"
@@ -0,0 +1,108 @@
+# 二叉树中的最大路径和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-maximum-path-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <span style="line-height: 30px;"><font color="#000000">给出一棵二叉树，</font></span><font color="#000000"><span style="line-height: 30px;">寻找一条路径使其路径和最大，路径可以在任一节点中开始和结束（路径和为两个节点之间所在路径上的节点权值之和）</span></font><br>
+ ### 样例说明
+ ```
+样例 1:
+	输入:  给定一棵树（只有一个节点）:
+	2
+	输出：2
+	
+样例 2:
+	输入:  给定一棵树：
+
+      1
+     / \
+    2   3
+		
+	输出: 6
+
+	
+```
+ ### 参考代码
+ Given a binary tree, find the maximum path sum.&nbsp;<div>The path may start and end at any node in the tree.&nbsp;</div><div><br></div><div>For example:&nbsp;</div><div>Given the below binary tree,&nbsp;</div><div>&nbsp; 1&nbsp;</div><div>&nbsp;/ &nbsp;\&nbsp;</div><div>2 &nbsp; 3&nbsp;</div><div><span style="line-height: 1.42857143;">Return 6.</span><br></div><div><div><br></div><div>详细题解请见九章算法微博：<a href="http://weibo.com/3948019741/BBY7gwi89" target="_blank">http://weibo.com/3948019741/BBY7gwi89</a></div></div>
+
+分治法。
+需要考虑的是，子树中最大的路不一定必过根节点。所以要记录single Path的值。
+见代码注释。
+```java
+public class Solution {
+    private class ResultType {
+        // singlePath: 从root往下走到任意点的最大路径，这条路径可以不包含任何点
+        // maxPath: 从树中任意到任意点的最大路径，这条路径至少包含一个点
+        int singlePath, maxPath; 
+        ResultType(int singlePath, int maxPath) {
+            this.singlePath = singlePath;
+            this.maxPath = maxPath;
+        }
+    }
+
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, Integer.MIN_VALUE);
+        }
+        // Divide
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        // Conquer
+        int singlePath = Math.max(left.singlePath, right.singlePath) + root.val;
+        singlePath = Math.max(singlePath, 0);
+
+        int maxPath = Math.max(left.maxPath, right.maxPath);
+        maxPath = Math.max(maxPath, left.singlePath + right.singlePath + root.val);
+
+        return new ResultType(singlePath, maxPath);
+    }
+
+    public int maxPathSum(TreeNode root) {
+        ResultType result = helper(root);
+        return result.maxPath;
+    }
+}
+
+
+// Version 2:
+// SinglePath也定义为，至少包含一个点。
+public class Solution {
+    /**
+     * @param root: The root of binary tree.
+     * @return: An integer.
+     */
+    private class ResultType {
+        int singlePath, maxPath;
+        ResultType(int singlePath, int maxPath) {
+            this.singlePath = singlePath;
+            this.maxPath = maxPath;
+        }
+    }
+
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(Integer.MIN_VALUE, Integer.MIN_VALUE);
+        }
+        // Divide
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        // Conquer
+        int singlePath =
+            Math.max(0, Math.max(left.singlePath, right.singlePath)) + root.val;
+
+        int maxPath = Math.max(left.maxPath, right.maxPath);
+        maxPath = Math.max(maxPath,
+                           Math.max(left.singlePath, 0) + 
+                           Math.max(right.singlePath, 0) + root.val);
+
+        return new ResultType(singlePath, maxPath);
+    }
+
+    public int maxPathSum(TreeNode root) {
+        ResultType result = helper(root);
+        return result.maxPath;
+    }
+
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-path-sum-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-path-sum-ii.md"
new file mode 100644
index 0000000..fa5ff2d
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-path-sum-ii.md"
@@ -0,0 +1,44 @@
+# 二叉树的路径和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-path-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树和一个目标值，设计一个算法找到二叉树上的和为该目标值的所有路径。路径可以从任何节点出发和结束，但是需要是一条一直往下走的路线。也就是说，路径上的节点的层级是逐个递增的。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @param {int} target an integer
+    # @return {int[][]} all valid paths
+    def binaryTreePathSum2(self, root, target):
+        # Write your code here
+        result = []
+        path = []
+        if root is None:
+            return result
+        self.dfs(root, path, result, 0,  target)
+        return result
+
+    def dfs(self, root, path, result, l, target):
+        if root is None:
+            return
+        path.append(root.val)
+        tmp = target
+        for i in xrange(l , -1, -1):
+            tmp -= path[i]
+            if tmp == 0:
+                result.append(path[i:])
+
+        self.dfs(root.left, path, result, l + 1, target)
+        self.dfs(root.right, path, result, l + 1, target)
+
+        path.pop()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-path-sum-iii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-path-sum-iii.md"
new file mode 100644
index 0000000..5ba4597
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-path-sum-iii.md"
@@ -0,0 +1,94 @@
+# 二叉树的路径和 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-path-sum-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树和一个目标值，找到二叉树上所有的和为该目标值的路径。路径可以从二叉树的任意节点出发，任意节点结束。
+
+ ### 样例说明
+ **样例 1:**
+
+```plain
+输入：{1,2,3,4},6
+输出：[[2, 4],[2, 1, 3],[3, 1, 2],[4, 2]]
+解释：
+该树如下：
+    1
+   / \
+  2   3
+ /
+4
+```
+
+**样例 2:**
+
+```plain
+输入：{1,2,3,4},3
+输出：[[1,2],[2,1],[3]]
+解释：
+该树如下：
+    1
+   / \
+  2   3
+ /
+4
+```
+ ### 参考代码
+ 使用dfs搜索的办法进行查找，可以进行相关的嵌套，从而达到结果
+```java
+/**
+ * Definition of ParentTreeNode:
+ * 
+ * class ParentTreeNode {
+ *     public int val;
+ *     public ParentTreeNode parent, left, right;
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @param target an integer
+     * @return all valid paths
+     */
+    public List<List<Integer>> binaryTreePathSum3(ParentTreeNode root, int target) {
+        // Write your code here
+        List<List<Integer>> results = new ArrayList<List<Integer>>();
+        dfs(root, target, results);
+        return results;
+    }
+    
+    public void dfs(ParentTreeNode root, int target, List<List<Integer>> results) {
+        if (root == null)
+            return;
+
+        List<Integer> path = new ArrayList<Integer>();
+        findSum(root, null, target, path, results);
+
+        dfs(root.left, target, results);
+        dfs(root.right, target, results);
+    }
+
+    public void findSum(ParentTreeNode root, ParentTreeNode father, int target,
+                 List<Integer> path, List<List<Integer>> results) {
+        path.add(root.val);
+        target -= root.val;
+        
+        if (target == 0) {
+            ArrayList<Integer> tmp = new ArrayList<Integer>();
+            Collections.addAll(tmp,  new  Integer[path.size()]); 
+            Collections.copy(tmp, path); 
+            results.add(tmp);
+        }
+
+        if (root.parent != null && root.parent != father)
+            findSum(root.parent, root, target, path, results);
+
+        if (root.left != null && root.left  != father)
+            findSum(root.left, root, target, path, results);
+
+        if (root.right != null && root.right != father)
+            findSum(root.right, root, target, path, results);
+
+        path.remove(path.size() - 1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-path-sum.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-path-sum.md"
new file mode 100644
index 0000000..60beeae
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-path-sum.md"
@@ -0,0 +1,80 @@
+# 二叉树的路径和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-path-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，找出所有路径中各节点相加总和等于给定 `目标值` 的路径。
+
+一个有效的路径，指的是从根节点到叶节点的路径。
+ ### 样例说明
+ **样例1:**
+
+```plain
+输入:
+{1,2,4,2,3}
+5
+输出: [[1, 2, 2],[1, 4]]
+说明:
+这棵树如下图所示：
+	     1
+	    / \
+	   2   4
+	  / \
+	 2   3
+对于目标总和为5，很显然1 + 2 + 2 = 1 + 4 = 5
+```
+
+**样例2:**
+
+```plain
+输入:
+{1,2,4,2,3}
+3
+输出: []
+说明:
+这棵树如下图所示：
+	     1
+	    / \
+	   2   4
+	  / \
+	 2   3
+注意到题目要求我们寻找从根节点到叶子节点的路径。
+1 + 2 + 2 = 5, 1 + 2 + 3 = 6, 1 + 4 = 5 
+这里没有合法的路径满足和等于3.
+```
+
+
+ ### 参考代码
+ ```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @param {int} target an integer
+    # @return {int[][]} all valid paths
+    def binaryTreePathSum(self, root, target):
+        # Write your code here
+        result = []
+        path = []
+        self.dfs(root, path, result, 0,  target)
+
+        return result
+
+    def dfs(self, root, path, result, len, target):
+        if root is None:
+            return
+        path.append(root.val)
+        len += root.val
+
+        if root.left is None and root.right is None and len == target:
+            result.append(path[:])
+
+        self.dfs(root.left, path, result, len, target)
+        self.dfs(root.right, path, result, len, target)
+
+        path.pop()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-paths.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-paths.md"
new file mode 100644
index 0000000..2757ca9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-paths.md"
@@ -0,0 +1,59 @@
+# 二叉树的所有路径
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-paths/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，找出从根节点到叶子节点的所有路径。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,#,5}
+输出：["1->2->5","1->3"]
+解释：
+   1
+ /   \
+2     3
+ \
+  5
+```
+**样例 2:**
+```
+输入：{1,2}
+输出：["1->2"]
+解释：
+   1
+ /   
+2     
+```
+ ### 参考代码
+ 使用分治算法(Divide Conquer)
+```java
+// version 1: Divide Conquer
+public class Solution {
+    /**
+     * @param root the root of the binary tree
+     * @return all root-to-leaf paths
+     */
+    public List<String> binaryTreePaths(TreeNode root) {
+        List<String> paths = new ArrayList<>();
+        if (root == null) {
+            return paths;
+        }
+        
+        List<String> leftPaths = binaryTreePaths(root.left);
+        List<String> rightPaths = binaryTreePaths(root.right);
+        for (String path : leftPaths) {
+            paths.add(root.val + "->" + path);
+        }
+        for (String path : rightPaths) {
+            paths.add(root.val + "->" + path);
+        }
+        
+        // root is a leaf
+        if (paths.size() == 0) {
+            paths.add("" + root.val);
+        }
+        
+        return paths;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-postorder-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-postorder-traversal.md"
new file mode 100644
index 0000000..7b92ec9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-postorder-traversal.md"
@@ -0,0 +1,86 @@
+# 二叉树的后序遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-postorder-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树，返回其节点值的后序遍历。</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3}
+输出：[2,3,1]
+解释： 
+   1
+  / \
+ 2   3
+它将被序列化为{1,2,3}
+后序遍历
+```
+**样例 2:**
+```
+输入：{1,#,2,3}
+输出：[3,2,1]
+解释： 
+1
+ \
+  2
+ /
+3
+它将被序列化为{1,#,2,3}
+后序遍历
+```
+ ### 参考代码
+ Given a binary tree, return the postorder traversal of its nodes' values.&nbsp;<div>For example:&nbsp;</div><div>Given binary tree {1,#,2,3},<div><br></div><div>1<div>&nbsp; \&nbsp;</div><div>&nbsp; &nbsp;2&nbsp;</div><div>&nbsp; /&nbsp;</div><div>&nbsp;3&nbsp;</div><div><br></div><div>return [3,2,1].&nbsp;</div><div><br></div><div>&nbsp;Note: Recursive solution is trivial, could you do it iteratively?</div></div></div><div><br></div><div>九章算法微博：<a href="http://weibo.com/3948019741/Bq8XobZFD" target="_blank">面试搞定二叉树大总结</a></div>
+考点：
+* 二叉树的后序遍历
+题解：
+使用栈进行二叉树后序遍历，首先对左子树进行遍历压入栈中，直至左子树为空，然后访问右子树。故每个节点会被访问两次，当节点被第二次访问时，该节点出栈。
+```java
+//Recursive
+public ArrayList<Integer> postorderTraversal(TreeNode root) {
+    ArrayList<Integer> result = new ArrayList<Integer>();
+
+    if (root == null) {
+        return result;
+    }
+
+    result.addAll(postorderTraversal(root.left));
+    result.addAll(postorderTraversal(root.right));
+    result.add(root.val);
+
+    return result;   
+}
+
+//Iterative
+public ArrayList<Integer> postorderTraversal(TreeNode root) {
+    ArrayList<Integer> result = new ArrayList<Integer>();
+    Stack<TreeNode> stack = new Stack<TreeNode>();
+    TreeNode prev = null; // previously traversed node
+    TreeNode curr = root;
+
+    if (root == null) {
+        return result;
+    }
+
+    stack.push(root);
+    while (!stack.empty()) {
+        curr = stack.peek();
+        if (prev == null || prev.left == curr || prev.right == curr) { // traverse down the tree
+            if (curr.left != null) {
+                stack.push(curr.left);
+            } else if (curr.right != null) {
+                stack.push(curr.right);
+            }
+        } else if (curr.left == prev) { // traverse up the tree from the left
+            if (curr.right != null) {
+                stack.push(curr.right);
+            }
+        } else { // traverse up the tree from the right
+            result.add(curr.val);
+            stack.pop();
+        }
+        prev = curr;
+    }
+
+    return result;
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-preorder-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-preorder-traversal.md"
new file mode 100644
index 0000000..7493978
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-preorder-traversal.md"
@@ -0,0 +1,113 @@
+# 二叉树的前序遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-preorder-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树，返回其节点值的前序遍历。</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3}
+输出：[1,2,3]
+解释：
+   1
+  / \
+ 2   3
+它将被序列化为{1,2,3}
+前序遍历
+```
+**样例 2:**
+```
+输入：{1,#,2,3}
+输出：[1,2,3]
+解释：
+1
+ \
+  2
+ /
+3
+它将被序列化为{1,#,2,3}
+前序遍历
+```
+ ### 参考代码
+ Given a binary tree, return the preorder traversal of its nodes' values.&nbsp;<div><br></div><div>For example:&nbsp;</div><div>Given binary tree {1,#,2,3},&nbsp;</div><div><br></div><div>&nbsp;1&nbsp;</div><div>&nbsp; &nbsp;\&nbsp;</div><div>&nbsp; &nbsp; &nbsp;2&nbsp;</div><div>&nbsp; &nbsp; /&nbsp;</div><div>&nbsp; 3&nbsp;</div><div>return [1,2,3].&nbsp;</div><div><br></div><div>&nbsp;Note: Recursive solution is trivial, could you do it iteratively?</div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;"><br></span></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博：</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/BzQahxewZ" target="_blank">http://weibo.com/3948019741/BzQahxewZ</a></span></font><br></div>
+考点：
+* 二叉树的前序遍历
+
+题解：
+非递归方式实现前序遍历时，首先存入当前节点值，然后先将右儿子压入栈中，再将左儿子压入栈中。对栈中元素遍历访问。
+```java
+Version 0: Non-Recursion (Recommend)
+/**
+ * Definition for binary tree
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    public List<Integer> preorderTraversal(TreeNode root) {
+        Stack<TreeNode> stack = new Stack<TreeNode>();
+        List<Integer> preorder = new ArrayList<Integer>();
+        
+        if (root == null) {
+            return preorder;
+        }
+        
+        stack.push(root);
+        while (!stack.empty()) {
+            TreeNode node = stack.pop();
+            preorder.add(node.val);
+            if (node.right != null) {
+                stack.push(node.right);
+            }
+            if (node.left != null) {
+                stack.push(node.left);
+            }
+        }
+        
+        return preorder;
+    }
+}
+
+//Version 1: Traverse
+public class Solution {
+    public ArrayList<Integer> preorderTraversal(TreeNode root) {
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        traverse(root, result);
+        return result;
+    }
+    // 把root为跟的preorder加入result里面
+    private void traverse(TreeNode root, ArrayList<Integer> result) {
+        if (root == null) {
+            return;
+        }
+
+        result.add(root.val);
+        traverse(root.left, result);
+        traverse(root.right, result);
+    }
+}
+
+//Version 2: Divide & Conquer
+public class Solution {
+    public ArrayList<Integer> preorderTraversal(TreeNode root) {
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        // null or leaf
+        if (root == null) {
+            return result;
+        }
+
+        // Divide
+        ArrayList<Integer> left = preorderTraversal(root.left);
+        ArrayList<Integer> right = preorderTraversal(root.right);
+
+        // Conquer
+        result.add(root.val);
+        result.addAll(left);
+        result.addAll(right);
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-right-side-view.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-right-side-view.md"
new file mode 100644
index 0000000..c796c9e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-right-side-view.md"
@@ -0,0 +1,68 @@
+# 二叉树的右视图
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-right-side-view/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一棵二叉树，想象自己站在它的右侧，按照从顶部到底部的顺序，返回从右侧所能看到的节点值。
+ ### 样例说明
+ **样例1**
+
+```
+输入: {1,2,3,#,5,#,4}
+输出: [1,3,4]
+说明:
+   1            
+ /   \
+2     3         
+ \     \
+  5     4       
+```
+
+**样例2**
+
+```plain
+输入: {1,2,3}
+输出: [1,3]
+说明:
+   1            
+ /   \
+2     3        
+```
+
+
+ ### 参考代码
+ dfs暴力即可。
+```java
+/**
+ * Definition for binary tree
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    private void dfs(HashMap<Integer, Integer> depthToValue, TreeNode node, int depth) {
+        if (node == null) {
+            return;
+        }
+        
+        depthToValue.put(depth, node.val);
+        dfs(depthToValue, node.left, depth + 1);
+        dfs(depthToValue, node.right, depth + 1);
+    }
+    
+    public List<Integer> rightSideView(TreeNode root) {
+        HashMap<Integer, Integer> depthToValue = new HashMap<Integer, Integer>();
+        dfs(depthToValue, root, 1);
+        
+        int depth = 1;
+        List<Integer> result = new ArrayList<Integer>();
+        while (depthToValue.containsKey(depth)) {
+            result.add(depthToValue.get(depth));
+            depth++;
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-serialization.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-serialization.md"
new file mode 100644
index 0000000..63e41f2
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-serialization.md"
@@ -0,0 +1,101 @@
+# 二叉树的序列化和反序列化
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-serialization/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个算法，并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”，读取文件后重建同样的二叉树被称为“反序列化”。
+
+如何反序列化或序列化二叉树是没有限制的，你只需要确保可以将二叉树序列化为一个字符串，并且可以将字符串反序列化为原来的树结构。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+class Solution {
+    /**
+     * This method will be invoked first, you should design your own algorithm 
+     * to serialize a binary tree which denote by a root node to a string which
+     * can be easily deserialized by your own "deserialize" method later.
+     */
+    public String serialize(TreeNode root) {
+        if (root == null) {
+            return "{}";
+        }
+
+        ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
+        queue.add(root);
+
+        for (int i = 0; i < queue.size(); i++) {
+            TreeNode node = queue.get(i);
+            if (node == null) {
+                continue;
+            }
+            queue.add(node.left);
+            queue.add(node.right);
+        }
+
+        while (queue.get(queue.size() - 1) == null) {
+            queue.remove(queue.size() - 1);
+        }
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append(queue.get(0).val);
+        for (int i = 1; i < queue.size(); i++) {
+            if (queue.get(i) == null) {
+                sb.append(",#");
+            } else {
+                sb.append(",");
+                sb.append(queue.get(i).val);
+            }
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+    
+    /**
+     * This method will be invoked second, the argument data is what exactly
+     * you serialized at method "serialize", that means the data is not given by
+     * system, it's given by your own serialize method. So the format of data is
+     * designed by yourself, and deserialize it here as you serialize it in 
+     * "serialize" method.
+     */
+    public TreeNode deserialize(String data) {
+        if (data.equals("{}")) {
+            return null;
+        }
+        String[] vals = data.substring(1, data.length() - 1).split(",");
+        ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
+        TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
+        queue.add(root);
+        int index = 0;
+        boolean isLeftChild = true;
+        for (int i = 1; i < vals.length; i++) {
+            if (!vals[i].equals("#")) {
+                TreeNode node = new TreeNode(Integer.parseInt(vals[i]));
+                if (isLeftChild) {
+                    queue.get(index).left = node;
+                } else {
+                    queue.get(index).right = node;
+                }
+                queue.add(node);
+            }
+            if (!isLeftChild) {
+                index++;
+            }
+            isLeftChild = !isLeftChild;
+        }
+        return root;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-vertical-order-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-vertical-order-traversal.md"
new file mode 100644
index 0000000..8092d04
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-vertical-order-traversal.md"
@@ -0,0 +1,134 @@
+# 二叉树垂直遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-vertical-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定二叉树，返回其节点值的垂直遍历顺序。 (即逐列从上到下)。
+如果两个节点在同一行和同一列中，则顺序应 **从左到右**。
+ ### 样例说明
+ **样例1**
+```
+输入： {3,9,20,#,#,15,7}
+输出： [[9],[3,15],[20],[7]]
+解释：
+   3
+  /\
+ /  \
+ 9  20
+    /\
+   /  \
+  15   7
+```
+**样例2**
+```
+输入： {3,9,8,4,0,1,7}
+输出：[[4],[9],[3,0,1],[8],[7]]
+解释：
+     3
+    /\
+   /  \
+   9   8
+  /\  /\
+ /  \/  \
+ 4  01   7
+```
+ ### 参考代码
+ 对于一棵树，我们设其根节点的位置为0。
+对于任一非叶子节点，若其位置为x，设其左儿子的位置为x-1，右儿子位置为x+1。
+按照以上规则bfs遍历整棵树统计所有节点的位置，然后按位置从小到大输出所有节点。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the vertical order traversal
+     */
+    public List<List<Integer>> verticalOrder(TreeNode root) {
+        // Write your code here
+        List<List<Integer>> results = new ArrayList<>();
+        if (root == null) {
+            return results;
+        }
+        Map<Integer, List<Integer>> map = new TreeMap<Integer, List<Integer>>();
+        Queue<Integer> qCol = new LinkedList<>();
+        Queue<TreeNode> queue = new LinkedList<>();
+        queue.offer(root);
+        qCol.offer(0);
+        
+        while(!queue.isEmpty()) {
+            TreeNode curr = queue.poll();
+            int col = qCol.poll();
+            if(!map.containsKey(col)) {
+                map.put(col, new ArrayList<Integer>(Arrays.asList(curr.val)));
+            } else {
+                map.get(col).add(curr.val);
+            }
+            if(curr.left != null) {
+                queue.offer(curr.left);
+                qCol.offer(col - 1);
+            }
+            if(curr.right != null) {
+                queue.offer(curr.right);
+                qCol.offer(col + 1);
+            }
+        }
+        for(int n : map.keySet()) {
+            results.add(map.get(n));
+        }
+        return results;
+    }   
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the vertical order traversal
+     */
+    public List<List<Integer>> verticalOrder(TreeNode root) {
+        // Write your code here
+        List<List<Integer>> ans = new ArrayList<>();
+        if (root == null) {
+            return ans;
+        }
+
+        Map<Integer, List<Integer>> hash = new HashMap<>();
+        Queue<Integer> qCol = new LinkedList<>();
+        Queue<TreeNode> qNode = new LinkedList<>();
+
+        qCol.offer(0);
+        qNode.offer(root);
+
+        while (!qCol.isEmpty()) {                      // bfs
+            int c = qCol.poll();
+            TreeNode node = qNode.poll();
+
+            hash.putIfAbsent(c, new ArrayList<>());
+            hash.get(c).add(node.val);
+
+            if (node.left != null) {
+                qCol.offer(c - 1);
+                qNode.offer(node.left);
+            }
+            if (node.right != null) {
+                qCol.offer(c + 1);
+                qNode.offer(node.right);
+            }
+        }
+
+        for (int i = Collections.min(hash.keySet()); i <= Collections.max(hash.keySet()); i++) {
+            ans.add(hash.get(i));
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-zigzag-level-order-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-zigzag-level-order-traversal.md"
new file mode 100644
index 0000000..fd40965
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-tree-zigzag-level-order-traversal.md"
@@ -0,0 +1,83 @@
+# 二叉树的锯齿形层次遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-zigzag-level-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树，返回其节点值的锯齿形层次遍历（先从左往右，下一层再从右往左，层与层之间交替进行）&nbsp;</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入:{1,2,3}
+输出:[[1],[3,2]]
+解释:
+    1
+   / \
+  2   3
+它将被序列化为 {1,2,3}
+```
+**样例 2:**
+```
+输入:{3,9,20,#,#,15,7}
+输出:[[3],[20,9],[15,7]]
+解释:
+    3
+   / \
+  9  20
+    /  \
+   15   7
+它将被序列化为 {3,9,20,#,#,15,7}
+```
+
+ ### 参考代码
+ 层序遍历完之后，看层数，偶数层reverse一下即可。
+```java
+public class Solution {
+    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
+        List<List<Integer>> result = new ArrayList<List<Integer>>();
+
+        if (root == null) {
+            return result;
+        }
+
+        Stack<TreeNode> currLevel = new Stack<TreeNode>();
+        Stack<TreeNode> nextLevel = new Stack<TreeNode>();
+        Stack<TreeNode> tmp;
+        
+        currLevel.push(root);
+        boolean normalOrder = true;
+
+        while (!currLevel.isEmpty()) {
+            ArrayList<Integer> currLevelResult = new ArrayList<Integer>();
+
+            while (!currLevel.isEmpty()) {
+                TreeNode node = currLevel.pop();
+                currLevelResult.add(node.val);
+
+                if (normalOrder) {
+                    if (node.left != null) {
+                        nextLevel.push(node.left);
+                    }
+                    if (node.right != null) {
+                        nextLevel.push(node.right);
+                    }
+                } else {
+                    if (node.right != null) {
+                        nextLevel.push(node.right);
+                    }
+                    if (node.left != null) {
+                        nextLevel.push(node.left);
+                    }
+                }
+            }
+
+            result.add(currLevelResult);
+            tmp = currLevel;
+            currLevel = nextLevel;
+            nextLevel = tmp;
+            normalOrder = !normalOrder;
+        }
+
+        return result;
+
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-watch.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-watch.md"
new file mode 100644
index 0000000..947712f
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/binary-watch.md"
@@ -0,0 +1,55 @@
+# 二进制手表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-watch/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给了一个二进制显示时间的手表和一个非负整数 `n`, `n` 代表在给定时间表上 `1` 的数量, 返回所有可能的时间
+ ### 样例说明
+ **样例1**
+```
+输入： 1
+输出： ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"]
+```
+**样例2**
+```
+输入： 2
+输出： ["0:03","0:05","0:06","0:09","0:10","0:12","0:17","0:18","0:20","0:24","0:33","0:34","0:36","0:40","0:48","10:00","1:01","1:02","1:04","1:08","1:16","1:32","2:01","2:02","2:04","2:08","2:16","2:32","3:00","4:01","4:02","4:04","4:08","4:16","4:32","5:00","6:00","8:01","8:02","8:04","8:08","8:16","8:32","9:00"]
+```
+ ### 参考代码
+ 遍历所有1的数量为num的二进制数，找出符合条件的数即可。
+```java
+public class Solution {
+    public List<String> readBinaryWatch(int num) {
+        ArrayList<String> ans = new ArrayList<String>();
+        ArrayList<ArrayList<Integer>> hour = new ArrayList<ArrayList<Integer>>();
+        ArrayList<ArrayList<Integer>> min = new ArrayList<ArrayList<Integer>>();
+    for(int i = 0; i < 4; i++) {
+        hour.add(new ArrayList<Integer>());
+    }
+    for(int i = 0; i < 6; i++) {
+        min.add(new ArrayList<Integer>());
+    }
+        for(int i = 0; i < 12; i++) {
+            int n = Integer.bitCount(i);
+            hour.get(n).add(i);
+        }
+        for(int i = 0; i < 60; i++) {
+            min.add(new ArrayList<Integer>());
+            int n = Integer.bitCount(i);
+            min.get(n).add(i);
+        }
+        for(int i = 0; i <= num && i < 4; i++) {
+            for(int h = 0; h < hour.get(i).size(); h++) {
+                for(int m = 0; m < min.get(num - i).size() && num - i < 6; m++) {
+                    String string = hour.get(i).get(h).toString() + ":";
+                    if(min.get(num - i).get(m) < 10) {
+                        string += "0";
+                    }
+                    string += min.get(num - i).get(m).toString();
+                    ans.add(string);
+                }
+            }
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/boundary-of-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/boundary-of-binary-tree.md"
new file mode 100644
index 0000000..1452242
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/boundary-of-binary-tree.md"
@@ -0,0 +1,117 @@
+# 二叉树边界
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/boundary-of-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，从根开始返回其**逆时针**方向的边界值。边界包括左边界、叶和右边界，没有重复的节点。
+
+**左边界**的定义为从根到**最左边**节点的路径。**右边界**的定义为从根到**最右边**的节点的路径。
+
+如果根没有左子树或右子树，那么根本身就是最左边或者最右边的节点。注意，这个定义只适用于二叉树的根节点，而不适用于任何子树。
+
+而当根有左子树时，最左边的节点是：你以有先访问左子节点的方式遍历二叉树时，第一个碰到的叶子节点。最右边的节点的定义类似，方向相反。
+
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,#,2,3,4}
+输出: [1,3,4,2]
+解释:
+  1
+   \
+    2
+   / \
+  3   4 
+  根没有左子树，所以根本身是左边界。
+  叶节点为节点3和节点4。
+  右边界是节点1 2 4。注意逆时针方向意味着你应该输出反向右边界。
+  所以用逆时针顺序排列它们没有重复，我们得到[1,3,4,2]
+```
+
+**样例 2:**
+
+```
+输入: {1,2,3,4,5,6,#,#,#,7,8,9,10}
+输出: [1,2,4,7,8,9,10,6,3]
+解释: 
+          1
+     /          \
+    2            3
+   / \          / 
+  4   5        6   
+     / \      / \
+    7   8    9  10  
+  左边的边界是节点1 2 4。(4最左边的节点)
+  叶节点是节点4 7 8 9 10。
+  右边界是节点1 3 6 10。(10是最右边的节点)。
+  所以逆时针顺序排列，我们得到[1,2,4,7,8,9,10,6,3]
+```
+ ### 参考代码
+ 面试中更加容易被面试官接受的版本。
+虽然使用 DFS 但是没有使用任何的 Recursion。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param root: a TreeNode
+    @return: a list of integer
+    """
+    def boundaryOfBinaryTree(self, root):
+        if root is None:
+            return []
+            
+        left_boundary = self.find_left_boundary(root.left)
+        leaves = self.find_leaves(root)
+        right_boundary = self.find_right_boundary(root.right)
+        
+        if left_boundary and leaves and left_boundary[-1] == leaves[0]:
+            leaves = leaves[1:]
+        if leaves and right_boundary and leaves[-1] == right_boundary[-1]:
+            leaves = leaves[:-1]
+        return [root.val] + left_boundary + leaves + list(reversed(right_boundary))
+
+    def find_leaves(self, root):
+        stack = [root]
+        leaves = []
+        while stack:
+            node = stack.pop()
+            if not node.left and not node.right:
+                leaves.append(node.val)
+            if node.right:
+                stack.append(node.right)
+            if node.left:
+                stack.append(node.left)
+        return leaves
+        
+    def find_left_boundary(self, root):
+        left_boundary = []
+        while root is not None:
+            left_boundary.append(root.val)
+            if root.left:
+                root = root.left
+            elif root.right:
+                root = root.right
+            else:
+                break
+        return left_boundary
+        
+    def find_right_boundary(self, root):
+        right_boundary = []
+        while root is not None:
+            right_boundary.append(root.val)
+            if root.right:
+                root = root.right
+            elif root.left:
+                root = root.left
+            else:
+                break
+        return right_boundary
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/classical-binary-search.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/classical-binary-search.md"
new file mode 100644
index 0000000..1301a08
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/classical-binary-search.md"
@@ -0,0 +1,84 @@
+# 经典二分查找问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/classical-binary-search/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个排序数组中找一个数，返回该数出现的任意位置，如果不存在，返回 `-1`。
+
+ ### 样例说明
+ **样例 1：**
+```
+输入：nums = [1,2,2,4,5,5], target = 2
+输出：1 或者 2
+```
+**样例 2：**
+```
+输入：nums = [1,2,2,4,5,5], target = 6
+输出：-1
+```
+ ### 参考代码
+ ```java
+// version 1: with jiuzhang template
+public class Solution {
+    /**
+     * @param A an integer array sorted in ascending order
+     * @param target an integer
+     * @return an integer
+     */
+    public int findPosition(int[] nums, int target) {
+        if (nums == null || nums.length == 0) {
+            return -1;
+        }
+        
+        int start = 0, end = nums.length - 1;
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (nums[mid] == target) {
+                return mid;
+            } else if (nums[mid] < target) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        
+        if (nums[start] == target) {
+            return start;
+        }
+        if (nums[end] == target) {
+            return end;
+        }
+        return -1;
+    }
+}
+
+// version 2: without jiuzhang template
+public class Solution {
+    /**
+     * @param A an integer array sorted in ascending order
+     * @param target an integer
+     * @return an integer
+     */
+    public int findPosition(int[] nums, int target) {
+        if (nums == null || nums.length == 0) {
+            return -1;
+        }
+        
+        int start = 0, end = nums.length - 1;
+        while (start < end) {
+            int mid = start + (end - start) / 2;
+            if (nums[mid] == target) {
+                return mid;
+            } else if (nums[mid] < target) {
+                start = mid + 1;
+            } else {
+                end = mid - 1;
+            }
+        }
+        
+        if (nums[start] == target) {
+            return start;
+        }
+        return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/clone-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/clone-binary-tree.md"
new file mode 100644
index 0000000..61bf058
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/clone-binary-tree.md"
@@ -0,0 +1,65 @@
+# 克隆二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/clone-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 深度复制一个二叉树。
+
+给定一个二叉树，返回一个他的 **克隆品** 。
+ ### 样例说明
+ **样例1:**
+
+```plain
+输入: {1,2,3,4,5}
+输出: {1,2,3,4,5}
+解释：
+样例中二叉树如下所示:
+     1
+   /  \
+  2    3
+ / \
+4   5
+```
+
+**样例2:**
+
+```plain
+输入: {1,2,3}
+输出: {1,2,3}
+解释：
+样例中二叉树如下所示:
+   1
+ /  \
+2    3
+```
+
+
+ ### 参考代码
+ 这题采用dfs（深度优先搜索）的方法，从根节点开始，一步步的去复制这一颗树。每次去复制他的左节点和右节点即可。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of binary tree
+     * @return root of new tree
+     */
+    public TreeNode cloneTree(TreeNode root) {
+        // Write your code here
+        if (root == null)
+            return null; //搜到了空节点，直接返回
+        TreeNode clone_root = new TreeNode(root.val); //创造当前深度的“根”
+        clone_root.left = cloneTree(root.left);  //左子树
+        clone_root.right = cloneTree(root.right); //右子树
+        return clone_root;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/closest-binary-search-tree-value-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/closest-binary-search-tree-value-ii.md"
new file mode 100644
index 0000000..ba08da2
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/closest-binary-search-tree-value-ii.md"
@@ -0,0 +1,138 @@
+# 二叉搜索树中最接近的值 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/closest-binary-search-tree-value-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一棵非空二叉搜索树以及一个target值，找到 BST 中最接近给定值的 `k` 个数。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+{1}
+0.000000
+1
+输出:
+[1]
+解释：
+二叉树 {1}，表示如下的树结构：
+ 1
+```
+
+**样例 2:**
+```
+输入:
+{3,1,4,#,2}
+0.275000
+2
+输出:
+[1,2]
+解释：
+二叉树 {3,1,4,#,2}，表示如下的树结构：
+  3
+ /  \
+1    4
+ \
+  2
+```
+ ### 参考代码
+ 最优算法，时间复杂度 $O(k + logn)$，空间复杂度 $O(logn)$
+
+实现如下的子函数：
+
+1. getStack() => 在假装插入 target 的时候，看看一路走过的节点都是哪些，放到 stack 里，用于 iterate
+2. moveUpper(stack) => 根据 stack，挪动到 next node
+3. moveLower(stack) => 根据 stack, 挪动到 prev node
+
+有了这些函数之后，就可以把整个树当作一个数组一样来处理，只不过每次 i++ 的时候要用 moveUpper，i--的时候要用 moveLower
+```
+[[java]]
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+class Solution {
+    public List<Integer> closestKValues(TreeNode root, double target, int k) {
+        List<Integer> values = new ArrayList<>();
+        
+        if (k == 0 || root == null) {
+            return values;
+        }
+        
+        Stack<TreeNode> lowerStack = getStack(root, target);
+        Stack<TreeNode> upperStack = new Stack<>();
+        upperStack.addAll(lowerStack);
+        if (target < lowerStack.peek().val) {
+            moveLower(lowerStack);
+        } else {
+            moveUpper(upperStack);
+        }
+        
+        for (int i = 0; i < k; i++) {
+            if (lowerStack.isEmpty() ||
+                   !upperStack.isEmpty() && target - lowerStack.peek().val > upperStack.peek().val - target) {
+                values.add(upperStack.peek().val);
+                moveUpper(upperStack);
+            } else {
+                values.add(lowerStack.peek().val);
+                moveLower(lowerStack);
+            }
+        }
+
+        return values;
+    }
+    
+    private Stack<TreeNode> getStack(TreeNode root, double target) {
+        Stack<TreeNode> stack = new Stack<>();
+        
+        while (root != null) {
+            stack.push(root);
+            
+            if (target < root.val) {
+                root = root.left;
+            } else {
+                root = root.right;
+            }
+        }
+        
+        return stack;
+    }
+    
+    public void moveUpper(Stack<TreeNode> stack) {
+        TreeNode node = stack.peek();
+        if (node.right == null) {
+            node = stack.pop();
+            while (!stack.isEmpty() && stack.peek().right == node) {
+                node = stack.pop();
+            }
+            return;
+        }
+        
+        node = node.right;
+        while (node != null) {
+            stack.push(node);
+            node = node.left;
+        }
+    }
+    
+    public void moveLower(Stack<TreeNode> stack) {
+        TreeNode node = stack.peek();
+        if (node.left == null) {
+            node = stack.pop();
+            while (!stack.isEmpty() && stack.peek().left == node) {
+                node = stack.pop();
+            }
+            return;
+        }
+        
+        node = node.left;
+        while (node != null) {
+            stack.push(node);
+            node = node.right;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/closest-binary-search-tree-value.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/closest-binary-search-tree-value.md"
new file mode 100644
index 0000000..4b8cdb9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/closest-binary-search-tree-value.md"
@@ -0,0 +1,114 @@
+# 二叉搜索树中最接近的值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/closest-binary-search-tree-value/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵非空二叉搜索树以及一个target值，找到在BST中最接近给定值的节点值
+ ### 样例说明
+ **样例1**
+
+```
+输入: root = {5,4,9,2,#,8,10} and target = 6.124780
+输出: 5
+解释：
+二叉树 {5,4,9,2,#,8,10}，表示如下的树结构：
+        5
+       / \
+     4    9
+    /    / \
+   2    8  10
+```
+
+
+
+**样例2**
+
+```
+输入: root = {3,2,4,1} and target = 4.142857
+输出: 4
+解释：
+二叉树 {3,2,4,1}，表示如下的树结构：
+     3
+    / \
+  2    4
+ /
+1
+```
+ ### 参考代码
+ 算法很简单，求出 lowerBound 和 upperBound。即 < target 的最大值和 >= target 的最小值。
+然后在两者之中去比较谁更接近，然后返回即可。
+
+时间复杂度为 $O(h)$，注意如果你使用 in-order traversal 的化，时间复杂度会是 $o(n)$ 并不是最优的。另外复杂度也不是 $O(logn)$ 因为BST 并不保证树高是 logn 的。
+```java
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+class Solution {
+    public int closestValue(TreeNode root, double target) {
+        if (root == null) {
+            return 0;
+        }
+        
+        TreeNode lowerNode = lowerBound(root, target);
+        TreeNode upperNode = upperBound(root, target);
+        
+        if (lowerNode == null) {
+            return upperNode.val;
+        }
+        
+        if (upperNode == null) {
+            return lowerNode.val;
+        }
+        
+        if (target - lowerNode.val > upperNode.val - target) {
+            return upperNode.val;
+        }
+        
+        return lowerNode.val;
+    }
+    
+    // find the node with the largest value that smaller than target
+    private TreeNode lowerBound(TreeNode root, double target) {
+        if (root == null) {
+            return null;
+        }
+        
+        if (target <= root.val) {
+            return lowerBound(root.left, target);
+        }
+        
+        // root.val < target
+        TreeNode lowerNode = lowerBound(root.right, target);
+        if (lowerNode != null) {
+            return lowerNode;
+        }
+        
+        return root;
+    }
+    
+    // find the node with the smallest value that larger than or equal to target
+    private TreeNode upperBound(TreeNode root, double target) {
+        if (root == null) {
+            return null;
+        }
+        
+        if (root.val < target) {
+            return upperBound(root.right, target);
+        }
+        
+        // root.val >= target
+        TreeNode upperNode = upperBound(root.left, target);
+        if (upperNode != null) {
+            return upperNode;
+        }
+        
+        return root;
+    }
+    
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/complete-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/complete-binary-tree.md"
new file mode 100644
index 0000000..30d21ef
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/complete-binary-tree.md"
@@ -0,0 +1,98 @@
+# 完全二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/complete-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 判断一个二叉树是否是完全二叉树
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,4}
+输出：true
+解释：
+        1
+       / \
+      2   3
+     /
+    4
+
+是完全二叉树。
+```
+**样例 2:**
+```
+输入：{1,2,3,#,4}
+输出：false
+解释：
+        1
+       / \
+      2   3
+       \
+        4
+
+不是完全二叉树
+```
+ ### 参考代码
+ 根据每个结点的左子树和右子树的深度和是否满判断该结点的子树的类型
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+ 
+class ResultType {
+    public int depth;
+    public boolean isFull, isComplete;
+    ResultType(int depth, boolean isFull, boolean isComplete) {
+        this.depth = depth;
+        this.isFull = isFull;
+        this.isComplete = isComplete;
+    }
+}
+
+public class Solution {
+    /**
+     * @param root, the root of binary tree.
+     * @return true if it is a complete binary tree, or false.
+     */
+    public boolean isComplete(TreeNode root) {
+        ResultType result = helper(root);
+        return result.isComplete;
+    }
+    
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, true, true);
+        }
+        
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+        if (!left.isComplete) {
+            return new ResultType(-1, false, false);
+        }
+        
+        // depth is the same, left should be full and right should be complete
+        if (left.depth == right.depth) {
+            if (!left.isFull || !right.isComplete) {
+                return new ResultType(-1, false, false);
+            }
+            return new ResultType(left.depth + 1, right.isFull, true);
+        }
+        
+        // left.depth = right.depth + 1, left should be complete and right should be full
+        if (left.depth == right.depth + 1) {
+            if (!left.isComplete || !right.isFull) {
+                return new ResultType(-1, false, false);
+            }
+            return new ResultType(left.depth + 1, false, true);
+        }
+        
+        return new ResultType(-1, false, false);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/construct-binary-tree-from-inorder-and-postorder-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/construct-binary-tree-from-inorder-and-postorder-traversal.md"
new file mode 100644
index 0000000..ea7c8bd
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/construct-binary-tree-from-inorder-and-postorder-traversal.md"
@@ -0,0 +1,74 @@
+# 中序遍历和后序遍历树构造二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/construct-binary-tree-from-inorder-and-postorder-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>根据中序遍历和后序遍历树构造二叉树</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：[],[]
+输出：{}
+解释：
+二叉树为空
+```
+**样例 2:**
+```
+输入：[1,2,3],[1,3,2]
+输出：{2,1,3}
+解释：
+二叉树如下
+  2
+ / \
+1   3
+```
+
+
+ ### 参考代码
+ 根据当前后续序列的最后一个结点，在对应的中序遍历中找到位置，然后相同的方法，递归左右子树即可。
+```cpp
+#include <vector>
+#include "lintcode.h"
+#include <algorithm>
+using namespace std;
+
+/**
+ * Definition of TreeNode:
+ * class TreeNode {
+ * public:
+ *     int val;
+ *     TreeNode *left, *right;
+ *     TreeNode(int val) {
+ *         this->val = val;
+ *         this->left = this->right = NULL;
+ *     }
+ * }
+ */
+ 
+
+class Solution {
+    /**
+     *@param inorder : A list of integers that inorder traversal of a tree
+     *@param postorder : A list of integers that postorder traversal of a tree
+     *@return : Root of a tree
+     */
+public:
+    typedef vector<int>::iterator Iter;
+    TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
+        // write your code here
+        if (inorder.size() == 0)
+            return NULL;
+        return buildTreeRecur(inorder.begin(), inorder.end(), postorder.begin(), 
+        postorder.end());
+    }
+    TreeNode *buildTreeRecur(Iter istart, Iter iend, Iter pstart, Iter pend)
+    {
+        if(istart == iend)return NULL;
+        int rootval = *(pend-1);
+        Iter iterroot = find(istart, iend, rootval);
+        TreeNode *res = new TreeNode(rootval);
+        res->left = buildTreeRecur(istart, iterroot, pstart, pstart+(iterroot-istart));
+        res->right = buildTreeRecur(iterroot+1, iend, pstart+(iterroot-istart), pend-1);
+        return res;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/construct-binary-tree-from-preorder-and-inorder-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/construct-binary-tree-from-preorder-and-inorder-traversal.md"
new file mode 100644
index 0000000..c377348
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/construct-binary-tree-from-preorder-and-inorder-traversal.md"
@@ -0,0 +1,70 @@
+# 前序遍历和中序遍历树构造二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/construct-binary-tree-from-preorder-and-inorder-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 根据前序遍历和中序遍历树构造二叉树.
+ ### 样例说明
+ **样例 1:**
+```
+输入：[],[]
+输出：{}
+解释：
+二叉树为空
+```
+**样例 2:**
+```
+输入：[2,1,3],[1,2,3]
+输出：{2,1,3}
+解释：
+二叉树如下
+  2
+ / \
+1   3
+```
+
+ ### 参考代码
+ Given preorder and inorder traversal of a tree, construct the binary tree.
+
+Note:
+You may assume that duplicates do not exist in the tree.
+
+前序的第一个为根，在中序中找到根的位置。
+中序中根的左右两边即为左右子树的中序遍历。同时可知左子树的大小size-left。
+前序中根接下来的size-left个是左子树的前序遍历。
+由此可以递归处理左右子树。
+```java
+public class Solution {
+    private int findPosition(int[] arr, int start, int end, int key) {
+        int i;
+        for (i = start; i <= end; i++) {
+            if (arr[i] == key) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private TreeNode myBuildTree(int[] inorder, int instart, int inend,
+            int[] preorder, int prestart, int preend) {
+        if (instart > inend) {
+            return null;
+        }
+
+        TreeNode root = new TreeNode(preorder[prestart]);
+        int position = findPosition(inorder, instart, inend, preorder[prestart]);
+
+        root.left = myBuildTree(inorder, instart, position - 1,
+                preorder, prestart + 1, prestart + position - instart);
+        root.right = myBuildTree(inorder, position + 1, inend,
+                preorder, position - inend + preend + 1, preend);
+        return root;
+    }
+
+    public TreeNode buildTree(int[] preorder, int[] inorder) {
+        if (inorder.length != preorder.length) {
+            return null;
+        }
+        return myBuildTree(inorder, 0, inorder.length - 1, preorder, 0, preorder.length - 1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-binary-search-tree-to-doubly-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-binary-search-tree-to-doubly-linked-list.md"
new file mode 100644
index 0000000..44401c9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-binary-search-tree-to-doubly-linked-list.md"
@@ -0,0 +1,86 @@
+# 将二叉查找树转换成双链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-binary-search-tree-to-doubly-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一个二叉查找树按照中序遍历转换成双向链表。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ * Definition for Doubly-ListNode.
+ * public class DoublyListNode {
+ *     int val;
+ *     DoublyListNode next, prev;
+ *     DoublyListNode(int val) {
+ *         this.val = val;
+ *         this.next = this.prev = null;
+ *     }
+ * }
+ */ 
+ 
+class ResultType {
+    DoublyListNode first, last;
+    
+    public ResultType(DoublyListNode first, DoublyListNode last) {
+        this.first = first;
+        this.last = last;
+    }
+}
+
+public class Solution {
+    /**
+     * @param root: The root of tree
+     * @return: the head of doubly list node
+     */
+    public DoublyListNode bstToDoublyList(TreeNode root) {  
+        if (root == null) {
+            return null;
+        }
+        
+        ResultType result = helper(root);
+        return result.first;
+    }
+    
+    //中序遍历函数 
+    public ResultType helper(TreeNode root) {  
+        if (root == null) {
+            return null;
+        }
+        
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+        DoublyListNode node = new DoublyListNode(root.val);
+        
+        ResultType result = new ResultType(null, null);
+        
+        //构造单链表
+        if (left == null) {
+            result.first = node;
+        } else {
+            result.first = left.first;
+            left.last.next = node;
+            node.prev = left.last;
+        }
+        
+        if (right == null) {
+            result.last = node;
+        } else {
+            result.last = right.last;
+            right.first.prev = node;
+            node.next = right.first;
+        }
+        
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-binary-tree-to-linked-lists-by-depth.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-binary-tree-to-linked-lists-by-depth.md"
new file mode 100644
index 0000000..8373b33
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-binary-tree-to-linked-lists-by-depth.md"
@@ -0,0 +1,124 @@
+# 将二叉树按照层级转化为链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-binary-tree-to-linked-lists-by-depth/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，设计一个算法为每一层的节点建立一个链表。也就是说，如果一棵二叉树有 `D` 层，那么你需要创建 `D` 条链表。
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,2,3,4}
+输出: [1->null,2->3->null,4->null]
+解释: 
+        1
+       / \
+      2   3
+     /
+    4
+```
+
+**样例 2:**
+
+```
+输入: {1,#,2,3}
+输出: [1->null,2->null,3->null]
+解释: 
+    1
+     \
+      2
+     /
+    3
+```
+ ### 参考代码
+ 考点：
+* 搜索遍历
+
+题解：采用基本的bfs搜索实现层序遍历即可。分别使用DFS和BFS两种解法解决这个问题。时间复杂度都是O(n)。
+```python
+# BFS 解法
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+Definition for singly-linked list.
+class ListNode:
+    def __init__(self, x):
+        self.val = x
+        self.next = None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @return {ListNode[]} a lists of linked list
+    def binaryTreeToLists(self, root):
+        result = []
+        if root is None:
+            return result
+            
+        import Queue
+        queue = Queue.Queue()
+        
+        queue.put(root)
+        
+        dummy = ListNode(0)
+        
+        lastNode = None
+        
+        while not queue.empty():
+            dummy.next = None
+            lastNode = dummy
+            size = queue.qsize()
+            for i in xrange(size):
+                head = queue.get()
+                lastNode.next = ListNode(head.val)
+                lastNode = lastNode.next
+
+                if head.left is not None:
+                    queue.put(head.left)
+                if head.right is not None:
+                    queue.put(head.right)
+        
+            result.append(dummy.next)
+        
+        return result
+    
+
+
+# DFS 解法
+
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+Definition for singly-linked list.
+class ListNode:
+    def __init__(self, x):
+        self.val = x
+        self.next = None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @return {ListNode[]} a lists of linked list
+    def binaryTreeToLists(self, root):
+        # Write your code here
+        result = []
+        self.dfs(root, 1, result)
+        return result
+
+    def dfs(self, root, depth, result):
+        if root is None:
+            return
+        node = ListNode(root.val)
+        if len(result) < depth:
+            result.append(node)
+        else:
+            node.next = result[depth-1]
+            result[depth-1] = node
+        
+        self.dfs(root.right, depth + 1, result)
+        self.dfs(root.left, depth + 1, result)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-bst-to-greater-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-bst-to-greater-tree.md"
new file mode 100644
index 0000000..56c31c4
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-bst-to-greater-tree.md"
@@ -0,0 +1,100 @@
+# 把二叉搜索树转化成更大的树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-bst-to-greater-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定二叉搜索树(BST)，将其转换为更大的树，使原始BST上每个节点的值都更改为在原始树中大于等于该节点值的节点值之和(包括该节点)。
+ ### 样例说明
+ **样例1:**
+
+```
+输入 : {5,2,13}
+              5
+            /   \
+           2     13
+输出 : {18,20,13}
+             18
+            /   \
+          20     13
+```
+
+**样例2:**
+
+```
+输入 : {5,3,15}
+              5
+            /   \
+           3     15
+输出 : {20,23,15}
+             20
+            /   \
+          23     15
+```
+
+
+ ### 参考代码
+ 从右子树开始递归，每次加上右子树的和，再递归左子树即可。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the new root
+     */
+    public int sum = 0;
+
+    void helper(TreeNode root){
+        if (root == null) {
+            return;
+        }
+        if (root.right != null) {
+            helper(root.right);
+        }
+        
+        root.val = (sum += root.val);
+        if (root.left != null) {
+            helper(root.left);
+        }
+    }
+
+    public TreeNode convertBST(TreeNode root) {
+        // Write your code here
+        helper(root);
+        return root;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the new root
+     */
+    int sum = 0;
+
+    void dfs(TreeNode cur) {
+        if (cur == null) {
+            return;
+        }
+        dfs(cur.right);
+        sum += cur.val;
+        cur.val = sum;
+        dfs(cur.left);
+    }
+
+    public TreeNode convertBST(TreeNode root) {
+        // Write your code here
+        dfs(root);
+        return root;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-sorted-array-to-binary-search-tree-with-minimal-height.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-sorted-array-to-binary-search-tree-with-minimal-height.md"
new file mode 100644
index 0000000..820d42e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-sorted-array-to-binary-search-tree-with-minimal-height.md"
@@ -0,0 +1,57 @@
+# 把排序数组转换为高度最小的二叉搜索树。
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-sorted-array-to-binary-search-tree-with-minimal-height/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个排序数组（从小到大），将其转换为一棵高度最小的二叉搜索树。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[]
+输出：{}
+解释：二叉搜索树为空
+```
+
+**样例 2:**
+```
+输入：[1,2,3,4,5,6,7]
+输出： {4,2,6,1,3,5,7}
+解释：
+拥有最小高度的二叉搜索树
+
+         4
+       /   \
+      2     6
+     / \    / \
+    1   3  5   7
+```
+ ### 参考代码
+ 每次取middle作为根，左半边是左子树，右半边是右子树。
+递归处理左右两边。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param A: a list of integer
+    @return: a tree node
+    """
+    def sortedArrayToBST(self, A):
+        return self.convert(A, 0, len(A) - 1)
+        
+    def convert(self, A, start, end):
+        if start > end:
+            return None
+        if start == end:
+            return TreeNode(A[start])
+        
+        mid = (start + end) // 2
+        root = TreeNode(A[mid])
+        root.left = self.convert(A, start, mid - 1)
+        root.right = self.convert(A, mid + 1, end)
+        return root
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-sorted-array-to-binary-search-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-sorted-array-to-binary-search-tree.md"
new file mode 100644
index 0000000..08ffca7
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-sorted-array-to-binary-search-tree.md"
@@ -0,0 +1,62 @@
+# 有序数组转换为二叉搜索树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-sorted-array-to-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数组，其中元素按升序排序，将其转换为高度平衡的BST。
+
+对于这个问题，高度平衡的二叉树被定义为二叉树，其中每个节点的两个子树的深度从不相差超过1。
+ ### 样例说明
+ **样例 1:**
+```
+输入: [-10,-3,0,5,9],
+输出: [0,-3,9,-10,#,5],
+解释:
+针对该数组的其中一个解为 [0,-3,9,-10,null,5], 其对应的平衡BST树如下:
+      0
+     / \
+   -3   9
+   /   /
+ -10  5
+```
+
+
+**样例 2:**
+```
+输入: [1,3]
+输出: [3,1]
+解释:
+针对该数组的其中一个解为 [3,1], 其对应的平衡BST树如下:
+  3
+ / 
+1   
+```
+
+
+
+ ### 参考代码
+ 考点：
+* 递归
+* BST
+
+题解：每次选择一个区间的中点作为当前区间的根，然后对左右子树依次构造。
+```java
+public class Solution {
+    private TreeNode buildTree(int[] num, int start, int end) {
+        if (start > end) {
+            return null;
+        }
+
+        TreeNode node = new TreeNode(num[(start + end) / 2]);
+        node.left = buildTree(num, start, (start + end) / 2 - 1);
+        node.right = buildTree(num, (start + end) / 2 + 1, end);
+        return node;
+    }
+
+    public TreeNode sortedArrayToBST(int[] num) {
+        if (num == null) {
+            return null;
+        }
+        return buildTree(num, 0, num.length - 1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-sorted-list-to-binary-search-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-sorted-list-to-binary-search-tree.md"
new file mode 100644
index 0000000..39760da
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/convert-sorted-list-to-binary-search-tree.md"
@@ -0,0 +1,123 @@
+# 有序链表转换为二叉搜索树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-sorted-list-to-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个所有元素以升序排序的单链表，将它转换成一棵高度平衡的二叉搜索树</p>
+ ### 样例说明
+ ```
+样例 1:
+	输入: array = 1->2->3
+	输出:
+		 2  
+		/ \
+		1  3
+		
+样例 2:
+	输入: 2->3->6->7
+	输出:
+		 3
+		/ \
+	       2   6
+		     \
+		      7
+
+	解释:
+	可能会有多个符合要求的结果，返回任意一个即可。
+```
+ ### 参考代码
+ Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
+
+高度平衡，所以将链表从中间分开，左边是左子树，右边是右子树。
+```cpp
+// version 1: (Recommend)
+class Solution {
+public:
+    /**
+     * @param head: The first node of linked list.
+     * @return: a tree node
+     */
+    TreeNode *sortedListToBST(ListNode *head) {
+        if (head == NULL) {
+            return NULL;
+        }
+        int size = getListSize(head);
+        return convertHelper(head, size);
+    }
+    
+    int getListSize(ListNode *head) {
+        int size = 0;
+        while (head != NULL) {
+            head = head->next;
+            size++;
+        }
+        return size;
+    }
+    
+    TreeNode *convertHelper(ListNode *&head, int size) {
+        if (size == 0) {
+            return NULL;
+        }
+        
+        TreeNode *root = new TreeNode(0);
+        root->left = convertHelper(head, size / 2);
+        root->val = head->val; head = head->next;
+        root->right = convertHelper(head, size - size / 2 - 1);
+        return root;
+    }
+};
+
+// version 2:
+struct ResultType {
+    TreeNode *tree;
+    ListNode *next;
+};
+
+class Solution {
+public:
+    /**
+     * @param head: The first node of linked list.
+     * @return: a tree node
+     */
+    TreeNode *sortedListToBST(ListNode *head) {
+        if (head == NULL) {
+            return NULL;
+        }
+        
+        int size = getListSize(head);
+        ResultType result = convertHelper(head, size);
+        return result.tree;
+    }
+    
+    int getListSize(ListNode *head) {
+        int size = 0;
+        while (head != NULL) {
+            head = head->next;
+            size++;
+        }
+        return size;
+    }
+    
+    ResultType convertHelper(ListNode *head, int size) {
+        ResultType result;
+        
+        if (size == 1) {
+            result.tree = new TreeNode(head->val);
+            result.next = head->next;
+            return result;
+        }
+        
+        ResultType left = convertHelper(head, size / 2);
+        result.tree = new TreeNode(left.next->val);
+        result.tree->left = left.tree;
+        if (left.next->next == NULL || size - size / 2 - 1 == 0) {
+            result.tree->right = NULL;
+            result.next = left.next->next;
+            return result;
+        }
+        ResultType right = convertHelper(left.next->next, size - size / 2 - 1);
+        result.tree->right = right.tree;
+        result.next = right.next;
+        return result;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/count-1-in-binary.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/count-1-in-binary.md"
new file mode 100644
index 0000000..ab0c763
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/count-1-in-binary.md"
@@ -0,0 +1,38 @@
+# 二进制中有多少个1 
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/count-1-in-binary/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 计算在一个 32 位的整数的二进制表示中有多少个 `1`。
+ ### 样例说明
+ **样例 1：**
+```
+输入：32
+输出：1
+解释：
+32(100000)，返回 1。
+```
+**样例 2：**
+```
+输入：5
+输出：2
+解释：
+5(101)，返回 2。
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param num: an integer
+     * @return: an integer, the number of ones in num
+     */
+    public int countOnes(int num) {
+        int count = 0;
+        while (num != 0) {
+            num = num & (num - 1);
+            count++;
+        }
+        return count;
+    }
+};
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/flatten-binary-tree-to-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/flatten-binary-tree-to-linked-list.md"
new file mode 100644
index 0000000..287e8ce
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/flatten-binary-tree-to-linked-list.md"
@@ -0,0 +1,74 @@
+# 将二叉树拆成链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/flatten-binary-tree-to-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一棵二叉树按照前序遍历拆解成为一个 `假链表`。所谓的假链表是说，用二叉树的 *right* 指针，来表示链表中的 *next* 指针。
+ ### 样例说明
+ **样例 1：**
+```
+输入：{1,2,5,3,4,#,6}
+输出：{1,#,2,#,3,#,4,#,5,#,6}
+解释：
+     1
+    / \
+   2   5
+  / \   \
+ 3   4   6
+ 
+1
+\
+ 2
+  \
+   3
+    \
+     4
+      \
+       5
+        \
+         6
+```
+**样例 2：**
+```
+输入：{1}
+输出：{1}
+解释：
+         1
+         1
+```
+
+ ### 参考代码
+ 使用 Divide & Conquer
+分治函数 return 这个 tree 的最后一个点。> 引用文本
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param root: a TreeNode, the root of the binary tree
+    @return: nothing
+    """
+    def flatten(self, root):
+        self.flatten_and_return_last_node(root)
+        
+    # restructure and return last node in preorder
+    def flatten_and_return_last_node(self, root):
+        if root is None:
+            return None
+            
+        left_last = self.flatten_and_return_last_node(root.left)
+        right_last = self.flatten_and_return_last_node(root.right)
+        
+        # connect 
+        if left_last is not None:
+            left_last.right = root.right
+            root.right = root.left
+            root.left = None
+            
+        return right_last or left_last or root
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/identical-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/identical-binary-tree.md"
new file mode 100644
index 0000000..96b2bfb
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/identical-binary-tree.md"
@@ -0,0 +1,44 @@
+# 等价二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/identical-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 检查两棵二叉树是否等价。等价的意思是说，首先两棵二叉树必须拥有相同的结构，并且每个对应位置上的节点上的数都相等。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```cpp
+/**
+ * Definition of TreeNode:
+ * class TreeNode {
+ * public:
+ *     int val;
+ *     TreeNode *left, *right;
+ *     TreeNode(int val) {
+ *         this->val = val;
+ *         this->left = this->right = NULL;
+ *     }
+ * }
+ */
+class Solution {
+public:
+    /**
+     * @aaram a, b, the root of binary trees.
+     * @return true if they are identical, or false.
+     */
+    bool isIdentical(TreeNode* a, TreeNode* b) {
+        // Write your code here
+        if(!a && !b)
+            return true;
+        else if(!a && b)
+            return false;
+        else if(a && !b)
+            return false;
+        else {
+            if(a->val != b->val)
+                return false;
+            else
+                return isIdentical(a->left, b->left) && isIdentical(a->right, b->right);
+        }
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/inorder-successor-in-binary-search-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/inorder-successor-in-binary-search-tree.md"
new file mode 100644
index 0000000..d7dc8e5
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/inorder-successor-in-binary-search-tree.md"
@@ -0,0 +1,56 @@
+# 二叉树查找树中序后继
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/inorder-successor-in-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个二叉查找树([什么是二叉查找树](http://www.lintcode.com/zh-cn/problem/validate-binary-search-tree/))，以及一个节点，求该节点的中序遍历后继，如果没有返回`null`
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
+        TreeNode successor = null;
+        while (root != null && root != p) {
+            if (root.val > p.val) {
+                successor = root;
+                root = root.left;
+            } else {
+                root = root.right;
+            }
+        }
+        
+        if (root == null) {
+            return null;
+        }
+        
+        if (root.right == null) {
+            return successor;
+        }
+        
+        root = root.right;
+        while (root.left != null) {
+            root = root.left;
+        }
+        
+        return root;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
+        // write your code here
+        if (root == null || p == null) {
+            return null;
+        }
+
+        if (root.val <= p.val) {
+            return inorderSuccessor(root.right, p);
+        } else {
+            TreeNode left = inorderSuccessor(root.left, p);
+            return (left != null) ? left : root;
+        }
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/inorder-successor-in-bst.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/inorder-successor-in-bst.md"
new file mode 100644
index 0000000..3babe9d
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/inorder-successor-in-bst.md"
@@ -0,0 +1,92 @@
+# 二叉查找树的中序后继
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/inorder-successor-in-bst/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉查找树([什么是二叉查找树](http://www.lintcode.com/zh-cn/problem/validate-binary-search-tree/))，以及一个节点，求该节点在中序遍历的后继，如果没有则返回`null`
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,#,2}, node with value 1
+输出: 2
+解释: 
+  1
+   \
+    2
+```
+
+**样例 2:**
+
+```
+输入: {2,1,3}, node with value 1
+输出: 2
+解释: 
+    2
+   / \
+  1   3
+```
+
+[二叉树的表示](https://www.lintcode.com/help/binary-tree-representation/)
+ ### 参考代码
+ 首先要确定中序遍历的后继:
+
+- 如果该节点有右子节点, 那么后继是其右子节点的子树中最左端的节点
+- 如果该节点没有右子节点, 那么后继是离它最近的祖先, 该节点在这个祖先的左子树内.
+
+使用循环实现:
+
+- 查找该节点, 并在该过程中维护上述性质的祖先节点
+- 查找到后, 如果该节点有右子节点, 则后继在其右子树内; 否则后继就是维护的那个祖先节点
+
+使用递归实现:
+
+- 如果根节点小于或等于要查找的节点, 直接进入右子树递归
+- 如果根节点大于要查找的节点, 则暂存左子树递归查找的结果, 如果是 `null`, 则直接返回当前根节点; 反之返回左子树递归查找的结果.
+
+在递归实现中, 暂存左子树递归查找的结果就相当于循环实现中维护的祖先节点.
+```java
+public class Solution {
+    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
+        TreeNode successor = null;
+        while (root != null && root.val != p.val) {
+            if (root.val > p.val) {
+                successor = root;
+                root = root.left;
+            } else {
+                root = root.right;
+            }
+        }
+
+        if (root == null) {
+            return null;
+        }
+
+        if (root.right == null) {
+            return successor;
+        }
+
+        root = root.right;
+        while (root.left != null) {
+            root = root.left;
+        }
+
+        return root;
+    }
+}
+
+// version:高频题班
+public class Solution {
+    public TreeNode inorderSuccessor(TreeNode root, TreeNode p) {
+        if (root == null || p == null) {
+            return null;
+        }
+
+        if (root.val <= p.val) {
+            return inorderSuccessor(root.right, p);
+        } else {
+            TreeNode left = inorderSuccessor(root.left, p);
+            return (left != null) ? left : root;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/insert-node-in-a-binary-search-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/insert-node-in-a-binary-search-tree.md"
new file mode 100644
index 0000000..9e1786a
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/insert-node-in-a-binary-search-tree.md"
@@ -0,0 +1,69 @@
+# 在二叉查找树中插入节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/insert-node-in-a-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一棵二叉查找树和一个新的树节点，将节点插入到树中。
+
+你需要保证该树仍然是一棵二叉查找树。
+ ### 样例说明
+ ```
+样例  1:
+	输入: tree = {}, node= 1
+	输出: {1}
+	
+	样例解释:
+	在空树中插入一个点，应该插入为根节点。
+
+	
+样例 2:
+	输入: tree = {2,1,4,3}, node = 6
+	输出: {2,1,4,3,6}
+	
+	样例解释: 
+	如下：
+	
+	  2             2
+	 / \           / \
+	1   4   -->   1   4
+	   /             / \ 
+	  3             3   6
+	
+```
+
+ ### 参考代码
+ 在树上定位要插入节点的位置。
+1. 如果它大于当前根节点，则应该在右子树中，如果没有右子树则将该点作为右儿子插入；若存在右子树则在右子树中继续定位。
+2. 如果它小于当前根节点，则应该在左子树中，处理同上。
+
+（二叉查找树中保证不插入已经存在的值）
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of the binary search tree.
+     * @param node: insert this node into the binary search tree
+     * @return: The root of the new binary search tree.
+     */
+    public TreeNode insertNode(TreeNode root, TreeNode node) {
+        if (root == null) {
+            return node;
+        }
+        if (root.val > node.val) {
+            root.left = insertNode(root.left, node);
+        } else {
+            root.right = insertNode(root.right, node);
+        }
+        return root;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/insert-node-in-binary-search-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/insert-node-in-binary-search-tree.md"
similarity index 100%
rename from "\351\242\230\350\247\243/insert-node-in-binary-search-tree.md"
rename to "\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/insert-node-in-binary-search-tree.md"
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/invert-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/invert-binary-tree.md"
new file mode 100644
index 0000000..923088c
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/invert-binary-tree.md"
@@ -0,0 +1,66 @@
+# 翻转二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/invert-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 翻转一棵二叉树。左右子树交换。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,3,#}
+输出: {1,#,3}
+解释:
+	  1    1
+	 /  =>  \
+	3        3
+```
+
+**样例 2:**
+```
+输入: {1,2,3,#,#,4}
+输出: {1,3,2,#,4}
+解释: 
+	
+      1         1
+     / \       / \
+    2   3  => 3   2
+       /       \
+      4         4
+```
+ ### 参考代码
+ 考点：
+* 二叉树
+* 搜索
+
+题解：
+递归过程中直接交换当前节点的左右子树，构造新的二叉树返回即可。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: a TreeNode, the root of the binary tree
+     * @return: nothing
+     */
+    public void invertBinaryTree(TreeNode root) {
+        if (root == null) {
+            return;
+        }
+        TreeNode temp = root.left;
+        root.left = root.right;
+        root.right = temp;
+        
+        invertBinaryTree(root.left);
+        invertBinaryTree(root.right);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/kth-smallest-element-in-a-bst.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/kth-smallest-element-in-a-bst.md"
new file mode 100644
index 0000000..0165b61
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/kth-smallest-element-in-a-bst.md"
@@ -0,0 +1,85 @@
+# BST中第K小的元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-smallest-element-in-a-bst/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉搜索树，写一个 `KthSmallest` 函数来找到其中第 K 小的元素。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,#,2},2
+输出：2
+解释：
+	1
+	 \
+	  2
+第二小的元素是2。
+```
+
+
+**样例 2:**
+```
+输入：{2,1,3},1
+输出：1
+解释：
+  2
+ / \
+1   3
+第一小的元素是1。
+```
+ ### 参考代码
+ 时间复杂度 $O(n)$ 最好最坏都是。
+算法思想类似于 Quick Select。
+这个算法的好处是，如果多次查询的话，给每个节点统计儿子个数这个过程只需要做一次。查询可以很快。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+
+public class Solution {
+    /**
+     * @param root: the given BST
+     * @param k: the given k
+     * @return: the kth smallest element in BST
+     */
+    public int kthSmallest(TreeNode root, int k) {
+        Map<TreeNode, Integer> numOfChildren = new HashMap<>();
+        countNodes(root, numOfChildren);
+        return quickSelectOnTree(root, k, numOfChildren);
+    }
+    
+    private int countNodes(TreeNode root, Map<TreeNode, Integer> numOfChildren) {
+        if (root == null) {
+            return 0;
+        }
+        
+        int left = countNodes(root.left, numOfChildren);
+        int right = countNodes(root.right, numOfChildren);
+        numOfChildren.put(root, left + right + 1);
+        return left + right + 1;
+    }
+    
+    private int quickSelectOnTree(TreeNode root, int k, Map<TreeNode, Integer> numOfChildren) {
+        if (root == null) {
+            return -1;
+        }
+        
+        int left = root.left == null ? 0 : numOfChildren.get(root.left);
+        if (left >= k) {
+            return quickSelectOnTree(root.left, k, numOfChildren);
+        }
+        if (left + 1 == k) {
+            return root.val;
+        }
+        
+        return quickSelectOnTree(root.right, k - left - 1, numOfChildren);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/largest-bst-subtree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/largest-bst-subtree.md"
new file mode 100644
index 0000000..d82d750
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/largest-bst-subtree.md"
@@ -0,0 +1,75 @@
+# 最大二叉搜索子树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/largest-bst-subtree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一棵二叉树，找到是二叉搜索树的最大子树，最大子树定义为子树节点最多。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+{10,5,15,1,8,#,7}
+输出：
+3
+
+解释:
+    10
+    / \
+   5  15
+  / \   \ 
+ 1   8   7
+二叉搜索树的最大子树为 :
+   5
+  / \
+ 1   8. 
+返回子树大小3.
+```
+
+**样例 2:**
+```
+输入:
+{1}
+输出：
+1
+```
+ ### 参考代码
+ 于每一个节点，都来验证其是否是BST，如果是的话，就统计节点的个数即可
+```java
+public class Solution {
+    public class SuperNode {
+        int ans;
+        int small, large;
+        boolean isBST;
+        public SuperNode() {
+            ans = 0;
+            isBST = true;
+            small = Integer.MAX_VALUE;
+            large = -Integer.MAX_VALUE;
+        }
+    }
+    public int largestBSTSubtree(TreeNode root) {
+        return dfs(root).ans;
+    }
+    public SuperNode dfs(TreeNode node) {
+        if (node == null) {
+            return new SuperNode();
+        }
+        SuperNode now = new SuperNode();
+        SuperNode left = dfs(node.left);
+        SuperNode right = dfs(node.right);
+        if (left.small < node.val) {
+            now.small = left.small;
+        } else {
+            now.small = node.val;
+        }
+        now.large = Math.max(right.large,node.val);
+        if (left.isBST && right.isBST && left.large <= node.val && right.small >= node.val) {
+            now.ans = left.ans + right.ans +1;
+            now.isBST = true;
+        } else {
+            now.ans=Math.max(left.ans,right.ans);
+            now.isBST = false;
+        }
+        return now;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/maximum-depth-of-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/maximum-depth-of-binary-tree.md"
new file mode 100644
index 0000000..937e43c
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/maximum-depth-of-binary-tree.md"
@@ -0,0 +1,53 @@
+# 二叉树的最大深度
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-depth-of-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，找出其最大深度。
+
+二叉树的深度为根节点到最远叶子节点的距离。
+ ### 样例说明
+ **样例  1:**
+
+```
+输入: tree = {}
+输出: 0	
+样例解释: 空树的深度是0。
+```
+**样例  2:**
+
+```
+输入: tree = {1,2,3,#,#,4,5}
+输出: 3
+样例解释: 树表示如下，深度是3
+   1
+  / \                
+ 2   3                
+    / \                
+   4   5
+它将被序列化为{1,2,3,#,#,4,5}
+```
+
+ ### 参考代码
+ Given a binary tree, find its maximum depth.
+
+The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.<div><br></div><div>详细解答请至九章微博：<a href="http://weibo.com/3948019741/BBY7gwi89" target="_blank">http://weibo.com/3948019741/BBY7gwi89</a></div>
+
+简单的树的遍历，点i为根的树高度，等于高度最大的子树的高度+1。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root: The root of binary tree.
+    @return: An integer
+    """ 
+    def maxDepth(self, root):
+        if root is None:
+            return 0
+        return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/minimum-depth-of-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/minimum-depth-of-binary-tree.md"
new file mode 100644
index 0000000..73217da
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/minimum-depth-of-binary-tree.md"
@@ -0,0 +1,75 @@
+# 二叉树的最小深度
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-depth-of-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，找出其最小深度。
+
+二叉树的最小深度为根节点到最近叶子节点的最短路径上的节点数量。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {}
+输出: 0
+```
+
+**样例 2:**
+
+```
+输入:  {1,#,2,3}
+输出: 3	
+解释:
+	1
+	 \ 
+	  2
+	 /
+	3    
+它将被序列化为 {1,#,2,3}
+```
+
+**样例 3:**
+
+```
+输入:  {1,2,3,#,#,4,5}
+输出: 2	
+解释: 
+      1
+     / \ 
+    2   3
+       / \
+      4   5  
+它将被序列化为 {1,2,3,#,#,4,5}
+```
+ ### 参考代码
+ Given a binary tree, find its minimum depth.
+
+The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
+
+考点：
+* 二叉树遍历
+* 搜索
+
+
+题解：直接搜索给出的二叉树即可。
+```java
+public class Solution {
+    public int minDepth(TreeNode root) {
+        if (root == null) {
+            return 0;
+        }
+        return getMin(root);
+    }
+
+    public int getMin(TreeNode root){
+        if (root == null) {
+            return Integer.MAX_VALUE;
+        }
+
+        if (root.left == null && root.right == null) {
+            return 1;
+        }
+
+        return Math.min(getMin(root.left), getMin(root.right)) + 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/recover-binary-search-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/recover-binary-search-tree.md"
new file mode 100644
index 0000000..c9bc940
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/recover-binary-search-tree.md"
@@ -0,0 +1,90 @@
+# 恢复二叉搜索树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/recover-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一棵二叉搜索树中, 只有两个节点是被交换的. 找到这些节点并交换, 如果没有节点被交换就返回原来的树的根节点.
+ ### 样例说明
+ **样例1**
+
+```
+输入： {4,5,2,1,3}
+输出： {4,2,5,1,3}
+解释：
+给出的二叉搜索树：
+    4
+   / \
+  5   2
+ / \
+1   3
+返回：
+    4
+   / \
+  2   5
+ / \
+1   3
+```
+
+**样例2**
+
+```
+输入： {1,2,5,4,3}
+输出： {4,2,5,1,3}
+解释：
+给出的二叉搜索树：
+    1
+   / \
+  2   5
+ / \
+4   3
+返回：
+    4
+   / \
+  2   5
+ / \
+1   3
+```
+
+
+ ### 参考代码
+ Two elements of a binary search tree (BST) are swapped by mistake.&nbsp;<div>Recover the tree without changing its structure.&nbsp;</div><div><br></div><div>Note:&nbsp;</div><div>A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?<div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博：<a href="http://weibo.com/3948019741/BErgRBUCb" target="_blank">&nbsp;http://weibo.com/3948019741/BErgRBUCb</a></span><br></div></div>
+```java
+/**
+ * Definition for binary tree
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    private TreeNode firstElement = null;
+    private TreeNode secondElement = null;
+    private TreeNode lastElement = new TreeNode(Integer.MIN_VALUE); 
+    
+    private void traverse(TreeNode root) {
+        if (root == null) {
+            return;
+        }
+        traverse(root.left);
+        if (firstElement == null && root.val < lastElement.val) {
+            firstElement = lastElement;
+        }
+        if (firstElement != null && root.val < lastElement.val) {
+            secondElement = root;
+        }
+        lastElement = root;
+        traverse(root.right);
+    }
+    
+    public void recoverTree(TreeNode root) {
+        // traverse and get two elements
+        traverse(root);
+        // swap
+        int temp = firstElement.val;
+        firstElement.val = secondElement.val;
+        secondElement.val = temp;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/remove-node-in-binary-search-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/remove-node-in-binary-search-tree.md"
new file mode 100644
index 0000000..ee86872
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/remove-node-in-binary-search-tree.md"
@@ -0,0 +1,146 @@
+# 删除二叉查找树的节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-node-in-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一棵具有不同节点值的二叉查找树，删除树中与给定值相同的节点。如果树中没有相同值的节点，就不做任何处理。你应该保证处理之后的树仍是<span style="line-height: 1.42857143;">二叉查找树。</span></p>
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: 
+Tree = {5,3,6,2,4}
+k = 3
+输出: {5,2,6,#,4} 或 {5,4,6,2}
+说明:
+给定了以下二叉搜索树:
+    5
+   / \
+  3   6
+ / \
+2   4
+移去3，你可以返回:
+    5
+   / \
+  2   6
+   \
+    4
+或
+    5
+   / \
+  4   6
+ /
+2
+```
+
+**样例2**
+
+```plain
+输入: 
+Tree = {5,3,6,2,4}
+k = 4
+输出: {5,3,6,2}
+说明:
+给定了以下二叉搜索树:
+    5
+   / \
+  3   6
+ / \
+2   4
+移去4，你应该返回
+    5
+   / \
+  3   6
+ /
+2
+```
+
+
+ ### 参考代码
+ Remove Node in Binary Search Tree
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of the binary search tree.
+     * @param value: Remove the node with given value.
+     * @return: The root of the binary search tree after removal.
+     */
+    public TreeNode removeNode(TreeNode root, int value) {
+        TreeNode dummy = new TreeNode(0);
+        dummy.left = root;
+        
+        TreeNode parent = findNode(dummy, root, value);
+        TreeNode node;
+        if (parent.left != null && parent.left.val == value) {
+            node = parent.left;
+        } else if (parent.right != null && parent.right.val == value) {
+            node = parent.right;
+        } else {
+            return dummy.left;
+        }
+        
+        deleteNode(parent, node);
+        
+        return dummy.left;
+    }
+    
+    private TreeNode findNode(TreeNode parent, TreeNode node, int value) {
+        if (node == null) {
+            return parent;
+        }
+        
+        if (node.val == value) {
+            return parent;
+        }
+        if (value < node.val) {
+            return findNode(node, node.left, value);
+        } else {
+            return findNode(node, node.right, value);
+        }
+    }
+    
+    private void deleteNode(TreeNode parent, TreeNode node) {
+        if (node.right == null) {
+            if (parent.left == node) {
+                parent.left = node.left;
+            } else {
+                parent.right = node.left;
+            }
+        } else {
+            TreeNode temp = node.right;
+            TreeNode father = node;
+            
+            while (temp.left != null) {
+                father = temp;
+                temp = temp.left;
+            }
+            
+            if (father.left == temp) {
+                father.left = temp.right;
+            } else {
+                father.right = temp.right;
+            }
+            
+            if (parent.left == node) {
+                parent.left = temp;
+            } else {
+                parent.right = temp;
+            }
+            
+            temp.left = node.left;
+            temp.right = node.right;
+        }
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/search-range-in-binary-search-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/search-range-in-binary-search-tree.md"
new file mode 100644
index 0000000..34a31fb
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/search-range-in-binary-search-tree.md"
@@ -0,0 +1,72 @@
+# 二叉查找树中搜索区间
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/search-range-in-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉查找树和范围`[k1, k2]`。按照升序返回给定范围内的节点值。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{5},6,10
+输出：[]
+        5
+它将被序列化为 {5}
+没有数字介于6和10之间
+```
+**样例 2:**
+```
+输入：{20,8,22,4,12},10,22
+输出：[12,20,22]
+解释：
+        20
+       /  \
+      8   22
+     / \
+    4   12
+它将被序列化为 {20,8,22,4,12}
+[12,20,22]介于10和22之间
+```
+ ### 参考代码
+ http://lintcode.com/zh-cn/problem/search-range-in-binary-search-tree/
+
+
+考点：
+* 二叉查找树 ：
+二叉排序树或者是一棵空树，或者是具有下列性质的二叉树：
+（1）若左子树不空，则左子树上所有结点的值均小于它的根结点的值；
+（2）若右子树不空，则右子树上所有结点的值均大于或等于它的根结点的值；
+（3）左、右子树也分别为二叉排序树；
+
+题解：从给定的BST的根节点开始查找，如果位于[k1,k2]，存入结果，向左右子树分别搜索。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root: The root of the binary search tree.
+    @param k1 and k2: range k1 to k2.
+    @return: Return all keys that k1<=key<=k2 in increasing order.
+    """     
+    def searchRange(self, root, k1, k2):
+        # write your code here
+        ans = []
+        if root is None:
+            return ans
+        queue = [root]
+        index = 0
+        while index < len(queue):
+            if queue[index] is not None:
+                if queue[index].val >= k1 and \
+                    queue[index].val <= k2:
+                    ans.append(queue[index].val)
+
+                queue.append(queue[index].left)
+                queue.append(queue[index].right)
+
+            index += 1
+        return sorted(ans)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/serialize-and-deserialize-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/serialize-and-deserialize-binary-tree.md"
new file mode 100644
index 0000000..4e82a1a
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/serialize-and-deserialize-binary-tree.md"
@@ -0,0 +1,108 @@
+# 二叉树的序列化和反序列化
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/serialize-and-deserialize-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个算法，并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”，读取文件后重建同样的二叉树被称为“反序列化”。
+
+如何反序列化或序列化二叉树是没有限制的，你只需要确保可以将二叉树序列化为一个字符串，并且可以将字符串反序列化为原来的树结构。
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入：{3,9,20,#,#,15,7}
+输出：{3,9,20,#,#,15,7}
+解释：
+二叉树 {3,9,20,#,#,15,7}，表示如下的树结构：
+	  3
+	 / \
+	9  20
+	  /  \
+	 15   7
+它将被序列化为 {3,9,20,#,#,15,7}
+```
+**样例 2：**
+```
+输入：{1,2,3}
+输出：{1,2,3}
+解释：
+二叉树 {1,2,3}，表示如下的树结构：
+   1
+  / \
+ 2   3
+它将被序列化为 {1,2,3}
+```
+我们的数据是进行 BFS 遍历得到的。当你测试结果 Wrong Answer 时，你可以作为输入调试你的代码。
+
+你可以采用其他的方法进行序列化和反序列化。
+ ### 参考代码
+ 使用 BFS 的方法来 serialize
+```python
+from collections import deque
+
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+
+class Solution:
+    """
+    @param root: An object of TreeNode, denote the root of the binary tree.
+    This method will be invoked first, you should design your own algorithm 
+    to serialize a binary tree which denote by a root node to a string which
+    can be easily deserialized by your own "deserialize" method later.
+    """
+    def serialize(self, root):
+        if root is None:
+            return ""
+            
+        # use bfs to serialize the tree
+        queue = deque([root])
+        bfs_order = []
+        while queue:
+            node = queue.popleft()
+            bfs_order.append(str(node.val) if node else '#')
+            if node:
+                queue.append(node.left)
+                queue.append(node.right)
+            
+        return ' '.join(bfs_order)
+
+    """
+    @param data: A string serialized by your serialize method.
+    This method will be invoked second, the argument data is what exactly
+    you serialized at method "serialize", that means the data is not given by
+    system, it's given by your own serialize method. So the format of data is
+    designed by yourself, and deserialize it here as you serialize it in 
+    "serialize" method.
+    """
+    def deserialize(self, data):
+        # None or ""
+        if not data:
+            return None
+
+        bfs_order = [
+            TreeNode(int(val)) if val != '#' else None
+            for val in data.split()
+        ]
+        root = bfs_order[0]
+        fast_index = 1
+        
+        nodes, slow_index = [root], 0
+        while slow_index < len(nodes):
+            node = nodes[slow_index]
+            slow_index += 1
+            node.left = bfs_order[fast_index]
+            node.right = bfs_order[fast_index + 1]
+            fast_index += 2
+            
+            if node.left:
+                nodes.append(node.left)
+            if node.right:
+                nodes.append(node.right)
+        
+        return root
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/symmetric-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/symmetric-binary-tree.md"
new file mode 100644
index 0000000..8413443
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/symmetric-binary-tree.md"
@@ -0,0 +1,61 @@
+# 对称二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/symmetric-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一颗二叉树，判断是否是对称二叉树
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,2,3,4,4,3}
+输出：true
+解释：
+
+         1
+        / \
+       2   2
+      / \ / \
+      3 4 4 3
+
+是一个对称的二叉树。
+```
+**样例 2:**
+```
+输入：{1,2,2,#,3,#,3}
+输出：false
+解释：
+
+         1
+        / \
+        2  2
+        \   \
+         3   3
+
+不是对称的二叉树。
+```
+ ### 参考代码
+ 递归地判断是否有对应结点
+```python
+1"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root, the root of binary tree.
+    @return true if it is a mirror of itself, or false.
+    """
+    def help(self, p, q):
+        if p == None and q == None: return True
+        if p and q and p.val == q.val:
+            return self.help(p.right, q.left) and self.help(p.left, q.right)
+        return False
+    
+    def isSymmetric(self, root):
+        # Write your code here
+        if root:
+            return self.help(root.left, root.right)
+        return True
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/tweaked-identical-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/tweaked-identical-binary-tree.md"
new file mode 100644
index 0000000..d8848b7
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/tweaked-identical-binary-tree.md"
@@ -0,0 +1,58 @@
+# 扭转后等价的二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/tweaked-identical-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 检查两棵二叉树是否在经过若干次扭转后可以等价。扭转的定义是，交换任意节点的左右子树。等价的定义是，两棵二叉树必须为相同的结构，并且对应位置上的节点的值要相等。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,4}，{1,3,2,#,#,#,4}
+输出：true
+解释：
+        1             1
+       / \           / \
+      2   3    和   3   2
+     /                   \
+    4                     4
+
+是相同的。
+```
+**样例 2:**
+```
+输入：{1,2,3,4}，{1,3,2,4}
+输出：false
+解释：
+
+        1             1
+       / \           / \
+      2   3    和   3   2
+     /             /
+    4             4
+
+不一样。
+```
+ ### 参考代码
+ 判断该子树不交换左右子树和交换左右子树是否能与对应的子树一致，往上回溯即可
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param a, b, the root of binary trees.
+    @return true if they are tweaked identical, or false.
+    """
+    def isTweakedIdentical(self, a, b):
+        # Write your code here
+        if a == None and b == None: return True
+        if a and b and a.val == b.val:
+            return self.isTweakedIdentical(a.left, b.left) and \
+                    self.isTweakedIdentical(a.right, b.right) or \
+                    self.isTweakedIdentical(a.left, b.right) and \
+                    self.isTweakedIdentical(a.right, b.left)
+        return False
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/unique-binary-search-trees-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/unique-binary-search-trees-ii.md"
new file mode 100644
index 0000000..ad473c7
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/unique-binary-search-trees-ii.md"
@@ -0,0 +1,60 @@
+# 不同的二叉查找树 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/unique-binary-search-trees-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="color: rgb(113, 113, 113); font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;">给出n，生成所有由1...n为节点组成的不同的二叉查找树</span><br></p>
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:3
+输出:
+    1         3     3       2    1
+     \       /     /       / \    \
+      3     2     1       1   3    2
+     /     /       \                \
+    2     1         2                3
+```
+ ### 参考代码
+ Given n, generate all structurally unique BST's (binary search trees) that store values 1...n.
+
+For example,
+Given n = 3, your program should return all 5 unique BST's shown below.
+
+   1         3     3      2      1
+    \       /     /      / \      \
+     3     2     1      1   3      2
+    /     /       \                 \
+   2     1         2                 3
+```java
+public class Solution {
+    public ArrayList<TreeNode> generateTrees(int n) {
+        return generate(1, n);
+    }
+    
+    private ArrayList<TreeNode> generate(int start, int end){
+        ArrayList<TreeNode> rst = new ArrayList<TreeNode>();   
+    
+        if(start > end){
+            rst.add(null);
+            return rst;
+        }
+     
+        for(int i=start; i<=end; i++){
+            ArrayList<TreeNode> left = generate(start, i-1);
+            ArrayList<TreeNode> right = generate(i+1, end);
+            for(TreeNode l: left){
+                for(TreeNode r: right){
+                    // should new a root here because it need to 
+                    // be different for each tree
+                    TreeNode root = new TreeNode(i);  
+                    root.left = l;
+                    root.right = r;
+                    rst.add(root);
+                }
+            }
+        }
+        return rst;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/unique-binary-search-trees.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/unique-binary-search-trees.md"
new file mode 100644
index 0000000..bc184d5
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/unique-binary-search-trees.md"
@@ -0,0 +1,57 @@
+# 不同的二叉查找树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/unique-binary-search-trees/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出 *n*，问由 1...*n* 为节点组成的不同的二叉查找树有多少种？
+ ### 样例说明
+ **样例 1：**
+```
+输入：n = 3
+输出：5
+解释：有5种不同形态的二叉查找树：
+```
+
+	1           3    3       2      1
+	 \         /    /       / \      \
+	  3      2     1       1   3      2
+	 /      /       \                  \
+	2     1          2                  3
+ ### 参考代码
+ Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
+
+For example,
+Given n = 3, there are a total of 5 unique BST's.
+
+   1         3     3      2      1
+    \       /     /      / \      \
+     3     2     1      1   3      2
+    /     /       \                 \
+   2     1         2                 3
+```java
+public class Solution {
+/*
+The case for 3 elements example
+Count[3] = Count[0]*Count[2]  (1 as root)
+              + Count[1]*Count[1]  (2 as root)
+              + Count[2]*Count[0]  (3 as root)
+
+Therefore, we can get the equation:
+Count[i] = ∑ Count[0...k] * [ k+1....i]     0<=k<i-1  
+
+*/
+    public int numTrees(int n) {
+        int[] count = new int[n + 2];
+        count[0] = 1;
+        count[1] = 1;
+        
+        for(int i = 2; i <= n; i++){
+            for(int j = 0; j < i; j++){
+                count[i] += count[j] * count[i - j - 1];
+            }
+        }
+        return count[n];
+    }
+}
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/validate-binary-search-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/validate-binary-search-tree.md"
new file mode 100644
index 0000000..3546e63
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/validate-binary-search-tree.md"
@@ -0,0 +1,98 @@
+# 验证二叉查找树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/validate-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，判断它是否是合法的二叉查找树(BST)
+
+一棵BST定义为：
+
+* 节点的左子树中的值要**严格**小于该节点的值。
+* 节点的右子树中的值要**严格**大于该节点的值。
+* 左右子树也必须是二叉查找树。
+* 一个节点的树也是二叉查找树。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{-1}
+输出：true
+解释：
+二叉树如下(仅有一个节点）:
+	-1
+这是二叉查找树。
+```	
+
+**样例 2:**
+```
+输入：{2,1,4,#,#,3,5}
+输出：true
+解释：
+	二叉树如下：
+	  2
+	 / \
+	1   4
+	   / \
+	  3   5
+这是二叉查找树。
+```
+ ### 参考代码
+ 分治法，但是 minValue 和 maxValue 用 minNode 和 maxNode 来代替。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+
+class ResultType {
+    public boolean isBST;
+    public TreeNode maxNode, minNode;
+    public ResultType(boolean isBST) {
+        this.isBST = isBST;
+        this.maxNode = null;
+        this.minNode = null;
+    }
+}
+
+public class Solution {
+    /**
+     * @param root: The root of binary tree.
+     * @return: True if the binary tree is BST, or false
+     */
+    public boolean isValidBST(TreeNode root) {
+        return divideConquer(root).isBST;
+    }
+    
+    private ResultType divideConquer(TreeNode root) {
+        if (root == null) {
+            return new ResultType(true);
+        }
+        
+        ResultType left = divideConquer(root.left);
+        ResultType right = divideConquer(root.right);
+        if (!left.isBST || !right.isBST) {
+            return new ResultType(false);
+        }
+        
+        if (left.maxNode != null && left.maxNode.val >= root.val) {
+            return new ResultType(false);
+        }
+        
+        if (right.minNode != null && right.minNode.val <= root.val) {
+            return new ResultType(false);
+        }
+        
+        // is bst
+        ResultType result = new ResultType(true);
+        result.minNode = left.minNode != null ? left.minNode : root;
+        result.maxNode = right.maxNode != null ? right.maxNode : root;
+        
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/verify-preorder-serialization-of-a-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/verify-preorder-serialization-of-a-binary-tree.md"
new file mode 100644
index 0000000..da85513
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\342\274\206\345\217\211\346\220\234\347\264\242\346\240\221/verify-preorder-serialization-of-a-binary-tree.md"
@@ -0,0 +1,83 @@
+# 验证二叉树的前序序列化
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/verify-preorder-serialization-of-a-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 二叉树序列化的一种方法是使用先序遍历。 当我们遇到非空节点时，我们记录节点的值。如果是一个空节点，我们使用诸如#的标记值。
+~~~~.
+     _9_
+    /   \
+   3     2
+  / \   / \
+ 4   1  #  6
+/ \ / \   / \
+# # # #   # #
+~~~~
+例如，上面的二叉树可以序列化为字符串”9,3,4,#,#,1,#,#,2,#,6,#,#”，其中#表示空节点。
+
+给定一个用逗号分隔的字符串，验证它是否是二叉树序列化正确的前序遍历。 找到一个不需要重建树的算法。
+
+字符串中的每个逗号分隔的值必须是整数或表示空指针的字符“#”。
+
+您可以假设输入格式始终符合要求，例如它永远不能包含两个连续的逗号，例如“1,,3”。
+ ### 样例说明
+ ```
+样例 1:
+	输入:  tree = "#"
+	输出:  true
+	
+	解释:
+	空树是合法的BST。
+	
+样例 2:
+	输入: tree = "9,3,4,#,#,1,#,#,2,#,6,#,#"
+	输出:  true
+
+样例 3:
+	输入: tree = "1,#"
+	输出:  false
+	
+	解释:
+	不是一棵完整的树
+	
+样例 4:
+	输入: tree = "9,#,#,1"
+	输出:  false
+	
+	解释:
+	不是一棵树
+
+```
+
+ ### 参考代码
+ ```java
+public class Solution {
+    public boolean isValidSerialization(String preorder) {
+        String s = preorder;
+        boolean flag = true;
+        while (s.length() > 1) {
+            int index = s.indexOf(",#,#");
+            if (index < 0) {
+                flag = false;
+                break;
+            }
+            int start = index;
+            while (start > 0 && s.charAt(start - 1) != ',')
+            {
+                start --;
+            }
+            if (s.charAt(start) == '#') {
+                flag = false;
+                break;
+            }
+            s = s.substring(0, start) + s.substring(index + 3);
+        }
+        if (s.equals("#") && flag) 
+            return true;
+        else 
+            return false;
+    }
+}
+
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/balanced-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/balanced-binary-tree.md"
new file mode 100644
index 0000000..cee5a4e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/balanced-binary-tree.md"
@@ -0,0 +1,81 @@
+# 平衡二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/balanced-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个二叉树,确定它是高度平衡的。对于这个问题,一棵高度平衡的二叉树的定义是：一棵二叉树中每个节点的两个子树的深度相差不会超过1。&nbsp;<br></p>
+ ### 样例说明
+ ```
+样例  1:
+	输入: tree = {1,2,3}
+	输出: true
+	
+	样例解释:
+	如下，是一个平衡的二叉树。
+		  1  
+		 / \                
+		2  3
+
+	
+样例  2:
+	输入: tree = {3,9,20,#,#,15,7}
+	输出: true
+	
+	样例解释:
+	如下，是一个平衡的二叉树。
+		  3  
+		 / \                
+		9  20                
+		  /  \                
+		 15   7 
+
+	
+样例  2:
+	输入: tree = {1,#,2,3,4}
+	输出: false
+	
+	样例解释:
+	如下，是一个不平衡的二叉树。1的左右子树高度差2
+		  1  
+		   \                
+		   2                
+		  /  \                
+		 3   4
+	
+```
+
+ ### 参考代码
+ Given a binary tree, determine if it is height-balanced.
+
+For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
+
+在树上做一次DFS，计算以每个点为根的子树高度。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root: The root of binary tree.
+    @return: True if this Binary tree is Balanced, or false.
+    """
+    def isBalanced(self, root):
+        balanced, _ = self.validate(root)
+        return balanced
+        
+    def validate(self, root):
+        if root is None:
+            return True, 0
+            
+        balanced, leftHeight = self.validate(root.left)
+        if not balanced:
+            return False, 0
+        balanced, rightHeight = self.validate(root.right)
+        if not balanced:
+            return False, 0
+            
+        return abs(leftHeight - rightHeight) <= 1, max(leftHeight, rightHeight) + 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-flipping.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-flipping.md"
new file mode 100644
index 0000000..9500772
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-flipping.md"
@@ -0,0 +1,67 @@
+# 二叉树翻转
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-flipping/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，其中所有右节点要么是具有兄弟节点的叶节点(有一个共享相同父节点的左节点)或空白，将其倒置并将其转换为树，其中原来的右节点变为左叶子节点。返回新的根节点。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the new root
+     */
+    public TreeNode upsideDownBinaryTree(TreeNode root) {
+        // Write your code here     
+        if (root == null || root.left == null) {
+            return root;
+        }
+        TreeNode new_root = upsideDownBinaryTree(root.left);
+        root.left.left = root.right;
+        root.left.right = root;
+        root.right = null;
+        root.left = null;
+        return new_root;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the new root
+     */
+
+    TreeNode dfs(TreeNode cur) {
+        if (cur.left == null) {
+            return cur;
+        }
+        TreeNode newRoot = dfs(cur.left);
+        cur.left.right = cur;
+        cur.left.left = cur.right;
+        cur.left = null;            // important
+        cur.right = null;
+        return newRoot;
+    }
+
+    public TreeNode upsideDownBinaryTree(TreeNode root) {
+        // Write your code here
+        if (root == null) {
+            return null;
+        }
+        return dfs(root);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-inorder-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-inorder-traversal.md"
new file mode 100644
index 0000000..722c465
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-inorder-traversal.md"
@@ -0,0 +1,70 @@
+# 二叉树的中序遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-inorder-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树,返回其中序遍历</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3}
+输出：[2,1,3]
+解释：
+   1
+  / \
+ 2   3
+它将被序列化为{1,2,3}
+中序遍历
+```
+**样例 2:**
+```
+输入：{1,#,2,3}
+输出：[1,3,2]
+解释：
+1
+ \
+  2
+ /
+3
+它将被序列化为{1,#,2,3}
+中序遍历
+```
+ ### 参考代码
+ 考点：
+* 二叉树的中序遍历
+* 搜索
+
+题解：按照左根右的次序遍历二叉树，搜索左子树，存入当前点，搜索右子树。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of binary tree.
+     * @return: Inorder in ArrayList which contains node values.
+     */
+    public ArrayList<Integer> inorderTraversal(TreeNode root) {
+        Stack<TreeNode> stack = new Stack<TreeNode>();
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        TreeNode curt = root;
+        while (curt != null || !stack.empty()) {
+            while (curt != null) {
+                stack.add(curt);
+                curt = curt.left;
+            }
+            curt = stack.pop();
+            result.add(curt.val);
+            curt = curt.right;
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-leaf-sum.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-leaf-sum.md"
new file mode 100644
index 0000000..7808d97
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-leaf-sum.md"
@@ -0,0 +1,53 @@
+# 二叉树叶子节点之和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-leaf-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 计算二叉树的叶子节点之和
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,4}
+输出：7
+解释：
+    1
+   / \
+  2   3
+ /
+4
+3+4=7
+```
+**样例 2:**
+```
+输入：{1,#,3}
+输出：3
+解释：
+    1
+      \
+       3
+```
+ ### 参考代码
+ 递归求和即可
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root the root of the binary tree
+    # @return {int} an integer
+    def leafSum(self, root):
+        # Write your code here
+        p = []
+        self.dfs(root, p)
+        return sum(p)
+    def dfs(self, root, p):
+        if root is None:
+            return
+        if root.left is None and root.right is None:
+            p.append(root.val)
+        self.dfs(root.left, p)
+        self.dfs(root.right, p)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-leaves-order-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-leaves-order-traversal.md"
new file mode 100644
index 0000000..b418649
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-leaves-order-traversal.md"
@@ -0,0 +1,78 @@
+# 二叉树叶子顺序遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-leaves-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，像这样收集树节点：收集并移除所有叶子，重复，直到树为空。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return collect and remove all leaves
+     */
+    public List<List<Integer>> findLeaves(TreeNode root) {
+        // Write your code here
+        List<List<Integer>> results = new ArrayList<List<Integer>>();
+        dfs(root, results);
+        return results;
+    }
+
+    int dfs(TreeNode root, List<List<Integer>> results) {
+        if (root == null) {
+            return 0;
+        }
+        int level = Math.max(dfs(root.left, results), dfs(root.right, results)) + 1;
+        int size = results.size();
+        if (level > size) {
+            results.add(new ArrayList<Integer>());
+        }
+        results.get(level - 1).add(root.val);
+        return level;
+    }   
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return collect and remove all leaves
+     */
+
+    int dfs(TreeNode cur, Map<Integer, List<Integer>> depth) {
+        if (cur == null) {
+            return 0;
+        }
+        int d = Math.max(dfs(cur.left, depth), dfs(cur.right, depth)) + 1;
+
+        depth.putIfAbsent(d, new ArrayList<>());
+        depth.get(d).add(cur.val);
+        return d;
+    }
+
+    public List<List<Integer>> findLeaves(TreeNode root) {
+        // Write your code here
+        List<List<Integer>> ans = new ArrayList<>();
+
+        Map<Integer, List<Integer>> depth = new HashMap<>();
+        int max_depth = dfs(root, depth);
+
+        for (int i = 1; i <= max_depth; i++) {
+            ans.add(depth.get(i));
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-level-order-traversal-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-level-order-traversal-ii.md"
new file mode 100644
index 0000000..70cefe9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-level-order-traversal-ii.md"
@@ -0,0 +1,83 @@
+# 二叉树的层次遍历 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-level-order-traversal-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树，返回其节点值从底向上的层次序遍历（按从叶节点所在层到根节点所在的层遍历，然后逐层从左往右遍历）</p>
+ ### 样例说明
+ 例1:
+```
+输入:
+{1,2,3}
+输出:
+[[2,3],[1]]
+解释:
+    1
+   / \
+  2   3
+它将被序列化为 {1,2,3}
+层次遍历
+```
+例2:
+```
+输入:
+{3,9,20,#,#,15,7}
+输出:
+[[15,7],[9,20],[3]]
+解释:
+    3
+   / \
+  9  20
+    /  \
+   15   7
+它将被序列化为 {3,9,20,#,#,15,7}
+层次遍历
+```
+
+ ### 参考代码
+ 利用队列层序遍历整棵树，最后翻转一下即可。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of binary tree.
+     * @return: buttom-up level order a list of lists of integer
+     */
+    public List<List<Integer>> levelOrderBottom(TreeNode root) {
+        List<List<Integer>> result = new ArrayList<>();
+        if (root == null) {
+            return result;
+        }
+        Queue<TreeNode> queue = new LinkedList<TreeNode>();
+        queue.offer(root);
+        
+        while (!queue.isEmpty()) {
+            int size = queue.size();
+            List<Integer> level = new ArrayList<>();
+            for (int i = 0; i < size; i++) {
+                TreeNode head = queue.poll();
+                level.add(head.val);
+                if (head.left != null) {
+                    queue.offer(head.left);
+                }
+                if (head.right != null) {
+                    queue.offer(head.right);
+                }
+            }
+            result.add(level);
+        }
+        
+        Collections.reverse(result);
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-level-order-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-level-order-traversal.md"
new file mode 100644
index 0000000..a215eb6
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-level-order-traversal.md"
@@ -0,0 +1,67 @@
+# 二叉树的层次遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-level-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一棵二叉树，返回其节点值的层次遍历（逐层从左往右访问）
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3}
+输出：[[1],[2,3]]
+解释：
+   1
+  / \
+ 2   3
+它将被序列化为{1,2,3}
+层次遍历
+```
+**样例 2:**
+```
+输入：{1,#,2,3}
+输出：[[1],[2],[3]]
+解释：
+1
+ \
+  2
+ /
+3
+它将被序列化为{1,#,2,3}
+层次遍历
+```
+
+ ### 参考代码
+ 用一个队列的方法。
+```python
+from collections import deque
+
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param root: The root of binary tree.
+    @return: Level order a list of lists of integer
+    """
+    def levelOrder(self, root):
+        if root is None:
+            return []
+            
+        queue = deque([root])
+        result = []
+        while queue:
+            level = []
+            for _ in range(len(queue)):
+                node = queue.popleft()
+                level.append(node.val)
+                if node.left:
+                    queue.append(node.left)
+                if node.right:
+                    queue.append(node.right)
+            result.append(level)
+        return result
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-level-sum.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-level-sum.md"
new file mode 100644
index 0000000..9f058ee
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-level-sum.md"
@@ -0,0 +1,64 @@
+# 二叉树的某层节点之和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-level-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一棵二叉树和一个整数代表树的某层深度。
+计算二叉树的某层节点之和。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,4,5,6,7,#,#,8,#,#,#,#,9},2
+输出：5 
+解释：
+     1
+   /   \
+  2     3
+ / \   / \
+4   5 6   7
+   /       \
+  8         9
+2+3=5
+```
+**样例 2:**
+```
+输入：{1,2,3,4,5,6,7,#,#,8,#,#,#,#,9},3
+输出：22
+解释：
+     1
+   /   \
+  2     3
+ / \   / \
+4   5 6   7
+   /       \
+  8         9
+4+5+6+7=22
+```
+ ### 参考代码
+ 递归遍历树，答案加上对应层的值即可
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root the root of the binary tree
+    # @param {int} level the depth of the target level
+    # @return {int} an integer
+    def levelSum(self, root, level):
+        # Write your code here
+        p = []
+        self.dfs(root, p, 1, level)
+        return sum(p)
+    def dfs(self, root, p, dep, level):
+        if root is None:
+            return
+        if dep == level:
+            p.append(root.val)
+            return
+
+        self.dfs(root.left, p, dep+1, level)
+        self.dfs(root.right, p, dep+1, level)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-longest-consecutive-sequence-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-longest-consecutive-sequence-ii.md"
new file mode 100644
index 0000000..4e74d6b
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-longest-consecutive-sequence-ii.md"
@@ -0,0 +1,94 @@
+# 二叉树的最长连续子序列 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-longest-consecutive-sequence-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一棵二叉树，找到最长连续序列(单调且相邻节点值相差为1)路径的长度(节点数)。
+路径起点跟终点可以为二叉树的任意节点。
+ ### 样例说明
+ **例1:**
+```
+输入:
+{1,2,0,3}
+输出:
+4
+解释:
+    1
+   / \
+  2   0
+ /
+3
+0-1-2-3
+```
+
+**例2:**
+```
+输入:
+{3,2,2}
+输出:
+2
+解释:
+    3
+   / \
+  2   2
+2-3
+```
+
+
+ ### 参考代码
+ ```java
+/**
+ * Definition for a binary tree node.
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+class ResultType {
+    public int max_length, max_down, max_up;
+    ResultType(int len, int down, int up) {
+        max_length = len;
+        max_down = down;
+        max_up = up;    
+    }
+}
+
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive2(TreeNode root) {
+        // Write your code here
+        return helper(root).max_length;
+    }
+    
+    ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, 0, 0);
+        }
+
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        int down = 0, up = 0;
+        if (root.left != null && root.left.val + 1 == root.val)
+            down = Math.max(down, left.max_down + 1);
+
+        if (root.left != null && root.left.val - 1 == root.val)
+            up = Math.max(up, left.max_up + 1);
+
+        if (root.right != null && root.right.val + 1 == root.val)
+            down = Math.max(down, right.max_down + 1);
+
+        if (root.right != null && root.right.val - 1 == root.val)
+            up = Math.max(up, right.max_up + 1);
+
+        int len = down + 1 + up;
+        len = Math.max(len, Math.max(left.max_length, right.max_length));
+
+        return new ResultType(len, down, up);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-longest-consecutive-sequence-iii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-longest-consecutive-sequence-iii.md"
new file mode 100644
index 0000000..43f671f
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-longest-consecutive-sequence-iii.md"
@@ -0,0 +1,83 @@
+# 二叉树的最长连续子序列III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-longest-consecutive-sequence-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 这题是 `二叉树的最长连续子序列II` 的后续。
+给出一棵 `k叉树`，找到最长连续序列路径的长度.
+路径的开头跟结尾可以是树的任意节点。
+ ### 样例说明
+ 例1:
+```
+输入:
+5<6<7<>,5<>,8<>>,4<3<>,5<>,31<>>>
+输出:
+5
+解释:
+     5
+   /   \
+  6     4
+ /|\   /|\
+7 5 8 3 5 31
+
+返回 5, // 3-4-5-6-7
+```
+
+例2:
+```
+输入:
+1<>
+输出:
+1
+```
+
+
+ ### 参考代码
+ 从根结点开始dfs，每次搜相邻的相差1的结点，跟新即可
+```java
+/**
+ * Definition for a multi tree node.
+ * public class MultiTreeNode {
+ *     int val;
+ *     List<TreeNode> children;
+ *     MultiTreeNode(int x) { val = x; }
+ * }
+ */
+ class ResultType {
+    public int max_len, max_down, max_up;
+    ResultType(int len, int down, int up) {
+        max_len = len;
+        max_down = down;
+        max_up = up;    
+    }
+}
+
+public class Solution {
+    /**
+     * @param root the root of k-ary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive3(MultiTreeNode root) {
+        // Write your code here
+        return helper(root).max_len;
+    }
+    
+    ResultType helper(MultiTreeNode root) {
+        if (root == null) {
+            return new ResultType(0, 0, 0);
+        }
+
+        int down = 0, up = 0, max_len = 1;
+        for (MultiTreeNode node : root.children) {
+            ResultType type = helper(node);
+            if (node.val + 1 == root.val)
+                down = Math.max(down, type.max_down + 1);
+            if (node.val - 1 == root.val)
+                up = Math.max(up, type.max_up + 1);
+            max_len = Math.max(max_len, type.max_len);
+        }
+
+        max_len = Math.max(down + 1 + up, max_len);
+        return new ResultType(max_len, down, up);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-longest-consecutive-sequence.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-longest-consecutive-sequence.md"
new file mode 100644
index 0000000..807f962
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-longest-consecutive-sequence.md"
@@ -0,0 +1,161 @@
+# 二叉树最长连续序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-longest-consecutive-sequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，找到最长连续路径的长度。
+这条路径是指 任何的节点序列中的起始节点到树中的任一节点都必须遵循 父-子 联系。最长的连续路径必须是从父亲节点到孩子节点（`不能逆序`）。
+
+ ### 样例说明
+ **样例1:**
+
+```
+输入:
+{1,#,3,2,4,#,#,#,5}
+输出:3
+说明:
+这棵树如图所示
+   1
+    \
+     3
+    / \
+   2   4
+        \
+         5
+最长连续序列是3-4-5，所以返回3.
+```
+
+**样例2:**
+
+```
+输入:
+{2,#,3,2,#,1,#}
+输出:2
+说明:
+这棵树如图所示：
+   2
+    \
+     3
+    / 
+   2    
+  / 
+ 1
+最长连续序列是2-3，而不是3-2-1，所以返回2.
+```
+
+
+ ### 参考代码
+ dfs搜索即可
+```java
+// version 1: Traverse + Divide Conquer
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive(TreeNode root) {
+        return helper(root, null, 0);
+    }
+    
+    private int helper(TreeNode root, TreeNode parent, int lengthWithoutRoot) {
+        if (root == null) {
+            return 0;
+        }
+        
+        int length = (parent != null && parent.val + 1 == root.val)
+            ? lengthWithoutRoot + 1
+            : 1;
+        int left = helper(root.left, root, length);
+        int right = helper(root.right, root, length);
+        return Math.max(length, Math.max(left, right));
+    }
+}
+
+// version 2: Another Traverse + Divide Conquer 
+public class Solution {
+    private int longest;
+    
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive(TreeNode root) {
+        longest = 0;
+        helper(root);
+        return longest;
+    }
+    
+    private int helper(TreeNode root) {
+        if (root == null) {
+            return 0;
+        }
+        
+        int left = helper(root.left);
+        int right = helper(root.right);
+        
+        int subtreeLongest = 1; // at least we have root
+        if (root.left != null && root.val + 1 == root.left.val) {
+            subtreeLongest = Math.max(subtreeLongest, left + 1);
+        }
+        if (root.right != null && root.val + 1 == root.right.val) {
+            subtreeLongest = Math.max(subtreeLongest, right + 1);
+        }
+        
+        if (subtreeLongest > longest) {
+            longest = subtreeLongest;
+        }
+        return subtreeLongest;
+    }
+}
+
+// version 3: Divide Conquer
+public class Solution {
+    private class ResultType {
+        int maxInSubtree;
+        int maxFromRoot;
+        public ResultType(int maxInSubtree, int maxFromRoot) {
+            this.maxInSubtree = maxInSubtree;
+            this.maxFromRoot = maxFromRoot;
+        }
+    }
+    /**
+     * @param root the root of binary tree
+     * @return the length of the longest consecutive sequence path
+     */
+    public int longestConsecutive(TreeNode root) {
+        return helper(root).maxInSubtree;
+    }
+    
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, 0);
+        }
+        
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+        
+        // 1 is the root itself.
+        ResultType result = new ResultType(0, 1);
+        
+        if (root.left != null && root.val + 1 == root.left.val) {
+            result.maxFromRoot = Math.max(
+                result.maxFromRoot,
+                left.maxFromRoot + 1
+            );
+        }
+        
+        if (root.right != null && root.val + 1 == root.right.val) {
+            result.maxFromRoot = Math.max(
+                result.maxFromRoot,
+                right.maxFromRoot + 1
+            );
+        }
+        
+        result.maxInSubtree = Math.max(
+            result.maxFromRoot,
+            Math.max(left.maxInSubtree, right.maxInSubtree)
+        );
+        
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-maximum-node.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-maximum-node.md"
new file mode 100644
index 0000000..0841bb5
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-maximum-node.md"
@@ -0,0 +1,67 @@
+# 二叉树的最大节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-maximum-node/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在二叉树中寻找值最大的节点并返回。
+ ### 样例说明
+ **样例1:**
+
+```
+输入:
+{1,-5,3,1,2,-4,-5}
+输出: 3
+说明:
+这棵树如下所示：
+     1
+   /   \
+ -5     3
+ / \   /  \
+1   2 -4  -5
+```
+
+**样例 2**
+
+```plain
+输入:
+{10,-5,2,0,3,-4,-5}
+输出: 10
+说明:
+这棵树如下所示：
+     10
+   /   \
+ -5     2
+ / \   /  \
+0   3 -4  -5 
+```
+
+
+ ### 参考代码
+ 树上基本遍历
+```java
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the max ndoe
+     */
+    public TreeNode maxNode(TreeNode root) {
+        // Write your code here
+        if (root == null)
+            return root;
+
+        TreeNode left = maxNode(root.left);
+        TreeNode right = maxNode(root.right);
+        return max(root, max(left, right));
+    }
+
+    TreeNode max(TreeNode a, TreeNode b) {
+        if (a == null)
+            return b;
+        if (b == null)
+            return a;
+        if (a.val > b.val) {
+            return a;
+        }
+        return b;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-maximum-path-sum-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-maximum-path-sum-ii.md"
new file mode 100644
index 0000000..691a9cb
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-maximum-path-sum-ii.md"
@@ -0,0 +1,57 @@
+# 二叉树的最大路径和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-maximum-path-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，找出从根节点出发的路径中，和最大的一条。
+
+这条路径可以在任何二叉树中的节点结束，但是必须包含至少一个点（也就是根了）。
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,2,3}
+输出: 4
+解释: 
+    1
+   / \
+  2   3
+1+3=4
+```
+
+**样例 2:**
+
+```
+输入: {1,-1,-1}
+输出: 1
+解释:
+    1
+   / \
+  -1 -1 
+```
+ ### 参考代码
+ 如果从动态规划的角度思考, 可以是这样的:
+
+- 状态: f[i] 表示从节点i往下走得到的最大路径和
+- 状态转移方程: f[i] = max{f[lc[i]], f[rc[i]], 0} + val[i]
+
+不过这道题目是二叉树, 比经典的数字三角形要简单, 无需记忆化/定义额外空间储存答案.
+
+一次递归遍历整棵二叉树即可.
+```java
+public class Solution {
+    /**
+     * @param root the root of binary tree.
+     * @return an integer
+     */
+    public int maxPathSum2(TreeNode root) {
+        if (root == null) {
+            return Integer.MIN_VALUE;
+        }
+
+        int left = maxPathSum2(root.left);
+        int right = maxPathSum2(root.right);
+        return root.val + Math.max(0, Math.max(left, right));
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-maximum-path-sum.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-maximum-path-sum.md"
new file mode 100644
index 0000000..e6280bc
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-maximum-path-sum.md"
@@ -0,0 +1,108 @@
+# 二叉树中的最大路径和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-maximum-path-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <span style="line-height: 30px;"><font color="#000000">给出一棵二叉树，</font></span><font color="#000000"><span style="line-height: 30px;">寻找一条路径使其路径和最大，路径可以在任一节点中开始和结束（路径和为两个节点之间所在路径上的节点权值之和）</span></font><br>
+ ### 样例说明
+ ```
+样例 1:
+	输入:  给定一棵树（只有一个节点）:
+	2
+	输出：2
+	
+样例 2:
+	输入:  给定一棵树：
+
+      1
+     / \
+    2   3
+		
+	输出: 6
+
+	
+```
+ ### 参考代码
+ Given a binary tree, find the maximum path sum.&nbsp;<div>The path may start and end at any node in the tree.&nbsp;</div><div><br></div><div>For example:&nbsp;</div><div>Given the below binary tree,&nbsp;</div><div>&nbsp; 1&nbsp;</div><div>&nbsp;/ &nbsp;\&nbsp;</div><div>2 &nbsp; 3&nbsp;</div><div><span style="line-height: 1.42857143;">Return 6.</span><br></div><div><div><br></div><div>详细题解请见九章算法微博：<a href="http://weibo.com/3948019741/BBY7gwi89" target="_blank">http://weibo.com/3948019741/BBY7gwi89</a></div></div>
+
+分治法。
+需要考虑的是，子树中最大的路不一定必过根节点。所以要记录single Path的值。
+见代码注释。
+```java
+public class Solution {
+    private class ResultType {
+        // singlePath: 从root往下走到任意点的最大路径，这条路径可以不包含任何点
+        // maxPath: 从树中任意到任意点的最大路径，这条路径至少包含一个点
+        int singlePath, maxPath; 
+        ResultType(int singlePath, int maxPath) {
+            this.singlePath = singlePath;
+            this.maxPath = maxPath;
+        }
+    }
+
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, Integer.MIN_VALUE);
+        }
+        // Divide
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        // Conquer
+        int singlePath = Math.max(left.singlePath, right.singlePath) + root.val;
+        singlePath = Math.max(singlePath, 0);
+
+        int maxPath = Math.max(left.maxPath, right.maxPath);
+        maxPath = Math.max(maxPath, left.singlePath + right.singlePath + root.val);
+
+        return new ResultType(singlePath, maxPath);
+    }
+
+    public int maxPathSum(TreeNode root) {
+        ResultType result = helper(root);
+        return result.maxPath;
+    }
+}
+
+
+// Version 2:
+// SinglePath也定义为，至少包含一个点。
+public class Solution {
+    /**
+     * @param root: The root of binary tree.
+     * @return: An integer.
+     */
+    private class ResultType {
+        int singlePath, maxPath;
+        ResultType(int singlePath, int maxPath) {
+            this.singlePath = singlePath;
+            this.maxPath = maxPath;
+        }
+    }
+
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(Integer.MIN_VALUE, Integer.MIN_VALUE);
+        }
+        // Divide
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+
+        // Conquer
+        int singlePath =
+            Math.max(0, Math.max(left.singlePath, right.singlePath)) + root.val;
+
+        int maxPath = Math.max(left.maxPath, right.maxPath);
+        maxPath = Math.max(maxPath,
+                           Math.max(left.singlePath, 0) + 
+                           Math.max(right.singlePath, 0) + root.val);
+
+        return new ResultType(singlePath, maxPath);
+    }
+
+    public int maxPathSum(TreeNode root) {
+        ResultType result = helper(root);
+        return result.maxPath;
+    }
+
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-path-sum-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-path-sum-ii.md"
new file mode 100644
index 0000000..fa5ff2d
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-path-sum-ii.md"
@@ -0,0 +1,44 @@
+# 二叉树的路径和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-path-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树和一个目标值，设计一个算法找到二叉树上的和为该目标值的所有路径。路径可以从任何节点出发和结束，但是需要是一条一直往下走的路线。也就是说，路径上的节点的层级是逐个递增的。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @param {int} target an integer
+    # @return {int[][]} all valid paths
+    def binaryTreePathSum2(self, root, target):
+        # Write your code here
+        result = []
+        path = []
+        if root is None:
+            return result
+        self.dfs(root, path, result, 0,  target)
+        return result
+
+    def dfs(self, root, path, result, l, target):
+        if root is None:
+            return
+        path.append(root.val)
+        tmp = target
+        for i in xrange(l , -1, -1):
+            tmp -= path[i]
+            if tmp == 0:
+                result.append(path[i:])
+
+        self.dfs(root.left, path, result, l + 1, target)
+        self.dfs(root.right, path, result, l + 1, target)
+
+        path.pop()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-path-sum-iii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-path-sum-iii.md"
new file mode 100644
index 0000000..5ba4597
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-path-sum-iii.md"
@@ -0,0 +1,94 @@
+# 二叉树的路径和 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-path-sum-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树和一个目标值，找到二叉树上所有的和为该目标值的路径。路径可以从二叉树的任意节点出发，任意节点结束。
+
+ ### 样例说明
+ **样例 1:**
+
+```plain
+输入：{1,2,3,4},6
+输出：[[2, 4],[2, 1, 3],[3, 1, 2],[4, 2]]
+解释：
+该树如下：
+    1
+   / \
+  2   3
+ /
+4
+```
+
+**样例 2:**
+
+```plain
+输入：{1,2,3,4},3
+输出：[[1,2],[2,1],[3]]
+解释：
+该树如下：
+    1
+   / \
+  2   3
+ /
+4
+```
+ ### 参考代码
+ 使用dfs搜索的办法进行查找，可以进行相关的嵌套，从而达到结果
+```java
+/**
+ * Definition of ParentTreeNode:
+ * 
+ * class ParentTreeNode {
+ *     public int val;
+ *     public ParentTreeNode parent, left, right;
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @param target an integer
+     * @return all valid paths
+     */
+    public List<List<Integer>> binaryTreePathSum3(ParentTreeNode root, int target) {
+        // Write your code here
+        List<List<Integer>> results = new ArrayList<List<Integer>>();
+        dfs(root, target, results);
+        return results;
+    }
+    
+    public void dfs(ParentTreeNode root, int target, List<List<Integer>> results) {
+        if (root == null)
+            return;
+
+        List<Integer> path = new ArrayList<Integer>();
+        findSum(root, null, target, path, results);
+
+        dfs(root.left, target, results);
+        dfs(root.right, target, results);
+    }
+
+    public void findSum(ParentTreeNode root, ParentTreeNode father, int target,
+                 List<Integer> path, List<List<Integer>> results) {
+        path.add(root.val);
+        target -= root.val;
+        
+        if (target == 0) {
+            ArrayList<Integer> tmp = new ArrayList<Integer>();
+            Collections.addAll(tmp,  new  Integer[path.size()]); 
+            Collections.copy(tmp, path); 
+            results.add(tmp);
+        }
+
+        if (root.parent != null && root.parent != father)
+            findSum(root.parent, root, target, path, results);
+
+        if (root.left != null && root.left  != father)
+            findSum(root.left, root, target, path, results);
+
+        if (root.right != null && root.right != father)
+            findSum(root.right, root, target, path, results);
+
+        path.remove(path.size() - 1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-path-sum.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-path-sum.md"
new file mode 100644
index 0000000..60beeae
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-path-sum.md"
@@ -0,0 +1,80 @@
+# 二叉树的路径和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-path-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，找出所有路径中各节点相加总和等于给定 `目标值` 的路径。
+
+一个有效的路径，指的是从根节点到叶节点的路径。
+ ### 样例说明
+ **样例1:**
+
+```plain
+输入:
+{1,2,4,2,3}
+5
+输出: [[1, 2, 2],[1, 4]]
+说明:
+这棵树如下图所示：
+	     1
+	    / \
+	   2   4
+	  / \
+	 2   3
+对于目标总和为5，很显然1 + 2 + 2 = 1 + 4 = 5
+```
+
+**样例2:**
+
+```plain
+输入:
+{1,2,4,2,3}
+3
+输出: []
+说明:
+这棵树如下图所示：
+	     1
+	    / \
+	   2   4
+	  / \
+	 2   3
+注意到题目要求我们寻找从根节点到叶子节点的路径。
+1 + 2 + 2 = 5, 1 + 2 + 3 = 6, 1 + 4 = 5 
+这里没有合法的路径满足和等于3.
+```
+
+
+ ### 参考代码
+ ```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @param {int} target an integer
+    # @return {int[][]} all valid paths
+    def binaryTreePathSum(self, root, target):
+        # Write your code here
+        result = []
+        path = []
+        self.dfs(root, path, result, 0,  target)
+
+        return result
+
+    def dfs(self, root, path, result, len, target):
+        if root is None:
+            return
+        path.append(root.val)
+        len += root.val
+
+        if root.left is None and root.right is None and len == target:
+            result.append(path[:])
+
+        self.dfs(root.left, path, result, len, target)
+        self.dfs(root.right, path, result, len, target)
+
+        path.pop()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-paths.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-paths.md"
new file mode 100644
index 0000000..2757ca9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-paths.md"
@@ -0,0 +1,59 @@
+# 二叉树的所有路径
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-paths/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，找出从根节点到叶子节点的所有路径。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,#,5}
+输出：["1->2->5","1->3"]
+解释：
+   1
+ /   \
+2     3
+ \
+  5
+```
+**样例 2:**
+```
+输入：{1,2}
+输出：["1->2"]
+解释：
+   1
+ /   
+2     
+```
+ ### 参考代码
+ 使用分治算法(Divide Conquer)
+```java
+// version 1: Divide Conquer
+public class Solution {
+    /**
+     * @param root the root of the binary tree
+     * @return all root-to-leaf paths
+     */
+    public List<String> binaryTreePaths(TreeNode root) {
+        List<String> paths = new ArrayList<>();
+        if (root == null) {
+            return paths;
+        }
+        
+        List<String> leftPaths = binaryTreePaths(root.left);
+        List<String> rightPaths = binaryTreePaths(root.right);
+        for (String path : leftPaths) {
+            paths.add(root.val + "->" + path);
+        }
+        for (String path : rightPaths) {
+            paths.add(root.val + "->" + path);
+        }
+        
+        // root is a leaf
+        if (paths.size() == 0) {
+            paths.add("" + root.val);
+        }
+        
+        return paths;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-postorder-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-postorder-traversal.md"
new file mode 100644
index 0000000..7b92ec9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-postorder-traversal.md"
@@ -0,0 +1,86 @@
+# 二叉树的后序遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-postorder-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树，返回其节点值的后序遍历。</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3}
+输出：[2,3,1]
+解释： 
+   1
+  / \
+ 2   3
+它将被序列化为{1,2,3}
+后序遍历
+```
+**样例 2:**
+```
+输入：{1,#,2,3}
+输出：[3,2,1]
+解释： 
+1
+ \
+  2
+ /
+3
+它将被序列化为{1,#,2,3}
+后序遍历
+```
+ ### 参考代码
+ Given a binary tree, return the postorder traversal of its nodes' values.&nbsp;<div>For example:&nbsp;</div><div>Given binary tree {1,#,2,3},<div><br></div><div>1<div>&nbsp; \&nbsp;</div><div>&nbsp; &nbsp;2&nbsp;</div><div>&nbsp; /&nbsp;</div><div>&nbsp;3&nbsp;</div><div><br></div><div>return [3,2,1].&nbsp;</div><div><br></div><div>&nbsp;Note: Recursive solution is trivial, could you do it iteratively?</div></div></div><div><br></div><div>九章算法微博：<a href="http://weibo.com/3948019741/Bq8XobZFD" target="_blank">面试搞定二叉树大总结</a></div>
+考点：
+* 二叉树的后序遍历
+题解：
+使用栈进行二叉树后序遍历，首先对左子树进行遍历压入栈中，直至左子树为空，然后访问右子树。故每个节点会被访问两次，当节点被第二次访问时，该节点出栈。
+```java
+//Recursive
+public ArrayList<Integer> postorderTraversal(TreeNode root) {
+    ArrayList<Integer> result = new ArrayList<Integer>();
+
+    if (root == null) {
+        return result;
+    }
+
+    result.addAll(postorderTraversal(root.left));
+    result.addAll(postorderTraversal(root.right));
+    result.add(root.val);
+
+    return result;   
+}
+
+//Iterative
+public ArrayList<Integer> postorderTraversal(TreeNode root) {
+    ArrayList<Integer> result = new ArrayList<Integer>();
+    Stack<TreeNode> stack = new Stack<TreeNode>();
+    TreeNode prev = null; // previously traversed node
+    TreeNode curr = root;
+
+    if (root == null) {
+        return result;
+    }
+
+    stack.push(root);
+    while (!stack.empty()) {
+        curr = stack.peek();
+        if (prev == null || prev.left == curr || prev.right == curr) { // traverse down the tree
+            if (curr.left != null) {
+                stack.push(curr.left);
+            } else if (curr.right != null) {
+                stack.push(curr.right);
+            }
+        } else if (curr.left == prev) { // traverse up the tree from the left
+            if (curr.right != null) {
+                stack.push(curr.right);
+            }
+        } else { // traverse up the tree from the right
+            result.add(curr.val);
+            stack.pop();
+        }
+        prev = curr;
+    }
+
+    return result;
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-preorder-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-preorder-traversal.md"
new file mode 100644
index 0000000..7493978
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-preorder-traversal.md"
@@ -0,0 +1,113 @@
+# 二叉树的前序遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-preorder-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树，返回其节点值的前序遍历。</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3}
+输出：[1,2,3]
+解释：
+   1
+  / \
+ 2   3
+它将被序列化为{1,2,3}
+前序遍历
+```
+**样例 2:**
+```
+输入：{1,#,2,3}
+输出：[1,2,3]
+解释：
+1
+ \
+  2
+ /
+3
+它将被序列化为{1,#,2,3}
+前序遍历
+```
+ ### 参考代码
+ Given a binary tree, return the preorder traversal of its nodes' values.&nbsp;<div><br></div><div>For example:&nbsp;</div><div>Given binary tree {1,#,2,3},&nbsp;</div><div><br></div><div>&nbsp;1&nbsp;</div><div>&nbsp; &nbsp;\&nbsp;</div><div>&nbsp; &nbsp; &nbsp;2&nbsp;</div><div>&nbsp; &nbsp; /&nbsp;</div><div>&nbsp; 3&nbsp;</div><div>return [1,2,3].&nbsp;</div><div><br></div><div>&nbsp;Note: Recursive solution is trivial, could you do it iteratively?</div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;"><br></span></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博：</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/BzQahxewZ" target="_blank">http://weibo.com/3948019741/BzQahxewZ</a></span></font><br></div>
+考点：
+* 二叉树的前序遍历
+
+题解：
+非递归方式实现前序遍历时，首先存入当前节点值，然后先将右儿子压入栈中，再将左儿子压入栈中。对栈中元素遍历访问。
+```java
+Version 0: Non-Recursion (Recommend)
+/**
+ * Definition for binary tree
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    public List<Integer> preorderTraversal(TreeNode root) {
+        Stack<TreeNode> stack = new Stack<TreeNode>();
+        List<Integer> preorder = new ArrayList<Integer>();
+        
+        if (root == null) {
+            return preorder;
+        }
+        
+        stack.push(root);
+        while (!stack.empty()) {
+            TreeNode node = stack.pop();
+            preorder.add(node.val);
+            if (node.right != null) {
+                stack.push(node.right);
+            }
+            if (node.left != null) {
+                stack.push(node.left);
+            }
+        }
+        
+        return preorder;
+    }
+}
+
+//Version 1: Traverse
+public class Solution {
+    public ArrayList<Integer> preorderTraversal(TreeNode root) {
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        traverse(root, result);
+        return result;
+    }
+    // 把root为跟的preorder加入result里面
+    private void traverse(TreeNode root, ArrayList<Integer> result) {
+        if (root == null) {
+            return;
+        }
+
+        result.add(root.val);
+        traverse(root.left, result);
+        traverse(root.right, result);
+    }
+}
+
+//Version 2: Divide & Conquer
+public class Solution {
+    public ArrayList<Integer> preorderTraversal(TreeNode root) {
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        // null or leaf
+        if (root == null) {
+            return result;
+        }
+
+        // Divide
+        ArrayList<Integer> left = preorderTraversal(root.left);
+        ArrayList<Integer> right = preorderTraversal(root.right);
+
+        // Conquer
+        result.add(root.val);
+        result.addAll(left);
+        result.addAll(right);
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-right-side-view.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-right-side-view.md"
new file mode 100644
index 0000000..c796c9e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-right-side-view.md"
@@ -0,0 +1,68 @@
+# 二叉树的右视图
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-right-side-view/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一棵二叉树，想象自己站在它的右侧，按照从顶部到底部的顺序，返回从右侧所能看到的节点值。
+ ### 样例说明
+ **样例1**
+
+```
+输入: {1,2,3,#,5,#,4}
+输出: [1,3,4]
+说明:
+   1            
+ /   \
+2     3         
+ \     \
+  5     4       
+```
+
+**样例2**
+
+```plain
+输入: {1,2,3}
+输出: [1,3]
+说明:
+   1            
+ /   \
+2     3        
+```
+
+
+ ### 参考代码
+ dfs暴力即可。
+```java
+/**
+ * Definition for binary tree
+ * public class TreeNode {
+ *     int val;
+ *     TreeNode left;
+ *     TreeNode right;
+ *     TreeNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    private void dfs(HashMap<Integer, Integer> depthToValue, TreeNode node, int depth) {
+        if (node == null) {
+            return;
+        }
+        
+        depthToValue.put(depth, node.val);
+        dfs(depthToValue, node.left, depth + 1);
+        dfs(depthToValue, node.right, depth + 1);
+    }
+    
+    public List<Integer> rightSideView(TreeNode root) {
+        HashMap<Integer, Integer> depthToValue = new HashMap<Integer, Integer>();
+        dfs(depthToValue, root, 1);
+        
+        int depth = 1;
+        List<Integer> result = new ArrayList<Integer>();
+        while (depthToValue.containsKey(depth)) {
+            result.add(depthToValue.get(depth));
+            depth++;
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-serialization.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-serialization.md"
new file mode 100644
index 0000000..63e41f2
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-serialization.md"
@@ -0,0 +1,101 @@
+# 二叉树的序列化和反序列化
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-serialization/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个算法，并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”，读取文件后重建同样的二叉树被称为“反序列化”。
+
+如何反序列化或序列化二叉树是没有限制的，你只需要确保可以将二叉树序列化为一个字符串，并且可以将字符串反序列化为原来的树结构。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+class Solution {
+    /**
+     * This method will be invoked first, you should design your own algorithm 
+     * to serialize a binary tree which denote by a root node to a string which
+     * can be easily deserialized by your own "deserialize" method later.
+     */
+    public String serialize(TreeNode root) {
+        if (root == null) {
+            return "{}";
+        }
+
+        ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
+        queue.add(root);
+
+        for (int i = 0; i < queue.size(); i++) {
+            TreeNode node = queue.get(i);
+            if (node == null) {
+                continue;
+            }
+            queue.add(node.left);
+            queue.add(node.right);
+        }
+
+        while (queue.get(queue.size() - 1) == null) {
+            queue.remove(queue.size() - 1);
+        }
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        sb.append(queue.get(0).val);
+        for (int i = 1; i < queue.size(); i++) {
+            if (queue.get(i) == null) {
+                sb.append(",#");
+            } else {
+                sb.append(",");
+                sb.append(queue.get(i).val);
+            }
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+    
+    /**
+     * This method will be invoked second, the argument data is what exactly
+     * you serialized at method "serialize", that means the data is not given by
+     * system, it's given by your own serialize method. So the format of data is
+     * designed by yourself, and deserialize it here as you serialize it in 
+     * "serialize" method.
+     */
+    public TreeNode deserialize(String data) {
+        if (data.equals("{}")) {
+            return null;
+        }
+        String[] vals = data.substring(1, data.length() - 1).split(",");
+        ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
+        TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
+        queue.add(root);
+        int index = 0;
+        boolean isLeftChild = true;
+        for (int i = 1; i < vals.length; i++) {
+            if (!vals[i].equals("#")) {
+                TreeNode node = new TreeNode(Integer.parseInt(vals[i]));
+                if (isLeftChild) {
+                    queue.get(index).left = node;
+                } else {
+                    queue.get(index).right = node;
+                }
+                queue.add(node);
+            }
+            if (!isLeftChild) {
+                index++;
+            }
+            isLeftChild = !isLeftChild;
+        }
+        return root;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-vertical-order-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-vertical-order-traversal.md"
new file mode 100644
index 0000000..8092d04
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-vertical-order-traversal.md"
@@ -0,0 +1,134 @@
+# 二叉树垂直遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-vertical-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定二叉树，返回其节点值的垂直遍历顺序。 (即逐列从上到下)。
+如果两个节点在同一行和同一列中，则顺序应 **从左到右**。
+ ### 样例说明
+ **样例1**
+```
+输入： {3,9,20,#,#,15,7}
+输出： [[9],[3,15],[20],[7]]
+解释：
+   3
+  /\
+ /  \
+ 9  20
+    /\
+   /  \
+  15   7
+```
+**样例2**
+```
+输入： {3,9,8,4,0,1,7}
+输出：[[4],[9],[3,0,1],[8],[7]]
+解释：
+     3
+    /\
+   /  \
+   9   8
+  /\  /\
+ /  \/  \
+ 4  01   7
+```
+ ### 参考代码
+ 对于一棵树，我们设其根节点的位置为0。
+对于任一非叶子节点，若其位置为x，设其左儿子的位置为x-1，右儿子位置为x+1。
+按照以上规则bfs遍历整棵树统计所有节点的位置，然后按位置从小到大输出所有节点。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the vertical order traversal
+     */
+    public List<List<Integer>> verticalOrder(TreeNode root) {
+        // Write your code here
+        List<List<Integer>> results = new ArrayList<>();
+        if (root == null) {
+            return results;
+        }
+        Map<Integer, List<Integer>> map = new TreeMap<Integer, List<Integer>>();
+        Queue<Integer> qCol = new LinkedList<>();
+        Queue<TreeNode> queue = new LinkedList<>();
+        queue.offer(root);
+        qCol.offer(0);
+        
+        while(!queue.isEmpty()) {
+            TreeNode curr = queue.poll();
+            int col = qCol.poll();
+            if(!map.containsKey(col)) {
+                map.put(col, new ArrayList<Integer>(Arrays.asList(curr.val)));
+            } else {
+                map.get(col).add(curr.val);
+            }
+            if(curr.left != null) {
+                queue.offer(curr.left);
+                qCol.offer(col - 1);
+            }
+            if(curr.right != null) {
+                queue.offer(curr.right);
+                qCol.offer(col + 1);
+            }
+        }
+        for(int n : map.keySet()) {
+            results.add(map.get(n));
+        }
+        return results;
+    }   
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the vertical order traversal
+     */
+    public List<List<Integer>> verticalOrder(TreeNode root) {
+        // Write your code here
+        List<List<Integer>> ans = new ArrayList<>();
+        if (root == null) {
+            return ans;
+        }
+
+        Map<Integer, List<Integer>> hash = new HashMap<>();
+        Queue<Integer> qCol = new LinkedList<>();
+        Queue<TreeNode> qNode = new LinkedList<>();
+
+        qCol.offer(0);
+        qNode.offer(root);
+
+        while (!qCol.isEmpty()) {                      // bfs
+            int c = qCol.poll();
+            TreeNode node = qNode.poll();
+
+            hash.putIfAbsent(c, new ArrayList<>());
+            hash.get(c).add(node.val);
+
+            if (node.left != null) {
+                qCol.offer(c - 1);
+                qNode.offer(node.left);
+            }
+            if (node.right != null) {
+                qCol.offer(c + 1);
+                qNode.offer(node.right);
+            }
+        }
+
+        for (int i = Collections.min(hash.keySet()); i <= Collections.max(hash.keySet()); i++) {
+            ans.add(hash.get(i));
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-zigzag-level-order-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-zigzag-level-order-traversal.md"
new file mode 100644
index 0000000..fd40965
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/binary-tree-zigzag-level-order-traversal.md"
@@ -0,0 +1,83 @@
+# 二叉树的锯齿形层次遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-zigzag-level-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树，返回其节点值的锯齿形层次遍历（先从左往右，下一层再从右往左，层与层之间交替进行）&nbsp;</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入:{1,2,3}
+输出:[[1],[3,2]]
+解释:
+    1
+   / \
+  2   3
+它将被序列化为 {1,2,3}
+```
+**样例 2:**
+```
+输入:{3,9,20,#,#,15,7}
+输出:[[3],[20,9],[15,7]]
+解释:
+    3
+   / \
+  9  20
+    /  \
+   15   7
+它将被序列化为 {3,9,20,#,#,15,7}
+```
+
+ ### 参考代码
+ 层序遍历完之后，看层数，偶数层reverse一下即可。
+```java
+public class Solution {
+    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
+        List<List<Integer>> result = new ArrayList<List<Integer>>();
+
+        if (root == null) {
+            return result;
+        }
+
+        Stack<TreeNode> currLevel = new Stack<TreeNode>();
+        Stack<TreeNode> nextLevel = new Stack<TreeNode>();
+        Stack<TreeNode> tmp;
+        
+        currLevel.push(root);
+        boolean normalOrder = true;
+
+        while (!currLevel.isEmpty()) {
+            ArrayList<Integer> currLevelResult = new ArrayList<Integer>();
+
+            while (!currLevel.isEmpty()) {
+                TreeNode node = currLevel.pop();
+                currLevelResult.add(node.val);
+
+                if (normalOrder) {
+                    if (node.left != null) {
+                        nextLevel.push(node.left);
+                    }
+                    if (node.right != null) {
+                        nextLevel.push(node.right);
+                    }
+                } else {
+                    if (node.right != null) {
+                        nextLevel.push(node.right);
+                    }
+                    if (node.left != null) {
+                        nextLevel.push(node.left);
+                    }
+                }
+            }
+
+            result.add(currLevelResult);
+            tmp = currLevel;
+            currLevel = nextLevel;
+            nextLevel = tmp;
+            normalOrder = !normalOrder;
+        }
+
+        return result;
+
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/boundary-of-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/boundary-of-binary-tree.md"
new file mode 100644
index 0000000..1452242
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/boundary-of-binary-tree.md"
@@ -0,0 +1,117 @@
+# 二叉树边界
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/boundary-of-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，从根开始返回其**逆时针**方向的边界值。边界包括左边界、叶和右边界，没有重复的节点。
+
+**左边界**的定义为从根到**最左边**节点的路径。**右边界**的定义为从根到**最右边**的节点的路径。
+
+如果根没有左子树或右子树，那么根本身就是最左边或者最右边的节点。注意，这个定义只适用于二叉树的根节点，而不适用于任何子树。
+
+而当根有左子树时，最左边的节点是：你以有先访问左子节点的方式遍历二叉树时，第一个碰到的叶子节点。最右边的节点的定义类似，方向相反。
+
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,#,2,3,4}
+输出: [1,3,4,2]
+解释:
+  1
+   \
+    2
+   / \
+  3   4 
+  根没有左子树，所以根本身是左边界。
+  叶节点为节点3和节点4。
+  右边界是节点1 2 4。注意逆时针方向意味着你应该输出反向右边界。
+  所以用逆时针顺序排列它们没有重复，我们得到[1,3,4,2]
+```
+
+**样例 2:**
+
+```
+输入: {1,2,3,4,5,6,#,#,#,7,8,9,10}
+输出: [1,2,4,7,8,9,10,6,3]
+解释: 
+          1
+     /          \
+    2            3
+   / \          / 
+  4   5        6   
+     / \      / \
+    7   8    9  10  
+  左边的边界是节点1 2 4。(4最左边的节点)
+  叶节点是节点4 7 8 9 10。
+  右边界是节点1 3 6 10。(10是最右边的节点)。
+  所以逆时针顺序排列，我们得到[1,2,4,7,8,9,10,6,3]
+```
+ ### 参考代码
+ 面试中更加容易被面试官接受的版本。
+虽然使用 DFS 但是没有使用任何的 Recursion。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param root: a TreeNode
+    @return: a list of integer
+    """
+    def boundaryOfBinaryTree(self, root):
+        if root is None:
+            return []
+            
+        left_boundary = self.find_left_boundary(root.left)
+        leaves = self.find_leaves(root)
+        right_boundary = self.find_right_boundary(root.right)
+        
+        if left_boundary and leaves and left_boundary[-1] == leaves[0]:
+            leaves = leaves[1:]
+        if leaves and right_boundary and leaves[-1] == right_boundary[-1]:
+            leaves = leaves[:-1]
+        return [root.val] + left_boundary + leaves + list(reversed(right_boundary))
+
+    def find_leaves(self, root):
+        stack = [root]
+        leaves = []
+        while stack:
+            node = stack.pop()
+            if not node.left and not node.right:
+                leaves.append(node.val)
+            if node.right:
+                stack.append(node.right)
+            if node.left:
+                stack.append(node.left)
+        return leaves
+        
+    def find_left_boundary(self, root):
+        left_boundary = []
+        while root is not None:
+            left_boundary.append(root.val)
+            if root.left:
+                root = root.left
+            elif root.right:
+                root = root.right
+            else:
+                break
+        return left_boundary
+        
+    def find_right_boundary(self, root):
+        right_boundary = []
+        while root is not None:
+            right_boundary.append(root.val)
+            if root.right:
+                root = root.right
+            elif root.left:
+                root = root.left
+            else:
+                break
+        return right_boundary
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/clone-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/clone-binary-tree.md"
new file mode 100644
index 0000000..61bf058
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/clone-binary-tree.md"
@@ -0,0 +1,65 @@
+# 克隆二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/clone-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 深度复制一个二叉树。
+
+给定一个二叉树，返回一个他的 **克隆品** 。
+ ### 样例说明
+ **样例1:**
+
+```plain
+输入: {1,2,3,4,5}
+输出: {1,2,3,4,5}
+解释：
+样例中二叉树如下所示:
+     1
+   /  \
+  2    3
+ / \
+4   5
+```
+
+**样例2:**
+
+```plain
+输入: {1,2,3}
+输出: {1,2,3}
+解释：
+样例中二叉树如下所示:
+   1
+ /  \
+2    3
+```
+
+
+ ### 参考代码
+ 这题采用dfs（深度优先搜索）的方法，从根节点开始，一步步的去复制这一颗树。每次去复制他的左节点和右节点即可。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of binary tree
+     * @return root of new tree
+     */
+    public TreeNode cloneTree(TreeNode root) {
+        // Write your code here
+        if (root == null)
+            return null; //搜到了空节点，直接返回
+        TreeNode clone_root = new TreeNode(root.val); //创造当前深度的“根”
+        clone_root.left = cloneTree(root.left);  //左子树
+        clone_root.right = cloneTree(root.right); //右子树
+        return clone_root;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/complete-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/complete-binary-tree.md"
new file mode 100644
index 0000000..30d21ef
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/complete-binary-tree.md"
@@ -0,0 +1,98 @@
+# 完全二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/complete-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 判断一个二叉树是否是完全二叉树
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,4}
+输出：true
+解释：
+        1
+       / \
+      2   3
+     /
+    4
+
+是完全二叉树。
+```
+**样例 2:**
+```
+输入：{1,2,3,#,4}
+输出：false
+解释：
+        1
+       / \
+      2   3
+       \
+        4
+
+不是完全二叉树
+```
+ ### 参考代码
+ 根据每个结点的左子树和右子树的深度和是否满判断该结点的子树的类型
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+ 
+class ResultType {
+    public int depth;
+    public boolean isFull, isComplete;
+    ResultType(int depth, boolean isFull, boolean isComplete) {
+        this.depth = depth;
+        this.isFull = isFull;
+        this.isComplete = isComplete;
+    }
+}
+
+public class Solution {
+    /**
+     * @param root, the root of binary tree.
+     * @return true if it is a complete binary tree, or false.
+     */
+    public boolean isComplete(TreeNode root) {
+        ResultType result = helper(root);
+        return result.isComplete;
+    }
+    
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, true, true);
+        }
+        
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+        if (!left.isComplete) {
+            return new ResultType(-1, false, false);
+        }
+        
+        // depth is the same, left should be full and right should be complete
+        if (left.depth == right.depth) {
+            if (!left.isFull || !right.isComplete) {
+                return new ResultType(-1, false, false);
+            }
+            return new ResultType(left.depth + 1, right.isFull, true);
+        }
+        
+        // left.depth = right.depth + 1, left should be complete and right should be full
+        if (left.depth == right.depth + 1) {
+            if (!left.isComplete || !right.isFull) {
+                return new ResultType(-1, false, false);
+            }
+            return new ResultType(left.depth + 1, false, true);
+        }
+        
+        return new ResultType(-1, false, false);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/construct-binary-tree-from-inorder-and-postorder-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/construct-binary-tree-from-inorder-and-postorder-traversal.md"
new file mode 100644
index 0000000..ea7c8bd
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/construct-binary-tree-from-inorder-and-postorder-traversal.md"
@@ -0,0 +1,74 @@
+# 中序遍历和后序遍历树构造二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/construct-binary-tree-from-inorder-and-postorder-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>根据中序遍历和后序遍历树构造二叉树</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：[],[]
+输出：{}
+解释：
+二叉树为空
+```
+**样例 2:**
+```
+输入：[1,2,3],[1,3,2]
+输出：{2,1,3}
+解释：
+二叉树如下
+  2
+ / \
+1   3
+```
+
+
+ ### 参考代码
+ 根据当前后续序列的最后一个结点，在对应的中序遍历中找到位置，然后相同的方法，递归左右子树即可。
+```cpp
+#include <vector>
+#include "lintcode.h"
+#include <algorithm>
+using namespace std;
+
+/**
+ * Definition of TreeNode:
+ * class TreeNode {
+ * public:
+ *     int val;
+ *     TreeNode *left, *right;
+ *     TreeNode(int val) {
+ *         this->val = val;
+ *         this->left = this->right = NULL;
+ *     }
+ * }
+ */
+ 
+
+class Solution {
+    /**
+     *@param inorder : A list of integers that inorder traversal of a tree
+     *@param postorder : A list of integers that postorder traversal of a tree
+     *@return : Root of a tree
+     */
+public:
+    typedef vector<int>::iterator Iter;
+    TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
+        // write your code here
+        if (inorder.size() == 0)
+            return NULL;
+        return buildTreeRecur(inorder.begin(), inorder.end(), postorder.begin(), 
+        postorder.end());
+    }
+    TreeNode *buildTreeRecur(Iter istart, Iter iend, Iter pstart, Iter pend)
+    {
+        if(istart == iend)return NULL;
+        int rootval = *(pend-1);
+        Iter iterroot = find(istart, iend, rootval);
+        TreeNode *res = new TreeNode(rootval);
+        res->left = buildTreeRecur(istart, iterroot, pstart, pstart+(iterroot-istart));
+        res->right = buildTreeRecur(iterroot+1, iend, pstart+(iterroot-istart), pend-1);
+        return res;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/construct-binary-tree-from-preorder-and-inorder-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/construct-binary-tree-from-preorder-and-inorder-traversal.md"
new file mode 100644
index 0000000..c377348
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/construct-binary-tree-from-preorder-and-inorder-traversal.md"
@@ -0,0 +1,70 @@
+# 前序遍历和中序遍历树构造二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/construct-binary-tree-from-preorder-and-inorder-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 根据前序遍历和中序遍历树构造二叉树.
+ ### 样例说明
+ **样例 1:**
+```
+输入：[],[]
+输出：{}
+解释：
+二叉树为空
+```
+**样例 2:**
+```
+输入：[2,1,3],[1,2,3]
+输出：{2,1,3}
+解释：
+二叉树如下
+  2
+ / \
+1   3
+```
+
+ ### 参考代码
+ Given preorder and inorder traversal of a tree, construct the binary tree.
+
+Note:
+You may assume that duplicates do not exist in the tree.
+
+前序的第一个为根，在中序中找到根的位置。
+中序中根的左右两边即为左右子树的中序遍历。同时可知左子树的大小size-left。
+前序中根接下来的size-left个是左子树的前序遍历。
+由此可以递归处理左右子树。
+```java
+public class Solution {
+    private int findPosition(int[] arr, int start, int end, int key) {
+        int i;
+        for (i = start; i <= end; i++) {
+            if (arr[i] == key) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private TreeNode myBuildTree(int[] inorder, int instart, int inend,
+            int[] preorder, int prestart, int preend) {
+        if (instart > inend) {
+            return null;
+        }
+
+        TreeNode root = new TreeNode(preorder[prestart]);
+        int position = findPosition(inorder, instart, inend, preorder[prestart]);
+
+        root.left = myBuildTree(inorder, instart, position - 1,
+                preorder, prestart + 1, prestart + position - instart);
+        root.right = myBuildTree(inorder, position + 1, inend,
+                preorder, position - inend + preend + 1, preend);
+        return root;
+    }
+
+    public TreeNode buildTree(int[] preorder, int[] inorder) {
+        if (inorder.length != preorder.length) {
+            return null;
+        }
+        return myBuildTree(inorder, 0, inorder.length - 1, preorder, 0, preorder.length - 1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/convert-binary-tree-to-linked-lists-by-depth.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/convert-binary-tree-to-linked-lists-by-depth.md"
new file mode 100644
index 0000000..8373b33
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/convert-binary-tree-to-linked-lists-by-depth.md"
@@ -0,0 +1,124 @@
+# 将二叉树按照层级转化为链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-binary-tree-to-linked-lists-by-depth/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，设计一个算法为每一层的节点建立一个链表。也就是说，如果一棵二叉树有 `D` 层，那么你需要创建 `D` 条链表。
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,2,3,4}
+输出: [1->null,2->3->null,4->null]
+解释: 
+        1
+       / \
+      2   3
+     /
+    4
+```
+
+**样例 2:**
+
+```
+输入: {1,#,2,3}
+输出: [1->null,2->null,3->null]
+解释: 
+    1
+     \
+      2
+     /
+    3
+```
+ ### 参考代码
+ 考点：
+* 搜索遍历
+
+题解：采用基本的bfs搜索实现层序遍历即可。分别使用DFS和BFS两种解法解决这个问题。时间复杂度都是O(n)。
+```python
+# BFS 解法
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+Definition for singly-linked list.
+class ListNode:
+    def __init__(self, x):
+        self.val = x
+        self.next = None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @return {ListNode[]} a lists of linked list
+    def binaryTreeToLists(self, root):
+        result = []
+        if root is None:
+            return result
+            
+        import Queue
+        queue = Queue.Queue()
+        
+        queue.put(root)
+        
+        dummy = ListNode(0)
+        
+        lastNode = None
+        
+        while not queue.empty():
+            dummy.next = None
+            lastNode = dummy
+            size = queue.qsize()
+            for i in xrange(size):
+                head = queue.get()
+                lastNode.next = ListNode(head.val)
+                lastNode = lastNode.next
+
+                if head.left is not None:
+                    queue.put(head.left)
+                if head.right is not None:
+                    queue.put(head.right)
+        
+            result.append(dummy.next)
+        
+        return result
+    
+
+
+# DFS 解法
+
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+Definition for singly-linked list.
+class ListNode:
+    def __init__(self, x):
+        self.val = x
+        self.next = None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @return {ListNode[]} a lists of linked list
+    def binaryTreeToLists(self, root):
+        # Write your code here
+        result = []
+        self.dfs(root, 1, result)
+        return result
+
+    def dfs(self, root, depth, result):
+        if root is None:
+            return
+        node = ListNode(root.val)
+        if len(result) < depth:
+            result.append(node)
+        else:
+            node.next = result[depth-1]
+            result[depth-1] = node
+        
+        self.dfs(root.right, depth + 1, result)
+        self.dfs(root.left, depth + 1, result)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/flatten-binary-tree-to-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/flatten-binary-tree-to-linked-list.md"
new file mode 100644
index 0000000..287e8ce
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/flatten-binary-tree-to-linked-list.md"
@@ -0,0 +1,74 @@
+# 将二叉树拆成链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/flatten-binary-tree-to-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一棵二叉树按照前序遍历拆解成为一个 `假链表`。所谓的假链表是说，用二叉树的 *right* 指针，来表示链表中的 *next* 指针。
+ ### 样例说明
+ **样例 1：**
+```
+输入：{1,2,5,3,4,#,6}
+输出：{1,#,2,#,3,#,4,#,5,#,6}
+解释：
+     1
+    / \
+   2   5
+  / \   \
+ 3   4   6
+ 
+1
+\
+ 2
+  \
+   3
+    \
+     4
+      \
+       5
+        \
+         6
+```
+**样例 2：**
+```
+输入：{1}
+输出：{1}
+解释：
+         1
+         1
+```
+
+ ### 参考代码
+ 使用 Divide & Conquer
+分治函数 return 这个 tree 的最后一个点。> 引用文本
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param root: a TreeNode, the root of the binary tree
+    @return: nothing
+    """
+    def flatten(self, root):
+        self.flatten_and_return_last_node(root)
+        
+    # restructure and return last node in preorder
+    def flatten_and_return_last_node(self, root):
+        if root is None:
+            return None
+            
+        left_last = self.flatten_and_return_last_node(root.left)
+        right_last = self.flatten_and_return_last_node(root.right)
+        
+        # connect 
+        if left_last is not None:
+            left_last.right = root.right
+            root.right = root.left
+            root.left = None
+            
+        return right_last or left_last or root
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/identical-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/identical-binary-tree.md"
new file mode 100644
index 0000000..96b2bfb
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/identical-binary-tree.md"
@@ -0,0 +1,44 @@
+# 等价二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/identical-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 检查两棵二叉树是否等价。等价的意思是说，首先两棵二叉树必须拥有相同的结构，并且每个对应位置上的节点上的数都相等。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```cpp
+/**
+ * Definition of TreeNode:
+ * class TreeNode {
+ * public:
+ *     int val;
+ *     TreeNode *left, *right;
+ *     TreeNode(int val) {
+ *         this->val = val;
+ *         this->left = this->right = NULL;
+ *     }
+ * }
+ */
+class Solution {
+public:
+    /**
+     * @aaram a, b, the root of binary trees.
+     * @return true if they are identical, or false.
+     */
+    bool isIdentical(TreeNode* a, TreeNode* b) {
+        // Write your code here
+        if(!a && !b)
+            return true;
+        else if(!a && b)
+            return false;
+        else if(a && !b)
+            return false;
+        else {
+            if(a->val != b->val)
+                return false;
+            else
+                return isIdentical(a->left, b->left) && isIdentical(a->right, b->right);
+        }
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/invert-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/invert-binary-tree.md"
new file mode 100644
index 0000000..923088c
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/invert-binary-tree.md"
@@ -0,0 +1,66 @@
+# 翻转二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/invert-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 翻转一棵二叉树。左右子树交换。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,3,#}
+输出: {1,#,3}
+解释:
+	  1    1
+	 /  =>  \
+	3        3
+```
+
+**样例 2:**
+```
+输入: {1,2,3,#,#,4}
+输出: {1,3,2,#,4}
+解释: 
+	
+      1         1
+     / \       / \
+    2   3  => 3   2
+       /       \
+      4         4
+```
+ ### 参考代码
+ 考点：
+* 二叉树
+* 搜索
+
+题解：
+递归过程中直接交换当前节点的左右子树，构造新的二叉树返回即可。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: a TreeNode, the root of the binary tree
+     * @return: nothing
+     */
+    public void invertBinaryTree(TreeNode root) {
+        if (root == null) {
+            return;
+        }
+        TreeNode temp = root.left;
+        root.left = root.right;
+        root.right = temp;
+        
+        invertBinaryTree(root.left);
+        invertBinaryTree(root.right);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/maximum-depth-of-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/maximum-depth-of-binary-tree.md"
new file mode 100644
index 0000000..937e43c
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/maximum-depth-of-binary-tree.md"
@@ -0,0 +1,53 @@
+# 二叉树的最大深度
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-depth-of-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，找出其最大深度。
+
+二叉树的深度为根节点到最远叶子节点的距离。
+ ### 样例说明
+ **样例  1:**
+
+```
+输入: tree = {}
+输出: 0	
+样例解释: 空树的深度是0。
+```
+**样例  2:**
+
+```
+输入: tree = {1,2,3,#,#,4,5}
+输出: 3
+样例解释: 树表示如下，深度是3
+   1
+  / \                
+ 2   3                
+    / \                
+   4   5
+它将被序列化为{1,2,3,#,#,4,5}
+```
+
+ ### 参考代码
+ Given a binary tree, find its maximum depth.
+
+The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.<div><br></div><div>详细解答请至九章微博：<a href="http://weibo.com/3948019741/BBY7gwi89" target="_blank">http://weibo.com/3948019741/BBY7gwi89</a></div>
+
+简单的树的遍历，点i为根的树高度，等于高度最大的子树的高度+1。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root: The root of binary tree.
+    @return: An integer
+    """ 
+    def maxDepth(self, root):
+        if root is None:
+            return 0
+        return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/minimum-depth-of-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/minimum-depth-of-binary-tree.md"
new file mode 100644
index 0000000..73217da
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/minimum-depth-of-binary-tree.md"
@@ -0,0 +1,75 @@
+# 二叉树的最小深度
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-depth-of-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，找出其最小深度。
+
+二叉树的最小深度为根节点到最近叶子节点的最短路径上的节点数量。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {}
+输出: 0
+```
+
+**样例 2:**
+
+```
+输入:  {1,#,2,3}
+输出: 3	
+解释:
+	1
+	 \ 
+	  2
+	 /
+	3    
+它将被序列化为 {1,#,2,3}
+```
+
+**样例 3:**
+
+```
+输入:  {1,2,3,#,#,4,5}
+输出: 2	
+解释: 
+      1
+     / \ 
+    2   3
+       / \
+      4   5  
+它将被序列化为 {1,2,3,#,#,4,5}
+```
+ ### 参考代码
+ Given a binary tree, find its minimum depth.
+
+The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.
+
+考点：
+* 二叉树遍历
+* 搜索
+
+
+题解：直接搜索给出的二叉树即可。
+```java
+public class Solution {
+    public int minDepth(TreeNode root) {
+        if (root == null) {
+            return 0;
+        }
+        return getMin(root);
+    }
+
+    public int getMin(TreeNode root){
+        if (root == null) {
+            return Integer.MAX_VALUE;
+        }
+
+        if (root.left == null && root.right == null) {
+            return 1;
+        }
+
+        return Math.min(getMin(root.left), getMin(root.right)) + 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/serialize-and-deserialize-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/serialize-and-deserialize-binary-tree.md"
new file mode 100644
index 0000000..4e82a1a
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/serialize-and-deserialize-binary-tree.md"
@@ -0,0 +1,108 @@
+# 二叉树的序列化和反序列化
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/serialize-and-deserialize-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个算法，并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”，读取文件后重建同样的二叉树被称为“反序列化”。
+
+如何反序列化或序列化二叉树是没有限制的，你只需要确保可以将二叉树序列化为一个字符串，并且可以将字符串反序列化为原来的树结构。
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入：{3,9,20,#,#,15,7}
+输出：{3,9,20,#,#,15,7}
+解释：
+二叉树 {3,9,20,#,#,15,7}，表示如下的树结构：
+	  3
+	 / \
+	9  20
+	  /  \
+	 15   7
+它将被序列化为 {3,9,20,#,#,15,7}
+```
+**样例 2：**
+```
+输入：{1,2,3}
+输出：{1,2,3}
+解释：
+二叉树 {1,2,3}，表示如下的树结构：
+   1
+  / \
+ 2   3
+它将被序列化为 {1,2,3}
+```
+我们的数据是进行 BFS 遍历得到的。当你测试结果 Wrong Answer 时，你可以作为输入调试你的代码。
+
+你可以采用其他的方法进行序列化和反序列化。
+ ### 参考代码
+ 使用 BFS 的方法来 serialize
+```python
+from collections import deque
+
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+
+class Solution:
+    """
+    @param root: An object of TreeNode, denote the root of the binary tree.
+    This method will be invoked first, you should design your own algorithm 
+    to serialize a binary tree which denote by a root node to a string which
+    can be easily deserialized by your own "deserialize" method later.
+    """
+    def serialize(self, root):
+        if root is None:
+            return ""
+            
+        # use bfs to serialize the tree
+        queue = deque([root])
+        bfs_order = []
+        while queue:
+            node = queue.popleft()
+            bfs_order.append(str(node.val) if node else '#')
+            if node:
+                queue.append(node.left)
+                queue.append(node.right)
+            
+        return ' '.join(bfs_order)
+
+    """
+    @param data: A string serialized by your serialize method.
+    This method will be invoked second, the argument data is what exactly
+    you serialized at method "serialize", that means the data is not given by
+    system, it's given by your own serialize method. So the format of data is
+    designed by yourself, and deserialize it here as you serialize it in 
+    "serialize" method.
+    """
+    def deserialize(self, data):
+        # None or ""
+        if not data:
+            return None
+
+        bfs_order = [
+            TreeNode(int(val)) if val != '#' else None
+            for val in data.split()
+        ]
+        root = bfs_order[0]
+        fast_index = 1
+        
+        nodes, slow_index = [root], 0
+        while slow_index < len(nodes):
+            node = nodes[slow_index]
+            slow_index += 1
+            node.left = bfs_order[fast_index]
+            node.right = bfs_order[fast_index + 1]
+            fast_index += 2
+            
+            if node.left:
+                nodes.append(node.left)
+            if node.right:
+                nodes.append(node.right)
+        
+        return root
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/symmetric-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/symmetric-binary-tree.md"
new file mode 100644
index 0000000..8413443
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/symmetric-binary-tree.md"
@@ -0,0 +1,61 @@
+# 对称二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/symmetric-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一颗二叉树，判断是否是对称二叉树
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,2,3,4,4,3}
+输出：true
+解释：
+
+         1
+        / \
+       2   2
+      / \ / \
+      3 4 4 3
+
+是一个对称的二叉树。
+```
+**样例 2:**
+```
+输入：{1,2,2,#,3,#,3}
+输出：false
+解释：
+
+         1
+        / \
+        2  2
+        \   \
+         3   3
+
+不是对称的二叉树。
+```
+ ### 参考代码
+ 递归地判断是否有对应结点
+```python
+1"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param root, the root of binary tree.
+    @return true if it is a mirror of itself, or false.
+    """
+    def help(self, p, q):
+        if p == None and q == None: return True
+        if p and q and p.val == q.val:
+            return self.help(p.right, q.left) and self.help(p.left, q.right)
+        return False
+    
+    def isSymmetric(self, root):
+        # Write your code here
+        if root:
+            return self.help(root.left, root.right)
+        return True
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/tweaked-identical-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/tweaked-identical-binary-tree.md"
new file mode 100644
index 0000000..d8848b7
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/tweaked-identical-binary-tree.md"
@@ -0,0 +1,58 @@
+# 扭转后等价的二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/tweaked-identical-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 检查两棵二叉树是否在经过若干次扭转后可以等价。扭转的定义是，交换任意节点的左右子树。等价的定义是，两棵二叉树必须为相同的结构，并且对应位置上的节点的值要相等。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,4}，{1,3,2,#,#,#,4}
+输出：true
+解释：
+        1             1
+       / \           / \
+      2   3    和   3   2
+     /                   \
+    4                     4
+
+是相同的。
+```
+**样例 2:**
+```
+输入：{1,2,3,4}，{1,3,2,4}
+输出：false
+解释：
+
+        1             1
+       / \           / \
+      2   3    和   3   2
+     /             /
+    4             4
+
+不一样。
+```
+ ### 参考代码
+ 判断该子树不交换左右子树和交换左右子树是否能与对应的子树一致，往上回溯即可
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param a, b, the root of binary trees.
+    @return true if they are tweaked identical, or false.
+    """
+    def isTweakedIdentical(self, a, b):
+        # Write your code here
+        if a == None and b == None: return True
+        if a and b and a.val == b.val:
+            return self.isTweakedIdentical(a.left, b.left) and \
+                    self.isTweakedIdentical(a.right, b.right) or \
+                    self.isTweakedIdentical(a.left, b.right) and \
+                    self.isTweakedIdentical(a.right, b.left)
+        return False
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/verify-preorder-serialization-of-a-binary-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/verify-preorder-serialization-of-a-binary-tree.md"
new file mode 100644
index 0000000..da85513
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\344\272\214\345\217\211\346\240\221\345\210\206\346\262\273/verify-preorder-serialization-of-a-binary-tree.md"
@@ -0,0 +1,83 @@
+# 验证二叉树的前序序列化
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/verify-preorder-serialization-of-a-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 二叉树序列化的一种方法是使用先序遍历。 当我们遇到非空节点时，我们记录节点的值。如果是一个空节点，我们使用诸如#的标记值。
+~~~~.
+     _9_
+    /   \
+   3     2
+  / \   / \
+ 4   1  #  6
+/ \ / \   / \
+# # # #   # #
+~~~~
+例如，上面的二叉树可以序列化为字符串”9,3,4,#,#,1,#,#,2,#,6,#,#”，其中#表示空节点。
+
+给定一个用逗号分隔的字符串，验证它是否是二叉树序列化正确的前序遍历。 找到一个不需要重建树的算法。
+
+字符串中的每个逗号分隔的值必须是整数或表示空指针的字符“#”。
+
+您可以假设输入格式始终符合要求，例如它永远不能包含两个连续的逗号，例如“1,,3”。
+ ### 样例说明
+ ```
+样例 1:
+	输入:  tree = "#"
+	输出:  true
+	
+	解释:
+	空树是合法的BST。
+	
+样例 2:
+	输入: tree = "9,3,4,#,#,1,#,#,2,#,6,#,#"
+	输出:  true
+
+样例 3:
+	输入: tree = "1,#"
+	输出:  false
+	
+	解释:
+	不是一棵完整的树
+	
+样例 4:
+	输入: tree = "9,#,#,1"
+	输出:  false
+	
+	解释:
+	不是一棵树
+
+```
+
+ ### 参考代码
+ ```java
+public class Solution {
+    public boolean isValidSerialization(String preorder) {
+        String s = preorder;
+        boolean flag = true;
+        while (s.length() > 1) {
+            int index = s.indexOf(",#,#");
+            if (index < 0) {
+                flag = false;
+                break;
+            }
+            int start = index;
+            while (start > 0 && s.charAt(start - 1) != ',')
+            {
+                start --;
+            }
+            if (s.charAt(start) == '#') {
+                flag = false;
+                break;
+            }
+            s = s.substring(0, start) + s.substring(index + 3);
+        }
+        if (s.equals("#") && flag) 
+            return true;
+        else 
+            return false;
+    }
+}
+
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/anagrams.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/anagrams.md"
new file mode 100644
index 0000000..a48bf3a
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/anagrams.md"
@@ -0,0 +1,38 @@
+# 乱序字符串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/anagrams/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个字符串数组S，找到其中所有的乱序字符串(Anagram)。如果一个字符串是乱序字符串，那么他存在一个字母集合相同，但顺序不同的字符串也在S中。</p>
+ ### 样例说明
+ **样例1:**
+```
+输入:["lint", "intl", "inlt", "code"]
+输出:["lint", "inlt", "intl"]
+```
+
+**样例 2:**
+```
+输入:["ab", "ba", "cd", "dc", "e"]
+输出: ["ab", "ba", "cd", "dc"]
+```
+ ### 参考代码
+ Given an array of strings, return all groups of strings that are anagrams.
+
+Note: All inputs will be in lower-case
+```python
+class Solution:
+    # @param strs: A list of strings
+    # @return: A list of strings
+    def anagrams(self, strs):
+        # write your code here
+        dict = {}
+        for word in strs:
+            sortedword = ''.join(sorted(word))
+            dict[sortedword] = [word] if sortedword not in dict else dict[sortedword] + [word]
+        res = []
+        for item in dict:
+            if len(dict[item]) >= 2:
+                res += dict[item]
+        return res
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/binary-tree-vertical-order-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/binary-tree-vertical-order-traversal.md"
new file mode 100644
index 0000000..8092d04
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/binary-tree-vertical-order-traversal.md"
@@ -0,0 +1,134 @@
+# 二叉树垂直遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-vertical-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定二叉树，返回其节点值的垂直遍历顺序。 (即逐列从上到下)。
+如果两个节点在同一行和同一列中，则顺序应 **从左到右**。
+ ### 样例说明
+ **样例1**
+```
+输入： {3,9,20,#,#,15,7}
+输出： [[9],[3,15],[20],[7]]
+解释：
+   3
+  /\
+ /  \
+ 9  20
+    /\
+   /  \
+  15   7
+```
+**样例2**
+```
+输入： {3,9,8,4,0,1,7}
+输出：[[4],[9],[3,0,1],[8],[7]]
+解释：
+     3
+    /\
+   /  \
+   9   8
+  /\  /\
+ /  \/  \
+ 4  01   7
+```
+ ### 参考代码
+ 对于一棵树，我们设其根节点的位置为0。
+对于任一非叶子节点，若其位置为x，设其左儿子的位置为x-1，右儿子位置为x+1。
+按照以上规则bfs遍历整棵树统计所有节点的位置，然后按位置从小到大输出所有节点。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the vertical order traversal
+     */
+    public List<List<Integer>> verticalOrder(TreeNode root) {
+        // Write your code here
+        List<List<Integer>> results = new ArrayList<>();
+        if (root == null) {
+            return results;
+        }
+        Map<Integer, List<Integer>> map = new TreeMap<Integer, List<Integer>>();
+        Queue<Integer> qCol = new LinkedList<>();
+        Queue<TreeNode> queue = new LinkedList<>();
+        queue.offer(root);
+        qCol.offer(0);
+        
+        while(!queue.isEmpty()) {
+            TreeNode curr = queue.poll();
+            int col = qCol.poll();
+            if(!map.containsKey(col)) {
+                map.put(col, new ArrayList<Integer>(Arrays.asList(curr.val)));
+            } else {
+                map.get(col).add(curr.val);
+            }
+            if(curr.left != null) {
+                queue.offer(curr.left);
+                qCol.offer(col - 1);
+            }
+            if(curr.right != null) {
+                queue.offer(curr.right);
+                qCol.offer(col + 1);
+            }
+        }
+        for(int n : map.keySet()) {
+            results.add(map.get(n));
+        }
+        return results;
+    }   
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param root the root of binary tree
+     * @return the vertical order traversal
+     */
+    public List<List<Integer>> verticalOrder(TreeNode root) {
+        // Write your code here
+        List<List<Integer>> ans = new ArrayList<>();
+        if (root == null) {
+            return ans;
+        }
+
+        Map<Integer, List<Integer>> hash = new HashMap<>();
+        Queue<Integer> qCol = new LinkedList<>();
+        Queue<TreeNode> qNode = new LinkedList<>();
+
+        qCol.offer(0);
+        qNode.offer(root);
+
+        while (!qCol.isEmpty()) {                      // bfs
+            int c = qCol.poll();
+            TreeNode node = qNode.poll();
+
+            hash.putIfAbsent(c, new ArrayList<>());
+            hash.get(c).add(node.val);
+
+            if (node.left != null) {
+                qCol.offer(c - 1);
+                qNode.offer(node.left);
+            }
+            if (node.right != null) {
+                qCol.offer(c + 1);
+                qNode.offer(node.right);
+            }
+        }
+
+        for (int i = Collections.min(hash.keySet()); i <= Collections.max(hash.keySet()); i++) {
+            ans.add(hash.get(i));
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/binary-tree-zigzag-level-order-traversal.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/binary-tree-zigzag-level-order-traversal.md"
new file mode 100644
index 0000000..fd40965
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/binary-tree-zigzag-level-order-traversal.md"
@@ -0,0 +1,83 @@
+# 二叉树的锯齿形层次遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-tree-zigzag-level-order-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一棵二叉树，返回其节点值的锯齿形层次遍历（先从左往右，下一层再从右往左，层与层之间交替进行）&nbsp;</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入:{1,2,3}
+输出:[[1],[3,2]]
+解释:
+    1
+   / \
+  2   3
+它将被序列化为 {1,2,3}
+```
+**样例 2:**
+```
+输入:{3,9,20,#,#,15,7}
+输出:[[3],[20,9],[15,7]]
+解释:
+    3
+   / \
+  9  20
+    /  \
+   15   7
+它将被序列化为 {3,9,20,#,#,15,7}
+```
+
+ ### 参考代码
+ 层序遍历完之后，看层数，偶数层reverse一下即可。
+```java
+public class Solution {
+    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
+        List<List<Integer>> result = new ArrayList<List<Integer>>();
+
+        if (root == null) {
+            return result;
+        }
+
+        Stack<TreeNode> currLevel = new Stack<TreeNode>();
+        Stack<TreeNode> nextLevel = new Stack<TreeNode>();
+        Stack<TreeNode> tmp;
+        
+        currLevel.push(root);
+        boolean normalOrder = true;
+
+        while (!currLevel.isEmpty()) {
+            ArrayList<Integer> currLevelResult = new ArrayList<Integer>();
+
+            while (!currLevel.isEmpty()) {
+                TreeNode node = currLevel.pop();
+                currLevelResult.add(node.val);
+
+                if (normalOrder) {
+                    if (node.left != null) {
+                        nextLevel.push(node.left);
+                    }
+                    if (node.right != null) {
+                        nextLevel.push(node.right);
+                    }
+                } else {
+                    if (node.right != null) {
+                        nextLevel.push(node.right);
+                    }
+                    if (node.left != null) {
+                        nextLevel.push(node.left);
+                    }
+                }
+            }
+
+            result.add(currLevelResult);
+            tmp = currLevel;
+            currLevel = nextLevel;
+            nextLevel = tmp;
+            normalOrder = !normalOrder;
+        }
+
+        return result;
+
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/building-outline.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/building-outline.md"
new file mode 100644
index 0000000..889c2f0
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/building-outline.md"
@@ -0,0 +1,286 @@
+# 大楼轮廓
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/building-outline/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 水平面上有 *N* 座大楼，每座大楼都是矩阵的形状，可以用一个三元组表示 `(start, end, height)`，分别代表其在x轴上的起点，终点和高度。大楼之间从远处看可能会重叠，求出 *N* 座大楼的外轮廓线。
+
+外轮廓线的表示方法为若干三元组，每个三元组包含三个数字 (start, end, height)，代表这段轮廓的起始位置，终止位置和高度。
+
+![](https://lintcode-media.s3.amazonaws.com/problem/jiuzhang3.jpg)
+
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+import java.util.*;
+
+public class Solution {
+
+  class HashHeap {
+    ArrayList<Integer> heap;
+    String mode;
+    int size_t;
+    HashMap<Integer, Node> hash;
+
+    class Node {
+      public Integer id;
+      public Integer num;
+
+      Node(Node now) {
+        id = now.id;
+        num = now.num;
+      }
+
+      Node(Integer first, Integer second) {
+
+        this.id = first;
+        this.num = second;
+      }
+    }
+
+    public HashHeap(String mod) {
+      // TODO Auto-generated constructor stub
+      heap = new ArrayList<Integer>();
+      mode = mod;
+      hash = new HashMap<Integer, Node>();
+      size_t = 0;
+    }
+
+    public int peek() {
+      return heap.get(0);
+    }
+
+    public int size() {
+      return size_t;
+    }
+
+    public Boolean isEmpty() {
+      return (heap.size() == 0);
+    }
+
+    int parent(int id) {
+      if (id == 0) {
+        return -1;
+      }
+      return (id - 1) / 2;
+    }
+
+    int lson(int id) {
+      return id * 2 + 1;
+    }
+
+    int rson(int id) {
+      return id * 2 + 2;
+    }
+
+    boolean comparesmall(int a, int b) {
+      if (a <= b) {
+        if (mode == "min")
+          return true;
+        else
+          return false;
+      } else {
+        if (mode == "min")
+          return false;
+        else
+          return true;
+      }
+
+    }
+
+    void swap(int idA, int idB) {
+      int valA = heap.get(idA);
+      int valB = heap.get(idB);
+
+      int numA = hash.get(valA).num;
+      int numB = hash.get(valB).num;
+      hash.put(valB, new Node(idA, numB));
+      hash.put(valA, new Node(idB, numA));
+      heap.set(idA, valB);
+      heap.set(idB, valA);
+    }
+
+    public Integer poll() {
+      size_t--;
+      Integer now = heap.get(0);
+      Node hashnow = hash.get(now);
+      if (hashnow.num == 1) {
+        swap(0, heap.size() - 1);
+        hash.remove(now);
+        heap.remove(heap.size() - 1);
+        if (heap.size() > 0) {
+          siftdown(0);
+        }
+      } else {
+        hash.put(now, new Node(0, hashnow.num - 1));
+      }
+      return now;
+    }
+
+    public void add(int now) {
+      size_t++;
+      if (hash.containsKey(now)) {
+        Node hashnow = hash.get(now);
+        hash.put(now, new Node(hashnow.id, hashnow.num + 1));
+
+      } else {
+        heap.add(now);
+        hash.put(now, new Node(heap.size() - 1, 1));
+      }
+
+      siftup(heap.size() - 1);
+    }
+
+    public void delete(int now) {
+      size_t--;
+      Node hashnow = hash.get(now);
+      int id = hashnow.id;
+      int num = hashnow.num;
+      if (hashnow.num == 1) {
+
+        swap(id, heap.size() - 1);
+        hash.remove(now);
+        heap.remove(heap.size() - 1);
+        if (heap.size() > id) {
+          siftup(id);
+          siftdown(id);
+        }
+      } else {
+        hash.put(now, new Node(id, num - 1));
+      }
+    }
+
+    void siftup(int id) {
+      while (parent(id) > -1) {
+        int parentId = parent(id);
+        if (comparesmall(heap.get(parentId), heap.get(id)) == true) {
+          break;
+        } else {
+          swap(id, parentId);
+        }
+        id = parentId;
+      }
+    }
+
+    void siftdown(int id) {
+      while (lson(id) < heap.size()) {
+        int leftId = lson(id);
+        int rightId = rson(id);
+        int son;
+        if (rightId >= heap.size()
+            || (comparesmall(heap.get(leftId), heap.get(rightId)) == true)) {
+          son = leftId;
+        } else {
+          son = rightId;
+        }
+        if (comparesmall(heap.get(id), heap.get(son)) == true) {
+          break;
+        } else {
+          swap(id, son);
+        }
+        id = son;
+      }
+    }
+  }
+
+  class Edge {
+    int pos;
+    int height;
+    boolean isStart;
+
+    public Edge(int pos, int height, boolean isStart) {
+      this.pos = pos;
+      this.height = height;
+      this.isStart = isStart;
+    }
+
+  }
+
+  class EdgeComparator implements Comparator<Edge> {
+    @Override
+    public int compare(Edge arg1, Edge arg2) {
+      Edge l1 = (Edge) arg1;
+      Edge l2 = (Edge) arg2;
+      if (l1.pos != l2.pos)
+        return compareInteger(l1.pos, l2.pos);
+      if (l1.isStart && l2.isStart) {
+        return compareInteger(l2.height, l1.height);
+      }
+      if (!l1.isStart && !l2.isStart) {
+        return compareInteger(l1.height, l2.height);
+      }
+      return l1.isStart ? -1 : 1;
+    }
+
+    int compareInteger(int a, int b) {
+      return a <= b ? -1 : 1;
+    }
+  }
+
+  List<List<Integer>> output(List<List<Integer>> res) {
+    List<List<Integer>> ans = new ArrayList<List<Integer>>();
+    if (res.size() > 0) {
+      int pre = res.get(0).get(0);
+      int height = res.get(0).get(1);
+      for (int i = 1; i < res.size(); i++) {
+        List<Integer> now = new ArrayList<Integer>();
+        int id = res.get(i).get(0);
+        if (height > 0) {
+          now.add(pre);
+          now.add(id);
+          now.add(height);
+          ans.add(now);
+        }
+        pre = id;
+        height = res.get(i).get(1);
+      }
+    }
+    return ans;
+  }
+
+  public List<List<Integer>> buildingOutline(int[][] buildings) {
+    // write your code here
+    List<List<Integer>> res = new ArrayList<List<Integer>>();
+
+    if (buildings == null || buildings.length == 0
+        || buildings[0].length == 0) {
+      return res;
+    }
+    ArrayList<Edge> edges = new ArrayList<Edge>();
+    for (int[] building : buildings) {
+      Edge startEdge = new Edge(building[0], building[2], true);
+      edges.add(startEdge);
+      Edge endEdge = new Edge(building[1], building[2], false);
+      edges.add(endEdge);
+    }
+    Collections.sort(edges, new EdgeComparator());
+
+    HashHeap heap = new HashHeap("max");
+
+    List<Integer> now = null;
+    for (Edge edge : edges) {
+      if (edge.isStart) {
+        if (heap.isEmpty() || edge.height > heap.peek()) {
+          now = new ArrayList<Integer>(Arrays.asList(edge.pos,
+              edge.height));
+          res.add(now);
+        }
+        heap.add(edge.height);
+      } else {
+        heap.delete(edge.height);
+        if (heap.isEmpty() || edge.height > heap.peek()) {
+          if (heap.isEmpty()) {
+            now = new ArrayList<Integer>(Arrays.asList(edge.pos, 0));
+          } else {
+            now = new ArrayList<Integer>(Arrays.asList(edge.pos,
+                heap.peek()));
+          }
+          res.add(now);
+        }
+      }
+    }
+    return output(res);
+  }
+
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/clone-graph.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/clone-graph.md"
new file mode 100644
index 0000000..7e9e4c5
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/clone-graph.md"
@@ -0,0 +1,63 @@
+# 克隆图
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/clone-graph/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 克隆一张无向图. 无向图的每个节点包含一个 `label` 和一个列表 `neighbors`. 保证每个节点的 `label` 互不相同.
+
+你的程序需要返回一个经过深度拷贝的新图. 新图和原图具有同样的结构, 并且对新图的任何改动不会对原图造成任何影响.
+ ### 样例说明
+ **样例1**
+```
+输入:
+{1,2,4#2,1,4#4,1,2}
+输出: 
+{1,2,4#2,1,4#4,1,2}
+解释:
+1------2  
+ \     |  
+  \    |  
+   \   |  
+    \  |  
+      4   
+```
+ ### 参考代码
+ 使用宽度优先搜索 BFS 的版本。
+
+第一步：找到所有的点
+第二步：复制所有的点，将映射关系存起来
+第三步：找到所有的边，复制每一条边
+```python
+class Solution:
+    def cloneGraph(self, node):
+        root = node
+        if node is None:
+            return node
+            
+        # use bfs algorithm to traverse the graph and get all nodes.
+        nodes = self.getNodes(node)
+        
+        # copy nodes, store the old->new mapping information in a hash map
+        mapping = {}
+        for node in nodes:
+            mapping[node] = UndirectedGraphNode(node.label)
+        
+        # copy neighbors(edges)
+        for node in nodes:
+            new_node = mapping[node]
+            for neighbor in node.neighbors:
+                new_neighbor = mapping[neighbor]
+                new_node.neighbors.append(new_neighbor)
+        
+        return mapping[root]
+        
+    def getNodes(self, node):
+        q = collections.deque([node])
+        result = set([node])
+        while q:
+            head = q.popleft()
+            for neighbor in head.neighbors:
+                if neighbor not in result:
+                    result.add(neighbor)
+                    q.append(neighbor)
+        return result
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/consistent-hashing-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/consistent-hashing-ii.md"
new file mode 100644
index 0000000..65681cb
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/consistent-hashing-ii.md"
@@ -0,0 +1,130 @@
+# 一致性哈希 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/consistent-hashing-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在 Consistent Hashing I 中我们介绍了一个比较简单的一致性哈希算法，这个简单的版本有两个缺陷：
+
+1. 增加一台机器之后，数据全部从其中一台机器过来，这一台机器的读负载过大，对正常的服务会造成影响。
+2. 当增加到3台机器的时候，每台服务器的负载量不均衡，为1:1:2。
+
+为了解决这个问题，引入了 micro-shards 的概念，一个更好的算法是这样：
+
+1. 将 360° 的区间分得更细。从 0~359 变为一个 0 ~ n-1 的区间，将这个区间首尾相接，连成一个圆。
+2. 当加入一台新的机器的时候，随机选择在圆周中撒 k 个点，代表这台机器的 k 个 micro-shards。
+3. 每个数据在圆周上也对应一个点，这个点通过一个 hash function 来计算。
+4. 一个数据该属于哪台机器负责管理，是按照该数据对应的圆周上的点在圆上顺时针碰到的第一个 micro-shard 点所属的机器来决定。
+
+n 和 k在真实的 NoSQL 数据库中一般是 2^64 和 1000。
+
+请实现这种引入了 micro-shard 的 consistent hashing 的方法。主要实现如下的三个函数：
+
+1. `create(int n, int k)`
+2. `addMachine(int machine_id)` // add a new machine, return a list of shard ids.
+3. `getMachineIdByHashCode(int hashcode)` // return machine id
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  create(100, 3)
+  addMachine(1)
+  getMachineIdByHashCode(4)
+  addMachine(2)
+  getMachineIdByHashCode(61)
+  getMachineIdByHashCode(91)
+输出: 
+  [77,83,86]
+  1
+  [15,35,93]
+  1
+  2
+```
+
+**样例 2:**
+
+```
+输入: 
+  create(10, 5)
+  addMachine(1)
+  getMachineIdByHashCode(4)
+  addMachine(2)
+  getMachineIdByHashCode(0)
+  getMachineIdByHashCode(1)
+  getMachineIdByHashCode(2)
+  getMachineIdByHashCode(3)
+  getMachineIdByHashCode(4)
+  getMachineIdByHashCode(5)
+输出: 
+  [2,3,5,6,7]
+  1
+  [0,1,4,8,9]
+  2
+  2
+  1
+  1
+  2
+  1
+```
+ ### 参考代码
+ ```java
+public class Solution {
+
+    public int n, k;
+    public Set<Integer> ids = null;
+    public Map<Integer, List<Integer>> machines = null;
+
+    // @param n a positive integer
+    // @param k a positive integer
+    // @return a Solution object
+    public static Solution create(int n, int k) {
+        // Write your code here
+        Solution solution = new Solution();
+        solution.n = n;
+        solution.k = k;
+        solution.ids = new TreeSet<Integer>();
+        solution.machines = new HashMap<Integer, List<Integer>>();
+        return solution;
+    }
+
+    // @param machine_id an integer
+    // @return a list of shard ids
+    public List<Integer> addMachine(int machine_id) {
+        // Write your code here
+        Random ra = new Random();
+        List<Integer> random_nums = new ArrayList<Integer>();
+        for (int i = 0; i < k; ++i) {
+            int index = ra.nextInt(n);
+            while (ids.contains(index))
+                index = ra.nextInt(n);
+            ids.add(index);
+            random_nums.add(index);
+        }
+
+        Collections.sort(random_nums);
+        machines.put(machine_id, random_nums);
+        return random_nums;
+    }
+
+    // @param hashcode an integer
+    // @return a machine id
+    public int getMachineIdByHashCode(int hashcode) {
+        // Write your code here
+        int distance = n + 1;
+        int machine_id = 0;
+        for (Map.Entry<Integer, List<Integer>> entry : machines.entrySet()) {
+            int key = entry.getKey();
+            List<Integer> random_nums = entry.getValue();
+            for (Integer num : random_nums) {
+                int d = num - hashcode;
+                if (d < 0)
+                    d += n;
+                if (d < distance) {
+                    distance = d;
+                    machine_id = key;
+                }
+            }
+        }
+        return machine_id;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/consistent-hashing.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/consistent-hashing.md"
new file mode 100644
index 0000000..78c02ba
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/consistent-hashing.md"
@@ -0,0 +1,89 @@
+# 一致性哈希
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/consistent-hashing/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 一般的数据库进行horizontal shard的方法是指，把 id 对 数据库服务器总数 n 取模，然后来得到他在哪台机器上。这种方法的缺点是，当数据继续增加，我们需要增加数据库服务器，将 n 变为 n+1 时，几乎所有的数据都要移动，这就造成了不 consistent。为了减少这种 naive 的 hash方法(%n) 带来的缺陷，出现了一种新的hash算法：一致性哈希的算法——Consistent Hashing。这种算法有很多种实现方式，这里我们来实现一种简单的 Consistent Hashing。
+
+1. 将 id 对 360 取模，假如一开始有3台机器，那么让3台机器分别负责0~119, 120~239, 240~359 的三个部分。那么模出来是多少，查一下在哪个区间，就去哪台机器。
+2. 当机器从 n 台变为 n+1 台了以后，我们从n个区间中，找到最大的一个区间，然后一分为二，把一半给第n+1台机器。
+3. 比如从3台变4台的时候，我们找到了第3个区间0~119是当前最大的一个区间，那么我们把0~119分为0~59和60~119两个部分。0~59仍然给第1台机器，60~119给第4台机器。
+4. 然后接着从4台变5台，我们找到最大的区间是第3个区间120~239，一分为二之后，变为 120~179, 180~239。
+
+假设一开始所有的数据都在一台机器上，请问加到第 n 台机器的时候，区间的分布情况和对应的机器编号分别是多少？
+ ### 样例说明
+ 
+例1:
+```
+输入:
+ n = 1, 
+输出:
+[
+  [0,359,1]
+]
+解释:
+表示 0~359 属于机器 1.
+```
+例2:
+```
+输入:
+ n = 2,
+输出:
+[
+  [0,179,1],
+  [180,359,2]
+]
+解释:
+表示 0~179 属于机器 1.
+表示 180~359 属于机器 2.
+```
+
+例3:
+```
+输入:
+n = 3,
+输出:
+[
+  [0,89,1]
+  [90,179,3],
+  [180,359,2]
+]
+```
+
+ ### 参考代码
+ 每次暴力找最大的编号最小的区间，然后分割即可
+```java
+public class Solution {
+    /**
+     * @param n a positive integer
+     * @return n x 3 matrix
+     */
+    public List<List<Integer>> consistentHashing(int n) {
+        // Write your code here
+        List<List<Integer>> results = new ArrayList<List<Integer>>();
+        List<Integer> machine = new ArrayList<Integer>();
+        machine.add(0);
+        machine.add(359);
+        machine.add(1);
+        results.add(machine);
+        for (int i = 1; i < n; ++i) {
+            List<Integer> new_machine = new ArrayList<Integer>();
+            int index = 0;
+            for (int j = 1; j < i; ++j) {
+                if (results.get(j).get(1) - results.get(j).get(0) + 1 >
+                    results.get(index).get(1) - results.get(index).get(0) + 1)
+                    index = j;
+            }
+
+            int x = results.get(index).get(0);
+            int y = results.get(index).get(1);
+            results.get(index).set(1, (x + y) / 2);
+            
+            new_machine.add((x + y) / 2 + 1);
+            new_machine.add(y);
+            new_machine.add(i + 1);
+            results.add(new_machine);
+        }
+        return results;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/copy-list-with-random-pointer.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/copy-list-with-random-pointer.md"
new file mode 100644
index 0000000..eed6917
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/copy-list-with-random-pointer.md"
@@ -0,0 +1,95 @@
+# 复制带随机指针的链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/copy-list-with-random-pointer/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个链表，每个节点包含一个额外增加的随机指针可以指向链表中的任何节点或空的节点。</p><p><span style="line-height: 1.42857143;">返回一个深拷贝的链表。&nbsp;</span></p>
+ ### 样例说明
+ 
+ ### 参考代码
+ A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
+
+Return a deep copy of the list.
+
+深拷贝要对每个点都新建一遍。ALL
+```java
+//HashMap version
+public class Solution {
+    public RandomListNode copyRandomList(RandomListNode head) {
+        if (head == null) {
+            return null;
+        }
+
+        HashMap<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
+        RandomListNode dummy = new RandomListNode(0);
+        RandomListNode pre = dummy, newNode;
+        while (head != null) {
+            if (map.containsKey(head)) {
+                newNode = map.get(head);
+            } else {
+                newNode = new RandomListNode(head.label);
+                map.put(head, newNode);
+            }
+            pre.next = newNode;
+
+            if (head.random != null) {
+                if (map.containsKey(head.random)) {
+                    newNode.random = map.get(head.random);
+                } else {
+                    newNode.random = new RandomListNode(head.random.label);
+                    map.put(head.random, newNode.random);
+                }
+            }
+
+            pre = newNode;
+            head = head.next;
+        }
+
+        return dummy.next;
+    }
+}
+
+/*第一遍扫的时候巧妙运用next指针， 开始数组是1->2->3->4  。 然后扫描过程中 先建立copy节点 1->1`->2->2`->3->3`->4->4`, 然后第二遍copy的时候去建立边的copy， 拆分节点, 一边扫描一边拆成两个链表，这里用到两个dummy node。第一个链表变回  1->2->3 , 然后第二变成 1`->2`->3`  */
+//No HashMap version
+public class Solution {
+    private void copyNext(RandomListNode head) {
+        while (head != null) {
+            RandomListNode newNode = new RandomListNode(head.label);
+            newNode.random = head.random;
+            newNode.next = head.next;
+            head.next = newNode;
+            head = head.next.next;
+        }
+    }
+
+    private void copyRandom(RandomListNode head) {
+        while (head != null) {
+            if (head.next.random != null) {
+                head.next.random = head.random.next;
+            }
+            head = head.next.next;
+        }
+    }
+
+    private RandomListNode splitList(RandomListNode head) {
+        RandomListNode newHead = head.next;
+        while (head != null) {
+            RandomListNode temp = head.next;
+            head.next = temp.next;
+            head = head.next;
+            if (temp.next != null) {
+                temp.next = temp.next.next;
+            }
+        }
+        return newHead;
+    }
+
+    public RandomListNode copyRandomList(RandomListNode head) {
+        if (head == null) {
+            return null;
+        }
+        copyNext(head);
+        copyRandom(head);
+        return splitList(head);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/count-characters.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/count-characters.md"
new file mode 100644
index 0000000..3369c5a
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/count-characters.md"
@@ -0,0 +1,55 @@
+# 字符计数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/count-characters/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 对一个字符串中的字符进行计数, 返回一个hashmap, key为字符, value是这个字符出现的次数.
+ ### 样例说明
+ 
+例1:
+```
+输入:
+str = "abca"
+
+输出:
+{
+  "a": 2,
+  "b": 1,
+  "c": 1
+}
+
+```
+例2:
+```
+输入:
+str = "ab"
+
+输出:
+{
+  "a": 1,
+  "b": 1
+}
+
+```
+
+ ### 参考代码
+ 利用map统计即可
+```java
+public class Solution {
+    /*
+     * @param : a string
+     * @return: a hash map
+     */
+    public Map<Character, Integer> countCharacters(String str) {
+        // Write your code here
+        Map<Character, Integer> map = new HashMap<Character, Integer>();
+        for (char c : str.toCharArray()) {
+            if (!map.containsKey(c)) {
+                map.put(c, 1);
+            } else {
+                map.put(c, map.get(c) + 1);
+            }
+        }
+        return map;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/counting-bloom-filter.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/counting-bloom-filter.md"
new file mode 100644
index 0000000..97ba27f
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/counting-bloom-filter.md"
@@ -0,0 +1,105 @@
+# 计数型布隆过滤器
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/counting-bloom-filter/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个计数型布隆过滤器, 支持以下方法:
+`add(string)`. 往布隆过滤器中加入一个字符串.
+`contains(string)`. 检查一个字符串是否在布隆过滤器中.
+`remove(string)`. 从布隆计数器中删除一个字符串.
+ ### 样例说明
+ **样例1**
+
+```
+输入:
+CountingBloomFilter(3)
+add("lint")
+add("code")
+contains("lint") 
+remove("lint")
+contains("lint") 
+
+输出: 
+[true,false]
+```
+
+**样例2**
+
+```
+输入:
+CountingBloomFilter(3)
+add("lint")
+add("lint")
+contains("lint")
+remove("lint")
+contains("lint")
+
+输出: 
+[true,true]
+```
+ ### 参考代码
+ 用map维护数字出现的次数
+当加入一个元素时，让map对应改元素的值+1，删除元素时，让map对应该元素的值-1
+```cpp
+class HashFunction {
+private:
+    int cap, seed;
+public:
+    HashFunction(int cap, int seed) {
+        this->cap = cap;
+        this->seed = seed;
+    }
+
+    int hash(string& value) {
+        int ret = 0;
+        int n = value.size();
+        for (int i = 0; i < n; ++i) {
+            ret += seed * ret + value[i];
+            ret %= cap;
+        }
+        return ret;
+    }
+};
+
+
+class CountingBloomFilter {
+private:
+    int k;
+    vector<HashFunction*> hashFunc;
+    vector<int> bits;
+
+public:
+    CountingBloomFilter(int k) {
+        // initialize your data structure here
+        this->k = k;
+        for (int i = 0; i < k; ++i)
+            hashFunc.push_back(new HashFunction(100000 + i, 2 * i + 3));
+
+        bits.resize(100000 + k, 0);
+    }
+
+    void add(string& word) {
+        // Write your code here
+        for (int i = 0; i < k; ++i) {
+            int position = hashFunc[i]->hash(word);
+            bits[position] += 1;
+        }
+    }
+
+    void remove(string& word) {
+        // Write your code here
+        for (int i = 0; i < k; ++i) {
+            int position = hashFunc[i]->hash(word);
+            bits[position] -= 1;
+        }
+    }
+    bool contains(string& word) {
+        // Write your code here
+        for (int i = 0; i < k; ++i) {
+            int position = hashFunc[i]->hash(word);
+            if (bits[position] <= 0)
+                return false;
+        }
+        return true;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/data-stream-as-disjoint-intervals.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/data-stream-as-disjoint-intervals.md"
new file mode 100644
index 0000000..e404575
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/data-stream-as-disjoint-intervals.md"
@@ -0,0 +1,76 @@
+# 将数据流变为多个不相交区间
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/data-stream-as-disjoint-intervals/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个非负整数的数据流输入 a1，a2，…，an，…，将到目前为止看到的数字总结为不相交的区间列表。
+
+例如，假设数据流中的整数为 1，3，7，2，6，…，每次的总结为：
+```
+[1, 1]
+[1, 1], [3, 3]
+[1, 1], [3, 3], [7, 7]
+[1, 3], [7, 7]
+[1, 3], [6, 7]
+```
+ ### 样例说明
+ **Example 1:**
+```
+输入：["SummaryRanges","addNum","getIntervals","addNum","getIntervals","addNum","getIntervals","addNum","getIntervals","addNum","getIntervals"],[[],[1],[],[3],[],[7],[],[2],[],[6],[]]
+输出：[null,null,[[1,1]],null,[[1,1],[3,3]],null,[[1,1],[3,3],[7,7]],null,[[1,3],[7,7]],null,[[1,3],[6,7]]]
+解释：add(1)->get([[1, 1]])->add(3)->get([[1, 1], [3, 3]])->add(7)->get([[1, 1], [3, 3], [7, 7]])->add(2)-merge(1,2,3)->get([[1, 3], [7, 7]])->add(6)->merge(6,7)->get([[1, 3], [6, 7]])
+```
+
+
+**Example 2:**
+```
+输入：["SummaryRanges","addNum","getIntervals","addNum","getIntervals"],[[],[4],[],[3],[]]
+输出：[null,null,[4,4],null,[3,4]]
+解释：add(4)->get([[4, 4]])->add(3)->merge(3,4)->get([[3, 4]])
+```
+ ### 参考代码
+ 无脑使用并查集的做法。
+相对于使用红黑树的做法而言，addNum 的操作变快了，O(1)。但是 getIntervals 因为需要排序，所以变慢了，O(NlogN)
+红黑树是 addNum O(logN)，getIntervals O(N)
+
+不能说哪个一个最好。因为取决于 addNum 和 getIntervals 的调用频率。
+```python
+class SummaryRanges:
+    
+    def __init__(self):
+        self.father = dict()
+        self.val2interval = dict()
+
+    def addNum(self, val):
+        if val in self.father:
+            return
+        
+        self.father[val] = val
+        self.val2interval[val] = [val, val]
+        if val - 1 in self.father:
+            self.merge(val - 1, val)
+            
+        if val + 1 in self.father:
+            self.merge(val + 1, val)
+      
+    def getIntervals(self):
+        return [
+            self.val2interval[val]
+            for val in sorted(self.father.keys())
+            if self.father[val] == val
+        ]
+        
+    def merge(self, a, b):
+        root_a = self.find(a)
+        root_b = self.find(b)
+        self.father[root_a] = root_b
+        self.val2interval[root_b] = [
+            min(self.val2interval[root_a][0], self.val2interval[root_b][0]),
+            max(self.val2interval[root_a][1], self.val2interval[root_b][1]),
+        ]
+    
+    def find(self, a):
+        if a == self.father[a]:
+            return a
+        self.father[a] = self.find(self.father[a])
+        return self.father[a]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/substring-anagrams.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/find-all-anagrams-in-a-string.md"
similarity index 59%
rename from "\351\242\230\350\247\243/substring-anagrams.md"
rename to "\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/find-all-anagrams-in-a-string.md"
index 45ae43a..cbaf31c 100644
--- "a/\351\242\230\350\247\243/substring-anagrams.md"
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/find-all-anagrams-in-a-string.md"
@@ -1,153 +1,101 @@
-# substring anagrams
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/substring-anagrams/?utm_source=sc-github-wzz)
+# 子串字谜
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-all-anagrams-in-a-string/?utm_source=sc-github-wzz)
  ## 题目描述
- 1785
+ 给定一个字符串 `s` 和一个 **非空字符串** `p` ，找到在 `s` 中所有关于 `p` 的字谜的起始索引。
+字符串仅由小写英文字母组成，字符串 **s** 和 **p** 的长度不得大于 40,000。
+输出顺序无关紧要。
  ### 样例说明
- 1785
+ **样例 1:**
+```
+输入 : s = "cbaebabacd", p = "abc"
+输出 : [0, 6]
+说明 : 
+子串起始索引 index = 0 是 "cba"，是"abc"的字谜。
+子串起始索引 index = 6 是 "bac"，是"abc"的字谜。
+```
  ### 参考代码
- ```java
-public class Solution {
-    /**
-     * @param s a string
-     * @param p a non-empty string
-     * @return a list of index
-     */
-    public List<Integer> findAnagrams(String s, String p) {
-        // Write your code here
-        List<Integer> ans = new ArrayList <Integer>();
-        int[] sum = new int[30];
-
-        int plength = p.length(), slength = s.length();
-        for(char c : p.toCharArray()){
-            sum[c - 'a'] ++;
-        }
-        
-        int start = 0, end = 0, matched = 0;
-        while(end < slength){
-            if(sum[s.charAt(end) - 'a'] >= 1){
-                matched ++;
-            }
-            sum[s.charAt(end) - 'a'] --;
-            end ++;
-            if(matched == plength) {
-                ans.add(start);
-            }
-            if(end - start == plength){
-                if(sum[s.charAt(start) - 'a'] >= 0){
-                    matched --;
-                }
-                sum[s.charAt(start) - 'a'] ++;
-                start ++;
-            }
-        }
-        return ans;
-    }
-}
-
-// version: 高频题班
-public class Solution {
-    /**
-     * @param s a string
-     * @param p a non-empty string
-     * @return a list of index
-     */
-    public List<Integer> findAnagrams(String s, String p) {
-        // Write your code here
-        List<Integer> ans = new ArrayList<>();
-        if (s.length() < p.length()) {
-            return ans;
-        }
-        char[] sc = s.toCharArray();
-        char[] pc = p.toCharArray();
-
-        int[] cntP = new int[256];
-        int[] cntS = new int[256];
-        int[] det = new int[256];
-
-        for (int i = 0; i < p.length(); i++) {
-            cntP[pc[i]]++;
-            cntS[sc[i]]++;
-
-            det[pc[i]]--;
-            det[sc[i]]++;
-        }
-
-        int absSum = 0;
-        for (int item : det) {
-            absSum += Math.abs(item);
-        }
-        if (absSum == 0) {
-            ans.add(0);
-        }
-
-        for (int i = p.length(); i < s.length(); i++) {
-            int r = sc[i];
-            int l = sc[i - p.length()];
-            cntS[r]++;
-            cntS[l]--;
-
-            absSum = absSum - Math.abs(det[r]) - Math.abs(det[l]);
-
-            det[r]++;
-            det[l]--;
-
-            absSum = absSum + Math.abs(det[r]) + Math.abs(det[l]);
-
-            if (absSum == 0) {
-                ans.add(i - p.length() + 1);
-            }
-        }
-        return ans;
-    }
-}
-
-/*
-//clean version
-
-public class Solution {
-
-    public List<Integer> findAnagrams(String s, String p) {
-        // Write your code here
-        List<Integer> ans = new ArrayList<>();
-        if (s.length() < p.length()) {
-            return ans;
-        }
-        char[] sc = s.toCharArray();
-        char[] pc = p.toCharArray();
-
-        int[] det = new int[256];
-
-        for (int i = 0; i < p.length(); i++) {
-            det[pc[i]]--;
-            det[sc[i]]++;
-        }
-
-        int absSum = 0;
-        for (int item : det) {
-            absSum += Math.abs(item);
-        }
-        if (absSum == 0) {
-            ans.add(0);
-        }
-
-        for (int i = p.length(); i < s.length(); i++) {
-            int r = sc[i];
-            int l = sc[i - p.length()];
-            absSum = absSum - Math.abs(det[r]) - Math.abs(det[l]);
-
-            det[r]++;
-            det[l]--;
-
-            absSum = absSum + Math.abs(det[r]) + Math.abs(det[l]);
-            if (absSum == 0) {
-                ans.add(i - p.length() + 1);
-            }
-        }
-        return ans;
-    }
-}
-*/
-
+ 由于和顺序无关，所以可以开一个数组来记录每个字符的个数，一旦满足p串的字符出现个数，就记录答案。
+```java
+public class Solution {
+    /**
+     * @param s a string
+     * @param p a non-empty string
+     * @return a list of index
+     */
+    public List<Integer> findAnagrams(String s, String p) {
+        // Write your code here
+        List<Integer> ans = new ArrayList <Integer>();
+        int[] sum = new int[30];
+
+        int plength = p.length(), slength = s.length();
+        for(char c : p.toCharArray()){
+            sum[c - 'a'] ++;
+        }
+        
+        int start = 0, end = 0, matched = 0;
+        while(end < slength){
+            if(sum[s.charAt(end) - 'a'] >= 1){
+                matched ++;
+            }
+            sum[s.charAt(end) - 'a'] --;
+            end ++;
+            if(matched == plength) {
+                ans.add(start);
+            }
+            if(end - start == plength){
+                if(sum[s.charAt(start) - 'a'] >= 0){
+                    matched --;
+                }
+                sum[s.charAt(start) - 'a'] ++;
+                start ++;
+            }
+        }
+        return ans;
+    }
+}
+
+//version 高频题班
+public class Solution {
+
+    public List<Integer> findAnagrams(String s, String p) {
+        // Write your code here
+        List<Integer> ans = new ArrayList<>();
+        if (s.length() < p.length()) {
+            return ans;
+        }
+        char[] sc = s.toCharArray();
+        char[] pc = p.toCharArray();
+
+        int[] det = new int[256];
+
+        for (int i = 0; i < p.length(); i++) {
+            det[pc[i]]--;
+            det[sc[i]]++;
+        }
+
+        int absSum = 0;
+        for (int item : det) {
+            absSum += Math.abs(item);
+        }
+        if (absSum == 0) {
+            ans.add(0);
+        }
+
+        for (int i = p.length(); i < s.length(); i++) {
+            int r = sc[i];
+            int l = sc[i - p.length()];
+            absSum = absSum - Math.abs(det[r]) - Math.abs(det[l]);
+
+            det[r]++;
+            det[l]--;
 
+            absSum = absSum + Math.abs(det[r]) + Math.abs(det[l]);
+            if (absSum == 0) {
+                ans.add(i - p.length() + 1);
+            }
+        }
+        return ans;
+    }
+}
 ```
  更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/first-unique-number-in-data-stream-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/first-unique-number-in-data-stream-ii.md"
new file mode 100644
index 0000000..ca4ed9e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/first-unique-number-in-data-stream-ii.md"
@@ -0,0 +1,98 @@
+# 数据流中第一个独特的数 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/first-unique-number-in-data-stream-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 我们需要实现一个叫 `DataStream` 的数据结构。并且这里有 `两` 个方法需要实现：
+
+1. `void add(number)` // 加一个新的数
+2. `int firstUnique()` // 返回第一个独特的数
+ ### 样例说明
+ 例1:
+```
+输入:
+add(1)
+add(2)
+firstUnique()
+add(1)
+firstUnique()
+输出:
+[1,2]
+```
+
+例2:
+```
+输入:
+add(1)
+add(2)
+add(3)
+add(4)
+add(5)
+firstUnique()
+add(1)
+firstUnique()
+add(2)
+firstUnique()
+add(3)
+firstUnique()
+add(4)
+firstUnique()
+add(5)
+add(6)
+firstUnique()
+输出:
+[1,2,3,4,5,6]
+```
+
+
+ ### 参考代码
+ 使用类似 LRU Cache 的做法来做。
+hash 的 key 为 num，value 为对应的 linkedlist 上的 previous node
+```python
+class DataStream:
+
+    def __init__(self):
+        self.dummy = ListNode(0)
+        self.tail = self.dummy
+        self.num_to_prev = {}
+        self.duplicates = set()
+          
+    """
+    @param num: next number in stream
+    @return: nothing
+    """
+    def add(self, num):
+        if num in self.duplicates:
+            return
+        
+        if num not in self.num_to_prev:
+            self.push_back(num)            
+            return
+        
+        # find duplicate, remove it from hash & linked list
+        self.duplicates.add(num)
+        self.remove(num)
+    
+    def remove(self, num):
+        prev = self.num_to_prev.get(num)
+        del self.num_to_prev[num]
+        prev.next = prev.next.next
+        if prev.next:
+            self.num_to_prev[prev.next.val] = prev
+        else:
+            # if we removed the tail node, prev will be the new tail
+            self.tail = prev
+
+    def push_back(self, num):
+        # new num add to the tail
+        self.tail.next = ListNode(num)
+        self.num_to_prev[num] = self.tail
+        self.tail = self.tail.next
+
+    """
+    @return: the first unique number in stream
+    """
+    def firstUnique(self):
+        if not self.dummy.next:
+            return None
+        return self.dummy.next.val
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/first-unique-number-in-data-stream.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/first-unique-number-in-data-stream.md"
new file mode 100644
index 0000000..3d36923
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/first-unique-number-in-data-stream.md"
@@ -0,0 +1,54 @@
+# 数据流中第一个唯一的数字
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/first-unique-number-in-data-stream/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个连续的数据流,写一个函数返回终止数字到达时的第一个唯一数字（包括终止数字）,如果找不到这个终止数字, 返回 `-1`.
+ ### 样例说明
+ **样例1**
+```
+输入： 
+[1, 2, 2, 1, 3, 4, 4, 5, 6]
+5
+输出： 3
+```
+**样例2**
+```
+输入：
+[1, 2, 2, 1, 3, 4, 4, 5, 6]
+7
+输出： -1
+```
+**样例3**
+```
+输入：
+[1, 2, 2, 1, 3, 4]
+3
+输出： 3
+```
+ ### 参考代码
+ 如果允许遍历两次，简单的这么做就可以了
+如果只允许遍历一次，请参见 first unique number in data stream ii 这个题的参考答案
+```python
+class Solution:
+    """
+    @param nums: a continuous stream of numbers
+    @param number: a number
+    @return: returns the first unique number
+    """
+    def firstUniqueNumber(self, nums, number):
+        counter = {}
+        for num in nums:
+            counter[num] = counter.get(num, 0) + 1
+            if num == number:
+                break
+        else:
+            return -1
+            
+        for num in nums:
+            if counter[num] == 1:
+                return num
+            if num == number:
+                break
+
+        return -1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/happy-number.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/happy-number.md"
new file mode 100644
index 0000000..267bf81
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/happy-number.md"
@@ -0,0 +1,60 @@
+# 快乐数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/happy-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 写一个算法来判断一个数是不是"快乐数"。
+
+一个数是不是快乐是这么定义的：对于一个正整数，每一次将该数替换为他每个位置上的数字的平方和，然后重复这个过程直到这个数变为1，或是无限循环但始终变不到1。如果可以变为1，那么这个数就是快乐数。
+ ### 样例说明
+ 例1：
+```
+输入：19
+输出：true
+说明：
+
+19是一个快乐的数字
+
+     1 ^ 2 + 9 ^ 2 = 82
+     8 ^ 2 + 2 ^ 2 = 68
+     6 ^ 2 + 8 ^ 2 = 100
+     1 ^ 2 + 0 ^ 2 + 0 ^ 2 = 1
+
+```
+
+例2：
+```
+输入：5
+输出：false
+说明：
+
+5不是一个快乐的数字
+
+25->29->85->89->145->42->20->4->16->37->58->89
+再次出现89。
+```
+ ### 参考代码
+ 看看变化的过程中，是否出现重复，若出现，则代表不是快乐数
+```java
+public class Solution {
+    private int getNextHappy(int n) {
+        int sum = 0;
+        while (n != 0) {
+            sum += (n % 10) * (n % 10);
+            n /= 10;
+        }
+        return sum;
+    }
+    
+    public boolean isHappy(int n) {
+        HashSet<Integer> hash = new HashSet<Integer>();
+        while (n != 1) {
+            if (hash.contains(n)) {
+                return false;
+            }
+            hash.add(n);
+            n = getNextHappy(n);
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/hash-function.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/hash-function.md"
new file mode 100644
index 0000000..d6f88f2
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/hash-function.md"
@@ -0,0 +1,38 @@
+# 哈希函数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/hash-function/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>在数据结构中，哈希函数是用来将一个字符串（或任何其他类型）转化为小于哈希表大小且大于等于零的整数。一个好的哈希函数可以尽可能少地产生冲突。一种广泛使用的哈希函数算法是使用数值33，假设任何字符串都是基于33的一个大整数，比如：</p><p style="color: rgb(113, 113, 113); font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;">hashcode("abcd") = (ascii(a) * 33<span style="position: relative; font-size: 12px; line-height: 0; vertical-align: baseline; top: -0.5em;">3</span>&nbsp;+&nbsp;<span style="line-height: 1.42857143;">ascii(</span><span style="line-height: 1.42857143;">b) * 33</span><span style="position: relative; font-size: 12px; line-height: 0; vertical-align: baseline; top: -0.5em;">2</span><span style="line-height: 1.42857143;">&nbsp;+&nbsp;</span><span style="line-height: 1.42857143;">ascii(</span><span style="line-height: 1.42857143;">c) *33 +&nbsp;</span><span style="line-height: 1.42857143;">ascii(</span><span style="line-height: 1.42857143;">d)) %&nbsp;</span>HASH_SIZE<span style="line-height: 1.42857143;">&nbsp;</span></p><p style="color: rgb(113, 113, 113); font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"><span style="line-height: 1.42857143;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = (</span><span style="line-height: 1.42857143;">97* 33</span><span style="font-size: 12px; line-height: 0; position: relative; vertical-align: baseline; top: -0.5em;">3</span><span style="line-height: 1.42857143;">&nbsp;</span><span style="line-height: 1.42857143;">+ 98</span><span style="line-height: 1.42857143;">&nbsp;* 33</span><span style="font-size: 12px; line-height: 0; position: relative; vertical-align: baseline; top: -0.5em;">2</span><span style="line-height: 1.42857143;">&nbsp;+ 99</span><span style="line-height: 1.42857143;">&nbsp;* 33 +100</span><span style="line-height: 1.42857143;">) % HASH_SIZE</span></p><p style="color: rgb(113, 113, 113); font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"><span style="line-height: 1.42857143;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =&nbsp;</span>3595978 % HASH_SIZE</p><p>其中HASH_SIZE表示哈希表的大小(可以假设一个哈希表就是一个索引0 ~ HASH_SIZE-1的数组)。</p><p>给出一个字符串作为key和一个哈希表的大小，返回这个字符串的哈希值。</p>
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:  key = "abcd", size = 1000
+输出: 978	
+样例解释：(97 * 33^3 + 98*33^2 + 99*33 + 100*1)%1000 = 978
+```
+
+**样例 2:**
+
+```
+输入:  key = "abcd", size = 100
+输出: 78	
+样例解释：(97 * 33^3 + 98*33^2 + 99*33 + 100*1)%100 = 78
+```
+ ### 参考代码
+ 取模过程要使用同余定理：
+(a * b ) % MOD = ((a % MOD) * (b % MOD)) % MOD
+```python
+class Solution:
+    """
+    @param key: A String you should hash
+    @param HASH_SIZE: An integer
+    @return an integer
+    """
+    def hashCode(self, key, HASH_SIZE):
+        # write your code here
+        ans = 0
+        for x in key:
+            ans = (ans * 33 + ord(x)) % HASH_SIZE
+        return ans
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/heart-beat.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/heart-beat.md"
new file mode 100644
index 0000000..305c4c3
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/heart-beat.md"
@@ -0,0 +1,98 @@
+# 心跳
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/heart-beat/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在Master-Slave结构模式中，slave端会每隔k秒向master端发送ping请求表示自己还在运行。如果master端在 2 * k 秒内没有接收到任何来自slave的ping请求，那么master端会向管理员发送一个警告(比如发送一个电子邮件)。
+
+现在让我们来模拟master端，你需要实现以下三个功能：
+1.`initialize(slaves_ip_list, k)`，slaves_ip_list是所有slaves的ip地址列表，k为一个定值。
+2.`ping(timestamp, slave_ip)`，这个方法在master端从slave端收到ping请求时执行，timestamp指当前的时间戳，slave_ip代表当前发送请求的slave端的ip地址
+3.`getDiedSlaves(timestamp)`，这个方法会定期的(两次执行之间的时间间隔不确定)执行，timestamp代表当前的时间戳，此方法需要返回不再运行的slave端的所有ip地址列表，如果没有发现则返回空集合。
+
+你可以假设当master端开始运行的时候时间戳为0，所有的方法都会根据全局的增长的时间戳来运行。
+ ### 样例说明
+ **样例1**
+
+```
+输入: 
+initialize(["10.173.0.2", "10.173.0.3"], 10)
+ping(1, "10.173.0.2")
+getDiedSlaves(20)
+getDiedSlaves(21)
+ping(22, "10.173.0.2")
+ping(23, "10.173.0.3")
+getDiedSlaves(24)
+getDiedSlaves(42)
+
+输出: 
+["10.173.0.3"]
+["10.173.0.2", "10.173.0.3"]
+[]
+["10.173.0.2"]
+
+解释:
+initialize(["10.173.0.2", "10.173.0.3"], 10)
+ping(1, "10.173.0.2")
+getDiedSlaves(20)
+>> ["10.173.0.3"]
+getDiedSlaves(21)
+>> ["10.173.0.2", "10.173.0.3"]
+ping(22, "10.173.0.2")
+ping(23, "10.173.0.3")
+getDiedSlaves(24)
+>> []
+getDiedSlaves(42)
+>> ["10.173.0.2"]
+```
+
+ ### 参考代码
+ ```java
+public class HeartBeat {
+
+    public Map<String, Integer> slaves_ip_list;
+    public int k;
+
+    public HeartBeat() {
+        // initialize your data structure here
+        slaves_ip_list = new HashMap<String, Integer>();
+    }
+
+    // @param slaves_ip_list a list of slaves'ip addresses
+    // @param k an integer
+    // @return void
+    public void initialize(List<String> slaves_ip_list, int k) {
+        // Write your code here
+        this.k = k;
+        for (String ip : slaves_ip_list)
+            this.slaves_ip_list.put(ip, 0);
+    }
+
+    // @param timestamp current timestamp in seconds
+    // @param slave_ip the ip address of the slave server
+    // @return nothing
+    public void ping(int timestamp, String slave_ip) {
+        // Write your code here
+        if (!slaves_ip_list.containsKey(slave_ip))
+            return;
+        
+        slaves_ip_list.put(slave_ip, timestamp);
+    }
+
+    // @param timestamp current timestamp in seconds
+    // @return a list of slaves'ip addresses that died
+    public List<String> getDiedSlaves(int timestamp) {
+        // Write your code here
+        List<String> results = new ArrayList<String>();
+        
+        Iterator iter = slaves_ip_list.entrySet().iterator();
+        while (iter.hasNext()) {
+            Map.Entry entry = (Map.Entry)iter.next();
+            String ip = (String) entry.getKey();
+            int time = (Integer) entry.getValue();
+            if (time <= timestamp - 2 * k)
+                results.add(ip);
+        }
+        return results;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/insert-delete-getrandom-o1-duplicates-allowed.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/insert-delete-getrandom-o1-duplicates-allowed.md"
new file mode 100644
index 0000000..9cfe712
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/insert-delete-getrandom-o1-duplicates-allowed.md"
@@ -0,0 +1,99 @@
+# Insert Delete GetRandom O(1) - 允许重复
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/insert-delete-getrandom-o1-duplicates-allowed/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个数据结构，需要支持以下操作，且平均时间复杂度为 **O(1)**。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+insert(1)
+insert(1)
+insert(2)
+getRandom()
+remove(1)
+
+// 初始化一个空的容器
+RandomizedCollection collection = new RandomizedCollection();
+
+// 把 1 插入到这容器中。如果这个容器不含 1 则返回 true 
+collection.insert(1);
+
+// 把 1 插入到这容器中。如果这个容器含 1 则返回 false, 此时容器中含有 [1,1]。
+collection.insert(1);
+
+// 把 1 插入到这容器中， 返回 true, 此时容器中含有 [1,1,2].
+collection.insert(2);
+
+// getRandom 应该有 2/3 的概率返回 1 ，1/3 的概率返回 2。
+collection.getRandom();
+
+// 从容器中删去一个 1 ， 此时容器中含有 [1,2].
+collection.remove(1);
+
+// getRandom 应该可以同等概率的返回 1 和 2。
+collection.getRandom();
+```
+
+**样例 2:**
+```
+输入:
+insert(1)
+insert(1)
+getRandom()
+remove(1)
+```
+
+ ### 参考代码
+ 用 LinkedHashSet 的版本
+```java
+public class RandomizedCollection {
+
+    ArrayList<Integer> result;
+    HashMap<Integer, LinkedHashSet<Integer>> map;
+    
+    public RandomizedCollection() {
+        result = new ArrayList<Integer>();
+        map = new HashMap<Integer, LinkedHashSet<Integer>>();
+    }
+
+    public boolean insert(int val) {
+        boolean alreadyExists = map.containsKey(val);
+        if(!alreadyExists) {
+            map.put(val, new LinkedHashSet<Integer>());
+        }
+        map.get(val).add(result.size());
+        result.add(val);
+        return !alreadyExists;
+    }
+    
+    public boolean remove(int val) {
+        if(!map.containsKey(val)) {
+            return false;
+        }
+        LinkedHashSet<Integer> valSet = map.get(val);
+        int indexToReplace = valSet.iterator().next();
+        
+        int numAtLastPlace = result.get(result.size() - 1);
+        LinkedHashSet<Integer> replaceWith = map.get(numAtLastPlace);
+        
+        result.set(indexToReplace, numAtLastPlace);
+        
+        valSet.remove(indexToReplace);
+        
+        if(indexToReplace != result.size() - 1) {
+            replaceWith.remove(result.size() - 1);
+            replaceWith.add(indexToReplace);
+        }
+        result.remove(result.size() - 1);
+        
+        if(valSet.isEmpty()) {
+            map.remove(val);
+        }
+        return true;
+    }
+    public int getRandom() {
+        return result.get((int)(Math.random() * result.size()));
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/insert-delete-getrandom-o1.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/insert-delete-getrandom-o1.md"
new file mode 100644
index 0000000..3ef427f
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/insert-delete-getrandom-o1.md"
@@ -0,0 +1,110 @@
+# Insert Delete GetRandom O(1)
+
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/insert-delete-getrandom-o1/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个数据结构实现在平均 `O(1)` 的复杂度下执行以下所有的操作。
+
+* `insert(val)`: 如果这个元素不在set中，则插入。
+
+* `remove(val)`: 如果这个元素在set中，则从set中移除。
+
+* `getRandom`: 随机从set中返回一个元素。每一个元素返回的可能性必须相同。
+ ### 样例说明
+ ```
+// 初始化空集set
+RandomizedSet randomSet = new RandomizedSet();
+
+// 1插入set中。返回正确因为1被成功插入
+randomSet.insert(1);
+
+// 返回错误因为2不在set中
+randomSet.remove(2);
+
+// 2插入set中，返回正确，set现在有[1,2]。
+randomSet.insert(2);
+
+// getRandom 应该随机的返回1或2。
+randomSet.getRandom();
+
+// 从set中移除1，返回正确。set现在有[2]。
+randomSet.remove(1);
+
+// 2已经在set中，返回错误。
+randomSet.insert(2);
+
+// 因为2是set中唯一的数字，所以getRandom总是返回2。
+randomSet.getRandom();
+```
+ ### 参考代码
+ 使用数组来保存当前集合中的元素，同时用一个hashMap来保存数字与它在数组中下标的对应关系。
+
+插入操作时：
+* 若已存在此元素返回false
+* 不存在时将新的元素插入数组最后一位，同时更新hashMap。
+
+删除操作时：
+* 若不存在此元素返回false
+* 存在时先根据hashMap得到要删除数字的下标，再将数组的最后一个数放到需要删除的数的位置上，删除数组最后一位，同时更新hashMap。
+
+获取随机数操作时：
+* 根据数组的长度来获取一个随机的下标，再根据下标获取元素。
+```java
+import java.util.Random;
+public class RandomizedSet {
+
+    ArrayList<Integer> nums;
+    HashMap<Integer, Integer> num2index;
+    Random rand;
+
+    public RandomizedSet() {
+        // do initialize if necessary 
+        nums = new ArrayList<Integer>();
+        num2index = new HashMap<Integer, Integer>();  
+        rand = new Random();
+    }
+    
+    // Inserts a value to the set
+    // Returns true if the set did not already contain the specified element or false
+    public boolean insert(int val) {
+        if (num2index.containsKey(val)) {
+            return false;
+        }
+        
+        num2index.put(val, nums.size());
+        nums.add(val);
+        return true;
+    }
+    
+    // Removes a value from the set
+    // Return true if the set contained the specified element or false
+    public boolean remove(int val) {
+        if (!num2index.containsKey(val)) {
+            return false; 
+        } 
+        
+        int index = num2index.get(val);
+        if (index < nums.size() - 1) { // not the last one than swap the last one with this val
+            int last = nums.get(nums.size() - 1);
+            nums.set(index, last);
+            num2index.put(last, index);
+        }
+        num2index.remove(val);
+        nums.remove(nums.size() - 1);
+        return true;
+    }
+    
+    // Get a random element from the set
+    public int getRandom() {
+        return nums.get(rand.nextInt(nums.size()));
+    }
+}
+
+/**
+ * Your RandomizedSet object will be instantiated and called as such:
+ * RandomizedSet obj = new RandomizedSet();
+ * boolean param = obj.insert(val);
+ * boolean param = obj.remove(val);
+ * int param = obj.getRandom();
+ */
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/island-perimeter.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/island-perimeter.md"
new file mode 100644
index 0000000..92a564b
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/island-perimeter.md"
@@ -0,0 +1,53 @@
+# 岛的周长
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/island-perimeter/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一张用二维数组表示的网格地图，其中1表示陆地单元格，0表示水域单元格。网格地图中的单元格视为水平/垂直相连（斜向不相连）。这个网格地图四周完全被水域包围着，并且其中有且仅有一个**岛**（定义为一块或多块相连的陆地单元格）。这个岛不包含**湖**（定义为不和外围水域相连的水域单元格）。一个地图单元格是边长为1的一个正方形；网格地图是一个矩形，并且它的长和宽不超过100。你要做的是求出这个岛的周长。
+ ### 样例说明
+ ```
+[[0,1,0,0],
+ [1,1,1,0],
+ [0,1,0,0],
+ [1,1,0,0]]
+
+答案：16
+```
+说明：岛的边界为下图中被标为黄色的边，其周长即为16：
+![](https://lintcode-media.s3.amazonaws.com/problem/island.png "")
+ ### 参考代码
+ 对于一片陆地，
+* 若其上方没有陆地，则贡献一条边；
+* 若其左方没有陆地，则贡献一条边；
+* 若其下方没有陆地，则贡献一条边；
+* 若其右方没有陆地，则贡献一条边；
+
+遍历所有陆地求出所有贡献和即可。
+```java
+public class Solution {
+    int []dx  = {1, 0, -1, 0};
+    int []dy  = {0, 1, 0, -1};
+    
+    private boolean valid(int x, int y, int[][] grid) {
+        if (0 <= x && x < grid.length && 0 <= y && y < grid[x].length) {
+            return grid[x][y] == 0;
+        }
+        return true;
+    } 
+    public int islandPerimeter(int[][] grid) {
+        int Perimeter = 0;
+        
+        for(int i = 0; i < grid.length; i ++) {
+            for(int j = 0; j < grid[i].length;j ++) {
+                if(grid[i][j] == 1) {
+                    for (int k = 0; k < 4; k++) {
+                        if (valid(i + dx[k], j + dy[k], grid)) {
+                            Perimeter ++;
+                        }
+                    }
+                }
+            }
+        }
+        return Perimeter;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/line-reflection.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/line-reflection.md"
new file mode 100644
index 0000000..a70b2b5
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/line-reflection.md"
@@ -0,0 +1,45 @@
+# 直线对称
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/line-reflection/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定二维平面上的`n`点，请问是否有这样一条与y轴平行的线使所有点对称。
+ ### 样例说明
+ **样例1**
+
+```
+输入: [[1,1],[-1,1]]
+输出: true
+```
+
+**样例2**
+
+```
+输入: [[1,1],[-1,-1]]
+输出: false
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    public boolean isReflected(int[][] points) {
+        int max = 0, min = 0;
+        HashMap<Integer, HashSet<Integer>> hashmap = new HashMap<>();
+        for (int i = 0; i < points.length; i++) {
+            max = Math.max(points[i][0], max);
+            min = Math.min(points[i][0], min);
+            if (!hashmap.containsKey(points[i][1])) {
+                HashSet<Integer> hashset = new HashSet<>();
+                hashset.add(points[i][0]);
+                hashmap.put(points[i][1], hashset);
+            } else {
+                hashmap.get(points[i][1]).add(points[i][0]);
+            }
+        }
+        for (int i = 0; i < points.length; i++) {
+            if (!hashmap.containsKey(points[i][1]) || !hashmap.get(points[i][1]).contains(max + min - points[i][0])) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/load-balancer.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/load-balancer.md"
new file mode 100644
index 0000000..1c4a078
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/load-balancer.md"
@@ -0,0 +1,93 @@
+# 负载均衡器
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/load-balancer/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 为网站实现一个负载均衡器，提供如下的 3 个功能：
+
+1. 添加一台新的服务器到整个集群中 => `add(server_id)`。
+2. 从集群中删除一个服务器 => `remove(server_id)`。
+3. 在集群中随机（等概率）选择一个有效的服务器 => `pick()`。
+
+最开始时，集群中一台服务器都没有。每次 `pick()` 调用你需要在集群中随机返回一个 `server_id`。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+  add(1)
+  add(2)
+  add(3)
+  pick()
+  pick()
+  pick()
+  pick()
+  remove(1)
+  pick()
+  pick()
+  pick()
+输出:
+  1
+  2
+  1
+  3
+  2
+  3
+  3
+解释: pick() 的返回值是随机的，也可以是 2 3 3 1 3 2 2 或其他的。
+```
+
+**样例 2:**
+```
+输入:
+  add(1)
+  add(2)
+  remove(1)
+  pick()
+  pick()
+输出:
+  2
+  2
+```
+
+ ### 参考代码
+ 一种可行的思路是同时使用哈希表和数组.
+
+* `pick()`: 数组中随机选取一个元素可以直接使用随机函数得到一个 \[0, 数组大小-1\] 的整数即可.
+* `add(server_id)`: 在数组末尾添加这个`server_id`, 并在哈希表中添加 `server_id` -> 数组下标 的键值映射
+* `remove(server_id)`: 利用哈希表得到 `server_id` 的数组下标, 在数组中将它和最末尾的元素交换位置, 然后删除, 并将修改同步到哈希表
+```python
+class LoadBalancer:
+    
+    def __init__(self):
+        self.server_ids = []
+        self.id2index = {}
+
+    # @param {int} server_id add a new server to the cluster 
+    # @return nothing
+    def add(self, server_id):
+        if server_id in self.id2index:
+            return
+        self.server_ids.append(server_id)
+        self.id2index[server_id] = len(self.server_ids) - 1
+
+    # @param {int} server_id remove a bad server from the cluster
+    # @return nothing
+    def remove(self, server_id):
+        if server_id not in self.id2index:
+            return
+        
+        # remove the server_id
+        index = self.id2index[server_id]
+        del self.id2index[server_id]
+        
+        # overwrite the one to be removed
+        last_server_id = self.server_ids[-1]
+        self.id2index[last_server_id] = index
+        self.server_ids[index] = last_server_id
+        self.server_ids.pop()
+
+    # @return {int} pick a server in the cluster randomly with equal probability
+    def pick(self):
+        import random
+        index = random.randint(0, len(self.server_ids) - 1)
+        return self.server_ids[index]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/longest-palindrome.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/longest-palindrome.md"
new file mode 100644
index 0000000..4d9bb2c
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/longest-palindrome.md"
@@ -0,0 +1,41 @@
+# 最长回文串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-palindrome/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个包含大小写字母的字符串。求出由这些字母构成的最长的回文串的长度是多少。
+
+数据是大小写敏感的，也就是说，`"Aa"` 并不会被认为是一个回文串。
+ ### 样例说明
+ **样例 1:**
+```
+输入 : s = "abccccdd"
+输出 : 7
+说明 : 
+一种可以构建出来的最长回文串方案是 "dccaccd"。
+```
+ ### 参考代码
+ ```python
+class Solution:
+    # @param {string} s a string which consists of lowercase or uppercase letters
+    # @return {int} the length of the longest palindromes that can be built
+    
+    # the answer is the count of characters that has even number of appereances.
+    # for characters that has odd number of appereances,
+    # their appereances minus 1 will make their apperances even.
+    # And finally we can put an unused character in the middle of the palindrome
+    def longestPalindrome(self, s):
+        # Write your code here
+        hash = {}
+
+        for c in s:
+            if c in hash:
+                del hash[c]
+            else:
+                hash[c] = True
+
+        remove = len(hash)
+        if remove > 0:
+            remove -= 1
+    
+        return len(s) - remove
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/majority-number-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/majority-number-ii.md"
new file mode 100644
index 0000000..5ad2f04
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/majority-number-ii.md"
@@ -0,0 +1,43 @@
+# 主元素 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/majority-number-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个整型数组，找到主元素，它在数组中的出现次数严格大于数组元素个数的三分之一。</p><p><br></p>
+ ### 样例说明
+ 
+ ### 参考代码
+ 可以发现，对于其他的元素来讲，若出现次数大于1/3，则两者出现总次数大于2/3.必不可能被抵消。
+若其他元素出现次数均不超过1/3，可以发现，抵消与重建至少要2/3的花费，则这个出现次数大于1/3的数必出现在candidate1与candidate2中，不可能被替换掉。
+```python
+class Solution:
+    """
+    @param nums: A list of integers
+    @return: The majority number occurs more than 1/3
+    """
+    def majorityNumber(self, nums):
+        candidate1, count1 = None, 0
+        candidate2, count2 = None, 0
+        for num in nums:
+            if candidate1 == num:
+                count1 += 1
+            elif candidate2 == num:
+                count2 += 1
+            elif count1 == 0:
+                count1 += 1
+                candidate1 = num
+            elif count2 == 0:
+                count2 += 1
+                candidate2 = num
+            else:
+                count1 -= 1
+                count2 -= 1
+    
+        count1, count2 = 0, 0
+        for num in nums:
+            if candidate1 == num:
+                count1 += 1
+            elif candidate2 == num:
+                count2 += 1
+    
+        return candidate1 if count1 > count2 else candidate2
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/majority-number-iii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/majority-number-iii.md"
new file mode 100644
index 0000000..46d47ca
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/majority-number-iii.md"
@@ -0,0 +1,85 @@
+# 主元素 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/majority-number-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个整型数组，找到主元素，它在数组中的出现次数严格大于数组元素个数的<font color="#e76363"><b>1/k</b></font>。<br></p>
+ ### 样例说明
+ 例1:
+```
+输入: [3,1,2,3,2,3,3,4,4,4] and k=3, 
+输出: 3.
+```
+
+例2:
+```
+输入: [1,1,2] and k=3, 
+输出: 1.
+```
+
+
+ ### 参考代码
+ 在原方法的基础上，利用hashmap即可
+```java
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @param k: As described
+     * @return: The majority number
+     */
+    public int majorityNumber(ArrayList<Integer> nums, int k) {
+        // count at most k keys.
+        HashMap<Integer, Integer> counters = new HashMap<Integer, Integer>();
+        for (Integer i : nums) {
+            if (!counters.containsKey(i)) {
+                counters.put(i, 1);
+            } else {
+                counters.put(i, counters.get(i) + 1);
+            }
+            
+            if (counters.size() >= k) {
+                removeKey(counters);
+            }
+        }
+        
+        // corner case
+        if (counters.size() == 0) {
+            return Integer.MIN_VALUE;
+        }
+        
+        // recalculate counters
+        for (Integer i : counters.keySet()) {
+            counters.put(i, 0);
+        }
+        for (Integer i : nums) {
+            if (counters.containsKey(i)) {
+                counters.put(i, counters.get(i) + 1);
+            }
+        }
+        
+        // find the max key
+        int maxCounter = 0, maxKey = 0;
+        for (Integer i : counters.keySet()) {
+            if (counters.get(i) > maxCounter) {
+                maxCounter = counters.get(i);
+                maxKey = i;
+            }
+        }
+        
+        return maxKey;
+    }
+    
+    private void removeKey(HashMap<Integer, Integer> counters) {
+        Set<Integer> keySet = counters.keySet();
+        List<Integer> removeList = new ArrayList<>();
+        for (Integer key : keySet) {
+            counters.put(key, counters.get(key) - 1);
+            if (counters.get(key) == 0) {
+                removeList.add(key);
+            }
+        }
+        for (Integer key : removeList) {
+            counters.remove(key);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/majority-number.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/majority-number.md"
new file mode 100644
index 0000000..61fe690
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/majority-number.md"
@@ -0,0 +1,33 @@
+# 主元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/majority-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个整型数组，找出主元素，它在数组中的出现次数严格大于数组元素个数的二分之一。</p><p><br></p>
+ ### 样例说明
+ 
+ ### 参考代码
+ <p>&nbsp;&nbsp;&nbsp;&nbsp;<br></p>
+```java
+public class Solution {
+    /**
+     * @param nums: a list of integers
+     * @return: find a  majority number
+     */
+    public int majorityNumber(ArrayList<Integer> nums) {
+        //由于主元素在数组中个数严格大于1/2，所以假设当前元素就是主元素，用count记录当前元素个数与其他元素个数的差值，
+        //candidate记录当前元素是什么，最后count一定为正数并且candidate就是主元素
+        int count = 0, candidate = -1;
+        for (int i = 0; i < nums.size(); i++) {
+            if (count == 0) {
+                candidate = nums.get(i);
+                count = 1;
+            } else if (candidate == nums.get(i)) {
+                count++;
+            } else {
+                count--;
+            }
+        }
+        return candidate;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/max-points-on-a-line.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/max-points-on-a-line.md"
new file mode 100644
index 0000000..34cb4a0
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/max-points-on-a-line.md"
@@ -0,0 +1,230 @@
+# 最多有多少个点在一条直线上
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/max-points-on-a-line/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出二维平面上的n个点，求最多有多少点在同一条直线上。
+ ### 样例说明
+ **样例 1:**
+```
+输入:(1,2),(3,6),(0,0),(1,3).
+输出:3
+```
+**样例 2:**
+```
+输入:(1,2),(2,3),(3,2).
+输出:2
+```
+ ### 参考代码
+ Given n points on a 2D plane, find the maximum number of points that lie on the same straight line.
+```java
+public class Solution {
+    public  int maxPoints(Point[] points) {
+        if (points == null || points.length == 0) {
+            return 0;
+        }  
+
+        HashMap<Double, Integer> map=new HashMap<Double, Integer>();
+        int max = 1;
+
+        for(int i = 0 ; i < points.length; i++) {
+            // shared point changed, map should be cleared and server the new point
+            map.clear();
+
+            // maybe all points contained in the list are same points,and same points' k is 
+            // represented by Integer.MIN_VALUE
+            map.put((double)Integer.MIN_VALUE, 1);
+
+            int dup = 0;
+            for(int j = i + 1; j < points.length; j++) {
+                if (points[j].x == points[i].x && points[j].y == points[i].y) {
+                    dup++;
+                    continue;
+                }
+
+                // look 0.0+(double)(points[j].y-points[i].y)/(double)(points[j].x-points[i].x)
+                // because (double)0/-1 is -0.0, so we should use 0.0+-0.0=0.0 to solve 0.0 !=-0.0
+                // problem
+
+                // if the line through two points are parallel to y coordinator, then K(slop) is 
+                // Integer.MAX_VALUE
+                double key=points[j].x - points[i].x == 0 ? 
+                    Integer.MAX_VALUE :
+                    0.0 + (double)(points[j].y - points[i].y) / (double)(points[j].x - points[i].x);
+
+                if (map.containsKey(key)) {
+                    map.put(key, map.get(key) + 1);
+                } else {
+                    map.put(key, 2);
+                }
+            }
+
+            for (int temp: map.values()) {
+                // duplicate may exist
+                if (temp + dup > max) {
+                    max = temp + dup;
+                }
+            }
+
+        }
+        return max;
+    }
+}
+
+
+// version 2:
+/**
+ * Definition for a point.
+ * class Point {
+ *     int x;
+ *     int y;
+ *     Point() { x = 0; y = 0; }
+ *     Point(int a, int b) { x = a; y = b; }
+ * }
+ */
+class Line {
+    public double a, b, c;
+    public Line(double a, double b, double c) {
+        this.a = a;
+        this.b = b;
+        this.c = c;
+    }
+    
+    public Line(int x1, int y1, int x2, int y2) {
+        if (x1 == x2) {
+            if (x1 == 0) {
+                a = 1;
+                b = 0;
+                c = 0;
+            } else {
+                a = 1.0 / x1;
+                b = 0;
+                c = 1;
+            }
+        } else if (y1 == y2) {
+            if (y1 == 0) {
+                a = 0;
+                b = 1;
+                c = 0;
+            } else {
+                a = 0;
+                b = 1.0 / y1;
+                c = 1;
+            }
+        } else {
+            if (x1 * y2 == x2 * y1) {
+                a = 1;
+                b = - 1.0 * (y1 - y2) / (x1 - x2);
+                c = 0;
+           } else {
+                a = 1.0 * (y1 - y2) / (x2 * y1 - x1 * y2);
+                b = 1.0 * (x1 - x2) / (x1 * y2 - x2 * y1);
+                c = 1;
+            }
+        }
+    }
+    
+    public String toString() {
+        return Double.toString(a) + " " + Double.toString(b) + " " + Double.toString(c);
+    }
+}
+
+public class Solution {
+    
+    public int maxPoints(Point[] points) {
+        if (points.length < 2) {
+            return points.length;
+        }
+        
+        HashMap<String, Integer> hash = new HashMap<String, Integer>();
+        for (int i = 0; i < points.length; i++) {
+            for (int j = i + 1; j < points.length; j++) {
+                Line line = new Line(points[i].x, points[i].y,
+                                     points[j].x, points[j].y);
+                String key = line.toString();
+                if (hash.containsKey(key)) {
+                    hash.put(key, hash.get(key) + 1);
+                } else {
+                    hash.put(key, 1);
+                }
+            }
+        }
+        
+        int max = 0;
+        String maxKey = "";
+        for (String key: hash.keySet()) {
+            if (hash.get(key) > max) {
+                max = hash.get(key);
+                maxKey = key;
+                
+            }
+        }
+        String[] params = maxKey.split(" ");
+        double a = Double.parseDouble(params[0]);
+        double b = Double.parseDouble(params[1]);
+        double c = Double.parseDouble(params[2]);
+        
+        int count = 0;
+        for (int i = 0; i < points.length; i++) {
+            if (Math.abs(a * points[i].x + b * points[i].y - c) < 1e-6) {
+                count++;
+            }
+        }
+        return count;
+    }
+}
+
+
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param points an array of point
+     * @return an integer
+     */
+    public int maxPoints(Point[] points) {
+        // Write your code here
+        if (points == null) {
+            return 0;
+        }
+        int ans = 0;
+        for (int i = 0; i < points.length; i++) {
+            Map<String, Integer> slope = new HashMap<>();
+            int maxPoints = 0, overlap = 0, vertical = 0;
+
+            for (int j = i + 1; j < points.length; j++) {
+                if (points[i].x == points[j].x) {
+                    if (points[i].y == points[j].y) {
+                        overlap++;
+                    } else {
+                        vertical++;
+                    }
+                    continue;
+                }
+                int dx = points[i].x - points[j].x;
+                int dy = points[i].y - points[j].y;
+                int tmp = gcd(dx, dy);
+                dx /= tmp;
+                dy /= tmp;
+                String k = dy + "/" + dx;
+
+                if (!slope.containsKey(k)) {
+                    slope.put(k, 0);
+                }
+                slope.put(k, slope.get(k) + 1);
+                maxPoints = Math.max(maxPoints, slope.get(k));
+            }
+            maxPoints = Math.max(maxPoints, vertical);
+            ans = Math.max(ans, maxPoints + overlap + 1);
+        }
+        return ans;
+    }
+
+    int gcd(int a, int b) {
+        if (b == 0) {
+            return a;
+        } else {
+            return gcd(b, a % b);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/memcache.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/memcache.md"
new file mode 100644
index 0000000..a6195b6
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/memcache.md"
@@ -0,0 +1,126 @@
+# 内存缓存
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/memcache/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现下列几个方法：
+1.`get(curtTime, key)`. 得到key的值，如果不存在返回2147483647
+2.`set(curtTime, key, value, ttl)`. 设置一个pair(key,value)，有效期从curtTime到curtTime + ttl -1 , 如果ttl为0，则一直存在
+3.`delete(curtTime, key)`. 删除这个key
+4.`incr(curtTime, key, delta)`. 给key的value加上delta，并且返回 如果不存在返回 2147483647。
+5.`decr(curtTime, key, delta)`. 给key的value减去delta，并且返回 如果不存在返回 2147483647。
+ ### 样例说明
+ **样例1**
+
+```
+get(1, 0)
+>> 2147483647
+set(2, 1, 1, 2)
+get(3, 1)
+>> 1
+get(4, 1)
+>> 2147483647
+incr(5, 1, 1)
+>> 2147483647
+set(6, 1, 3, 0)
+incr(7, 1, 1)
+>> 4
+decr(8, 1, 1)
+>> 3
+get(9, 1)
+>> 3
+delete(10, 1)
+get(11, 1)
+>> 2147483647
+incr(12, 1, 1)
+>> 2147483647
+```**样例1**
+
+```
+get(1, 0)
+>> 2147483647
+set(2, 1, 1, 2)
+get(3, 1)
+>> 1
+get(4, 1)
+>> 2147483647
+incr(5, 1, 1)
+>> 2147483647
+set(6, 1, 3, 0)
+incr(7, 1, 1)
+>> 4
+decr(8, 1, 1)
+>> 3
+get(9, 1)
+>> 3
+delete(10, 1)
+get(11, 1)
+>> 2147483647
+incr(12, 1, 1)
+>> 2147483647
+```
+ ### 参考代码
+ ```java
+class Resource {
+    public int value;
+    public int expired;
+    public Resource(int value, int expired) {
+        this.value = value;
+        this.expired = expired;
+    }
+}
+
+public class Memcache {
+
+    Map<Integer, Resource> client = null;
+
+    public Memcache() {
+        // Initialize your data structure here.
+        client = new HashMap<Integer, Resource>();
+    }
+
+    public int get(int curtTime, int key) {
+        // Write your code here
+        if (!client.containsKey(key))
+            return Integer.MAX_VALUE;
+
+        Resource res = client.get(key);
+        if (res.expired >= curtTime || res.expired == -1)
+            return res.value;
+        else
+            return Integer.MAX_VALUE;
+    }
+
+    public void set(int curtTime, int key, int value, int ttl) {
+        // Write your code here
+        int expired;
+        if (ttl == 0)
+            expired = -1;
+        else
+            expired = curtTime + ttl - 1;
+        client.put(key, new Resource(value, expired));
+    }
+
+    public void delete(int curtTime, int key) {
+        // Write your code here
+        if (!client.containsKey(key))
+            return;
+        client.remove(key);
+    }
+    
+    public int incr(int curtTime, int key, int delta) {
+        // Write your code here
+        if (get(curtTime, key) == Integer.MAX_VALUE)
+            return Integer.MAX_VALUE;
+        client.get(key).value += delta;
+        return client.get(key).value;
+    }
+
+    public int decr(int curtTime, int key, int delta) {
+        // Write your code here
+        if (get(curtTime, key) == Integer.MAX_VALUE)
+            return Integer.MAX_VALUE;
+        client.get(key).value -= delta;
+        return client.get(key).value;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/mini-cassandra.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/mini-cassandra.md"
new file mode 100644
index 0000000..a39c333
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/mini-cassandra.md"
@@ -0,0 +1,106 @@
+# 迷你Cassandra
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/mini-cassandra/?utm_source=sc-github-wzz)
+ ## 题目描述
+ Cassandra是一个NoSQL数据库。Cassandra中的一个单独数据条目由3部分构成：
+
+1. row_key (相当于于哈希值)
+2. column_key
+3. value
+
+row_key 用于哈希，不支持范围查询。我们将其简化为字符串。
+column_key 已排序并支持范围查询。我们将其简化为整数。
+value 是一个字符串。你可以将任何数据序列化为字符串并将其存储在值中。
+
+现在要实现下面两个方法：
+
+1. `insert(row_key, column_key, value)`
+2. `query(row_key, column_start, column_end)`  返回条目列表
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  insert("google", 1, "haha")
+  query("google", 0, 1)
+输出: [(1, "haha")]
+```
+
+**样例 2:**
+
+```
+输入: 
+  insert("google", 1, "haha")
+  insert("lintcode", 1, "Good")
+  insert("google", 2, "hehe")
+  query("google", 0, 1)
+  query("google", 0, 2)
+  query("go", 0, 1)
+  query("lintcode", 0, 10)
+输出: 
+  [(1, "haha")]
+  [(1, "haha"),(2, "hehe")]
+  []
+  [(1, "Good")]
+```
+ ### 参考代码
+ 注意: 一个 row_key 可以对应多个 Column; 而一个 row_key 和一个 column_key 是唯一确定对应的 value 的.
+
+可以使用哈希表套哈希表实现: `map<row_key, map<column_key, value>>` 
+
+每次 `insert` 直接更新 value 即可.
+
+而 `query` 则需要取出一个 row_key 对应的所有的 <column_key, value> 对, 如果 column_key 在给定范围内时, 放入答案序列中即可.
+```java
+/**
+ * Definition of Column:
+ * public class Column {
+ *     public int key;
+ *     public String value;
+ *     public Column(int key, String value) {
+ *         this.key = key;
+ *         this.value = value;
+ *    }
+ * }
+ */
+public class MiniCassandra {
+
+    private Map<String, NavigableMap<Integer, String>> hash;
+
+    public MiniCassandra() {
+        // initialize your data structure here.
+        hash = new HashMap<String, NavigableMap<Integer, String>>();
+    }
+
+    /**
+     * @param raw_key      a string
+     * @param column_start an integer
+     * @param column_end   an integer
+     * @return void
+     */
+    public void insert(String raw_key, int column_key, String column_value) {
+        // Write your code here
+        if (!hash.containsKey(raw_key))
+            hash.put(raw_key, new TreeMap<Integer, String>());
+        hash.get(raw_key).put(column_key, column_value);
+    }
+
+    /**
+     * @param raw_key      a string
+     * @param column_start an integer
+     * @param column_end   an integer
+     * @return a list of Columns
+     */
+    public List<Column> query(String raw_key, int column_start, int column_end) {
+        // Write your code here
+        List<Column> rt = new ArrayList<Column>();
+        if (!hash.containsKey(raw_key))
+            return rt;
+        for (Map.Entry<Integer, String> entry : hash.get(raw_key).subMap(column_start, true, column_end, true)
+                .entrySet()) {
+            rt.add(new Column(entry.getKey(), entry.getValue()));
+        }
+        return rt;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/minimum-window-substring.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/minimum-window-substring.md"
new file mode 100644
index 0000000..054fe02
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/minimum-window-substring.md"
@@ -0,0 +1,101 @@
+# 最小子串覆盖
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-window-substring/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个字符串 `source` 和 `target`. 求 `source` 中最短的包含 `target` 中每一个字符的子串.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: source = "abc", target = "ac"
+输出: "abc"
+```
+
+**样例 2:**
+
+```
+输入: source = "adobecodebanc", target = "abc"
+输出: "banc"
+解释: "banc" 是 source 的包含 target 的每一个字符的最短的子串.
+```
+
+**样例 3:**
+
+```
+输入: source = "abc", target = "aa"
+输出: ""
+解释: 没有子串包含两个 'a'.
+```
+ ### 参考代码
+ 利用双指针的方式，找到最短的子串
+```java
+public class Solution {
+    /**
+     * @param source : A string
+     * @param target: A string
+     * @return: A string denote the minimum window, return "" if there is no such a string
+     */
+    public String minWindow(String ss , String tt) {
+        char[] s = ss.toCharArray();
+        char[] t = tt.toCharArray();
+        if (t.length == 0) {
+            return "";
+        }
+        
+        int[] cntS = new int[256]; // number of appearances for each character in the window
+        int[] cntT = new int[256]; // how many times each character appears in T
+        int K = 0; // number of T's unique chracters
+        for (int i = 0; i < 256; ++i) {
+            cntS[i] = cntT[i] = 0;
+        }
+        
+        for (char c : t) {
+            ++cntT[c];
+            if (cntT[c] == 1) {
+                ++K;
+            }
+        }
+        
+        // abccba ==> K=3
+        int now = 0; // number of T's unique characters the window contains
+        // when now == K, we're good
+        
+        int ansl = -1, ansr = -1;
+        int l, r = 0;
+        for (l = 0; l < s.length; ++l) { // main pointer, st
+            // insert into window
+            while (r < s.length && now < K) {
+                ++cntS[s[r]];
+                // phase jump
+                if (cntS[s[r]] == cntT[s[r]]) {
+                    ++now;
+                }
+                
+                ++r;
+            }
+            
+            if (now == K) {
+                // this window is good
+                if (ansl == -1 || r - l < ansr - ansl) {
+                    ansl = l;
+                    ansr = r;
+                }
+            }
+            
+            // remove from window
+            --cntS[s[l]];
+            if (cntS[s[l]] == cntT[s[l]] - 1) {
+                --now;
+            }
+        }
+        
+        // s[l...(r-1)]
+        if (ansl == -1) {
+            return "";
+        }
+        else {
+            return ss.substring(ansl, ansr);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/mirror-numbers.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/mirror-numbers.md"
new file mode 100644
index 0000000..dd4f211
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/mirror-numbers.md"
@@ -0,0 +1,63 @@
+# 镜像数字
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/mirror-numbers/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 一个镜像数字是指一个数字旋转180度以后和原来一样(倒着看)。例如，数字"69"，"88"，和"818"都是镜像数字。
+写下一个函数来判断是否这个数字是镜像的。数字用字符串来表示。
+ ### 样例说明
+ 
+ ### 参考代码
+ 将倒过来能看成数字的数字哈希一下，就能进行转换判断了。
+```java
+public class Solution {
+    /**
+     * @param num a string
+     * @return true if a number is strobogrammatic or false
+     */
+    public boolean isStrobogrammatic(String num) {
+        // Write your code here
+        Map<Character, Character> map = new HashMap<Character, Character>();
+        map.put('6', '9');
+        map.put('9', '6');
+        map.put('0', '0');
+        map.put('1', '1');
+        map.put('8', '8');
+        int left = 0, right = num.length() - 1;
+        while (left <= right) {
+            if (!map.containsKey(num.charAt(left))) {
+                return false;
+            }
+            if (map.get(num.charAt(left)) != num.charAt(right)) {
+                return false;
+            }
+            left ++;
+            right --;
+        }
+        return true;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param num a string
+     * @return true if a number is strobogrammatic or false
+     */
+    public boolean isStrobogrammatic(String num) {
+        // Write your code here
+        int[] map = new int[256];
+        map['0'] = '0';
+        map['1'] = '1';
+        map['6'] = '9';
+        map['8'] = '8';
+        map['9'] = '6';
+        for (int i = 0; i < num.length(); i++) {
+            int j = num.length() - i - 1;
+            if (map[num.charAt(i)] != num.charAt(j)) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/name-deduplication.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/name-deduplication.md"
new file mode 100644
index 0000000..c98eda3
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/name-deduplication.md"
@@ -0,0 +1,44 @@
+# 姓名去重
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/name-deduplication/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一串名字，将他们去重之后返回。两个名字重复是说在忽略大小写的情况下是一样的。
+ ### 样例说明
+ 例1: 
+```
+输入:["James", "james", "Bill Gates", "bill Gates", "Hello World", "HELLO WORLD", "Helloworld"]
+
+
+输出:["james", "bill gates", "hello world", "helloworld"]
+```
+例2: 
+```
+输入:["cmy","Cmy"]
+
+输出:["cmy"]
+```
+ ### 参考代码
+ 利用map去重
+```cpp
+#include <algorithm>
+class Solution {
+public:
+    /**
+     * @param names a string array
+     * @return a string array
+     */
+    vector<string> nameDeduplication(vector<string>& names) {
+        // Write your code here
+        map<string, bool> mp;
+        vector<string> result;
+        for (auto& str : names) {
+            std::transform(str.begin(), str.end(), str.begin(), ::tolower);
+            if (mp.find(str) == mp.end()) {
+                mp[str] = true;
+                result.push_back(str);
+            }
+        }
+        return result;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/number-of-boomerangs.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/number-of-boomerangs.md"
new file mode 100644
index 0000000..2975b66
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/number-of-boomerangs.md"
@@ -0,0 +1,55 @@
+# 回旋镖的数量
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/number-of-boomerangs/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在平面中给定n个点，每一对点都是不同的，“回旋镖”是一个点的的元组 `(i, j, k)`，其中 `i` 和 `j` 之间的距离与`i`和`k`之间的距离相同 **（元组的顺序是重要的）**。
+
+找到回旋镖的数量。 您可以假设n最多为**500**并且点的坐标都在  **[-10000, 10000]** （包括）范围内。
+
+
+ ### 样例说明
+ ```
+输入:
+[[0,0],[1,0],[2,0]]
+
+输出:
+2
+
+说明：
+两个回旋镖是[[1,0], [0,0], [2,0]]和[[1,0], [2,0], [0,0]]
+```
+ ### 参考代码
+ 两层for循环遍历每两个点，计算两点之间距离，以及可以构成该距离的的个数。
+用hash表记录Map<distance, count>
+则该距离下可构成回旋镖的个数为count * (count - 1)
+```java
+public class Solution {
+    private int getDistance(int[] a, int[] b) {
+        int dx = a[0] - b[0];
+        int dy = a[1] - b[1];
+        return dx * dx + dy * dy;
+    }
+    
+    public int numberOfBoomerangs(int[][] points) {
+        if (points == null) {
+            return 0;
+        }
+        int ans = 0;
+        for (int i = 0; i < points.length; i++) {
+            Map<Integer, Integer> disCount = new HashMap<>();
+            for (int j = 0; j < points.length; j++) {
+                if (i == j) {
+                    continue;
+                }
+                int distance = getDistance(points[i], points[j]);
+                int count = disCount.getOrDefault(distance, 0);
+                disCount.put(distance, count + 1);
+            }
+            for (int count : disCount.values()) {
+                ans += count * (count - 1);
+            }
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/rehashing.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/rehashing.md"
new file mode 100644
index 0000000..300f871
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/rehashing.md"
@@ -0,0 +1,64 @@
+# 重哈希
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/rehashing/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 哈希表容量的大小在一开始是不确定的。如果哈希表存储的元素太多（如超过容量的十分之一），我们应该将哈希表容量扩大一倍，并将所有的哈希值重新安排。假设你有如下一哈希表：
+
+`size=3`, `capacity=4`
+
+	[null, 21, 14, null]
+	       ↓    ↓
+	       9   null
+	       ↓
+	      null
+
+
+哈希函数为：
+
+	int hashcode(int key, int capacity) {
+	    return key % capacity;
+	}
+
+这里有三个数字9，14，21，其中21和9共享同一个位置因为它们有相同的哈希值1(21 % 4 = 9 % 4 = 1)。我们将它们存储在同一个链表中。
+
+重建哈希表，将容量扩大一倍，我们将会得到：
+
+`size=3`, `capacity=8`
+
+	index:   0    1    2    3     4    5    6   7
+	hash : [null, 9, null, null, null, 21, 14, null]
+
+给定一个哈希表，返回重哈希后的哈希表。
+ ### 样例说明
+ ***样例 1***
+```
+输入 : [null, 21->9->null, 14->null, null]
+输出 : [null, 9->null, null, null, null, 21->null, 14->null, null]
+```
+
+ ### 参考代码
+ ```python
+class Solution:
+    def addlistnode(self, node, number):
+        if node.next != None:
+            self.addlistnode(node.next, number)
+        else:
+            node.next = ListNode(number)
+
+    def addnode(self, anshashTable, number):
+        p = number % len(anshashTable)
+        if anshashTable[p] == None:
+            anshashTable[p] = ListNode(number)
+        else:
+            self.addlistnode(anshashTable[p], number)
+
+    def rehashing(self,hashTable):
+        HASH_SIZE = 2 * len(hashTable)
+        anshashTable = [None for i in range(HASH_SIZE)]
+        for item in hashTable:
+            p = item
+            while p != None:
+                self.addnode(anshashTable,p.val)
+                p = p.next
+        return anshashTable
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/same-number.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/same-number.md"
new file mode 100644
index 0000000..2109a1e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/same-number.md"
@@ -0,0 +1,51 @@
+# 相同数字
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/same-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个数组，如果数组中**存在**相同数字，且至少有两个相同数字的距离小于给定值`k`，输出`YES`，否则输出`NO`。
+ ### 样例说明
+ **样例1**
+
+```
+输入: array = [1,2,3,1,5,9,3] 和 k = 4
+输出: "YES"
+解释:
+index为3的1和index为0的1距离为3，满足题意输出YES。
+```
+
+**样例2**
+
+```
+输入: array = [1,2,3,5,7,1,5,1,3] 和 k = 4,
+输出: "YES"
+解释:
+index为7的1和index为5的1距离为2，满足题意。
+```
+ ### 参考代码
+ 哈希表
+```java
+public class Solution {
+    /**
+     * @param nums: the arrays
+     * @param k: the distance of the same number
+     * @return: the ans of this question
+     */
+    public String sameNumber(int[] nums, int k) {
+        if (nums == null || nums.length == 0) {
+            return "NO";
+        }
+        
+        Map<Integer, Integer> position = new HashMap<>();
+        for (int i = 0; i < nums.length; i++) {
+            if (position.containsKey(nums[i])) {
+                if (i - position.get(nums[i]) < k) {
+                    return "YES";
+                }
+            } 
+            position.put(nums[i], i);
+        }
+        
+        return "NO";
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/standard-bloom-filter.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/standard-bloom-filter.md"
new file mode 100644
index 0000000..e5df647
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/standard-bloom-filter.md"
@@ -0,0 +1,96 @@
+# 标准型布隆过滤器
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/standard-bloom-filter/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个标准型布隆过滤器, 支持一下方法:
+
+1. `StandardBloomFilter(k)` 构造方法, 你需要创建k个hash方法
+2. `add(string)` 往布隆过滤器中加入一个字符串.
+3. `contains(string)` 检查字符串是否在过滤器中
+ ### 样例说明
+ **样例1**
+
+```
+输入:
+    StandardBloomFilter(3)
+    add("lint")
+    add("code")
+    contains("lint")
+    contains("world")
+输出: [true]
+```
+
+**样例2**
+
+```
+输入:
+    StandardBloomFilter(10)
+    add("hello")
+    contains("hell")
+    contains("helloa")
+    contains("hello")
+    contains("hell")
+    contains("helloa")
+    contains("hello")
+输出: [false,false,true,false,false,true]
+```
+ ### 参考代码
+ 利用哈希表进行维护，维护某个值是否出现过
+当加入一个数时，在哈希表里记录下
+当删除一个数时，从哈希表里将这个数删掉即可
+```java
+import java.util.BitSet;
+
+class HashFunction {
+    public int cap, seed;
+
+    public HashFunction(int cap, int seed) {
+        this.cap = cap;
+        this.seed = seed;
+    }
+
+    public int hash(String value) {
+        int ret = 0;
+        int n = value.length();
+        for (int i = 0; i < n; ++i) {
+            ret += seed * ret + value.charAt(i);
+            ret %= cap;
+        }
+        return ret;
+    }
+}
+
+public class StandardBloomFilter {
+
+    public BitSet bits;
+    public int k;
+    public List<HashFunction> hashFunc;
+
+    public StandardBloomFilter(int k) {
+        // initialize your data structure here
+        this.k = k;
+        hashFunc = new ArrayList<HashFunction>();
+        for (int i = 0; i < k; ++i)
+            hashFunc.add(new HashFunction(100000 + i, 2 * i + 3));
+        bits = new BitSet(100000 + k);
+    }
+
+    public void add(String word) {
+        // Write your code here
+        for (int i = 0; i < k; ++i) {
+            int position = hashFunc.get(i).hash(word);
+            bits.set(position);
+        }
+    }
+
+    public boolean contains(String word) {
+        // Write your code here
+        for (int i = 0; i < k; ++i) {
+            int position = hashFunc.get(i).hash(word);
+            if (!bits.get(position))
+                return false;
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/strstr-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/strstr-ii.md"
new file mode 100644
index 0000000..cc27482
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/strstr-ii.md"
@@ -0,0 +1,97 @@
+# 字符串查找 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/strstr-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现时间复杂度为 O(n + m)的方法 `strStr`。
+`strStr` 返回目标字符串在源字符串中第一次出现的第一个字符的位置. 目标字串的长度为 *m* , 源字串的长度为 *n* . 如果目标字串不在源字串中则返回 -1。
+ ### 样例说明
+ **样例 1:**
+```
+输入：source = "abcdef"， target = "bcd"
+输出：1
+解释：
+字符串第一次出现的位置为1。
+```
+
+
+**样例 2:**
+```
+输入：source = "abcde"， target = "e"
+输出：4
+解释：
+字符串第一次出现的位置为4。
+```
+ ### 参考代码
+ 考点：
+* hash
+* kmp
+
+题解：
+* 采用字符串哈希，字符串哈希时需要将字符串映射为数字，hash_target = (hash_target * 33 + target.charAt(i) - 'a') % mod;此处哈希函数，提供了字符串转化数字的关系式。
+* 对于需要匹配的子串对应一个值，然后再遍历主串，当前位置为i，则用i的哈希值减去i-m部分的哈希值，求出中间m个长度的子串的哈希值，如果与要匹配串相同，由于哈希本身不安全，需要截取出来m长度的子串再进行匹配，完全相同即可。
+* 注意负数取模时，需要通过+mod，将负数变为正数。
+* kmp是线性的字符串匹配算法，同样可以实现。
+```java
+public class Solution {
+    /**
+     * @param source a source string
+     * @param target a target string
+     * @return an integer as index
+     */
+    public int strStr2(String source, String target) {
+        if(target == null) {
+            return -1;
+        }
+        int m = target.length();
+        if(m == 0 && source != null) {
+            return 0;
+        }
+        
+        if(source == null) {
+            return -1;
+        }
+        int n = source.length();
+        if(n == 0) {
+            return -1;
+        }
+
+        // mod could be any big integer
+        // just make sure mod * 33 wont exceed max value of int.
+        int mod = Integer.MAX_VALUE / 33;
+        int hash_target = 0;
+
+        // 33 could be something else like 26 or whatever you want
+        for (int i = 0; i < m; ++i) {
+            hash_target = (hash_target * 33 + target.charAt(i) - 'a') % mod;
+            if (hash_target < 0) {
+                hash_target += mod;
+            }
+        }
+
+        int m33 = 1;
+        for (int i = 0; i < m - 1; ++i) {
+            m33 = m33 * 33 % mod;
+        }
+
+        int value = 0;
+        for (int i = 0; i < n; ++i) {
+            if (i >= m) {
+                value = (value - m33 * (source.charAt(i - m) - 'a')) % mod;
+            }
+
+            value = (value * 33 + source.charAt(i) - 'a') % mod;
+            if (value < 0) {
+                value += mod;
+            }
+
+            if (i >= m - 1 && value == hash_target) {
+                // you have to double check by directly compare the string
+                if (target.equals(source.substring(i - m + 1, i + 1))) {
+                    return i - m + 1;
+                }
+            }
+        }
+        return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/subarray-sum-equals-k-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/subarray-sum-equals-k-ii.md"
new file mode 100644
index 0000000..9bc912d
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/subarray-sum-equals-k-ii.md"
@@ -0,0 +1,88 @@
+# 子数组和为K II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/subarray-sum-equals-k-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组和一个整数k，你需要找到和为k的最短子数组，并返回它的长度。
+
+如果没有这样的子数组，返回-1.
+ ### 样例说明
+ **Example1**
+
+```
+Input: nums = [1,1,1,2] and k = 3
+Output: 2
+```
+
+**Example2**
+
+```
+Input: nums = [2,1,-1,4,2,-3] and k = 3
+Output: 2
+```
+ ### 参考代码
+ 使用 前缀和+哈希表 的方法
+《九章算法面试高频题冲刺班》中有讲解
+
+```
+[[python]]
+class Solution:
+    """
+    @param nums: a list of integer
+    @param k: an integer
+    @return: return an integer, denote the minimum length of continuous subarrays whose sum equals to k
+    """
+    def subarraySumEqualsKII(self, nums, k):
+        prefix_sum = self.get_prefix_sum(nums)
+        
+        answer = float('inf')
+        sum2index = {0: 0}
+        for end in range(len(nums)):
+            # find prefix_sum[end + 1] - prefix_sum[start] = k
+            # => prefix_sum[start] = prefix_sum[end + 1] - k
+            if prefix_sum[end + 1] - k in sum2index:
+               length = end + 1 - sum2index[prefix_sum[end + 1] - k] 
+               answer = min(answer, length)
+            sum2index[prefix_sum[end + 1]] = end + 1
+            
+        return answer
+        
+    def get_prefix_sum(self, nums):
+        prefix_sum = [0]
+        for num in nums:
+            prefix_sum.append(prefix_sum[-1] + num)
+        return prefix_sum
+[[java]]
+public class Solution {
+    /**
+     * @param nums: a list of integer
+     * @param k: an integer
+     * @return: return an integer, denote the minimum length of continuous subarrays whose sum equals to k
+     */
+    public int subarraySumEqualsKII(int[] nums, int k) {
+        int[] prefixSum = getPrefixSum(nums);
+        
+        int answer = Integer.MAX_VALUE;
+        Map<Integer, Integer> sum2index = new HashMap<>();
+        sum2index.put(0, 0);
+        for (int end = 0; end < nums.length; end++) {
+            // find prefix_sum[end + 1] - prefix_sum[start] = k
+            // => prefix_sum[start] = prefix_sum[end + 1] - k
+            if (sum2index.containsKey(prefixSum[end + 1] - k)) {
+                int len = end + 1 - sum2index.get(prefixSum[end + 1] - k);
+                answer = Math.min(answer, len);
+            }
+            sum2index.put(prefixSum[end + 1], end + 1);
+        }
+        return answer;
+    }
+    
+    private int[] getPrefixSum(int[] nums) {
+        int[] prefixSum = new int[nums.length + 1];
+        prefixSum[0] = 0;
+        for (int i = 0; i < nums.length; i++) {
+            prefixSum[i + 1] = prefixSum[i] + nums[i];
+        }
+        return prefixSum;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/subarray-sum-equals-to-k-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/subarray-sum-equals-to-k-ii.md"
new file mode 100644
index 0000000..72015af
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/subarray-sum-equals-to-k-ii.md"
@@ -0,0 +1,76 @@
+# 子数组和为K II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/subarray-sum-equals-to-k-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组和一个整数k，你需要找到和为k的最短子数组，并返回它的长度。
+
+如果没有这样的子数组，返回-1.
+ ### 样例说明
+ 
+ ### 参考代码
+ 使用 前缀和+哈希表 的方法
+《九章算法面试高频题冲刺班》中有讲解
+
+```
+[[python]]
+class Solution:
+    """
+    @param nums: a list of integer
+    @param k: an integer
+    @return: return an integer, denote the minimum length of continuous subarrays whose sum equals to k
+    """
+    def subarraySumEqualsKII(self, nums, k):
+        prefix_sum = self.get_prefix_sum(nums)
+        
+        answer = float('inf')
+        sum2index = {0: 0}
+        for end in range(len(nums)):
+            # find prefix_sum[end + 1] - prefix_sum[start] = k
+            # => prefix_sum[start] = prefix_sum[end + 1] - k
+            if prefix_sum[end + 1] - k in sum2index:
+               length = end + 1 - sum2index[prefix_sum[end + 1] - k] 
+               answer = min(answer, length)
+            sum2index[prefix_sum[end + 1]] = end + 1
+            
+        return answer
+        
+    def get_prefix_sum(self, nums):
+        prefix_sum = [0]
+        for num in nums:
+            prefix_sum.append(prefix_sum[-1] + num)
+        return prefix_sum
+[[java]]
+public class Solution {
+    /**
+     * @param nums: a list of integer
+     * @param k: an integer
+     * @return: return an integer, denote the minimum length of continuous subarrays whose sum equals to k
+     */
+    public int subarraySumEqualsKII(int[] nums, int k) {
+        int[] prefixSum = getPrefixSum(nums);
+        
+        int answer = Integer.MAX_VALUE;
+        Map<Integer, Integer> sum2index = new HashMap<>();
+        sum2index.put(0, 0);
+        for (int end = 0; end < nums.length; end++) {
+            // find prefix_sum[end + 1] - prefix_sum[start] = k
+            // => prefix_sum[start] = prefix_sum[end + 1] - k
+            if (sum2index.containsKey(prefixSum[end + 1] - k)) {
+                int len = end + 1 - sum2index.get(prefixSum[end + 1] - k);
+                answer = Math.min(answer, len);
+            }
+            sum2index.put(prefixSum[end + 1], end + 1);
+        }
+        return answer;
+    }
+    
+    private int[] getPrefixSum(int[] nums) {
+        int[] prefixSum = new int[nums.length + 1];
+        prefixSum[0] = 0;
+        for (int i = 0; i < nums.length; i++) {
+            prefixSum[i + 1] = prefixSum[i] + nums[i];
+        }
+        return prefixSum;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/tiny-url-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/tiny-url-ii.md"
new file mode 100644
index 0000000..3069f15
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/tiny-url-ii.md"
@@ -0,0 +1,109 @@
+# 短网址 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/tiny-url-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个顾客短网址，使得顾客可以创立他们自己的短网址. 也就是说, 你需要在 [232. 短网址](https://www.lintcode.com/problem/tiny-url/description) 的基础上再实现一个 `createCustom`.
+
+你需要实现三个方法：
+ 
+* `longToShort(url)` 把一个长网址转换成一个以`http://tiny.url/`开头的短网址
+* `shortToLong(url)` 把一个短网址转换成一个长网址
+* `createCustom(url, key)` 设定一个长网址的短网址为 `http://tiny.url/` + `key`
+
+你可以任意设计算法，评测只关心：
+
+1. `longToShort` 生成的短网址的key的长度应该等于6 （不算域名和反斜杠）。 可以使用的字符只有 `[a-zA-Z0-9]`. 比如: `abcD9E`
+2. 任意两个长的url不会对应成同一个短url，反之亦然。
+3. 如果 `createCustom` 不能完成用户期望的设定, 那么应该返回 `"error"`, 反之如果成功将长网址与短网址对应, 应该返回这个短网址.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  createCustom("http://www.lintcode.com/", "lccode")
+  shortToLong("http://tiny.url/lccode")
+  createCustom("http://www.lintcode.com/", "ltcode")
+输出: 
+  "http://tiny.url/lccode"
+  "http://www.lintcode.com/"
+  "error"
+```
+
+**样例 2:**
+
+```
+输入: 
+  longToShort("http://www.lintcode.com/")
+  createCustom("http://www.lintcode.com/", "ltcode")
+输出: 
+  "http://tiny.url/abcdef"      => 该答案不唯一
+  "error"
+解释: 
+  虽然这几乎不可能发生: 
+  如果你的 longToShort() 恰好返回了 "http://tiny.url/ltcode",
+  那么你的 createCustom() 需要返回 "http://tiny.url/ltcode".
+```
+ ### 参考代码
+ 同 [短网址](https://www.lintcode.com/problem/tiny-url/description) 一样, 我们可以用两个哈希表处理长网址和短网址之间的相互映射关系.
+
+我们需要额外处理的便是用户设定的网址与已有的冲突时, 需要返回 "error". 
+
+但是注意这个细节: 如果用户设定的和已有的恰好相同, 那么同样应该返回短网址.
+```python
+class TinyUrl2:
+    def __init__(self):
+        self.l2s = {}
+        self.s2l = {}
+        self.cnt = 0
+        self.tinyUrl = 'http://tiny.url/'
+        self.charset = 'qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM'
+    
+    def newShortUrl(self):
+        res = ''
+        tmp = self.cnt
+        for i in range(6):
+            res += self.charset[tmp % 62]
+            tmp //= 62
+        self.cnt += 1
+        return self.tinyUrl + res
+        
+    """
+    @param: long_url: a long url
+    @param: key: a short key
+    @return: a short url starts with http://tiny.url/
+    """
+    def createCustom(self, long_url, key):
+        short_url = self.tinyUrl + key
+        if long_url in self.l2s:
+            if self.l2s[long_url] == short_url:
+                return short_url
+            else:
+                return 'error' 
+        if short_url in self.s2l:
+            return 'error'
+        self.l2s[long_url] = short_url
+        self.s2l[short_url] = long_url
+        return short_url
+
+    """
+    @param: long_url: a long url
+    @return: a short url starts with http://tiny.url/
+    """
+    def longToShort(self, long_url):
+        if long_url in self.l2s:
+            return self.l2s[long_url]
+        short_url = self.newShortUrl()
+        self.l2s[long_url] = short_url
+        self.s2l[short_url] = long_url
+        return short_url
+
+    """
+    @param: short_url: a short url starts with http://tiny.url/
+    @return: a long url
+    """
+    def shortToLong(self, short_url):
+        if short_url in self.s2l:
+            return self.s2l[short_url]
+        else:
+            return 'error'
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/tiny-url.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/tiny-url.md"
new file mode 100644
index 0000000..8c3af48
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/tiny-url.md"
@@ -0,0 +1,164 @@
+# 短网址
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/tiny-url/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个长网址，返回一个短网址。
+
+你需要实现两个方法：
+
+* `longToShort(url)` 把一个长网址转换成一个以`http://tiny.url/`开头的短网址
+* `shortToLong(url)` 把一个短网址转换成一个长网址
+
+你可以任意设计算法，评测只关心两件事：
+
+1. 短网址的key的长度应该等于6 （不算域名和反斜杠）。 可以使用的字符只有 `[a-zA-Z0-9]`. 比如: `abcD9E`
+2. 任意两个长的url不会对应成同一个短url，反之亦然。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: shortToLong(longToShort("http://www.lintcode.com/faq/?id=10"))
+输出: "http://www.lintcode.com/faq/?id=10"
+解释: 
+  longToShort()被调用时你可以返回任何短网址, 比如 "http://tiny.url/abcdef".
+  或者 "http://tiny.url/ABCDEF" 也时可以的.
+```
+
+**样例 2:**
+
+```
+输入: 
+  shortToLong(longToShort("http://www.lintcode.com/faq/?id=10"))
+  shortToLong(longToShort("http://www.lintcode.com/faq/?id=10"))
+输出: 
+  "http://www.lintcode.com/faq/?id=10"
+  "http://www.lintcode.com/faq/?id=10"
+```
+ ### 参考代码
+ 用两个哈希表, 一个是短网址映射到长网址, 一个是长网址映射到短网址.
+
+短网址是固定的格式: "http://tiny.url/" + 6个字符, 字符可以是任意的.
+
+为了避免重复, 我们可以按照字典序依次使用, 或者在随机生成的基础上用一个集合来记录是否使用过.
+```java
+// version 1: Random
+public class TinyUrl {
+    private Map<String, String> long2Short;
+    private Map<String, String> short2Long;
+
+    public TinyUrl() {
+        long2Short = new HashMap<String, String>();
+        short2Long = new HashMap<String, String>();
+    }
+
+    /**
+     * @param url a long url
+     * @return a short url starts with http://tiny.url/
+     */
+    public String longToShort(String url) {
+        if (long2Short.containsKey(url)) {
+            return long2Short.get(url);
+        }
+
+        while (true) {
+            String shortURL = generateShortURL();
+            if (!short2Long.containsKey(shortURL)) {
+                short2Long.put(shortURL, url);
+                long2Short.put(url, shortURL);
+                return shortURL;
+            }
+        }
+    }
+
+    /**
+     * @param url a short url starts with http://tiny.url/
+     * @return a long url
+     */
+    public String shortToLong(String url) {
+        if (!short2Long.containsKey(url)) {
+            return null;
+        }
+
+        return short2Long.get(url);
+    }
+
+    private String generateShortURL() {
+        String allowedChars = "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+        Random rand = new Random();
+        String shortURL = "http://tiny.url/";
+        for (int i = 0; i < 6; i++) {
+            int index = rand.nextInt(62);
+            shortURL += allowedChars.charAt(index);
+        }
+
+        return shortURL;
+    }
+}
+
+// version 2: base62
+public class TinyUrl {
+    public static int GLOBAL_ID = 0;
+    private HashMap<Integer, String> id2url = new HashMap<Integer, String>();
+    private HashMap<String, Integer> url2id = new HashMap<String, Integer>();
+
+    private String getShortKey(String url) {
+        return url.substring("http://tiny.url/".length());
+    }
+
+    private int toBase62(char c) {
+        if (c >= '0' && c <= '9') {
+            return c - '0';
+        }
+        if (c >= 'a' && c <= 'z') {
+            return c - 'a' + 10;
+        }
+        return c - 'A' + 36;
+    }
+
+    private int shortKeytoID(String short_key) {
+        int id = 0;
+        for (int i = 0; i < short_key.length(); ++i) {
+            id = id * 62 + toBase62(short_key.charAt(i));
+        }
+        return id;
+    }
+
+    private String idToShortKey(int id) {
+        String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+        String short_url = "";
+        while (id > 0) {
+            short_url = chars.charAt(id % 62) + short_url;
+            id = id / 62;
+        }
+        while (short_url.length() < 6) {
+            short_url = "0" + short_url;
+        }
+        return short_url;
+    }
+
+    /**
+     * @param url a long url
+     * @return a short url starts with http://tiny.url/
+     */
+    public String longToShort(String url) {
+        if (url2id.containsKey(url)) {
+            return "http://tiny.url/" + idToShortKey(url2id.get(url));
+        }
+        GLOBAL_ID++;
+        url2id.put(url, GLOBAL_ID);
+        id2url.put(GLOBAL_ID, url);
+        return "http://tiny.url/" + idToShortKey(GLOBAL_ID);
+    }
+
+    /**
+     * @param url a short url starts with http://tiny.url/
+     * @return a long url
+     */
+    public String shortToLong(String url) {
+        String short_key = getShortKey(url);
+        int id = shortKeytoID(short_key);
+        return id2url.get(id);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/top-k-frequent-words.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/top-k-frequent-words.md"
new file mode 100644
index 0000000..03712ca
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/top-k-frequent-words.md"
@@ -0,0 +1,111 @@
+# 最高频的K个单词
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/top-k-frequent-words/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个单词列表，求出这个列表中出现频次最高的K个单词。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  [
+    "yes", "lint", "code",
+    "yes", "code", "baby",
+    "you", "baby", "chrome",
+    "safari", "lint", "code",
+    "body", "lint", "code"
+  ]
+  k = 3
+输出: ["code", "lint", "baby"]
+```
+
+**样例 2:**
+
+```
+输入:
+  [
+    "yes", "lint", "code",
+    "yes", "code", "baby",
+    "you", "baby", "chrome",
+    "safari", "lint", "code",
+    "body", "lint", "code"
+  ]
+  k = 4
+输出: ["code", "lint", "baby", "yes"] 
+```
+ ### 参考代码
+ 欲记录单词出现的次数, 首选是哈希表. 大多高级语言内置相关的数据结构, 编码简单.
+
+使用哈希表记录每个单词出现的次数, 然后需要将单词按照 次数(主要关键词)和字典序(次要关键字) 排序, 取出前k个即可.
+
+排序的过程可以用 heap, 也可以使用快排等排序算法.
+```java
+class Pair {
+    String key;
+    int value;
+    
+    Pair(String key, int value) {
+        this.key = key;
+        this.value = value;
+    }
+}
+
+public class Solution {
+    /**
+     * @param words an array of string
+     * @param k an integer
+     * @return an array of string
+     */
+     
+    private Comparator<Pair> pairComparator = new Comparator<Pair>() {
+        public int compare(Pair left, Pair right) {
+            if (left.value != right.value) {
+                return left.value - right.value;
+            }
+            return right.key.compareTo(left.key);
+        }
+    };
+    
+    public String[] topKFrequentWords(String[] words, int k) {
+        if (k == 0) {
+            return new String[0];
+        }
+        
+        HashMap<String, Integer> counter = new HashMap<>();
+        for (String word : words) {
+            if (counter.containsKey(word)) {
+                counter.put(word, counter.get(word) + 1);
+            } else {
+                counter.put(word, 1);
+            }
+        }
+        
+        PriorityQueue<Pair> Q = new PriorityQueue<Pair>(k, pairComparator);
+        for (String word : counter.keySet()) {
+            Pair peak = Q.peek();
+            Pair newPair = new Pair(word, counter.get(word));
+            if (Q.size() < k) {
+                Q.add(newPair);
+            } else if (pairComparator.compare(newPair, peak) > 0) {
+                Q.poll();
+                Q.add(newPair);
+            }
+        }
+        
+        String[] result = new String[k];
+        int index = 0;
+        while (!Q.isEmpty()) {
+            result[index++] = Q.poll().key;
+        }
+        
+        // reverse
+        for (int i = 0; i < index / 2; i++) {
+            String temp = result[i];
+            result[i] = result[index - i - 1];
+            result[index - i - 1] = temp;
+        }
+        
+        return result;
+     }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/word-search-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/word-search-ii.md"
new file mode 100644
index 0000000..945c6f3
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/word-search-ii.md"
@@ -0,0 +1,97 @@
+# 单词搜索 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-search-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个由小写字母组成的矩阵和一个字典。找出所有同时在字典和矩阵中出现的单词。一个单词可以从矩阵中的任意位置开始，可以向左/右/上/下四个相邻方向移动。一个字母在一个单词中只能被使用一次。且字典中不存在重复单词</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：["doaf","agai","dcan"]，["dog","dad","dgdg","can","again"]
+输出：["again","can","dad","dog"]
+解释：
+  d o a f
+  a g a i
+  d c a n
+矩阵中查找，返回 ["again","can","dad","dog"]。
+```
+
+**样例 2:**
+```
+输入：["a"]，["b"]
+输出：[]
+解释：
+ a
+矩阵中查找，返回 []。
+```
+ ### 参考代码
+ 不用 Trie，直接使用哈希表的方法
+```python
+DIRECTIONS = [(0, -1), (0, 1), (-1, 0), (1, 0)]
+
+class Solution:
+    """
+    @param board: A list of lists of character
+    @param words: A list of string
+    @return: A list of string
+    """
+    def wordSearchII(self, board, words):
+        if board is None or len(board) == 0:
+            return []
+        
+        # pre-process
+        # 预处理
+        word_set = set(words)
+        prefix_set = set()
+        for word in words:
+            for i in range(len(word)):
+                prefix_set.add(word[:i + 1])
+        
+        result = set()
+        for i in range(len(board)):
+            for j in range(len(board[0])):
+                c = board[i][j]
+                self.search(
+                    board,
+                    i,
+                    j,
+                    board[i][j],
+                    word_set,
+                    prefix_set,
+                    set([(i, j)]),
+                    result,
+                )
+                
+        return list(result)
+        
+    def search(self, board, x, y, word, word_set, prefix_set, visited, result):
+        if word not in prefix_set:
+            return
+        
+        if word in word_set:
+            result.add(word)
+        
+        for delta_x, delta_y in DIRECTIONS:
+            x_ = x + delta_x
+            y_ = y + delta_y
+            
+            if not self.inside(board, x_, y_):
+                continue
+            if (x_, y_) in visited:
+                continue
+            
+            visited.add((x_, y_))
+            self.search(
+                board,
+                x_,
+                y_,
+                word + board[x_][y_],
+                word_set,
+                prefix_set,
+                visited,
+                result,
+            )
+            visited.remove((x_, y_))
+            
+    def inside(self, board, x, y):
+        return 0 <= x < len(board) and 0 <= y < len(board[0])
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/word-search.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/word-search.md"
new file mode 100644
index 0000000..077d894
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\223\210\345\270\214\350\241\250/word-search.md"
@@ -0,0 +1,69 @@
+# 单词搜索
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-search/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">给出一个二维的字母板和一个单词，寻找字母板网格中是否存在这个单词。</span><br></p><p>单词可以由按顺序的相邻单元的字母组成，其中相邻单元指的是水平或者垂直方向相邻。每个单元中的字母最多只能使用一次。</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：["ABCE","SFCS","ADEE"]，"ABCCED"
+输出：true
+解释：
+[    
+     A B C E
+     S F C S 
+     A D E E
+]
+(0,0)A->(0,1)B->(0,2)C->(1,2)C->(2,2)E->(2,1)D
+```
+
+**样例 2:**
+```
+输入：["z"]，"z"
+输出：true
+解释：
+[ z ]
+(0,0)z
+```
+ ### 参考代码
+ Given a 2D board and a word, find if the word exists in the grid.&nbsp;<div>The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.&nbsp;</div><div><br></div><div>For example,&nbsp;</div><div>Given board =&nbsp;</div><div><br></div><div>[&nbsp;</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;["ABCE"],&nbsp;</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;["SFCS"],&nbsp;</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;["ADEE"]&nbsp;</div><div>]&nbsp;</div><div>word = "ABCCED", -&gt; returns true,&nbsp;</div><div>word = "SEE", -&gt; returns true,&nbsp;</div><div>word = "ABCB", -&gt; returns false.</div><div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博：</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/BsAol7c9Q" target="_blank">http://weibo.com/3948019741/BsAol7c9Q</a></span></font><br></div>
+```python
+class Solution:
+    # @param board, a list of lists of 1 length string
+    # @param word, a string
+    # @return a boolean
+    def exist(self, board, word):
+        # write your code here
+        # Boundary Condition
+        if word == []:
+            return True
+        m = len(board)
+        if m == 0:
+            return False
+        n = len(board[0])
+        if n == 0:
+            return False
+        # Visited Matrix
+        visited = [[False for j in range(n)] for i in range(m)]
+        # DFS
+        for i in range(m):
+            for j in range(n):
+                if self.exist2(board, word, visited, i, j):
+                    return True
+        return False
+
+    def exist2(self, board, word, visited, row, col):
+        if word == '':
+            return True
+        m, n = len(board), len(board[0])
+        if row < 0 or row >= m or col < 0 or col >= n:
+            return False
+        if board[row][col] == word[0] and not visited[row][col]:
+            visited[row][col] = True
+            # row - 1, col
+            if self.exist2(board, word[1:], visited, row - 1, col) or self.exist2(board, word[1:], visited, row, col - 1) or self.exist2(board, word[1:], visited, row + 1, col) or self.exist2(board, word[1:], visited, row, col + 1):
+                return True
+            else:
+                visited[row][col] = False
+        return False
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/heapify.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/heapify.md"
new file mode 100644
index 0000000..7ba7e64
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/heapify.md"
@@ -0,0 +1,46 @@
+# 堆化
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/heapify/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个整数数组，堆化操作就是把它变成一个最小堆数组。
+
+对于堆数组A，A[0]是堆的根，并对于每个A[i]，A [i * 2 + 1]是A[i]的左儿子并且A[i * 2 + 2]是A[i]的右儿子。
+
+ ### 样例说明
+ ***样例 1***
+```
+输入 : [3,2,1,4,5]
+输出 : [1,2,3,4,5]
+解释 : 返回任何一个合法的堆数组
+```
+ ### 参考代码
+ Heapify 的具体实现方法。时间复杂度为 $O(n)$，使用的是 siftdown
+之所以是 O(n) 是因为从第 N/2 个位置开始往下 siftdown，那么就有大约 N/4 个数在 siftdown 中最多交换 1 次，N/8 个数最多交换 2 次，N/16 个数最多交换 3 次。
+所以 $O(N/4 * 1 + N/8 * 2 + N/16 * 3 + ... + 1 * LogN) = O(N)$
+```python
+class Solution:
+    """
+    @param: A: Given an integer array
+    @return: nothing
+    """
+    def heapify(self, A):
+        for i in range(len(A) // 2, -1, -1):
+            self.siftdown(A, i)
+            
+    def siftdown(self, A, index):
+        n = len(A)
+        while index < n:
+            left = index * 2 + 1
+            right = index * 2 + 2
+            minIndex = index
+            if left < n and A[left] < A[minIndex]:
+                minIndex = left
+            if right < n and A[right] < A[minIndex]:
+                minIndex = right
+
+            if minIndex == index:
+                break
+            
+            A[minIndex], A[index] = A[index], A[minIndex]
+            index = minIndex
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/high-five.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/high-five.md"
new file mode 100644
index 0000000..0f96b56
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/high-five.md"
@@ -0,0 +1,76 @@
+# 优秀成绩
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/high-five/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 每个学生有两个属性 `id` 和 `scores`。找到每个学生最高的5个分数的平均值。
+ ### 样例说明
+ 例1:
+```
+输入: 
+[[1,91],[1,92],[2,93],[2,99],[2,98],[2,97],[1,60],[1,58],[2,100],[1,61]]
+输出:
+1: 72.40
+2: 97.40
+
+```
+
+例2:
+```
+输入:
+[[1,90],[1,90],[1,90],[1,90],[1,90],[1,90]]
+输出: 
+1: 90.00
+```
+
+
+ ### 参考代码
+ 利用map与优先队列即可，找到对应的人的成绩，pop出前5个即可。
+```java
+/**
+ * Definition for a Record
+ * class Record {
+ *     public int id, score;
+ *     public Record(int id, int score){
+ *         this.id = id;
+ *         this.score = score;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param results a list of <student_id, score>
+     * @return find the average of 5 highest scores for each person
+     * Map<Integer, Double> (student_id, average_score)
+     */
+    public Map<Integer, Double> highFive(Record[] results) {
+        Map<Integer, Double> answer = new HashMap<Integer, Double>();
+        Map<Integer, PriorityQueue<Integer>> hash = new HashMap<Integer, PriorityQueue<Integer>>();
+
+        for (Record r : results) {
+            if (!hash.containsKey(r.id)){
+                hash.put(r.id, new PriorityQueue<Integer>());
+            }
+            PriorityQueue<Integer> pq=hash.get(r.id);
+            if (pq.size() < 5) {
+                pq.add(r.score);
+            } else {
+                if (pq.peek() < r.score){
+                    pq.poll();
+                    pq.add(r.score);
+                }
+            }
+        }
+
+        for (Map.Entry<Integer, PriorityQueue<Integer>> entry : hash.entrySet()) {
+            int id = entry.getKey();
+            PriorityQueue<Integer> scores = entry.getValue();
+            double average = 0;
+            for (int i = 0; i < 5; ++i)
+                average += scores.poll();
+            average /= 5.0;
+            answer.put(id, average);
+        }
+        return answer;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/k-closest-points.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/k-closest-points.md"
new file mode 100644
index 0000000..a1e4bcf
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/k-closest-points.md"
@@ -0,0 +1,73 @@
+# K个最近的点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/k-closest-points/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一些 `points` 和一个 `origin`，从 `points` 中找到 `k` 个离 `origin` 最近的点。按照距离由小到大返回。如果两个点有相同距离，则按照x值来排序；若x值也相同，就再按照y值排序。
+ ### 样例说明
+ 例1:
+```
+输入: points = [[4,6],[4,7],[4,4],[2,5],[1,1]], origin = [0, 0], k = 3 
+输出: [[1,1],[2,5],[4,4]]
+```
+
+例2:
+```
+输入: points = [[0,0],[0,9]], origin = [3, 1], k = 1
+输出: [[0,0]]
+```
+
+ ### 参考代码
+ 基于 PriorityQueue 的方法
+PriorityQueue 里从远到近排序。当 PQ 里超过 k 个的时候，就 pop 掉一个。
+时间复杂度 $O(nlogk)$
+```java
+/**
+ * Definition for a point.
+ * class Point {
+ *     int x;
+ *     int y;
+ *     Point() { x = 0; y = 0; }
+ *     Point(int a, int b) { x = a; y = b; }
+ * }
+ */
+public class Solution {
+    /**
+     * @param points a list of points
+     * @param origin a point
+     * @param k an integer
+     * @return the k closest points
+     */
+    private Point global_origin = null;
+    public Point[] kClosest(Point[] points, Point origin, int k) {
+        // Write your code here
+        global_origin = origin;
+        PriorityQueue<Point> pq = new PriorityQueue<Point> (k, new Comparator<Point> () {
+            @Override
+            public int compare(Point a, Point b) {
+                int diff = getDistance(b, global_origin) - getDistance(a, global_origin);
+                if (diff == 0)
+                    diff = b.x - a.x;
+                if (diff == 0)
+                    diff = b.y - a.y;
+                return diff;
+            }
+        });
+
+        for (int i = 0; i < points.length; i++) {
+            pq.offer(points[i]);
+            if (pq.size() > k)
+                pq.poll();
+        }
+        
+        k = pq.size();
+        Point[] ret = new Point[k];  
+        while (!pq.isEmpty())
+            ret[--k] = pq.poll();
+        return ret;
+    }
+    
+    private int getDistance(Point a, Point b) {
+        return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-largest-element-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-largest-element-ii.md"
new file mode 100644
index 0000000..0740e00
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-largest-element-ii.md"
@@ -0,0 +1,41 @@
+# 第K大的元素 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-largest-element-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 找到数组中第K大的元素，N远大于K。请注意你需要找的是数组排序后的第 k 个最大的元素，而不是第 k 个不同的元素
+ ### 样例说明
+ **例1:**
+```
+输入:[9,3,2,4,8],3
+输出:4
+
+```
+**例2:**
+```
+输入:[1,2,3,4,5,6,8,9,10,7],10
+输出:1
+
+```
+
+ ### 参考代码
+ 利用优先队列求第k大元素
+```java
+class Solution {
+    /**
+     * @param nums an integer unsorted array
+     * @param k an integer from 1 to n
+     * @return the kth largest element
+     */
+    public int kthLargestElement2(int[] nums, int k) {
+        // Write your code here
+        PriorityQueue<Integer> q = new PriorityQueue<Integer>(k);
+        for (int num : nums) {
+            q.offer(num);
+            if (q.size() > k) {
+                q.poll();
+            }
+        }
+        return q.peek();
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-largest-element.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-largest-element.md"
new file mode 100644
index 0000000..adebf60
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-largest-element.md"
@@ -0,0 +1,75 @@
+# 第k大元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-largest-element/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在数组中找到第 k 大的元素。
+
+ ### 样例说明
+ **样例 1：**
+```
+输入：
+n = 1, nums = [1,3,4,2]
+输出：
+4
+```
+**样例 2：**
+```
+输入：
+n = 3, nums = [9,3,2,4,8]
+输出：
+4
+```
+ ### 参考代码
+ 九章算法强化班里讲过的标准 Parition 模板。
+```java
+class Solution {
+    /*
+     * @param k : description of k
+     * @param nums : array of nums
+     * @return: description of return
+     */
+    public int kthLargestElement(int k, int[] nums) {
+        if (nums == null || nums.length == 0 || k < 1 || k > nums.length){
+            return -1;
+        }
+        return partition(nums, 0, nums.length - 1, nums.length - k);
+    }
+    
+    private int partition(int[] nums, int start, int end, int k) {
+        if (start >= end) {
+            return nums[k];
+        }
+        
+        int left = start, right = end;
+        int pivot = nums[(start + end) / 2];
+        
+        while (left <= right) {
+            while (left <= right && nums[left] < pivot) {
+                left++;
+            }
+            while (left <= right && nums[right] > pivot) {
+                right--;
+            }
+            if (left <= right) {
+                swap(nums, left, right);
+                left++;
+                right--;
+            }
+        }
+        
+        if (k <= right) {
+            return partition(nums, start, right, k);
+        }
+        if (k >= left) {
+            return partition(nums, left, end, k);
+        }
+        return nums[k];
+    }    
+    
+    private void swap(int[] nums, int i, int j) {
+        int tmp = nums[i];
+        nums[i] = nums[j];
+        nums[j] = tmp;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-largest-in-n-arrays.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-largest-in-n-arrays.md"
new file mode 100644
index 0000000..4cb7ca3
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-largest-in-n-arrays.md"
@@ -0,0 +1,95 @@
+# N数组第K大元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-largest-in-n-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在N个数组中找到第K大元素
+ ### 样例说明
+ 例1:
+```
+输入:
+k = 3, [[9,3,2,4,7],[1,2,3,4,8]]
+输出:
+7
+解释:
+第三大的元素为 7。
+
+```
+例2:
+```
+输入:
+k = 2, [[9,3,2,4,8],[1,2,3,4,2]]
+输出:
+8
+解释:
+最大的元素为 9，第二大的元素为 8，第三大的元素为 4 等等。
+
+```
+
+ ### 参考代码
+ 对每个数组排序，然后将每个数组的最小元素加入到优先队列中，每次从优先队列中pop出一个元素，然后push进同组的下一个元素，直到第k个
+```java
+import java.util.Comparator;  
+import java.util.PriorityQueue;  
+import java.util.Queue; 
+
+class Node {
+    public int value, from_id, index;
+    public Node(int _v, int _id, int _i) {
+        this.value = _v;
+        this.from_id = _id;
+        this.index = _i;
+    }
+}
+
+public class Solution {
+    /**
+     * @param arrays a list of array
+     * @param k an integer
+     * @return an integer, K-th largest element in N arrays
+     */
+    public int KthInArrays(int[][] arrays, int k) {
+        // Write your code here
+        Queue<Node> queue =  new PriorityQueue<Node>(k, new Comparator<Node>() {  
+                public int compare(Node o1, Node o2) {  
+                    if (o1.value > o2.value)
+                        return -1;
+                    else if (o1.value < o2.value)
+                        return 1;
+                    else
+                        return 0;
+                }
+            }); 
+
+        int n = arrays.length;
+        int i;
+        for (i = 0; i < n; ++i) {
+            Arrays.sort(arrays[i]);
+            
+            if (arrays[i].length > 0) {
+                int from_id = i;
+                int index = arrays[i].length - 1;
+                int value = arrays[i][index];
+                queue.add(new Node(value, from_id, index));
+            }
+        }
+
+        for (i  = 0; i < k; ++i) {
+            Node temp = queue.poll();
+            int from_id = temp.from_id;
+            int index = temp.index;
+            int value = temp.value;
+            
+            if (i == k - 1)
+                return value;
+            
+            if (index > 0) {
+                index --;
+                value = arrays[from_id][index];
+                queue.add(new Node(value, from_id, index));
+            }
+        }
+
+        return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-smallest-number-in-sorted-matrix.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-smallest-number-in-sorted-matrix.md"
new file mode 100644
index 0000000..648cc29
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/kth-smallest-number-in-sorted-matrix.md"
@@ -0,0 +1,67 @@
+# 排序矩阵中的从小到大第k个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-smallest-number-in-sorted-matrix/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个排序矩阵中找从小到大的第 *k* 个整数。
+
+排序矩阵的定义为：每一行递增，每一列也递增。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+[
+  [1 ,5 ,7],
+  [3 ,7 ,8],
+  [4 ,8 ,9],
+]
+k = 4
+输出: 5
+```
+
+**样例 2:**
+
+```
+输入: 
+[
+  [1, 2],
+  [3, 4]
+]
+k = 3
+输出: 3
+```
+ ### 参考代码
+ 使用 heapq
+注意 visited 不能开成一个二维数组，因为那样会增加时间复杂度。比如 K=1 的时候，理应 O(1) 的时间返回。开一个二维数组的耗费显然不只是 O(1) 的
+```python
+import heapq
+
+class Solution:
+    """
+    @param matrix: a matrix of integers
+    @param k: An integer
+    @return: the kth smallest number in the matrix
+    """
+    def kthSmallest(self, matrix, k):
+        n = len(matrix)
+        if n == 0:
+            return None
+        
+        m = len(matrix[0])
+        if m == 0:
+            return None
+            
+        minheap = [(matrix[0][0], 0, 0)]
+        visited = set([0])
+        num = None
+        for _ in range(k):
+            num, x, y = heapq.heappop(minheap)
+            if x + 1 < n and (x + 1) * m + y not in visited:
+                heapq.heappush(minheap, (matrix[x + 1][y], x + 1, y))
+                visited.add((x + 1) * m + y)
+            if y + 1 < m and x * m + y + 1 not in visited:
+                heapq.heappush(minheap, (matrix[x][y + 1], x, y + 1))
+                visited.add(x * m + y + 1)
+
+        return num
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/largest-number.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/largest-number.md"
new file mode 100644
index 0000000..b0fc90a
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/largest-number.md"
@@ -0,0 +1,50 @@
+# 最大数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/largest-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一组非负整数，重新排列他们的顺序把他们组成一个最大的整数。
+ ### 样例说明
+ **样例 1:**
+```
+输入:[1, 20, 23, 4, 8]
+输出:"8423201"
+```
+**样例 2:**
+```
+输入:[4, 6, 65]
+输出:"6654"
+```
+
+ ### 参考代码
+ ```java
+class NumbersComparator implements Comparator<String> {
+	@Override
+	public int compare(String s1, String s2) {
+		return (s2 + s1).compareTo(s1 + s2);
+	}
+}
+
+public class Solution {
+    
+    public String largestNumber(int[] nums) {
+        String[] strs = new String[nums.length];
+        for (int i = 0; i < nums.length; i++) {
+            strs[i] = Integer.toString(nums[i]);
+        }
+        Arrays.sort(strs, new NumbersComparator());
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < strs.length; i++) {
+            sb.append(strs[i]);
+        }
+        String result = sb.toString();
+        int index = 0;
+        while (index < result.length() && result.charAt(index) == '0') {
+            index++;
+        }
+        if (index == result.length()) {
+            return "0";
+        }
+        return result.substring(index);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/merge-k-sorted-arrays.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/merge-k-sorted-arrays.md"
new file mode 100644
index 0000000..72a65ba
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/merge-k-sorted-arrays.md"
@@ -0,0 +1,58 @@
+# 合并k个排序数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-k-sorted-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将 *k* 个有序数组合并为一个大的有序数组。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  [
+    [1, 3, 5, 7],
+    [2, 4, 6],
+    [0, 8, 9, 10, 11]
+  ]
+输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
+```
+
+**样例 2:**
+
+```
+输入: 
+  [
+    [1,2,3],
+    [1,2]
+  ]
+输出: [1,1,2,2,3]
+```
+ ### 参考代码
+ 使用 Heapq 的方法
+最快，因为不需要创建额外空间。
+时间复杂度和其他的算法一致，都是 $O(NlogK)$ N 是所有元素个数
+```python
+import heapq
+
+
+class Solution:
+    """
+    @param arrays: k sorted integer arrays
+    @return: a sorted array
+    """
+    def mergekSortedArrays(self, arrays):
+        result = []
+        heap = []
+        for index, array in enumerate(arrays):
+            if len(array) == 0:
+                continue
+            heapq.heappush(heap, (array[0], index, 0))
+             
+        while len(heap):
+            val, x, y = heap[0]
+            heapq.heappop(heap)
+            result.append(val)
+            if y + 1 < len(arrays[x]):
+                heapq.heappush(heap, (arrays[x][y + 1], x, y + 1))
+            
+        return result
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/merge-k-sorted-interval-lists.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/merge-k-sorted-interval-lists.md"
new file mode 100644
index 0000000..0485ff9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/merge-k-sorted-interval-lists.md"
@@ -0,0 +1,99 @@
+# 合并K个排序间隔列表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-k-sorted-interval-lists/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将K个排序的间隔列表合并到一个排序的间隔列表中，你需要合并重叠的间隔。
+ ### 样例说明
+ **样例1**
+
+```
+输入: [
+  [(1,3),(4,7),(6,8)],
+  [(1,2),(9,10)]
+]
+输出: [(1,3),(4,8),(9,10)]
+```
+
+**样例2**
+
+```
+输入: [
+  [(1,2),(5,6)],
+  [(3,4),(7,8)]
+]
+输出: [(1,2),(3,4),(5,6),(7,8)]
+```
+ ### 参考代码
+ 使用 PriorityQueue 的版本
+假设总共有 N 个整数，一共 K 个数组
+时间复杂度 $O(NlogK)$
+空间复杂度 $O(K)$
+```java
+class Pair {
+    int row, col;
+    public Pair(int row, int col) {
+        this.row = row;
+        this.col = col;
+    }
+}
+
+public class Solution {
+    /**
+     * @param intervals: the given k sorted interval lists
+     * @return:  the new sorted interval list
+     */
+    public List<Interval> mergeKSortedIntervalLists(List<List<Interval>> intervals) {
+        int k = intervals.size();
+        PriorityQueue<Pair> queue = new PriorityQueue<>(
+          k,
+          new Comparator<Pair>() {
+            public int compare(Pair e1, Pair e2) {
+                return intervals.get(e1.row).get(e1.col).start - 
+                  intervals.get(e2.row).get(e2.col).start;
+            }
+          }
+        );
+        
+        for (int i = 0; i < intervals.size(); i ++) {
+            if (intervals.get(i).size() > 0) {
+                queue.add(new Pair(i, 0));
+            }
+        }
+        
+        List<Interval> result = new ArrayList<>();
+        while (!queue.isEmpty()) {
+            Pair pair = queue.poll();
+            result.add(intervals.get(pair.row).get(pair.col));
+            pair.col++;
+            if (pair.col < intervals.get(pair.row).size()) {
+                queue.add(pair);
+            }
+        }
+        
+        return merge(result);
+    }
+    
+    private List<Interval> merge(List<Interval> intervals) {
+        if (intervals.size() <= 1) {
+            return intervals;
+        }
+        
+        List<Interval> result = new ArrayList<>();
+        int start = intervals.get(0).start;
+        int end = intervals.get(0).end;
+        for (Interval interval : intervals) {
+            if (interval.start <= end) {
+                end = Math.max(end, interval.end);
+            } else {
+                result.add(new Interval(start, end));
+                start = interval.start;
+                end = interval.end;
+            }
+        }
+        // kickoff the last interval
+        result.add(new Interval(start, end));
+        
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/merge-k-sorted-lists.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/merge-k-sorted-lists.md"
new file mode 100644
index 0000000..2145767
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/merge-k-sorted-lists.md"
@@ -0,0 +1,177 @@
+# 合并k个排序链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-k-sorted-lists/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>合并k个排序链表，并且返回合并后的排序链表。尝试分析和描述其复杂度。<br></p>
+ ### 样例说明
+ ```
+样例 1:
+	输入:   [2->4->null,null,-1->null]
+	输出:  -1->2->4->null
+
+样例 2:
+	输入: [2->6->null,5->null,7->null]
+	输出:  2->5->6->7->null
+	
+```
+ ### 参考代码
+ Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
+
+有序数组合并，使用两个指针向后移动，每次比较，小的一个数字取出来，并将指针后移一位。
+
+K个有序链表可以每次合并一个链表进结果链表中。合并k次
+```java
+// version 1: Divide & Conquer
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+public class Solution {
+    /**
+     * @param lists: a list of ListNode
+     * @return: The head of one sorted list.
+     */
+    public ListNode mergeKLists(List<ListNode> lists) {
+        if (lists.size() == 0) {
+            return null;
+        }
+        return mergeHelper(lists, 0, lists.size() - 1);
+    }
+    
+    private ListNode mergeHelper(List<ListNode> lists, int start, int end) {
+        if (start == end) {
+            return lists.get(start);
+        }
+        
+        int mid = start + (end - start) / 2;
+        ListNode left = mergeHelper(lists, start, mid);
+        ListNode right = mergeHelper(lists, mid + 1, end);
+        return mergeTwoLists(left, right);
+    }
+    
+    private ListNode mergeTwoLists(ListNode list1, ListNode list2) {
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (list1 != null && list2 != null) {
+            if (list1.val < list2.val) {
+                tail.next = list1;
+                tail = list1;
+                list1 = list1.next;
+            } else {
+                tail.next = list2;
+                tail = list2;
+                list2 = list2.next;
+            }
+        }
+        if (list1 != null) {
+            tail.next = list1;
+        } else {
+            tail.next = list2;
+        }
+        
+        return dummy.next;
+    }
+}
+
+// version 2: Heap
+public class Solution {
+    private Comparator<ListNode> ListNodeComparator = new Comparator<ListNode>() {
+        public int compare(ListNode left, ListNode right) {
+            return left.val - right.val;
+        }
+    };
+    
+    public ListNode mergeKLists(List<ListNode> lists) {
+        if (lists == null || lists.size() == 0) {
+            return null;
+        }
+        
+        Queue<ListNode> heap = new PriorityQueue<ListNode>(lists.size(), ListNodeComparator);
+        for (int i = 0; i < lists.size(); i++) {
+            if (lists.get(i) != null) {
+                heap.add(lists.get(i));
+            }
+        }
+        
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (!heap.isEmpty()) {
+            ListNode head = heap.poll();
+            tail.next = head;
+            tail = head;
+            if (head.next != null) {
+                heap.add(head.next);
+            }
+        }
+        return dummy.next;
+    }
+}
+
+// Version 3: merge two by two
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+public class Solution {
+    /**
+     * @param lists: a list of ListNode
+     * @return: The head of one sorted list.
+     */
+    public ListNode mergeKLists(List<ListNode> lists) {  
+        if (lists == null || lists.size() == 0) {
+            return null;
+        }
+        
+        while (lists.size() > 1) {
+            List<ListNode> new_lists = new ArrayList<ListNode>();
+            for (int i = 0; i + 1 < lists.size(); i += 2) {
+                ListNode merged_list = merge(lists.get(i), lists.get(i+1));
+                new_lists.add(merged_list);
+            }
+            if (lists.size() % 2 == 1) {
+                new_lists.add(lists.get(lists.size() - 1));
+            }
+            lists = new_lists;
+        }
+        
+        return lists.get(0);
+    }
+    
+    private ListNode merge(ListNode a, ListNode b) {
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (a != null && b != null) {
+            if (a.val < b.val) {
+                tail.next = a;
+                a = a.next;
+            } else {
+                tail.next = b;
+                b = b.next;
+            }
+            tail = tail.next;
+        }
+        
+        if (a != null) {
+            tail.next = a;
+        } else {
+            tail.next = b;
+        }
+        
+        return dummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/shortest-subarray-with-sum-at-least-k.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/shortest-subarray-with-sum-at-least-k.md"
new file mode 100644
index 0000000..85c939c
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/shortest-subarray-with-sum-at-least-k.md"
@@ -0,0 +1,192 @@
+# 和至少为 K 的最短子数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/shortest-subarray-with-sum-at-least-k/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 返回 `A` 的最短的非空连续子数组的**长度**，该子数组的和至少为 `K` 。
+
+如果没有和至少为 `K` 的非空子数组，返回 `-1` 。
+ ### 样例说明
+ **样例 1:**
+```
+输入：A = [1], K = 1
+输出：1
+```
+**样例 2:**
+```
+输入：A = [1,2], K = 4
+输出：-1
+```
+ ### 参考代码
+ 使用堆的方法。堆支持删除的时候用 lazy_deletion 的方法。
+解题详情详见《九章算法面试高频题班》中的讲解
+
+```
+[[python]]
+from heapq import heappush, heappop
+
+
+class Heap:
+    
+    def __init__(self):
+        self.minheap = []
+        self.deleted_set = set()
+    
+    def push(self, index, val):
+        heappush(self.minheap, (val, index))
+    
+    def _lazy_deletion(self):
+        while self.minheap and self.minheap[0][1] in self.deleted_set:
+            heappop(self.minheap)
+    
+    def top(self):
+        self._lazy_deletion()
+        return self.minheap[0]
+    
+    def pop(self):
+        self._lazy_deletion()
+        heappop(self.minheap)
+        
+    def delete(self, index):
+        self.deleted_set.add(index)
+        
+    def is_empty(self):
+        return not bool(self.minheap)
+        
+
+class Solution:
+    """
+    @param A: the array
+    @param K: sum
+    @return: the length
+    """
+    def shortestSubarray(self, A, K):
+        prefix_sum = self.get_prefix_sum(A)
+        
+        # do binary search to find the minimum length that
+        # we could find a subarray within that length and sum >= K
+        start, end = 1, len(A)
+        while start + 1 < end:
+            mid = (start + end) // 2
+            if self.is_valid(prefix_sum, K, mid):
+                end = mid
+            else:
+                start = mid
+        if self.is_valid(prefix_sum, K, start):
+            return start
+        if self.is_valid(prefix_sum, K, end):
+            return end
+        return -1
+    
+    def is_valid(self, prefix_sum, K, length):
+        minheap = Heap()
+        for end in range(len(prefix_sum)):
+            index = end - length - 1
+            minheap.delete(index)
+            # find the maximum subarray
+            if not minheap.is_empty() and prefix_sum[end] - minheap.top()[0] >= K:
+                return True
+            minheap.push(end, prefix_sum[end])
+        return False
+        
+    def get_prefix_sum(self, A):
+        prefix_sum = [0]
+        for num in A:
+            prefix_sum.append(prefix_sum[-1] + num)
+        return prefix_sum
+[[java]]
+class ValueIndexPair {
+    int val, index;
+    public ValueIndexPair(int val, int index) {
+        this.val = val;
+        this.index = index;
+    } 
+}
+
+class Heap {
+    private Queue<ValueIndexPair> minheap;
+    private Set<Integer> deleteSet;
+    public Heap() {
+        minheap = new PriorityQueue<>((p1, p2) -> (p1.val - p2.val));
+        deleteSet = new HashSet<>();
+    }
+    
+    public void push(int index, int val) {
+        minheap.add(new ValueIndexPair(val, index));
+    }
+    
+    private void lazyDeletion() {
+        while (minheap.size() != 0 && deleteSet.contains(minheap.peek().index)) {
+            ValueIndexPair pair = minheap.poll();
+            deleteSet.remove(pair.index);
+        }
+    }
+    
+    public ValueIndexPair top() {
+        lazyDeletion();
+        return minheap.peek();
+    }
+    
+    public void pop() {
+        lazyDeletion();
+        minheap.poll();
+    }
+    
+    public void delete(int index) {
+        deleteSet.add(index);
+    }
+    
+    public boolean isEmpty() {
+        return minheap.size() == 0;
+    }
+}
+
+public class Solution {
+    /**
+     * @param A: the array
+     * @param K: sum
+     * @return: the length
+     */
+    public int shortestSubarray(int[] A, int K) {
+        int[] prefixSum = getPrefixSum(A);
+        
+        int start = 1, end = A.length;
+        while (start + 1 < end) {
+            int mid = (start + end) / 2;
+            if (isValid(prefixSum, K, mid)) {
+                end = mid;
+            } else {
+                start = mid;
+            }
+        }
+        if (isValid(prefixSum, K, start)) {
+            return start;
+        }
+        if (isValid(prefixSum, K, end)) {
+            return end;
+        }
+        return -1;
+    }
+    
+    private boolean isValid(int[] prefixSum, int K, int length) {
+        Heap minheap = new Heap();
+        for (int end = 0; end < prefixSum.length; end++) {
+            int index = end - length - 1;
+            minheap.delete(index);
+            if (!minheap.isEmpty() && prefixSum[end] - minheap.top().val >= K) {
+                return true;
+            }
+            minheap.push(end, prefixSum[end]);
+        }
+        return false;
+    }
+    
+    private int[] getPrefixSum(int[] A) {
+        int[] prefixSum = new int[A.length + 1];
+        prefixSum[0] = 0;
+        for (int i = 0; i < A.length; i++) {
+            prefixSum[i + 1] = prefixSum[i] + A[i];
+        }
+        return prefixSum;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/super-ugly-number.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/super-ugly-number.md"
new file mode 100644
index 0000000..f2b8d3a
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/super-ugly-number.md"
@@ -0,0 +1,74 @@
+# 超级丑数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/super-ugly-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 写一个程序来找第 *n* 个超级丑数。
+
+超级丑数是所有的质数因子都在给定的的质数集合内的正整数。
+
+比如给定质数集合 `[2, 7, 13, 19]`, 那么 `[1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32]` 是前 12 个超级丑数。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: n = 6, [2,7,13,19]
+输出: 13
+```
+
+**样例 2:**
+
+```
+输入: n = 11, [2,3,5]
+输出: 15
+```
+ ### 参考代码
+ **做法1**:
+
+使用小根堆, 初始将1放入堆, 循环 n-1 次, 每次取出堆顶, 然后将该值与素数列表每个数的乘积再次放入堆.
+
+注意可能会有数重复入堆, 所以还需要额外的数据结构记录一个数是否出现过, 把重复的数排除, 以保证取出的堆顶是从小到大的超级丑数.
+
+n-1 次循环之后, 此时的堆顶即是第 n 个丑数.
+
+时间复杂度 O(nklogn)
+
+**做法2**:
+
+依次求出前n个超级丑数. 定义times[i]表示当前的超级丑数的质因数中, 列表中第i个素数的次数. uglys[i]表示第i+1个素数.
+
+初始 times[i] = 0, uglys[0] = 1, 然后依次由 uglys[0] ~ uglys[i] 求出 uglys[i+1]:
+
+1. 枚举, 求出 uglys[times[j]] * prime[j] 的最小值, 即是 uglys[i+1]
+2. 更新对应的 times[j], 即 若 uglys[times[j]] * prime[j] == uglys[i+1], times[j]++
+
+时间复杂度 O(nk)
+
+可参考 <https://blog.csdn.net/happyaaaaaaaaaaa/article/details/50850473>
+```java
+public class Solution {
+    /**
+     * @param n a positive integer
+     * @param primes the given prime list
+     * @return the nth super ugly number
+     */
+    public int nthSuperUglyNumber(int n, int[] primes) {
+        int[] times = new int[primes.length];
+        int[] uglys = new int[n];
+        uglys[0] = 1;
+
+        for (int i = 1; i < n; i++) {
+            uglys[i] = Integer.MAX_VALUE;
+            for (int j = 0; j < primes.length; j++) {
+                uglys[i] = Math.min(uglys[i], primes[j] * uglys[times[j]]);
+            }
+
+            for (int j = 0; j < times.length; j++) {
+                if (uglys[times[j]] * primes[j] == uglys[i]) {
+                    times[j]++;
+                }
+            }
+        }
+        return uglys[n - 1];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/the-skyline-problem.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/the-skyline-problem.md"
new file mode 100644
index 0000000..27ed8f2
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/the-skyline-problem.md"
@@ -0,0 +1,173 @@
+# 大楼轮廓
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/the-skyline-problem/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 水平面上有 *N* 座大楼，每座大楼都是矩阵的形状，可以用一个三元组表示 `(start, end, height)`，分别代表其在x轴上的起点，终点和高度。大楼之间从远处看可能会重叠，求出 *N* 座大楼的外轮廓线。
+
+外轮廓线的表示方法为若干三元组，每个三元组包含三个数字 (start, end, height)，代表这段轮廓的起始位置，终止位置和高度。
+
+![](https://lintcode-media.s3.amazonaws.com/problem/jiuzhang3.jpg)
+
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+[
+    [1, 3, 3],
+    [2, 4, 4],
+    [5, 6, 1]
+]
+输出:
+[
+    [1, 2, 3],
+    [2, 4, 4],
+    [5, 6, 1]
+]
+说明:
+建筑物如下图所示，黄色部分表示建筑物
+```
+
+![图片](https://media-cdn.jiuzhang.com/markdown/images/6/20/18bd686e-934d-11e9-a170-0242ac110002.jpg)
+
+**样例2**
+
+```plain
+输入:
+[
+    [1, 4, 3],
+    [6, 9, 5]
+]
+输出:
+[
+    [1, 4, 3],
+    [6, 9, 5]
+]
+说明:
+建筑物如下图所示，黄色部分表示建筑物
+```
+
+![图片](https://media-cdn.jiuzhang.com/markdown/images/6/20/58c5f08e-934d-11e9-a170-0242ac110002.jpg)
+ ### 参考代码
+ 使用九章算法强化班中讲过的 HashHeap 和扫描线算法。 Java 可以用 TreeSet / TreeMap， C++ 可以用 Map
+```python
+class HashHeap:
+    
+    def __init__(self, desc=False):
+        self.hash = dict()
+        self.heap = []
+        self.desc = desc
+        
+    @property
+    def size(self):
+        return len(self.heap)
+        
+    def push(self, item):
+        self.heap.append(item)
+        self.hash[item] = self.size - 1
+        self._sift_up(self.size - 1)
+        
+    def pop(self):
+        item = self.heap[0]
+        self.remove(item)
+        return item
+    
+    def top(self):
+        return self.heap[0]
+        
+    def remove(self, item):
+        if item not in self.hash:
+            return
+            
+        index = self.hash[item]
+        self._swap(index, self.size - 1)
+        
+        del self.hash[item]
+        self.heap.pop()
+        
+        # in case of the removed item is the last item
+        if index < self.size:
+            self._sift_up(index)
+            self._sift_down(index)
+
+    def _smaller(self, left, right):
+        return right < left if self.desc else left < right
+
+    def _sift_up(self, index):
+        while index != 0:
+            parent = (index - 1) // 2
+            if self._smaller(self.heap[parent], self.heap[index]):
+                break
+            self._swap(parent, index)
+            index = parent
+    
+    def _sift_down(self, index):
+        if index is None:
+            return
+        while index * 2 + 1 < self.size:
+            smallest = index
+            left = index * 2 + 1
+            right = index * 2 + 2
+            
+            if self._smaller(self.heap[left], self.heap[smallest]):
+                smallest = left
+                
+            if right < self.size and self._smaller(self.heap[right], self.heap[smallest]):
+                smallest = right
+                
+            if smallest == index:
+                break
+            
+            self._swap(index, smallest)
+            index = smallest
+        
+    def _swap(self, i, j):
+        elem1 = self.heap[i]
+        elem2 = self.heap[j]
+        self.heap[i] = elem2
+        self.heap[j] = elem1
+        self.hash[elem1] = j
+        self.hash[elem2] = i
+        
+
+class Solution:
+    """
+    @param buildings: A list of lists of integers
+    @return: Find the outline of those buildings
+    """
+    def buildingOutline(self, buildings):
+        points = []
+        for index, (start, end, height) in enumerate(buildings):
+            points.append((start, height, index, True))
+            points.append((end, height, index, False))
+        points = sorted(points)
+        
+        maxheap = HashHeap(desc=True)
+        intervals = []
+        last_position = None
+        for position, height, index, is_start in points:
+            max_height = maxheap.top()[0] if maxheap.size else 0
+            self.merge_to(intervals, last_position, position, max_height)
+            if is_start:
+                maxheap.push((height, index))
+            else:
+                maxheap.remove((height, index))
+            last_position = position
+
+        return intervals
+        
+    def merge_to(self, intervals, start, end, height):
+        if start is None or height == 0 or start == end:
+            return
+        
+        if not intervals:
+            intervals.append([start, end, height])
+            return
+        
+        _, prev_end, prev_height = intervals[-1]
+        if prev_height == height and prev_end == start:
+            intervals[-1][1] = end
+            return
+        
+        intervals.append([start, end, height])
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/top-k-largest-numbers.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/top-k-largest-numbers.md"
new file mode 100644
index 0000000..4b6260f
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/top-k-largest-numbers.md"
@@ -0,0 +1,113 @@
+# 前K大数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/top-k-largest-numbers/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个数组中找到前K大的数
+ ### 样例说明
+ **样例1**
+
+```
+输入: [3, 10, 1000, -99, 4, 100] 并且 k = 3
+输出: [1000, 100, 10]
+```
+
+**样例2**
+
+```
+输入: [8, 7, 6, 5, 4, 3, 2, 1] 并且 k = 5
+输出: [8, 7, 6, 5, 4]
+```
+
+ ### 参考代码
+ 用堆排序求出前K大数即可
+```java
+// base on heap
+class Solution {
+    /*
+     * @param nums an integer array
+     * @param k an integer
+     * @return the top k largest numbers in array
+     */
+     public int[] topk(int[] nums, int k) {
+         PriorityQueue<Integer> minheap = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
+             public int compare(Integer o1, Integer o2) {
+                 return o1 - o2;
+             }
+         });
+
+         for (int i : nums) {
+             minheap.add(i);
+             if (minheap.size() > k) {
+                minheap.poll();
+             }
+         }
+
+         int[] result = new int[k];
+         for (int i = 0; i < result.length; i++) {
+             result[k - i - 1] = minheap.poll();
+         }
+         return result;
+    }
+};
+
+// base on quicksort
+import java.util.Random;
+
+class Solution {
+    /*
+     * @param nums an integer array
+     * @param k an integer
+     * @return the top k largest numbers in array
+     */
+    public int[] topk(int[] nums, int k) {
+        // Write your code here
+        quickSort(nums, 0, nums.length - 1, k);
+
+        int[] topk = new int[k];
+        for (int i = 0; i < k; ++i)
+            topk[i] = nums[i];
+
+        return topk;
+    }
+    
+    private void quickSort(int[] A, int start, int end, int k) {
+        if (start >= k)
+            return;
+
+        if (start >= end) {
+            return;
+        }
+        
+        int left = start, right = end;
+        // key point 1: pivot is the value, not the index
+        Random rand =new Random(end - start + 1);
+        int index = rand.nextInt(end - start + 1) + start;
+        int pivot = A[index];
+
+        // key point 2: every time you compare left & right, it should be 
+        // left <= right not left < right
+        while (left <= right) {
+            // key point 3: A[left] < pivot not A[left] <= pivot
+            while (left <= right && A[left] > pivot) {
+                left++;
+            }
+            // key point 3: A[right] > pivot not A[right] >= pivot
+            while (left <= right && A[right] < pivot) {
+                right--;
+            }
+
+            if (left <= right) {
+                int temp = A[left];
+                A[left] = A[right];
+                A[right] = temp;
+                
+                left++;
+                right--;
+            }
+        }
+        
+        quickSort(A, start, right, k);
+        quickSort(A, left, end, k);
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/trapping-rain-water-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/trapping-rain-water-ii.md"
new file mode 100644
index 0000000..f45904e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/trapping-rain-water-ii.md"
@@ -0,0 +1,106 @@
+# 接雨水 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/trapping-rain-water-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出 `n * m` 个非负整数，代表一张X轴上每个区域为 `1 * 1` 的 2d 海拔图, 计算这个海拔图最多能接住多少（面积）雨水。
+
+![](https://lintcode-media.s3.amazonaws.com/problem/trapping-rain-water-ii.jpg "")
+ ### 样例说明
+ **样例 1:**
+```
+例如，给定一个 5*4 的矩阵： 
+输入:
+[[12,13,0,12],[13,4,13,12],[13,8,10,12],[12,13,12,12],[13,13,13,13]]
+输出:
+14
+```
+
+**样例 2:**
+```
+输入:
+[[2,2,2,2],[2,2,3,4],[3,3,3,1],[2,3,4,5]]
+输出:
+0
+```
+ ### 参考代码
+ 将矩阵周边的格子都放到堆里，这些格子上面是无法盛水的。
+每次在堆里挑出一个高度最小的格子 cell，把周围的格子加入到堆里。
+这些格子被加入堆的时候，计算他们上面的盛水量。
+
+```
+盛水量 = cell.height - 这个格子的高度
+```
+
+当然如果这个值是负数，盛水量就等于 0。
+```java
+class Cell {
+    public int x, y, height;
+    Cell() {}
+    Cell(int x, int y, int height) {
+        this.x = x;
+        this.y = y;
+        this.height = height;
+    }
+}
+
+class CellComparator implements Comparator<Cell> {
+    @Override
+    public int compare(Cell left, Cell right) {
+        return left.height - right.height;
+    }
+}
+
+public class Solution {
+    int[] dx = {1, -1, 0, 0};
+    int[] dy = {0, 0, 1, -1};
+    
+    public int trapRainWater(int[][] heights) {
+        if (heights == null || heights.length == 0) {
+            return 0;
+        }
+    
+        PriorityQueue<Cell> minheap =  new PriorityQueue<>(new CellComparator());
+        
+        int n = heights.length;
+        int m = heights[0].length;
+        boolean[][] visited = new boolean[n][m];
+        
+        for (int i = 0; i < n; i++) {
+            minheap.offer(new Cell(i, 0, heights[i][0]));
+            minheap.offer(new Cell(i, m - 1, heights[i][m-1]));
+            visited[i][0] = true;
+            visited[i][m - 1] = true;
+        }
+        
+        for (int i = 0; i < m; i++) {
+            minheap.offer(new Cell(0, i, heights[0][i]));
+            minheap.offer(new Cell(n-1, i, heights[n-1][i]));
+            visited[0][i] = true;
+            visited[n - 1][i] = true;
+        }
+
+        int water = 0;
+        while (!minheap.isEmpty()) {
+            Cell cell = minheap.poll();
+            
+            for (int i = 0; i < 4; i++) {
+                int nx = cell.x + dx[i];
+                int ny = cell.y + dy[i];
+                
+                if (nx < 0 || nx >= n || ny < 0 || ny >= m) {
+                    continue;
+                }
+                if (visited[nx][ny]) {
+                    continue;
+                }
+                
+                visited[nx][ny] = true;
+                minheap.offer(new Cell(nx, ny, Math.max(cell.height, heights[nx][ny])));
+                water = water + Math.max(0, cell.height - heights[nx][ny]);
+            }
+        }
+        
+        return water;
+    } 
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/ugly-number-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/ugly-number-ii.md"
new file mode 100644
index 0000000..8a84505
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\240\206/ugly-number-ii.md"
@@ -0,0 +1,44 @@
+# 丑数 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/ugly-number-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个算法，找出只含素因子`2`，`3`，`5` 的第 *n* 小的数。
+
+符合条件的数如：`1, 2, 3, 4, 5, 6, 8, 9, 10, 12...`
+
+ ### 样例说明
+ **样例 1：**
+```
+输入：9
+输出：10
+```
+**样例 2：**
+```
+输入：1
+输出：1
+```
+ ### 参考代码
+ 使用九章算法班中讲的 heap
+时间复杂度 $O(nlogn)$
+```python
+import heapq
+
+class Solution:
+    """
+    @param {int} n an integer.
+    @return {int} the nth prime number as description.
+    """
+    def nthUglyNumber(self, n):
+        heap = [1]
+        visited = set([1])
+        
+        val = None
+        for i in range(n):
+            val = heapq.heappop(heap)
+            for factor in [2, 3, 5]:
+                if val * factor not in visited:
+                    visited.add(val * factor)
+                    heapq.heappush(heap, val * factor)
+            
+        return val
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/add-and-search-word-data-structure-design.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/add-and-search-word-data-structure-design.md"
new file mode 100644
index 0000000..ffe2a93
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/add-and-search-word-data-structure-design.md"
@@ -0,0 +1,88 @@
+# 单词的添加与查找
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/add-and-search-word-data-structure-design/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个包含下面两个操作的数据结构：`addWord(word)`, `search(word)`
+
+`addWord(word)`会在数据结构中添加一个单词。而`search(word)`则支持普通的单词查询或是只包含`.`和`a-z`的简易正则表达式的查询。
+
+一个 `.` 可以代表一个任何的字母。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  addWord("a")
+  search(".")
+输出: 
+  true
+```
+
+**样例 2:**
+
+```
+输入: 
+  addWord("bad")
+  addWord("dad")
+  addWord("mad")
+  search("pad")  
+  search("bad")  
+  search(".ad")  
+  search("b..") 
+输出:
+  false
+  true
+  true
+  true 
+```
+ ### 参考代码
+ ```python
+class TrieNode:
+    def __init__(self):
+        self.children = {}
+        self.is_word = False
+
+
+class WordDictionary:
+    
+    def __init__(self):
+        self.root = TrieNode()
+        
+    """
+    @param: word: Adds a word into the data structure.
+    @return: nothing
+    """
+    def addWord(self, word):
+        node = self.root
+        for c in word:
+            if c not in node.children:
+                node.children[c] = TrieNode()
+            node = node.children[c]
+        node.is_word =True
+
+    """
+    @param: word: A word could contain the dot character '.' to represent any one letter.
+    @return: if the word is in the data structure.
+    """
+    def search(self, word):
+        if word is None:
+            return False
+        return self.search_helper(self.root, word, 0)
+        
+    def search_helper(self, node, word, index):
+        if node is None:
+            return False
+            
+        if index >= len(word):
+            return node.is_word
+        
+        char = word[index]
+        if char != '.':
+            return self.search_helper(node.children.get(char), word, index + 1)
+            
+        for child in node.children:
+            if self.search_helper(node.children[child], word, index + 1):
+                return True
+                
+        return False
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/add-and-search-word.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/add-and-search-word.md"
new file mode 100644
index 0000000..904fc0f
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/add-and-search-word.md"
@@ -0,0 +1,160 @@
+# 单词的添加与查找
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/add-and-search-word/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个包含下面两个操作的数据结构：`addWord(word)`, `search(word)`
+
+`addWord(word)`会在数据结构中添加一个单词。而`search(word)`则支持普通的单词查询或是只包含`.`和`a-z`的简易正则表达式的查询。
+
+一个 `.` 可以代表一个任何的字母。
+ ### 样例说明
+ 
+ ### 参考代码
+ 可以说, 这道题是 [442. 实现 Trie (前缀树)](https://www.lintcode.com/problem/implement-trie-prefix-tree/description) 的升级版.
+
+只需要在查询的时候将 `'.'` 处理为回溯即可, 即遇到 `'.'` 则需要访问每一个子节点判断是否有匹配.
+```java
+// Version1 use Array
+class TrieNode {
+
+    public TrieNode[] children;
+    public boolean hasWord;
+    
+    public TrieNode() {
+        children = new TrieNode[26];
+        for (int i = 0; i < 26; ++i)
+            children[i] = null;
+        hasWord = false;
+    }
+}
+
+
+public class WordDictionary {
+    private TrieNode root;
+ 
+    public WordDictionary() {
+        root = new TrieNode();
+    }
+ 
+    // Adds a word into the data structure.
+    public void addWord(String word) {
+        TrieNode now = root;
+        for (int i = 0; i < word.length(); i++) {
+            Character c = word.charAt(i);
+            if (now.children[c - 'a'] == null) {
+                now.children[c - 'a'] = new TrieNode();
+            }
+            now = now.children[c - 'a'];
+        }
+        now.hasWord = true;
+    }
+    
+    boolean find(String word, int index, TrieNode now) {
+        if (index == word.length()) {
+            return now.hasWord;
+        }
+        
+        Character c = word.charAt(index);
+        if (c == '.') {
+            for (int i = 0; i < 26; ++i) 
+                if (now.children[i] != null) {
+                    if (find(word, index+1, now.children[i]))
+                        return true;
+                }
+            return false;
+        } else if (now.children[c - 'a'] != null) {
+            return find(word, index+1, now.children[c - 'a']);  
+        } else {
+            return false;
+        }
+    }
+    
+    // Returns if the word is in the data structure. A word could
+    // contain the dot character '.' to represent any one letter.
+    public boolean search(String word) {
+        // Write your code here
+        return find(word, 0, root);
+    }
+}
+
+// Your WordDictionary object will be instantiated and called as such:
+// WordDictionary wordDictionary = new WordDictionary();
+// wordDictionary.addWord("word");
+// wordDictionary.search("pattern");
+
+
+
+// Version 2 use HashMap and dfs
+class TrieNode {
+    // Initialize your data structure here.
+    public HashMap<Character, TrieNode> children;
+    public boolean hasWord;
+    
+    // Initialize your data structure here.
+    public TrieNode() {
+        children = new HashMap<Character, TrieNode>();
+        hasWord = false;
+    }
+}
+
+
+public class WordDictionary {
+    private TrieNode root;
+ 
+    public WordDictionary() {
+        root = new TrieNode();
+    }
+ 
+    // Adds a word into the data structure.
+    public void addWord(String word) {
+        TrieNode now = root;
+        for (int i = 0; i < word.length(); i++) {
+            Character c = word.charAt(i);
+            if (!now.children.containsKey(c)) {
+                now.children.put(c, new TrieNode());
+            }
+            now = now.children.get(c);
+        }
+        now.hasWord = true;
+    }
+    
+    boolean find(String word, int index, TrieNode now) {
+        if (index == word.length()){
+            if (now.children.size() == 0) 
+                return true; 
+            else
+                return false;
+        }
+        
+        Character c = word.charAt(index);
+        if (now.children.containsKey(c)) {
+            if (index == word.length()-1 && now.children.get(c).hasWord) {
+                return true;
+            }
+            return find(word, index+1, now.children.get(c)) ;  
+        } else if(c == '.') {
+            boolean result = false;
+            for (Map.Entry<Character, TrieNode> child: now.children.entrySet()) {
+                if (index == word.length()-1 && child.getValue().hasWord) {
+                    return true;
+                } 
+ 
+                //if any path is true, set result to be true; 
+                if (find(word, index+1, child.getValue())) {
+                    result = true;
+                }
+            }
+            return result;
+        } else {
+            return false;
+        }
+    }
+    
+    // Returns if the word is in the data structure. A word could
+    // contain the dot character '.' to represent any one letter.
+    public boolean search(String word) {
+        // Write your code here
+        return find(word, 0, root);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/boggle-game.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/boggle-game.md"
new file mode 100644
index 0000000..03013bc
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/boggle-game.md"
@@ -0,0 +1,160 @@
+# 拼字游戏
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/boggle-game/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个2D矩阵包括 `a-z` 和字典 `dict`，找到矩阵上最大的单词集合，这些单词不能在相同的位置重叠。返回最大集合的 `大小`。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+["abc","def","ghi"]
+{"abc","defi","gh"}
+输出:
+3
+
+解释:
+我们可以得到最大的集合 `["abc", "defi", "gh"]`
+```
+
+**样例 2:**
+```
+输入:
+["aaaa","aaaa","aaaa","aaaa"]
+{"a"}
+输出:
+16
+
+解释:
+我们可以得到最大的集合 `["a", "a","a","a","a","a","a","a","a","a","a","a","a","a","a","a"]`
+```
+
+ ### 参考代码
+ tire + dfs。
+字典树用于前缀查找。
+dfs用于搜索，
+找到单词时搜索下一个单词
+没有搜索到单词时，四方向遍历（回溯 + 标记）
+```java
+//建立tire树的过程
+class Trie {
+    TrieNode root;
+
+    Trie() {
+        root = new TrieNode('0');
+    }
+
+    public void insert(String word) {
+        if(word == null || word.length() == 0) {
+            return;
+        }
+        TrieNode node = root;
+        for(int i = 0; i < word.length(); i++) {
+            char ch = word.charAt(i);
+            if(node.children[ch - 'a'] == null) {
+                node.children[ch - 'a'] = new TrieNode(ch);
+            }
+            node = node.children[ch - 'a'];
+        }
+        node.isWord = true;
+    }
+}
+//tire的结点
+class TrieNode {
+    char value;
+    boolean isWord;
+    TrieNode[] children;
+
+    TrieNode(char v) {
+        value = v;
+        isWord = false;
+        children = new TrieNode[26];
+    }
+}
+
+public class Solution {
+    /**
+     * @param board a list of lists of character
+     * @param words a list of string
+     * @return an integer
+     */
+    public int boggleGame(char[][] board, String[] words) {
+        // Write your code here
+        Trie trie = new Trie();
+        for(String word : words) {
+            trie.insert(word);
+        }
+
+        int m = board.length;
+        int n = board[0].length;
+        List<String> result = new ArrayList<>();
+        boolean[][] visited = new boolean[m][n];
+        List<String> path = new ArrayList<>();
+        findWords(result, board, visited, path, 0, 0, trie.root);
+        return result.size();
+    }
+	//从当前位置出发寻单词存不存在
+    public void findWords(List<String> result, char[][] board, boolean[][] visited, List<String> words, int x, int y, TrieNode root) {
+
+        int m = board.length;
+        int n = board[0].length;
+
+        for (int i = x; i < m; i++) {
+            for (int j = y; j < n; j++) {
+                List<List<Integer>> nextWordIndexes = new ArrayList<>();
+                List<Integer> path = new ArrayList<>();
+                getNextWords(nextWordIndexes, board, visited, path, i, j, root);
+                for (List<Integer> indexes : nextWordIndexes) {
+                    String word = "";
+                    for (int index : indexes) {
+                        int row = index / n;
+                        int col = index % n;
+                        visited[row][col] = true;
+                        word += board[row][col];
+                    }
+
+                    words.add(word);
+                    if (words.size() > result.size()) {
+                        result.clear();
+                        result.addAll(words);
+                    }
+                    findWords(result, board, visited, words, i, j, root);
+                    for (int index : indexes) {
+                        int row = index / n;
+                        int col = index % n;
+                        visited[row][col] = false;
+                    }
+                    words.remove(words.size() - 1);
+                }
+            }
+            y = 0;
+        }
+    }
+    
+    int []dx = {0, 1, 0, -1};
+    int []dy = {1, 0, -1, 0};
+    //dfs搜索查找单词
+    private void getNextWords(List<List<Integer>> words, char[][] board,
+                              boolean[][] visited, List<Integer> path, int i, int j, TrieNode root) {
+        if(i < 0 | i >= board.length || j < 0 || j >= board[0].length
+            || visited[i][j] == true || root.children[board[i][j] - 'a'] == null) {
+            return;
+        }
+		//找下一个单词
+        root = root.children[board[i][j] - 'a'];
+        if(root.isWord) {
+            List<Integer> newPath = new ArrayList<>(path);
+            newPath.add(i * board[0].length + j);
+            words.add(newPath);
+            return;
+        }
+		//回溯标记
+        visited[i][j] = true;
+        path.add(i * board[0].length + j);
+        for (int k = 0; k < 4; k ++) {
+            getNextWords(words, board, visited, path, i + dx[k], j + dy[k], root);
+        }
+        path.remove(path.size() - 1);
+        visited[i][j] = false;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/implement-trie-prefix-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/implement-trie-prefix-tree.md"
new file mode 100644
index 0000000..93ee191
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/implement-trie-prefix-tree.md"
@@ -0,0 +1,89 @@
+# 实现 Trie（前缀树）
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/implement-trie-prefix-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个 Trie，包含 `insert`, `search`, 和 `startsWith` 这三个方法。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 
+  insert("lintcode")
+  search("lint")
+  startsWith("lint")
+输出: 
+  false
+  true
+```
+
+**样例 2:**
+
+```
+输入:
+  insert("lintcode")
+  search("code")
+  startsWith("lint")
+  startsWith("linterror")
+  insert("linterror")
+  search("lintcode”)
+  startsWith("linterror")
+输出: 
+  false
+  true
+  false
+  true
+  true
+```
+ ### 参考代码
+ ```python
+class TrieNode:
+    
+    def __init__(self):
+        self.children = {}
+        self.is_word = False
+    
+    
+class Trie:
+    
+    def __init__(self):
+        self.root = TrieNode()
+
+    """
+    @param: word: a word
+    @return: nothing
+    """
+    def insert(self, word):
+        node = self.root
+        for c in word:
+            if c not in node.children:
+                node.children[c] = TrieNode()
+            node = node.children[c]
+        
+        node.is_word = True
+
+    """
+    return the node in the trie if exists 
+    """
+    def find(self, word):
+        node = self.root
+        for c in word:
+            node = node.children.get(c)
+            if node is None:
+                return None
+        return node
+        
+    """
+    @param: word: A string
+    @return: if the word is in the trie.
+    """
+    def search(self, word):
+        node = self.find(word)
+        return node is not None and node.is_word
+
+    """
+    @param: prefix: A string
+    @return: if there is any word in the trie that starts with the given prefix.
+    """
+    def startsWith(self, prefix):
+        return self.find(prefix) is not None
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/trie.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/implement-trie.md"
similarity index 56%
rename from "\351\242\230\350\247\243/trie.md"
rename to "\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/implement-trie.md"
index 59785f2..5e6a30e 100644
--- "a/\351\242\230\350\247\243/trie.md"
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/implement-trie.md"
@@ -1,93 +1,152 @@
-# trie
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/trie/?utm_source=sc-github-wzz)
+# 实现 Trie（前缀树）
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/implement-trie/?utm_source=sc-github-wzz)
  ## 题目描述
- 1758
+ 实现一个 Trie，包含 `insert`, `search`, 和 `startsWith` 这三个方法。
  ### 样例说明
- 1758
+ 
  ### 参考代码
- ```java
-/*
-Your Trie object will be instantiated and called as such:
-Trie trie = new Trie();
-trie.insert("lintcode");
-trie.search("lint"); will return false
-trie.startsWith("lint"); will return true
-*/
-class TrieNode {
-    // Initialize your data structure here.
-    char c;
-    HashMap<Character, TrieNode> children = new HashMap<Character, TrieNode>();
-    boolean hasWord;
-    
-    public TrieNode(){
-        
-    }
-    
-    public TrieNode(char c){
-        this.c = c;
-    }
-}
-
-public class Trie {
-    private TrieNode root;
-
-    public Trie() {
-        root = new TrieNode();
-    }
-
-    // Inserts a word into the trie.
-    public void insert(String word) {
-        TrieNode cur = root;
-        HashMap<Character, TrieNode> curChildren = root.children;
-        char[] wordArray = word.toCharArray();
-        for(int i = 0; i < wordArray.length; i++){
-            char wc = wordArray[i];
-            if(curChildren.containsKey(wc)){
-                cur = curChildren.get(wc);
-            } else {
-                TrieNode newNode = new TrieNode(wc);
-                curChildren.put(wc, newNode);
-                cur = newNode;
-            }
-            curChildren = cur.children;
-            if(i == wordArray.length - 1){
-                cur.hasWord= true;
-            }
-        }
-    }
-
-    // Returns if the word is in the trie.
-    public boolean search(String word) {
-        if(searchWordNodePos(word) == null){
-            return false;
-        } else if(searchWordNodePos(word).hasWord) 
-          return true;
-          else return false;
-    }
-
-    // Returns if there is any word in the trie
-    // that starts with the given prefix.
-    public boolean startsWith(String prefix) {
-        if(searchWordNodePos(prefix) == null){
-            return false;
-        } else return true;
-    }
-    
-    public TrieNode searchWordNodePos(String s){
-        HashMap<Character, TrieNode> children = root.children;
-        TrieNode cur = null;
-        char[] sArray = s.toCharArray();
-        for(int i = 0; i < sArray.length; i++){
-            char c = sArray[i];
-            if(children.containsKey(c)){
-                cur = children.get(c);
-                children = cur.children;
-            } else{
-                return null;
-            }
-        }
-        return cur;
-    }
+ Trie(前缀树) 的模板应用.
+
+维基百科: <https://zh.wikipedia.org/zh-hans/Trie>
+```java
+// Version 1: Array of TrieNode
+class TrieNode {
+    private TrieNode[] children;
+    public boolean hasWord;
+    
+    public TrieNode() {
+        children = new TrieNode[26];
+        hasWord = false;
+    }
+    
+    public void insert(String word, int index) {
+        if (index == word.length()) {
+            this.hasWord = true;
+            return;
+        }
+        
+        int pos = word.charAt(index) - 'a';
+        if (children[pos] == null) {
+            children[pos] = new TrieNode();
+        }
+        children[pos].insert(word, index + 1);
+    }
+    
+    public TrieNode find(String word, int index) {
+        if (index == word.length()) {
+            return this;
+        }
+        
+        int pos = word.charAt(index) - 'a';
+        if (children[pos] == null) {
+            return null;
+        }
+        return children[pos].find(word, index + 1);
+    }
+}
+
+public class Trie {
+    private TrieNode root;
+
+    public Trie() {
+        root = new TrieNode();
+    }
+
+    // Inserts a word into the trie.
+    public void insert(String word) {
+        root.insert(word, 0);
+    }
+
+    // Returns if the word is in the trie.
+    public boolean search(String word) {
+        TrieNode node = root.find(word, 0);
+        return (node != null && node.hasWord);
+    }
+
+    // Returns if there is any word in the trie
+    // that starts with the given prefix.
+    public boolean startsWith(String prefix) {
+        TrieNode node = root.find(prefix, 0);
+        return node != null;
+    }
+}
+
+// Version 2: HashMap Version, this version will be TLE when you submit on LintCode
+class TrieNode {
+    // Initialize your data structure here.
+    char c;
+    HashMap<Character, TrieNode> children = new HashMap<Character, TrieNode>();
+    boolean hasWord;
+    
+    public TrieNode(){
+        
+    }
+    
+    public TrieNode(char c){
+        this.c = c;
+    }
+}
+
+public class Trie {
+    private TrieNode root;
+
+    public Trie() {
+        root = new TrieNode();
+    }
+
+    // Inserts a word into the trie.
+    public void insert(String word) {
+        TrieNode cur = root;
+        HashMap<Character, TrieNode> curChildren = root.children;
+        char[] wordArray = word.toCharArray();
+        for(int i = 0; i < wordArray.length; i++){
+            char wc = wordArray[i];
+            if(curChildren.containsKey(wc)){
+                cur = curChildren.get(wc);
+            } else {
+                TrieNode newNode = new TrieNode(wc);
+                curChildren.put(wc, newNode);
+                cur = newNode;
+            }
+            curChildren = cur.children;
+            if(i == wordArray.length - 1){
+                cur.hasWord= true;
+            }
+        }
+    }
+
+    // Returns if the word is in the trie.
+    public boolean search(String word) {
+        if(searchWordNodePos(word) == null){
+            return false;
+        } else if(searchWordNodePos(word).hasWord) 
+          return true;
+          else return false;
+    }
+
+    // Returns if there is any word in the trie
+    // that starts with the given prefix.
+    public boolean startsWith(String prefix) {
+        if(searchWordNodePos(prefix) == null){
+            return false;
+        } else return true;
+    }
+    
+    public TrieNode searchWordNodePos(String s){
+        HashMap<Character, TrieNode> children = root.children;
+        TrieNode cur = null;
+        char[] sArray = s.toCharArray();
+        for(int i = 0; i < sArray.length; i++){
+            char c = sArray[i];
+            if(children.containsKey(c)){
+                cur = children.get(c);
+                children = cur.children;
+            } else{
+                return null;
+            }
+        }
+        return cur;
+    }
 }
 ```
  更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/word-squares.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/word-squares.md"
new file mode 100644
index 0000000..b426a50
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\345\255\227\345\205\270\346\240\221/word-squares.md"
@@ -0,0 +1,185 @@
+# 单词矩阵
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-squares/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一系列 **不重复的单词**，找出所有用这些单词能构成的 [单词矩阵](https://en.wikipedia.org/wiki/Word_square "Word square")。
+一个有效的单词矩阵是指, 如果从第 k 行读出来的单词和第 k 列读出来的单词相同(0 <= k < max(numRows, numColumns))，那么就是一个单词矩阵.
+例如，单词序列为 `["ball","area","lead","lady"]` ,构成一个单词矩阵。因为对于每一行和每一列，读出来的单词都是相同的。
+```
+b a l l
+a r e a
+l e a d
+l a d y
+```
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+["area","lead","wall","lady","ball"]
+输出:
+[["wall","area","lead","lady"],["ball","area","lead","lady"]]
+
+解释:
+输出包含 两个单词矩阵，这两个矩阵的输出的顺序没有影响(只要求矩阵内部有序)。
+```
+
+**样例 2:**
+```
+输入:
+["abat","baba","atan","atal"]
+输出:
+ [["baba","abat","baba","atan"],["baba","abat","baba","atal"]]
+```
+ ### 参考代码
+ 字典树+dfs。
+根据已添加单词确定下一个单词的前缀，利用dfs搜索。
+```java
+public class Solution {
+     class TrieNode {
+        List<String> startWith;
+        TrieNode[] children;
+
+        TrieNode() {
+            startWith = new ArrayList<>();
+            children = new TrieNode[26];
+        }
+    }
+
+    class Trie {
+        TrieNode root;
+
+        Trie(String[] words) {
+            root = new TrieNode();
+            for (String w : words) {
+                TrieNode cur = root;
+                for (char ch : w.toCharArray()) {
+                    int idx = ch - 'a';
+                    if (cur.children[idx] == null)
+                        cur.children[idx] = new TrieNode();
+                    cur.children[idx].startWith.add(w);
+                    cur = cur.children[idx];
+                }
+            }
+        }
+
+        List<String> findByPrefix(String prefix) {
+            List<String> ans = new ArrayList<>();
+            TrieNode cur = root;
+            for (char ch : prefix.toCharArray()) {
+                int idx = ch - 'a';
+                if (cur.children[idx] == null)
+                    return ans;
+
+                cur = cur.children[idx];
+            }
+            ans.addAll(cur.startWith);
+            return ans;
+        }
+    }
+
+    public List<List<String>> wordSquares(String[] words) {
+        List<List<String>> ans = new ArrayList<>();
+        if (words == null || words.length == 0)
+            return ans;
+        int len = words[0].length();
+        Trie trie = new Trie(words);
+        List<String> ansBuilder = new ArrayList<>();
+        for (String w : words) {
+            ansBuilder.add(w);
+            search(len, trie, ans, ansBuilder);
+            ansBuilder.remove(ansBuilder.size() - 1);
+        }
+
+        return ans;
+    }
+
+    private void search(int len, Trie tr, List<List<String>> ans,
+            List<String> ansBuilder) {
+        if (ansBuilder.size() == len) {
+            ans.add(new ArrayList<>(ansBuilder));
+            return;
+        }
+
+        int idx = ansBuilder.size();
+        StringBuilder prefixBuilder = new StringBuilder();
+        for (String s : ansBuilder)
+            prefixBuilder.append(s.charAt(idx));
+        List<String> startWith = tr.findByPrefix(prefixBuilder.toString());
+        for (String sw : startWith) {
+            ansBuilder.add(sw);
+            search(len, tr, ans, ansBuilder);
+            ansBuilder.remove(ansBuilder.size() - 1);
+        }
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param words a set of words without duplicates
+     * @return all word squares
+     */
+
+    void initPrefix(String[] words, Map<String, List<String>> hash) {
+        for (String item : words) {
+            hash.putIfAbsent("", new ArrayList<>());
+            hash.get("").add(item);
+
+            String prefix = "";
+            for (char c : item.toCharArray()) {
+                prefix += c;
+                hash.putIfAbsent(prefix, new ArrayList<>());
+                hash.get(prefix).add(item);
+            }
+        }
+    }
+
+    boolean checkPrefix(int l, String nextWord, int wordLen, Map<String, List<String>> hash, List<String> squares) {
+        for (int j = l + 1; j < wordLen; j++) {
+            String prefix = "";
+            for (int k = 0; k < l; k++) {
+                prefix += squares.get(k).charAt(j);
+            }
+            prefix += nextWord.charAt(j);
+            if (!hash.containsKey(prefix)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    void dfs(int l, int wordLen, Map<String, List<String>> hash, List<String> squares, List<List<String>> ans) {
+        if (l == wordLen) {
+            ans.add(new ArrayList<>(squares));
+            return;
+        }
+        String prefix = "";
+        for (int i = 0; i < l; i++) {
+            prefix += squares.get(i).charAt(l);
+        }
+
+        for (String item : hash.get(prefix)) {
+            if (!checkPrefix(l, item, wordLen, hash, squares)) {
+                continue;
+            }
+            squares.add(item);
+            dfs(l + 1, wordLen, hash, squares, ans);
+            squares.remove(squares.size() - 1);
+        }
+    }
+
+    public List<List<String>> wordSquares(String[] words) {
+        // Write your code here
+        List<List<String>> ans = new ArrayList<>();
+        if (words.length == 0) {
+            return ans;
+        }
+        Map<String, List<String>> hash = new HashMap<>();
+        initPrefix(words, hash);
+
+        List<String> squares = new ArrayList<>();
+        dfs(0, words[0].length(), hash, squares, ans);
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/132-pattern.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/132-pattern.md"
new file mode 100644
index 0000000..e38d8d5
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/132-pattern.md"
@@ -0,0 +1,47 @@
+# 132 模式
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/132-pattern/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个 n 个整数的序列 a1,a2,...,an，一个 `132` 模式是对于一个子串 ai,aj,ak，满足 `i` < `j` < `k` 和 `ai` < `ak` < `aj`。设计一个算法来检查输入的这 n 个整数的序列中是否存在132模式。
+`n` 会小于 `20,000`。
+ ### 样例说明
+ 例1:
+```
+输入: nums = [1, 2, 3, 4] 
+输出: False 
+解释:
+没有132模式在这个序列中。
+```
+例2:
+```
+输入: nums = [3, 1, 4, 2] 
+输出: True 
+解释:
+存在132模式：[1,4,2]。
+```
+
+ ### 参考代码
+ s2代表当前次大值。
+从最后一个开始遍历，依次与S2做比较，若小于，直接返回true，若大于，跟新s2的值即可
+```java
+public class Solution {
+    /**
+     * @param nums a list of n integers
+     * @return true if there is a 132 pattern or false
+     */
+    public boolean find132pattern(int[] nums) {
+        // Write your code here
+        Stack<Integer> stack = new Stack<Integer>();
+        for (int i = nums.length - 1, two = Integer.MIN_VALUE; i >= 0; i--) {
+            if (nums[i] < two) {
+                return true;
+            } else {
+                while (!stack.empty() && nums[i] > stack.peek())
+                    two = stack.pop();
+            }
+            stack.push(nums[i]);
+        }
+        return false;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/132-patterns.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/132-patterns.md"
similarity index 100%
rename from "\351\242\230\350\247\243/132-patterns.md"
rename to "\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/132-patterns.md"
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/basic-calculator-iii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/basic-calculator-iii.md"
new file mode 100644
index 0000000..444a648
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/basic-calculator-iii.md"
@@ -0,0 +1,115 @@
+# 基础计算器III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/basic-calculator-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个基本的计算器来计算一个简单的表达式字符串。
+
+表达式字符串可以包含左括号 `(`和右括号 `)`、加号` + `或减号` - `、` non-negative ` 整数和空格。
+
+表达式字符串只包含非负整数、`+`, `-`, `*`, `/`操作符、左括号 `(`，右括号 `)`和空格。
+
+您可以假设给定的表达式总是有效的。所有中间结果将在“[-2147483648,2147483647]”范围内。
+ ### 样例说明
+ **样例 1:**
+```
+输入："1 + 1"
+输出：2
+解释：1 + 1 = 2
+```
+
+
+**样例 2:**
+```
+输入：" 6-4 / 2 "
+输出：4
+解释：4/2=2，6-2=4
+```
+
+
+ ### 参考代码
+ 用递归的方法来实现。
+效率不太高，但是写法比较简单。
+面试要求不高的话，也可以过。
+
+```
+[[python]]
+class Solution:
+    """
+    @param s: the expression string
+    @return: the answer
+    """
+    def calculate(self, s):
+        expression = []
+        val = None
+        for char in s:
+            if char == ' ':
+                continue
+            if char in ['+', '-', '*', '/', '(', ')']:
+                if val is not None:
+                    expression.append(str(val))
+                expression.append(char)
+                val = None
+            else:
+                if val is None:
+                    val = 0
+                val = val * 10 + ord(char) - ord('0')
+        if val is not None:
+            expression.append(str(val))
+        
+        return self.evaluate_expression(expression)
+            
+    def calc(self, a, operator, b):
+        if operator == '+':
+            return a + b
+        elif operator == '-':
+            return a - b
+        elif operator == '*':
+            return a * b
+        else:
+            return a // b
+            
+    def divide_expression(self, expression, operators):
+        last_index, parens = 0, 0
+        last_operator = operators[0]
+        total = 1 if last_operator == '*' else 0
+        can_divide = False
+        
+        for index, elem in enumerate(expression):
+            if elem in operators and parens == 0:
+                can_divide = True
+                val = self.evaluate_expression(expression[last_index: index])
+                total = self.calc(total, last_operator, val)
+                last_operator = elem
+                last_index = index + 1
+            elif elem == '(':
+                parens += 1
+            elif elem == ')':
+                parens -= 1
+        
+        if can_divide:
+            val = self.evaluate_expression(expression[last_index:])
+            total = self.calc(total, last_operator, val)
+            
+        return can_divide, total
+
+    """
+    @param expression: a list of strings
+    @return: an integer
+    """
+    def evaluate_expression(self, expression):
+        if not expression:
+            return 0
+        if len(expression) == 1:
+            return int(expression[0])
+            
+        can_divide, total = self.divide_expression(expression, ['+', '-'])
+        if can_divide:
+            return total
+    
+        can_divide, total = self.divide_expression(expression, ['*', '/'])
+        if can_divide:
+            return total
+            
+        # must be parentheses around the expression
+        return self.evaluate_expression(expression[1:-1])
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/basic-calculator.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/basic-calculator.md"
new file mode 100644
index 0000000..77d0d85
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/basic-calculator.md"
@@ -0,0 +1,99 @@
+# 基础计算器
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/basic-calculator/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个基础的计算器来计算一个简单表达式。
+
+这个表达式字符串可能包含左括号 `'('` 与右括号 `')'`，加号 `'+'` 或者 减号 `'-'`，**非负**整数以及空格 `' '`。
+
+给出的表达式总是合理的。
+ ### 样例说明
+ **样例 1**
+```
+输入："1 + 1"
+输出：2
+```
+**样例 2**
+```
+输入："(1+(4+5+2)-3)+(6+8)" 
+输出：23
+```
+ ### 参考代码
+ ```
+[[python]]
+class Solution:
+    """
+    @param s: the expression string
+    @return: the answer
+    """
+    def calculate(self, s):
+        expression = []
+        val = None
+        for char in s:
+            if char == ' ':
+                continue
+            if char in ['+', '-', '*', '/', '(', ')']:
+                if val is not None:
+                    expression.append(str(val))
+                expression.append(char)
+                val = None
+            else:
+                if val is None:
+                    val = 0
+                val = val * 10 + ord(char) - ord('0')
+        if val is not None:
+            expression.append(str(val))
+        
+        return self.evaluate_expression(expression)
+
+    def evaluate_expression(self, expression):
+        if not expression:
+            return 0
+        if len(expression) == 1:
+            return int(expression[0])
+            
+        can_divide, total = self.divide_expression(expression, ['+', '-'])
+        if can_divide:
+            return total
+    
+        can_divide, total = self.divide_expression(expression, ['*', '/'])
+        if can_divide:
+            return total
+            
+        # must be parens around the expression
+        return self.evaluate_expression(expression[1:-1])
+            
+    def divide_expression(self, expression, operators):
+        last_index, parens = 0, 0
+        last_operator = operators[0]
+        total = 1 if last_operator == '*' else 0
+        can_divide = False
+        
+        for index, elem in enumerate(expression):
+            if elem in operators and parens == 0:
+                can_divide = True
+                val = self.evaluate_expression(expression[last_index: index])
+                total = self.calc(total, last_operator, val)
+                last_operator = elem
+                last_index = index + 1
+            elif elem == '(':
+                parens += 1
+            elif elem == ')':
+                parens -= 1
+        
+        if can_divide:
+            val = self.evaluate_expression(expression[last_index:])
+            total = self.calc(total, last_operator, val)
+            
+        return can_divide, total
+     
+    def calc(self, a, operator, b):
+        if operator == '+':
+            return a + b
+        elif operator == '-':
+            return a - b
+        elif operator == '*':
+            return a * b
+        else:
+            return a // b
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/convert-expression-to-polish-notation.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/convert-expression-to-polish-notation.md"
new file mode 100644
index 0000000..c451519
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/convert-expression-to-polish-notation.md"
@@ -0,0 +1,118 @@
+# 将表达式转换为波兰表达式
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-expression-to-polish-notation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串数组，它代表一个表达式，返回该表达式的波兰表达式。（去掉括号）
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: ["(", "5", "-", "6", ")", "*", "7"]
+输出: ["*", "-", "5", "6", "7"]
+解释: (5 - 6) * 7 = -1 * 7 = -7
+    * - 5 6 7 = * -1 7 = -7
+```
+
+**样例 2:**
+
+```
+输入: ["3", "+", "(", "1", "-", "2", ")"]
+输出: ["+", "3", "-", "1", "2"] 
+解释: 3 + (1 - 2) = 3 + -1 = 2
+    + 3 - 1 2 = + 3 -1 = 2
+```
+ ### 参考代码
+ 借助 **栈** 我们可以实现中缀表达式到前缀表达式(即波兰表达式, PN)的转换.
+
+从右到左遍历中缀表达式:
+
+1. 如果碰到 **数字**, 直接追加到 PN 末尾.
+2. 如果碰到 **右括号**, 入栈
+3. 如果碰到 **左括号**, 弹栈, 并将弹出的元素依次追加到 PN 末尾, 直至右括号弹出(右括号不追加至PN)
+4. 如果碰到 **运算符**, 弹栈直至栈顶元素优先级 **不大于** 当前运算符, 所有弹出的元素依次追加到 PN 末尾, 最后再将该运算符入栈
+
+出于方便, 我们设定所有元素的优先级: `*/` 最高, `+-` 次之, 然后是数字, 最后是括号.
+
+(把括号设为最低是因为, 碰到运算符弹栈时, 遇到括号也要停止, 所以可以直接设为最低)
+
+遍历完后, 如果栈中还剩元素, 依次弹栈, 追加到 PN 末尾. 最后, 我们再将 PN 翻转, 就得到了正确的结果.
+```python
+class Solution:
+    """
+    @param expression: A string array
+    @return: The Polish notation of this expression
+    """
+    def convertToPN(self, expression):
+        stk = []
+        PN = []
+        for s in expression[::-1]:
+            if s == ')':
+                stk.append(s)
+            elif s == '(':
+                pos = stk[::-1].index(')')
+                PN += stk[::-1][:pos]
+                stk = stk[:-pos-1]
+            elif s[0] in '1234567890':
+                PN.append(s)
+            else:
+                priority = self.getPriority(s)
+                while len(stk) and self.getPriority(stk[-1]) > priority:
+                    PN.append(stk[-1])
+                    stk.pop()
+                stk.append(s)
+        PN += stk[::-1]
+        return PN[::-1]
+    
+    def getPriority(self, s):
+        if s in '*/':
+            return 3 
+        if s in '+-':
+            return 2 
+        if s in '()':
+            return 1 
+        return 0
+
+# 解法 2
+class Solution:
+    # @param m: An integer m denotes the size of a backpack
+    # @param A: Given n items with size A[i]
+    def opOrder(self, op1, op2):
+        order_dic = {'*': 4, '/': 4, '+': 3, '-': 3}
+        if op1 == '(' or op2 == '(':
+            return False
+        elif op2 == ')':
+            return True
+        else:
+            if order_dic[op1] <= order_dic[op2]:
+                return False
+            else:
+                return True
+
+    def convertToPN(self, expression):
+        prefix = []
+        stack = []
+        string_tmp = []
+        for s in expression[::-1]:
+            if s == '(':
+                string_tmp.append(')')
+            elif s == ')':
+                string_tmp.append('(')
+            else:
+                string_tmp.append(s)
+
+        for s in string_tmp:
+            if s.isdigit():
+                prefix = [s] + prefix
+            else:
+                while len(stack) and self.opOrder(stack[-1], s):
+                    op = stack.pop()
+                    prefix = [op] + prefix
+                if len(stack) == 0 or s != ')':
+                    stack.append(s)
+                else:
+                    stack.pop()
+        if len(stack):
+            prefix = stack + prefix
+
+        return prefix
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/convert-expression-to-reverse-polish-notation.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/convert-expression-to-reverse-polish-notation.md"
new file mode 100644
index 0000000..dddb51a
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/convert-expression-to-reverse-polish-notation.md"
@@ -0,0 +1,74 @@
+# 将表达式转换为逆波兰表达式
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-expression-to-reverse-polish-notation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串数组，它代表一个表达式，返回该表达式的逆波兰表达式。（去掉括号）
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: ["3", "-", "4", "+", "5"]
+输出: ["3", "4", "-", "5", "+"]
+解释: 3 - 4 + 5 = -1 + 5 = 4
+    3 4 - 5 + = -1 5 + = 4
+```
+
+**样例 2:**
+
+```
+输入: ["(", "5", "-", "6", ")", "*", "7"]
+输出: ["5","6","-","7","*"]
+解释: (5 - 6) * 7 = -1 * 7 = -7
+    5 6 - 7 * = -1 7 * = -7
+```
+ ### 参考代码
+ 借助 **栈** 我们可以实现中缀表达式到后缀表达式(即逆波兰表达式, RPN)的转换.
+
+从左到右遍历中缀表达式:
+
+1. 如果碰到 **数字**, 直接追加到 RPN 末尾.
+2. 如果碰到 **左括号**, 入栈
+3. 如果碰到 **右括号**, 弹栈, 并将弹出的元素依次追加到 RPN 末尾, 直至左括号弹出(左括号不追加至PN)
+4. 如果碰到 **运算符**, 弹栈直至栈顶元素优先级 **小于** 当前运算符, 所有弹出的元素依次追加到 RPN 末尾, 最后再将该运算符入栈
+
+出于方便, 我们设定所有元素的优先级: `*/` 最高, `+-` 次之, 然后是数字, 最后是括号.
+
+(把括号设为最低是因为, 碰到运算符弹栈时, 遇到括号也要停止, 所以可以直接设为最低)
+
+最后, 如果栈还有剩余, 弹栈, 依次追加到 RPN 末尾, 然后我们就得到了正确结果 RPN.
+```python
+class Solution:
+    """
+    @param expression: A string array
+    @return: The Reverse Polish notation of this expression
+    """
+    def convertToRPN(self, expression):
+        stk = []
+        RPN = []
+        for s in expression:
+            if s == '(':
+                stk.append(s)
+            elif s == ')':
+                pos = stk[::-1].index('(')
+                RPN += stk[::-1][:pos]
+                stk = stk[:-pos-1]
+            elif s[0] in '1234567890':
+                RPN.append(s)
+            else:
+                priority = self.getPriority(s)
+                while len(stk) and self.getPriority(stk[-1]) >= priority:
+                    RPN.append(stk[-1])
+                    stk.pop()
+                stk.append(s)
+        RPN += stk[::-1]
+        return RPN
+    
+    def getPriority(self, s):
+        if s in '*/':
+            return 3 
+        if s in '+-':
+            return 2 
+        if s in '()':
+            return 1 
+        return 0
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/evaluate-reverse-polish-notation.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/evaluate-reverse-polish-notation.md"
new file mode 100644
index 0000000..3be93a7
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/evaluate-reverse-polish-notation.md"
@@ -0,0 +1,59 @@
+# 逆波兰表达式求值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/evaluate-reverse-polish-notation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 求[逆波兰表达式](https://zh.wikipedia.org/zh-hans/%E9%80%86%E6%B3%A2%E5%85%B0%E8%A1%A8%E7%A4%BA%E6%B3%95)的值。
+
+在逆波兰表达法中，其有效的运算符号包括 `+`, `-`, `*`, `/` 。每个运算对象可以是**整数**，也可以是另一个逆波兰计数表达。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: ["2", "1", "+", "3", "*"] 
+输出: 9
+解释: ["2", "1", "+", "3", "*"] -> (2 + 1) * 3 -> 9
+```
+
+**样例 2:**
+
+```
+输入: ["4", "13", "5", "/", "+"]
+输出: 6
+解释: ["4", "13", "5", "/", "+"] -> 4 + 13 / 5 -> 6
+```
+ ### 参考代码
+ 逆波兰表达式是更利于计算机运算的表达式形式, 需要用到栈(先进后出的数据结构).
+
+遍历表达式:
+
+- 碰到数字则入栈
+- 碰到运算符则连续从栈中取出2个元素, 使用该运算符运算然后将结果入栈
+
+最后栈中剩余一个数字, 就是结果.
+```java
+public class Solution {
+    public int evalRPN(String[] tokens) {
+        Stack<Integer> s = new Stack<Integer>();
+        String operators = "+-*/";
+        for (String token : tokens) {
+            if (!operators.contains(token)) {
+                s.push(Integer.valueOf(token));
+                continue;
+            }
+
+            int a = s.pop();
+            int b = s.pop();
+            if (token.equals("+")) {
+                s.push(b + a);
+            } else if(token.equals("-")) {
+                s.push(b - a);
+            } else if(token.equals("*")) {
+                s.push(b * a);
+            } else {
+                s.push(b / a);
+            }
+        }
+        return s.pop();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/expression-tree-build.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/expression-tree-build.md"
new file mode 100644
index 0000000..d3c3f2f
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/expression-tree-build.md"
@@ -0,0 +1,212 @@
+# 表达树构造
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/expression-tree-build/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 表达树是一个二叉树的结构，用于衡量特定的表达。所有表达树的叶子都有一个数字字符串值。而所有表达树的非叶子都有另一个操作字符串值。
+
+给定一个表达数组，请构造该表达的表达树，并返回该表达树的根。
+ ### 样例说明
+ **样例 1:**
+```
+输入: ["2","*","6","-","(","23","+","7",")","/","(","1","+","2",")"]
+输出: {[-],[*],[/],[2],[6],[+],[+],#,#,#,#,[23],[7],[1],[2]} 
+解释:
+其表达树如下：
+
+	                 [ - ]
+	             /          \
+	        [ * ]              [ / ]
+	      /     \           /         \
+	    [ 2 ]  [ 6 ]      [ + ]        [ + ]
+	                     /    \       /      \
+	                   [ 23 ][ 7 ] [ 1 ]   [ 2 ] .
+
+在构造该表达树后，你只需返回根节点`[-]`。
+```
+
+**样例 2:**
+```
+输入: ["10","+","(","3","-","5",")","+","7","*","7","-","2"]
+输出: {[-],[+],[2],[+],[*],#,#,[10],[-],[7],[7],#,#,[3],[5]}
+解释:
+其表达树如下：
+ 	                       [ - ]
+	                   /          \
+	               [ + ]          [ 2 ]
+	           /          \      
+	       [ + ]          [ * ]
+              /     \         /     \
+	  [ 10 ]  [ - ]    [ 7 ]   [ 7 ]
+	          /    \ 
+                [3]    [5]
+在构造该表达树后，你只需返回根节点`[-]`。
+```
+
+ ### 参考代码
+ 根据运算符的优先级来构造单调递增栈，最后弹出栈中元素，最后一个就是根节点，返回即可。
+```java
+// version 1
+/**
+ * Definition of ExpressionTreeNode:
+ * public class ExpressionTreeNode {
+ *     public String symbol;
+ *     public ExpressionTreeNode left, right;
+ *     public ExpressionTreeNode(String symbol) {
+ *         this.symbol = symbol;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+
+public class Solution {
+    class TreeNode {
+        int val;
+        ExpressionTreeNode eNode;
+        public TreeNode(int val, String s) {
+            this.val = val;
+            eNode = new ExpressionTreeNode(s);
+        }
+    }
+    /**
+     * @param expression: A string array
+     * @return: The root of expression tree
+     */
+    public ExpressionTreeNode build(String[] expression) {
+        if (expression == null || expression.length == 0) {
+            return null;
+        }
+        Stack<TreeNode> stack = new Stack<TreeNode>();
+        int base = 0;
+        int val = 0;
+
+        for (int i = 0; i < expression.length; i++) {
+            if (expression[i].equals("(")) {
+                base += 10;
+                continue;
+            }
+            if (expression[i].equals(")")) {
+                base -= 10;
+                continue;
+            }
+            val = getWeight(base, expression[i]);
+            TreeNode node = new TreeNode(val, expression[i]);
+            while (!stack.isEmpty() && node.val <= stack.peek().val) {
+                node.eNode.left = stack.pop().eNode;
+            }
+            if (!stack.isEmpty()) {
+                stack.peek().eNode.right = node.eNode;
+            }
+            stack.push(node);
+        }
+        if (stack.isEmpty()) {
+            return null;
+        }
+        TreeNode rst = stack.pop();
+        while (!stack.isEmpty()) {
+            rst = stack.pop();
+        }
+        return rst.eNode;
+    }
+    //Calculate weight for characters
+    public int getWeight(int base, String s) {
+        if (s.equals("+") || s.equals("-")) {
+            return base + 1;
+        }
+        if (s.equals("*") || s.equals("/")) {
+            return base + 2;
+        }
+        return Integer.MAX_VALUE;
+    }
+}
+
+// version 2
+/**
+ * Definition of ExpressionTreeNode:
+ * public class ExpressionTreeNode {
+ *     public String symbol;
+ *     public ExpressionTreeNode left, right;
+ *     public ExpressionTreeNode(rooting symbol) {
+ *         this.symbol = symbol;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+class TreeNode {
+	public int val;
+	public String s;
+	public ExpressionTreeNode root; 
+
+	public TreeNode(int val, String ss) {
+		this.val = val;
+		this.root = new ExpressionTreeNode(ss);
+	}
+
+}
+
+public class Solution {
+
+	int get(String a, Integer base) {
+		if (a.equals("+") || a.equals("-"))
+			return 1 + base;
+		if (a.equals("*") || a.equals("/"))
+			return 2 + base;
+
+		return Integer.MAX_VALUE;
+	}
+
+
+
+	public ExpressionTreeNode build(String[] expression) {
+		// write your code here
+		Stack<TreeNode> stack = new Stack<TreeNode>();
+		TreeNode root = null;
+		int val = 0;
+		Integer base = 0;
+		for (int i = 0; i <= expression.length; i++) {
+			if(i != expression.length)
+			{
+				
+				if (expression[i].equals("(")) {
+					base += 10;
+					continue;
+				}
+				if (expression[i].equals(")")) {
+					base -= 10;
+					continue;
+				}
+				val = get(expression[i], base);
+
+			}
+			TreeNode right = i == expression.length ? new TreeNode(
+					Integer.MIN_VALUE, "") : new TreeNode(val,
+					expression[i]);
+			while (!stack.isEmpty()) {
+				if (right.val <= stack.peek().val) {
+					TreeNode nodeNow = stack.pop();
+
+					if (stack.isEmpty()) {
+						right.root.left = nodeNow.root;
+
+					} else {
+						TreeNode left = stack.peek();
+						if (left.val < right.val) {
+							right.root.left = nodeNow.root;
+						} else {
+							left.root.right = nodeNow.root;
+						}
+					}
+				} else {
+					break;
+				}
+			}
+			stack.push(right);
+		}
+
+	
+		
+		return stack.peek().root.left;
+	}
+
+
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/implement-three-stacks-by-single-array.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/implement-three-stacks-by-single-array.md"
new file mode 100644
index 0000000..ece6429
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/implement-three-stacks-by-single-array.md"
@@ -0,0 +1,126 @@
+# 用一个数组实现三个栈
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/implement-three-stacks-by-single-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 用一个数组实现三个栈。你可以假设这三个栈都一样大并且足够大。你不需要担心如果一个栈满了之后怎么办。
+ ### 样例说明
+ ```
+ThreeStacks(5)  // create 3 stacks with size 5 in single array. stack index from 0 to 2
+push(0, 10) // push 10 in the 1st stack.
+push(0, 11)
+push(1, 20) // push 20 in the 2nd stack.
+push(1, 21)
+pop(0) // return 11
+pop(1) // return 21
+peek(1) // return 20
+push(2, 30)  // push 30 in the 3rd stack.
+pop(2) // return 30
+isEmpty(2) // return true
+isEmpty(0) // return false
+```
+ ### 参考代码
+ ```java
+public class ThreeStacks {
+    public int stackSize;
+    public int indexUsed;
+    public int[] stackPointer;
+    public StackNode[] buffer;
+
+    public ThreeStacks(int size) {
+        // do intialization if necessary
+        stackSize = size;
+        stackPointer = new int[3];
+        for (int i = 0; i < 3; ++i)
+            stackPointer[i] = -1;
+        indexUsed = 0;
+        buffer = new StackNode[stackSize * 3];
+    }
+
+    public void push(int stackNum, int value) {
+        // Write your code here
+        // Push value into stackNum stack
+        int lastIndex = stackPointer[stackNum];
+	    stackPointer[stackNum] = indexUsed;
+        indexUsed++;
+        buffer[stackPointer[stackNum]] = new StackNode(lastIndex, value, -1);
+    }
+    
+    public int pop(int stackNum) {
+        // Write your code here
+        // Pop and return the top element from stackNum stack
+        int value = buffer[stackPointer[stackNum]].value;
+        int lastIndex = stackPointer[stackNum];
+        if (lastIndex != indexUsed - 1)
+            swap(lastIndex, indexUsed - 1, stackNum);
+
+        stackPointer[stackNum] = buffer[stackPointer[stackNum]].prev;
+        if (stackPointer[stackNum] != -1)
+            buffer[stackPointer[stackNum]].next = -1;
+
+        buffer[indexUsed-1] = null;
+        indexUsed --;
+        return value;
+    }
+
+    public int peek(int stackNum) {
+        // Write your code here
+        // Return the top element
+        return buffer[stackPointer[stackNum]].value;
+    }
+
+    public boolean isEmpty(int stackNum) {
+        // Write your code here
+        return stackPointer[stackNum] == -1;
+    }
+
+    public void swap(int lastIndex, int topIndex, int stackNum) {
+        if (buffer[lastIndex].prev == topIndex) {
+            int tmp = buffer[lastIndex].value;
+            buffer[lastIndex].value = buffer[topIndex].value;
+            buffer[topIndex].value = tmp;
+            int tp = buffer[topIndex].prev;
+            if (tp != -1) {
+                buffer[tp].next = lastIndex;
+            }
+            buffer[lastIndex].prev = tp;
+            buffer[lastIndex].next = topIndex;
+            buffer[topIndex].prev = lastIndex;
+            buffer[topIndex].next = -1;
+            stackPointer[stackNum] = topIndex;
+            return;
+        }
+
+        int lp = buffer[lastIndex].prev;
+        if (lp != -1)
+            buffer[lp].next = topIndex;
+        
+        int tp = buffer[topIndex].prev;
+        if (tp != -1)
+            buffer[tp].next = lastIndex;
+
+        int tn = buffer[topIndex].next;
+        if (tn != -1)
+            buffer[tn].prev = lastIndex;
+        else {
+            for (int i = 0; i < 3; ++i)
+                if (stackPointer[i] == topIndex)
+                    stackPointer[i] = lastIndex;
+        }
+
+        StackNode tmp = buffer[lastIndex];
+        buffer[lastIndex] = buffer[topIndex];
+        buffer[topIndex] = tmp;
+        stackPointer[stackNum] = topIndex;
+    }
+}
+
+class StackNode {
+    public int prev, next;
+    public int value;
+    public StackNode(int p, int v, int n) {	
+        value = v;
+        prev = p;
+        next = n;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/kth-smallest-sum-in-two-sorted-arrays.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/kth-smallest-sum-in-two-sorted-arrays.md"
new file mode 100644
index 0000000..65d5444
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/kth-smallest-sum-in-two-sorted-arrays.md"
@@ -0,0 +1,168 @@
+# 两个排序数组和的第K小
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-smallest-sum-in-two-sorted-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个排好序的数组 *A*, *B*，定义集合 *sum* = *a* + *b* ，其中a来自A数组，b来自B数组，求 *sum* 中第k小的元素
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+a = [1, 7, 11]
+b = [2, 4, 6]
+k = 3
+输出: 7
+说明: 满足条件的所有的和有[3, 5, 7, 9, 11, 13, 13, 15, 17]，其中第三个是7.
+```
+
+**样例2**
+
+```plain
+输入:
+a = [1, 7, 11]
+b = [2, 4, 6]
+k = 4
+输出: 9
+说明: 满足条件的所有的和有[3, 5, 7, 9, 11, 13, 13, 15, 17]，其中第四个是9.
+```
+
+**样例3**
+
+```plain
+输入:
+a = [1, 7, 11]
+b = [2, 4, 6]
+k = 8
+输出: 15
+说明: 满足条件的所有的和有[3, 5, 7, 9, 11, 13, 13, 15, 17]，其中第八个是15.
+```
+
+
+ ### 参考代码
+ 类似于 Kth smallest in sorted matrix 一题。
+使用 heapq
+我们把行和列分别定为两个数组，就可以形成一个排好序的矩阵
+```java
+// 方法一
+class Pair {
+    public int x, y, sum;
+    public Pair(int x, int y, int val) {
+        this.x = x;
+        this.y = y;
+        this.sum = val;
+    }
+}
+class PairComparator implements Comparator<Pair> {
+    public int compare(Pair a, Pair b) {
+        return a.sum - b.sum;
+    }
+}
+
+public class Solution {
+    /**
+     * @param A an integer arrays sorted in ascending order
+     * @param B an integer arrays sorted in ascending order
+     * @param k an integer
+     * @return an integer
+     */
+    public int kthSmallestSum(int[] A, int[] B, int k) {
+        int[] dx = new int[]{0, 1};
+        int[] dy = new int[]{1, 0};
+        boolean[][] hash = new boolean[A.length][B.length];
+        PriorityQueue<Pair> minHeap = new PriorityQueue<Pair>(k, new PairComparator());
+        minHeap.add(new Pair(0, 0, A[0] + B[0]));
+
+        for(int i = 0; i < k - 1; i ++){
+            Pair cur = minHeap.poll();
+            for(int j = 0; j < 2; j ++){
+                int next_x = cur.x + dx[j];
+                int next_y = cur.y + dy[j];
+                Pair next_Pair = new Pair(next_x, next_y, 0);
+                if(next_x < A.length && next_y < B.length &&  !hash[next_x][next_y]){
+                    hash[next_x][next_y] = true;
+                    next_Pair.sum = A[next_x] + B[next_y];
+                    minHeap.add(next_Pair);
+                }
+            }
+        }
+        return minHeap.peek().sum;
+    }
+}
+
+//方法二:
+class Pair implements Comparable<Pair> {
+    int x;
+    int y;
+    int sum;
+    Pair(int x, int y, int sum) {
+        this.x = x;
+        this.y = y;
+        this.sum = sum;
+    }
+    @Override
+    public int compareTo(Pair another) {
+        if (this.sum == another.sum) {
+            return 0;
+        }
+        return this.sum < another.sum ? -1 : 1;
+    }
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        } else if (!(obj instanceof Pair)) {
+            return false;
+        }
+        Pair another = (Pair) obj;
+        return this.x == another.x && this.y == another.y;
+    }
+    @Override
+    public int hashCode() {
+        return x * 101 + y;
+    }
+}
+public class Solution {
+    /**
+     * @param A an integer arrays sorted in ascending order
+     * @param B an integer arrays sorted in ascending order
+     * @param k an integer
+     * @return an integer
+     */
+    int[] dx = {1, 0};
+    int[] dy = {0, 1};
+    public int kthSmallestSum(int[] A, int[] B, int k) {
+        if (A.length == 0 && B.length == 0) {
+            return 0; 
+        } else if (A.length == 0) {
+            return B[k];
+        } else if (B.length == 0) {
+            return A[k];
+        }
+        HashSet<Pair> isVisited = new HashSet<Pair>();
+        PriorityQueue<Pair> minHeap = new PriorityQueue<Pair>();
+        Pair p;
+        Pair nextP;
+        p = new Pair(0, 0, A[0] + B[0]);
+        minHeap.offer(p);
+        isVisited.add(p);
+        int nextX;
+        int nextY;
+        int nextSum;
+        for (int count = 0; count < k - 1; count++) {
+            p = minHeap.poll();
+            for (int i = 0; i < 2; i++) {
+                nextX = p.x + dx[i];
+                nextY = p.y + dy[i];
+                nextP = new Pair(nextX, nextY, 0);
+                if (nextX >= 0 && nextX < A.length && nextY >= 0 && nextY < B.length && !isVisited.contains(nextP)) {
+                    nextSum = A[nextX] + B[nextY];
+                    nextP.sum = nextSum;
+                    minHeap.offer(nextP);
+                    isVisited.add(nextP);
+                }
+            }
+        }
+        return minHeap.peek().sum;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/largest-rectangle-in-histogram.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/largest-rectangle-in-histogram.md"
new file mode 100644
index 0000000..d1b8a91
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/largest-rectangle-in-histogram.md"
@@ -0,0 +1,53 @@
+# 直方图最大矩形覆盖
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/largest-rectangle-in-histogram/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出的n个非负整数表示每个直方图的高度，每个直方图的宽均为1，在直方图中找到最大的矩形面积。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[2,1,5,6,2,3]
+输出：10
+解释：
+第三个和第四个直方图截取矩形面积为2*5=10。
+```
+
+**样例 2:**
+```
+输入：[1,1]
+输出：2
+解释：
+第一个和第二个直方图截取矩形面积为2*1=2。
+```
+ ### 参考代码
+ 考点：
+* 单调栈
+
+题解：
+用九章算法强化班中讲过的单调栈(stack)。维护一个单调递增栈，逐个将元素 push 到栈里。push 进去之前先把 >= 自己的元素 pop 出来。
+每次从栈中 pop 出一个数的时候，就找到了往左数比它小的第一个数（当前栈顶）和往右数比它小的第一个数（即将入栈的数），
+从而可以计算出这两个数中间的部分宽度 * 被pop出的数，就是以这个被pop出来的数为最低的那个直方向两边展开的最大矩阵面积。
+因为要计算两个数中间的宽度，因此放在 stack 里的是每个数的下标。
+```java
+public class Solution {
+    public int largestRectangleArea(int[] height) {
+        if (height == null || height.length == 0) {
+            return 0;
+        }
+        
+        Stack<Integer> stack = new Stack<Integer>();  //维护单调递增
+        int max = 0;
+        for (int i = 0; i <= height.length; i++) {
+            int curt = (i == height.length) ? -1 : height[i];
+            while (!stack.isEmpty() && curt <= height[stack.peek()]) {	//如果栈顶高度大于当前高度	            
+                int h = height[stack.pop()];		//保存栈顶元素信息
+                int w = stack.isEmpty() ? i : i - stack.peek() - 1;		//如果栈已经为空，宽度为i，否则i-s.top()-1
+                max = Math.max(max, h * w);
+            }
+            stack.push(i);				//压入栈中
+        }
+        
+        return max;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/longest-valid-parentheses.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/longest-valid-parentheses.md"
new file mode 100644
index 0000000..6a412c3
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/longest-valid-parentheses.md"
@@ -0,0 +1,75 @@
+# 最长有效括号
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-valid-parentheses/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 30px;">给出一个只包含</span><code style="font-size: 12.6000003814697px; white-space: normal; line-height: 30px;">'('</code><span style="line-height: 30px;">&nbsp;和</span><code style="font-size: 12.6000003814697px; white-space: normal; line-height: 30px;">')'</code><span style="line-height: 30px;">的字符串，找出其中最长的左右括号正确匹配的合法子串。</span><br></p>
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "(()"
+输出: 2
+解释: 最长有效括号子串为 "()"
+```
+
+**样例 2:**
+
+```
+输入: ")()())"
+输出: 4
+解释: 最长有效括号子串为 "()()"
+```
+ ### 参考代码
+ Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.&nbsp;<div><br></div><div>&nbsp;For "(()", the longest valid parentheses substring is "()", which has length = 2.&nbsp;</div><div><br></div><div>&nbsp;Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.</div><div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博:&nbsp;</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/Bxp24fkup" target="_blank">http://weibo.com/3948019741/Bxp24fkup</a></span></font><br></div>
+
+考点：
+* 栈
+* dp
+
+题解：
+
+1.遍历给字符串中的所有字符
+1.1若当前字符s[index]为左括号'('，将当前字符下标index入栈（下标稍后有其他用处），处理下一字符
+1.2若当前字符s[index]为右括号')'，判断当前栈是否为空
+1.2.1若栈为空，则accumulatedLen = 0，当前有效长度为0，处理下一字符（当前字符右括号下标不入栈）
+1.2.2若栈不为空，则出栈（由于仅左括号入栈，则出栈元素对应的字符一定为左括号，可与当前字符右括号配对），判断栈是否为空
+1.2.2.1若栈为空，则maxlen = max(maxlen, index-start+1)，更新当前最大匹配序列长度
+1.2.2.2若栈不为空，则maxlen = max(maxlen, i-栈顶元素值)，更新当前最大匹配序列长度
+```java
+public class Solution {
+    public int longestValidParentheses(String s) {
+
+        if (s == null) {
+            return 0;
+        }
+
+        Stack<Integer> stack = new Stack<Integer>();
+        int maxLen = 0;
+        int accumulatedLen = 0;
+
+        for(int i = 0; i < s.length(); i++) {
+            if (s.charAt(i) == '(') {
+                stack.push(i);
+            } else {
+                if (stack.isEmpty()) {   //如果栈为空，没有左括号可以匹配
+                    accumulatedLen = 0;
+                } else {
+                    int matchedPos = stack.pop(); //从最近的'('作为起点
+                    int matchedLen = i - matchedPos + 1;	//计算两括号间的长度
+
+                    if (stack.isEmpty()) {			//如果栈为空，没有左括号可以匹配
+                        accumulatedLen += matchedLen;	
+                        matchedLen = accumulatedLen;	//更新当前匹配括号序列长度
+                    } else {
+                        matchedLen = i - stack.peek();  
+                    }
+
+                    maxLen = Math.max(maxLen, matchedLen);
+                }
+            }
+        }
+
+        return maxLen;
+   }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/max-stack.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/max-stack.md"
new file mode 100644
index 0000000..975f449
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/max-stack.md"
@@ -0,0 +1,68 @@
+# 最大栈
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/max-stack/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个支持push，pop，top，peekMax和popMax操作的最大栈。
+
+1. push(x) -- 将元素x添加到栈中。
+2. pop() -- 删除栈中最顶端的元素并将其返回。
+3. top() -- 返回栈中最顶端的元素。
+4. peekMax() -- 返回栈中最大的元素。
+5. popMax() -- 返回栈中最大的元素，并将其删除。如果有多于一个最大的元素，只删除最靠近顶端的一个元素。
+ ### 样例说明
+ ```
+输入:
+push(5)
+push(1)
+push(5)
+top()
+popMax()
+top()
+peekMax()
+pop()
+top()
+输出:
+5
+5
+1
+5
+1
+5
+```
+ ### 参考代码
+ ```python
+class MaxStack:
+
+    def __init__(self):
+        self.stack = []
+        self.max_stack = []
+        
+    def push(self, x):
+        self.stack.append(x)
+        if self.max_stack:
+            number = max(self.max_stack[-1], x)
+            self.max_stack.append(number)
+        else:
+            self.max_stack.append(x)
+
+    def pop(self):
+        self.max_stack.pop()
+        return self.stack.pop()
+
+    def top(self):
+        return self.stack[-1]
+
+    def peekMax(self):
+        return self.max_stack[-1]
+
+    def popMax(self):
+        max_number = self.peekMax()
+        buffer_stack = []
+        while self.top() != max_number:
+            buffer_stack.append(self.pop())
+        self.pop()
+        while buffer_stack:
+            self.push(buffer_stack[-1])
+            buffer_stack.pop()
+        return max_number
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/max-tree.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/max-tree.md"
new file mode 100644
index 0000000..9a36960
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/max-tree.md"
@@ -0,0 +1,74 @@
+# 最大树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/max-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个没有重复的整数数组，在此数组上建立最大树的定义如下：
+
+- 根是数组中最大的数
+- 左子树和右子树元素分别是被父节点元素切分开的子数组中的最大值
+
+利用给定的数组构造最大树。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[2, 5, 6, 0, 3, 1]
+输出：{6,5,3,2,#,0,1}
+解释：
+此数组构造的最大树是：
+```
+        6
+       / \
+      5   3
+     /   / \
+    2   0   1
+```
+```
+**样例 2:**
+```
+输入：[6,4,20]
+输出：{20,6,#,#,4}
+解释：
+     20
+     / 
+    6
+     \
+      4
+
+```
+ ### 参考代码
+ 使用九章算法强化班中讲到的单调栈。保存一个单调递减栈。每个数从栈中被 pop 出的时候，就知道它往左和往右的第一个比他大的数的位置了。
+时间复杂度 $O(n)$，而暴力算法最坏情况下会有 $O(n^2)$
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param A: Given an integer array with no duplicates.
+    @return: The root of max tree.
+    """
+    def maxTree(self, A):
+        if not A:
+            return None
+            
+        nodes = [TreeNode(num) for num in A + [sys.maxsize]]
+        stack = []
+        for index, num in enumerate(A + [sys.maxsize]):
+            while stack and A[stack[-1]] < num:
+                top = stack.pop()
+                left = A[stack[-1]] if stack else sys.maxsize
+                if left < num:
+                    nodes[stack[-1]].right = nodes[top]
+                else:
+                    nodes[index].left = nodes[top]
+            
+            stack.append(index)
+
+        # sys.maxsize 's left child is the maximum number
+        return nodes[-1].left
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/meeting-rooms.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/meeting-rooms.md"
new file mode 100644
index 0000000..df03064
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/meeting-rooms.md"
@@ -0,0 +1,48 @@
+# 会议室
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/meeting-rooms/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一系列的会议时间间隔，包括起始和结束时间[[s1,e1]，[s2,e2]，…(si < ei)，确定一个人是否可以参加所有会议。
+ ### 样例说明
+ **样例1**
+
+```
+输入: intervals = [(0,30),(5,10),(15,20)]
+输出: false
+解释:
+(0,30), (5,10) 和 (0,30),(15,20) 这两对会议会冲突
+```
+
+**样例2**
+
+```
+输入: intervals = [(5,8),(9,15)]
+输出: true
+解释:
+这两个时间段不会冲突
+```
+
+
+
+
+ ### 参考代码
+ ```java
+public class Solution {
+    public boolean canAttendMeetings(Interval[] intervals) {
+        if(intervals == null || intervals.length == 0) return true;
+        Arrays.sort(intervals, new Comparator<Interval>(){
+            public int compare(Interval i1, Interval i2){
+                return i1.start - i2.start;
+            }
+        });
+        int end = intervals[0].end;
+        for(int i = 1; i < intervals.length; i++){
+            if(intervals[i].start < end) {
+                return false;
+            }
+            end = Math.max(end, intervals[i].end);
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/min-stack.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/min-stack.md"
new file mode 100644
index 0000000..b880b6d
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/min-stack.md"
@@ -0,0 +1,96 @@
+# 带最小值操作的栈
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/min-stack/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个栈, 支持以下操作:
+
+- `push(val)` 将 val 压入栈
+- `pop()` 将栈顶元素弹出, 并返回这个弹出的元素
+- `min()` 返回栈中元素的最小值 
+
+要求 O(1) 开销.
+ ### 样例说明
+ **样例 2:**
+
+```
+输入: 
+  push(1)
+  min()
+  push(2)
+  min()
+  push(3)
+  min()
+输出: 
+  1
+  1
+  1
+```
+ ### 参考代码
+ 使用两个仅支持 `pop` 和 `push` 的栈就可以完成, `stack` 储存压入的数据, `minStack` 储存最小值.
+
+- `push` 直接把元素压入 stack, 对于 minStack, 如果它为空则直接压入, 反之压入当前元素与 minStack 栈顶的最小值
+- `pop` 两个栈都弹出一个元素, 返回 stack 弹出的元素
+- `min` 返回 minStack 的栈顶
+
+> 还可以令 minStack 为单调栈, 即`push`时只有元素更小的时候才放入这个栈, 而`pop`时只有栈顶与stack栈顶相同时才弹出
+> 
+> 这样可以节约一定的空间, 但是实质上空间复杂度仍然是 O(n), 且多了一些判断, 并不一定更优
+```java
+// version 1:
+public class MinStack {
+    private Stack<Integer> stack;
+    private Stack<Integer> minStack;
+    
+    public MinStack() {
+        stack = new Stack<Integer>();
+        minStack = new Stack<Integer>();
+    }
+
+    public void push(int number) {
+        stack.push(number);
+        if (minStack.isEmpty()) {
+            minStack.push(number);
+        } else {
+            minStack.push(Math.min(number, minStack.peek()));
+        }
+    }
+
+    public int pop() {
+        minStack.pop();
+        return stack.pop();
+    }
+
+    public int min() {
+        return minStack.peek();
+    }
+}
+
+// version 2, save more space. but space complexity doesn't change.
+public class MinStack {
+    private Stack<Integer> stack;
+    private Stack<Integer> minStack;
+
+    public MinStack() {
+        stack = new Stack<Integer>();
+        minStack = new Stack<Integer>();
+    }
+
+    public void push(int number) {
+        stack.push(number);
+        if (minStack.empty() == true)
+            minStack.push(number);
+        else if (minStack.peek() >= number) // 这里考虑的相等的情况也会继续push
+            minStack.push(number);
+    }
+
+    public int pop() {
+        if (stack.peek().equals(minStack.peek()))
+            minStack.pop();
+        return stack.pop();
+    }
+
+    public int min() {
+        return minStack.peek();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/mock-hanoi-tower-by-stacks.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/mock-hanoi-tower-by-stacks.md"
new file mode 100644
index 0000000..be65270
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/mock-hanoi-tower-by-stacks.md"
@@ -0,0 +1,89 @@
+# 用栈模拟汉诺塔问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/mock-hanoi-tower-by-stacks/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在经典的汉诺塔问题中，有 3 个塔和 N 个可用来堆砌成塔的不同大小的盘子。要求盘子必须按照从小到大的顺序从上往下堆 （如，任意一个盘子，其必须堆在比它大的盘子上面）。同时，你必须满足以下限制条件：
+
+(1) 每次只能移动一个盘子。
+(2) 每个盘子从堆的顶部被移动后，只能置放于下一个堆中。
+(3) 每个盘子只能放在比它大的盘子上面。
+
+请写一段程序，实现将第一个堆的盘子移动到最后一个堆中。
+
+
+ ### 样例说明
+ **样例1:**
+```plain
+输入: 3
+输出: 
+towers[0]: []
+towers[1]: []
+towers[2]: [2,1,0]
+```
+
+**样例2:**
+```plain
+输入: 10
+输出:
+towers[0]: []
+towers[1]: []
+towers[2]: [9,8,7,6,5,4,3,2,1,0]
+```
+ ### 参考代码
+ 汉诺塔问题的解决方案如下：
+- 以目标杆为中介，从起始杆将1至$n-1$号盘移至中间杆
+- 将起始杆里的第$n$号盘移动到目标杆
+- 以起始杆为中介，从中间杆将1至$n-1$号盘移至目标杆
+
+这一个流程形成了一个递归过程，而我们要做的就是要利用栈去模拟这一个过程。栈具有后进先出的性质，这个和汉诺塔里塔的移动是一样的。
+```java
+public class Tower {
+    private Stack<Integer> disks;
+    // create three towers (i from 0 to 2)
+    public Tower(int i) {
+        disks = new Stack<Integer>();
+    }
+	
+    // Add a disk into this tower
+    public void add(int d) {
+        if (!disks.isEmpty() && disks.peek() <= d) {
+            System.out.println("Error placing disk " + d);
+        } else {
+            disks.push(d);
+        }
+    }
+	
+    // @param t a tower
+    // Move the top disk of this tower to the top of t.
+    public void moveTopTo(Tower t) {
+        // Write your code here
+        int top = disks.pop();
+        t.add(top);
+    }
+	
+    // @param n an integer
+    // @param destination a tower
+    // @param buffer a tower
+    // Move n Disks from this tower to destination by buffer tower
+    public void moveDisks(int n, Tower destination, Tower buffer) {
+        // Write your code here
+        if (n > 0) {	
+            moveDisks(n - 1, buffer, destination); //// 以目标杆为中介，从起始杆将1至n-1号盘移至中间杆
+            moveTopTo(destination); //将起始杆里的第n号盘移动到目标杆
+            buffer.moveDisks(n - 1, destination, this); //以起始杆为中介，从中间杆将1至n-1号盘移至目标杆
+        }
+    }
+
+    public Stack<Integer> getDisks() {
+        return disks;
+    }
+}
+/**
+ * Your Tower object will be instantiated and called as such:
+ * Tower[] towers = new Tower[3];	
+ * for (int i = 0; i < 3; i++) towers[i] = new Tower(i);
+ * for (int i = n - 1; i >= 0; i--) towers[0].add(i);	
+ * towers[0].moveDisks(n, towers[2], towers[1]);
+ * print towers[0], towers[1], towers[2]
+*/
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/odd-even-jump.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/odd-even-jump.md"
new file mode 100644
index 0000000..a3294d5
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/odd-even-jump.md"
@@ -0,0 +1,367 @@
+# 奇偶跳
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/odd-even-jump/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组A。从某一些起始索引，你可以做一系列的跳跃。`其中的（第1，第3，第5 ......）跳跃称为奇数跳跃，（第2，第4，第6 ......）跳跃称为偶数跳跃`。
+
+你可以从索引` i ` 以下列方式跳转到索引 `j`（i <j）：
+
+在奇数跳跃（即跳跃1,3,5，...）期间，跳转到索引j，使得`A [i] <= A [j]`并且A [j]是可能的最小值。如果有多个这样的索引j，则只能跳转到最小的索引 j。 在偶数跳跃（即跳跃2,4,6，...）期间，跳转到索引j，使得`A [i]> = A [j]`，A [j]是最大的可能值。如果有多个这样的索引j，则只能跳转到最小的索引 j。（可能存在某些索引，不存在合法的跳跃）
+如果从该索引开始，您可以通过跳转一些次数（大于等于0次）到达数组的末尾（索引A.length - 1），那么这是一个有效的起始索引。
+
+返回有效的起始索引的个数
+
+ ### 样例说明
+ **样例 1:**
+```
+输入: [10,13,12,14,15]
+输出: 2
+解析: 
+从 index i = 0 开始，我们可以跳跃至 i = 2 (因为 A[2] 是 A[1], A[2], A[3], A[4] 中 >= A[0]最小的), 然后我们就无法再继续跳跃了
+从 i = 1 和 i = 2 开始, 我们可以跳跃至 i = 3, 然后无法再继续跳跃了
+从 i = 3 开始, 我们可以跳跃至 i = 4, 因此我们可以到达末尾
+从 i = 4 开始, 我们已经在末尾了
+综上, 有 2 个有效的索引 (i = 3, i = 4) 我们可以经过一系列的跳跃达到末尾
+```
+**样例 2:**
+```
+输入: [2,3,1,1,4]
+输出: 3
+解析: 
+从 i = 0 开始, 我们可以跳跃至 i = 1, i = 2, i = 3:
+
+在我们的第一次跳跃 (奇数跳), 我们先跳跃至 i = 1, 因为 A[1] 是 (A[1], A[2], A[3], A[4] >= A[0]) 当中最小的，
+
+在我们的第二次跳跃 (偶数跳), 我们从 i = 1 跳到 i = 2 因为 A[2] 是 (A[2], A[3], A[4] <= A[1])当中最大的.  A[3] 也是最大的, 但是 2 是更小的索引, 所以我们跳到 i = 2 而不是 i = 3.
+
+在我们的第三次跳跃 (奇数跳),我们从 i = 2 跳到 i = 3 因为 A[3] 是 (A[3], A[4] >= A[2])当中最小的
+
+我们不能从 i = 3 跳跃 i = 4, 因此起始索引 i = 0 是无效的
+
+根据同样的规则，我们可以求出：
+存在 3 个有效的起始索引 (i = 1, i = 3, i = 4) 我们可以跳跃至末尾
+```
+ ### 参考代码
+ 线段树建图+动态规划解法
+```
+[[python]]
+def get_max(pair_a, pair_b):
+    if pair_a[0] != pair_b[0]:
+        return max(pair_a, pair_b)
+    if pair_a[1] < pair_b[1]:
+        return pair_a
+    return pair_b
+    
+def get_min(pair_a, pair_b):
+    if pair_a[0] != pair_b[0]:
+        return min(pair_a, pair_b)
+    if pair_a[1] < pair_b[1]:
+        return pair_a
+    return pair_b
+
+class MySegmentTreeNode:
+    
+    def __init__(self, start, end):
+        self.start, self.end = start, end
+        self.max_val, self.min_val = (-float('inf'), -1), (float('inf'), -1)
+        self.left_child, self.right_child = None, None
+    
+    
+class MySegmentTree:
+    
+    def __init__(self, start, end):
+        self.range_start = start
+        self.range_end = end
+        self.root = self.build_tree(start, end)
+    
+    def build_tree(self, start, end):
+        node = MySegmentTreeNode(start, end)
+        if start == end:
+            return node
+            
+        node.left_child = self.build_tree(start, (start + end) // 2)
+        node.right_child = self.build_tree((start + end ) // 2 + 1, end)
+        return node
+    
+    def insert(self, index, val, node=None):
+        if node is None:
+            node = self.root
+        if node.start == index and node.end == index:
+            node.max_val = node.min_val = val
+            return
+        if index <= node.left_child.end:
+            self.insert(index, val, node.left_child)
+        else:
+            self.insert(index, val, node.right_child)
+        node.max_val = get_max(node.left_child.max_val, node.right_child.max_val)
+        node.min_val = get_min(node.left_child.min_val, node.right_child.min_val)
+    
+    def query_max(self, start, end, node=None):
+        if node is None:
+            node = self.root
+        if end < start:
+            return (-float('inf'), -1)
+        if node.start == start and node.end == end:
+            return node.max_val
+        if end <= node.left_child.end:
+            return self.query_max(start, end, node.left_child)
+        elif start >= node.right_child.start:
+            return self.query_max(start, end, node.right_child)
+        return get_max(
+            self.query_max(start, node.left_child.end, node.left_child),
+            self.query_max(node.right_child.start, end, node.right_child)
+        )
+        
+    def query_min(self, start, end, node=None):
+        if node is None:
+            node = self.root
+        if end < start:
+            return (float('inf'), -1)
+        if node.start == start and node.end == end:
+            return node.min_val
+        if end <= node.left_child.end:
+            return self.query_min(start, end, node.left_child)
+        elif start >= node.right_child.start:
+            return self.query_min(start, end, node.right_child)
+        return get_min(
+            self.query_min(start, node.left_child.end, node.left_child),
+            self.query_min(node.right_child.start, end, node.right_child)
+        )
+
+
+class Solution:
+    """
+    @param A: An integer array A
+    @return: Return the number of good starting indexes
+    """
+    def oddEvenJumps(self, A):
+        odd_jump, even_jump = self.get_jumps(A)
+
+        # dp = array of n x 2
+        # dp[i][0] can we jump to n - 1 when we arrive i by even jumps
+        # dp[i][1] can we jump to n - 1 when we arrive i by odd jumps
+        n = len(A)
+        dp = [[False, False] for _ in range(n)]
+        dp[n - 1][0] = dp[n - 1][1] = True
+        
+        answer = 1
+        for i in range(n - 2, -1, -1):
+            dp[i][0] = dp[odd_jump[i]][1] if odd_jump[i] != -1 else False
+            dp[i][1] = dp[even_jump[i]][0] if even_jump[i] != -1 else False
+            if dp[i][0] == True:
+                answer += 1
+        return answer
+        
+    def get_jumps(self, A):
+        import bisect
+        sorted_A = sorted(list(set(A)))
+        range_start = bisect.bisect(sorted_A, min(A))
+        range_end = bisect.bisect(sorted_A, max(A))
+        seg = MySegmentTree(range_start, range_end)
+
+        n = len(A)
+        even_jump = [-1] * n
+        odd_jump = [-1] * n
+        for i in range(n - 1, -1, -1):
+            val = bisect.bisect(sorted_A, A[i])
+            odd_jump[i] = seg.query_min(val, range_end)[1]
+            even_jump[i] = seg.query_max(range_start, val)[1]
+            seg.insert(val, (val, i))
+            
+        return odd_jump, even_jump
+[[java]]
+class Pair {
+    int value, index;
+    
+    Pair(int value, int index) {
+        this.value = value;
+        this.index = index;
+    }
+}
+
+class MySegmentTreeNode {
+    int start, end;
+    Pair maxValue, minValue;
+    MySegmentTreeNode leftChild, rightChild;
+    
+    MySegmentTreeNode(int start, int end) {
+        this.start = start;
+        this.end = end;
+        this.maxValue = new Pair(Integer.MIN_VALUE, -1);
+        this.minValue = new Pair(Integer.MAX_VALUE, -1);
+        this.leftChild = this.rightChild = null;
+    }
+}
+
+class MySegmentTree {
+    int rangeStart, rangeEnd;
+    MySegmentTreeNode root;
+    
+    MySegmentTree(int start, int end) {
+        rangeStart = start;
+        rangeEnd = end;
+        root = buildTree(start, end);
+    }
+    
+    private MySegmentTreeNode buildTree(int start, int end) {
+        MySegmentTreeNode node = new MySegmentTreeNode(start, end);
+        
+        if (start == end) {
+            return node;
+        }
+        
+        int middle = start + (end - start) / 2;
+        node.leftChild = buildTree(start, middle);
+        node.rightChild = buildTree(middle + 1, end);
+        
+        return node;
+    }
+    
+    public void insert(int index, Pair value) {
+        insert(index, value, this.root);
+    }
+    
+    private void insert(int index, Pair value, MySegmentTreeNode node) {
+        if (node.start == index && node.end == index) {
+            node.maxValue = node.minValue = value;
+            return;
+        }
+        if (index <= node.leftChild.end) {
+            insert(index, value, node.leftChild);
+        } else {
+            insert(index, value, node.rightChild);
+        }
+        
+        node.maxValue = getMax(node.leftChild.maxValue, node.rightChild.maxValue);
+        node.minValue = getMin(node.leftChild.minValue, node.rightChild.minValue);
+    }
+    
+    public Pair queryMax(int start, int end) {
+        return queryMax(start, end, this.root);
+    }
+    
+    private Pair queryMax(int start, int end, MySegmentTreeNode node) {
+        if (end < start) {
+            return new Pair(Integer.MIN_VALUE, -1);
+        }
+        if (node.start == start && node.end == end) {
+            return node.maxValue;
+        }
+        
+        if (end <= node.leftChild.end) {
+            return queryMax(start, end, node.leftChild);
+        } else if (start >= node.rightChild.start) {
+            return queryMax(start, end, node.rightChild);
+        }
+        
+        return getMax(
+            queryMax(start, node.leftChild.end, node.leftChild),
+            queryMax(node.rightChild.start, end, node.rightChild)
+        );
+    }
+    
+    public Pair queryMin(int start, int end) {
+        return queryMin(start, end, this.root);
+    }
+    
+    private Pair queryMin(int start, int end, MySegmentTreeNode node) {
+        if (end < start) {
+            return new Pair(Integer.MIN_VALUE, -1);
+        }
+        if (node.start == start && node.end == end) {
+            return node.minValue;
+        }
+        
+        if (end <= node.leftChild.end) {
+            return queryMin(start, end, node.leftChild);
+        } else if (start >= node.rightChild.start) {
+            return queryMin(start, end, node.rightChild);
+        }
+        
+        return getMin(
+            queryMin(start, node.leftChild.end, node.leftChild),
+            queryMin(node.rightChild.start, end, node.rightChild)
+        );
+    }
+    
+    private static Pair getMax(Pair pairA, Pair pairB) {
+        if (pairA.value != pairB.value) {
+            return pairA.value > pairB.value ? pairA : pairB;
+        }
+        
+        return pairA.index < pairB.index ? pairA : pairB;
+    }
+    
+    private static Pair getMin(Pair pairA, Pair pairB) {
+        if (pairA.value != pairB.value) {
+            return pairA.value < pairB.value ? pairA : pairB;
+        }
+        
+        return pairA.index < pairB.index ? pairA : pairB;
+    }
+}
+
+public class Solution {
+    /**
+     * @param A: An integer array A
+     * @return: Return the number of good starting indexes
+     */
+    public int oddEvenJumps(int[] A) {
+        int n = A.length;
+        int[] oddJump = new int[n];
+        int[] evenJump = new int[n];
+        getJumps(A, oddJump, evenJump);
+        
+        // dp = array of n x 2
+        // dp[i][0] can we jump to n - 1 when we arrive i by even jumps
+        // dp[i][1] can we jump to n - 1 when we arrive i by odd jumps
+        boolean[][] dp = new boolean[n][2];
+        for (int i = 0; i < n; i++) {
+            dp[i][0] = false;
+            dp[i][1] = false;
+        }
+        
+        dp[n - 1][0] = dp[n - 1][1] = true;
+        
+        int answer = 1;
+        for (int i = n - 2; i >= 0; i--) {
+            dp[i][0] = oddJump[i] != -1 ? dp[oddJump[i]][1] : false;
+            dp[i][1] = evenJump[i] != -1 ? dp[evenJump[i]][0] : false;
+            if (dp[i][0] == true) {
+                answer++;
+            }
+        }
+        return answer;
+    }
+    
+    private void getJumps(int[] A, int[] oddJump, int[] evenJump) {
+        int n = A.length, count = 0;;
+        int[] B = new int[n];
+        System.arraycopy(A, 0, B, 0, n);
+        Arrays.sort(B);
+        Map<Integer, Integer> value2Index = new HashMap<>();
+        int minVal = Integer.MAX_VALUE, maxVal = Integer.MIN_VALUE;
+        for (int i = 0; i < B.length; i++) {
+            if (value2Index.containsKey(B[i])) {
+                continue;
+            }
+            value2Index.put(B[i], ++count);
+        }
+        
+        int rangeStart = 1, rangeEnd = A.length;
+        MySegmentTree seg = new MySegmentTree(rangeStart, rangeEnd);
+        
+        for (int i = 0; i < n; i++) {
+            oddJump[i] = -1;
+            evenJump[i] = -1;
+        }
+        
+        for (int i = n - 1; i >= 0; i--) {
+            int index = value2Index.get(A[i]);
+            oddJump[i] = seg.queryMin(index, rangeEnd).index;
+            evenJump[i] = seg.queryMax(rangeStart, index).index;
+            seg.insert(index, new Pair(index, i));
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/set-of-stacks-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/set-of-stacks-ii.md"
new file mode 100644
index 0000000..13a67ba
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/set-of-stacks-ii.md"
@@ -0,0 +1,164 @@
+# 栈集II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/set-of-stacks-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假如你有一堆的盘子。如果你堆得太高的话，就可能会垮掉。所以，在真实的生活中，如果盘子叠到一定高度，你会重新开始堆新的一堆盘子。
+
+实现这样的一个数据结构，我们称之为栈集，来模拟这个过程。这个栈集包含若干个栈（可以理解为若干堆的盘子），如果一个栈满了，就需要新建一个栈来装新加入的项。你需要实现栈集的两个方法，`push(item)` 和 `pop()`，让这个栈集对外表现得就像是一个栈在进行操作一样。
+
+另外，你还需要多实现一个`popAt(index)`的方法，该方法可以pop栈集中指定的栈的栈顶元素。并且，该方法执行后，除了，最后一个栈可以不满以外，其他的栈仍然需要保持是满的。
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+SetOfStacks(2)
+push(1)
+push(2)
+push(4)
+push(8)
+push(16)
+popAt(0) 
+popAt(0) 
+pop()    
+
+输出:
+[2,4,16]
+
+解释:
+起初，堆栈0是[1,2]。 当popAt(0)时, 我们得到2然后栈变成[1,4]. 
+在整个栈里，我们应该pop16。
+```
+
+
+
+**样例2**
+
+```plain
+输入:
+SetOfStacks2(5)
+push(1)
+push(2)
+push(3)
+push(4)
+push(5)
+push(32)
+pop()
+push(64)
+popAt(1)
+
+输出:
+[32,64]
+
+说明:
+开始栈0是[32]. 当pop的时候我们取出32然后栈变空了。
+然后我们放入64，它被放在栈1，我们 popAt(1) 取出它。
+```
+
+
+ ### 参考代码
+ 本题考查栈的模拟应用，按照题目要求进行分组，然后取出或者加入对应元素即可。
+```java
+public class SetOfStacks2 {
+    ArrayList<Stack> stacks = new ArrayList<Stack>();
+    public int capacity;
+    // @param capacity an inetger, capacity of sub stack
+    public SetOfStacks2(int capacity) {
+        // do initialization if necessary
+        this.capacity = capacity;
+    }
+    public Stack getLastStack() {	
+        if (stacks.size() == 0) return null;
+            return stacks.get(stacks.size() - 1);
+    }
+	
+    // @param v an integer
+    public void push(int v) {
+        // Write your code here
+        Stack last = getLastStack();
+        if (last != null && !last.isAtCapacity()) { // add to last stack
+            last.push(v);
+        } else { // must create new stack
+		    Stack stack = new Stack(capacity);
+            stack.push(v);
+            stacks.add(stack);
+        }
+    }
+	
+    // @return an integer
+    public int pop() {
+        // Write your code here
+        Stack last = getLastStack();
+        int v = last.pop();
+        if (last.size == 0) stacks.remove(stacks.size() - 1);
+            return v;
+    }
+	
+    // popAt which performs a pop operation on a specific sub-stack
+    // @return top element of the specific sub-stack
+    public int popAt(int index) {
+        // Write your code here
+        return leftShift(index, true);
+    }
+	
+    public int leftShift(int index, boolean removeTop) {
+        Stack stack = stacks.get(index);
+        int removed_item;
+        if (removeTop) removed_item = stack.pop();
+        else removed_item = stack.removeBottom();
+        if (stack.isEmpty()) {	
+            stacks.remove(index);
+        } else if (stacks.size() > index + 1) {
+            int v = leftShift(index + 1, false);
+		    stack.push(v);	
+        }
+        return removed_item;
+    }
+}
+
+class Stack {
+    private int capacity;
+    public Node top, bottom;
+    public int size = 0;
+    public Stack(int capacity) { this.capacity = capacity; }
+    public boolean isAtCapacity() { return capacity == size; }
+    public void join(Node above, Node below) {	
+        if (below != null) below.above = above;
+        if (above != null) above.below = below;	
+    }
+	
+    public boolean push(int v) {	
+        if (size >= capacity) return false;
+		size++;		
+        Node n = new Node(v);
+        if (size == 1) bottom = n;
+        join(n, top);
+        top = n;
+        return true;
+    }
+	
+    public int pop() {	
+        Node t = top;	
+        top = top.below;
+        size--;
+        return t.value;
+    }
+
+    public boolean isEmpty() { return size == 0; }
+    public int removeBottom() {	
+        Node b = bottom;	
+        bottom = bottom.above;	
+        if (bottom != null) bottom.below = null;	
+        size--;
+        return b.value;	
+    }
+}
+
+class Node {
+    public Node below, above;
+    public int value;
+    Node(int v) {
+        this.value = v;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/set-of-stacks.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/set-of-stacks.md"
new file mode 100644
index 0000000..a0bfca4
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/set-of-stacks.md"
@@ -0,0 +1,122 @@
+# 栈集
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/set-of-stacks/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假如你有一堆的盘子。如果你堆得太高的话，就可能会垮掉。所以，在真实的生活中，如果盘子叠到一定高度，你会重新开始堆新的一堆盘子。
+
+实现这样的一个数据结构，我们称之为`栈集`，来模拟这个过程。这个栈集包含若干个栈（可以理解为若干堆的盘子），如果一个栈满了，就需要新建一个栈来装新加入的项。你需要实现栈集的两个方法，`push(item)` 和 `pop()`，让这个栈集对外表现得就像是一个栈在进行操作一样。
+ ### 样例说明
+ 例1:
+```
+输入：
+SetOfStacks(2);  // create a SetOfStacks object with capacity = 2
+push(1)
+push(2)
+push(4)
+push(8)
+push(16)
+pop() // return 16
+pop() // return 8
+pop() // return 4
+```
+
+例2:
+```
+输入：
+SetOfStacks(5)  
+push(1)
+push(2)
+push(3)
+push(4)
+push(5)
+push(32)
+pop()  // return 32
+push(64)
+pop()  // return 64
+
+```
+ ### 参考代码
+ 若当前栈满，开辟一个新的栈加入到vector中或链表中，若当前栈空，取出这个栈即可
+```java
+public class SetOfStacks {
+    ArrayList<Stack> stacks = new ArrayList<Stack>();
+    public int capacity;
+    // @param capacity an inetger, capacity of sub stack
+    public SetOfStacks(int capacity) {
+        // do initialization if necessary
+        this.capacity = capacity;
+    }
+    public Stack getLastStack() {	
+        if (stacks.size() == 0) return null;
+            return stacks.get(stacks.size() - 1);
+    }
+	
+    // @param v an integer
+    public void push(int v) {
+        // Write your code here
+        Stack last = getLastStack();
+        if (last != null && !last.isAtCapacity()) { // add to last stack
+            last.push(v);
+        } else { // must create new stack
+		    Stack stack = new Stack(capacity);
+            stack.push(v);
+            stacks.add(stack);
+        }
+    }
+	
+    // @return an integer
+    public int pop() {
+        // Write your code here
+        Stack last = getLastStack();
+        int v = last.pop();
+        if (last.size == 0) stacks.remove(stacks.size() - 1);
+            return v;
+    }
+}
+
+class Stack {
+    private int capacity;
+    public Node top, bottom;
+    public int size = 0;
+    public Stack(int capacity) { this.capacity = capacity; }
+    public boolean isAtCapacity() { return capacity == size; }
+    public void join(Node above, Node below) {	
+        if (below != null) below.above = above;
+        if (above != null) above.below = below;	
+    }
+	
+    public boolean push(int v) {	
+        if (size >= capacity) return false;
+		size++;		
+        Node n = new Node(v);
+        if (size == 1) bottom = n;
+        join(n, top);
+        top = n;
+        return true;
+    }
+	
+    public int pop() {	
+        Node t = top;	
+        top = top.below;
+        size--;
+        return t.value;
+    }
+
+    public boolean isEmpty() { return size == 0; }
+    public int removeBottom() {	
+        Node b = bottom;	
+        bottom = bottom.above;	
+        if (bottom != null) bottom.below = null;	
+        size--;
+        return b.value;	
+    }
+}
+
+class Node {
+    public Node below, above;
+    public int value;
+    Node(int v) {
+        this.value = v;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/simplify-path.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/simplify-path.md"
new file mode 100644
index 0000000..02d2842
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/simplify-path.md"
@@ -0,0 +1,51 @@
+# 简化路径
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/simplify-path/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个文件的绝对路径(Unix-style)，请进行路径简化。
+
+Unix中, `.` 表示当前目录, `..` 表示父目录。
+
+结果必须以 `/` 开头，并且两个目录名之间有且只有一个 `/`。最后一个目录名(如果存在)后不能出现  `/` 。你需要保证结果是正确表示路径的最短的字符串。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "/home/"
+输出: "/home"
+```
+
+**样例 2:**
+
+```
+输入: "/a/./../../c/"
+输出: "/c"
+解释: "/" 没有上级目录, "/../" 的结果就是 "/".
+```
+ ### 参考代码
+ 用栈处理即可.
+
+将原字符串以 `'/'` 分隔, 然后遍历:
+
+- 遇到正常的目录名, 入栈
+- 遇到 `'.'` 或 空名称 (对应 `"//"`) 则忽略
+- 遇到 `".."` 则从栈顶弹出一个元素 (如果栈为空则不弹栈, 对应 `"/../"`)
+
+最后将栈中的元素以 `'/'` 连接得到结果.
+```python
+class Solution:
+    """
+    @param path: the original path
+    @return: the simplified path
+    """
+    def simplifyPath(self, path):
+        path = path.split('/')
+        stack = []
+        for i in path:
+            if i == '..':
+                if len(stack):
+                    stack.pop()
+            elif i != '.' and i != '':
+                stack.append(i)
+        return '/' + '/'.join(stack)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/stack-sorting.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/stack-sorting.md"
new file mode 100644
index 0000000..18611bb
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/stack-sorting.md"
@@ -0,0 +1,65 @@
+# 栈排序
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/stack-sorting/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 请设计一种方法将一个栈进行升序排列 （最大的数在最上面）。
+
+你可以使用另外一个栈来辅助操作，但不可将这些数复制到另外一个数据结构中 （如，数组）。
+ ### 样例说明
+ 给一个栈：
+```
+| |
+|3|
+|1|
+|2|
+|4|
+ -
+```
+
+排序之后：
+```
+| |
+|4|
+|3|
+|2|
+|1|
+ -
+```
+
+栈会被序列化为`[4,2,1,3]`，也就是说最右边是栈顶。
+ ### 参考代码
+ ```cpp
+class Solution {
+public:
+    /**
+     * @param stk an integer stack
+     * @return void
+     */
+    void stackSorting(stack<int>& stk) {
+        // Write your code here
+        stack<int> tmp;
+        while (!stk.empty()) {
+            if (!stk.empty() && (tmp.empty() || tmp.top() >= stk.top())) {
+                tmp.push(stk.top());
+                stk.pop();
+            }
+            else {
+                int value = stk.top(); stk.pop();
+                while (!tmp.empty() && tmp.top() <= value)  {
+                    stk.push(tmp.top());
+                    tmp.pop();
+                }
+                stk.push(value);
+                while (!tmp.empty()) {
+                    stk.push(tmp.top());
+                    tmp.pop();
+                }
+            }
+        }
+        while (!tmp.empty()) {
+            stk.push(tmp.top());
+            tmp.pop();
+        }
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/valid-parentheses.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/valid-parentheses.md"
new file mode 100644
index 0000000..491017e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\346\240\210/valid-parentheses.md"
@@ -0,0 +1,84 @@
+# 有效的括号序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/valid-parentheses/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串所表示的括号序列，包含以下字符： `'(', ')'`, `'{'`, `'}'`, `'['` and `']'`， 判定是否是有效的括号序列。
+
+括号必须依照 `"()"` 顺序表示， `"()[]{}"` 是有效的括号，但 `"([)]"` 则是无效的括号。
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入："([)]"
+输出：False
+```
+**样例 2：**
+```
+输入："()[]{}"
+输出：True
+```
+
+ ### 参考代码
+ Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
+
+The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.&nbsp;
+```java
+public class Solution {
+    public boolean isValidParentheses(String s) {
+        Stack<Character> stack = new Stack<Character>();
+        for (Character c : s.toCharArray()) {
+	    if ("({[".contains(String.valueOf(c))) {
+                stack.push(c);
+            } else {
+               if (!stack.isEmpty() && is_valid(stack.peek(), c)) {
+                   stack.pop();
+               } else {
+                   return false;
+               }
+           }
+       }
+       return stack.isEmpty();
+    }
+
+    private boolean is_valid(char c1, char c2) {
+        return (c1 == '(' && c2 == ')') || (c1 == '{' && c2 == '}')
+            || (c1 == '[' && c2 == ']');
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param s A string
+     * @return whether the string is a valid parentheses
+     */
+    public boolean isValidParentheses(String s) {
+        // Write your code here
+        Stack<Character> stack = new Stack<>();
+        for (char c : s.toCharArray()) {
+            if (c == '(' || c == '[' || c == '{') {
+                stack.push(c);
+            }
+            if (c == ')') {
+                if (stack.isEmpty() || stack.pop() != '(') {
+                    return false;
+                }
+            }
+            if (c == ']') {
+                if (stack.isEmpty() || stack.pop() != '[') {
+                    return false;
+                }
+            }
+            if (c == '}') {
+                if (stack.isEmpty() || stack.pop() != '{') {
+                    return false;
+                }
+            }
+        }
+        return stack.isEmpty();
+    }
+}
+
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/add-two-numbers-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/add-two-numbers-ii.md"
new file mode 100644
index 0000000..b3f32a7
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/add-two-numbers-ii.md"
@@ -0,0 +1,97 @@
+# 链表求和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/add-two-numbers-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假定用链表表示两个数，其中每个节点仅包含一个数字。假设这两个数的数字`顺序`排列，请设计一种方法将两个数相加，并将其结果表现为链表的形式。
+
+ ### 样例说明
+ **样例 1:**
+```
+输入: 6->1->7   2->9->5
+输出: 9->1->2
+```
+
+**样例 2:**
+```
+输入: 1->2->3   4->5->6
+输出: 5->7->9
+```
+
+
+ ### 参考代码
+ ```java
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int x) {
+ *         val = x;
+ *         next = null;      
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param l1: the first list
+     * @param l2: the second list
+     * @return: the sum list of l1 and l2 
+     */
+    public ListNode addLists2(ListNode l1, ListNode l2) {
+        l1 = reverse(l1);
+        l2 = reverse(l2);
+        
+        return reverse(addList1(l1, l2));
+    }  
+    
+    private ListNode reverse(ListNode head) {
+        ListNode prev = null;
+        while (head != null) {
+            ListNode temp = head.next;
+            head.next = prev;
+            prev = head;
+            head = temp;
+        }
+        return prev;
+    }
+    
+    private ListNode addList1(ListNode l1, ListNode l2) {
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        int carry = 0;
+        
+        while (l1 != null && l2 != null) {
+            tail.next = new ListNode((l1.val + l2.val + carry) % 10);
+            tail = tail.next;
+            carry = (l1.val + l2.val + carry) / 10;
+            
+            l1 = l1.next;
+            l2 = l2.next;
+        }
+        
+        while (l1 != null) {
+            tail.next = new ListNode((l1.val + carry) % 10);
+            tail = tail.next;
+            carry = (l1.val + carry) / 10;
+            
+            l1 = l1.next;
+        }
+        while (l2 != null) {
+            tail.next = new ListNode((l2.val + carry) % 10);
+            tail = tail.next;
+            carry = (l2.val + carry) / 10;
+            
+            l2 = l2.next;
+        }
+        
+        while (carry != 0) {
+            tail.next = new ListNode(carry % 10);
+            tail = tail.next;
+            carry = carry / 10;
+        }
+        
+        return dummy.next;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/add-two-numbers.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/add-two-numbers.md"
new file mode 100644
index 0000000..0cbff19
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/add-two-numbers.md"
@@ -0,0 +1,115 @@
+# 链表求和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/add-two-numbers/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 你有两个用链表代表的整数，其中每个节点包含一个数字。数字存储按照在原来整数中`相反`的顺序，使得第一个数字位于链表的开头。写出一个函数将两个整数相加，用链表形式返回和。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 7->1->6->null, 5->9->2->null
+输出: 2->1->9->null	
+样例解释: 617 + 295 = 912, 912 转换成链表:  2->1->9->null
+```
+
+**样例 2:**
+
+```
+输入:  3->1->5->null, 5->9->2->null
+输出: 8->0->8->null	
+样例解释: 513 + 295 = 808, 808 转换成链表: 8->0->8->null
+```
+ ### 参考代码
+ You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
+
+Input: (2 -&gt; 4 -&gt; 3) + (5 -&gt; 6 -&gt; 4)
+Output: 7 -&gt; 0 -&gt; 8class Solution(object):<br><br>
+
+从前到后模拟加法过程，用一个变量记录每次加法的进位。进位最开始为0，每次加法对应的节点数字相加再加上进位，对10取模得到结果对应位置，除以10得到新的进位。
+```java
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int x) {
+ *         val = x;
+ *         next = null;
+ *     }
+ * }
+ */
+public class Solution {
+    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
+        if(l1 == null && l2 == null) {
+            return null;
+        }
+            
+        ListNode head = new ListNode(0);
+        ListNode point = head;
+        int carry = 0;
+        while(l1 != null && l2!=null){
+            int sum = carry + l1.val + l2.val;
+            point.next = new ListNode(sum % 10);
+            carry = sum / 10;
+            l1 = l1.next;
+            l2 = l2.next;
+            point = point.next;
+        }
+        
+        while(l1 != null) {
+            int sum =  carry + l1.val;
+            point.next = new ListNode(sum % 10);
+            carry = sum /10;
+            l1 = l1.next;
+            point = point.next;
+        }
+        
+        while(l2 != null) {
+            int sum =  carry + l2.val;
+            point.next = new ListNode(sum % 10);
+            carry = sum /10;
+            l2 = l2.next;
+            point = point.next;
+        }
+        
+        if (carry != 0) {
+            point.next = new ListNode(carry);
+        }
+        return head.next;
+    }
+}
+
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param l1: the first list
+     * @param l2: the second list
+     * @return: the sum list of l1 and l2
+     */
+    public ListNode addLists(ListNode l1, ListNode l2) {
+        // write your code here
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+
+        int carry = 0;
+        for (ListNode i = l1, j = l2; i != null || j != null; ) {
+            int sum = carry;
+            sum += (i != null) ? i.val : 0;
+            sum += (j != null) ? j.val : 0;
+
+            tail.next = new ListNode(sum % 10);
+            tail = tail.next;
+
+            carry = sum / 10;
+            i = (i == null) ? i : i.next;
+            j = (j == null) ? j : j.next;
+        }
+
+        if (carry != 0) {
+            tail.next = new ListNode(carry);
+        }
+        return dummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/animal-shelter.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/animal-shelter.md"
new file mode 100644
index 0000000..341d67e
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/animal-shelter.md"
@@ -0,0 +1,75 @@
+# 宠物收养所
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/animal-shelter/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个宠物避难所里，仅有`狗`和`猫`两种动物可供领养，且领养时严格执行`“先进先出”`的规则。如果有人想要从避难所领养动物，他只有两种选择：要么选择领养所有动物中`最资深`的一只（根据到达避难所的时间，越早到的越资深），要么选择领养猫或狗（同样，也只能领养最资深的一只）。也就是说，领养者不能随意选择某一指定动物。请建立一个数据结构，使得它可以运行以上规则，并可实现 `enqueue`, `dequeueAny`, `dequeueDog`， 和 `dequeueCat` 操作。 
+
+建议使用 `LinkedList` 作为数据结构实现。
+ ### 样例说明
+ 
+ ### 参考代码
+ 我们可以用两个队列实现，分别代表猫和狗，每次取的时候看两个顶端哪个出现的早
+```java
+public class AnimalShelter {
+
+    public AnimalShelter() {
+        // do initialize if necessary
+        tot = 0;
+        dogs = new LinkedList<String>();
+        cats = new LinkedList<String>();
+    }
+
+    /**
+     * @param name a string
+     * @param type an integer, 1 if Animal is dog or 0
+     * @return void
+     */
+    void enqueue(String name, int type) {
+        // write your code here
+        tot += 1;
+        if (type == 1)
+            dogs.add(tot + "#" + name);
+        else
+            cats.add(tot + "#" + name);
+    }
+
+    public String dequeueAny() {
+        // write your code here
+        if (cats.isEmpty())
+            return dequeueDog();
+        else if (dogs.isEmpty())
+            return dequeueCat();
+        else {
+            int d_time = getTime(dogs.getFirst());
+            int c_time = getTime(cats.getFirst());
+            if (c_time < d_time)
+                return dequeueCat();
+            else
+                return dequeueDog();
+        }
+    }
+
+    public String dequeueDog() {
+        // write your code here
+        String name = getName(dogs.getFirst());
+        dogs.removeFirst();
+        return name;
+    }
+
+    public String dequeueCat() {
+        // write your code here
+        String name = getName(cats.getFirst());
+        cats.removeFirst();
+        return name;
+    }
+
+    private int tot;
+    private LinkedList<String> cats, dogs;
+    private String getName(String str) {
+        return str.substring(str.indexOf("#") + 1, str.length());
+    }
+    private int getTime(String str) {
+        return Integer.parseInt(str.substring(0, str.indexOf("#")));
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-array-list-to-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-array-list-to-linked-list.md"
new file mode 100644
index 0000000..5bec183
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-array-list-to-linked-list.md"
@@ -0,0 +1,56 @@
+# 链表化数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-array-list-to-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一个数组变成链表
+ ### 样例说明
+ 例1:
+```
+输入: [1,2,3,4], 
+输出: 1->2->3->4->null.
+```
+
+例2:
+```
+输入: [1,2], 
+输出: 1->2->null.
+```
+
+ ### 参考代码
+ 元素之间链起来即可
+```java
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+public class Solution {
+    /**
+     * @param nums an integer array list
+     * @return the first node of linked list
+     */
+    public ListNode toLinkedList(ArrayList<Integer> nums) {  
+        // Write your code here
+        if (nums.size() == 0)
+            return null;
+        ListNode head = null;
+        ListNode p = null;
+        for (Integer num : nums) {
+            if (head == null) {
+                head = new ListNode(num);
+                p = head;
+            } else {
+                p.next = new ListNode(num);
+                p = p.next;
+            }
+        }
+        return head;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-binary-search-tree-to-doubly-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-binary-search-tree-to-doubly-linked-list.md"
new file mode 100644
index 0000000..44401c9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-binary-search-tree-to-doubly-linked-list.md"
@@ -0,0 +1,86 @@
+# 将二叉查找树转换成双链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-binary-search-tree-to-doubly-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一个二叉查找树按照中序遍历转换成双向链表。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ * Definition for Doubly-ListNode.
+ * public class DoublyListNode {
+ *     int val;
+ *     DoublyListNode next, prev;
+ *     DoublyListNode(int val) {
+ *         this.val = val;
+ *         this.next = this.prev = null;
+ *     }
+ * }
+ */ 
+ 
+class ResultType {
+    DoublyListNode first, last;
+    
+    public ResultType(DoublyListNode first, DoublyListNode last) {
+        this.first = first;
+        this.last = last;
+    }
+}
+
+public class Solution {
+    /**
+     * @param root: The root of tree
+     * @return: the head of doubly list node
+     */
+    public DoublyListNode bstToDoublyList(TreeNode root) {  
+        if (root == null) {
+            return null;
+        }
+        
+        ResultType result = helper(root);
+        return result.first;
+    }
+    
+    //中序遍历函数 
+    public ResultType helper(TreeNode root) {  
+        if (root == null) {
+            return null;
+        }
+        
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+        DoublyListNode node = new DoublyListNode(root.val);
+        
+        ResultType result = new ResultType(null, null);
+        
+        //构造单链表
+        if (left == null) {
+            result.first = node;
+        } else {
+            result.first = left.first;
+            left.last.next = node;
+            node.prev = left.last;
+        }
+        
+        if (right == null) {
+            result.last = node;
+        } else {
+            result.last = right.last;
+            right.first.prev = node;
+            node.next = right.first;
+        }
+        
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-binary-tree-to-linked-lists-by-depth.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-binary-tree-to-linked-lists-by-depth.md"
new file mode 100644
index 0000000..8373b33
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-binary-tree-to-linked-lists-by-depth.md"
@@ -0,0 +1,124 @@
+# 将二叉树按照层级转化为链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-binary-tree-to-linked-lists-by-depth/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，设计一个算法为每一层的节点建立一个链表。也就是说，如果一棵二叉树有 `D` 层，那么你需要创建 `D` 条链表。
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,2,3,4}
+输出: [1->null,2->3->null,4->null]
+解释: 
+        1
+       / \
+      2   3
+     /
+    4
+```
+
+**样例 2:**
+
+```
+输入: {1,#,2,3}
+输出: [1->null,2->null,3->null]
+解释: 
+    1
+     \
+      2
+     /
+    3
+```
+ ### 参考代码
+ 考点：
+* 搜索遍历
+
+题解：采用基本的bfs搜索实现层序遍历即可。分别使用DFS和BFS两种解法解决这个问题。时间复杂度都是O(n)。
+```python
+# BFS 解法
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+Definition for singly-linked list.
+class ListNode:
+    def __init__(self, x):
+        self.val = x
+        self.next = None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @return {ListNode[]} a lists of linked list
+    def binaryTreeToLists(self, root):
+        result = []
+        if root is None:
+            return result
+            
+        import Queue
+        queue = Queue.Queue()
+        
+        queue.put(root)
+        
+        dummy = ListNode(0)
+        
+        lastNode = None
+        
+        while not queue.empty():
+            dummy.next = None
+            lastNode = dummy
+            size = queue.qsize()
+            for i in xrange(size):
+                head = queue.get()
+                lastNode.next = ListNode(head.val)
+                lastNode = lastNode.next
+
+                if head.left is not None:
+                    queue.put(head.left)
+                if head.right is not None:
+                    queue.put(head.right)
+        
+            result.append(dummy.next)
+        
+        return result
+    
+
+
+# DFS 解法
+
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+Definition for singly-linked list.
+class ListNode:
+    def __init__(self, x):
+        self.val = x
+        self.next = None
+"""
+class Solution:
+    # @param {TreeNode} root the root of binary tree
+    # @return {ListNode[]} a lists of linked list
+    def binaryTreeToLists(self, root):
+        # Write your code here
+        result = []
+        self.dfs(root, 1, result)
+        return result
+
+    def dfs(self, root, depth, result):
+        if root is None:
+            return
+        node = ListNode(root.val)
+        if len(result) < depth:
+            result.append(node)
+        else:
+            node.next = result[depth-1]
+            result[depth-1] = node
+        
+        self.dfs(root.right, depth + 1, result)
+        self.dfs(root.left, depth + 1, result)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-linked-list-to-array-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-linked-list-to-array-list.md"
new file mode 100644
index 0000000..d90e652
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/convert-linked-list-to-array-list.md"
@@ -0,0 +1,42 @@
+# 链表转数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-linked-list-to-array-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一个链表转换为一个数组。
+ ### 样例说明
+ **样例 1:**
+```
+输入: 1->2->3->null
+输出: [1,2,3]
+```
+**样例 2:**
+```
+输入: 3->5->8->null
+输出: [3,5,8]
+```
+
+
+ ### 参考代码
+ ```python
+"""
+Definition of ListNode
+class ListNode(object):
+
+    def __init__(self, val, next=None):
+        self.val = val
+        self.next = next
+"""
+class Solution:
+    """
+    @param {ListNode} head the first node of the linked list.
+    @return {int[]} an integer list
+    """
+    def toArrayList(self, head):
+        # Write your code here
+        r = []
+        #遍历链表，并将每个节点的val存储在数组中
+        while head is not None:
+            r.append(head.val)
+            head = head.next
+        return r
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/count-linked-list-nodes.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/count-linked-list-nodes.md"
new file mode 100644
index 0000000..0a1d84b
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/count-linked-list-nodes.md"
@@ -0,0 +1,54 @@
+# 链表节点计数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/count-linked-list-nodes/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 计算链表中有多少个节点.
+ ### 样例说明
+ ```
+样例  1:
+	输入:  1->3->5->null
+	输出: 3
+	
+	样例解释: 
+	返回链表中结点个数，也就是链表的长度.
+
+样例 2:
+	输入:  null
+	输出: 0
+	
+	样例解释: 
+	空链表长度为0
+
+```
+ ### 参考代码
+ 简单模拟
+```cpp
+/**
+ * Definition of ListNode
+ * class ListNode {
+ * public:
+ *     int val;
+ *     ListNode *next;
+ *     ListNode(int val) {
+ *         this->val = val;
+ *         this->next = NULL;
+ *     }
+ * }
+ */
+class Solution {
+public:
+    /**
+     * @param head the first node of linked list.
+     * @return an integer
+     */
+    int countNodes(ListNode *head) {
+        // Write your code here
+        int cnt = 0;
+        while (head != NULL) {
+            cnt ++;
+            head = head->next;
+        }
+        return cnt;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/delete-node-in-the-middle-of-singly-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/delete-node-in-the-middle-of-singly-linked-list.md"
new file mode 100644
index 0000000..5e3c110
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/delete-node-in-the-middle-of-singly-linked-list.md"
@@ -0,0 +1,29 @@
+# 在O(1)时间复杂度删除链表节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/delete-node-in-the-middle-of-singly-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个单链表中的一个等待被删除的节点(非表头或表尾)。请在在 O(1) 时间复杂度删除该链表节点。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```python
+"""
+Definition of ListNode
+class ListNode(object):
+
+    def __init__(self, val, next=None):
+        self.val = val
+        self.next = next
+"""
+class Solution:
+    # @param node: the node in the list should be deleted
+    # @return: nothing
+    def deleteNode(self, node):
+        # write your code here
+        if node is None or node.next is None:
+            return
+        next = node.next;
+        node.val = next.val
+        node.next = next.next
+        return
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/find-node-in-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/find-node-in-linked-list.md"
new file mode 100644
index 0000000..9dabf81
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/find-node-in-linked-list.md"
@@ -0,0 +1,46 @@
+# 在链表中找节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-node-in-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在链表中找值为 value 的节点，如果没有的话，返回空(null)。
+ ### 样例说明
+ **样例 1:**
+```
+输入:  1->2->3 and value = 3
+输出: 最后一个结点
+```		
+**样例 2:**
+```
+输入:  1->2->3 and value = 4
+输出: null
+```
+ ### 参考代码
+ 简单模拟，复杂度O(n)
+```java
+/**
+ * Definition for ListNode
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int x) {
+ *         val = x;
+ *         next = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param head: the head of linked list.
+     * @param val: an integer
+     * @return: a linked node or null
+     */
+    public ListNode findNode(ListNode head, int val) { 
+        for (ListNode node = head; node != null; node = node.next) {
+            if (node.val == val) {
+                return node;
+            }
+        }
+        return null;
+    }  
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/implement-queue-by-linked-list-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/implement-queue-by-linked-list-ii.md"
new file mode 100644
index 0000000..510003c
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/implement-queue-by-linked-list-ii.md"
@@ -0,0 +1,105 @@
+# 维护队列 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/implement-queue-by-linked-list-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个双端队列
+1. `push_front(item)`. 将新项添加到队列的前面。
+2. `push_back(item)`. 将新项添加到队列的后面。
+2. `pop_front()`. 将第一个项移出队列，返回它。
+3. `pop_back()`. 将最后一项移出队列，返回它。
+ ### 样例说明
+ 例1：
+```
+输入：
+push_front(1)
+push_back(2)
+pop_back() // return 2
+pop_back() // return 1
+push_back(3)
+push_back(4)
+pop_front() // return 3
+pop_front() // return 4
+```
+
+例2：
+```
+输入：
+push_front(1)
+pop_front()// return 1
+
+```
+ ### 参考代码
+ 实现双端队列的两头进出操作
+```java
+class Node {
+    public int val;
+    public Node next, prev;
+    public Node(int _val) {
+        val = _val;
+        prev = next = null;
+    }
+}
+
+public class Dequeue {
+    public Node first, last;
+    
+    public Dequeue() {
+        first = last = null;
+        // do initialize if necessary
+    }
+
+    public void push_front(int item) {
+        // Write your code here
+        if (first == null) {
+            last = new Node(item);
+            first = last;		
+        } else {
+            Node tmp = new Node(item);
+            first.prev = tmp;
+            tmp.next = first;
+            first = first.prev;
+        }
+    }
+
+    public void push_back(int item) {
+        // Write your code here
+        if (last == null) {
+            last = new Node(item);
+            first = last;		
+        } else {
+            Node tmp = new Node(item);
+            last.next = tmp;
+            tmp.prev = last;
+            last = last.next;
+        }
+    }
+
+    public int pop_front() {
+        // Write your code here
+        if (first != null) {
+            int item = first.val;
+            first = first.next;
+            if (first != null)
+                first.prev = null;
+            else
+                last = null;
+            return item;
+        }
+        return -11;
+    }
+
+    public int pop_back() {
+        // Write your code here
+        if (last != null) {
+            int item = last.val;
+            last = last.prev;
+            if (last != null)
+                last.next = null;
+            else
+                first = null;
+            return item;
+        }
+        return -11;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/implement-queue-by-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/implement-queue-by-linked-list.md"
new file mode 100644
index 0000000..97aaace
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/implement-queue-by-linked-list.md"
@@ -0,0 +1,68 @@
+# 队列维护
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/implement-queue-by-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个队列的操作
+
+1. `enqueue(item)`.将新元素放入队列中。
+2. `dequeue()`. 将第一个元素移出队列，返回它。
+ ### 样例说明
+ 例1:
+```
+输入：
+enqueue(1)
+enqueue(2)
+enqueue(3)
+dequeue() // return 1
+enqueue(4)
+dequeue() // return 2
+```
+例2:
+```
+输入：
+enqueue(10)
+dequeue()// return 10
+
+```
+ ### 参考代码
+ 实现队列基本入队出队操作
+```java
+class Node {
+    public int val;
+    public Node next;
+    public Node(int _val) {
+        val = _val;
+        next = null;
+    }
+}
+
+public class MyQueue {
+    public Node first, last;
+    
+    public Queue() {
+        first = last = null;
+        // do initialize if necessary
+    }
+
+    public void enqueue(int item) {
+        // Write your code here
+        if (first == null) {
+            last = new Node(item);
+            first = last;		
+        } else {
+            last.next = new Node(item);
+            last = last.next;
+        }
+    }
+
+    public int dequeue() {
+        // Write your code here
+        if (first != null) {
+            int item = first.val;
+            first = first.next;
+            return item;
+        }
+        return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/insert-into-a-cyclic-sorted-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/insert-into-a-cyclic-sorted-list.md"
new file mode 100644
index 0000000..921aef3
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/insert-into-a-cyclic-sorted-list.md"
@@ -0,0 +1,67 @@
+# 向循环有序链表插入节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/insert-into-a-cyclic-sorted-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个来自已经排过序的循环链表的节点，写一个函数来将一个值插入到循环链表中，并且保持还是有序循环链表。给出的节点可以是链表中的任意一个单节点。返回插入后的新链表。
+ ### 样例说明
+ 例1:
+```
+输入:
+3->5->1
+4
+输出:
+5->1->3->4
+```
+
+例2:
+```
+输入:
+2->2->2
+3
+输出:
+3->2->2->2
+```
+
+ ### 参考代码
+ 由于已经是排序好的链表。
+所以只需顺序扫描一遍链表即可。
+需要注意的是，若为最大或是最小，需要额外判断。
+```python
+"""
+Definition of ListNode
+class ListNode(object):
+
+    def __init__(self, val, next=None):
+        self.val = val
+        self.next = next
+"""
+class Solution:
+    # @param {ListNode} node a list node in the list
+    # @param {int} x an integer
+    # @return {ListNode} the inserted new list node
+    def insert(self, node, x):
+        # Write your code here
+        if node is None:
+            node = ListNode(x)
+            node.next = node
+            return node
+
+        p = node
+        prev = None
+        while True:
+            prev = p
+            p = p.next
+            if x <= p.val and x >= prev.val:
+                break
+
+            if (prev.val > p.val) and (x < p.val or x > prev.val):
+                break
+
+            if p is node:
+                break
+
+        newNode = ListNode(x)
+        newNode.next = p
+        prev.next = newNode
+        return newNode
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/insert-node-in-sorted-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/insert-node-in-sorted-linked-list.md"
new file mode 100644
index 0000000..b3341ee
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/insert-node-in-sorted-linked-list.md"
@@ -0,0 +1,42 @@
+# 在排序链表中插入一个节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/insert-node-in-sorted-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在链表中插入一个节点。
+ ### 样例说明
+ **样例 1：**
+```
+输入：head = 1->4->6->8->null, val = 5
+输出：1->4->5->6->8->null
+```
+**样例 2：**
+```
+输入：head = 1->null, val = 2
+输出：1->2->null
+```
+ ### 参考代码
+ ----------------------------------------------------------
+```python
+"""
+Definition of ListNode
+class ListNode(object):
+
+    def __init__(self, val, next=None):
+        self.val = val
+        self.next = next
+"""
+
+class Solution:
+    # @param head, a ListNode
+    # @param val, an integer
+    # @return the head of new linked list
+    def insertNode(self, head, val):
+        # Write your code here
+        dummy = ListNode(0, head)
+        p = dummy
+        while p.next and p.next.val < val:
+            p = p.next
+        node = ListNode(val, p.next)
+        p.next = node
+        return dummy.next
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/insertion-sort-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/insertion-sort-list.md"
new file mode 100644
index 0000000..fc6ff88
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/insertion-sort-list.md"
@@ -0,0 +1,45 @@
+# 链表插入排序
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/insertion-sort-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 用插入排序对链表排序
+ ### 样例说明
+ ```
+样例 1:
+	输入: 0->null
+	输出: 0->null
+
+
+样例 2:
+	输入:  1->3->2->0->null
+	输出 :0->1->2->3->null
+	
+
+```
+
+ ### 参考代码
+ Sort a linked list using insertion sort.
+
+与数组普通插入排序一样的做法。
+```java
+public class Solution {
+    public ListNode insertionSortList(ListNode head) {
+        ListNode dummy = new ListNode(0);
+        // 这个dummy的作用是，把head开头的链表一个个的插入到dummy开头的链表里
+        // 所以这里不需要dummy.next = head;
+
+        while (head != null) {
+            ListNode node = dummy;
+            while (node.next != null && node.next.val < head.val) {
+                node = node.next;
+            }
+            ListNode temp = head.next;
+            head.next = node.next;
+            node.next = head;
+            head = temp;
+        }
+
+        return dummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/intersection-of-two-linked-lists.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/intersection-of-two-linked-lists.md"
new file mode 100644
index 0000000..8dcc06d
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/intersection-of-two-linked-lists.md"
@@ -0,0 +1,76 @@
+# 两个链表的交叉
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/intersection-of-two-linked-lists/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 请写一个程序，找到两个单链表最开始的交叉节点。
+ ### 样例说明
+ **样例 1：**
+```
+输入：
+	A:          a1 → a2
+	                   ↘
+	                     c1 → c2 → c3
+	                   ↗            
+	B:     b1 → b2 → b3
+输出：c1
+解释：在节点 c1 开始交叉。
+```
+
+**样例 2:**
+
+```
+输入:
+Intersected at 6
+1->2->3->4->5->6->7->8->9->10->11->12->13->null
+6->7->8->9->10->11->12->13->null
+输出: Intersected at 6
+解释：begin to intersect at node 6.
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param headA: the first list
+     * @param headB: the second list
+     * @return: a ListNode 
+     */
+    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
+        if (headA == null || headB == null) {
+            return null;
+        }
+        
+        // get the tail of list A.
+        ListNode node = headA;
+        while (node.next != null) {
+            node = node.next;
+        }
+        node.next = headB;
+        ListNode result = listCycleII(headA);
+        node.next = null;
+        return result;
+    }
+    
+    private ListNode listCycleII(ListNode head) {
+        ListNode slow = head, fast = head.next;
+        
+        while (slow != fast) {
+            if (fast == null || fast.next == null) {
+                return null;
+            }
+            
+            slow = slow.next;
+            fast = fast.next.next;
+        }
+        
+        slow = head;
+        fast = fast.next;
+        while (slow != fast) {
+            slow = slow.next;
+            fast = fast.next;
+        }
+        
+        return slow;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/merge-k-sorted-lists.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/merge-k-sorted-lists.md"
new file mode 100644
index 0000000..2145767
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/merge-k-sorted-lists.md"
@@ -0,0 +1,177 @@
+# 合并k个排序链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-k-sorted-lists/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>合并k个排序链表，并且返回合并后的排序链表。尝试分析和描述其复杂度。<br></p>
+ ### 样例说明
+ ```
+样例 1:
+	输入:   [2->4->null,null,-1->null]
+	输出:  -1->2->4->null
+
+样例 2:
+	输入: [2->6->null,5->null,7->null]
+	输出:  2->5->6->7->null
+	
+```
+ ### 参考代码
+ Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
+
+有序数组合并，使用两个指针向后移动，每次比较，小的一个数字取出来，并将指针后移一位。
+
+K个有序链表可以每次合并一个链表进结果链表中。合并k次
+```java
+// version 1: Divide & Conquer
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+public class Solution {
+    /**
+     * @param lists: a list of ListNode
+     * @return: The head of one sorted list.
+     */
+    public ListNode mergeKLists(List<ListNode> lists) {
+        if (lists.size() == 0) {
+            return null;
+        }
+        return mergeHelper(lists, 0, lists.size() - 1);
+    }
+    
+    private ListNode mergeHelper(List<ListNode> lists, int start, int end) {
+        if (start == end) {
+            return lists.get(start);
+        }
+        
+        int mid = start + (end - start) / 2;
+        ListNode left = mergeHelper(lists, start, mid);
+        ListNode right = mergeHelper(lists, mid + 1, end);
+        return mergeTwoLists(left, right);
+    }
+    
+    private ListNode mergeTwoLists(ListNode list1, ListNode list2) {
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (list1 != null && list2 != null) {
+            if (list1.val < list2.val) {
+                tail.next = list1;
+                tail = list1;
+                list1 = list1.next;
+            } else {
+                tail.next = list2;
+                tail = list2;
+                list2 = list2.next;
+            }
+        }
+        if (list1 != null) {
+            tail.next = list1;
+        } else {
+            tail.next = list2;
+        }
+        
+        return dummy.next;
+    }
+}
+
+// version 2: Heap
+public class Solution {
+    private Comparator<ListNode> ListNodeComparator = new Comparator<ListNode>() {
+        public int compare(ListNode left, ListNode right) {
+            return left.val - right.val;
+        }
+    };
+    
+    public ListNode mergeKLists(List<ListNode> lists) {
+        if (lists == null || lists.size() == 0) {
+            return null;
+        }
+        
+        Queue<ListNode> heap = new PriorityQueue<ListNode>(lists.size(), ListNodeComparator);
+        for (int i = 0; i < lists.size(); i++) {
+            if (lists.get(i) != null) {
+                heap.add(lists.get(i));
+            }
+        }
+        
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (!heap.isEmpty()) {
+            ListNode head = heap.poll();
+            tail.next = head;
+            tail = head;
+            if (head.next != null) {
+                heap.add(head.next);
+            }
+        }
+        return dummy.next;
+    }
+}
+
+// Version 3: merge two by two
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+public class Solution {
+    /**
+     * @param lists: a list of ListNode
+     * @return: The head of one sorted list.
+     */
+    public ListNode mergeKLists(List<ListNode> lists) {  
+        if (lists == null || lists.size() == 0) {
+            return null;
+        }
+        
+        while (lists.size() > 1) {
+            List<ListNode> new_lists = new ArrayList<ListNode>();
+            for (int i = 0; i + 1 < lists.size(); i += 2) {
+                ListNode merged_list = merge(lists.get(i), lists.get(i+1));
+                new_lists.add(merged_list);
+            }
+            if (lists.size() % 2 == 1) {
+                new_lists.add(lists.get(lists.size() - 1));
+            }
+            lists = new_lists;
+        }
+        
+        return lists.get(0);
+    }
+    
+    private ListNode merge(ListNode a, ListNode b) {
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (a != null && b != null) {
+            if (a.val < b.val) {
+                tail.next = a;
+                a = a.next;
+            } else {
+                tail.next = b;
+                b = b.next;
+            }
+            tail = tail.next;
+        }
+        
+        if (a != null) {
+            tail.next = a;
+        } else {
+            tail.next = b;
+        }
+        
+        return dummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/merge-two-sorted-lists.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/merge-two-sorted-lists.md"
new file mode 100644
index 0000000..8a2c488
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/merge-two-sorted-lists.md"
@@ -0,0 +1,49 @@
+# 合并两个排序链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-two-sorted-lists/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将两个排序链表合并为一个新的排序链表
+ ### 样例说明
+ ```
+样例 1:
+	输入: list1 = null, list2 = 0->3->3->null
+	输出: 0->3->3->null
+
+
+样例2:
+	输入:  list1 =  1->3->8->11->15->null, list2 = 2->null
+	输出: 1->2->3->8->11->15->null
+
+```
+
+ ### 参考代码
+ Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
+
+与合并数组一个方法，两个指针往后走。
+```java
+public class Solution {
+    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
+        ListNode dummy = new ListNode(0);
+        ListNode lastNode = dummy;
+        
+        while (l1 != null && l2 != null) {
+            if (l1.val < l2.val) {
+                lastNode.next = l1;
+                l1 = l1.next;
+            } else {
+                lastNode.next = l2;
+                l2 = l2.next;
+            }
+            lastNode = lastNode.next;
+        }
+        
+        if (l1 != null) {
+            lastNode.next = l1;
+        } else {
+            lastNode.next = l2;
+        }
+        
+        return dummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/middle-of-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/middle-of-linked-list.md"
new file mode 100644
index 0000000..e732313
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/middle-of-linked-list.md"
@@ -0,0 +1,49 @@
+# 链表的中点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/middle-of-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 找链表的中点。
+ ### 样例说明
+ **样例 1:**
+```
+输入:  1->2->3
+输出: 2	
+样例解释: 返回中间节点的值
+```
+**样例 2:**
+```
+输入:  1->2
+输出: 1	
+样例解释: 如果长度是偶数，则返回中间偏左的节点的值。	
+```	
+ ### 参考代码
+ 这里使用快慢指针的方法来寻找终点。
+可以确保时间复杂度是 O(n/2)
+
+快指针每次两步，慢指针每次一步。
+快指针到尾的时候，慢指针就是中点。
+```python
+"""
+Definition of ListNode
+class ListNode(object):
+
+    def __init__(self, val, next=None):
+        self.val = val
+        self.next = next
+"""
+
+class Solution:
+    # @param head: the head of linked list.
+    # @return: a middle node of the linked list
+    def middleNode(self, head):
+        # Write your code here
+        if head is None:
+            return None
+        slow = head
+        fast = slow.next
+        while fast is not None and fast.next is not None:
+            slow = slow.next
+            fast = fast.next.next
+
+        return slow
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/nth-to-last-node-in-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/nth-to-last-node-in-list.md"
new file mode 100644
index 0000000..9d88983
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/nth-to-last-node-in-list.md"
@@ -0,0 +1,48 @@
+# 链表倒数第n个节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/nth-to-last-node-in-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>找到单链表倒数第n个节点，保证链表中节点的最少数量为n。</p>
+ ### 样例说明
+ 
+ ### 参考代码
+ 两个指针，先让快指针走n步， 然后一起走，快指针到头的时候，慢指针就是倒数第n个。
+```java
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+public class Solution {
+    /**
+     * @param head: The first node of linked list.
+     * @param n: An integer.
+     * @return: Nth to last node of a singly linked list. 
+     */
+    ListNode nthToLast(ListNode head, int n) {
+        if (head == null || n < 1) {
+            return null;
+        }
+	
+        ListNode p1 = head;
+        ListNode p2 = head;
+        for (int j = 0; j < n - 1; ++j) {
+            if (p2 == null) {
+                return null;
+            }
+            p2 = p2.next;
+        }
+        while (p2.next != null) {   
+            p1 = p1.next;   
+            p2 = p2.next;
+	    }
+	    return p1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/palindrome-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/palindrome-linked-list.md"
new file mode 100644
index 0000000..7da1448
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/palindrome-linked-list.md"
@@ -0,0 +1,72 @@
+# 回文链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/palindrome-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一种方式检查一个链表是否为回文链表。
+ ### 样例说明
+ **样例 1:**
+```
+输入: 1->2->1
+输出: true
+```
+
+**样例 2:**
+```
+输入: 2->2->1
+输出: false
+```
+
+ ### 参考代码
+ ```java
+// This code would destroy the original structure of the linked list.
+// If you do not want to destroy the structure, you can reserve the second part back.
+public class Solution {
+    /**
+     * @param head a ListNode
+     * @return a boolean
+     */
+    public boolean isPalindrome(ListNode head) {
+        if (head == null) {
+            return true;
+        }
+        
+        ListNode middle = findMiddle(head);
+        middle.next = reverse(middle.next);
+        
+        ListNode p1 = head, p2 = middle.next;
+        while (p1 != null && p2 != null && p1.val == p2.val) {
+            p1 = p1.next;
+            p2 = p2.next;
+        }
+        
+        return p2 == null;
+    }
+    
+    private ListNode findMiddle(ListNode head) {
+        if (head == null) {
+            return null;
+        }
+        ListNode slow = head, fast = head.next;
+        while (fast != null && fast.next != null) {
+            slow = slow.next;
+            fast = fast.next.next;
+        }
+        
+        return slow;
+    }
+    
+    private ListNode reverse(ListNode head) {
+        ListNode prev = null;
+        
+        while (head != null) {
+            ListNode temp = head.next;
+            head.next = prev;
+            prev = head;
+            head = temp;
+        }
+        
+        return prev;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-duplicates-from-sorted-list-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-duplicates-from-sorted-list-ii.md"
new file mode 100644
index 0000000..2b4f2ea
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-duplicates-from-sorted-list-ii.md"
@@ -0,0 +1,51 @@
+# 删除排序链表中的重复数字 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-duplicates-from-sorted-list-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个排序链表，删除所有重复的元素只留下原链表中没有重复的元素。
+
+ ### 样例说明
+ ***样例 1***
+```
+输入 : 1->2->3->3->4->4->5->null
+输出 : 1->2->5->null
+```
+
+***样例 2***
+```
+输入 : 1->1->1->2->3->null
+输出 : 2->3->null
+```
+ ### 参考代码
+ Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
+
+For example,
+Given 1->2->3->3->4->4->5, return 1->2->5.
+Given 1->1->1->2->3, return 2->3.
+```java
+
+public class Solution {
+    public ListNode deleteDuplicates(ListNode head) {
+        if(head == null || head.next == null)
+            return head;
+        
+        ListNode dummy = new ListNode(0);
+        dummy.next = head;
+        head = dummy;
+
+        while (head.next != null && head.next.next != null) {
+            if (head.next.val == head.next.next.val) {
+                int val = head.next.val;
+                while (head.next != null && head.next.val == val) {
+                    head.next = head.next.next;
+                }            
+            } else {
+                head = head.next;
+            }
+        }
+        
+        return dummy.next;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-duplicates-from-sorted-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-duplicates-from-sorted-list.md"
new file mode 100644
index 0000000..b5471cb
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-duplicates-from-sorted-list.md"
@@ -0,0 +1,49 @@
+# 删除排序链表中的重复元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-duplicates-from-sorted-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个排序链表，删除所有重复的元素每个元素只留下一个。
+ ### 样例说明
+ ```
+样例 1:
+	输入:  null
+	输出: null
+
+
+样例 2:
+	输入: 1->1->2->null
+	输出: 1->2->null
+
+样例 3:
+	输入: 1->1->2->3->3->null
+	输出: 1->2->3->null
+
+
+```
+ ### 参考代码
+ Given a sorted linked list, delete all duplicates such that each element appear only once.
+
+For example,
+Given 1->1->2, return 1->2.
+Given 1->1->2->3->3, return 1->2->3.
+
+跳过相同的元素，指向再后一个元素。
+```java
+public class Solution {
+    public ListNode deleteDuplicates(ListNode head) {
+        if (head == null) {
+            return null;
+        }
+
+        ListNode node = head;
+        while (node.next != null) {
+            if (node.val == node.next.val) {
+                node.next = node.next.next;
+            } else {
+                node = node.next;
+            }
+        }
+        return head;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-duplicates-from-unsorted-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-duplicates-from-unsorted-list.md"
new file mode 100644
index 0000000..1aec004
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-duplicates-from-unsorted-list.md"
@@ -0,0 +1,54 @@
+# 无序链表的重复项删除
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-duplicates-from-unsorted-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一种方法，从无序链表中删除重复项。
+ ### 样例说明
+ **样例 1：**
+```
+输入：1->2->1->3->3->5->6->3->null
+输出：1->2->3->5->6->null
+```
+**样例 2：**
+```
+输入：2->2->2->2->2->null
+输出：2->null
+```
+ ### 参考代码
+ ```java
+/**
+ * Definition for ListNode
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int x) {
+ *         val = x;
+ *         next = null;
+ *     }
+ * }
+ */
+public class Solution {
+    /**
+     * @param head: The first node of linked list.
+     * @return: head node
+     */
+    public ListNode removeDuplicates(ListNode head) { 
+        HashSet<Integer> hash = new HashSet<Integer>();
+        
+        ListNode dummy = new ListNode(0);
+        dummy.next = head;
+        head = dummy;
+        while (head.next != null) {
+            if (hash.contains(head.next.val)) {
+                head.next = head.next.next;
+            } else {
+                hash.add(head.next.val);
+                head = head.next;
+            }
+        }
+        
+        return dummy.next;
+    }  
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-linked-list-elements.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-linked-list-elements.md"
new file mode 100644
index 0000000..814c364
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-linked-list-elements.md"
@@ -0,0 +1,51 @@
+# 删除链表中的元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-linked-list-elements/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 删除链表中等于给定值 `val` 的所有节点。
+ ### 样例说明
+ **样例 1：**
+```
+输入：head = 1->2->3->3->4->5->3->null, val = 3
+输出：1->2->4->5->null
+```
+**样例 2：**
+```
+输入：head = 1->1->null, val = 1
+输出：null
+```
+
+ ### 参考代码
+ ```java
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    /**
+     * @param head a ListNode
+     * @param val an integer
+     * @return a ListNode
+     */
+    public ListNode removeElements(ListNode head, int val) {
+        ListNode dummy = new ListNode(0);
+        dummy.next = head;
+        head = dummy;
+        
+        while (head.next != null) {
+            if (head.next.val == val) {
+                head.next = head.next.next;
+            } else {
+                head = head.next;
+            }
+        }
+        
+        return dummy.next;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-nth-node-from-end-of-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-nth-node-from-end-of-list.md"
new file mode 100644
index 0000000..cf24ce5
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/remove-nth-node-from-end-of-list.md"
@@ -0,0 +1,40 @@
+# 删除链表中倒数第n个节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-nth-node-from-end-of-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">给定一个链表，删除链表中倒数第n个节点，返回链表的头节点。</span><br></p><p><br></p>
+ ### 样例说明
+ 
+ ### 参考代码
+ Given a linked list, remove the nth node from the end of list and return its head.
+
+For example,
+
+   Given linked list: 1->2->3->4->5, and n = 2.
+
+   After removing the second node from the end, the linked list becomes 1->2->3->5.
+Note:
+Given n will always be valid.
+Try to do this in one pass.
+
+先让快指针走n步，然后快慢一起走，走到头的时候慢指针指向的点删掉。
+```python
+class Solution(object):
+    '''
+    题意：删除链表中倒数第n个结点，尽量只扫描一遍。
+    使用两个指针扫描，当第一个指针扫描到第N个结点后，
+    第二个指针从表头与第一个指针同时向后移动，
+    当第一个指针指向空节点时，另一个指针就指向倒数第n个结点了       
+    '''
+    def removeNthFromEnd(self, head, n):
+        res = ListNode(0)
+        res.next = head
+        tmp = res
+        for i in range(0, n):
+            head = head.next
+        while head != None:
+            head = head.next
+            tmp = tmp.next
+        tmp.next = tmp.next.next
+        return res.next
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reorder-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reorder-list.md"
new file mode 100644
index 0000000..c6d66b9
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reorder-list.md"
@@ -0,0 +1,89 @@
+# 重排链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reorder-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个单链表L: *L*<sub>0</sub>→*L*<sub>1</sub>→…→*L*<sub>n-1</sub>→*L*<sub>n</sub>,
+
+重新排列后为：*L*<sub>0</sub>→*L*<sub>n</sub>→*L*<sub>1</sub>→*L*<sub>n-1</sub>→*L*<sub>2</sub>→*L*<sub>n-2</sub>→…
+
+必须在不改变节点值的情况下进行原地操作。
+ ### 样例说明
+ ```
+样例 1:
+	输入: 1->2->3->4->null
+	输出: 1->4->2->3->null
+
+样例 2:
+	输入: 1->2->3->4->5->null
+	输出: 1->5->2->4->3->null
+	
+```
+
+
+
+ ### 参考代码
+ Given a singly linked list L: L0→L1→…→Ln-1→Ln,
+reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
+
+You must do this in-place without altering the nodes' values.
+
+For example,
+Given {1,2,3,4}, reorder it to {1,4,2,3}.
+
+先找到中点，然后把后半段倒过来，然后前后交替合并。
+```java
+public class Solution {
+    private ListNode reverse(ListNode head) {
+        ListNode newHead = null;
+        while (head != null) {
+            ListNode temp = head.next;
+            head.next = newHead;
+            newHead = head;
+            head = temp;
+        }
+        return newHead;
+    }
+
+    private void merge(ListNode head1, ListNode head2) {
+        int index = 0;
+        ListNode dummy = new ListNode(0);
+        while (head1 != null && head2 != null) {
+            if (index % 2 == 0) {
+                dummy.next = head1;
+                head1 = head1.next;
+            } else {
+                dummy.next = head2;
+                head2 = head2.next;
+            }
+            dummy = dummy.next;
+            index ++;
+        }
+        if (head1 != null) {
+            dummy.next = head1;
+        } else {
+            dummy.next = head2;
+        }
+    }
+
+    private ListNode findMiddle(ListNode head) {
+        ListNode slow = head, fast = head.next;
+        while (fast != null && fast.next != null) {
+            fast = fast.next.next;
+            slow = slow.next;
+        }
+        return slow;
+    }
+
+    public void reorderList(ListNode head) {
+        if (head == null || head.next == null) {
+            return;
+        }
+
+        ListNode mid = findMiddle(head);
+        ListNode tail = reverse(mid.next);
+        mid.next = null;
+
+        merge(head, tail);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reverse-linked-list-ii.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reverse-linked-list-ii.md"
new file mode 100644
index 0000000..7bbb4f7
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reverse-linked-list-ii.md"
@@ -0,0 +1,70 @@
+# 翻转链表 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reverse-linked-list-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>翻转链表中第m个节点到第n个节点的部分</p>
+ ### 样例说明
+ 例1:
+```
+输入: 1->2->3->4->5->NULL, m = 2 and n = 4, 
+输出: 1->4->3->2->5->NULL.
+```
+
+例2:
+```
+输入: 1->2->3->4->NULL, m = 2 and n = 3, 
+输出: 1->3->2->4->NULL.
+```
+
+
+ ### 参考代码
+ 1. 创建head.
+2. 找到m的前一个节点-Pre
+3. 记录Pre的下一个节点，它会是翻转链的尾部。
+4. 翻转指定区间的链表，翻到最后一个节点时，把reverseTail.next指向它的next。这样就把翻转链表与之后
+的链表接起来了。
+5. 返回dummynode的下一个节点。
+```java
+/**
+ * Definition for ListNode
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ * }
+ */
+public class Solution {
+    public ListNode reverseBetween(ListNode head, int m, int n) {
+        if (m >= n || head == null) {
+            return head;
+        }
+        
+        ListNode dummy = new ListNode(0);
+        dummy.next = head;
+        head = dummy;
+        
+        for (int i = 1; i < m; i++) {
+            if (head == null) {
+                return null;
+            }
+            head = head.next;
+        }
+        
+        ListNode premNode = head;
+        ListNode mNode = head.next;
+        ListNode nNode = mNode, postnNode = mNode.next;
+        for (int i = m; i < n; i++) {
+            if (postnNode == null) {
+                return null;
+            }
+            ListNode temp = postnNode.next;
+            postnNode.next = nNode;
+            nNode = postnNode;
+            postnNode = temp;
+        }
+        mNode.next = postnNode;
+        premNode.next = nNode;
+        
+        return dummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reverse-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reverse-linked-list.md"
new file mode 100644
index 0000000..4cdf2dd
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reverse-linked-list.md"
@@ -0,0 +1,35 @@
+# 翻转链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reverse-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>翻转一个链表</p>
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 1->2->3->null
+输出: 3->2->1->null
+```
+
+**样例 2:**
+
+```
+输入: 1->2->3->4->null
+输出: 4->3->2->1->null
+```
+ ### 参考代码
+ http://www.lintcode.com/zh-cn/problem/reverse-linked-list/
+```python
+class Solution:
+
+    def reverse(self, head):
+        #curt表示前继节点
+        curt = None
+        while head != None:
+            #temp记录下一个节点，head是当前节点
+            temp = head.next
+            head.next = curt
+            curt = head
+            head = temp
+        return curt
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reverse-nodes-in-k-group.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reverse-nodes-in-k-group.md"
new file mode 100644
index 0000000..23a0833
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/reverse-nodes-in-k-group.md"
@@ -0,0 +1,56 @@
+# K组翻转链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reverse-nodes-in-k-group/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个链表以及一个*k*,将这个链表从头指针开始每*k*个翻转一下。
+链表元素个数不是*k*的倍数，最后剩余的不用翻转。
+ ### 样例说明
+ 
+ ### 参考代码
+ Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
+
+If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
+
+You may not alter the values in the nodes, only nodes itself may be changed.
+
+Only constant memory is allowed.
+
+For example,
+Given this linked list: 1->2->3->4->5
+
+For k = 2, you should return: 2->1->4->3->5
+
+For k = 3, you should return: 3->2->1->4->5
+```python
+# Definition for singly-linked list.
+# class ListNode:
+#     def __init__(self, x):
+#         self.val = x
+#         self.next = None
+
+class Solution:
+    # @param head, a ListNode
+    # @param k, an integer
+    # @return a ListNode
+    def reverse(self, start, end):
+        # Write your code here
+        newhead=ListNode(0); newhead.next=start
+        while newhead.next!=end:
+            tmp=start.next
+            start.next=tmp.next
+            tmp.next=newhead.next
+            newhead.next=tmp
+        return [end, start]
+    def reverseKGroup(self, head, k):
+        if head==None: return None
+        nhead=ListNode(0); nhead.next=head; start=nhead
+        while start.next:
+            end=start
+            for i in range(k-1):
+                end=end.next
+                if end.next==None: return nhead.next
+            res=self.reverse(start.next, end.next)
+            start.next=res[0]
+            start=res[1]
+        return nhead.next
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/rotate-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/rotate-list.md"
new file mode 100644
index 0000000..1bba30b
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/rotate-list.md"
@@ -0,0 +1,64 @@
+# 旋转链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/rotate-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">给定一个链表，</span><span style="line-height: 1.42857143;">旋转链表，使得每个节点向右移动</span><span style="line-height: 1.42857143;">k个位置，其中k是一个非负数</span></p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：1->2->3->4->5  k = 2
+输出：4->5->1->2->3
+```
+
+**样例 2:**
+```
+输入：3->2->1  k = 1
+输出：1->3->2
+```
+ ### 参考代码
+ Given a list, rotate the list to the right by k places, where k is non-negative.
+
+For example:
+Given 1->2->3->4->5->NULL and k = 2,
+return 4->5->1->2->3->NULL.
+```java
+public class Solution {
+    private int getLength(ListNode head) {
+        int length = 0;
+        while (head != null) {
+            length ++;
+            head = head.next;
+        }
+        return length;
+    }
+    
+    public ListNode rotateRight(ListNode head, int n) {
+        if (head == null) {
+            return null;
+        }
+        
+        int length = getLength(head);
+        n = n % length;
+        
+        ListNode dummy = new ListNode(0);
+        dummy.next = head;
+        head = dummy;
+        
+        ListNode tail = dummy;
+        for (int i = 0; i < n; i++) {
+            head = head.next;
+        }
+        
+        while (head.next != null) {
+            tail = tail.next;
+            head = head.next;
+        }
+        
+        head.next = dummy.next;
+        dummy.next = tail.next;
+        tail.next = null;
+        return dummy.next;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/sort-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/sort-list.md"
new file mode 100644
index 0000000..fe9dc4f
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/sort-list.md"
@@ -0,0 +1,239 @@
+# 链表排序
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sort-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在 O(*n* log *n*) 时间复杂度和常数级的空间复杂度下给链表排序。
+
+ ### 样例说明
+ ```
+样例 1:
+	输入:  1->3->2->null
+	输出:  1->2->3->null
+
+样例 2:
+	输入: 1->7->2->6->null
+	输出: 1->2->6->7->null
+	
+```
+ ### 参考代码
+ Sort a linked list in O(n log n) time using constant space complexity.<div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博:&nbsp;</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/ByB4LtgnG" target="_blank">http://weibo.com/3948019741/ByB4LtgnG</a></span></font><br></div>
+
+
+快速排序算法可以在链表中使用。
+```java
+// version 1: Merge Sort
+public class Solution {            
+    private ListNode findMiddle(ListNode head) {
+        ListNode slow = head, fast = head.next;
+        while (fast != null && fast.next != null) {
+            fast = fast.next.next;
+            slow = slow.next;
+        }
+        return slow;
+    }    
+
+    private ListNode merge(ListNode head1, ListNode head2) {
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (head1 != null && head2 != null) {
+            if (head1.val < head2.val) {
+                tail.next = head1;
+                head1 = head1.next;
+            } else {
+                tail.next = head2;
+                head2 = head2.next;
+            }
+            tail = tail.next;
+        }
+        if (head1 != null) {
+            tail.next = head1;
+        } else {
+            tail.next = head2;
+        }
+
+        return dummy.next;
+    }
+
+    public ListNode sortList(ListNode head) {
+        if (head == null || head.next == null) {
+            return head;
+        }
+
+        ListNode mid = findMiddle(head);
+
+        ListNode right = sortList(mid.next);
+        mid.next = null;
+        ListNode left = sortList(head);
+
+        return merge(left, right);
+    }
+}
+
+// version 2: Quick Sort 1
+public class Solution {
+    public ListNode sortList(ListNode head) {
+        if (head == null || head.next == null) {
+            return head;
+        }
+        
+        ListNode mid = findMedian(head); // O(n)
+        
+        ListNode leftDummy = new ListNode(0), leftTail = leftDummy;
+        ListNode rightDummy = new ListNode(0), rightTail = rightDummy;
+        ListNode middleDummy = new ListNode(0), middleTail = middleDummy;
+        while (head != null) {
+            if (head.val < mid.val) {
+                leftTail.next = head;
+                leftTail = head;
+            } else if (head.val > mid.val) {
+                rightTail.next = head;
+                rightTail = head;
+            } else {
+                middleTail.next = head;
+                middleTail = head;
+            }
+            head = head.next;
+        }
+        
+        leftTail.next = null;
+        middleTail.next = null;
+        rightTail.next = null;
+        
+        ListNode left = sortList(leftDummy.next);
+        ListNode right = sortList(rightDummy.next);
+        
+        return concat(left, middleDummy.next, right);
+    }
+    
+    private ListNode findMedian(ListNode head) {
+        ListNode slow = head, fast = head.next;
+        while (fast != null && fast.next != null) {
+            slow = slow.next;
+            fast = fast.next.next;
+        }
+        return slow;
+    }
+    
+    private ListNode concat(ListNode left, ListNode middle, ListNode right) {
+        ListNode dummy = new ListNode(0), tail = dummy;
+        
+        tail.next = left; tail = getTail(tail);
+        tail.next = middle; tail = getTail(tail);
+        tail.next = right; tail = getTail(tail);
+        return dummy.next;
+    }
+    
+    private ListNode getTail(ListNode head) {
+        if (head == null) {
+           return null;
+        } 
+       
+        while (head.next != null) {
+            head = head.next;
+        }
+        return head;
+    }
+}
+
+// version 3: Quick Sort 2
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+class Pair {
+    public ListNode first, second; 
+    public Pair(ListNode first, ListNode second) {
+        this.first = first;
+        this.second = second;
+    }
+}
+
+public class Solution {
+    /**
+     * @param head: The head of linked list.
+     * @return: You should return the head of the sorted linked list,
+                    using constant space complexity.
+     */
+    public ListNode sortList(ListNode head) {
+        if (head == null || head.next == null) {
+            return head;
+        }
+        
+        ListNode mid = findMedian(head); // O(n)
+        Pair pair = partition(head, mid.val); // O(n)
+        
+        ListNode left = sortList(pair.first);
+        ListNode right = sortList(pair.second);
+        
+        getTail(left).next = right; // O(n)
+        
+        return left;
+    }
+    
+    // 1->2->3 return 2
+    // 1->2 return 1
+    private ListNode findMedian(ListNode head) {
+        ListNode slow = head, fast = head.next;
+        while (fast != null && fast.next != null) {
+            slow = slow.next;
+            fast = fast.next.next;
+        }
+        return slow;
+    }
+    
+    // < value in the left, > value in the right
+    private Pair partition(ListNode head, int value) {
+        ListNode leftDummy = new ListNode(0), leftTail = leftDummy;
+        ListNode rightDummy = new ListNode(0), rightTail = rightDummy;
+        ListNode equalDummy = new ListNode(0), equalTail = equalDummy;
+        while (head != null) {
+            if (head.val < value) {
+                leftTail.next = head;
+                leftTail = head;
+            } else if (head.val > value) {
+                rightTail.next = head;
+                rightTail = head;
+            } else {
+                equalTail.next = head;
+                equalTail = head;
+            }
+            head = head.next;
+        }
+        
+        leftTail.next = null;
+        rightTail.next = null;
+        equalTail.next = null;
+        
+        if (leftDummy.next == null && rightDummy.next == null) {
+            ListNode mid = findMedian(equalDummy.next);
+            leftDummy.next = equalDummy.next;
+            rightDummy.next = mid.next;
+            mid.next = null;
+        } else if (leftDummy.next == null) {
+            leftTail.next = equalDummy.next;
+        } else {
+            rightTail.next = equalDummy.next;
+        }
+        
+        return new Pair(leftDummy.next, rightDummy.next);
+    }
+    
+    private ListNode getTail(ListNode head) {
+        if (head == null) {
+           return null;
+        } 
+       
+        while (head.next != null) {
+            head = head.next;
+        }
+        return head;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/swap-nodes-in-pairs.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/swap-nodes-in-pairs.md"
new file mode 100644
index 0000000..fe5b01a
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/swap-nodes-in-pairs.md"
@@ -0,0 +1,59 @@
+# 两两交换链表中的节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/swap-nodes-in-pairs/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个链表，两两交换其中的节点，然后返回交换后的链表。
+ ### 样例说明
+ **样例 1：**
+```
+输入：1->2->3->4->null
+输出：2->1->4->3->null
+```
+**样例 2：**
+```
+输入：5->null
+输出：5->null
+```
+ ### 参考代码
+ Given a linked list, swap every two adjacent nodes and return its head.
+
+For example,
+Given 1->2->3->4, you should return the list as 2->1->4->3.
+
+Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
+```java
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    /**
+     * @param head a ListNode
+     * @return a ListNode
+     */
+    public ListNode swapPairs(ListNode head) {
+        ListNode dummy = new ListNode(0);
+        dummy.next = head;
+        
+        head = dummy;
+        while (head.next != null && head.next.next != null) {
+            ListNode n1 = head.next, n2 = head.next.next;
+            // head->n1->n2->...
+            // => head->n2->n1->...
+            head.next = n2;
+            n1.next = n2.next;
+            n2.next = n1;
+            
+            // move to next pair
+            head = n1;
+        }
+        
+        return dummy.next;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/swap-two-nodes-in-linked-list.md" "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/swap-two-nodes-in-linked-list.md"
new file mode 100644
index 0000000..d2da1b1
--- /dev/null
+++ "b/\346\225\260\346\215\256\347\273\223\346\236\204/\351\223\276\350\241\250/swap-two-nodes-in-linked-list.md"
@@ -0,0 +1,89 @@
+# 交换链表当中两个节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/swap-two-nodes-in-linked-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个链表以及两个权值`v1`和`v2`，交换链表中权值为`v1`和`v2`的这两个节点。保证链表中节点权值各不相同，如果没有找到对应节点，那么什么也不用做。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 1->2->3->4->null, v1 = 2, v2 = 4
+输出: 1->4->3->2->null
+```
+
+**样例 2:**
+
+```
+输入: 1->null, v1 = 2, v2 = 1
+输出: 1->null
+```
+ ### 参考代码
+ 因为数据结构是单链表, 所以假设需要修改权值为 `v` 的节点的链接, 那么需要获取该节点的前驱节点.
+
+我们需要定义一个虚节点, 作为链表头, 它不储存数据.
+
+找到权值为 `v1` 和 `v2` 的节点之后, 分情况讨论:
+
+- 如果二者本身是相邻的, 则一共需要修改三条边(即三个next关系) {a node} -> {v = v1} -> {v = v2} -> {a node}
+- 如果二者是不相邻的, 则一共需要修改四条边 {a node} -> {v = v1} -> {some nodes} -> {v = v2} -> {a node} (假定v1在v2前)
+```java
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int x) { val = x; }
+ * }
+ */
+public class Solution {
+    /**
+     * @param head a ListNode
+     * @oaram v1 an integer
+     * @param v2 an integer
+     * @return a new head of singly-linked list
+     */
+    public ListNode swapNodes(ListNode head, int v1, int v2) {
+        ListNode dummy = new ListNode(0);
+        dummy.next = head;
+        
+        ListNode node1Prev = null, node2Prev = null;
+        ListNode cur = dummy;
+        while (cur.next != null) {
+            if (cur.next.val == v1) {
+                node1Prev = cur;
+            } else if (cur.next.val == v2) {
+                node2Prev = cur;
+            }
+            cur = cur.next;
+        }
+        
+        if (node1Prev == null || node2Prev == null) {
+            return head;
+        }
+        
+        if (node2Prev.next == node1Prev) {
+            // make sure node2Prev.next is not node1Prev
+            ListNode t = node1Prev;
+            node1Prev = node2Prev;
+            node2Prev = t;
+        }
+        
+        ListNode node1 = node1Prev.next;
+        ListNode node2 = node2Prev.next;
+        ListNode node2Next = node2.next;
+        if (node1Prev.next == node2Prev) {
+            node1Prev.next = node2;
+            node2.next = node1;
+            node1.next = node2Next;
+        } else {
+            node1Prev.next = node2;
+            node2.next = node1.next;
+            
+            node2Prev.next = node1;
+            node1.next = node2Next;
+        }
+        
+        return dummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/lowest-common-ancestor-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/lowest-common-ancestor-ii.md"
new file mode 100644
index 0000000..678e735
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/lowest-common-ancestor-ii.md"
@@ -0,0 +1,178 @@
+# 最近公共祖先 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/lowest-common-ancestor-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树和二叉树中的两个节点，找到这两个节点的最近公共祖先`LCA`。
+
+两个节点的最近公共祖先，是指两个节点的所有父亲节点中（包括这两个节点），离这两个节点最近的公共的节点。
+
+每个节点除了左右儿子指针以外，还包含一个父亲指针`parent`，指向自己的父亲。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{4,3,7,#,#,5,6},3,5
+输出：4
+解释：
+     4
+     / \
+    3   7
+       / \
+      5   6
+LCA(3, 5) = 4
+```
+**样例 2:**
+```
+输入：{4,3,7,#,#,5,6},5,6
+输出：7
+解释：
+      4
+     / \
+    3   7
+       / \
+      5   6
+LCA(5, 6) = 7
+```
+ ### 参考代码
+ 将两个结点移动到相同的高度，然后同时向上移动，直到移动到相同的点
+```
+[[java]]
+/**
+ * Definition of ParentTreeNode:
+ * 
+ * class ParentTreeNode {
+ *     public ParentTreeNode parent, left, right;
+ * }
+ */
+public class Solution {
+    /**
+     * @param root: The root of the tree
+     * @param A, B: Two node in the tree
+     * @return: The lowest common ancestor of A and B
+     */
+    public ParentTreeNode lowestCommonAncestorII(ParentTreeNode root,
+                                                 ParentTreeNode A,
+                                                 ParentTreeNode B) {
+        ArrayList<ParentTreeNode> pathA = getPath2Root(A);
+        ArrayList<ParentTreeNode> pathB = getPath2Root(B);
+        
+        int indexA = pathA.size() - 1;
+        int indexB = pathB.size() - 1;
+        
+        ParentTreeNode lowestAncestor = null;
+        while (indexA >= 0 && indexB >= 0) {
+            if (pathA.get(indexA) != pathB.get(indexB)) {
+                break;
+            }
+            lowestAncestor = pathA.get(indexA);
+            indexA--;
+            indexB--;
+        }
+        
+        return lowestAncestor;
+    }
+    
+    private ArrayList<ParentTreeNode> getPath2Root(ParentTreeNode node) {
+        ArrayList<ParentTreeNode> path = new ArrayList<>();
+        while (node != null) {
+            path.add(node);
+            node = node.parent;
+        }
+        return path;
+    }
+}
+[[python]]
+"""
+Definition of ParentTreeNode:
+class ParentTreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.parent, self.left, self.right = None, None, None
+"""
+class Solution:
+    """
+    @param root: The root of the tree
+    @param A and B: Two node in the tree
+    @return: The lowest common ancestor of A and B
+    """ 
+    def lowestCommonAncestorII(self, root, A, B):
+        visited = set()
+        while A is not root:
+            visited.add(A)
+            A = A.parent
+
+        while B is not root:
+            if B in visited:
+                return B
+            B = B.parent
+
+        return root
+[[c++]]
+/**
+ * Definition of ParentTreeNode:
+ * class ParentTreeNode {
+ * public:
+ *     int val;
+ *     ParentTreeNode *parent, *left, *right;
+ * }
+ */
+class Solution {
+public:
+    /**
+     * @param root: The root of the tree
+     * @param A, B: Two node in the tree
+     * @return: The lowest common ancestor of A and B
+     */
+    int Atop, Btop, top;
+    ParentTreeNode *a[100000], *b[100000], *ans[100000];
+    bool find;
+    void inorder(ParentTreeNode *node, ParentTreeNode *A, int flag) { 
+        if (find==true)
+            return;
+        if (node == NULL)
+            return;
+        ans[++top] = node;
+        if (A == node) {
+            find = true;
+            if (flag == 0) {
+                Atop = top;
+                for (int i = 1; i <= top; ++i)
+                    a[i] = ans[i];
+            } else {
+                Btop = top;
+                for (int i = 1; i <= top; ++i)
+                    b[i] = ans[i];
+            }
+            return;
+        }
+
+        inorder(node->left, A, flag);
+        if (find) return;
+            
+        inorder(node->right, A, flag);
+        if (find) return;
+          
+        top --;
+        
+    }
+
+    ParentTreeNode *lowestCommonAncestorII(ParentTreeNode *root,
+                                           ParentTreeNode *A,
+                                           ParentTreeNode *B) {
+        // Write your code here
+        top = 0; find = false;
+        inorder(root, A, 0);
+
+        top = 0; find = false;
+        inorder(root, B, 1);
+  
+        Atop = min(Atop, Btop);
+        Btop = Atop;
+
+        while (a[Atop] != b[Btop]) {
+            Atop --;
+            Btop --;
+        }
+        return a[Atop];
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/lowest-common-ancestor-iii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/lowest-common-ancestor-iii.md"
new file mode 100644
index 0000000..f10defb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/lowest-common-ancestor-iii.md"
@@ -0,0 +1,99 @@
+# 最近公共祖先 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/lowest-common-ancestor-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树和二叉树中的两个节点，找到这两个节点的最近公共祖先LCA。
+
+两个节点的最近公共祖先，是指两个节点的所有父亲节点中（包括这两个节点），离这两个节点最近的公共的节点。
+
+返回 `null` 如果两个节点在这棵树上不存在最近公共祖先的话。
+ ### 样例说明
+ **样例1**
+
+```
+输入: 
+{4, 3, 7, #, #, 5, 6}
+3 5
+5 6
+6 7 
+5 8
+输出: 
+4
+7
+7
+null
+解释:
+  4
+ / \
+3   7
+   / \
+  5   6
+
+LCA(3, 5) = 4
+LCA(5, 6) = 7
+LCA(6, 7) = 7
+LCA(5, 8) = null
+
+```
+
+**样例2**
+
+```
+输入:
+{1}
+1 1
+输出: 
+1
+说明：
+这棵树只有一个值为1的节点
+```
+
+ ### 参考代码
+ 每次返回 是否在左子树中找到了节点A，是否在右子树中找到了节点B，以及是否已经找到了LCA，
+这三个结果。然后分类讨论。如果已经在子树中找到了LCA,就直接return。否则，如果当前节点是
+A且在子树中找到了B，或者当前节点是B且已经在子树中找到了A，就说明当前节点是LCA。
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+import copy
+class Solution:
+    """
+    @param {TreeNode} root The root of the binary tree.
+    @param {TreeNode} A and {TreeNode} B two nodes
+    @return Return the LCA of the two nodes.
+    """ 
+    def lowestCommonAncestor3(self, root, A, B):
+        # write your code here
+        a, b, lca = self.helper(root, A, B)
+        if a and b:
+            return lca
+        else:
+            return None
+
+    def helper(self, root, A, B):
+        if root is None:
+            return False, False, None
+            
+        left_a, left_b, left_node = self.helper(root.left, A, B)
+        right_a, right_b, right_node = self.helper(root.right, A, B)
+        
+        a = left_a or right_a or root == A
+        b = left_b or right_b or root == B
+        
+        if root == A or root == B:
+            return a, b, root
+
+        if left_node is not None and right_node is not None:
+            return a, b, root
+        if left_node is not None:
+            return a, b, left_node
+        if right_node is not None:
+            return a, b, right_node
+
+        return a, b, None
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/lowest-common-ancestor.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/lowest-common-ancestor.md"
new file mode 100644
index 0000000..5724aa4
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/lowest-common-ancestor.md"
@@ -0,0 +1,42 @@
+# 最近公共祖先
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/lowest-common-ancestor/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一棵二叉树，找到两个节点的最近公共父节点(LCA)。</p><p>最近公共祖先是两个节点的公共的祖先节点且具有最大深度。</p>
+ ### 样例说明
+ 
+ ### 参考代码
+ LCA
+```java
+Version : Divide & Conquer
+
+public class Solution {
+    // 在root为根的二叉树中找A,B的LCA:
+    // 如果找到了就返回这个LCA
+    // 如果只碰到A，就返回A
+    // 如果只碰到B，就返回B
+    // 如果都没有，就返回null
+    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode node1, TreeNode node2) {
+        if (root == null || root == node1 || root == node2) {
+            return root;
+        }
+        
+        // Divide
+        TreeNode left = lowestCommonAncestor(root.left, node1, node2);
+        TreeNode right = lowestCommonAncestor(root.right, node1, node2);
+        
+        // Conquer
+        if (left != null && right != null) {
+            return root;
+        } 
+        if (left != null) {
+            return left;
+        }
+        if (right != null) {
+            return right;
+        }
+        return null;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/permutation-sequence.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/permutation-sequence.md"
new file mode 100644
index 0000000..6653542
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/permutation-sequence.md"
@@ -0,0 +1,64 @@
+# 第k个排列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/permutation-sequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定 *n* 和 *k*，求n的全排列中字典序第k个排列.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: n = 3, k = 4
+输出: "231"
+解释: 
+n = 3时, 全排列如下:
+"123", "132", "213", "231", "312", "321"
+```
+
+**样例 2:**
+
+```
+输入: n = 1, k = 1
+输出: "1"
+```
+ ### 参考代码
+ 康拓展开的应用, 模板题.
+
+康拓展开, 计算排列与字典序排名的映射关系.
+
+[维基百科 康拓展开](https://zh.wikipedia.org/wiki/%E5%BA%B7%E6%89%98%E5%B1%95%E5%BC%80)
+```java
+public class Solution {
+
+    public String getPermutation(int n, int k) {
+        StringBuilder sb = new StringBuilder();
+        boolean[] used = new boolean[n];
+
+        k = k - 1;
+        int factor = 1;
+        for (int i = 1; i < n; i++) {
+            factor *= i;
+        }
+
+        for (int i = 0; i < n; i++) {
+            int index = k / factor;
+            k = k % factor;
+            for (int j = 0; j < n; j++) {
+                if (used[j] == false) {
+                    if (index == 0) {
+                        used[j] = true;
+                        sb.append((char) ('0' + j + 1));
+                        break;
+                    } else {
+                        index--;
+                    }
+                }
+            }
+            if (i < n - 1) {
+                factor = factor / (n - 1 - i);
+            }
+        }
+
+        return sb.toString();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/build-post-office.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/build-post-office.md"
new file mode 100644
index 0000000..09501f4
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/build-post-office.md"
@@ -0,0 +1,215 @@
+# 邮局的建立
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/build-post-office/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个二维的网格，每一个格子上用 `1` 表示房子，`0` 表示空。要求在网格中，找到一个空地建立邮局，使得邮局到所有的房子的距离和最小。返回所有房子到邮局的最小距离和，如果不可能建邮局则返回`-1`。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[[0,1,0,0],[1,0,1,1],[0,1,0,0]]
+输出： 6
+解释：
+把邮局设立在(1,1)这个位置时，邮局离所有的房子的距离和是最近的
+```
+
+**样例 2:**
+```
+输入：[[0,1,0],[1,0,1],[0,1,0]]
+输出：4
+解释：
+把邮局设立在(1,1)这个位置时，邮局离所有的房子的距离是最近的。
+```
+ ### 参考代码
+ 考点：
+* 二分
+* 前缀和
+
+题解：
+方法一：
+* 由于题中所求两点间距离表示为d(i，j)=|xi-xj|+|yi-yj|，所以可以在x方向和y方向分别计算，然后求和即可，实现一维方向的计算即可。
+* 首先遍历网格，为1的方格，将其横纵坐标，即i和j分别存储，然后排序，方便接下来的查找计算。然后利用sumx和sumy前缀和，sumx代表起点到各个点的x方向距离和，sumy同理。
+* 再次遍历网格，当前处为0时，首先二分查找该方向i或j的位置，如果有多个相同的，寻找最右边的，即可，设为index。
+* 然后求和即可
+* sum.get(n) - sum.get(index + 1) - pos * (n - index - 1) + (index + 1) * pos - sum.get(index + 1);
+* sum.get(n) - sum.get(index + 1)计算出当前点右侧部分到起点的距离和
+*  - pos * (n - index - 1) 减去多余部分，因为之前是到起点的距离和，现在要求到当前点的距离和
+* (index + 1) * pos - sum.get(index + 1) 此处开始计算当前点左侧部分，index+1个当前点距离和减去index+1到起点的距离和，即为左侧部分的距离和。
+
+方法二：
+* 处理前缀：
+   prefixSum1记录数组 a 的前缀和，即:prefixSum1[i]=a[0]+a[1]+..+a[i].
+   prefixSum2记录数组 prefixSum1 前缀和，prefixSum2即为前 i 个点到第 i 个点的代价和。
+* 处理后缀：
+   prefixSum1记录数组 a 的后缀和，即:prefixSum1[i]=a[n-1]+a[n-2]+..+a[i].
+   prefixSum2记录数组 prefixSum1 的后缀和，prefixSum2即为 i 之后的点到第 i 个点的代价和。
+```java
+// 方法一 
+public class Solution {
+    /**
+     * @param grid a 2D grid
+     * @return an integer
+     */
+    public int shortestDistance(int[][] grid) {
+        // Write your code here
+        int n = grid.length;
+        if (n == 0)
+            return -1;
+
+        int m = grid[0].length;
+        if (m == 0)
+            return -1;
+
+        List<Integer> sumx = new ArrayList<Integer>();
+        List<Integer> sumy = new ArrayList<Integer>();
+        List<Integer> x = new ArrayList<Integer>();
+        List<Integer> y = new ArrayList<Integer>();
+
+        int result = Integer.MAX_VALUE;
+        for (int i = 0; i < n; ++i)
+            for (int j = 0; j < m; ++j)
+                if (grid[i][j] == 1) {
+                    x.add(i);
+                    y.add(j);
+                }
+        
+        Collections.sort(x);
+        Collections.sort(y);
+
+        int total = x.size();
+
+        sumx.add(0);
+        sumy.add(0);
+        for (int i = 1; i <= total; ++i) {
+            sumx.add(sumx.get(i-1) + x.get(i-1));
+            sumy.add(sumy.get(i-1) + y.get(i-1));
+        }
+
+        for (int i = 0; i < n; ++i)
+            for (int j = 0; j < m; ++j)
+                if (grid[i][j] == 0) {
+                    int cost_x = get_cost(x, sumx, i, total);
+                    int cost_y = get_cost(y, sumy, j, total);
+                    if (cost_x + cost_y < result)
+                        result = cost_x + cost_y;
+                }
+
+        return result;
+    }
+
+    public int get_cost(List<Integer> x, List<Integer> sum, int pos, int n) {
+        if (n == 0)
+            return 0;
+        if (x.get(0) > pos)
+            return sum.get(n) - pos * n;
+
+        int l = 0, r = n - 1;
+        while (l + 1 < r) {
+            int mid = l + (r - l) / 2;
+            if (x.get(mid) <= pos)
+                l = mid;
+            else
+                r = mid - 1;
+        }
+        
+        int index = 0;
+        if (x.get(r) <= pos)
+            index = r;
+        else
+            index = l;
+        return sum.get(n) - sum.get(index + 1) - pos * (n - index - 1) + 
+               (index + 1) * pos - sum.get(index + 1);
+    }
+}
+
+// 方法二
+public class Solution {
+    /**
+     * @param grid a 2D grid
+     * @return an integer
+     */
+    public int shortestDistance(int[][] grid) {
+        // Write your code here
+        int row = grid.length, column = grid[0].length;
+        if(row == 0 || column == 0 || !haveZero(grid,row,column)) {
+        	return -1;
+        }
+
+        int[] rowSum = new int[row];
+        int[] columnSum = new int[column]; 
+        for(int i = 0; i < row; i++)
+        	for(int j = 0; j < column; j++)
+        		if(grid[i][j] == 1) {
+        			rowSum[i]++;
+        			columnSum[j]++;
+        		}
+
+        int[] ansRow = new int[row];
+        int[] ansColumn = new int[column];
+        getSumDistance(rowSum,row,ansRow);
+        getSumDistance(columnSum,column,ansColumn);
+
+        int ans = Integer.MAX_VALUE;
+        for(int i = 0; i < row; i++)
+        	for(int j = 0; j < column; j++)
+        		if(grid[i][j] == 0 && ans > ansRow[i] + ansColumn[j]) {
+        			ans = ansRow[i] + ansColumn[j];
+        		}
+        return ans;
+    }
+
+    void getSumDistance(int[] a,int n,int[] ans) {
+    	int[] prefixSum1 = new int[n];
+    	int[] prefixSum2 = new int[n];
+    	/*
+    	第一阶段，处理前缀。
+    	prefixSum1记录数组 a 的前缀和，即:prefixSum1[i]=a[0]+a[1]+..+a[i].
+    	prefixSum2记录数组 prefixSum1 前缀和，prefixSum2即为前 i 个点到第 i 个点的代价和。
+    	*/
+    	prefixSum1[0] = a[0];
+    	for(int i = 1; i < n; i++) {
+    		prefixSum1[i] = prefixSum1[i - 1] + a[i];
+    	}
+    	prefixSum2[0] = 0;
+    	for(int i = 1; i < n; i++) {
+    		prefixSum2[i] = prefixSum2[i - 1] + prefixSum1[i - 1];
+     	}
+
+     	for(int i = 0; i < n; i++) {
+     		ans[i] = prefixSum2[i];
+     	}
+
+    	/*
+    	第二阶段，处理后缀。
+    	prefixSum1记录数组 a 的后缀和，即:prefixSum1[i]=a[n-1]+a[n-2]+..+a[i].
+    	prefixSum2记录数组 prefixSum1 的后缀和，prefixSum2即为 i 之后的点到第 i 个点的代价和。
+    	*/
+    	prefixSum1[n - 1] = a[n - 1];
+    	for(int i = n - 2; i >= 0; i--) {
+    		prefixSum1[i] = prefixSum1[i + 1] + a[i];
+    	}
+    	prefixSum2[n - 1] =0;
+    	for(int i = n - 2; i >= 0; i--) {
+    		prefixSum2[i] = prefixSum2[i + 1] + prefixSum1[i + 1];
+     	}
+
+     	for(int i = 0; i < n; i++) {
+     		ans[i] += prefixSum2[i];
+     	}
+
+     	/*
+     	ans[i] 即为a数组中所有点到第 i 点的代价和
+     	*/
+    }
+
+    boolean haveZero(int[][] grid, int row, int column) {
+    	for(int i = 0; i < row; i++) {
+    		for(int j = 0; j < column; j++){
+    			if(grid[i][j] == 0) {
+    				return true;
+    			}
+    		}
+    	}
+    	return false;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/classical-binary-search.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/classical-binary-search.md"
new file mode 100644
index 0000000..1301a08
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/classical-binary-search.md"
@@ -0,0 +1,84 @@
+# 经典二分查找问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/classical-binary-search/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个排序数组中找一个数，返回该数出现的任意位置，如果不存在，返回 `-1`。
+
+ ### 样例说明
+ **样例 1：**
+```
+输入：nums = [1,2,2,4,5,5], target = 2
+输出：1 或者 2
+```
+**样例 2：**
+```
+输入：nums = [1,2,2,4,5,5], target = 6
+输出：-1
+```
+ ### 参考代码
+ ```java
+// version 1: with jiuzhang template
+public class Solution {
+    /**
+     * @param A an integer array sorted in ascending order
+     * @param target an integer
+     * @return an integer
+     */
+    public int findPosition(int[] nums, int target) {
+        if (nums == null || nums.length == 0) {
+            return -1;
+        }
+        
+        int start = 0, end = nums.length - 1;
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (nums[mid] == target) {
+                return mid;
+            } else if (nums[mid] < target) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        
+        if (nums[start] == target) {
+            return start;
+        }
+        if (nums[end] == target) {
+            return end;
+        }
+        return -1;
+    }
+}
+
+// version 2: without jiuzhang template
+public class Solution {
+    /**
+     * @param A an integer array sorted in ascending order
+     * @param target an integer
+     * @return an integer
+     */
+    public int findPosition(int[] nums, int target) {
+        if (nums == null || nums.length == 0) {
+            return -1;
+        }
+        
+        int start = 0, end = nums.length - 1;
+        while (start < end) {
+            int mid = start + (end - start) / 2;
+            if (nums[mid] == target) {
+                return mid;
+            } else if (nums[mid] < target) {
+                start = mid + 1;
+            } else {
+                end = mid - 1;
+            }
+        }
+        
+        if (nums[start] == target) {
+            return start;
+        }
+        return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/closest-number-in-sorted-array.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/closest-number-in-sorted-array.md"
new file mode 100644
index 0000000..9636a1e
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/closest-number-in-sorted-array.md"
@@ -0,0 +1,45 @@
+# 排序数组中最接近元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/closest-number-in-sorted-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个排好序的数组 *A* 中找到 *i* 使得 *A[i]* 最接近 *target*
+ ### 样例说明
+ 样例1：
+```
+输入：[1, 2, 3] ，target = 2
+输出： 1.
+```
+样例2：
+```
+输入：[1, 4, 6]， target = 3
+输出： 1.
+```
+样例3：
+```
+输入：[1, 4, 6]，target = 5,
+输出： 1 或 2.
+```
+ ### 参考代码
+ 利用二分查找的思想即可
+```python
+class Solution:
+    # @param {int[]} A an integer array sorted in ascending order
+    # @param {int} target an integer
+    # @return {int} an integer
+    def closestNumber(self, A, target):
+        if not A:
+            return -1
+        start, end = 0, len(A) - 1
+        while start + 1 < end:
+            mid = (start + end) / 2
+            if A[mid] == target:
+                return mid
+            elif A[mid] > target:
+                end = mid
+            else:
+                start = mid
+        if A[end] - target > target - A[start]:
+            return start
+        else:
+            return end
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/continuous-subarray-sum-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/continuous-subarray-sum-ii.md"
new file mode 100644
index 0000000..a71b61d
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/continuous-subarray-sum-ii.md"
@@ -0,0 +1,64 @@
+# 连续子数组求和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/continuous-subarray-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数循环数组（头尾相接），请找出一个连续的子数组，使得该子数组的和最大。输出答案时，请分别返回第一个数字和最后一个数字的值。
+
+如果多个答案，请返回其中任意一个。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [3, 1, -100, -3, 4]
+输出: [4, 1]
+```
+
+**样例 2:**
+
+```
+输入: [1,-1]
+输出: [0, 0]
+```
+ ### 参考代码
+ 分两种情况讨论：
+
+1. 最大数组仍然是中间的某一段
+2. 最大数组是去掉了中间的一段之后剩下的部分
+
+第一种情况用传统的最大子数组做法走一遍(参考[题解](https://www.jiuzhang.com/solution/continuous-subarray-sum))。第二种做法稍微想一下就可以证明中间被去掉的那一段是整个数组的 minimum subarray。
+所以求一遍 minimum subarray 之后，比较两种情况, 取最优解即可
+
+需要特殊考虑 minimum subarray 是取了所有数的情况。
+```python
+class Solution:
+    """
+    @param: A: An integer array
+    @return: A list of integers includes the index of the first number and the index of the last number
+    """
+    def continuousSubarraySumII(self, A):
+        max_start, max_end, max_sum = self.find_maximum_subarray(A)
+        min_start, min_end, min_sum = self.find_maximum_subarray([-a for a in A])
+        min_sum = -min_sum  # *-1 after reuse find maximum array
+        
+        total = sum(A)
+        if max_sum >= total - min_sum or min_end - min_start + 1 == len(A):
+            return [max_start, max_end]
+        
+        return [min_end + 1, min_start - 1]
+        
+    def find_maximum_subarray(self, nums):
+        max_sum = -sys.maxsize
+        curt_sum, start = 0, 0
+        max_range = []
+        
+        for index, num in enumerate(nums):
+            if curt_sum < 0:
+                curt_sum = 0
+                start = index
+            curt_sum += num
+            if curt_sum > max_sum:
+                max_sum = curt_sum
+                max_range = [start, index]
+                
+        return max_range[0], max_range[1], max_sum
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/count-of-smaller-number-before-itself.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/count-of-smaller-number-before-itself.md"
new file mode 100644
index 0000000..5e93025
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/count-of-smaller-number-before-itself.md"
@@ -0,0 +1,68 @@
+# 统计前面比自己小的数的个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/count-of-smaller-number-before-itself/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组（下标由 0 到 n-1， n 表示数组的规模，取值范围由 0 到10000）。对于数组中的每个 `ai` 元素，请计算 `ai` 前的数中比它小的元素的数量。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+[1,2,7,8,5]
+输出:
+[0,1,2,3,2]
+```
+
+**样例 2:**
+```
+输入:
+[7,8,2,1,3]
+输出:
+[0,1,0,0,2]
+```
+ ### 参考代码
+ 使用 Fenwick Tree （Binary Indexed Tree） 的解法
+```java
+class BITree {
+    public int[] bit;
+
+    public BITree(int range) {
+        bit = new int[range + 1];
+    }
+    
+    public void increase(int index, int delta) {
+        for (int i = index + 1; i < bit.length; i = i + lowbit(i)) {
+            bit[i] += delta;
+        }
+    }
+    
+    public int getPrefixSum(int index) {
+        int sum = 0;
+        for (int i = index + 1; i >= 1; i = i - lowbit(i)) {
+            sum += bit[i];
+        }
+        return sum;
+    }
+    
+    private int lowbit(int x) {
+        return x & (-x);
+    }
+}
+
+public class Solution {
+    /**
+     * @param A: an integer array
+     * @return: A list of integers includes the index of the first number and the index of the last number
+     */
+    public List<Integer> countOfSmallerNumberII(int[] A) {
+        BITree bitree = new BITree(10000);
+        List<Integer> results = new ArrayList<>();
+        for (int i = 0; i < A.length; i++) {
+            results.add(bitree.getPrefixSum(A[i] - 1));
+            bitree.increase(A[i], 1); 
+        }
+        
+        return results;
+    }
+    
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/count-of-smaller-number.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/count-of-smaller-number.md"
new file mode 100644
index 0000000..9c958b2
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/count-of-smaller-number.md"
@@ -0,0 +1,122 @@
+# 统计比给定整数小的数的个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/count-of-smaller-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组 （下标由 0 到 n-1，其中 n 表示数组的规模，数值范围由 0 到 10000），以及一个 查询列表。对于每一个查询，将会给你一个整数，请你返回该数组中小于给定整数的元素的数量。
+ ### 样例说明
+ **样例 1:**
+```
+输入: array =[1,2,7,8,5] queries =[1,8,5]
+输出:[0,4,2]
+```
+
+**样例 2:**
+```
+输入: array =[3,4,5,8] queries =[2,4]
+输出:[0,1]
+```
+
+
+ ### 参考代码
+ ```java
+public class Solution {
+   /**
+     * @param A: An integer array
+     * @return: The number of element in the array that 
+     *          are smaller that the given integer
+     */
+    class SegmentTreeNode {
+        public int start, end;
+        public int count;
+        public SegmentTreeNode left, right;
+        public SegmentTreeNode(int start, int end, int count) {
+              this.start = start;
+              this.end = end;
+              this.count = count;
+              this.left = this.right = null;
+        }
+    }
+    SegmentTreeNode root;
+    public SegmentTreeNode build(int start, int end) {
+        // write your code here
+        if(start > end) {  // check core case
+            return null;
+        }
+        
+        SegmentTreeNode root = new SegmentTreeNode(start, end, 0);
+        
+        if(start != end) {
+            int mid = (start + end) / 2;
+            root.left = build(start, mid);
+            root.right = build(mid+1, end);
+        } else {
+            root.count =  0;
+        }
+        return root;
+    }
+    public int querySegmentTree(SegmentTreeNode root, int start, int end) {
+        // write your code here
+        if(start == root.start && root.end == end) { // 相等 
+            return root.count;
+        }
+        
+        
+        int mid = (root.start + root.end)/2;
+        int leftcount = 0, rightcount = 0;
+        // 左子区
+        if(start <= mid) {
+            if( mid < end) { // 分裂 
+                leftcount =  querySegmentTree(root.left, start, mid);
+            } else { // 包含 
+                leftcount = querySegmentTree(root.left, start, end);
+            }
+        }
+        // 右子区
+        if(mid < end) { // 分裂 3
+            if(start <= mid) {
+                rightcount = querySegmentTree(root.right, mid+1, end);
+            } else { //  包含 
+                rightcount = querySegmentTree(root.right, start, end);
+            } 
+        }  
+        // else 就是不相交
+        return leftcount + rightcount;
+    }
+    public void modifySegmentTree(SegmentTreeNode root, int index, int value) {
+        // write your code here
+        if(root.start == index && root.end == index) { // 查找到
+            root.count += value;
+            return;
+        }
+        
+        // 查询
+        int mid = (root.start + root.end) / 2;
+        if(root.start <= index && index <=mid) {
+            modifySegmentTree(root.left, index, value);
+        }
+        
+        if(mid < index && index <= root.end) {
+            modifySegmentTree(root.right, index, value);
+        }
+        //更新
+        root.count = root.left.count + root.right.count;
+    }
+    public ArrayList<Integer> countOfSmallerNumber(int[] A, int[] queries) {
+        // write your code here
+        root = build(0, 10000);
+        ArrayList<Integer> ans = new ArrayList<Integer>();
+        int res;
+        for(int i = 0; i < A.length; i++) {
+            modifySegmentTree(root, A[i], 1);
+        }
+        for(int i = 0; i < queries.length; i++) {
+            res = 0;
+            if(queries[i] > 0)
+                res = querySegmentTree(root, 0, queries[i] - 1);
+            ans.add(res);
+        }
+        return ans;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/divide-two-integers.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/divide-two-integers.md"
new file mode 100644
index 0000000..3e9516f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/divide-two-integers.md"
@@ -0,0 +1,73 @@
+# 两个整数相除
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/divide-two-integers/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将两个整数相除，**要求不使用乘法、除法和 mod 运算符。**
+
+如果溢出(超出32位有符号整型表示范围)，返回 `2147483647` 。
+
+整数除法应截断为零。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 被除数 = 0, 除数 = 1
+输出: 0
+```
+
+**样例 2:**
+
+```
+输入: 被除数 = 100, 除数 = 9
+输出: 11
+```
+ ### 参考代码
+ 基本思路是利用减法, 看看被除数可以减去多少次除数.
+
+使用倍增的思想优化, 可以将减法的次数优化到对数时间复杂度.
+
+我们将除数左移一位(或者让它加上自己), 即得到了二倍的除数, 这时一次减法相当于减去了2个除数. 不断倍增, 时间效率很优秀.
+
+与此同时还需要一个变量记录此时的除数是最初的除数的多少倍, 每次减法后都加到结果上即可.
+
+---
+
+还可参考九章算法微博: <http://weibo.com/3948019741/BtiIg7xm4>
+```java
+public class Solution {
+    /**
+     * @param dividend the dividend
+     * @param divisor the divisor
+     * @return the result
+     */
+    public int divide(int dividend, int divisor) {
+        if (divisor == 0) {
+             return dividend >= 0? Integer.MAX_VALUE : Integer.MIN_VALUE;
+        }
+        
+        if (dividend == 0) {
+            return 0;
+        }
+        
+        if (dividend == Integer.MIN_VALUE && divisor == -1) {
+            return Integer.MAX_VALUE;
+        }
+        
+        boolean isNegative = (dividend < 0 && divisor > 0) || 
+                             (dividend > 0 && divisor < 0);
+                             
+        long a = Math.abs((long)dividend);
+        long b = Math.abs((long)divisor);
+        int result = 0;
+        while (a >= b) {
+            int shift = 0;
+            while (a >= (b << shift)) {
+                shift++;
+            }
+            a -= b << (shift - 1);
+            result += 1 << (shift - 1);
+        }
+        return isNegative? -result: result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/dungeon-game.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/dungeon-game.md"
new file mode 100644
index 0000000..7f6758f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/dungeon-game.md"
@@ -0,0 +1,107 @@
+# 	
+地下城游戏
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/dungeon-game/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 恶魔抓住了公主（P）并将她关在地牢的右下角。地牢由M x N的2D网格房间组成，。我们英勇的骑士（K）最初位于左上角的房间，必须通过地牢的房间来拯救公主。
+
+骑士的初始生命值由正整数表示。如果他的生命值在任何时候下降到0或更低，他会立即死亡。
+
+有些房间是由恶魔守卫的，因此骑士进入这些房间时会失去生命值（负整数）；其他房间要么是空的（0），要么包含增加骑士健康的魔法球（正整数）。
+
+为了尽快到达公主所在的地方，骑士决定在每一步中仅向右或向下移动。
+
+编写一个函数来确定骑士的最少的初始生命值，使得他能够拯救公主。
+
+例如，给定下面的地下城，如果骑士遵循最佳路径 右-> 右 -> 下 -> 下，则骑士的初始生命值必须至少为7。
+
+```plain
+| -2(K)   | -3     | 3        |
+| -5      | -10    | 1        |
+| 10      | 30     | -5(P)    |
+```
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: [[-2,-3,3],[-5,-10,1],[10,30,-5]]
+输出: 7
+说明:
+路径 右右下下 是最优解
+```
+
+**样例2**
+
+```plain
+输入: [[-2,0,3],[-5,100,-999],[10,30,-5]]
+输出: 3
+说明:
+路径 右下下右 是最优解
+```
+
+
+ ### 参考代码
+ 本题采用二分+dp check的做法
+- 二分是对于答案进行二分。
+- check的时候我们要用dp进行，考虑到起点用mid的血量开始到终点是否够，最后比较得出答案
+```java
+public class Solution {
+  private boolean canSurvive(int health, int[][] dungeon) {
+    int n = dungeon.length, m = dungeon[0].length;
+    int[][] f = new int[n][m];
+
+    f[0][0] = dungeon[0][0] + health;
+    if (f[0][0] <= 0) {
+      return false;
+    }
+    
+    for (int i = 1; i < n; i++) {
+      f[i][0] = f[i - 1][0] == Integer.MIN_VALUE
+                ? Integer.MIN_VALUE
+                : f[i - 1][0] + dungeon[i][0];
+      if (f[i][0] <= 0) {
+        f[i][0] = Integer.MIN_VALUE;
+      }
+    }
+    for (int i = 1; i < m; i++) {
+      f[0][i] = f[0][i - 1] == Integer.MIN_VALUE
+                ? Integer.MIN_VALUE
+                : f[0][i - 1] + dungeon[0][i];
+      if (f[0][i] <= 0) {
+        f[0][i] = Integer.MIN_VALUE;
+      }
+    }
+    
+    for (int i = 1; i < n; i++) {
+      for (int j = 1; j < m; j++) {
+        f[i][j] = Math.max(f[i - 1][j], f[i][j - 1]);
+        if (f[i][j] == Integer.MIN_VALUE) {
+          continue;
+        }
+        f[i][j] += dungeon[i][j];
+        if (f[i][j] <= 0) {
+          f[i][j] = Integer.MIN_VALUE;
+        }
+      }
+    }
+    
+    return f[n - 1][m - 1] > 0;
+  }
+  
+  public int calculateMinimumHP(int[][] dungeon) {
+    int start = 1, end = Integer.MAX_VALUE - 1;
+    while (start + 1 < end) {
+      int mid = (end - start) / 2 + start;
+      if (canSurvive(mid, dungeon)) {
+        end = mid;
+      } else {
+        start = mid;
+      }
+    }
+    if (canSurvive(start, dungeon)) {
+      return start;
+    }
+    return end;
+  }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-k-closest-elements.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-k-closest-elements.md"
new file mode 100644
index 0000000..658c75a
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-k-closest-elements.md"
@@ -0,0 +1,77 @@
+# 在排序数组中找最接近的K个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-k-closest-elements/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个目标数 `target`, 一个非负整数 `k`, 一个按照升序排列的数组 `A`。在`A`中找与`target`最接近的`k`个整数。返回这`k`个数并按照与`target`的接近程度从小到大排序，如果接近程度相当，那么小的数排在前面。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: A = [1, 2, 3], target = 2, k = 3
+输出: [2, 1, 3]
+```
+
+**样例 2:**
+
+```
+输入: A = [1, 4, 6, 8], target = 3, k = 3
+输出: [4, 1, 6]
+```
+ ### 参考代码
+ 采用的是二分法 + 双指针
+二分法确定一个位置，左侧是 < target，右侧是 >= target
+然后用两根指针从中间向两边走，依次找到最接近的 k 个数
+
+与 Java 的版本的小区别是，起始位置是先找到右指针。然后左指针=右指针-1。
+```python
+class Solution:
+    """
+    @param A: an integer array
+    @param target: An integer
+    @param k: An integer
+    @return: an integer array
+    """
+    def kClosestNumbers(self, A, target, k):
+        # 找到 A[left] < target, A[right] >= target
+        # 也就是最接近 target 的两个数，他们肯定是相邻的
+        right = self.findUpperClosest(A, target)
+        left = right - 1
+    
+    	# 两根指针从中间往两边扩展，依次找到最接近的 k 个数
+        results = []
+        for _ in range(k):
+            if self.isLeftCloser(A, target, left, right):
+                results.append(A[left])
+                left -= 1
+            else:
+                results.append(A[right])
+                right += 1
+        
+        return results
+    
+    def findUpperClosest(self, A, target):
+        # find the first number >= target in A
+        start, end = 0, len(A) - 1
+        while start + 1 < end:
+            mid = (start + end) // 2
+            if A[mid] >= target:
+                end = mid
+            else:
+                start = mid
+        
+        if A[start] >= target:
+            return start
+        
+        if A[end] >= target:            
+            return end
+        
+        # 找不到的情况
+        return len(A)
+        
+    def isLeftCloser(self, A, target, left, right):
+        if left < 0:
+            return False
+        if right >= len(A):
+            return True
+        return target - A[left] <= A[right] - target
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-minimum-in-rotated-sorted-array-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-minimum-in-rotated-sorted-array-ii.md"
new file mode 100644
index 0000000..80fca6d
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-minimum-in-rotated-sorted-array-ii.md"
@@ -0,0 +1,72 @@
+# 寻找旋转排序数组中的最小值 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-minimum-in-rotated-sorted-array-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>假设一个旋转排序的数组其起始位置是未知的（比如<span style="font-weight: 700;"><font color="#e76363">0 1 2 4 5 6 7</font></span>&nbsp;可能变成是<font color="#e76363"><span style="font-weight: 700;">4 5 6 7 0 1 2</span></font>）。</p><p>你需要找到其中最小的元素。</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入 :[2,1]
+输出 : 1.
+```
+
+**样例 2:**
+```
+输入 :[4,4,5,6,7,0,1,2]
+输出: 0.
+```
+ ### 参考代码
+ <p><a href="http://www.lintcode.com/problem/find-minimum-in-rotated-sorted-array-ii/" target="_blank">http://www.lintcode.com/problem/find-minimum-in-rotated-sorted-array-ii/</a><br></p>
+```java
+// version 1: just for loop is enough
+public class Solution {
+    public int findMin(int[] num) {
+        //  这道题目在面试中不会让写完整的程序
+        //  只需要知道最坏情况下 [1,1,1....,1] 里有一个0
+        //  这种情况使得时间复杂度必须是 O(n)
+        //  因此写一个for循环就好了。
+        //  如果你觉得，不是每个情况都是最坏情况，你想用二分法解决不是最坏情况的情况，那你就写一个二分吧。
+        //  反正面试考的不是你在这个题上会不会用二分法。这个题的考点是你想不想得到最坏情况。
+        int min = num[0];
+        for (int i = 1; i < num.length; i++) {
+            if (num[i] < min)
+                min = num[i];
+        }
+        return min;
+    }
+}
+
+// version 2: use *fake* binary-search
+public class Solution {
+    /**
+     * @param num: a rotated sorted array
+     * @return: the minimum number in the array
+     */
+    public int findMin(int[] nums) {
+        if (nums == null || nums.length == 0) {
+            return -1;
+        }
+        
+        int start = 0, end = nums.length - 1;
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (nums[mid] == nums[end]) {
+                // if mid equals to end, that means it's fine to remove end
+                // the smallest element won't be removed
+                end--;
+            } else if (nums[mid] < nums[end]) {
+                end = mid;
+                // of course you can merge == & <
+            } else {
+                start = mid;
+                // or start = mid + 1
+            }
+        }
+        
+        if (nums[start] <= nums[end]) {
+            return nums[start];
+        }
+        return nums[end];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-minimum-in-rotated-sorted-array.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-minimum-in-rotated-sorted-array.md"
new file mode 100644
index 0000000..e805874
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-minimum-in-rotated-sorted-array.md"
@@ -0,0 +1,69 @@
+# 寻找旋转排序数组中的最小值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-minimum-in-rotated-sorted-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假设一个排好序的数组在其某一未知点发生了旋转（比如`0 1 2 4 5 6 7` 可能变成`4 5 6 7 0 1 2`）。你需要找到其中最小的元素。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[4, 5, 6, 7, 0, 1, 2]
+输出：0
+解释：
+数组中的最小值为0
+```
+
+**样例 2:**
+```
+输入：[2,1]
+输出：1
+解释：
+数组中的最小值为1
+```
+ ### 参考代码
+ 第二种解法，每次都和 end 去比。
+```
+[[python]]
+class Solution:
+    """
+    @param: nums: a rotated sorted array
+    @return: the minimum number in the array
+    """
+    def findMin(self, nums):
+        if not nums:
+            return -1
+            
+        start, end = 0, len(nums) - 1
+        while start + 1 < end:
+            mid = (start + end) // 2
+            if nums[mid] > nums[end]:
+                start = mid
+            else:
+                end = mid
+                
+        return min(nums[start], nums[end])
+[[java]]
+public class Solution {
+    /**
+     * @param nums: a rotated sorted array
+     * @return: the minimum number in the array
+     */
+    public int findMin(int[] nums) {
+        if (nums == null || nums.length == 0) {
+            return -1;
+        }
+        
+        int start = 0, end = nums.length - 1;
+        
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (nums[mid] > nums[end]) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        
+        return Math.min(nums[start], nums[end]);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-peak-element-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-peak-element-ii.md"
new file mode 100644
index 0000000..0228a1a
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-peak-element-ii.md"
@@ -0,0 +1,162 @@
+# 找峰值 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-peak-element-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数矩阵 `A`, 它有如下特性:
+
+- 相邻的整数不同
+- 矩阵有 `n` 行 `m` 列。
+- 对于所有的 `i < n`, 都有 `A[i][0] < A[i][1] && A[i][m - 2] > A[i][m - 1]`
+- 对于所有的 `j < m`, 都有 `A[0][j] < A[1][j] && A[n - 2][j] > A[n - 1][j]`
+
+我们定义一个位置 `[i,j]` 是峰值, 当且仅当它满足:
+
+```C++
+  A[i][j] > A[i + 1][j] && A[i][j] > A[i - 1][j] && 
+  A[i][j] > A[i][j + 1] && A[i][j] > A[i][j - 1]
+```
+
+找到该矩阵的一个峰值元素, 返回它的坐标.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 
+    [
+      [1, 2, 3, 6,  5],
+      [16,41,23,22, 6],
+      [15,17,24,21, 7],
+      [14,18,19,20,10],
+      [13,14,11,10, 9]
+    ]
+输出: [1,1]
+解释: [2,2] 也是可以的. [1,1] 的元素是 41, 大于它四周的每一个元素 (2, 16, 23, 17).
+```
+
+**样例 2:**
+
+```
+输入: 
+    [
+      [1, 5, 3],
+      [4,10, 9],
+      [2, 8, 7]
+    ]
+输出: [1,1]
+解释: 只有这一个峰值
+```
+ ### 参考代码
+ 网上很多 O(n+m) 的算法不正确, LintCode 已经加强数据.
+
+正确的算法请参考: <http://courses.csail.mit.edu/6.006/spring11/lectures/lec02.pdf>
+```java
+// O(n + m) 解法
+class Solution {
+    /**
+     * @param A: An integer matrix
+     * @return: The index of the peak
+     */
+    public List<Integer> find(int x1, int x2, int y1, int y2, int[][] A) {
+
+        int mid1 = x1 + (x2 - x1) / 2;
+        int mid2 = y1 + (y2 - y1) / 2;
+
+        int x = mid1, y = mid2;
+        int max = A[mid1][mid2];
+        for (int i = y1; i <= y2; ++i)
+            if (A[mid1][i] > max) {
+                max = A[mid1][i];
+                x = mid1;
+                y = i;
+            }
+
+        for (int i = x1; i <= x2; ++i)
+            if (A[i][mid2] > max) {
+                max = A[i][mid2];
+                x = i;
+                y = mid2;
+            }
+
+        boolean isPeak = true;
+        if (A[x - 1][y] > A[x][y]) {
+            isPeak = false;
+            x -= 1;
+        } else if (A[x + 1][y] > A[x][y]) {
+            isPeak = false;
+            x += 1;
+        } else if (A[x][y - 1] > A[x][y]) {
+            isPeak = false;
+            y -= 1;
+        } else if (A[x][y + 1] > A[x][y]) {
+            isPeak = false;
+            y += 1;
+        }
+
+        if (isPeak) {
+            return new ArrayList<Integer>(Arrays.asList(x, y));
+        }
+
+        if (x >= x1 && x < mid1 && y >= y1 && y < mid2) {
+            return find(x1, mid1 - 1, y1, mid2 - 1, A);
+        }
+
+        if (x >= 1 && x < mid1 && y > mid2 && y <= y2) {
+            return find(x1, mid1 - 1, mid2 + 1, y2, A);
+        }
+
+        if (x > mid1 && x <= x2 && y >= y1 && y < mid2) {
+            return find(mid1 + 1, x2, y1, mid2 - 1, A);
+        }
+
+        if (x >= mid1 && x <= x2 && y > mid2 && y <= y2) {
+            return find(mid1 + 1, x2, mid2 + 1, y2, A);
+        }
+
+        return new ArrayList<Integer>(Arrays.asList(-1, -1));
+
+    }
+
+    public List<Integer> findPeakII(int[][] A) {
+        // write your code here
+        int n = A.length;
+        int m = A[0].length;
+        return find(1, n - 2, 1, m - 2, A);
+    }
+}
+
+class Solution {
+    /**
+     * @param A: An integer matrix
+     * @return: The index of the peak
+     */
+    public List<Integer> findPeakII(int[][] A) {
+        // this is the nlog(n) method
+        int low = 1, high = A.length - 2;
+        List<Integer> ans = new ArrayList<Integer>();
+        while (low <= high) {
+            int mid = (low + high) / 2;
+            int col = find(mid, A);
+            if (A[mid][col] < A[mid - 1][col]) {
+                high = mid - 1;
+            } else if (A[mid][col] < A[mid + 1][col]) {
+                low = mid + 1;
+            } else {
+                ans.add(mid);
+                ans.add(col);
+                break;
+            }
+        }
+        return ans;
+    }
+
+    int find(int row, int[][] A) {
+        int col = 0;
+        for (int i = 0; i < A[row].length; i++) {
+            if (A[row][i] > A[row][col]) {
+                col = i;
+            }
+        }
+        return col;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-peak-element.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-peak-element.md"
new file mode 100644
index 0000000..ba78eb4
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-peak-element.md"
@@ -0,0 +1,66 @@
+# 寻找峰值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-peak-element/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 你给出一个整数数组(size为n)，其具有以下特点：
+
+- 相邻位置的数字是不同的
+- A[0] < A[1] 并且 A[n - 2] > A[n - 1]
+
+假定*P*是峰值的位置则满足`A[P] > A[P-1]`且`A[P] > A[P+1]`，返回数组中任意一个峰值的位置。
+ ### 样例说明
+ ```
+样例 1:
+	输入:  [1, 2, 1, 3, 4, 5, 7, 6]
+	输出:  1 or 6
+	
+	解释:
+	返回峰顶元素的下标
+
+
+样例 2:
+	输入: [1,2,3,4,1]
+	输出:  3
+
+```
+ ### 参考代码
+ 这个题 LintCode 和 LeetCode 的 find peak element 是有区别的。
+数据上，LintCode 保证数据第一个数比第二个数小，倒数第一个数比到倒数第二个数小。
+因此 start, end 的范围要取 1, A.length - 2
+
+二分法。
+每次取中间元素，如果大于左右，则这就是peek。
+否则取大的一边，两个都大，可以随便取一边。最终会找到peek。
+
+正确性证明：
+1. A[0] < A[1] && A[n-2] > A[n-1] 所以一定存在一个peek元素。
+2. 二分时，选择大的一边, 则留下的部分仍然满足1 的条件，即最两边的元素都小于相邻的元素。所以仍然必然存在peek。
+3. 二分至区间足够小，长度为3, 则中间元素就是peek。
+```
+[[java]]
+class Solution {
+    /**
+     * @param A: An integers array.
+     * @return: return any of peek positions.
+     */
+    public int findPeak(int[] A) {
+        // 1.答案在之间，2.不会出界 
+        int start = 1, end = A.length - 2;
+        while (start + 1 <  end) {
+            int mid = start + (end - start) / 2;
+            if (A[mid] < A[mid - 1]) {
+                end = mid;
+            } else if (A[mid] < A[mid + 1]) {
+                start = mid;
+            } else {
+                return mid;
+            }
+        }
+        if (A[start] < A[end]) {
+            return end;
+        } else { 
+            return start;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-right-interval.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-right-interval.md"
new file mode 100644
index 0000000..aba6edd
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/find-right-interval.md"
@@ -0,0 +1,95 @@
+# 寻找右区间
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-right-interval/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一组区间，对于每一个区间 i，检查是否存在一个区间 j，它的起始点大于或等于区间 i 的终点，这可以称为 j 在 i 的“右侧”。
+
+对于任何区间，你需要存储的满足条件的区间 j 的最小索引，这意味着区间 j 有最小的起始点可以使其成为“右侧”区间。如果区间 j 不存在，则将区间 i 存储为 -1。最后，你需要输出一个值为存储的区间值的数组。
+ ### 样例说明
+ **样例 1:**
+```
+输入: intervals = [(1,2)]
+输出: [-1]
+解释:
+集合中只有一个区间，所以输出-1。
+```
+**样例 2:**
+```
+输入: intervals = [(3,4),(2,3),(1,2)]
+输出: [-1, 0, 1]
+解释:
+对于(3,4)，没有满足条件的“右侧”区间。
+对于(2,3)，区间[3,4]具有最小的“右”起点;
+对于(1,2)，区间[2,3]具有最小的“右”起点。
+```
+ ### 参考代码
+ 扫描线算法。
+详见九章算法强化班
+```java
+/**
+ * Definition for an interval.
+ * public class Interval {
+ *     int start;
+ *     int end;
+ *     Interval() { start = 0; end = 0; }
+ *     Interval(int s, int e) { start = s; end = e; }
+ * }
+ */
+
+class Point {
+    public int index, val;
+    public boolean isStart;
+    
+    public Point(int index, int val, boolean isStart) {
+        this.index = index;
+        this.val = val;
+        this.isStart = isStart;
+    }
+}
+
+class Solution {
+    private Comparator<Point> comparator = new Comparator<Point>() {
+        public int compare(Point left, Point right) {
+            if (left.val != right.val) {
+                return left.val - right.val;
+            }
+            if (left.isStart) {
+                return 1;
+            }
+            return -1;
+        }
+    };
+    
+    public int[] findRightInterval(Interval[] intervals) {
+        List<Point> points = getSortedPoints(intervals);
+        int[] rightArray = new int[intervals.length];
+        Queue<Point> minheap = new PriorityQueue<>(comparator);
+        
+        // traverse points from right to left
+        for (int i = points.size() - 1; i >= 0; i--) {
+            Point point = points.get(i);
+            if (point.isStart) {
+                minheap.offer(point);
+            } else {
+                if (minheap.size() == 0) {
+                    rightArray[point.index] = -1;
+                } else {
+                    rightArray[point.index] = minheap.peek().index;
+                }
+            }
+        }
+        
+        return rightArray;
+    }
+    
+    public List<Point> getSortedPoints(Interval[] intervals) {
+        List<Point> points = new ArrayList<>(); 
+        for (int i = 0; i < intervals.length; i++) {
+            points.add(new Point(i, intervals[i].start, true));
+            points.add(new Point(i, intervals[i].end, false));
+        }
+        Collections.sort(points, comparator);
+        return points;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/first-bad-version.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/first-bad-version.md"
new file mode 100644
index 0000000..7200d39
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/first-bad-version.md"
@@ -0,0 +1,50 @@
+# 第一个错误的代码版本
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/first-bad-version/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 代码库的版本号是从 1 到 *n* 的整数。某一天，有人提交了错误版本的代码，因此造成自身及之后版本的代码在单元测试中均出错。请找出第一个错误的版本号。
+
+你可以通过 `isBadVersion` 的接口来判断版本号 version 是否在单元测试中出错，具体接口详情和调用方法请见代码的注释部分。
+ ### 样例说明
+ ```
+n = 5:
+
+    isBadVersion(3) -> false
+    isBadVersion(5) -> true
+    isBadVersion(4) -> true
+
+因此可以确定第四个版本是第一个错误版本。
+```
+ ### 参考代码
+ 使用二分答案方法，即可定位出第一个错误版本。
+```java
+/**
+ * public class GitRepo {
+ *     public static boolean isBadVersion(int k);
+ * }
+ * you can use GitRepo.isBadVersion(k) to judge whether 
+ * the kth code version is bad or not.
+*/
+class Solution {
+    /**
+     * @param n: An integers.
+     * @return: An integer which is the first bad version.
+     */
+    public int findFirstBadVersion(int n) {
+        int start = 1, end = n;
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (SVNRepo.isBadVersion(mid)) {
+                end = mid;
+            } else {
+                start = mid;
+            }
+        }
+            
+        if (SVNRepo.isBadVersion(start)) {
+            return start;
+        }
+        return end;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/first-position-of-target.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/first-position-of-target.md"
new file mode 100644
index 0000000..eca44eb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/first-position-of-target.md"
@@ -0,0 +1,105 @@
+# 二分查找
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/first-position-of-target/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个排序的整数数组（升序）和一个要查找的整数`target`，用`O(logn)`的时间查找到target第一次出现的下标（从0开始），如果target不存在于数组中，返回`-1`。
+ ### 样例说明
+ ```
+样例  1:
+	输入:[1,4,4,5,7,7,8,9,9,10]，1
+	输出: 0
+	
+	样例解释: 
+	第一次出现在第0个位置。
+
+样例 2:
+	输入: [1, 2, 3, 3, 4, 5, 10]，3
+	输出: 2
+	
+	样例解释: 
+	第一次出现在第2个位置
+	
+样例 3:
+	输入: [1, 2, 3, 3, 4, 5, 10]，6
+	输出: -1
+	
+	样例解释: 
+	没有出现过6， 返回-1
+
+```
+ ### 参考代码
+ 二分查找的模版，找第一次出现的位置。
+注意可能出现多次，所以当找到这个数字的时候不能直接结束，而要将end移动到mid处。
+直到最后缩小到只有一个或两个数字时，优先判断start，再判断end。
+
+时间复杂度$O(log_2 n)$
+```java
+// version 1: with jiuzhang template
+class Solution {
+    /**
+     * @param nums: The integer array.
+     * @param target: Target to find.
+     * @return: The first position of target. Position starts from 0.
+     */
+    public int binarySearch(int[] nums, int target) {
+        if (nums == null || nums.length == 0) {
+            return -1;
+        }
+        
+        int start = 0, end = nums.length - 1;
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (nums[mid] == target) {
+                end = mid;
+            } else if (nums[mid] < target) {
+                start = mid;
+                // or start = mid + 1
+            } else {
+                end = mid;
+                // or end = mid - 1
+            }
+        }
+        
+        if (nums[start] == target) {
+            return start;
+        }
+        if (nums[end] == target) {
+            return end;
+        }
+        return -1;
+    }
+}
+
+
+// version 2: without jiuzhang template
+class Solution {
+    /**
+     * @param nums: The integer array.
+     * @param target: Target to find.
+     * @return: The first position of target. Position starts from 0.
+     */
+    public int binarySearch(int[] nums, int target) {
+        if (nums == null || nums.length == 0) {
+            return -1;
+        }
+        
+        int start = 0, end = nums.length - 1;
+        while (start < end) {
+            int mid = start + (end - start) / 2;
+            if (nums[mid] == target) {
+                end = mid;
+            } else if (nums[mid] < target) {
+                start = mid + 1;
+            } else {
+                end = mid - 1;
+            }
+        }
+        
+        if (nums[start] == target) {
+            return start;
+        }
+        
+        return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/geohash-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/geohash-ii.md"
new file mode 100644
index 0000000..76c1b5e
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/geohash-ii.md"
@@ -0,0 +1,64 @@
+# Geo哈希 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/geohash-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 这题是 [Geohash](http://www.lintcode.com/problem/geohash/)的加强版
+将一个字符串用Geohash的逆运算求出latitude和longitude
+Geohash细节见帮助[Geohash](http://www.lintcode.com/zh-cn/help/geohash/)或者wiki [GeoHash](https://en.wikipedia.org/wiki/Geohash)
+
+
+ ### 样例说明
+ **样例1**
+
+```
+输入: "wx4g0s"`
+输出: lat = 39.92706299 and lng = 116.39465332
+```
+
+**样例2**
+
+```
+输入: "w"
+输出: lat = 22.50000000 and lng = 112.50000000
+```
+
+ ### 参考代码
+ 二分求解
+```java
+public class GeoHash {
+    /**
+     * @param geohash a base32 string
+     * @return latitude and longitude a location coordinate pair
+     */
+    public double[] decode(String geohash) {
+        // Write your code here
+        String _base32 = "0123456789bcdefghjkmnpqrstuvwxyz";
+        int[] mask = {16, 8, 4, 2, 1};
+        double[] lon = {-180, 180};
+        double[] lat = {-90, 90};
+        boolean is_even = true;
+
+        for (int i = 0; i < geohash.length(); ++i) {
+            int val = _base32.indexOf(geohash.charAt(i));
+            for (int j = 0; j < 5; ++j) {
+                if (is_even) {
+                    refine_interval(lon, val, mask[j]);
+                } else {
+                    refine_interval(lat, val, mask[j]);
+                }
+                is_even = ! is_even;
+            }
+        }
+        double[] location = {(lat[0] + lat[1]) / 2.0, (lon[0] + lon[1]) / 2.0};
+        return location;
+    }
+
+    public void refine_interval(double[] interval, int val, int mask) {
+        if ((val & mask) > 0) {
+            interval[0] = (interval[0] + interval[1]) / 2.0;
+        } else {
+            interval[1] = (interval[0] + interval[1]) / 2.0;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/geohash.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/geohash.md"
new file mode 100644
index 0000000..91b779c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/geohash.md"
@@ -0,0 +1,63 @@
+# Geo哈希
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/geohash/?utm_source=sc-github-wzz)
+ ## 题目描述
+ Geo哈希是一个著名的哈希算法，用于将坐标哈希成一个32位字符串
+[Geohash](https://en.wikipedia.org/wiki/Geohash)
+[http://geohash.co/](http:// "http://geohash.co/")
+ ### 样例说明
+ **样例1**
+
+```
+输入: 
+lat = 39.92816697 
+lng = 116.38954991
+precision = 12 
+输出: "wx4g0s8q3jf9"
+```
+
+**样例2**
+
+```
+输入: 
+lat = -90
+lng = 180
+precision = 12 
+输出: "pbpbpbpbpbpb"
+```
+
+ ### 参考代码
+ 直接按照链接中的做法进行哈希即可
+```python
+class GeoHash:
+    # @param {double} latitude, longitude a location coordinate pair
+    # @param {int} precision an integer between 1 to 12
+    # @return {string} a base32 string
+    def encode(self, latitude, longitude, precision):
+        # Write your code here
+        _base32 = "0123456789bcdefghjkmnpqrstuvwxyz"
+        lat_bin = self.get_bin(latitude, -90, 90)
+        lng_bin = self.get_bin(longitude, -180, 180)
+        
+        hash_code, b = '', ''
+        for i in xrange(30):
+            b += lng_bin[i] + lat_bin[i]
+
+        for i in xrange(0, 60, 5):
+            hash_code += _base32[int(b[i:i + 5], 2)]
+
+        return hash_code[:precision]
+            
+
+    def get_bin(self, value, left, right):
+        b = ''
+        for i in xrange(30):
+            mid = (left + right) / 2.0
+            if value > mid:
+                left = mid
+                b += '1'
+            else:
+                right = mid
+                b += '0'
+        return b
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/h-index-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/h-index-ii.md"
new file mode 100644
index 0000000..294fb0f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/h-index-ii.md"
@@ -0,0 +1,44 @@
+# H指数 II
+
+
+
+
+
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/h-index-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一位研究者论文被引用次数的数组（被引用次数是非负整数），数组已经按照升序排列。编写一个方法，计算出研究者的 h 指数。
+
+h 指数的定义: “h 代表“高引用次数”（high citations），一名科研人员的 h 指数是指他（她）的 （N 篇论文中）至多有 h 篇论文分别被引用了至少 h 次。（其余的 N - h 篇论文每篇被引用次数不多于 h 次。）"
+
+ ### 样例说明
+ ```
+输入: citations = [0,1,3,5,6]
+输出: 3 
+解释: 给定数组表示研究者总共有 5 篇论文，每篇论文相应的被引用了 0, 1, 3, 5, 6 次。
+     由于研究者有 3 篇论文每篇至少被引用了 3 次，其余两篇论文每篇被引用不多于 3 次，所以她的 h 指数是 3。
+```
+ ### 参考代码
+ ```cpp
+class Solution {
+public:
+    int hIndex(vector<int>& citations) {
+        int ans = 0;
+        int h;
+        int l = 0, r = citations.size() - 1;
+        
+        while(l <= r) {
+            int mid = (l + r)/2;
+            h = citations.size() - mid;
+            if (citations[mid] >= h) {
+                ans = max(ans, h);
+                r = mid - 1;
+            } else {
+                ans = max(ans, citations[mid]);
+                l = mid + 1;
+            }
+        }
+        return ans;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/h-index.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/h-index.md"
new file mode 100644
index 0000000..6d3edc3
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/h-index.md"
@@ -0,0 +1,55 @@
+# H指数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/h-index/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个研究员的引用量数组（每个引用量都是一个非负整数）。请计算该研究员的H指数。
+
+一个研究者的H指数为h，意味着他的论文中，有h篇有至少有h个引用量。
+ ### 样例说明
+ **样例1**
+
+```
+输入: citations = [3, 0, 6, 1, 5]
+输出: 3
+解释:
+研究者有5篇论文，每一篇的引用量为3，0，6，1，5。因为研究者有三篇论文至少有3个引用，而剩下两篇则引用不足3次，所以他的H指数为3
+```
+
+**样例2**
+
+```
+输入: citations = [5, 5, 5, 5, 5]
+输出: 5
+解释:
+研究者有5篇论文，每一篇的引用量为5, 5, 5, 5, 5。因为研究者有5篇论文至少有5个引用，所以他的H指数为5
+```
+
+ ### 参考代码
+ 求出一个后缀和数组，这个数组下标i对应的数表示大于等于i的数字出现的次数，这个数组可以O(n)求出
+然后从大到小枚举这些数，找到最大的满足条件的数即可
+总复杂度O(n)
+```cpp
+class Solution {
+public:
+    int hIndex(vector<int>& citations) {
+        int n = citations.size();
+        int num[n+1];
+        memset(num, 0, sizeof(num));
+        
+        for (int i = 0; i < citations.size(); i++) {
+            if (citations[i] >= n) {
+                num[n] ++;
+            } else {
+                num[citations[i]] ++;
+            }
+        }
+        int sum = 0;
+        for (int i = n; i >= 0; i--) {
+            sum += num[i];
+            if(sum >= i)
+                return i;
+        }
+        return 0;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/intersection-of-two-arrays-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/intersection-of-two-arrays-ii.md"
new file mode 100644
index 0000000..d304f1b
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/intersection-of-two-arrays-ii.md"
@@ -0,0 +1,60 @@
+# 两数组的交集 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/intersection-of-two-arrays-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个数组，计算两个数组的交集
+ ### 样例说明
+ **样例1**
+
+```
+输入: 
+nums1 = [1, 2, 2, 1], nums2 = [2, 2]
+输出: 
+[2, 2]
+```
+
+**样例2**
+
+```
+输入: 
+nums1 = [1, 1, 2], nums2 = [1]
+输出: 
+[1]
+```
+ ### 参考代码
+ 用map维护前一个数组中每个值出现的次数
+然后遍历第二个数组，对于每个遍历到的数，在map中将这个数出现的次数-1
+```java
+public class Solution {
+    /**
+     * @param nums1 an integer array
+     * @param nums2 an integer array
+     * @return an integer array
+     */
+    public int[] intersection(int[] nums1, int[] nums2) {
+        // Write your code here
+        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
+        for(int i = 0; i < nums1.length; ++i) {
+            if (map.containsKey(nums1[i]))
+                map.put(nums1[i], map.get(nums1[i]) + 1); 
+            else
+                map.put(nums1[i], 1);
+        }
+
+        List<Integer> results = new ArrayList<Integer>();
+
+        for (int i = 0; i < nums2.length; ++i)
+            if (map.containsKey(nums2[i]) &&
+                map.get(nums2[i]) > 0) {
+                results.add(nums2[i]);
+                map.put(nums2[i], map.get(nums2[i]) - 1); 
+            }
+
+        int result[] = new int[results.size()];
+        for(int i = 0; i < results.size(); ++i)
+            result[i] = results.get(i);
+
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/intersection-of-two-arrays.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/intersection-of-two-arrays.md"
new file mode 100644
index 0000000..347a78f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/intersection-of-two-arrays.md"
@@ -0,0 +1,155 @@
+# 两数组的交集
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/intersection-of-two-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出两个数组，写出一个方法求出它们的交集
+ ### 样例说明
+ **例1:**
+```
+输入: nums1 = [1, 2, 2, 1], nums2 = [2, 2], 
+输出: [2].
+```
+**例2:**
+```
+输入: nums1 = [1, 2], nums2 = [2], 
+输出: [2].
+```
+
+
+ ### 参考代码
+ 利用排序后二分查找即可实现
+```java
+// version 1: sort & merge
+public class Solution {
+    /**
+     * @param nums1 an integer array
+     * @param nums2 an integer array
+     * @return an integer array
+     */
+    public int[] intersection(int[] nums1, int[] nums2) {
+        Arrays.sort(nums1);
+        Arrays.sort(nums2);
+        
+        int i = 0, j = 0;
+        int[] temp = new int[nums1.length];
+        int index = 0;
+        while (i < nums1.length && j < nums2.length) {
+            if (nums1[i] == nums2[j]) {
+                if (index == 0 || temp[index - 1] != nums1[i]) {
+                    temp[index++] = nums1[i];
+                }
+                i++;
+                j++;
+            } else if (nums1[i] < nums2[j]) {
+                i++;
+            } else {
+                j++;
+            }
+        }
+        
+        int[] result = new int[index];
+        for (int k = 0; k < index; k++) {
+            result[k] = temp[k];
+        }
+        
+        return result;
+    }
+}
+
+// version 2: hash map
+public class Solution {
+    /**
+     * @param nums1 an integer array
+     * @param nums2 an integer array
+     * @return an integer array
+     */
+    public int[] intersection(int[] nums1, int[] nums2) {
+        if (nums1 == null || nums2 == null) {
+            return null;
+        }
+        
+        HashSet<Integer> hash = new HashSet<>();
+        for (int i = 0; i < nums1.length; i++) {
+            hash.add(nums1[i]);
+        }
+        
+        HashSet<Integer> resultHash = new HashSet<>();
+        for (int i = 0; i < nums2.length; i++) {
+            if (hash.contains(nums2[i]) && !resultHash.contains(nums2[i])) {
+                resultHash.add(nums2[i]);
+            }
+        }
+        
+        int size = resultHash.size();
+        int[] result = new int[size];
+        int index = 0;
+        for (Integer num : resultHash) {
+            result[index++] = num;
+        }
+        
+        return result;
+    }
+}
+
+// version 3: sort & binary search
+public class Solution {
+    /**
+     * @param nums1 an integer array
+     * @param nums2 an integer array
+     * @return an integer array
+     */
+    public int[] intersection(int[] nums1, int[] nums2) {
+        if (nums1 == null || nums2 == null) {
+            return null;
+        }
+        
+        HashSet<Integer> set = new HashSet<>();
+        
+        Arrays.sort(nums1);
+        for (int i = 0; i < nums2.length; i++) {
+            if (set.contains(nums2[i])) {
+                continue;
+            }
+            if (binarySearch(nums1, nums2[i])) {
+                set.add(nums2[i]);
+            }
+        }
+        
+        int[] result = new int[set.size()];
+        int index = 0;
+        for (Integer num : set) {
+            result[index++] = num;
+        }
+        
+        return result;
+    }
+    
+    private boolean binarySearch(int[] nums, int target) {
+        if (nums == null || nums.length == 0) {
+            return false;
+        }
+        
+        int start = 0, end = nums.length - 1;
+        while (start + 1 < end) {
+            int mid = (end - start) / 2 + start;
+            if (nums[mid] == target) {
+                return true;
+            }
+            if (nums[mid] < target) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        
+        if (nums[start] == target) {
+            return true;
+        }
+        if (nums[end] == target) {
+            return true;
+        }
+        
+        return false;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/interval-minimum-number.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/interval-minimum-number.md"
new file mode 100644
index 0000000..5b6d822
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/interval-minimum-number.md"
@@ -0,0 +1,96 @@
+# 区间最小数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/interval-minimum-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组（下标由 0 到 n-1，其中 n 表示数组的规模），以及一个查询列表。每一个查询列表有两个整数 `[start, end]`。 对于每个查询，计算出数组中从下标 start 到 end 之间的数的最小值，并返回在结果列表中。 
+ ### 样例说明
+ **样例1：**
+`输入：数组 ：[1,2,7,8,5] 查询 ：[(1,2),(0,4),(2,4)]。输出：[2,1,5]`
+**样例2：**
+`输入：数组 ：[4,5,7,1] 查询 ：[(1,2),(1,3)]。输出：[5,1]`
+ ### 参考代码
+ ```java
+/**
+ * Definition of Interval:
+ * public classs Interval {
+ *     int start, end;
+ *     Interval(int start, int end) {
+ *         this.start = start;
+ *         this.end = end;
+ *     }
+ */
+class SegmentTreeNode {
+    public int start, end, min;
+    public SegmentTreeNode left, right;
+    public SegmentTreeNode(int start, int end, int min) {
+          this.start = start;
+          this.end = end;
+          this.min = min;
+          this.left = this.right = null;
+    }
+}
+public class Solution {
+    /**
+     *@param A, queries: Given an integer array and an query list
+     *@return: The result list
+     */
+    public SegmentTreeNode build(int start, int end, int[] A) {
+        // write your code here
+        if(start > end) {  // check core case
+            return null;
+        }
+        
+        SegmentTreeNode root = new SegmentTreeNode(start, end, Integer.MAX_VALUE);
+        
+        if(start != end) {
+            int mid = (start + end) / 2;
+            root.left = build(start, mid, A);
+            root.right = build(mid+1, end, A);
+            
+            root.min = Math.min(root.left.min, root.right.min);
+        } else {
+            root.min = A[start];
+        }
+        return root;
+    }
+    public int query(SegmentTreeNode root, int start, int end) {
+        // write your code here
+        if(start == root.start && root.end == end) { // 相等 
+            return root.min;
+        }
+        
+        
+        int mid = (root.start + root.end)/2;
+        int leftmin = Integer.MAX_VALUE, rightmin = Integer.MAX_VALUE;
+        // 左子区
+        if(start <= mid) {
+            if( mid < end) { // 分裂 
+                leftmin =  query(root.left, start, mid);
+            } else { // 包含 
+                leftmin = query(root.left, start, end);
+            }
+        }
+        // 右子区
+        if(mid < end) { // 分裂 3
+            if(start <= mid) {
+                rightmin = query(root.right, mid+1, end);
+            } else { //  包含 
+                rightmin = query(root.right, start, end);
+            } 
+        }  
+        // else 就是不相交
+        return Math.min(leftmin, rightmin);
+    }
+    
+    public List<Integer> intervalMinNumber(int[] A, 
+                                           List<Interval> queries) {
+        // write your code here
+        SegmentTreeNode root = build(0, A.length - 1, A);
+        List<Integer> ans = new ArrayList<Integer>();
+        for(Interval in : queries) {
+            ans.add(query(root, in.start, in.end));
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/interval-sum-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/interval-sum-ii.md"
new file mode 100644
index 0000000..5ccb603
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/interval-sum-ii.md"
@@ -0,0 +1,150 @@
+# 区间求和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/interval-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在类的构造函数中给一个整数数组, 实现两个方法 `query(start, end)` 和 `modify(index, value)`:
+
+- 对于 query(*start*, *end*), 返回数组中下标 *start* 到 *end* 的 **和**。
+- 对于 modify(*index*, *value*), 修改数组中下标为 *index* 上的数为 *value*.
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+[1,2,7,8,5]
+[query(0,2),modify(0,4),query(0,1),modify(2,1),query(2,4)]
+输出: [10,6,14]
+说明:
+给定数组 A = [1,2,7,8,5].
+在query(0, 2)后, 1 + 2 + 7 = 10,
+在modify(0, 4)后, 将 A[0] 修改为 4， A = [4,2,7,8,5].
+在query(0, 1)后, 4 + 2 = 6.
+在modify(2, 1)后, 将 A[2] 修改为 1，A = [4,2,1,8,5].
+After query(2, 4), 1 + 8 + 5 = 14.
+```
+
+**样例2**
+
+```plain
+输入:
+[1,2,3,4,5]
+[query(0,0),query(1,2),quert(3,4)]
+输出: [1,5,9]
+说明:
+1 = 1
+2 + 3 = 5
+4 + 5 = 9
+```
+
+
+ ### 参考代码
+ 本题为线段树的基本运用，实现线段树的修改和查询即可。
+```java
+public class Solution {
+    /* you may need to use some attributes here */
+    
+     class SegmentTreeNode {
+        public int start, end;
+        public int sum;
+        public SegmentTreeNode left, right;
+        public SegmentTreeNode(int start, int end, int sum) {
+              this.start = start;
+              this.end = end;
+              this.sum = sum;
+              this.left = this.right = null;
+        }
+    }
+    SegmentTreeNode root;
+    public SegmentTreeNode build(int start, int end, int[] A) {
+        // write your code here
+        if(start > end) {  // check core case
+            return null;
+        }
+        
+        SegmentTreeNode root = new SegmentTreeNode(start, end, 0);
+        
+        if(start != end) {
+            int mid = (start + end) / 2;
+            root.left = build(start, mid, A);
+            root.right = build(mid+1, end, A);
+            
+            root.sum = root.left.sum + root.right.sum;
+        } else {
+            root.sum =  A[start];
+            
+        }
+        return root;
+    }
+    public int querySegmentTree(SegmentTreeNode root, int start, int end) {
+        // write your code here
+        if(start == root.start && root.end == end) { // 相等 
+            return root.sum;
+        }
+        
+        
+        int mid = (root.start + root.end)/2;
+        int leftsum = 0, rightsum = 0;
+        // 左子区
+        if(start <= mid) {
+            if( mid < end) { // 分裂 
+                leftsum =  querySegmentTree(root.left, start, mid);
+            } else { // 包含 
+                leftsum = querySegmentTree(root.left, start, end);
+            }
+        }
+        // 右子区
+        if(mid < end) { // 分裂 3
+            if(start <= mid) {
+                rightsum = querySegmentTree(root.right, mid+1, end);
+            } else { //  包含 
+                rightsum = querySegmentTree(root.right, start, end);
+            } 
+        }  
+        // else 就是不相交
+        return leftsum + rightsum;
+    }
+    public void modifySegmentTree(SegmentTreeNode root, int index, int value) {
+        // write your code here
+        if(root.start == index && root.end == index) { // 查找到
+            root.sum = value;
+            return;
+        }
+        
+        // 查询
+        int mid = (root.start + root.end) / 2;
+        if(root.start <= index && index <=mid) {
+            modifySegmentTree(root.left, index, value);
+        }
+        
+        if(mid < index && index <= root.end) {
+            modifySegmentTree(root.right, index, value);
+        }
+        //更新
+        root.sum = root.left.sum + root.right.sum;
+    }
+    /**
+     * @param A: An integer array
+     */
+    public Solution(int[] A) {
+        // write your code here
+        root = build(0, A.length-1, A);
+    }
+    
+    /**
+     * @param start, end: Indices
+     * @return: The sum from start to end
+     */
+    public long query(int start, int end) {
+        // write your code here
+        return querySegmentTree(root, start ,end);
+    }
+    
+    /**
+     * @param index, value: modify A[index] to value.
+     */
+    public void modify(int index, int value) {
+        // write your code here
+        modifySegmentTree(root, index, value);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/interval-sum.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/interval-sum.md"
new file mode 100644
index 0000000..d1fba19
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/interval-sum.md"
@@ -0,0 +1,185 @@
+# 区间求和  I
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/interval-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组（下标由 0 到 n-1，其中 n 表示数组的规模），以及一个查询列表。每一个查询列表有两个整数 `[start, end]` 。 对于每个查询，计算出数组中从下标 start 到 end 之间的数的总和，并返回在结果列表中。 
+ ### 样例说明
+ **样例 1:**
+```
+输入: 数组 = [1,2,7,8,5], 查询 = [(0,4),(1,2),(2,4)]
+输出: [23,9,20]
+```
+
+**样例 2:**
+```
+输入: 数组 = [4,3,1,2],  查询 = [(1,2),(0,2)]
+输出: [4,8]
+```
+ ### 参考代码
+ ```java
+/**
+ * Definition of Interval:
+ * public classs Interval {
+ *     int start, end;
+ *     Interval(int start, int end) {
+ *         this.start = start;
+ *         this.end = end;
+ *     }
+ */
+public class Solution {
+    /**
+     *@param A, queries: Given an integer array and an query list
+     *@return: The result list
+     */
+     class SegmentTreeNode {
+        public int start, end;
+        public Long sum;
+        public SegmentTreeNode left, right;
+        public SegmentTreeNode(int start, int end, Long sum) {
+              this.start = start;
+              this.end = end;
+              this.sum = sum;
+              this.left = this.right = null;
+        }
+    }
+    public SegmentTreeNode build(int start, int end, int[] A) {
+        // write your code here
+        if(start > end) {  // check core case
+            return null;
+        }
+        
+        SegmentTreeNode root = new SegmentTreeNode(start, end, 0L);
+        
+        if(start != end) {
+            int mid = (start + end) / 2;
+            root.left = build(start, mid, A);
+            root.right = build(mid+1, end, A);
+            
+            root.sum = root.left.sum + root.right.sum;
+        } else {
+            root.sum =  Long.valueOf(A[start]);
+            
+        }
+        return root;
+    }
+    public Long query(SegmentTreeNode root, int start, int end) {
+        // write your code here
+        if(start == root.start && root.end == end) { // 相等 
+            return root.sum;
+        }
+        
+        
+        int mid = (root.start + root.end)/2;
+        Long leftsum = 0L, rightsum = 0L;
+        // 左子区
+        if(start <= mid) {
+            if( mid < end) { // 分裂 
+                leftsum =  query(root.left, start, mid);
+            } else { // 包含 
+                leftsum = query(root.left, start, end);
+            }
+        }
+        // 右子区
+        if(mid < end) { // 分裂 3
+            if(start <= mid) {
+                rightsum = query(root.right, mid+1, end);
+            } else { //  包含 
+                rightsum = query(root.right, start, end);
+            } 
+        }  
+        // else 就是不相交
+        return leftsum + rightsum;
+    }
+    public ArrayList<Long> intervalSum(int[] A, 
+                                       ArrayList<Interval> queries) {
+        // write your code here
+        SegmentTreeNode root = build(0, A.length - 1, A);
+        ArrayList ans = new ArrayList<Long>();
+        for(Interval in : queries) {
+            ans.add(query(root, in.start, in.end));
+        }
+        return ans;
+    }
+}
+
+
+ *     Interval(int start, int end) {
+ *         this.start = start;
+ *         this.end = end;
+ *     }
+ */
+
+public class Solution {
+    /**
+     *@param A, queries: Given an integer array and an query list
+     *@return: The result list
+     */
+    public class SegmentTreeNode {
+        public int start, end, min;
+        public SegmentTreeNode left, right;
+        public SegmentTreeNode(int start, int end, int min) {
+              this.start = start;
+              this.end = end;
+              this.min = min;
+              this.left = this.right = null;
+        }
+    }
+    public SegmentTreeNode build(int start, int end, int[] A) {
+        // write your code here
+        if(start > end) {  // check core case
+            return null;
+        }
+       
+        SegmentTreeNode root = new SegmentTreeNode(start, end, Integer.MAX_VALUE);
+       
+        if(start != end) {
+            int mid = (start + end) / 2;
+            root.left = build(start, mid, A);
+            root.right = build(mid+1, end, A);
+           
+            root.min = Math.min(root.left.min, root.right.min);
+        } else {
+            root.min = A[start];
+        }
+        return root;
+    }
+    public int query(SegmentTreeNode root, int start, int end) {
+        // write your code here
+        if(start == root.start && root.end == end) { // equal
+            return root.min;
+        }
+       
+       
+        int mid = (root.start + root.end)/2;
+        int leftmin = Integer.MAX_VALUE, rightmin = Integer.MAX_VALUE;
+        // left
+        if(start <= mid) {
+            if( mid < end) { // split
+                leftmin =  query(root.left, start, mid);
+            } else { //  contain
+                leftmin = query(root.left, start, end);
+            }
+        }
+        // right
+        if(mid < end) { // split
+            if(start <= mid) {
+                rightmin = query(root.right, mid+1, end);
+            } else { //  contain
+                rightmin = query(root.right, start, end);
+            }
+        }
+        return Math.min(leftmin, rightmin);
+    }
+   
+    public List<Integer> intervalMinNumber(int[] A,
+                                           List<Interval> queries) {
+        // write your code here
+        SegmentTreeNode root = build(0, A.length - 1, A);
+        List<Integer> ans = new ArrayList<Integer>();
+        for(Interval in : queries) {
+            ans.add(query(root, in.start, in.end));
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/k-closest-numbers-in-sorted-array.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/k-closest-numbers-in-sorted-array.md"
new file mode 100644
index 0000000..be9c46c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/k-closest-numbers-in-sorted-array.md"
@@ -0,0 +1,72 @@
+# 在排序数组中找最接近的K个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/k-closest-numbers-in-sorted-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个目标数 `target`, 一个非负整数 `k`, 一个按照升序排列的数组 `A`。在`A`中找与`target`最接近的`k`个整数。返回这`k`个数并按照与`target`的接近程度从小到大排序，如果接近程度相当，那么小的数排在前面。
+ ### 样例说明
+ 
+ ### 参考代码
+ 直接在数组中二分查找 `target`, 如果不存在则返回大于 `target` 的最小的或者小于 `target` 的最大的元素均可.
+
+然后使用两根指针从该位置开始向两端遍历, 每次把差值比较小的元素放入答案中然后将该指针向边界方向移动一下即可.
+```java
+public class Solution {
+    /**
+     * @param A      an integer array
+     * @param target an integer
+     * @param k      a non-negative integer
+     * @return an integer array
+     */
+    public int[] kClosestNumbers(int[] A, int target, int k) {
+        int[] result = new int[k];
+
+        if (A == null || A.length == 0) {
+            return A;
+        }
+        if (k > A.length) {
+            return A;
+        }
+
+        int index = firstIndex(A, target);
+
+        int start = index - 1;
+        int end = index;
+        for (int i = 0; i < k; i++) {
+            if (start < 0) {
+                result[i] = A[end++];
+            } else if (end >= A.length) {
+                result[i] = A[start--];
+            } else {
+                if (target - A[start] <= A[end] - target) {
+                    result[i] = A[start--];
+                } else {
+                    result[i] = A[end++];
+                }
+            }
+        }
+        return result;
+    }
+
+    private int firstIndex(int[] A, int target) {
+        int start = 0, end = A.length - 1;
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (A[mid] < target) {
+                start = mid;
+            } else if (A[mid] > target) {
+                end = mid;
+            } else {
+                end = mid;
+            }
+        }
+
+        if (A[start] >= target) {
+            return start;
+        }
+        if (A[end] >= target) {
+            return end;
+        }
+        return A.length;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/last-position-of-target.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/last-position-of-target.md"
new file mode 100644
index 0000000..3629e95
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/last-position-of-target.md"
@@ -0,0 +1,46 @@
+# 目标最后位置
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/last-position-of-target/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个升序数组，找到 `target` 最后一次出现的位置，如果没出现过返回 `-1`
+ ### 样例说明
+ **样例 1：**
+```
+输入：nums = [1,2,2,4,5,5], target = 2
+输出：2
+```
+**样例 2：**
+```
+输入：nums = [1,2,2,4,5,5], target = 6
+输出：-1
+```
+ ### 参考代码
+ ```python
+class Solution:
+    # @param {int[]} A an integer array sorted in ascending order
+    # @param {int} target an integer
+    # @return {int} an integer
+    def lastPosition(self, A, target):
+        if not A or target is None:
+            return -1
+
+        start = 0
+        end = len(A) - 1
+
+        while start + 1 < end:
+            mid = start + (end - start) // 2
+
+            if A[mid] < target:
+                start = mid
+            elif A[mid] > target:
+                end = mid
+            else:
+                start = mid
+    
+        if A[end] == target:
+            return end
+        elif A[start] == target:
+            return start
+        else:
+            return -1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-absolute-value.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-absolute-value.md"
new file mode 100644
index 0000000..e67364c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-absolute-value.md"
@@ -0,0 +1,70 @@
+# 最大绝对值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-absolute-value/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组`A`，从中选出`n`个数，使得这个`n`个数中两两之差的绝对值的最小值尽可能大。你需要返回这个最大的绝对值。
+ ### 样例说明
+ **样例1**
+
+```
+输入: A = [1,2,8,4,9,3], n = 3
+输出: 3
+解释:
+选择[1,4,8]或者[1,4,9]均可。
+```
+
+**样例2**
+
+```
+输入: A = [1,2,3,4,5,6],  n = 2
+输出: 5
+解释:
+选[1,6]
+```
+ ### 参考代码
+ 二分答案，类似 Wood Cut
+```java
+public class Solution {
+    /**
+     * @param A: an array
+     * @param n: an integer
+     * @return: makes the smallest absolute value of the difference between any two elements to largest
+     */
+    public int maximumAbsolutValue(int[] A, int n) {
+        if (A == null || A.length == 0) {
+            return -1;
+        }
+        
+        Arrays.sort(A);
+        
+        // find maximum gap that we can get more than n numbers
+        int start = 0, end = 2147483647;
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (getNumbers(A, mid) >= n) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        
+        if (getNumbers(A, end) >= n) {
+            return end;
+        }
+        
+        return start;
+    }
+
+    // greedy algorithm to get the most numbers from array
+    private int getNumbers(int[] A, int gap) {
+        int count = 1, lastNumber = A[0];
+        for (int i = 1; i < A.length; i++) {
+            if (A[i] - lastNumber >= gap) {
+                lastNumber = A[i];
+                count++;
+            }
+        }
+        return count;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-average-subarray-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-average-subarray-ii.md"
new file mode 100644
index 0000000..55b3a21
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-average-subarray-ii.md"
@@ -0,0 +1,86 @@
+# 子数组的最大平均值 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-average-subarray-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个整数数组，有正有负。找到这样一个子数组，他的长度大于等于 `k`，且平均值最大。
+ ### 样例说明
+ 例1:
+```
+输入:
+[1,12,-5,-6,50,3]
+3
+输出:
+15.667
+解释:
+ (-6 + 50 + 3) / 3 = 15.667
+```
+
+例2:
+```
+输入:
+[5]
+1
+输出:
+5.000
+```
+
+
+
+ ### 参考代码
+ 使用九章算法强化班中讲过的基于二分答案的方法
+二分出 average 之后，把数组中的每个数都减去 average，然后的任务就是去求这个数组中，是否有长度 >= k 的 subarray，他的和超过 0。
+这一步用类似 Maximum Subarray 的解法来做就好了
+```java
+// 九章算法强化班版本，辅助空间O(1) 
+public class Solution {
+    /**
+     * @param nums: an array with positive and negative numbers
+     * @param k: an integer
+     * @return: the maximum average
+     */
+    
+    private boolean canFind(int[] A, int K, double avg) {
+        int i, k;
+        double rightSum = 0, leftSum = 0, minLeftSum = 0;
+        for (i = 0; i < K; ++i) {
+            rightSum += A[i] - avg;
+        }
+        
+        for (i = K; i <= A.length; ++i) {
+            if (rightSum - minLeftSum >= 0) {
+                return true;
+            }
+            
+            if (i < A.length) {
+                rightSum += A[i] - avg;
+                leftSum += A[i - K] - avg;
+                minLeftSum = Math.min(minLeftSum, leftSum);
+            }
+        }
+        
+        return false;
+    } 
+     
+    public double maxAverage(int[] A, int K) {
+        int i;
+        double start, stop, mid;
+        start = stop = A[0];
+        for (i = 0; i < A.length; ++i) {
+            start = Math.min(A[i], start);
+            stop = Math.max(A[i], stop);
+        }
+        
+        while (start + 1e-5 < stop) {
+            mid = (start + stop) / 2;
+            if (canFind(A, K, mid)) {
+                start = mid;
+            }
+            else {
+                stop = mid;
+            }
+        }
+        
+        return start;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-average-subarray.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-average-subarray.md"
new file mode 100644
index 0000000..f0068dc
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-average-subarray.md"
@@ -0,0 +1,48 @@
+# 子数组的最大平均值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-average-subarray/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个由`n`个整数组成的数组，找到给定长度`k`的连续子数组，该子数组具有最大平均值。你需要输出最大平均值。
+ ### 样例说明
+ **样例1**
+
+```
+输入: nums = [1,12,-5,-6,50,3] and k = 4
+输出: 12.75
+解释:
+最大平均为(12-5-6+50)/4 = 51/4 = 12.75
+```
+
+
+
+**样例2**
+
+```
+输入: nums = [4,2,1,3,3] and k = 2
+输出: 3.00
+解释:
+最大平均为(3+3)/2 = 6/2 = 3.00
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param nums: an array
+     * @param k: an integer
+     * @return: the maximum average value
+     */
+    public double findMaxAverage(int[] nums, int k) {
+        // Write your code here
+        int n = nums.length;
+        int[] sum = new int[n + 1];
+        for(int i = 1; i <= n; i++){
+            sum[i] = sum[i - 1] + nums[i - 1];
+        }
+        int ans = Integer.MIN_VALUE;
+        for(int i = k; i <= n; i++){
+            ans = Math.max(ans, sum[i] - sum[i - k]);
+        }
+        return ans * 1.0 / k;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-number-in-mountain-sequence.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-number-in-mountain-sequence.md"
new file mode 100644
index 0000000..031d29f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/maximum-number-in-mountain-sequence.md"
@@ -0,0 +1,72 @@
+# 山脉序列中的最大值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-number-in-mountain-sequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给 `n` 个整数的山脉数组，即先增后减的序列，找到山顶（最大值）
+ ### 样例说明
+ 例1:
+```
+输入: nums = [1, 2, 4, 8, 6, 3] 
+输出: 8
+```
+例2:
+```
+输入: nums = [10, 9, 8, 7], 
+输出: 10
+```
+
+ ### 参考代码
+ 二分法，判断山脉趋势，按照取数递归左边或者右边即可。
+山顶的条件是第一个使得 `nums[i] > nums[i + 1]` 的 i。
+当然也可以反过来，最后一个使得 `nums[i] > nums[i - 1]` 的 i
+```
+[[python]]
+class Solution:
+    """
+    @param nums: a mountain sequence which increase firstly and then decrease
+    @return: then mountain top
+    """
+    def mountainSequence(self, nums):
+        if not nums:
+            return -1
+            
+        # find first index i so that nums[i] > nums[i + 1]
+        start, end = 0, len(nums) - 1
+        while start + 1 < end:
+            mid = (start + end) // 2
+            # mid + 1 保证不会越界
+            # 因为 start 和 end 是 start + 1 < end
+            if nums[mid] > nums[mid + 1]:
+                end = mid
+            else:
+                start = mid
+        
+        return max(nums[start], nums[end])
+[[java]]
+public class Solution {
+    /**
+     * @param nums: a mountain sequence which increase firstly and then decrease
+     * @return: then mountain top
+     */
+    public int mountainSequence(int[] nums) {
+        if (nums == null || nums.length == 0) {
+            return -1;
+        }
+            
+        // find first index i so that nums[i] > nums[i + 1]
+        int start = 0, end = nums.length - 1;
+        while (start + 1 < end) {
+            int mid = (start + end) / 2;
+            // mid + 1 保证不会越界
+            // 因为 start 和 end 是 start + 1 < end
+            if (nums[mid] > nums[mid + 1]) {
+                end = mid;
+            } else {
+                start = mid;
+            }
+        }
+        
+        return Math.max(nums[start], nums[end]);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/median-of-k-sorted-arrays.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/median-of-k-sorted-arrays.md"
new file mode 100644
index 0000000..68f293c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/median-of-k-sorted-arrays.md"
@@ -0,0 +1,87 @@
+# K 个有序数组的中位数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/median-of-k-sorted-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有 `k` 个有序数组 `nums`。找到这 `k` 个有序数组的中位数。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+[[1],[2],[3]]
+输出:
+2.00
+```
+
+**样例 2:**
+```
+输入:
+[[1,1,2],[2,4,8],[3,7,10,20]]
+输出:
+3.50
+```
+ ### 参考代码
+ 使用二分答案的方法。
+可以在《九章算法强化班》中学到哦！
+```python
+class Solution:
+    """
+    @param nums: the given k sorted arrays
+    @return: the median of the given k sorted arrays
+    """
+    def findMedian(self, nums):
+        if not nums:
+            return 0.0
+            
+        n = sum(len(arr) for arr in nums)
+        if n == 0:
+            return 0.0
+            
+        if n % 2 == 1:
+            return self.find_kth(nums, n // 2 + 1) * 1.0
+        return (self.find_kth(nums, n // 2) + self.find_kth(nums, n // 2 + 1)) / 2.0
+
+    # k is one-based, from 1 to n
+    def find_kth(self, arrs, k):
+        start, end = self.get_range(arrs)
+        
+        # find the first num that there are >= k nums <= num
+        while start + 1 < end:
+            mid = (start + end) // 2
+            if self.get_smaller_or_equal(arrs, mid) >= k:
+                end = mid
+            else:
+                start = mid
+        if self.get_smaller_or_equal(arrs, start) >= k:
+            return start
+        return end
+            
+    def get_range(self, arrs):
+        start = min(arr[0] for arr in arrs if len(arr))
+        end = max(arr[-1] for arr in arrs if len(arr))
+        return start, end
+        
+    def get_smaller_or_equal(self, arrs, val):
+        count = 0
+        for arr in arrs:
+            count += self.get_smaller_or_equal_in_arr(arr, val)
+        return count
+        
+    def get_smaller_or_equal_in_arr(self, arr, val):
+        if not arr:
+            return 0
+            
+        # find the first num > val
+        start, end = 0, len(arr) - 1
+        while start + 1 < end:
+            mid = (start + end) // 2
+            if arr[mid] > val:
+                end = mid
+            else:
+                start = mid
+        
+        if arr[start] > val:
+            return start
+        if arr[end] > val:
+            return end
+        return end + 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/powx-n.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/powx-n.md"
new file mode 100644
index 0000000..88a08dc
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/powx-n.md"
@@ -0,0 +1,68 @@
+# x的n次幂
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/powx-n/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现 pow(x, n). (n是一个整数)
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: x = 9.88023, n = 3
+输出: 964.498
+```
+
+**样例 2:**
+
+```
+输入: x = 2.1, n = 3
+输出: 9.261
+```
+
+**样例 3:**
+
+```
+输入: x = 1, n = 0
+输出: 1
+```
+ ### 参考代码
+ 注意 n 可能是负数, 需要求一下倒数, 可以在一开始把x转换成倒数, 也可以到最后再把结果转换为倒数.
+
+那么现在我们实现 pow(x, n), n 是正整数的版本:
+
+二分即可: 有 $x^n = x{n/2} * x{n/2}$, 因此可以在 O(*logn*) 的时间复杂度内实现.
+
+又叫快速幂. 有递归实现和循环实现的版本.
+
+*还可以参考一下 fast power 中的[二进制的做法](https://www.jiuzhang.com/solutions/fast-power)。*
+```java
+public class Solution {
+    /**
+     * @param x the base number
+     * @param n the power number
+     * @return the result
+     */
+    public double myPow(double x, int n) {
+        boolean isNegative = false;
+        if (n < 0) {
+            x = 1 / x;
+            isNegative = true;
+            n = -(n + 1);       // Avoid overflow when n == MIN_VALUE
+        }
+
+        double ans = 1, tmp = x;
+
+        while (n != 0) {
+            if (n % 2 == 1) {
+                ans *= tmp;
+            }
+            tmp *= tmp;
+            n /= 2;
+        }
+        
+        if (isNegative) {
+            ans *= x;
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-a-2d-matrix.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-a-2d-matrix.md"
new file mode 100644
index 0000000..641f396
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-a-2d-matrix.md"
@@ -0,0 +1,147 @@
+# 搜索二维矩阵
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/search-a-2d-matrix/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 写出一个高效的算法来搜索 *m* × *n*矩阵中的值。
+
+这个矩阵具有以下特性：
+
+- 每行中的整数从左到右是排序的。
+- 每行的第一个数大于上一行的最后一个整数。
+ ### 样例说明
+ ```
+样例  1:
+	输入: [[5]],2
+	输出: false
+	
+	样例解释: 
+  没有包含，返回false。
+
+样例 2:
+	输入:  
+[
+  [1, 3, 5, 7],
+  [10, 11, 16, 20],
+  [23, 30, 34, 50]
+],3
+	输出: true
+	
+	样例解释: 
+	包含则返回true。
+
+```
+
+ ### 参考代码
+ Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:
+
+Integers in each row are sorted from left to right.
+The first integer of each row is greater than the last integer of the previous row.
+For example,
+
+Consider the following matrix:
+
+[
+  [1,   3,  5,  7],
+  [10, 11, 16, 20],
+  [23, 30, 34, 50]
+]
+Given target = 3, return true.
+
+可以看作是一个有序数组被分成了n段，每段就是一行。因此依然可以二分求解。
+对每个数字，根据其下标i，j进行编号，每个数字可被编号为0～n*n-1
+
+相当于是在一个数组中的下标。然后直接像在数组中二分一样来做。取的mid要还原成二位数组中的下标，i = mid/n, j = mid%n
+```java
+// Binary Search Twice
+public class Solution {
+    public boolean searchMatrix(int[][] matrix, int target) {
+        if (matrix == null || matrix.length == 0) {
+            return false;
+        }
+        if (matrix[0] == null || matrix[0].length == 0) {
+            return false;
+        }
+        
+        int row = matrix.length;
+        int column = matrix[0].length;
+        
+        // find the row index, the last number <= target 
+        int start = 0, end = row - 1;
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (matrix[mid][0] == target) {
+                return true;
+            } else if (matrix[mid][0] < target) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        if (matrix[end][0] <= target) {
+            row = end;
+        } else if (matrix[start][0] <= target) {
+            row = start;
+        } else {
+            return false;
+        }
+        
+        // find the column index, the number equal to target
+        start = 0;
+        end = column - 1;
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (matrix[row][mid] == target) {
+                return true;
+            } else if (matrix[row][mid] < target) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        if (matrix[row][start] == target) {
+            return true;
+        } else if (matrix[row][end] == target) {
+            return true;
+        }
+        return false;
+    }
+}
+
+// Binary Search Once
+public class Solution {
+    /**
+     * @param matrix, a list of lists of integers
+     * @param target, an integer
+     * @return a boolean, indicate whether matrix contains target
+     */
+    public boolean searchMatrix(int[][] matrix, int target) {
+        // write your code here
+        if(matrix == null || matrix.length == 0){
+            return false;
+        }
+        
+        if(matrix[0] == null || matrix[0].length == 0){
+            return false;
+        }
+        
+        int row = matrix.length;
+        int column = matrix[0].length;
+        
+        int start = 0, end = row * column - 1;
+        while(start <= end){
+            int mid = start + (end - start) / 2;
+            int number = matrix[mid / column][mid % column];
+            if(number == target){
+                return true;
+            }else if(number > target){
+                end = mid - 1;
+            }else{
+                start = mid + 1;
+            }
+        }
+        
+        return false;
+        
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-for-a-range.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-for-a-range.md"
new file mode 100644
index 0000000..4ab8bc3
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-for-a-range.md"
@@ -0,0 +1,68 @@
+# 搜索区间
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/search-for-a-range/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个包含 *n* 个整数的排序数组，找出给定目标值 *target* 的起始和结束位置。
+
+如果目标值不在数组中，则返回`[-1, -1]`
+ ### 样例说明
+ 例1:
+```
+输入:
+[]
+9
+输出:
+[-1,-1]
+
+```
+
+例2:
+```
+输入:
+[5, 7, 7, 8, 8, 10]
+8
+输出:
+[3, 4]
+```
+
+ ### 参考代码
+ 由于是排序数组，两次二分查找，一个是第一次比target-1大的位置，一个是第一次比他target大的位置。返回即可
+```python
+class Solution:
+    """
+    @param A : a list of integers
+    @param target : an integer to be searched
+    @return : a list of length 2, [index1, index2]
+    """
+    def searchRange(self, A, target):
+        if len(A) == 0:
+            return [-1, -1]
+        
+        start, end = 0, len(A) - 1
+        while start + 1 < end:
+            mid = (start + end) / 2
+            if A[mid] < target:
+                start = mid
+            else:
+                end = mid
+        
+        if A[start] == target:
+            leftBound = start
+        elif A[end] == target:
+            leftBound = end
+        else:
+            return [-1, -1]
+        
+        start, end = leftBound, len(A) - 1
+        while start + 1 < end:
+            mid = (start + end) / 2
+            if A[mid] <= target:
+                start = mid
+            else:
+                end = mid
+        if A[end] == target:
+            rightBound = end
+        else:
+            rightBound = start
+        return [leftBound, rightBound]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-in-a-big-sorted-array.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-in-a-big-sorted-array.md"
new file mode 100644
index 0000000..970e90a
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-in-a-big-sorted-array.md"
@@ -0,0 +1,128 @@
+# 在大数组中查找
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/search-in-a-big-sorted-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个按照升序排序的非负整数数组。这个数组很大以至于你只能通过固定的接口 `ArrayReader.get(k)` 来访问第k个数(或者C++里是ArrayReader->get(k))，并且你也没有办法得知这个数组有多大。
+
+找到给出的整数target第一次出现的位置。你的算法需要在O(logk)的时间复杂度内完成，k为target第一次出现的位置的下标。
+
+如果找不到target，返回-1。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [1, 3, 6, 9, 21, ...], target = 3
+输出: 1
+```
+
+**样例 2:**
+
+```
+输入: [1, 3, 6, 9, 21, ...], target = 4
+输出: -1
+```
+ ### 参考代码
+ > 该题目有两种思路: 二分和倍增. 其实这两种方法有一些相似之处, 很多时候可以在相同的时空分析下解决同一个问题.
+
+**方法1 倍增:**
+
+首先特判一下首个元素. 然后设定 `idx = 0` 为查找的下标, `jump = 1` 为向后跳跃的长度.
+
+每次循环将 `idx` 向后移动 `jump` 个元素, 并将 `jump` 翻倍. 而如果移动后的位置不小于 `target`, 则 `jump` 缩小至一半.
+
+即我们在保证每次跳跃后的 `idx` 的位置都小于`target`的前提下, 倍增式地跳跃, 以此保证 O(logn) 的时间复杂度.
+
+循环终止的条件就是 `jump == 0`, 就是说, 这时 `idx + 1` 的位置以及不小于 `target` 了 (此时idx位置的仍然是小于target)
+
+也就是说, 到最后`idx`指向的元素是: 最大的小于`target`的元素. 返回答案前判断一下 `idx + 1` 是否 `target` 即可.
+
+---
+
+**方法2 二分:**
+
+二分查找第一个不小于`target`的元素很简单. 但是需要确定二分区间的范围. 此时还是需要倍增地找到右边界.
+
+初始右边界为1, 如果右边界的数小于 `target`, 就将其倍增, 直到右边界不小于`target`.
+
+这时就可以二分查找了.
+
+注意: 越界访问是没有关系的, 因为这个`ArrayReader`在越界访问时, 返回 INT_MAX, 一定不小于 `target`. 而即使是返回 -1 之类的数值, 我们也可以加一个判断搞定.
+```java
+/////////////// 方法1 倍增
+
+/**
+ * Definition of ArrayReader:
+ * 
+ * public class ArrayReader {
+ * public int get(int index) {
+ *          // return the number on given index, 
+ *          // return 2147483647 if the index is invalid.
+ *     }
+ * };
+ */
+public class Solution {
+    /*
+     * @param reader: An instance of ArrayReader.
+     * @param target: An integer
+     * @return: An integer which is the first index of target.
+     */
+    public int searchBigSortedArray(ArrayReader reader, int target) {
+        int firstElement = reader.get(0);
+        if (firstElement == target) 
+            return 0;
+        else if (firstElement > target)
+            return -1;
+        
+        int idx = 0, jump = 1;
+        while (jump != 0) {
+            while (jump != 0 && reader.get(idx + jump) >= target)   // 越界时返回INT_MAX, 必然不小于target
+                jump >>= 1;
+            idx += jump;
+            jump <<= 1;     // 当jump为0时, 左移一位不影响它的值, 不影响循环结束
+        }
+        
+        if (reader.get(idx + 1) == target)
+            return idx + 1;
+        else
+            return -1;
+    }
+}
+
+/////////////// 方法2 二分
+
+/**
+ * Definition of ArrayReader:
+ * 
+ * public class ArrayReader {
+ * public int get(int index) {
+ *          // return the number on given index, 
+ *          // return 2147483647 if the index is invalid.
+ *     }
+ * };
+ */
+public class Solution {
+    /*
+     * @param reader: An instance of ArrayReader.
+     * @param target: An integer
+     * @return: An integer which is the first index of target.
+     */
+    public int searchBigSortedArray(ArrayReader reader, int target) {
+        int l = 0, r = 1, mid;
+        while (reader.get(r) < target)     // 越界返回INT_MAX, 必然大于target, 所以没有关系
+            r <<= 1;
+        
+        while (l < r) {
+            mid = (l + r) >> 1;
+            if (reader.get(mid) >= target)
+                r = mid;
+            else
+                l = mid + 1;
+        }
+        
+        if (reader.get(l) == target)
+            return l;
+        else
+            return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-insert-position.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-insert-position.md"
new file mode 100644
index 0000000..ef711ed
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/search-insert-position.md"
@@ -0,0 +1,87 @@
+# 搜索插入位置
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/search-insert-position/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">给定一个排序数组和一个目标值，如果在数组中找到目标值则返回索引。如果没有，返回到它将会被按顺序插入的位置。</span><br></p><p>你可以假设在数组中无重复元素。</p>
+ ### 样例说明
+ <p><b><font color="#e76363">[1,3,5,6]</font></b>，5 → 2</p><p><font color="#e76363"><b>[1,3,5,6]</b></font>，2 → 1</p><p><b><font color="#e76363">[1,3,5,6]</font></b>， 7 → 4</p><p><b><font color="#e76363">[1,3,5,6]</font></b>，0 → 0</p>
+ ### 参考代码
+ Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
+
+You may assume no duplicates in the array.
+
+Here are few examples.
+[1,3,5,6], 5 → 2
+[1,3,5,6], 2 → 1
+[1,3,5,6], 7 → 4
+[1,3,5,6], 0 → 0
+分析:题目要求时间复杂度O(log(n))，同时涉及有序数组中查找，使用标准二分查找即可实现。
+```java
+// version 1: find the first position >= target
+public class Solution {
+    public int searchInsert(int[] A, int target) {
+        if (A == null || A.length == 0) {
+            return 0;
+        }
+        int start = 0, end = A.length - 1;
+        
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (A[mid] == target) {
+                return mid;
+            } else if (A[mid] < target) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        
+        if (A[start] >= target) {
+            return start;
+        } else if (A[end] >= target) {
+            return end;
+        } else {
+            return end + 1;
+        }
+    }
+}
+
+// version 2: find the last position < target, return +1， 要特判一下target小于所有数组里面的元素
+
+public class Solution {
+    public int searchInsert(int[] A, int target) {
+        if (A == null || A.length == 0) {
+            return 0;
+        }
+        int start = 0;
+        int end = A.length - 1;
+        int mid;
+        
+        if (target < A[0]) {
+            return 0;
+        }
+        // find the last number less than target
+        while (start + 1 < end) {
+            mid = start + (end - start) / 2;
+            if (A[mid] == target) {
+                return mid;
+            } else if (A[mid] < target) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        
+        if (A[end] == target) {
+            return end;
+        }
+        if (A[end] < target) {
+            return end + 1;
+        }
+        if (A[start] == target) {
+            return start;
+        }
+        return start + 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/smallest-rectangle-enclosing-black-pixels.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/smallest-rectangle-enclosing-black-pixels.md"
new file mode 100644
index 0000000..a4d89e5
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/smallest-rectangle-enclosing-black-pixels.md"
@@ -0,0 +1,137 @@
+# 包裹黑色像素点的最小矩形
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/smallest-rectangle-enclosing-black-pixels/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 一个由二进制矩阵表示的图，`0` 表示白色像素点，`1` 表示黑色像素点。黑色像素点是联通的，即只有一块黑色区域。像素是水平和竖直连接的，给一个黑色像素点的坐标 `(x, y)` ，返回囊括所有黑色像素点的矩阵的最小面积。
+ ### 样例说明
+ **样例 1:**
+```
+输入：["0010","0110","0100"]，x=0，y=2
+输出：6
+解释：
+矩阵左上角坐标是(0, 1), 右下角的坐标是(2, 2)
+```
+
+**样例 2:**
+```
+输入：["1110","1100","0000","0000"], x = 0, y = 1
+输出：6
+解释：
+矩阵左上角坐标是(0,  0), 右下角坐标是(1, 3)
+```
+ ### 参考代码
+ 考点：
+* 二分
+
+题解：
+根据题意，在列中需要找出第一个'1'出现的最左侧坐标和最右侧坐标，在行中需要找出第一个'1'出现的最上面坐标和最下面坐标。故采用二分的方法在区间查找即可。最后返回(right - left + 1) * (bottom - top + 1)即可。
+```java
+public class Solution {
+    /**
+     * @param image a binary matrix with '0' and '1'
+     * @param x, y the location of one of the black pixels
+     * @return an integer
+     */
+    public int minArea(char[][] image, int x, int y) {
+        if (image == null || image.length == 0 || image[0].length == 0) {
+            return 0;
+        }
+        
+        int n = image.length;
+        int m = image[0].length;
+        
+        int left = findLeft(image, 0, y);
+        int right = findRight(image, y, m - 1);
+        int top = findTop(image, 0, x);
+        int bottom = findBottom(image, x, n - 1);
+
+        return (right - left + 1) * (bottom - top + 1);
+    }
+    
+    private int findLeft(char[][] image, int start, int end) {
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (isEmptyColumn(image, mid)) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        
+        if (isEmptyColumn(image, start)) {
+            return end;
+        }
+        
+        return start;
+    }
+    
+    private int findRight(char[][] image, int start, int end) {
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (isEmptyColumn(image, mid)) {
+                end = mid;
+            } else {
+                start = mid;
+            }
+        }
+        
+        if (isEmptyColumn(image, end)) {
+            return start;
+        }
+        
+        return end;
+    }
+    
+    private int findTop(char[][] image, int start, int end) {
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (isEmptyRow(image, mid)) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        
+        if (isEmptyRow(image, start)) {
+            return end;
+        }
+        
+        return start;
+    }
+    
+    private int findBottom(char[][] image, int start, int end) {
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (isEmptyRow(image, mid)) {
+                end = mid;
+            } else {
+                start = mid;
+            }
+        }
+        
+        if (isEmptyRow(image, end)) {
+            return start;
+        }
+        
+        return end;
+    }
+    
+    private boolean isEmptyColumn(char[][] image, int col) {
+        for (int i = 0; i < image.length; i++) {
+            if (image[i][col] == '1') {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    private boolean isEmptyRow(char[][] image, int row) {
+        for (int j = 0; j < image[0].length; j++) {
+            if (image[row][j] == '1') {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/split-array-largest-sum.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/split-array-largest-sum.md"
new file mode 100644
index 0000000..a25c52d
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/split-array-largest-sum.md"
@@ -0,0 +1,72 @@
+# 拆分子数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/split-array-largest-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个由非负整数组成的数组和一个整数m，我们要把数组拆分为m个非空连续子数组。编写算法以最小化这些m个子阵列中的最大总和。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[7,2,5,10,8], m = 2
+输出：18
+解释：
+    将nums拆分成子数组的方式有4种。
+    最好的选择是拆分成 [7,2,5] 和 [10,8], 
+    两个子数组中的最大的和只有 18。
+```
+
+**样例 2:**
+```
+输入：[1,4,4], m = 3
+输出：4
+解释：
+    将nums拆分成子数组的方式有1种。
+    最好的选择是拆分成 [1],[4] 和 [4],
+    两个子数组中的最大的和只有4。
+```
+
+
+
+ ### 参考代码
+ 考点：
+* 二分法
+
+题解：二分答案即可，左端为max，右端为sum(数组和)，二分答案check即可。
+```cpp
+class Solution {
+public:
+    bool check(int max_val, vector<int>& nums, int m) {
+        int cnt = 1;
+        int sum = 0;
+        for (int i = 0; i < nums.size(); i++) {
+            if (nums[i] > max_val) {
+                return false;
+            }
+            if (sum + nums[i] > max_val) {		//如果当前连续和大于max_val
+                cnt++;							//计数+1
+                sum = nums[i];					//sum更新为num[i]
+            } else {
+                sum += nums[i];
+            }
+        }
+        return cnt <= m;
+    }
+    int splitArray(vector<int>& nums, int m) {
+        long long l = 0, r = 0;
+        for (int i = 0; i < nums.size(); ++i) {
+            l = max((int)l, nums[i]);		//确定二分查找的左右端点
+            r += nums[i];
+        }
+        int ans = 0;
+        while(l <= r) {
+            long long mid = (l + r) / 2;
+            if (check(mid, nums, m)) {	//二分check
+                ans = mid;
+                r = mid - 1;
+            } else {
+                l = mid + 1;
+            }
+        }
+        return ans;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/sqrt-x.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/sqrt-x.md"
new file mode 100644
index 0000000..d6ac820
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/sqrt-x.md"
@@ -0,0 +1,39 @@
+# 对x开根
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sqrt-x/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现 `int sqrt(int x)` 函数，计算并返回 *x* 的平方根。
+
+ ### 样例说明
+ 
+ ### 参考代码
+ Implement int sqrt(int x).
+
+Compute and return the square root of x.
+<div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博: &nbsp;</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/BDJCsFUbt" target="_blank">http://weibo.com/3948019741/BDJCsFUbt</a></span></font><br></div>
+```java
+class Solution {
+    /**
+     * @param x: An integer
+     * @return: The sqrt of x
+     */
+    public int sqrt(int x) {
+        // find the last number which square of it <= x
+        long start = 1, end = x;
+        while (start + 1 < end) {
+            long mid = start + (end - start) / 2;
+            if (mid * mid <= x) {
+                start = mid;
+            } else {
+                end = mid;
+            }
+        }
+        
+        if (end * end <= x) {
+            return (int) end;
+        }
+        return (int) start;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/sqrtx-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/sqrtx-ii.md"
new file mode 100644
index 0000000..e192ee6
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/sqrtx-ii.md"
@@ -0,0 +1,40 @@
+# 对x开根II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sqrtx-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现 `double sqrt(double x)` 并且 `x >= 0`。
+计算并返回x开根后的值。
+ ### 样例说明
+ 例1:
+```
+输入: n = 2 
+输出: 1.41421356
+```
+例2:
+```
+输入: n = 3
+输出: 1.73205081
+```
+
+ ### 参考代码
+ ```python
+class Solution:
+    """
+    @param: x: a double
+    @return: the square root of x
+    """
+    def sqrt(self, x):
+        if x >= 1:
+            start, end = 1, x
+        else:
+            start, end = x, 1
+        
+        while end - start > 1e-10:
+            mid = (start + end) / 2
+            if mid * mid < x:
+                start = mid
+            else:
+                end = mid
+                
+        return start
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/subarray-sum-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/subarray-sum-ii.md"
new file mode 100644
index 0000000..1cdd312
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/subarray-sum-ii.md"
@@ -0,0 +1,77 @@
+# 子数组求和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/subarray-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个正整数数组 `A` 和一个区间. 返回和在给定区间范围内的子数组数量.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: A = [1, 2, 3, 4], start = 1, end = 3
+输出: 4
+解释: 所有可能的子数组: [1](和为1), [1, 2](和为3), [2](和为2), [3](和为3).
+```
+
+**样例 2:**
+
+```
+输入: A = [1, 2, 3, 4], start = 1, end = 100
+输出: 10
+解释: 任意子数组都可以.
+```
+ ### 参考代码
+ **O(N) 的两根指针的算法**
+
+其实需要三根指针, 因为需要额外记录一下从哪个位置开始的加和已经 >= start 了.
+
+对于每一个左端点 left, 求出对应的两个右端点 right_start, right_end. 前者表示最左边的使得 [left, right_start] 子数组的和不小于 start 的点, 而后者表示最右边的使得 [left, right_end] 子数组的和不大于 end 的点.
+
+right_end - right_start + 1 就是以 left 为左端点的合法子数组的数量.
+
+从左到右枚举 left, 而 right_start, right_end 随着left的增长也是只增不减的, 所以时间复杂度是 O(N)
+
+**O(NlogN) 的二分法**
+
+求出一个前缀和数组, 然后对于每一个前缀和 presum[right], 我们要求出两个点 left_start, left_end. 前者表示最左边的使得 [left_start, right] 子数组和不大于 end 的点, 后者表示最右边的使得 [left_end, right] 子数组和不小于 start 的点.
+
+枚举 right, 我们可以在 presum[0..right] 上二分查找确定 left_start, left_end.
+
+**总结**
+
+上面两种方法是相通的, 都是对于子数组的一个端点, 确认另外一个端点的范围. 在枚举其中一个端点的过程, 另外一个端点的范围是单调的, 所以可以使用两根指针 O(N) 地完成.
+
+可以把两根指针和二分法综合一下, 不过这样理论时间复杂度是不变的, 没有很大的必要. 以上两种方法推荐第一种, 复杂度更低.
+```python
+class Solution:
+    """
+    @param A: An integer array
+    @param start: An integer
+    @param end: An integer
+    @return: the number of possible answer
+    """
+    def subarraySumII(self, A, start, end):
+        n = len(A)
+        big_sum, small_sum = 0, 0
+        big_end, small_end = 0, 0
+        ans = 0
+        for i in range(n):
+            small_end = max(small_end, i)
+            big_end = max(big_end, i)
+            while small_end < n and small_sum + A[small_end] < start:
+                small_sum += A[small_end]
+                small_end += 1
+            while big_end < n and big_sum + A[big_end] <= end:
+                big_sum += A[big_end]
+                big_end += 1
+            
+            if big_end - small_end > 0:
+                ans += big_end - small_end
+                
+            if small_end > i:
+                small_sum -= A[i]
+            
+            if big_end > i:
+                big_sum -= A[i]
+            
+        return ans
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/total-occurrence-of-target.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/total-occurrence-of-target.md"
new file mode 100644
index 0000000..e8acb22
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/total-occurrence-of-target.md"
@@ -0,0 +1,67 @@
+# 目标出现总和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/total-occurrence-of-target/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个升序的数组，以及一个*target*，找到它在数组中出现的次数。
+ ### 样例说明
+ 样例1：
+```
+输入：[1,3,3,4,5]和target= 3，
+输出：2。
+```
+样例2：
+```
+输入：[2,2,3,4,6]和target= 4，
+输出：1。
+```
+样例3：
+```
+输入：[1,2,3,4,5]和target= 6，
+输出：0。
+```
+ ### 参考代码
+ 用二分找到target 第一次出现的位置，在找到最后一次出现的位置，算一下距离差就知道了。
+```java
+public class Solution {
+    /**
+     * @param A an integer array sorted in ascending order
+     * @param target an integer
+     * @return an integer
+     */
+    public int totalOccurrence(int[] A, int target) {
+        // Write your code here
+        int n = A.length;
+        if (n == 0) {
+            return 0;
+        }
+        if (A[n-1] < target || A[0] > target) {
+            return 0;
+        }
+        
+        int l = 0, r = n - 1;
+        int start = 0;
+        while (l <= r) {
+            int mid = l + (r - l) / 2;
+            if (A[mid] >= target) {
+                start = mid;
+                r = mid - 1;
+            } else
+                l = mid + 1;
+        }
+        if (A[start] != target)
+            return 0;
+
+        int end = n - 1;
+        l = 0; r = n - 1;
+        while (l <= r) {
+            int mid = l + (r - l) / 2;
+            if (A[mid] <= target) {
+                end = mid;
+                l = mid + 1;
+            } else
+                r = mid - 1;
+        }
+        return end - start + 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/web-logger.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/web-logger.md"
new file mode 100644
index 0000000..b97afd9
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/web-logger.md"
@@ -0,0 +1,80 @@
+# 网页日志
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/web-logger/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现下面两个方法：
+1.`hit(timestamp)` 建立一个时间戳
+2.`get_hit_count_in_last_5_minutes(timestamp)` 得到最后5分钟时间戳个数
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  hit(1);
+  hit(2);
+  get_hit_count_in_last_5_minutes(3);
+  hit(300);
+  get_hit_count_in_last_5_minutes(300);
+  get_hit_count_in_last_5_minutes(301);
+输出: 
+  2
+  3
+  2
+```
+
+**样例 2:**
+
+```
+输入: 
+  hit(1)
+  hit(1)
+  hit(1)
+  hit(2)
+  get_hit_count_in_last_5_minutes(3)
+  hit(300)
+  get_hit_count_in_last_5_minutes(300)
+  get_hit_count_in_last_5_minutes(301)
+  get_hit_count_in_last_5_minutes(302)
+  get_hit_count_in_last_5_minutes(900)
+输出: 
+  4
+  5
+  2
+  1
+  0
+  0
+```
+ ### 参考代码
+ 因为 `timestamp` 是递增的, 所以我们可以用一个队列储存所有的记录.
+
+- `hit(timestamp)` 直接将 `timestamp` 放到队尾
+- `get_hit_count_in_last_5_minutes(timestamp)` 弹出队首, 直到队首元素与 `timestamp` 差距在300内为止, 返回队列大小即可
+
+其中, 弹出元素的过程可以优化, 使用二分查找确定最大的小于 `timestamp - 300` 的元素.
+```python
+class WebLogger:
+    
+    def __init__(self):
+        self.Q = []
+
+    """
+    @param: timestamp: An integer
+    @return: nothing
+    """
+    def hit(self, timestamp):
+        self.Q.append(timestamp)
+
+    """
+    @param: timestamp: An integer
+    @return: An integer
+    """
+    def get_hit_count_in_last_5_minutes(self, timestamp):
+        if self.Q == []:
+            return 0
+        i = 0
+        n = len(self.Q)
+        while i < n and self.Q[i] + 300 <= timestamp:
+            i += 1
+        self.Q = self.Q[i:]
+        return len(self.Q)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/wiggle-sort-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/wiggle-sort-ii.md"
new file mode 100644
index 0000000..6c9f5be
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/wiggle-sort-ii.md"
@@ -0,0 +1,84 @@
+# 摆动排序 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/wiggle-sort-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个数组`nums`，将它重排列如下形式
+```
+nums[0] < nums[1] > nums[2] < nums[3]....
+```
+ ### 样例说明
+ 
+ ### 参考代码
+ $O(n)$ 的时间，$O(1)$ 额外空间
+算法一言难尽，去上九章算法强化班吧。
+
+这个问题的做法是，先找到中位数，然后根据中位数把数组分成三个部分，< median, == median, > median
+然后把这三个部分按照从大到小摆放在从右到左每次跳一格的位置。
+```python
+class Solution:
+    """
+    @param: nums: A list of integers
+    @return: nothing
+    """
+    def wiggleSort(self, nums):
+        if not nums:
+            return
+        
+        # partition nums into smaller half and bigger half
+        # all nums in smaller half <= any num in bigger half
+        median = self.find_median(nums)
+        
+        n = len(nums)
+
+        # reorder the nums from
+        # 0 => n-1(odd), (n-2)(even)
+        # 1 => n-3
+        # 2 => n-5
+        # ...
+        # (n - 1) / 2 => 0
+        # (n - 1) / 2 + 1 => n - 2(odd), n - 1(even)
+        # (n - 1) / 2 + 2 => n - 4(odd), n - 3(even)
+        # ... 
+        def get_index(i):
+            if i <= (n - 1) // 2:
+                return n - i * 2 - 1 - (n + 1) % 2
+            i -= (n - 1) // 2 + 1
+            return n - i * 2 - 1 - n % 2
+            
+        # 3-way partition
+        left, i, right = 0, 0, n - 1
+        while i <= right:
+            if nums[get_index(i)] < median:
+                nums[get_index(left)], nums[get_index(i)] = nums[get_index(i)], nums[get_index(left)]
+                i += 1
+                left += 1
+            elif nums[get_index(i)] == median:
+                i += 1
+            else:
+                nums[get_index(right)], nums[get_index(i)] = nums[get_index(i)], nums[get_index(right)]
+                right -= 1
+        
+    def find_median(self, nums):
+        return self.find_kth(nums, 0, len(nums) - 1, (len(nums) - 1) // 2)
+    
+    def find_kth(self, nums, start, end, kth):
+        # k is zero based
+        left, right = start, end
+        mid = nums[(left + right) // 2]
+        
+        while left <= right:
+            while left <= right and nums[left] < mid:
+                left += 1
+            while left <= right and nums[right] > mid:
+                right -= 1
+            if left <= right:
+                nums[left], nums[right] = nums[right], nums[left]
+                left, right = left + 1, right - 1
+                
+        if kth <= right:
+            return self.find_kth(nums, start, right, kth)
+        elif kth >= left:
+            return self.find_kth(nums, left, end, kth)
+        else:
+            return nums[kth]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/wood-cut.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/wood-cut.md"
new file mode 100644
index 0000000..724536f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\272\214\345\210\206\346\263\225/wood-cut.md"
@@ -0,0 +1,60 @@
+# 木材加工
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/wood-cut/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有一些原木，现在想把这些木头切割成一些长度相同的小段木头，需要得到的小段的数目至少为 `k`。当然，我们希望得到的小段越长越好，你需要计算能够得到的小段木头的最大长度。
+ ### 样例说明
+ **样例 1**
+
+```plain
+输入:
+L = [232, 124, 456]
+k = 7
+输出: 114
+Explanation: 我们可以把它分成114cm的7段，而115cm不可以
+```
+
+**样例 2**
+
+```plain
+输入:
+L = [1, 2, 3]
+k = 7
+输出: 0
+说明:很显然我们不能按照题目要求完成。
+```
+ ### 参考代码
+ 使用九章算法强化班中所讲的基于答案值域的二分法。
+木头长度的范围在 1 到 max(L)，在这个范围内二分出一个长度 length，然后看看以这个 wood length 为前提的基础上，能切割出多少木头，如果少于 k 根，说明要短一些才行，如果多余 k，说明可以继续边长一些。
+```python
+class Solution:
+    """
+    @param L: Given n pieces of wood with length L[i]
+    @param k: An integer
+    @return: The maximum length of the small pieces
+    """
+    def woodCut(self, L, k):
+        if not L:
+            return 0
+
+        start, end = 1, max(L)
+        while start + 1 < end:
+            mid = (start + end) // 2
+            if self.get_pieces(L, mid) >= k:
+                start = mid
+            else:
+                end = mid
+                
+        if self.get_pieces(L, end) >= k:
+            return end
+        if self.get_pieces(L, start) >= k:
+            return start
+            
+        return 0
+        
+    def get_pieces(self, L, length):
+        pieces = 0
+        for l in L:
+            pieces += l // length
+        return pieces
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/a-b-problem.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/a-b-problem.md"
new file mode 100644
index 0000000..897ba3a
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/a-b-problem.md"
@@ -0,0 +1,53 @@
+# A + B 问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/a-b-problem/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出两个整数 $a$ 和 $b$ , 求他们的和。
+ ### 样例说明
+ **样例  1:**
+
+```
+输入:  a = 1, b = 2
+输出: 3	
+样例解释: 返回a+b的结果.
+```
+
+**样例 2:**
+
+```
+输入:  a = -1, b = 1
+输出: 0	
+样例解释: 返回a+b的结果.
+```
+ ### 参考代码
+ 不使用加法运算符计算a+b
+
+详细解释见注释
+```java
+class Solution {
+    /*
+     * param a: The first integer
+     * param b: The second integer
+     * return: The sum of a and b
+     */
+    public int aplusb(int a, int b) {
+        // 主要利用异或运算来完成 
+        // 异或运算有一个别名叫做：不进位加法
+        // 那么a ^ b就是a和b相加之后，该进位的地方不进位的结果
+        // 然后下面考虑哪些地方要进位，自然是a和b里都是1的地方
+        // a & b就是a和b里都是1的那些位置，a & b << 1 就是进位
+        // 之后的结果。所以：a + b = (a ^ b) + (a & b << 1)
+        // 令a' = a ^ b, b' = (a & b) << 1
+        // 可以知道，这个过程是在模拟加法的运算过程，进位不可能
+        // 一直持续，所以b最终会变为0。因此重复做上述操作就可以
+        // 求得a + b的值。
+        while (b != 0) {
+            int _a = a ^ b;
+            int _b = (a & b) << 1;
+            a = _a;
+            b = _b;
+        }
+        return a;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/add-binary.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/add-binary.md"
new file mode 100644
index 0000000..6d02617
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/add-binary.md"
@@ -0,0 +1,90 @@
+# 二进制求和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/add-binary/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个二进制字符串，返回他们的和（用二进制表示）。
+ ### 样例说明
+ **样例 1：**
+```
+输入：
+a = "0", b = "0"
+输出：
+"0"
+```
+**样例 2：**
+```
+输入：
+a = "11", b = "1"
+输出：
+"100"
+```
+ ### 参考代码
+ Given two binary strings, return their sum (also a binary string).
+
+For example,
+a = "11"
+b = "1"
+Return "100".
+```java
+public class Solution {
+    public String addBinary(String a, String b) {
+        if(a.length() < b.length()){
+            String tmp = a;
+            a = b;
+            b = tmp;
+        }
+        
+        int pa = a.length()-1;
+        int pb = b.length()-1;
+        int carries = 0;
+        String rst = "";
+        
+        while(pb >= 0){
+            int sum = (int)(a.charAt(pa) - '0') + (int)(b.charAt(pb) - '0') + carries;
+            rst = String.valueOf(sum % 2) + rst;
+            carries = sum / 2;
+            pa --;
+            pb --;
+        }
+        
+        while(pa >= 0){
+            int sum = (int)(a.charAt(pa) - '0') + carries;
+            rst = String.valueOf(sum % 2) + rst;
+            carries = sum / 2;
+            pa --;
+        }       
+        
+        if (carries == 1)
+            rst = "1" + rst;
+        return rst;
+    }
+}
+
+
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param a a number
+     * @param b a number
+     * @return the result
+     */
+    public String addBinary(String a, String b) {
+        // Write your code here
+        String ans = "";
+
+        int carry = 0;
+        for (int i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
+            int sum = carry;
+            sum += (i >= 0) ? a.charAt(i) - '0' : 0;
+            sum += (j >= 0) ? b.charAt(j) - '0' : 0;
+            ans = (sum % 2) + ans;
+            carry = sum / 2;
+        }
+        if (carry != 0) {
+            ans = carry + ans;
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/add-digits.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/add-digits.md"
new file mode 100644
index 0000000..b6dc829
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/add-digits.md"
@@ -0,0 +1,83 @@
+# 各位相加
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/add-digits/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个非负整数 `num`，反复的将所有位上的数字相加，直到得到一个一位的整数。
+ ### 样例说明
+ 例1:
+```
+输入:
+num=38
+输出:
+2
+解释:
+过程如下： 3 + 8 = 11, 1 + 1 = 2. 因为 2 只有一个数字，返回 2.
+
+```
+
+例2:
+```
+输入:
+num=9
+输出:
+9
+解释:
+9<10,返回 9.
+```
+
+ ### 参考代码
+ 反复相加，直到最后小于10,退出循环
+```java
+#### 参考程序 - Java
+
+
+
+	public class Solution {
+
+		public int addDigits(int num) {
+
+			if (num == 0) {
+
+			    return 0;
+
+			}
+
+			int ans = 0;
+
+			for (; num != 0; ) {
+
+			    int digit = num % 10;
+
+			    ans = (ans * 10 + digit) % 9;
+
+			    num /= 10;
+
+			}
+
+			return ans == 0 ? 9 : ans;
+
+		}
+
+	}
+
+// 九章硅谷求职算法集训营版本
+public class Solution {
+    /**
+     * @param num: a non-negative integer
+     * @return: one digit
+     */
+    public int addDigits(int num) {
+        while (num >= 10) {
+            int sum = 0;
+            while (num > 0) {
+                sum += num % 10;
+                num /= 10;
+            }
+            
+            num = sum;
+        }
+        
+        return num;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/add-strings.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/add-strings.md"
new file mode 100644
index 0000000..5f09190
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/add-strings.md"
@@ -0,0 +1,40 @@
+# 大整数加法
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/add-strings/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 以字符串的形式给出两个非负整数 `num1` 和 `num2`，返回 `num1` 和 `num2` 的和。 
+ ### 样例说明
+ **样例 1:**
+```
+输入 : num1 = "123", num2 = "45"
+输出 : "168"
+```
+ ### 参考代码
+ 将两个数解析后相加即可
+```java
+public class Solution {
+    public String addStrings(String num1, String num2) {
+        String res = "";
+        int m = num1.length(), n = num2.length(), i = m - 1, j = n - 1, flag = 0;
+        while(i >= 0 || j >= 0){
+            int a, b; 
+            if(i >= 0){
+                a = num1.charAt(i--) - '0';
+            }
+            else{
+                a = 0;
+            }
+            if(j >= 0){
+                b = num2.charAt(j--) - '0';
+            }
+            else{
+                b = 0;
+            }
+            int sum = a + b + flag;
+            res =(char)(sum % 10 + '0') + res;
+            flag = sum / 10;
+        }
+        return flag == 1 ? "1" + res: res; 
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/binary-representation.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/binary-representation.md"
new file mode 100644
index 0000000..56d4aac
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/binary-representation.md"
@@ -0,0 +1,65 @@
+# 二进制表示
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-representation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数将其转换为二进制（均用字符串表示），如果这个数的小数部分不能在 32 个字符之内来精确地表示，则返回 `"ERROR"`。
+ ### 样例说明
+ 
+ ### 参考代码
+ 我们需要把整数和小数部分分离，整数部分按照短除法进行进制转换，小数部分按照$*2$看整数部分法进行进制转换，注意的是，如果乘32次都没有结束，直接返回ERROR
+```java
+public class Solution {
+    /**
+     *@param n: Given a decimal number that is passed in as a string
+     *@return: A string
+     */
+     
+    private String parseInteger(String str) {
+        int n = Integer.parseInt(str);
+        if (str.equals("") || str.equals("0")) {
+            return "0";
+        }
+        String binary = "";
+        while (n != 0) {
+            binary = Integer.toString(n % 2) + binary;
+            n = n / 2;
+        }
+        return binary;
+    }
+    
+    private String parseFloat(String str) {
+        double d = Double.parseDouble("0." + str);
+        String binary = "";
+        HashSet<Double> set = new HashSet<Double>();
+        while (d > 0) {
+            if (binary.length() > 32 || set.contains(d)) {
+                return "ERROR";
+            }
+            set.add(d);
+            d = d * 2;
+            if (d >= 1) {
+                binary = binary + "1";
+                d = d - 1;
+            } else {
+                binary = binary + "0";
+            }
+        }
+        return binary;
+    }
+    
+    public String binaryRepresentation(String n) {
+        if (n.indexOf('.') == -1) {
+            return parseInteger(n);
+        }
+        String[] params = n.split("\\.");
+        String flt = parseFloat(params[1]);
+        if (flt == "ERROR") {
+            return flt;
+        }
+        if (flt.equals("0") || flt.equals("")) {
+            return parseInteger(params[0]);
+        }
+        return parseInteger(params[0]) + "." + flt;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/binary-watch.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/binary-watch.md"
new file mode 100644
index 0000000..947712f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/binary-watch.md"
@@ -0,0 +1,55 @@
+# 二进制手表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/binary-watch/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给了一个二进制显示时间的手表和一个非负整数 `n`, `n` 代表在给定时间表上 `1` 的数量, 返回所有可能的时间
+ ### 样例说明
+ **样例1**
+```
+输入： 1
+输出： ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"]
+```
+**样例2**
+```
+输入： 2
+输出： ["0:03","0:05","0:06","0:09","0:10","0:12","0:17","0:18","0:20","0:24","0:33","0:34","0:36","0:40","0:48","10:00","1:01","1:02","1:04","1:08","1:16","1:32","2:01","2:02","2:04","2:08","2:16","2:32","3:00","4:01","4:02","4:04","4:08","4:16","4:32","5:00","6:00","8:01","8:02","8:04","8:08","8:16","8:32","9:00"]
+```
+ ### 参考代码
+ 遍历所有1的数量为num的二进制数，找出符合条件的数即可。
+```java
+public class Solution {
+    public List<String> readBinaryWatch(int num) {
+        ArrayList<String> ans = new ArrayList<String>();
+        ArrayList<ArrayList<Integer>> hour = new ArrayList<ArrayList<Integer>>();
+        ArrayList<ArrayList<Integer>> min = new ArrayList<ArrayList<Integer>>();
+    for(int i = 0; i < 4; i++) {
+        hour.add(new ArrayList<Integer>());
+    }
+    for(int i = 0; i < 6; i++) {
+        min.add(new ArrayList<Integer>());
+    }
+        for(int i = 0; i < 12; i++) {
+            int n = Integer.bitCount(i);
+            hour.get(n).add(i);
+        }
+        for(int i = 0; i < 60; i++) {
+            min.add(new ArrayList<Integer>());
+            int n = Integer.bitCount(i);
+            min.get(n).add(i);
+        }
+        for(int i = 0; i <= num && i < 4; i++) {
+            for(int h = 0; h < hour.get(i).size(); h++) {
+                for(int m = 0; m < min.get(num - i).size() && num - i < 6; m++) {
+                    String string = hour.get(i).get(h).toString() + ":";
+                    if(min.get(num - i).get(m) < 10) {
+                        string += "0";
+                    }
+                    string += min.get(num - i).get(m).toString();
+                    ans.add(string);
+                }
+            }
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/bitwise-and-of-numbers-range.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/bitwise-and-of-numbers-range.md"
new file mode 100644
index 0000000..020086a
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/bitwise-and-of-numbers-range.md"
@@ -0,0 +1,44 @@
+#  数字范围内位的与
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/bitwise-and-of-numbers-range/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定范围[m，n]，其中0 <= m <= n <= 2147483647，输出此范围内所有数字的按位AND，包括端值。
+
+例如，给定范围[5,7]，输出返回4。
+ ### 样例说明
+ **样例1**
+
+```
+输入: m=5, n=7
+输出: 4
+```
+
+**样例2**
+
+```
+输入: m=14, n=15
+输出: 14
+```
+ ### 参考代码
+ 本题中，我们需要得到[m,n]所有元素按位与的结果。举个例子，当m=26，n=30时，它们的二进制表示为为：
+**11**010　　**11**011　　**11**100　　**11**101　　**11**110
+这个样例的答案是**11**000，易见我们发现我们只需要找到m和n最左边的公共部分即可。
+
+每次都将n与n-1按位与，当n的二进制为1010时，1010 & 1001 = 1000，相当于把二进制位的最后一个1去掉了。因此我们不断的做n^n-1的操作，直到n小于m相等即可。
+```java
+public class Solution {
+    /**
+     * @param m: an Integer
+     * @param n: an Integer
+     * @return: the bitwise AND of all numbers in [m,n]
+     */
+    public int rangeBitwiseAnd(int m, int n) {
+        // Write your code here
+        while(m < n) {
+            n = n & (n-1);
+        }
+        return n;
+        
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/convert-a-number-to-hexadecimal.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/convert-a-number-to-hexadecimal.md"
new file mode 100644
index 0000000..bd8c4d4
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/convert-a-number-to-hexadecimal.md"
@@ -0,0 +1,89 @@
+# 将数字转换为16进制
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-a-number-to-hexadecimal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数，写一个函数将其转换为16进制。对于负整数，需要使用[**二进制补码**](https://en.wikipedia.org/wiki/Two%27s_complement "")。
+ ### 样例说明
+ **样例1**
+```
+输入：26
+输出："1a"
+```
+**样例2**
+```
+输入：-1
+输出："ffffffff"
+```
+ ### 参考代码
+ 辗转相除求十六进制
+```java
+// 方法一
+public class Solution {
+    public String toHex(int num) {
+        if(num == 0) {
+            return "0";
+        }
+        String ans = "";
+        int len = 0;
+        while(num != 0 && len < 8) {
+            //15的二进制：1111
+            int bit = num & 15;
+            if(bit < 10) {
+                //0 - 9
+                ans = (char)('0' + bit) + ans;
+            }
+            else {
+                //a - f
+                ans = (char)('a' + bit - 10) + ans;
+            }
+            //位运算，对二进制的num右移4位相当于除以16
+            num >>= 4;
+            len++;
+        }
+        return ans;
+    }
+}
+
+// 方法二：普通的辗转相除，区分正负整数分别计算
+public class Solution {
+    public String toHex(int num) {
+        if(num == 0) {
+            return "0";
+        }
+        int bit[] = new int[10];
+        int len = 0;
+        String ans = "";
+        for(int i=0; i<9; i++) {
+            bit[i] = 0;
+        }
+        long n = num;
+        n = n > 0? n : -n;
+        while(n > 0) {
+            bit[len++] = (int)n % 16;
+            n /= 16;
+        }
+        if(num < 0) {
+            for(int i=0; i<8; i++)
+            {
+                bit[i] = 15 - bit[i];
+            }
+            int pos = 0;
+            while(bit[pos] == 15)
+            {
+                bit[pos] = 0;
+                pos++;
+            }
+            bit[pos]++;
+        }
+        int leader0 = 1;
+        for(int i=7; i>=0; i--)
+        {    
+            if(bit[i] != 0) leader0 = 0;
+            if(leader0 == 1) continue;
+            if(bit[i] < 10) ans += (char)('0' + bit[i]);
+            else ans += (char)('a' + bit[i] - 10);
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/count-1-in-binary.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/count-1-in-binary.md"
new file mode 100644
index 0000000..ab0c763
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/count-1-in-binary.md"
@@ -0,0 +1,38 @@
+# 二进制中有多少个1 
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/count-1-in-binary/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 计算在一个 32 位的整数的二进制表示中有多少个 `1`。
+ ### 样例说明
+ **样例 1：**
+```
+输入：32
+输出：1
+解释：
+32(100000)，返回 1。
+```
+**样例 2：**
+```
+输入：5
+输出：2
+解释：
+5(101)，返回 2。
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param num: an integer
+     * @return: an integer, the number of ones in num
+     */
+    public int countOnes(int num) {
+        int count = 0;
+        while (num != 0) {
+            num = num & (num - 1);
+            count++;
+        }
+        return count;
+    }
+};
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/flip-bits.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/flip-bits.md"
new file mode 100644
index 0000000..911ba5d
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/flip-bits.md"
@@ -0,0 +1,25 @@
+# 将整数A转换为B
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/flip-bits/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 如果要将整数n转换为m，需要改变多少个bit位？
+ ### 样例说明
+ 
+ ### 参考代码
+ a ^ b 得到的结果的二进制中，1的个数就是a和b相异的位数。
+```java
+class Solution {
+    /**
+     *@param a, b: Two integer
+     *return: An integer
+     */
+    public static int bitSwapRequired(int a, int b) {
+        // write your code here
+        int count = 0;  
+        for (int c = a ^ b; c != 0; c = c >>> 1) {
+            count += c & 1;
+        }
+        return count;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/gray-code.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/gray-code.md"
new file mode 100644
index 0000000..1322eeb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/gray-code.md"
@@ -0,0 +1,50 @@
+# 格雷编码
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/gray-code/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 格雷编码是一个二进制数字系统，在该系统中，两个连续的数值仅有一个二进制的差异。
+
+给定一个非负整数 `n` ，表示该代码中所有二进制的总数，请找出其格雷编码顺序。一个格雷编码顺序必须以 `0` 开始，并覆盖所有的 2<sup>n</sup> 个整数。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 1
+输出: [0, 1]
+```
+
+**样例 2:**
+
+```
+输入: 2
+输出: [0, 1, 3, 2]
+解释: 
+  0 - 00
+  1 - 01
+  3 - 11
+  2 - 10
+```
+ ### 参考代码
+ 最简单的做法是利用位运算. 在 [计算机组成与设计](https://www.amazon.cn/dp/B01174AJ0S/ref=sr_1_1?ie=UTF8&qid=1549795920&sr=8-1&keywords=%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E4%B8%8E%E8%AE%BE%E8%AE%A1+%E7%A1%AC%E4%BB%B6%2F%E8%BD%AF%E4%BB%B6%E6%8E%A5%E5%8F%A3)一书上有介绍. (*或者其他相关书籍也有, 笔者在这本书上看到的*)
+
+一个数字对应的格雷编码的计算方式是: 
+
+- 将其二进制第一位(从高位数)与0异或, 得到的结果为格雷码的第一位
+- 之后依次将原数的第i位与生成的格雷码第i-1位做异或运算, 即可得到格雷码的第i位.
+
+递归做法题解见九章算法微博: <http://weibo.com/3948019741/BxXJHiQeN>
+```cpp
+class Solution {
+public:
+    /**
+     * @param n a number
+     * @return Gray code
+     */
+    vector<int> grayCode(int n) {
+        vector<int> result(1 << n);
+        for (size_t i = 0; i < (1 << n); i++)
+            result[i] = i ^ (i >> 1);
+        return result;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/hamming-distance.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/hamming-distance.md"
new file mode 100644
index 0000000..5252dc4
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/hamming-distance.md"
@@ -0,0 +1,47 @@
+# Hamming距离
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/hamming-distance/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 两个整数的Hamming距离是对应比特位不同的个数。
+给定两个整数x和y，计算两者的Hamming距离。
+ ### 样例说明
+ **样例1**
+
+```
+输入: x = 1 和 y = 4
+输出: 2
+解释:
+1的二进制表示是001
+4的二进制表示是100
+共有2位不同
+```
+
+
+
+**样例2**
+
+```
+输入: x = 5 和 y = 2
+输出: 3
+解释:
+5的二进制表示是101
+2的二进制表示是010
+共有3位不同
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    public int hammingDistance(int x, int y) {
+        int Distance=0;
+        
+        while ( x != 0 || y != 0 ) {
+            if ( x % 2 != y % 2 ) {
+                Distance ++;
+            }
+            x /= 2;
+            y /= 2;
+        }
+        return Distance;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/number-of-1-bits.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/number-of-1-bits.md"
new file mode 100644
index 0000000..6b2dde1
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/number-of-1-bits.md"
@@ -0,0 +1,38 @@
+# 判断一个整数中有多少个1
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/number-of-1-bits/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 写一个函数，其以无符号整数为输入，而输出对应二进制数所具有的“1”的位数（也被称为汉明权重）
+ ### 样例说明
+ **样例 1**
+```
+输入：n = 11
+输出：3
+解析：11(10) = 1011(2), 返回 3
+```
+**样例 2**
+```
+输入：n = 7
+输出：3
+解析：7(10) = 111(2), 返回 3
+```
+ ### 参考代码
+ 使用位运算符号‘&’，与1做与操作
+并将n右移一位( >>1 )
+直到n为0
+```java
+public class Solution {
+    /**
+     * @param n: an unsigned integer
+     * @return: the number of â€™1' bits
+     */
+    public int hammingWeight(int n) {
+        int ones = 0;
+        while(n!=0) {
+            ones += (n & 1);
+            n = n>>1;
+        }
+        return ones;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/o1-check-power-of-2.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/o1-check-power-of-2.md"
new file mode 100644
index 0000000..c33db1d
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/o1-check-power-of-2.md"
@@ -0,0 +1,27 @@
+# O(1)时间检测2的幂次
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/o1-check-power-of-2/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 用 O(*1*) 时间检测整数 *n* 是否是 *2* 的幂次。
+ ### 样例说明
+ 
+ ### 参考代码
+ 2的幂的数字，其二进制中只有一个1。
+$n&(n-1) == 0$ 说明只有1个1。
+```cpp
+class Solution {
+public:
+    /*
+     * @param n: An integer
+     * @return: True or false
+     */
+    bool checkPowerOf2(int n) {
+        // write your code here
+        if (n==0)
+            return false;
+        while (n % 2 == 0)
+            n /=2 ;
+        return n == 1;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/single-number-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/single-number-ii.md"
new file mode 100644
index 0000000..20008aa
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/single-number-ii.md"
@@ -0,0 +1,45 @@
+# 落单的数 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/single-number-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出3*n + 1 个非负整数，除其中一个数字之外其他每个数字均出现三次，找到这个数字。</p>
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:  [1,1,2,3,3,3,2,2,4,1]
+输出:  4
+```
+
+**样例 2:**
+
+```
+输入: [2,1,2,2]
+输出:  1	
+```
+ ### 参考代码
+ Given an array of integers, every element appears three times except for one. Find that single one.&nbsp;<div><br></div><div>Note:&nbsp;</div><div>Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?<div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博：&nbsp;</span><a href="http://weibo.com/3948019741/BjVFuAKoh" target="_blank">http://weibo.com/3948019741/BjVFuAKoh</a><br></div></div>
+
+
+统计二进制每个位上1的个数并对3取模。
+出现一次的数字对应位上的1会被统计出来。
+```java
+public class Solution {
+    public int singleNumberII(int[] A) {
+        if (A == null || A.length == 0) {
+            return -1;
+        }
+        int result=0;
+        int[] bits=new int[32];
+        for (int i = 0; i < 32; i++) {
+            for(int j = 0; j < A.length; j++) {
+                bits[i] += A[j] >> i & 1;
+                bits[i] %= 3;
+            }
+
+            result |= (bits[i] << i);
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/single-number-iii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/single-number-iii.md"
new file mode 100644
index 0000000..3c89621
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/single-number-iii.md"
@@ -0,0 +1,57 @@
+# 落单的数 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/single-number-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出2*n + 2个的数字，除其中两个数字之外其他每个数字均出现两次，找到这两个数字。</p>
+ ### 样例说明
+ 
+```
+样例 1:
+	输入:  [1,2,2,3,4,4,5,3]
+	输出:  [1,5]
+
+样例 2:
+	输入: [1,1,2,3,4,4]
+	输出:  [2,3]
+	
+```
+
+ ### 参考代码
+ 利用异或运算。
+假设两个落单数字是 A、B
+$2*n + 2$ 个数字异或，会得到两个仅出现一次的数字的异或结果：xor = A^B。
+
+其中我们取出xor中任何一位1，这里取最低位的1。
+这个1一定是A和B中对应位上一个是1一个是0。
+所以可以将所有数字分成两类，一类是该位是1的，一类是该位是0的。
+分别异或起来就得到A和B了。两类数一定都是奇数个，多出来的一个分别就是A、B。
+```java
+public class Solution {
+    /**
+     * @param A : An integer array
+     * @return : Two integers
+     */
+    public List<Integer> singleNumberIII(int[] A) {
+        int xor = 0;
+        for (int i = 0; i < A.length; i++) {
+            xor ^= A[i];
+        }
+        
+        int lastBit = xor - (xor & (xor - 1));
+        // int lastBit = xor & (-xor); // 两句一样的作用，只保留xor的最后一个1。
+        int group0 = 0, group1 = 0;
+        for (int i = 0; i < A.length; i++) {
+            if ((lastBit & A[i]) == 0) {
+                group0 ^= A[i];
+            } else {
+                group1 ^= A[i];
+            }
+        }
+        
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        result.add(group0);
+        result.add(group1);
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/single-number.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/single-number.md"
new file mode 100644
index 0000000..dd501a2
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/single-number.md"
@@ -0,0 +1,42 @@
+# 落单的数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/single-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出 `2 * n + 1`个数字，除其中一个数字之外其他每个数字均出现两次，找到这个数字。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[1,1,2,2,3,4,4]
+输出：3
+解释：
+仅3出现一次
+```
+**样例 2:**
+```
+输入：[0,0,1]
+输出：1
+解释：
+仅1出现一次
+```
+
+ ### 参考代码
+ Given an array of integers, every element appears twice except for one. Find that single one.
+考点：
+* 异或位运算
+
+Note:
+Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
+异或运算具有很好的性质，相同数字异或运算后为0，并且具有交换律和结合律，故将所有数字异或运算后即可得到只出现一次的数字。
+```python
+class Solution:
+    """
+   @param A : an integer array
+   @return : a integer
+   """
+    def singleNumber(self, A):
+        # write your code here
+        ans = 0;
+        for x in A:
+            ans = ans ^ x
+        return ans
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/swap-bits.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/swap-bits.md"
new file mode 100644
index 0000000..3153bed
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/swap-bits.md"
@@ -0,0 +1,34 @@
+# 交换奇偶二进制位
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/swap-bits/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个方法，用尽可能少的指令，将一个整数中奇数数位和偶数数位的数字交换 （如，数位 0 和数位 1 交换，数位 2 和数位 3 交换，等等）。
+ ### 样例说明
+ **样例 1：**
+```
+输入：0
+输出：0
+解释：
+0 = 0(2) -> 0(2) = 0
+```
+**样例 2：**
+```
+输入：5
+输出：10
+解释：
+5 = 101(2) -> 1010(2) = 10
+```
+ ### 参考代码
+ ```cpp
+class Solution {
+public:
+    /**
+     * @param x an integer
+     * @return an integer
+     */
+    int swapOddEvenBits(int x) {
+        // Write your code here
+        return ( ((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1) );
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/swap-without-extra-variable-only-c.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/swap-without-extra-variable-only-c.md"
new file mode 100644
index 0000000..d9ec89c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/swap-without-extra-variable-only-c.md"
@@ -0,0 +1,29 @@
+# 交换不借助额外变量(仅C++)
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/swap-without-extra-variable-only-c/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出两个变量，x 和 y ，不使用第三个变量交换这两个变量的值。
+ ### 样例说明
+ **样例 1:**
+```
+输入 : x = 10, y = 5
+输出 : x = 5, y = 10
+```
+ ### 参考代码
+ 通过位运算实现。
+```cpp
+class Solution {
+public:
+    /**
+     * @param x an integer
+     * @param y an integer
+     * @return nothing
+     */
+    void swap(int &x, int &y) {
+        // Write your code here
+        x = x ^ y;
+        y = x ^ y;
+        x = x ^ y;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/update-bits.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/update-bits.md"
new file mode 100644
index 0000000..26aec9c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\344\275\215\350\277\220\347\256\227/update-bits.md"
@@ -0,0 +1,47 @@
+# 更新二进制位
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/update-bits/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出两个32位的整数N和M，以及两个二进制位的位置i和j。写一个方法来使得N中的第i到j位等于M（M会是N中从第i为开始到第j位的子串）</p>
+ ### 样例说明
+ **样例1:**
+```
+输入: N=(10000000000)2 M=(10101)2 i=2 j=6
+输出: N=(10001010100)2
+```
+
+
+**样例 2:**
+```
+输入: N=(10000000000)2 M=(11111)2 i=2 j=6
+输出: N=(10001111100)2
+```
+
+ ### 参考代码
+ ```java
+class Solution {
+    /**
+     *@param n, m: Two integer
+     *@param i, j: Two bit positions
+     *return: An integer
+     */
+    public int updateBits(int n, int m, int i, int j) {
+        // write your code here
+        int max = ~0; /* All 1’s */
+        // 1’s through position j, then 0’s
+        if (j == 31)
+            j = max;
+        else
+            j = (1 << (j + 1)) - 1;
+        int left = max - j;
+        // 1’s after position i
+	    int right = ((1 << i) - 1);
+	    // 1’s, with 0s between i and j
+        int mask = left | right;
+        // Clear i through j, then put m in there
+        return ((n & mask) | (m << i));
+    }
+}
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/alien-dictionary.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/alien-dictionary.md"
new file mode 100644
index 0000000..818d828
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/alien-dictionary.md"
@@ -0,0 +1,307 @@
+# 外星人词典
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/alien-dictionary/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有一种新的使用拉丁字母的外来语言。但是，你不知道字母之间的顺序。你会从词典中收到一个**非空的**单词列表，其中的单词**在这种新语言的规则下按字典顺序排序**。请推导出这种语言的字母顺序。
+ ### 样例说明
+ **样例 1:**
+```
+输入：["wrt","wrf","er","ett","rftt"]
+输出："wertf"
+解释：
+从 "wrt"和"wrf" ,我们可以得到 't'<'f'
+从 "wrt"和"er" ,我们可以得到'w'<'e'
+从 "er"和"ett" ,我们可以得到 get 'r'<'t'
+从 "ett"和"rftt" ,我们可以得到 'e'<'r'
+所以返回 "wertf"
+
+```
+
+
+**样例 2:**
+```
+输入：["z","x"]
+输出："zx"
+解释：
+从 "z" 和 "x"，我们可以得到 'z' < 'x'
+所以返回"zx"
+```
+ ### 参考代码
+ 使用拓扑排序算法。
+这个版本的实现当中，无需假设所有字母为小写字母。
+```
+[[java]]
+class Solution {
+    public String alienOrder(String[] words) {
+        Map<Character, Set<Character>> graph = constructGraph(words);
+        if (graph == null) {
+            return "";
+        }
+        return topologicalSorting(graph);
+    }
+    
+        
+    private Map<Character, Set<Character>> constructGraph(String[] words) {
+        Map<Character, Set<Character>> graph = new HashMap<>();
+        
+        // create nodes
+        for (int i = 0; i < words.length; i++) {
+            for (int j = 0; j < words[i].length(); j++) {
+                char c = words[i].charAt(j);
+                if (!graph.containsKey(c)) {
+                    graph.put(c, new HashSet<Character>());
+                }
+            }
+        }
+        
+        // create edges
+        for (int i = 0; i < words.length - 1; i++) {
+            int index = 0;
+            while (index < words[i].length() && index < words[i + 1].length()) {
+                if (words[i].charAt(index) != words[i + 1].charAt(index)) {
+                    graph.get(words[i].charAt(index)).add(words[i + 1].charAt(index));
+                    break;
+                }
+                index++;
+            }
+            if (index == Math.min(words[i].length(), words[i + 1].length())) {
+                if (words[i].length() > words[i + 1].length()) {
+                    return null;
+                }
+            }
+        }
+
+        return graph;
+    }
+    
+    private Map<Character, Integer> getIndegree(Map<Character, Set<Character>> graph) {
+        Map<Character, Integer> indegree = new HashMap<>();
+        for (Character u : graph.keySet()) {
+            indegree.put(u, 0);
+        }
+        
+        for (Character u : graph.keySet()) {
+            for (Character v : graph.get(u)) {
+                indegree.put(v, indegree.get(v) + 1);
+            }
+        }     
+        
+        return indegree;
+    }
+
+    private String topologicalSorting(Map<Character, Set<Character>> graph) {
+        // as we should return the topo order with lexicographical order
+        // we should use PriorityQueue instead of a FIFO Queue
+        Map<Character, Integer> indegree = getIndegree(graph);
+        Queue<Character> queue = new PriorityQueue<>();
+        
+        for (Character u : indegree.keySet()) {
+            if (indegree.get(u) == 0) {
+                queue.offer(u);
+            }
+        }
+        
+        StringBuilder sb = new StringBuilder();
+        while (!queue.isEmpty()) {
+            Character head = queue.poll();
+            sb.append(head);
+            for (Character neighbor : graph.get(head)) {
+                indegree.put(neighbor, indegree.get(neighbor) - 1);
+                if (indegree.get(neighbor) == 0) {
+                    queue.offer(neighbor);
+                }
+            }
+        }
+        if (sb.length() != indegree.size()) {
+            return "";
+        }
+        return sb.toString();
+    }
+}
+
+[[python]]
+"""
+before looking into this part of code
+you should know how to use bfs algorithm to do topological sorting
+if you don't know, please google it first or join us at 九章算法班.
+"""
+
+from heapq import heappush, heappop, heapify
+
+class Solution:
+    """
+    @param words: a list of words
+    @return: a string which is correct order
+    """
+    def alienOrder(self, words):
+        graph = self.build_graph(words)
+        if not graph:
+            return ""
+        return self.topological_sort(graph)
+        
+    def build_graph(self, words):
+        # key is node, value is neighbors
+        graph = {}
+
+        # initialize graph
+        for word in words:
+            for c in word:
+                if c not in graph:
+                    graph[c] = set() 
+
+        # add edges        
+        n = len(words)
+        for i in range(n - 1):
+            for j in range(min(len(words[i]), len(words[i + 1]))):
+                if words[i][j] != words[i + 1][j]:
+                    graph[words[i][j]].add(words[i + 1][j])
+                    break
+                if j == min(len(words[i]), len(words[i + 1])) - 1:
+                    if len(words[i]) > len(words[i + 1]):
+                        return None
+                
+        return graph
+
+    def topological_sort(self, graph):        
+        # initialize indegree 
+        indegree = {
+            node: 0
+            for node in graph
+        }
+        
+        # calculate indegree
+        for node in graph:
+            for neighbor in graph[node]:
+                indegree[neighbor] = indegree[neighbor] + 1
+        
+        # use heapq instead of regular queue so that we can get the 
+        # smallest lexicographical order
+        queue = [node for node in graph if indegree[node] == 0]
+        heapify(queue)
+        
+        # regular bfs algorithm to do topological sorting
+        topo_order = ""
+        while queue:
+            node = heappop(queue)
+            topo_order += node
+            for neighbor in graph[node]:
+                indegree[neighbor] -= 1
+                if indegree[neighbor] == 0:
+                    heappush(queue, neighbor)
+            
+        # if all nodes popped
+        if len(topo_order) == len(graph):
+            return topo_order
+        
+        return ""
+
+[[c++]]
+class Solution {
+public:
+    /**
+     * @param words: a list of words
+     * @return: a string which is correct order
+     */
+    string alienOrder(vector<string>& words) {
+        map<char, set<char> > graph = constructGraph(words);
+        if (!graph.size()) {
+            return "";
+        }
+
+        return topologicalSorting(graph);
+    }
+
+    map<char, set<char> > constructGraph(vector<string>& words) {
+        map<char, set<char> > graph;
+        // create nodes
+        for (int i = 0; i < words.size(); i++) {
+            for (int j = 0; j < words[i].size(); j++) {
+                char c = words[i][j];
+                if (graph.find(c) == graph.end()) {
+                    set<char> temp;
+                    graph[c] = temp;
+                }
+            }
+        }
+
+        // create edges
+        for (int i = 0; i < words.size() - 1; i++) {
+            int index = 0;
+            while (index < words[i].size() && index < words[i + 1].size()) {
+                if (words[i][index] != words[i + 1][index]) {
+                    graph[words[i][index]].insert(words[i + 1][index]);
+                    break;
+                }
+                index++;
+            }
+            if (index == min(words[i].size(), words[i + 1].size())) {
+                if (words[i].size() > words[i + 1].size()) {
+                    return map<char, set<char> >();
+                }
+            }
+        }
+
+        return graph;
+    }
+
+    map<char, int> getIndegree(map<char, set<char> >& graph) {
+        map<char, int> indegree;
+        map<char, set<char> >::iterator iter;
+        iter = graph.begin();
+        while (iter != graph.end()) {
+            indegree[iter->first] = 0;
+            iter++;
+        }
+        
+        iter = graph.begin();
+        while (iter != graph.end()) {
+            set<char>::iterator _iter = (iter->second).begin();
+            while (_iter != (iter->second).end()) {
+                indegree[*_iter] = indegree[*_iter] + 1;
+                _iter++;
+            }
+            iter++;
+        }
+
+        return indegree;
+    }
+    
+    string topologicalSorting(map<char, set<char> > graph) {
+        map<char, int> indegree = getIndegree(graph);
+
+        priority_queue<char, vector<char>, greater<char> > Q;
+
+        map<char, int>::iterator iter;
+        iter = indegree.begin();
+        while (iter != indegree.end()) {
+            if (indegree[iter->first] == 0) {
+                Q.push(iter->first);
+            }
+            iter++;
+        }
+
+        string s = "";
+        while (Q.size()) {
+            char head = Q.top();
+            Q.pop();
+            s += head;
+            set<char>::iterator iter;
+            iter = graph[head].begin();
+            while (iter != graph[head].end()) {
+                char neighbor = *iter;
+                indegree[neighbor] -= 1;
+                if (indegree[neighbor] == 0) {
+                    Q.push(neighbor);
+                }
+                iter++;
+            }
+        }
+        
+        if (s.size() != indegree.size()) {
+            return "";
+        }
+        return s;
+    }
+
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/amicable-pair.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/amicable-pair.md"
new file mode 100644
index 0000000..99dcbb6
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/amicable-pair.md"
@@ -0,0 +1,60 @@
+# 相亲数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/amicable-pair/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 一对整数是相亲数是说他们各自的所有有效因子（除了自己以外的因子）之和等于另外一个数。比如 (220, 284) 就是一对相亲数。因为：
+
+* 220的所有因子：1+2+4+5+10+11+20+22+44+55+110 = 284
+* 284的所有因子：1+2+4+71+142 = 220 
+
+给出整数 k，求 1~k 之间的所有相亲数对。
+ ### 样例说明
+ **样例 1：**
+```
+输入：300
+输出：[[220,284]]
+```
+**样例 2：**
+```
+输入：220
+输出：[]
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param k an integer
+     * @return all amicable pairs
+     */
+    public int factorSum(int n) {
+        int sum = 1, i;
+        for (i = 2; i * i < n; ++i) {
+            if (n % i == 0) {
+                sum += i + n / i;
+            }
+        }
+        if (i * i == n) {
+            sum += i;
+        }
+        return sum;
+    }
+    
+    public List<List<Integer>> amicablePair(int k) {
+        List<List<Integer>> result = new ArrayList<List<Integer>>();
+        for (int i = 2; i <= k; ++i) {
+            int amicable = factorSum(i);
+            if (amicable <= i || amicable > k) {
+                continue;
+            }
+            if (factorSum(amicable) == i) {
+                ArrayList<Integer> pair = new ArrayList<Integer>();
+                pair.add(i);
+                pair.add(amicable);
+                result.add(pair);
+            }
+        }
+        return result;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/assignment-operator-overloading-c-only.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/assignment-operator-overloading-c-only.md"
new file mode 100644
index 0000000..169ac49
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/assignment-operator-overloading-c-only.md"
@@ -0,0 +1,56 @@
+# 赋值运算符重载
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/assignment-operator-overloading-c-only/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现赋值运算符重载函数，确保：
+
+- 新的数据可准确地被复制
+- 旧的数据可准确地删除/释放
+- 可进行 `A = B = C` 赋值
+
+
+ ### 样例说明
+ 如果进行 `A = B` 赋值，则 A 中的数据被删除，取而代之的是 B 中的数据。
+
+如果进行 `A = B = C` 赋值，则 A 和 B 都复制了 C 中的数据。
+ ### 参考代码
+ ```cpp
+class Solution {
+public:
+    char *m_pData;
+    Solution() {
+        this->m_pData = NULL;
+    }
+    Solution(char *pData) {
+        if (pData) {
+            m_pData = new char[strlen(pData) + 1];
+            strcpy(m_pData, pData);
+        } else {
+            m_pData = NULL;
+        }
+    }
+
+    // Implement an assignment operator
+    Solution operator=(const Solution &object) {
+        if (this == &object) {
+            return *this;
+        }
+        
+        if (object.m_pData) {
+            char *temp = m_pData;
+            try {
+                m_pData = new char[strlen(object.m_pData)+1];
+                strcpy(m_pData, object.m_pData);
+                if (temp)
+                    delete[] temp;
+            } catch (bad_alloc& e) {
+                m_pData = temp;
+            }
+        } else {
+            m_pData = NULL;
+        }
+        return *this;
+    }
+};
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/convex-polygon.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/convex-polygon.md"
new file mode 100644
index 0000000..c70c1bb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/convex-polygon.md"
@@ -0,0 +1,63 @@
+# 凸多边形
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convex-polygon/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一组点的数组，当一个多边形按顺序连接时，发现这个多边形是凸多边形([凸多边形定义](https://en.wikipedia.org/wiki/Convex_polygon))。
+ ### 样例说明
+ ```
+样例 1:
+	输入: points = [[0, 0], [0, 1], [1, 1], [1, 0]]
+	输出:  true
+	
+	解释:
+```
+![](https://lintcode-media.s3.amazonaws.com/problem/E3N5G.png)
+
+```
+样例 2:
+	输入:  points = [[0, 0], [0, 10], [10, 10], [10, 0], [5, 5]]
+	输出:  false
+	
+	解释:
+```	
+![](https://lintcode-media.s3.amazonaws.com/problem/E3f02.png)
+ ### 参考代码
+ 利用向量外积来判断两个向量的夹角是否是非钝角。
+$a 叉乘 b = a和b的模乘夹角的正弦$， 因此结果的正负对应着夹角的大小。
+```java
+public class Solution {
+    public int Cross_Product(List<Integer> p1,List<Integer> p2,List<Integer> p3){
+        int ax = p2.get(0) - p1.get(0);
+        int ay = p2.get(1) - p1.get(1);
+        int bx = p3.get(0) - p2.get(0);
+        int by = p3.get(1) - p2.get(1);
+        int cp= ax * by - ay * bx;
+        if(cp > 0){
+            return 1;
+        } else if(cp < 0){
+            return -1;
+        } else {
+            return 0;
+        }
+    }
+    public boolean isConvex(List<List<Integer>> points) {
+        int cp;
+        int numPoints = points.size();
+        boolean negativeFlag = false;
+        boolean postiveFlag = false;
+        for(int i = 2; i < numPoints + 2; i++){
+            cp = Cross_Product(points.get((i - 2) % numPoints), points.get((i - 1) % numPoints), points.get(i % numPoints));
+            if(cp == 1){
+                postiveFlag = true;
+            } else if(cp == -1){
+                negativeFlag = true;
+            } 
+        }
+        if(postiveFlag && negativeFlag || (!postiveFlag && !negativeFlag)){
+            return false;
+        } else {
+            return true;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/cosine-similarity.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/cosine-similarity.md"
new file mode 100644
index 0000000..ca22c28
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/cosine-similarity.md"
@@ -0,0 +1,60 @@
+# 余弦相似度
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/cosine-similarity/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 余弦相似性是内积空间的两个矢量之间的相似性的度量，其测量它们之间的角度的余弦。 0° 的余弦为 1，对于任何其他角度，余弦小于 1。
+
+Wiki 链接: [Cosine Similarity](https://en.wikipedia.org/wiki/Cosine_similarity "")
+
+这里给出公式:
+
+![cosine-similarity](https://lintcode-media.s3.amazonaws.com/problem/cosine-similarity.png "")
+
+给你两个相同大小的向量 *A* *B*，求出他们的余弦相似度。
+
+返回 `2.0000` 如果余弦相似不合法 (比如 A = [0] B = [0])。
+ ### 样例说明
+ **样例 1：**
+```
+输入：A = [1,4,0], B = [1,2,3]
+输出：0.5834
+```
+**样例 2：**
+```
+输入：A = [1], B = [2]
+输出：1.0000
+```
+ ### 参考代码
+ ```cpp
+class Solution {
+public:
+    /**
+     * @param A: An integer array.
+     * @param B: An integer array.
+     * @return: Cosine similarity.
+     */
+    double cosineSimilarity(vector<int> A, vector<int> B) {
+        int factor = 0;
+        for (int i = 0; i < A.size(); i++) {
+            factor += A[i] * B[i];
+        }
+
+        int sumA = 0;
+        for (int i = 0; i < A.size(); i++) {
+            sumA += A[i] * A[i];
+        }
+        int sumB = 0;
+        for (int i = 0; i < B.size(); i++) {
+            sumB += B[i] * B[i];
+        }
+
+        if (sumA == 0 || sumB == 0) {
+            return 2;
+        }
+
+        return factor / sqrt(sumA) / sqrt(sumB);
+    }
+};
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/delete-and-earn.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/delete-and-earn.md"
new file mode 100644
index 0000000..34035d1
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/delete-and-earn.md"
@@ -0,0 +1,53 @@
+# 删除并赚取
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/delete-and-earn/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，你可以在这个数组上进行操作。
+
+在每次操作中，你可以选择任意数num[i]并且删除它从而得到num[i]的分数。在此之后，你必须删除掉任何和num[i]-1或者num[i]+1相等的元素。
+
+你将从0分开始。返回你通过这些操作可以获得的最大的分数。
+ ### 样例说明
+ ```
+样例 1:
+	输入:  nums = [3, 4, 2]
+	输出:  6
+	
+	解释:
+	删除4，获得4分。同时删除3
+	然后删除2，获得2分。
+
+	
+样例 2:
+	输入: nums = [2, 2, 3, 3, 3, 4]
+	输出:  9
+	
+	解释:
+	删除3，获得3分。然后删除2和4
+	然后再删除3，获得3分。
+	再删除3，获得3分。
+	
+```
+ ### 参考代码
+ DP[i]表示删除的数字不超过i时所能获得的最大的分数。
+
+考虑当前数字是主动删的还是被动删的。
+由于i-1和i+1是相互的，我们只考虑一边，避免重复。
+```java
+class Solution {
+    public int deleteAndEarn(int[] nums) {
+        int[] counters = new int[10001];
+        for (int i = 0; i < nums.length; i++) {
+            counters[nums[i]]++;
+        }
+        
+        int[] dp = new int[10001];
+        dp[1] = counters[1];
+        for (int i = 2; i <= 10000; i++) {
+            dp[i] = Math.max(dp[i - 1], dp[i - 2] + i * counters[i]);
+        }
+        
+        return dp[10000];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/digit-counts.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/digit-counts.md"
new file mode 100644
index 0000000..0855590
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/digit-counts.md"
@@ -0,0 +1,57 @@
+# 统计数字
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/digit-counts/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>计算数字 k 在 0 到 n 中的出现的次数，k 可能是 0~9 的一个值。</p>
+ ### 样例说明
+ **样例 1：**
+```
+输入：
+k = 1, n = 1
+输出：
+1
+解释：
+在 [0, 1] 中，我们发现 1 出现了 1 次 (1)。
+```
+**样例 2：**
+```
+输入：
+k = 1, n = 12
+输出：
+5
+解释：
+在 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] 中，我们发现 1 出现了 5 次 (1, 10, 11, 12)(注意11中有两个1)。
+```
+ ### 参考代码
+ ```java
+class Solution {
+    /*
+     * param k : As description.
+     * param n : As description.
+     * return: An integer denote the count of digit k in 1..n
+     */
+    public int digitCounts(int k, int n) {
+        // write your code here
+        int cnt = 0;
+        for (int i = k; i <= n; i++) {
+            cnt += singleCount(i, k);
+        }
+        return cnt;
+    }
+    
+    public int singleCount(int i, int k) {
+        if (i == 0 && k == 0)
+            return 1;
+        int cnt = 0;
+        while (i > 0) {
+            if (i % 10 == k) {
+                cnt++;
+            }
+            i = i / 10;
+        }
+        return cnt;
+    }
+};
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/fibonacci.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/fibonacci.md"
new file mode 100644
index 0000000..acb34ed
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/fibonacci.md"
@@ -0,0 +1,74 @@
+# 斐波纳契数列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/fibonacci/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 查找斐波纳契数列中第 N 个数。
+
+所谓的斐波纳契数列是指：
+
+- 前2个数是 0 和 1 。
+- 第 *i* 个数是第 *i*-1 个数和第*i*-2 个数的和。
+
+斐波纳契数列的前10个数字是：
+
+`0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ...`
+ ### 样例说明
+ ```
+样例  1:
+	输入:  1
+	输出: 0
+	
+	样例解释: 
+	返回斐波那契的第一个数字，是0.
+
+样例 2:
+	输入:  2
+	输出: 1
+	
+	样例解释: 
+	返回斐波那契的第二个数字是1.
+
+```
+ ### 参考代码
+ 纯用递归会超时，如果用带有记忆化的递归就可以，使用循环和记忆化递归的时间复杂度一样，都是$O(n)$。
+
+不超出Integer的斐波那契数很少，仅有50个左右。
+但是使用纯的递归，复杂度会是$O(2^n)$。因此会超时。
+```java
+class Solution {
+    /**
+     * @param n: an integer
+     * @return an integer f(n)
+     */
+    public int fibonacci(int n) {
+        int a = 0;
+        int b = 1;
+        for (int i = 0; i < n - 1; i++) {
+            int c = a + b;
+            a = b;
+            b = c;
+        }
+        return a;
+    }
+}
+
+//递归版本，会超时
+public class Solution {
+    /*
+     * @param : an integer
+     * @return: an ineger f(n)
+     */
+    public int fibonacci(int n) {
+        // write your code here
+        if (n == 1) {
+            return 0;
+        }
+        
+        if (n == 2) {
+            return 1;
+        }
+        
+        return fibonacci(n - 1) + fibonacci(n - 2);
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/find-the-celebrity.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/find-the-celebrity.md"
new file mode 100644
index 0000000..9619060
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/find-the-celebrity.md"
@@ -0,0 +1,65 @@
+# 识别名人
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-the-celebrity/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假设你和 `n` 个人在一个聚会中(标记为 `0` 到 `n - 1`)，其中可能存在一个名人。名人的定义是所有其他 `n - 1` 人都认识他/她，但他/她不知道任何一个。
+现在你想要找出这个名人是谁或者验证这个名人不存在。你唯一可以做的事情就是提出如下问题：“你好，A，你认识B吗？” 来获取A是否认识B。您需要通过询问尽可能少的问题(以渐近的意义)来找出名人是谁(或验证其不存在)。
+你得到一个辅助函数 `bool know(a，b)`，它会告诉你A是否知道B.实现一个函数 `int findCelebrity(n)`，你的函数应该使 `knows` 的调用次数最少。
+ ### 样例说明
+ **样例1**
+```
+输入：
+2 // 接下来n*(n-1)行
+0 knows 1
+1 does not know 0
+输出： 1
+解释：
+所有人都认识1，而且1不认识其他人。
+```
+**样例2**
+```
+输入：
+3 // 接下来n*(n-1)行
+0 does not know 1
+0 does not know 2
+1 knows 0
+1 does not know 2
+2 knows 0
+2 knows 1
+输出：0
+解释：
+所有人都认识0，而且0不认识其他人。
+0不认识1，同时1认识0。
+2认识所有人，但是1不认识2。
+```
+ ### 参考代码
+ 首先loop一遍找到一个人i使得对于所有j(j>=i)都不认识i。
+然后再loop一遍判断是否有人不认识i或者i认识某个人。
+```java
+// version: 高频题班
+public class Solution extends Relation {
+    /**
+     * @param n a party with n people
+     * @return the celebrity's label or -1
+     */
+    public int findCelebrity(int n) {
+        // Write your code here
+        int ans = 0;
+        for (int i = 1; i < n; i++) {
+            if (knows(ans, i)) {
+                ans = i;
+            }
+        }
+
+        for (int i = 0; i < n; i++) {
+            if (ans != i && knows(ans, i)) {
+                return -1;
+            }
+            if (ans != i && !knows(i, ans)) {
+                return -1;
+            }
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/find-the-missing-number.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/find-the-missing-number.md"
new file mode 100644
index 0000000..2f7d6b0
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/find-the-missing-number.md"
@@ -0,0 +1,60 @@
+# 寻找缺失的数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-the-missing-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个包含 0 .. *N* 中 *N* 个数的序列，找出0 .. *N* 中没有出现在序列中的那个数。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    /**    
+     * @param nums: an array of integers
+     * @return: an integer
+     */
+    public int findMissing(int[] nums) {
+        // write your code here
+        int n = nums.length, i = 0;
+        while (i<n) {
+            while (nums[i]!=i && nums[i]<n) {
+                int t = nums[i];
+                nums[i] = nums[t];
+                nums[t] = t;
+            }
+            ++i;
+        }
+        for (i=0; i<n; ++i)
+            if (nums[i]!=i) return i;
+        return n;
+    }
+}
+
+//Math
+public class Solution {
+    /**    
+     * @param nums: an array of integers
+     * @return: an integer
+     */
+    public int findMissing(int[] nums) {
+        long N = nums.length;
+        long sum = N * (N + 1) / 2;
+        for(int i : nums){
+            sum -= i;
+        }
+        return (int)sum;
+    }
+}
+
+//Xor
+public int findMissing(int[] nums) {
+    // write your code here
+    int ans = 0;
+    for (int i = 0; i <= nums.length; i++) {
+        ans ^= i;
+    }
+    for (int i = 0; i < nums.length; i++) {
+        ans ^= nums[i];
+    }
+    return ans;
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/fizz-buzz.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/fizz-buzz.md"
new file mode 100644
index 0000000..fbc233f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/fizz-buzz.md"
@@ -0,0 +1,67 @@
+# Fizz Buzz 问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/fizz-buzz/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个整数*n*. 从 *1* 到 *n* 按照下面的规则打印每个数：
+
+- 如果这个数被3整除，打印`fizz`.
+- 如果这个数被5整除，打印`buzz`.
+- 如果这个数能同时被`3`和`5`整除，打印`fizz buzz`.
+- 如果这个数既不能被 `3` 整除也不能被 `5` 整除，打印数字`本身。`
+ ### 样例说明
+ 比如 *n* = `15`, 返回一个字符串数组：
+
+```
+[
+  "1", "2", "fizz",
+  "4", "buzz", "fizz",
+  "7", "8", "fizz",
+  "buzz", "11", "fizz",
+  "13", "14", "fizz buzz"
+]
+```
+ ### 参考代码
+ 有的面试官会要求你能不能只用一个 if 语句来完成这个题，这是一个参考。突破点在于：那我可以用 while 呀~
+```java
+class Solution {
+    /**
+     * param n: As description.
+     * return: A list of strings.
+     */
+    public ArrayList<String> fizzBuzz(int n) {
+        ArrayList<String> results = new ArrayList<String>();
+        int i = 1;
+        //p3表示3的多少倍，p5表示5的多少倍
+        int p3 = 1, p5 = 1;
+        
+        while (i <= n) {
+          while (i < p3 * 3 && i < p5 * 5) {
+            results.add(i + "");
+            i++;
+          }
+        
+          if (i <= n && p3 * 3 == p5 * 5) {
+            results.add("fizz buzz");
+            p3++;
+            p5++;
+            i++;
+            continue;
+          }
+        
+          while (i <= n && p3 * 3 <= i) {
+            results.add("fizz");
+            p3++;
+            i++;
+          }
+        
+          while (i <= n && p5 * 5 <= i) {
+            results.add("buzz");
+            p5++;
+            i++;
+          }
+        }
+        
+        return results;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/friendship-service.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/friendship-service.md"
new file mode 100644
index 0000000..ae17369
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/friendship-service.md"
@@ -0,0 +1,110 @@
+# 友谊服务
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/friendship-service/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 支持 follow & unfollow, getFollowers, getFollowings方法
+注意：getfollow（）的结果是排序后的。
+ ### 样例说明
+ 例1:
+```
+输入:
+follow(1, 3)
+getFollowers(1) 
+getFollowings(3) 
+follow(2, 3)
+getFollowings(3) 
+unfollow(1, 3)
+getFollowings(3) 
+输出:
+[3]
+[1]
+[1,2]
+[2]
+解释:
+follow(1, 3)
+getFollowers(1) // return [3]
+getFollowings(3) // return [1]
+follow(2, 3)
+getFollowings(3) // return [1,2]
+unfollow(1, 3)
+getFollowings(3) // return [2]
+```
+例2:
+```
+输入:
+follow(1, 2)
+unfollow(1, 2)
+getFollowings(1)
+unfollow(1, 2)
+getFollowings(1)
+unfollow(1, 2)
+follow(1, 2)
+getFollowings(1)
+输出:
+[]
+[]
+[]
+```
+
+ ### 参考代码
+ 利用hashmap以及treeset实现即可
+```java
+public class FriendshipService { 
+
+    private Map<Integer, Set<Integer>> followers, followings;
+
+    public FriendshipService() {
+        // initialize your data structure here.
+        this.followers = new HashMap<Integer, Set<Integer>>();
+        this.followings = new HashMap<Integer, Set<Integer>>();
+    }
+
+    // @param user_id an integer
+    // return all followers and sort by user_id
+    public List<Integer> getFollowers(int user_id) {
+        // Write your code here
+        if (!followers.containsKey(user_id))
+            return new ArrayList<Integer>();
+
+        return new ArrayList<Integer>(followers.get(user_id));
+    }
+        
+    // @param user_id an integer
+    // return all followings and sort by user_id
+    public List<Integer>  getFollowings(int user_id) {
+        // Write your code here
+        if (!followings.containsKey(user_id))
+            return new ArrayList<Integer>();
+
+        return new ArrayList<Integer>(followings.get(user_id));
+    }
+
+    // @param from_user_id an integer
+    // @param to_user_id an integer
+    // from user_id follows to_user_id
+    public void follow(int to_user_id, int from_user_id) {
+        // Write your code here
+        if (!followers.containsKey(to_user_id))
+            followers.put(to_user_id, new TreeSet<Integer>());
+
+        followers.get(to_user_id).add(from_user_id);
+
+        if (!followings.containsKey(from_user_id))
+            followings.put(from_user_id, new TreeSet<Integer>());
+
+        followings.get(from_user_id).add(to_user_id);
+    }
+
+    // @param from_user_id an integer
+    // @param to_user_id an integer
+    // from user_id unfollows to_user_id
+    public void unfollow(int to_user_id, int from_user_id) {
+        // Write your code here
+        if (followers.containsKey(to_user_id))
+            followers.get(to_user_id).remove(from_user_id);
+
+        if (followings.containsKey(from_user_id))
+            followings.get(from_user_id).remove(to_user_id);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/generate-parentheses.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/generate-parentheses.md"
new file mode 100644
index 0000000..5164bf9
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/generate-parentheses.md"
@@ -0,0 +1,89 @@
+# 生成括号
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/generate-parentheses/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定 n，表示有 n 对括号, 请写一个函数以将其生成所有的括号组合，并返回组合结果。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 3
+输出: ["((()))", "(()())", "(())()", "()(())", "()()()"] 
+```
+
+**样例 2:**
+
+```
+输入: 2
+输出: ["()()", "(())"]
+```
+ ### 参考代码
+ 回溯. 逐个字符添加, 生成每一种组合. 
+
+一个状态需要记录的有: 当前字符串本身, 左括号数量, 右括号数量.
+
+递归过程中解决:
+
+- 如果当前右括号数量等于括号对数 n, 那么当前字符串即是一种组合, 放入解中.
+- 如果当前左括号数量等于括号对数 n, 那么当前字符串后续填充满右括号, 即是一种组合.
+- 如果当前左括号数量未超过 n:
+  - 如果左括号多于右括号, 那么此时可以添加一个左括号或右括号, 递归进入下一层
+  - 如果左括号不多于右括号, 那么此时只能添加一个左括号, 递归进入下一层
+```java
+public class Solution {
+    public ArrayList<String> generateParenthesis(int n) {
+        ArrayList<String> result = new ArrayList<String>();
+        if (n <= 0) {
+            return result;
+        }
+        helper(result, "", n, n);
+        return result;
+    }
+    
+	public void helper(ArrayList<String> result,
+	                   String paren, // current paren
+	                   int left,     // how many left paren we need to add
+	                   int right) {  // how many right paren we need to add
+		if (left == 0 && right == 0) {
+			result.add(paren);
+			return;
+		}
+
+        if (left > 0) {
+		    helper(result, paren + "(", left - 1, right);
+        }
+        
+        if (right > 0 && left < right) {
+		    helper(result, paren + ")", left, right - 1);
+        }
+	}
+}
+
+///////////////////// 九章硅谷求职算法集训营版本
+
+class Solution {
+    List<String> res = new ArrayList<>();
+    int n;
+    
+    void gen(int nleft, int nright, String cur) {
+        if (nleft == n && nright == n) {
+            res.add(cur);
+            return;
+        }
+        
+        if (nleft < n) {
+            gen(nleft + 1, nright, cur + "(");
+        }
+        
+        if (nright < nleft) {
+            gen(nleft, nright + 1, cur + ")");
+        }
+    }
+    
+    public List<String> generateParenthesis(int nn) {
+        n = nn;
+        gen(0, 0, "");
+        return res;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/gfs-client.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/gfs-client.md"
new file mode 100644
index 0000000..232ca43
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/gfs-client.md"
@@ -0,0 +1,89 @@
+# GFS客户端
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/gfs-client/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 为GFS(Google文件系统)实现一个简单的客户端，提供一下功能：
+	1.`read(文件名)`，通过文件名从GFS中读取文件。
+	2.`write(文件名，内容)`，通过文件名和内容写入GFS中。
+现在有两种已经在基础类中实现的方法：
+	1.`readChunk(文件名，块索引)`，从GFS中读取一个块。
+	2.`writeChunk(文件名，块索引，块数据)`，向GFS中写入一个块。
+为了简化这个问题，我们可以假设块大小为 *chunkSize* 位的(在真实的文件系统中，是64M)，GFS客户端的任务是将一个文件分为若干块(如果需要的话)并且保存在远端的GFS服务器上，*chunkSize*会在构造函数中给出，你需要的是实现`read`和`write`这两个private方法。
+ ### 样例说明
+ ```
+GFSClient(5)
+read("a.txt")
+>> null
+write("a.txt", "World")
+>> You don't need to return anything, but you need to call writeChunk("a.txt", 0, "World") to write a 5 bytes chunk to GFS.
+read("a.txt")
+>> "World"
+write("b.txt", "111112222233")
+>> You need to save "11111" at chunk 0, "22222" at chunk 1, "33" at chunk 2.
+write("b.txt", "aaaaabbbbb")
+read("b.txt")
+>> "aaaaabbbbb"
+```
+ ### 参考代码
+ ```java
+/* Definition of BaseGFSClient
+ * class BaseGFSClient {
+ *     private Map<String, String> chunk_list;
+ *     public BaseGFSClient() {}
+ *     public String readChunk(String filename, int chunkIndex) {
+ *         // Read a chunk from GFS
+ *     }
+ *     public void writeChunk(String filename, int chunkIndex,
+ *                            String content) {
+ *         // Write a chunk to GFS
+ *     }
+ * }
+ */
+public class GFSClient extends BaseGFSClient {
+
+    public int chunkSize;
+    public Map<String, Integer> chunkNum;
+
+    public GFSClient(int chunkSize) {
+        // initialize your data structure here
+        this.chunkSize = chunkSize;
+        this.chunkNum = new HashMap<String, Integer>();
+    }
+    
+    // @param filename a file name
+    // @return conetent of the file given from GFS
+    public String read(String filename) {
+        // Write your code here
+        if (!chunkNum.containsKey(filename))
+            return null;
+
+        StringBuffer content = new StringBuffer();
+
+        for (int i = 0; i < chunkNum.get(filename); ++i) {
+            String sub_content = readChunk(filename, i);
+            if (sub_content != null)
+                content.append(sub_content);
+        }
+        return content.toString();
+    }
+
+    // @param filename a file name
+    // @param content a string
+    // @return void
+    public void write(String filename, String content) {
+        // Write your code here
+        int length = content.length();
+
+        int num = (length - 1) / chunkSize + 1;
+        chunkNum.put(filename, num);
+
+        for (int i = 0; i < num; ++i) {
+            int start = i * chunkSize;
+            int end = i == num -1 ? length : (i + 1) * chunkSize; 
+            String sub_content = content.substring(start, end);
+            writeChunk(filename, i, sub_content);
+        }
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/guess-number-game.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/guess-number-game.md"
new file mode 100644
index 0000000..c106d75
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/guess-number-game.md"
@@ -0,0 +1,47 @@
+# 猜数游戏
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/guess-number-game/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 我们正在玩猜数游戏。 游戏如下：
+我从 **1** 到 **n** 选择一个数字。 你需要猜我选择了哪个号码。
+每次你猜错了，我会告诉你这个数字与你猜测的数字相比是大还是小。
+你调用一个预定义的接口 `guess(int num)`，它会返回 3 个可能的结果(-1，1或0):
+-1代表这个数字小于你猜测的数
+1代表这个数字大于你猜测的数
+0代表这个数字等于你猜测的数
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+// version: 高频题班
+
+/* The guess API is defined in the parent class GuessGame.
+   @param num, your guess
+   @return -1 if my number is lower, 1 if my number is higher, otherwise return 0
+      int guess(int num); */
+
+public class Solution extends GuessGame {
+    /**
+     * @param n an integer
+     * @return the number you guess
+     */
+    public int guessNumber(int n) {
+        // Write your code here
+        int l = 1, r = n;
+        while (l <= r) {
+            int mid = l + (r - l) / 2;
+            int res = guess(mid);
+            if (res == 0) {
+                return mid;
+            }
+            
+            if (res == -1) {
+                r = mid - 1;
+            } else {
+                l = mid + 1;
+            }
+        }
+        return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/insert-interval.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/insert-interval.md"
new file mode 100644
index 0000000..c5dcfe1
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/insert-interval.md"
@@ -0,0 +1,83 @@
+# 插入区间
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/insert-interval/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个<font color="#e76363"><b>无重叠的</b></font><span style="line-height: 1.42857143;">按照区间起始端点排序的区间列表。</span></p><p>在列表中插入一个新的区间，你要确保列表中的区间仍然有序且<font color="#e76363"><b>不重叠</b></font>（如果有必要的话，可以合并区间）。</p>
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入:
+(2, 5) into [(1,2), (5,9)]
+输出:
+[(1,9)]
+```
+**样例 2：**
+```
+输入:
+(3, 4) into [(1,2), (5,9)]
+输出:
+[(1,2), (3,4), (5,9)]
+```
+
+ ### 参考代码
+ 定位到区间集与待插入的区间开始重合的部分，然后开始求交集。
+交集一直延伸到相交区间的最末端。
+```java
+public class Solution {
+    public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
+        if (newInterval == null || intervals == null) {
+            return intervals;
+        }
+
+        List<Interval> results = new ArrayList<Interval>();
+        int insertPos = 0;
+
+        for (Interval interval : intervals) {
+            if (interval.end < newInterval.start) {
+                results.add(interval);
+                insertPos++;
+            } else if (interval.start > newInterval.end) {
+                results.add(interval);
+            } else {
+                newInterval.start = Math.min(interval.start, newInterval.start);
+                newInterval.end = Math.max(interval.end, newInterval.end);
+            }
+        }
+
+        results.add(insertPos, newInterval);
+
+        return results;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /*
+     * @param intervals: Sorted interval list.
+     * @param newInterval: new interval.
+     * @return: A new interval list.
+     */
+    public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
+        // write your code here
+        List<Interval> ans = new ArrayList<>();
+
+        int idx = 0;
+        while (idx < intervals.size() && intervals.get(idx).start < newInterval.start) {
+            idx++;
+        }
+        intervals.add(idx, newInterval);
+
+        Interval last = null;
+        for (Interval item : intervals) {
+            if (last == null || last.end < item.start) {
+                ans.add(item);
+                last = item;
+            } else {
+                last.end = Math.max(last.end, item.end); // Modify the element already in list
+            }
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/kth-prime-number.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/kth-prime-number.md"
new file mode 100644
index 0000000..f0085bb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/kth-prime-number.md"
@@ -0,0 +1,84 @@
+# 第K个质数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-prime-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出质数`n`，输出它是第几个质数。
+ ### 样例说明
+ **样例1**
+
+```
+输入: n = 3
+输出: 2
+解释:
+[2,3,5]，3是第2个质数。
+```
+
+
+
+**样例2**
+
+```
+输入: n = 11
+输出: 5
+解释:
+[2,3,5,7,11]，11是第五个质数。
+```
+ ### 参考代码
+ ```cpp
+class Solution {
+
+public:
+
+    /*
+
+     * @param k: The number k.
+
+     * @return: The kth prime number as description.
+
+     */
+
+    long long kthPrimeNumber(int k) {
+
+        priority_queue<long long> heap;
+
+        unordered_map<long long, bool> hash;
+
+        
+
+        long long primes[3];
+
+        primes[0] = 3; primes[1] = 5; primes[2] = 7;
+
+        heap.push(-3); heap.push(-5); heap.push(-7);
+
+        
+
+        for (int i = 0; i < k - 1; i++) {
+
+            long long top = -heap.top();
+
+            heap.pop();
+
+            
+
+            for (int j = 0; j < 3; j++) {
+
+                if (hash.find(top * primes[j]) == hash.end()) {
+
+                    hash[top * primes[j]] = true;
+
+                    heap.push(-top * primes[j]);
+
+                }
+
+            }
+
+        }
+
+        return -heap.top();
+
+    }
+
+};
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/lfu-cache.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/lfu-cache.md"
new file mode 100644
index 0000000..84a01db
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/lfu-cache.md"
@@ -0,0 +1,207 @@
+# LFU缓存
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/lfu-cache/?utm_source=sc-github-wzz)
+ ## 题目描述
+ LFU是一个著名的缓存算法
+对于容量为k的缓存，如果缓存已满，并且需要逐出其中的密钥，则最少使用的密钥将被踢出。 
+实现LFU中的`set` 和 `get`
+ ### 样例说明
+ ```plain
+输入:
+LFUCache(3)
+set(2,2)
+set(1,1)
+get(2)
+get(1)
+get(2)
+set(3,3)
+set(4,4)
+get(3)
+get(2)
+get(1)
+get(4)
+
+输出:
+2
+1
+2
+-1
+2
+1
+4
+```
+
+
+ ### 参考代码
+ 了解LFU的基本算法，按照要求进行模拟即可，记录下每一个的出现频率，如果满了，选出频率最低的踢出
+```java
+public class LFUCache {
+
+    private final Map<Integer, CacheNode> cache;
+    private final LinkedHashSet[] frequencyList;
+    private int lowestFrequency;
+    private int maxFrequency;
+    private final int maxCacheSize;
+
+    // @param capacity, an integer
+    public LFUCache(int capacity) {
+        // Write your code here
+        this.cache = new HashMap<Integer, CacheNode>(capacity);
+        this.frequencyList = new LinkedHashSet[capacity * 2];
+        this.lowestFrequency = 0;
+        this.maxFrequency = capacity * 2 - 1;
+        this.maxCacheSize = capacity;
+        initFrequencyList();
+    }
+
+    // @param key, an integer
+    // @param value, an integer
+    // @return nothing
+    public void set(int key, int value) {
+        // Write your code here
+        CacheNode currentNode = cache.get(key);
+        if (currentNode == null) {
+            if (cache.size() == maxCacheSize) {
+                doEviction();
+            }
+            LinkedHashSet<CacheNode> nodes = frequencyList[0];
+            currentNode = new CacheNode(key, value, 0);
+            nodes.add(currentNode);
+            cache.put(key, currentNode);
+            lowestFrequency = 0;
+        } else {
+            currentNode.v = value;
+        }
+        addFrequency(currentNode);
+    }
+
+    public int get(int key) {
+        // Write your code here
+        CacheNode currentNode = cache.get(key);
+        if (currentNode != null) {
+            addFrequency(currentNode);
+            return currentNode.v;
+        } else {
+            return -1;
+        }
+    }
+
+    public void addFrequency(CacheNode currentNode) {
+        int currentFrequency = currentNode.frequency;
+        if (currentFrequency < maxFrequency) {
+            int nextFrequency = currentFrequency + 1;
+            LinkedHashSet<CacheNode> currentNodes = frequencyList[currentFrequency];
+            LinkedHashSet<CacheNode> newNodes = frequencyList[nextFrequency];
+            moveToNextFrequency(currentNode, nextFrequency, currentNodes, newNodes);
+            cache.put(currentNode.k, currentNode);
+            if (lowestFrequency == currentFrequency && currentNodes.isEmpty()) {
+                lowestFrequency = nextFrequency;
+            }
+        } else {
+            // Hybrid with LRU: put most recently accessed ahead of others:
+            LinkedHashSet<CacheNode> nodes = frequencyList[currentFrequency];
+            nodes.remove(currentNode);
+            nodes.add(currentNode);
+        }
+    }
+
+    public int remove(int key) {
+        CacheNode currentNode = cache.remove(key);
+        if (currentNode != null) {
+            LinkedHashSet<CacheNode> nodes = frequencyList[currentNode.frequency];
+            nodes.remove(currentNode);
+            if (lowestFrequency == currentNode.frequency) {
+                findNextLowestFrequency();
+            }
+            return currentNode.v;
+        } else {
+            return -1;
+        }
+    }
+
+    public int frequencyOf(int key) {
+        CacheNode node = cache.get(key);
+        if (node != null) {
+            return node.frequency + 1;
+        } else {
+            return 0;
+        }
+    }
+
+    public void clear() {
+        for (int i = 0; i <= maxFrequency; i++) {
+            frequencyList[i].clear();
+        }
+        cache.clear();
+        lowestFrequency = 0;
+    }
+
+    public int size() {
+        return cache.size();
+    }
+
+    public boolean isEmpty() {
+        return this.cache.isEmpty();
+    }
+
+    public boolean containsKey(int key) {
+        return this.cache.containsKey(key);
+    }
+
+    private void initFrequencyList() {
+        for (int i = 0; i <= maxFrequency; i++) {
+            frequencyList[i] = new LinkedHashSet<CacheNode>();
+        }
+    }
+
+    private void doEviction() {
+        int currentlyDeleted = 0;
+        double target = 1; // just one
+        while (currentlyDeleted < target) {
+            LinkedHashSet<CacheNode> nodes = frequencyList[lowestFrequency];
+            if (nodes.isEmpty()) {
+                break;
+            } else {
+                Iterator<CacheNode> it = nodes.iterator();
+                while (it.hasNext() && currentlyDeleted++ < target) {
+                    CacheNode node = it.next();
+                    it.remove();
+                    cache.remove(node.k);
+                }
+                if (!it.hasNext()) {
+                    findNextLowestFrequency();
+                }
+            }
+        }
+    }
+
+    private void moveToNextFrequency(CacheNode currentNode, int nextFrequency,
+                                     LinkedHashSet<CacheNode> currentNodes,
+                                     LinkedHashSet<CacheNode> newNodes) {
+        currentNodes.remove(currentNode);
+        newNodes.add(currentNode);
+        currentNode.frequency = nextFrequency;
+    }
+
+    private void findNextLowestFrequency() {
+        while (lowestFrequency <= maxFrequency && frequencyList[lowestFrequency].isEmpty()) {
+            lowestFrequency++;
+        }
+        if (lowestFrequency > maxFrequency) {
+            lowestFrequency = 0;
+        }
+    }
+
+    private class CacheNode {
+        public final int k;
+        public int v;
+        public int frequency;
+
+        public CacheNode(int k, int v, int frequency) {
+            this.k = k;
+            this.v = v;
+            this.frequency = frequency;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/matrix-zigzag-traversal.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/matrix-zigzag-traversal.md"
new file mode 100644
index 0000000..fca8536
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/matrix-zigzag-traversal.md"
@@ -0,0 +1,63 @@
+# 矩阵的之字型遍历
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/matrix-zigzag-traversal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个包含 *m* x *n* 个元素的矩阵 (*m* 行, *n* 列), 求该矩阵的之字型遍历。
+ ### 样例说明
+ ```
+样例 1:
+	输入: [[1]]
+	输出:  [1]
+
+样例 2:
+	输入:   
+	[
+    [1, 2,  3,  4],
+    [5, 6,  7,  8],
+    [9,10, 11, 12]
+  ]
+
+	输出:  [1, 2, 5, 9, 6, 3, 4, 7, 10, 11, 8, 12]
+
+
+```
+
+ ### 参考代码
+ 使用下标偏移变量来实现遍历。
+遇到边界时改变偏移量。
+直接模拟即可。
+```java
+public class Solution {
+    /**
+     * @param matrix: a matrix of integers
+     * @return: an array of integers
+     */ 
+    public int[] printZMatrix(int[][] matrix) {
+        // write your code here
+        int x, y, dx, dy, count, m, n;
+        x = y = 0;
+        count = 1;
+        dx = -1; dy = 1;
+        m = matrix.length;
+        n = matrix[0].length;
+        int[] z = new int[m*n];
+        z[0] = matrix[0][0];
+        while (count<m*n) {
+            if (x+dx>=0 && y+dy>=0 && x+dx<m && y+dy<n) {
+                x += dx; y += dy;
+            }
+            else
+                if (dx==-1 && dy ==1) {
+                    if (y+1<n) ++y; else ++x;
+                    dx = 1; dy = -1;
+                }
+                else {
+                    if (x+1<m) ++x; else ++y;
+                    dx = -1; dy = 1;
+                }
+            z[count] = matrix[x][y]; ++count;
+        }
+        return z;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/max-of-3-numbers.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/max-of-3-numbers.md"
new file mode 100644
index 0000000..3fc24b8
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/max-of-3-numbers.md"
@@ -0,0 +1,43 @@
+# 三数之中的最大值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/max-of-3-numbers/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给三个整数，求他们中的最大值。
+ ### 样例说明
+ ```
+样例  1:
+	输入:  num1 = 1, num2 = 9, num3 = 0
+	输出: 9
+	
+	样例解释: 
+	返回三个数中最大的数。
+
+样例 2:
+	输入:  num1 = 1, num2 = 2, num3 = 3
+	输出: 3
+	
+	样例解释: 
+	返回三个中最大的数字。
+
+```
+ ### 参考代码
+ if选择语句的基本操作
+```java
+public class Solution {
+    /**
+     * @param a an integer
+     * @param b an integer
+     * @param c an integer
+     * @return an integer
+     */
+    public int maxOfThreeNumbers(int a, int b, int c) {
+        if (a >= b && a >= c) {
+            return a;
+        } else if (b >= a && b >= c) {
+            return b;
+        } else {
+            return c;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/narcissistic-number.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/narcissistic-number.md"
new file mode 100644
index 0000000..c9d3a8c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/narcissistic-number.md"
@@ -0,0 +1,68 @@
+# 水仙花数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/narcissistic-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 水仙花数的定义是，这个数等于他每一位数上的幂次之和 [见维基百科的定义](https://en.wikipedia.org/wiki/Narcissistic_number "See wiki")
+
+比如一个3位的十进制整数`153`就是一个水仙花数。因为 153 = 1<sup>3</sup> + 5<sup>3</sup> + 3<sup>3</sup>。
+
+而一个4位的十进制数`1634`也是一个水仙花数，因为 1634 = 1<sup>4</sup> + 6<sup>4</sup> + 3<sup>4</sup> + 4<sup>4</sup>。
+
+给出`n`，找到所有的n位十进制水仙花数。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 1
+输出: [0,1,2,3,4,5,6,7,8,9]
+```
+
+**样例 2:**
+
+```
+输入:  2
+输出: []	
+样例解释: 没有2位数的水仙花数。
+```
+ ### 参考代码
+ 直接枚举，拆数计算然后判断即可。
+```java
+class Solution {
+    /*
+     * @param n: The number of digits. 
+     * @return: All narcissistic numbers with n digits.
+     */
+    public ArrayList<Integer> getNarcissisticNumbers(int n) {
+        // write your code here
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        if (n == 1) {
+            for (int i = 0; i < 10; ++i)
+                result.add(i);
+            return result;
+        }
+        if (n == 6) {
+            result.add(548834);
+            return result;
+        }
+
+        for (int i = pow(10, n-1); i < pow(10, n); ++i) {
+            int j = i;
+            int s = 0;
+            while (j > 0) {
+                s += pow((j % 10), n);
+                j = j / 10;
+            }
+            if (s == i)
+                result.add(i);
+        }
+        return result;
+    }
+    
+    public int pow(int a, int b) {
+        int val = 1;
+        for (int i = 1; i <=b; ++i)
+            val *=a;
+        return val;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/next-smaller-and-larger-number-with-the-same-1-bits.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/next-smaller-and-larger-number-with-the-same-1-bits.md"
new file mode 100644
index 0000000..5535500
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/next-smaller-and-larger-number-with-the-same-1-bits.md"
@@ -0,0 +1,63 @@
+# 拥有同样多的1的下一个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/next-smaller-and-larger-number-with-the-same-1-bits/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个正整数，找出其用二进制表示拥有同样`1`的数量的比它小的最大正数和比它大的最小正数。
+
+如果找不到则输出`-1`，这里的正整数都是指32位带符号正整数。
+ ### 样例说明
+ **样例 1:**
+```
+输入: n=5
+输出: Smaller: 3 ,Larger : 6
+```
+**样例 2:**
+```
+输入: n=6
+输出: Smaller: 5 ,Larger : 9
+```
+ ### 参考代码
+ ```python
+class Solution:
+    # @param {int} n a 32bit positive integer
+    # @return {int} a 32bit positive integer or -1
+    def getPrev(self, n):
+        # Write your code here
+        temp = n;
+        c0 = 0;
+        c1 = 0;
+        while (temp & 1) == 1:
+            c1 += 1
+            temp >>= 1
+
+        if temp == 0:
+            return -1
+
+        while ((temp & 1) == 0) and (temp != 0):
+            c0 += 1
+            temp >>= 1
+
+        return n - (1 << c1) - (1 << (c0 - 1)) + 1
+
+    # @param {int} n a 32bit positive integer
+    # @return {int} a 32bit positive integer or -1
+    def getNext(self, n):
+        # Write your code here
+        temp = n
+        c0 = 0
+        c1 = 0
+        
+        while ((temp & 1) == 0) and (temp != 0):
+            c0 += 1
+            temp >>= 1
+
+        while (temp & 1) == 1:
+            c1 += 1
+            temp >>= 1
+
+        result = n + (1 << c0) + (1 << (c1 - 1)) - 1;
+        if result < 0 or result >= (1 << 31):
+            return -1
+
+        return n + (1 << c0) + (1 << (c1 - 1)) - 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/previous-permutation.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/previous-permutation.md"
new file mode 100644
index 0000000..1a8bbfe
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/previous-permutation.md"
@@ -0,0 +1,51 @@
+# 上一个排列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/previous-permutation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组来表示排列，找出其上一个排列。
+ ### 样例说明
+ 
+例1:
+```
+输入:[1]
+输出:[1]
+```
+
+
+例2:
+```
+输入:[1,3,2,3]
+输出:[1,2,3,3]
+```
+
+例3:
+```
+输入:[1,2,3,4]
+输出:[4,3,2,1]
+
+```
+
+ ### 参考代码
+ 从排列的最末尾开始，找到第一个下降点，下降点的意义为这个点之前的序列无需改动。
+然后,将后面的序列变为降序。
+从下降点开始扫描，找到第一个比她小的数字，交换即可。
+```python
+class Solution:
+    # @param num :  a list of integer
+    # @return : a list of integer
+    def previousPermuation(self, num):
+        # write your code here
+        for i in range(len(num)-2, -1, -1):
+            if num[i] > num[i+1]:
+                break
+        else:
+            num.reverse()
+            return num
+        for j in range(len(num)-1, i, -1):
+            if num[j] < num[i]:
+                num[i], num[j] = num[j], num[i]
+                break
+        for j in range(0, (len(num) - i)//2):
+            num[i+j+1], num[len(num)-j-1] = num[len(num)-j-1], num[i+j+1]
+        return num
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/rectangle-overlap.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/rectangle-overlap.md"
new file mode 100644
index 0000000..cbda4c6
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/rectangle-overlap.md"
@@ -0,0 +1,48 @@
+# 矩形重叠
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/rectangle-overlap/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个矩形，判断这两个矩形是否有重叠。
+ ### 样例说明
+ **样例 1:**
+```
+输入 : l1 = [0, 8], r1 = [8, 0], l2 = [6, 6], r2 = [10, 0]
+输出 : true
+```
+**样例 2:**
+```
+输入 : [0, 8], r1 = [8, 0], l2 = [9, 6], r2 = [10, 0]
+输出 : false
+```
+ ### 参考代码
+ 判断一下边界即可
+```java
+/**
+ * Definition for a point.
+ * class Point {
+ *     public int x, y;
+ *     public Point() { x = 0; y = 0; }
+ *     public Point(int a, int b) { x = a; y = b; }
+ * }
+ */
+
+public class Solution {
+    /**
+     * @param l1 top-left coordinate of first rectangle
+     * @param r1 bottom-right coordinate of first rectangle
+     * @param l2 top-left coordinate of second rectangle
+     * @param r2 bottom-right coordinate of second rectangle
+     * @return true if they are overlap or false
+     */
+    public boolean doOverlap(Point l1, Point r1, Point l2, Point r2) {
+        // Write your code here
+        if (l1.x > r2.x || l2.x > r1.x)
+            return false;
+    
+        if (l1.y < r2.y || l2.y < r1.y)
+            return false;
+ 
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/remove-element.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/remove-element.md"
new file mode 100644
index 0000000..e4dcd0d
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/remove-element.md"
@@ -0,0 +1,30 @@
+# 删除元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-element/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个数组和一个值，在原地删除与值相同的数字，返回新数组的长度。</p><p>元素的顺序可以改变，并且对新的数组不会有影响。</p>
+ ### 样例说明
+ 
+ ### 参考代码
+ Given an array and a value, remove all instances of that value in place and return the new length.
+
+The order of elements can be changed. It doesn't matter what you leave beyond the new length.
+
+从前往后，遇到等于value的就跳过，把后面的元素填到前面的位置里。
+```java
+public class Solution {
+    public int removeElement(int[] A, int elem) {
+        int i = 0;
+        int pointer = A.length - 1;
+        while(i <= pointer){
+            if(A[i] == elem){
+                A[i] = A[pointer];
+                pointer--;
+            } else {
+                i++;
+            }
+        }
+        return pointer + 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/restore-ip-addresses.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/restore-ip-addresses.md"
new file mode 100644
index 0000000..28ec19c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/restore-ip-addresses.md"
@@ -0,0 +1,70 @@
+# 恢复IP地址
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/restore-ip-addresses/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个由数字组成的字符串。求出其可能恢复为的所有IP地址。
+
+(你的任务就是往这段字符串中添加三个点, 使它成为一个合法的IP地址. 返回所有可能的IP地址.)
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "25525511135"
+输出: ["255.255.11.135", "255.255.111.35"]
+解释: ["255.255.111.35", "255.255.11.135"] 同样可以.
+```
+
+**样例 2:**
+
+```
+输入: "1116512311"
+输出: ["11.165.123.11","111.65.123.11"]
+```
+ ### 参考代码
+ 详见九章算法微博: [http://weibo.com/3948019741/BwVKqsKIO](http://weibo.com/3948019741/BwVKqsKIO)
+```java
+public class Solution {
+    public ArrayList<String> restoreIpAddresses(String s) {
+        ArrayList<String> result = new ArrayList<String>();
+        ArrayList<String> list = new ArrayList<String>();
+        
+        if (s.length() < 4 || s.length() > 12)
+            return result;
+        
+        helper(result, list, s , 0);
+        return result;
+    }
+    
+    public void helper(ArrayList<String> result, ArrayList<String> list, String s, int start) {
+        if (list.size() == 4) {
+            if (start != s.length())
+                return;
+            
+            StringBuffer sb = new StringBuffer();
+            for (String tmp: list) {
+                sb.append(tmp);
+                sb.append(".");
+            }
+            sb.deleteCharAt(sb.length()-1);
+            result.add(sb.toString());
+            return;
+        }
+        
+        for (int i = start; i < s.length() && i < start + 3; i++) {
+            String tmp = s.substring(start, i + 1);
+            if (isvalid(tmp)) {
+                list.add(tmp);
+                helper(result, list, s, i+1);
+                list.remove(list.size() - 1);
+            }
+        }
+    }
+    
+    private boolean isvalid(String s) {
+        if (s.charAt(0) == '0')
+            return s.equals("0"); 		// to eliminate cases like "00", "10"
+        int digit = Integer.valueOf(s);
+        return digit >= 0 && digit <= 255;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/reverse-3-digit-integer.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/reverse-3-digit-integer.md"
new file mode 100644
index 0000000..aabf04d
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/reverse-3-digit-integer.md"
@@ -0,0 +1,40 @@
+# 反转一个3位整数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reverse-3-digit-integer/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 反转一个只有3位数的整数。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: number = 123
+输出: 321
+```
+**样例 2:**
+
+```
+输入: number = 900
+输出: 9
+```
+
+ ### 参考代码
+ 硅谷求职算法集训营上课版本
+```java
+public class Solution {
+    /*
+     * @param number: A 3-digit number.
+     * @return: Reversed number.
+     */
+    public int reverseInteger(int number) {
+        // write your code here
+        //获得个位数
+        int num1 = number % 10;
+        //获得十位数
+        int num2 = (number / 10) % 10;
+        //获得百位数
+        int num3 = ((number / 10) / 10) % 10;
+        //相加
+        return num3 + num2 * 10 + num1 * 100;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/reverse-bits.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/reverse-bits.md"
new file mode 100644
index 0000000..1b30cb5
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/reverse-bits.md"
@@ -0,0 +1,37 @@
+# 颠倒二进制位
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reverse-bits/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 颠倒给定的 32 位无符号整数的二进制位。
+ ### 样例说明
+ **样例 1:**
+```
+输入: 00000010100101000001111010011100
+输出: 00111001011110000010100101000000
+解释: 
+输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596，
+因此返回 964176192，其二进制表示形式为 00111001011110000010100101000000。
+```
+**样例 2:**
+```
+输入：11111111111111111111111111111101
+输出：10111111111111111111111111111111
+解释：
+输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293，
+因此返回 3221225471 其二进制表示形式为 10101111110010110010011101101001。
+```
+ ### 参考代码
+ 分离出输入数字的每一位，最低位左移31bit，次低位左移30bit，以此类推。
+```java
+public class Solution {
+    // you need treat n as an unsigned value
+    public long reverseBits(int n) {
+        int reversed = 0;
+        for (int i = 0; i < 32; i++) {
+            reversed = (reversed << 1) | (n & 1);
+            n = (n >> 1);
+        }
+        return reversed;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/reverse-integer.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/reverse-integer.md"
new file mode 100644
index 0000000..55ca665
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/reverse-integer.md"
@@ -0,0 +1,42 @@
+# 反转整数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reverse-integer/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一个整数中的数字进行颠倒，当颠倒后的整数溢出时，返回 0 (标记为 32 位整数)。
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入：123
+输出：321
+```
+**样例 2：**
+```
+输入：-123
+输出：-321
+```
+ ### 参考代码
+ Reverse digits of an integer.&nbsp;<div><br></div><div>Example1: x = 123, return 321&nbsp;</div><div>Example2: x = -123, return -321&nbsp;</div><div><br></div><div>Have you thought about this?
+Here are some good questions to ask before coding. Bonus points for you if you have already thought through this!&nbsp;</div><div>If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100.&nbsp;</div><div>Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases?&nbsp;</div><div>&nbsp;Throw an exception? Good, but what if throwing an exception is not an option? You would then have to re-design the function (ie, add an extra parameter).<div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博:</span><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">&nbsp;&nbsp;</span><a href="http://weibo.com/3948019741/BAKMpkQmg" target="_blank">http://weibo.com/3948019741/BAKMpkQmg</a><br></div></div>
+```java
+public class Solution {
+    /**
+     * @param n the integer to be reversed
+     * @return the reversed integer
+     */
+    public int reverseInteger(int n) {
+        int reversed_n = 0;
+        
+        while (n != 0) {
+            int temp = reversed_n * 10 + n % 10;
+            n = n / 10;
+            if (temp / 10 != reversed_n) {
+                reversed_n = 0;
+                break;
+            }
+            reversed_n = temp;
+        }
+        return reversed_n;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/root-of-equation.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/root-of-equation.md"
new file mode 100644
index 0000000..96fb5ab
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/root-of-equation.md"
@@ -0,0 +1,58 @@
+# 方程的根
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/root-of-equation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个方程：*a*x<sup>2</sup> + *b*x + *c* = 0，求根。
+
+* 如果方程有两个根，就返回一个包含两个根的数组/列表。
+* 如果方程只有一个根，就返回一个包含一个跟的数组/列表。
+* 如果方程没有根，就返回一个空数组/列表。
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入：a = 1, b = -2, c = 1
+输出：[1]
+解释：方程有一个根，返回 [1]。
+```
+**样例 2：**
+```
+输入：a = 1, b = -3, c = 2
+输出：[1,2]
+解释：方程有两个根，返回 [1,2] 且第一个数应比第二个数小。
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param a an integer
+     * @param b an integer
+     * @param c an integer
+     * @return a double array
+     */
+    public double[] rootOfEquation(double a, double b, double c) {
+        if (b * b - 4 * a * c < 0) {
+            return new double[0];
+        }
+        
+        if (b * b - 4 * a * c == 0) {
+            double[] root = new double[1];
+            root[0] = -b / 2.0 / a;
+            return root;
+        }
+        
+        double[] root = new double[2];
+        double delta = Math.sqrt(b * b - 4 * a * c);
+        root[0] = (-b - delta) / 2.0 / a;
+        root[1] = (-b + delta) / 2.0 / a;
+        
+        if (root[0] > root[1]) {
+            double temp = root[0];
+            root[0] = root[1];
+            root[1] = temp;
+        }
+        return root;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/rotate-array.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/rotate-array.md"
new file mode 100644
index 0000000..6a9e088
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/rotate-array.md"
@@ -0,0 +1,55 @@
+# 旋转数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/rotate-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数组，将数组向右移动k步，其中k为非负数。
+ ### 样例说明
+ **样例 1:**
+```
+输入: [1,2,3,4,5,6,7], k = 3
+输出: [5,6,7,1,2,3,4]
+解释:
+向右旋转1步: [7,1,2,3,4,5,6]
+向右旋转2步: [6,7,1,2,3,4,5]
+向右旋转3步: [5,6,7,1,2,3,4]
+```
+
+**样例 2:**
+```
+输入: [-1,-100,3,99], k = 2
+输出: [3,99,-1,-100]
+解释: 
+向右旋转1步: [99,-1,-100,3]
+向右旋转2步: [3,99,-1,-100]
+```
+ ### 参考代码
+ Example：nums = [1,2,3,4,5,6,7] k = 3
+Step1:划分成[1,2,3,4], [5,6,7]
+Step2:分别reverse，[4,3,2,1], [7,6,5]
+Step3:合并reverse，[5,6,7,1,2,3,4]
+```java
+public class Solution {
+    /**
+     * @param nums: an array
+     * @param k: an integer
+     * @return: rotate the array to the right by k steps
+     */
+    public int[] rotate(int[] nums, int k) {
+        // Write your code here
+        int n = nums.length;
+        k %= n;
+        reverse(nums, 0, n - k - 1);
+        reverse(nums, n - k, nums.length - 1);
+        reverse(nums, 0, nums.length - 1);
+        return nums;
+    }
+    
+    public void reverse(int[] n, int i, int j) {
+        for (int p = i, q = j; p < q; p++, q--) {
+            int temp = n[p];
+            n[p] = n[q];
+            n[q] = temp;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/search-in-rotated-sorted-array-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/search-in-rotated-sorted-array-ii.md"
new file mode 100644
index 0000000..2d6011c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/search-in-rotated-sorted-array-ii.md"
@@ -0,0 +1,44 @@
+# 搜索旋转排序数组 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/search-in-rotated-sorted-array-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>跟进“搜索旋转排序数组”，假如有重复元素又将如何？</p><p><i>是否会影响运行时间复杂度？</i></p><p><i>如何影响？</i></p><p><i>为何会影响？</i></p><p>写出一个函数判断给定的目标值是否出现在数组中。</p>
+ ### 样例说明
+ 例1:
+```
+输入:
+[]
+1
+输出:
+false
+```
+例2:
+```
+输入:
+[3,4,4,5,7,0,1,2]
+4
+输出:
+true
+```
+
+ ### 参考代码
+ 由于出现重复元素，故不能使用二分法。
+所以暴力比较即可。
+```java
+public class Solution {
+    // 这个问题在面试中不会让实现完整程序
+    // 只需要举出能够最坏情况的数据是 [1,1,1,1... 1] 里有一个0即可。
+    // 在这种情况下是无法使用二分法的，复杂度是O(n)
+    // 因此写个for循环最坏也是O(n)，那就写个for循环就好了
+    //  如果你觉得，不是每个情况都是最坏情况，你想用二分法解决不是最坏情况的情况，那你就写一个二分吧。
+    //  反正面试考的不是你在这个题上会不会用二分法。这个题的考点是你想不想得到最坏情况。
+    public boolean search(int[] A, int target) {
+        for (int i = 0; i < A.length; i ++) {
+            if (A[i] == target) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/setter-and-getter.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/setter-and-getter.md"
new file mode 100644
index 0000000..6c1ba22
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/setter-and-getter.md"
@@ -0,0 +1,47 @@
+# Getter与Setter
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/setter-and-getter/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个`School`的类，包含下面的这些属性和方法:
+
+* 一个string类型的私有成员`name`.
+* 一个setter方法`setName`，包含一个参数name.
+* 一个getter方法`getName`，返回该对象的name。
+ ### 样例说明
+ ```
+Java:
+    School school = new School();
+    school.setName("MIT");
+    school.getName(); // 返回 "MIT" 作为结果 
+
+Python:
+    school = School();
+    school.setName("MIT")
+    school.getName() # 返回 "MIT" 作为结果 
+		
+```
+ ### 参考代码
+ 面向对象程序设计，name为私有成员，setter和getter是公有成员。
+```java
+public class School {
+    /*
+     * Declare a private attribute *name* of type string.
+     */
+    private String name;
+    
+    /**
+     * Declare a setter method `setName` which expect a parameter *name*.
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    /**
+     * Declare a getter method `getName` which expect no parameter and return
+     * the name of this school
+     */
+    public String getName() {
+        return this.name;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/shape-factory.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/shape-factory.md"
new file mode 100644
index 0000000..ba63166
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/shape-factory.md"
@@ -0,0 +1,106 @@
+# 形状工厂
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/shape-factory/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 工厂模式是一种常见的设计模式。实现一个形状工厂 `ShapeFactory` 来创建不同的形状类。这里我们假设只有三角形，正方形和矩形三种形状。
+ ### 样例说明
+ 例1:
+```
+输入:
+ShapeFactory sf = new ShapeFactory();
+Shape shape = sf.getShape("Square");
+shape.draw();
+输出:
+  ----
+ |    |
+ |    |
+  ----
+```
+例2:
+```
+输入:
+ShapeFactory sf = new ShapeFactory();
+shape = sf.getShape("Triangle");
+shape.draw();
+输出:
+   /\
+  /  \
+ /____\
+```
+例3:
+```
+
+输入:
+ShapeFactory sf = new ShapeFactory();
+shape = sf.getShape("Rectangle");
+shape.draw();
+输出:
+  ----
+ |    |
+  ----
+```
+ ### 参考代码
+ 直接根据对应类型输出对应形状即可
+```java
+/**
+ * Your object will be instantiated and called as such:
+ * ShapeFactory sf = new ShapeFactory();
+ * Shape shape = sf.getShape(shapeType);
+ * shape.draw();
+ */
+interface Shape {
+    void draw();
+}
+
+class Rectangle implements Shape {
+    // Write your code here
+    @Override
+    public void draw() {
+        System.out.println(" ---- ");
+        System.out.println("|    |");
+        System.out.println(" ---- ");
+   }
+}
+
+class Square implements Shape {
+    // Write your code here
+   @Override
+   public void draw() {
+        System.out.println(" ---- ");
+        System.out.println("|    |");
+        System.out.println("|    |");
+        System.out.println(" ---- ");
+   }
+}
+
+class Triangle implements Shape {
+    // Write your code here
+   @Override
+   public void draw() {
+        System.out.println("  /\\");
+        System.out.println(" /  \\");
+        System.out.println("/____\\");
+   }
+}
+
+public class ShapeFactory {
+    /**
+     * @param shapeType a string
+     * @return Get object of type Shape
+     */
+    public Shape getShape(String shapeType) {
+        // Write your code here
+        if (shapeType == null) {
+            return null;
+        }		
+        if (shapeType.equalsIgnoreCase("Triangle")) {
+            return new Triangle();
+        } else if(shapeType.equalsIgnoreCase("Rectangle")) {
+            return new Rectangle();         
+        } else if(shapeType.equalsIgnoreCase("Square")) {
+            return new Square();
+        }
+        return null;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/simple-calculator.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/simple-calculator.md"
new file mode 100644
index 0000000..0a07ac9
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/simple-calculator.md"
@@ -0,0 +1,59 @@
+# 简单计算器
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/simple-calculator/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出两个整数 *a* , *b* ,以及一个操作符 *opeator*
+```
++, -, *, /
+```
+返回结果 `a<operator>b`
+ ### 样例说明
+ ```
+样例 1:
+	输入:  a = 1, b = 2, operator = +
+	输出: 3
+	
+	样例解释: 
+	返回 1 + 2 的结果.
+
+样例 2:
+	输入:  a = 10, b = 20, operator = *
+	输出: 200
+	
+	样例解释: 
+	返回10 * 20的结果.
+
+样例 3:
+	输入:  a = 3, b = 2, operator = /
+	输出: 1
+	
+	样例解释: 
+	返回 3 / 2的结果.
+
+样例 4:
+	输入:  a = 10, b = 11, operator = -
+	输出: -1
+	
+	样例解释: 
+	返回 10 - 11的结果.
+
+```
+ ### 参考代码
+ 简单模拟
+```java
+public class Calculator {
+    /**
+      * @param a, b: Two integers.
+      * @param operator: A character, +, -, *, /.
+      */
+    public int calculate(int a, char operator, int b) {
+        switch (operator) {
+            case '+': return a + b;
+            case '-': return a - b;
+            case '*': return a * b;
+            case '/': return a / b;
+        }
+        return 0;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/singleton.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/singleton.md"
new file mode 100644
index 0000000..0c269cb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/singleton.md"
@@ -0,0 +1,35 @@
+# 单例
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/singleton/?utm_source=sc-github-wzz)
+ ## 题目描述
+ **单例** 是最为最常见的设计模式之一。对于任何时刻，如果某个类只存在且最多存在一个具体的实例，那么我们称这种设计模式为单例。例如，对于 class Mouse (不是动物的mouse哦)，我们应将其设计为 singleton 模式。
+
+你的任务是设计一个 `getInstance` 方法，对于给定的类，每次调用 `getInstance` 时，都可得到同一个实例。
+ ### 样例说明
+ ```
+在 Java 中:
+
+	A a = A.getInstance();
+	A b = A.getInstance();
+
+a 应等于 b.
+
+```
+ ### 参考代码
+ 创建私有静态成员对象，每次获取时返回此对象。
+```java
+class Solution {
+    
+    
+    /**
+     * @return: The same instance of this class every time
+     */
+    public static Solution instance = null;
+    public static Solution getInstance() {
+        if (instance == null) {
+            instance = new Solution();
+        }
+        return instance;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/strings-homomorphism.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/strings-homomorphism.md"
new file mode 100644
index 0000000..8274eb2
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/strings-homomorphism.md"
@@ -0,0 +1,73 @@
+# 字符同构
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/strings-homomorphism/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个字符串 **s** 和 **t** ，确定它们是否是同构的。
+两个字符串是同构的如果 s 中的字符可以被替换得到 t。
+所有出现的字符必须用另一个字符代替，同时保留字符串的顺序。 没有两个字符可以映射到同一个字符，但一个字符可以映射到自己。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param s a string
+     * @param t a string
+     * @return true if the characters in s can be replaced to get t or false
+     */
+    public boolean isIsomorphic(String s, String t) {
+        // Write your code here
+        int[] m1 = new int[128];
+        int[] m2 = new int[128];
+        for (int i = 0; i < s.length(); ++i) {
+            int cs = (int) s.charAt(i);
+            int ts = (int) t.charAt(i);
+            if (m1[cs] == 0 && m2[ts] == 0) {
+                m1[cs] = ts;
+                m2[ts] = 1;
+            } else if (m1[cs] != ts) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param s a string
+     * @param t a string
+     * @return true if the characters in s can be replaced to get t or false
+     */
+    public boolean isIsomorphic(String s, String t) {
+        // Write your code here
+        int[] map = new int[256];  // ASCII 的范围是0-255
+        char[] sc = s.toCharArray();
+        char[] tc = t.toCharArray();
+
+        for (int i = 0; i < s.length(); i++) {
+            if (map[sc[i]] == 0) {
+                map[sc[i]] = tc[i];
+            } else {
+                if (map[sc[i]] != tc[i]) {
+                    return false;
+                }
+            }
+        }
+
+        int[] map2 = new int[256];
+        for (int i = 0; i < t.length(); i++) {
+            if (map2[tc[i]] == 0) {
+                map2[tc[i]] = sc[i];
+            } else {
+                if (map2[tc[i]] != sc[i]) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/strings-serialization.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/strings-serialization.md"
new file mode 100644
index 0000000..6ee61c9
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/strings-serialization.md"
@@ -0,0 +1,95 @@
+# 编码和解码字符串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/strings-serialization/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个将字符串列表编码为字符串的算法。 已经编码的字符串之后会通过网络发送同时也会被解码回到原始的字符串列表。
+请实现 `encode` 和 `decode` 
+ ### 样例说明
+ 
+ ### 参考代码
+ 仿照转义字符的表示方法：用":;"表示字符串连接符，"::"表示":"自己本身
+```java
+public class Solution {
+    /**
+     * @param strs a list of strings
+     * @return encodes a list of strings to a single string.
+     */
+    public String encode(List<String> strs) {
+        // Write your code here
+        StringBuilder result = new StringBuilder();
+        for(String str : strs){
+            result.append(String.valueOf(str.length()) + "$");
+            result.append(str);
+        }
+        return result.toString();
+    }
+
+    /**
+     * @param str a string
+     * @return dcodes a single string to a list of strings
+     */
+    public List<String> decode(String str) {
+        // Write your code here
+        List<String> result = new LinkedList<String>();
+        int start = 0;
+        while(start < str.length()){
+            int idx = str.indexOf('$', start);
+            int size = Integer.parseInt(str.substring(start, idx));
+            result.add(str.substring(idx + 1, idx + size + 1));
+            start = idx + size + 1;
+        }
+        return result;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param strs a list of strings
+     * @return encodes a list of strings to a single string.
+     */
+    public String encode(List<String> strs) {
+        // Write your code here
+        StringBuilder ans = new StringBuilder();
+        for (String s : strs) {
+            for (char c : s.toCharArray()) {
+                if (c == ':') {                  // : itself
+                    ans.append("::");
+                } else {                         //ordinary character
+                    ans.append(c);
+                }
+            }
+            ans.append(":;");                    // ; connector
+        }
+        return ans.toString();
+    }
+
+    /**
+     * @param str a string
+     * @return dcodes a single string to a list of strings
+     */
+    public List<String> decode(String str) {
+        // Write your code here
+        List<String> ans = new ArrayList<>();
+        char[] sc = str.toCharArray();
+        StringBuilder item = new StringBuilder();
+        int i = 0;
+        while (i < str.length()) {
+            if (sc[i] == ':') {                  //escape
+                if (sc[i + 1] == ';') {          // ; connector
+                    ans.add(item.toString());
+                    item = new StringBuilder();
+                    i += 2;
+                } else {                         // : itself
+                    item.append(sc[i + 1]);
+                    i += 2;
+                }
+            } else {                             //ordinary character
+                item.append(sc[i]);
+                i += 1;
+            }
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/student-id.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/student-id.md"
new file mode 100644
index 0000000..e67da05
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/student-id.md"
@@ -0,0 +1,64 @@
+# 学号
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/student-id/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个名为`Class`的类，包含如下的一些属性和方法：
+
+1. 一个public的students属性，是一个Student类的数组。
+2. 一个构造函数，接受一个参数n，代表班级里有n个学生。构造函数需要创建n个学生的实例对象并放在students这个成员中，每个学生按照创建的顺序，学号需要依次标记为0, 1, 2 ... n-1。
+ ### 样例说明
+ **样例1:**
+
+```plain
+输入: 3
+输出: [0, 1, 2]
+样例说明: 对于3个学生的情况，我们应该让cls.students[0] = 0，cls.students[1] = 1，cls.students[2] = 2
+```
+
+**样例2:**
+
+```plain
+输入: 5
+输出: [0, 1, 2, 3, 4]
+```
+
+
+
+
+ ### 参考代码
+ 添加students属性和Class构造函数，时间复杂度O(n)，空间复杂度O(n)
+```python
+# Solution 1
+class Student:
+    def __init__(self, id):
+        self.id = id;
+
+class Class:
+
+    '''
+     * Declare a constructor with a parameter n which is the total number of
+     * students in the *class*. The constructor should create n Student
+     * instances and initialized with student id from 0 ~ n-1
+    '''
+    # write your code here
+    def __init__(self, n):
+        self.students = []
+        for i in range(n): 
+            self.students.append(Student(i))
+
+# Solution 2
+class Student:
+    def __init__(self, id):
+        self.id = id;
+
+class Class:
+
+    '''
+     * Declare a constructor with a parameter n which is the total number of
+     * students in the *class*. The constructor should create n Student
+     * instances and initialized with student id from 0 ~ n-1
+    '''
+    # write your code here
+    def __init__(self, n):
+        self.students = [Student(i) for i in range(n)]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/student-level.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/student-level.md"
new file mode 100644
index 0000000..989a3f8
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/student-level.md"
@@ -0,0 +1,68 @@
+# 成绩等级
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/student-level/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个学生的类 `Student`. 包含如下的成员函数和方法：
+
+1. 两个公有成员 `name` 和 `score`。分别是字符串类型和整数类型。
+2. 一个构造函数，接受一个参数 `name`。
+3. 一个公有成员函数 `getLevel()` 返回学生的成绩等级（一个字符）。
+
+等级表如下：
+
+* A: score >= 90
+* B: score >= 80 and < 90
+* C: score >= 60 and < 80
+* D: score < 60
+ ### 样例说明
+ **样例 1：**
+```
+Java:
+    Student student = new Student("Zuck");
+    student.score = 10;
+    student.getLevel(); // should be 'D'
+    student.score = 60;
+    student.getLevel(); // should be 'C'
+```
+**样例 2：**
+```
+Python:
+    student = Student("Zuck")
+    student.score = 10
+    student.getLevel() # should be 'D'
+    student.score = 60
+    student.getLevel() # should be 'C'
+```
+ ### 参考代码
+ ```java
+public class Student {
+    /**
+     * Declare two public attributes name(string) and score(int).
+     */
+    public String name;
+    public int score;
+    
+    /**
+     * Declare a constructor expect a name as a parameter.
+     */
+    public Student(String name) {
+        this.name = name;
+    }
+    
+    /**
+     * Declare a public method `getLevel` to get the level(char) of this student.
+     */
+    public char getLevel() {
+        if (score >= 90) {
+            return 'A';
+        } else if (score >= 80) {
+            return 'B';
+        } else if (score >= 60) {
+            return 'C';
+        } else {
+            return 'D';
+        }
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/substring-rotation.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/substring-rotation.md"
new file mode 100644
index 0000000..2102523
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/substring-rotation.md"
@@ -0,0 +1,45 @@
+# 用isSubstring判断字符串的循环移动
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/substring-rotation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假定有一种 isSubstring 的方法，可以检验某个单词是否为另一个单词的子字符串。给定 `s1` 和 `s2`，请设计一种方法来检验 s2 是否为 s1 的循环移动后的字符串。注意，只能调用一次 isSubstring 。
+ ### 样例说明
+ **样例 1：**
+```
+输入：s1 = "waterbottle", s2 = "erbottlewat"
+输出：True
+解释："waterbottle" 是 "erbottlewat" 的一种循环移动后的字符串。
+```
+**样例 2：**
+```
+输入：s1 = "apple", s2 = "ppale"
+输出：False
+解释："apple" 不是 "ppale" 的一种循环移动后的字符串。
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param s1 the first string
+     * @param s2 the second string
+     * @return true if s2 is a rotation of s1 or false
+     */
+    public boolean isRotation(String s1, String s2) {
+        // Write your code here
+        // Using one call to isSubstring
+        int len = s1.length();
+        /* check that s1 and s2 are equal length and not empty */
+        if (len == s2.length() && len > 0) {
+            /* concatenate s1 and s1 within new buffer */
+            String s1s1 = s1 + s1;
+            return isSubstring(s1s1, s2);
+        }
+        return false;
+    }
+    
+    // @return true if t is a substring of s or false
+    public boolean isSubstring(String s, String t) {
+        return s.contains(t);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/substring-with-concatenation-of-all-words.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/substring-with-concatenation-of-all-words.md"
new file mode 100644
index 0000000..5f47faf
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/substring-with-concatenation-of-all-words.md"
@@ -0,0 +1,53 @@
+# 包含所有单词连接的子串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/substring-with-concatenation-of-all-words/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个字符串`s`和一个单词列表`words`，`words`里的单词的长度都相同。 在`s`中查找子串的所有起始索引，这个子串是`words`中每个单词恰好一次的连接，且没有任何插入字符。
+ ### 样例说明
+ 
+ ### 参考代码
+ 复杂度：$O(nm)$
+
+$n = len(s),m =  len(words[0]), k = len(words)$
+
+暴力做法，枚举开始位置，判断之后长度$m*k$的子串是否由给定字符串集合组成，最坏复杂度为$O(nmk)$。
+
+对于长度为$m$的字符串，0与m位置开始的区别，只在于少了$s[0:m]$，多了$s[m*k+1:(m+1)*k]$，所以产生了许多冗余操作。我们根据开始位置$0$ ~ $m-1$分类，扫描字符串`s`，使用一个滑动窗口记录当前匹配了那些字符串，当下一个字符串不在`words`中，清空窗口(任意包含该串的均不合法)，如果记录的出现次数超过了`words`中数量，表示需要滑动窗口，
+
+窗口中单词数量等于k时，更新答案。
+```java
+public class Solution {
+    public ArrayList<Integer> findSubstring(String S, String[] L) {
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        HashMap<String, Integer> toFind = new HashMap<String, Integer>();
+        HashMap<String, Integer> found = new HashMap<String, Integer>();
+        int m = L.length, n = L[0].length();
+        for (int i = 0; i < m; i ++){
+            if (!toFind.containsKey(L[i])){
+                toFind.put(L[i], 1);
+            }
+            else{
+                toFind.put(L[i], toFind.get(L[i]) + 1);
+            }
+        }
+        for (int i = 0; i <= S.length() - n * m; i ++){
+            found.clear();
+            int j;
+            for (j = 0; j < m; j ++){
+                int k = i + j * n;
+                String stub = S.substring(k, k + n);
+                if (!toFind.containsKey(stub)) break;
+                if(!found.containsKey(stub)){
+                    found.put(stub, 1);
+                }
+                else{
+                    found.put(stub, found.get(stub) + 1);
+                }
+                if (found.get(stub) > toFind.get(stub)) break;
+            }
+            if (j == m) result.add(i);
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/sudoku-solver.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/sudoku-solver.md"
new file mode 100644
index 0000000..3a8a40d
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/sudoku-solver.md"
@@ -0,0 +1,163 @@
+# 数独
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sudoku-solver/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 编写一个程序，通过填充空单元来解决数独难题。
+空单元由数字`0`表示。
+你可以认为只有一个唯一的解决方案。
+ ### 样例说明
+ **样例 1：**
+```
+给定的数独谜题:
+```
+![](http://lintcode-media.s3.amazonaws.com/problem/250px-Sudoku-by-L2G-20050714.svg.png)
+```
+返回结果：
+```
+![](http://lintcode-media.s3.amazonaws.com/problem/250px-Sudoku-by-L2G-20050714_solution.svg.png)
+ ### 参考代码
+ 详细题解，请见九章微博：http://weibo.com/3948019741/BullK0fYo
+
+采用递归+回溯模板来解决此问题：
+1. 判定DFS的退出条件。
+
+    (1) y越界，应该往下一行继续解。
+
+  （2）x越界，代表数独解完，应该返回。
+
+2. DFS的主体部分：
+
+    把9个可能的值遍历一次，如果是OK的（使用独立 的Valid函数来判定行，列，BLOCK是否符合），继续DFS，否则回溯。
+
+3. 最后的返回值：
+
+    如果所有的可能性遍历都没有找到TRUE，最后应该返回FALSE，也就是当前情况无解。这个时候DFS会自动回溯到上一层再查找别的可能解。
+```java
+public class Solution {
+    public void solveSudoku(char[][] board){
+        solve(board);
+    }
+
+    public boolean solve(char[][] board) {
+        for(int i = 0; i < 9; i++) {
+            for(int j = 0; j < 9; j++){
+                if(board[i][j] != '.'){
+                    continue;
+                }
+                for(int k = 1; k <= 9; k++){
+                    board[i][j] = (char) (k + '0');
+                    if (isValid(board, i, j) && solve(board)){
+                        return true;
+                    }
+                    board[i][j] = '.';
+                }
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    
+     public boolean isValid(char[][] board, int a, int b){
+        Set<Character> contained = new HashSet<Character>();
+        for(int j=0;j<9;j++){
+            if(contained.contains(board[a][j])) return false;
+            if(board[a][j]>'0' && board[a][j]<='9')
+                contained.add(board[a][j]);
+        }
+            
+        
+    
+        contained = new HashSet<Character>();
+        for(int j=0;j<9;j++){
+            if (contained.contains(board[j][b])) {
+                return false;
+            }
+            if (board[j][b]>'0' && board[j][b]<='9') {
+                contained.add(board[j][b]);
+            }
+        }
+        
+    
+        contained = new HashSet<Character>();
+        for (int m = 0; m < 3; m++) {
+            for (int n = 0; n < 3; n++){
+                int x = a / 3 * 3 + m, y = b / 3 * 3 + n;
+                if (contained.contains(board[x][y])) {
+                    return false;
+                }
+                if (board[x][y] > '0' && board[x][y] <= '9') {
+                        contained.add(board[x][y]);
+                }
+            } 
+        }
+    
+        return true;
+    }
+}
+
+// 九章硅谷求职算法集训营版本
+public class Solution {
+    boolean[][] row = new boolean[9][9 + 1];
+    boolean[][] col = new boolean[9][9 + 1];
+    boolean[][][] block = new boolean[3][3][9 + 1];
+    public void solveSudoku(int[][] board){
+        int i, j, k;
+        for (i = 0; i < 9; ++i) {
+            for (j = 1; j <= 9; ++j) {
+                row[i][j] = col[i][j] = false;
+            }
+        }
+
+        for (i = 0; i < 3; ++i) {
+            for (j = 0; j < 3; ++j) {
+                for (k = 1; k <= 9; ++k) {
+                    block[i][j][k] = false;
+                }
+            }
+        }
+
+        for (i = 0; i < 9; ++i) {
+            for (j = 0; j < 9; ++j) {
+                if (board[i][j] != 0) {
+                    k = board[i][j];
+                    row[i][k] = col[j][k] = true;
+                    block[i / 3][j / 3][k] = true;
+                }
+            }
+        }
+
+        solve(board, 0, 0);
+    }
+
+    public boolean solve(int[][] board, int i, int j) {
+        if (i == 9) {
+            return true;
+        }
+
+        if (j == 9) {
+            return solve(board, i + 1, 0);
+        }
+
+        if (board[i][j] != 0) {
+            return solve(board, i, j + 1);
+        }
+
+        int k;
+        for (k = 1; k <= 9; ++k) {
+            if (!row[i][k] && !col[j][k] && !block[i/3][j/3][k]) {
+                row[i][k] = col[j][k] = block[i/3][j/3][k] = true;
+                board[i][j] = k;
+                if (solve(board, i, j + 1)) {
+                    return true;
+                }
+                
+                board[i][j] = 0;
+                row[i][k] = col[j][k] = block[i/3][j/3][k] = false;
+            }
+        }
+
+        return false;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/text-justification.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/text-justification.md"
new file mode 100644
index 0000000..e5bf829
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/text-justification.md"
@@ -0,0 +1,92 @@
+# 文字并排
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/text-justification/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个单词数组和一个宽度maxWidth，格式化文本，使每行具有刚好maxWidth个字符并完全（左和右）对齐。
+
+你应该用贪心法打包你的单词; 也就是说，在每行中包含尽可能多的单词。 必要时填充额外的空格，以便每行具有正确的maxWidth字符。
+
+单词之间的额外空格应尽可能均匀分布。 如果一行上的空格数不均匀分配，则左侧的空插槽将分配比右侧插槽更多的空格。
+
+对于最后一行文本，它应该是左对齐的，并且在单词之间不插入额外的空格。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+words = ["This", "is", "an", "example", "of", "text", "justification."]
+maxWidth = 16
+输出:
+[
+   "This    is    an",
+   "example  of text",
+   "justification.  "
+]
+```
+**样例 2:**
+```
+输入:
+words = ["What","must","be","acknowledgment","shall","be"]
+maxWidth = 16
+输出:
+[
+  "What   must   be",
+  "acknowledgment  ",
+  "shall be        "
+]
+说明：请注意，最后一行是 "shall be    " 而不是 "shall     be"，
+              因为最后一行必须左对齐而不是完全对齐。
+              请注意，第二行也是左对齐的，因为它只包含一个单词。
+```
+**样例 3:**
+```
+输入:
+words = ["Science","is","what","we","understand","well","enough","to","explain",
+         "to","a","computer.","Art","is","everything","else","we","do"]
+maxWidth = 20
+输出:
+[
+  "Science  is  what we",
+  "understand      well",
+  "enough to explain to",
+  "a  computer.  Art is",
+  "everything  else  we",
+  "do                  "
+]
+```
+ ### 参考代码
+ ```python
+class Solution:
+    def _format(self, line, maxWidth):
+        if len(line) == 1:
+            return line[0] + " " * (maxWidth - len(line[0]))
+        length = sum([len(w) for w in line])
+        s, gaps = line[0], len(line) - 1
+        for index, w in enumerate(line[1:]):
+            if index < (maxWidth - length) % gaps:
+                s = s + " " + " " * ((maxWidth - length) / gaps) + w
+            else:
+                s = s + " " * ((maxWidth - length) / gaps) + w
+        return s
+        
+    def _formatLast(self, line, maxWidth):
+        s = ' '.join(line)
+        return s + " " * (maxWidth - len(s))
+    
+    # @param {string[]} words
+    # @param {integer} maxWidth
+    # @return {string[]}
+    def fullJustify(self, words, maxWidth):
+        line, length = [], 0
+        results = []
+        for w in words:
+            if length + len(w) + len(line) <= maxWidth:
+                length += len(w)
+                line.append(w)
+            else:
+                results.append(self._format(line, maxWidth))
+                length = len(w)
+                line = [w]
+        if len(line):
+            results.append(self._formatLast(line, maxWidth))
+        return results
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/toy-factory.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/toy-factory.md"
new file mode 100644
index 0000000..a918b09
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/toy-factory.md"
@@ -0,0 +1,75 @@
+# 玩具工厂
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/toy-factory/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 工厂模式是一种常见的设计模式。请实现一个玩具工厂 `ToyFactory` 用来产生不同的玩具类。可以假设只有猫和狗两种玩具。
+
+ ### 样例说明
+ 
+例1：
+```
+输入：
+ToyFactory tf = ToyFactory();
+Toy toy = tf.getToy('Dog');
+toy.talk(); 
+输出：
+Wow
+```
+例2:
+```
+输入：
+ToyFactory tf = ToyFactory();
+toy = tf.getToy('Cat');
+toy.talk();
+输出：
+Meow
+
+```
+ ### 参考代码
+ 设计两个子类继承父类即可
+```java
+/**
+ * Your object will be instantiated and called as such:
+ * ToyFactory tf = new ToyFactory();
+ * Toy toy = tf.getToy(type);
+ * toy.talk();
+ */
+interface Toy {
+    void talk();
+}
+
+class Dog implements Toy {
+    // Write your code here
+    @Override
+    public void talk() {
+        System.out.println("Wow");
+   }
+}
+
+class Cat implements Toy {
+    // Write your code here
+    @Override
+    public void talk() {
+        System.out.println("Meow");
+   }
+}
+
+public class ToyFactory {
+    /**
+     * @param type a string
+     * @return Get object of the type
+     */
+    public Toy getToy(String type) {
+        // Write your code here
+        if (type == null) {
+            return null;
+        }		
+        if (type.equalsIgnoreCase("Dog")) {
+            return new Dog();
+        } else if(type.equalsIgnoreCase("Cat")) {
+            return new Cat();         
+        }
+        return null;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/trailing-zeros.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/trailing-zeros.md"
new file mode 100644
index 0000000..2025448
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/trailing-zeros.md"
@@ -0,0 +1,42 @@
+# 尾部的零
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/trailing-zeros/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>设计一个算法，计算出n阶乘中尾部零的个数</p>
+ ### 样例说明
+ ```
+样例  1:
+	输入: 11
+	输出: 2
+	
+	样例解释: 
+	11! = 39916800, 结尾的0有2个。
+
+样例 2:
+	输入:  5
+	输出: 1
+	
+	样例解释: 
+	5! = 120， 结尾的0有1个。
+
+```
+ ### 参考代码
+ 可以将每个数拆分成其素因子的乘积，可以发现，0是由`2*5`产生的，而5的数量一定小于2的数量，因此5的个数决定了结尾0的个数。
+
+只要计算n的阶乘中，5这个素因子出现多少次即可。
+```java
+class Solution {
+    /*
+     * param n: As desciption
+     * return: An integer, denote the number of trailing zeros in n!
+     */
+    public long trailingZeros(long n) {
+        long sum = 0;
+        while (n != 0) {
+            sum += n / 5;
+            n /= 5;
+        }
+        return sum;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/trie-service.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/trie-service.md"
new file mode 100644
index 0000000..ea7b4f3
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/trie-service.md"
@@ -0,0 +1,84 @@
+# 查找树服务
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/trie-service/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 通过<字符串，值\>的集合来建立树结构，每个结点保存前10大的数值。
+ ### 样例说明
+ **样例1**
+
+```
+输入:  
+ <"abc", 2>
+ <"ac", 4>
+ <"ab", 9>
+输出:<a[9,4,2]<b[9,2]<c[2]<>>c[4]<>>> 
+解释:
+			Root
+             / 
+           a(9,4,2)
+          /    \
+        b(9,2) c(4)
+       /
+     c(2)
+```
+
+**样例2**
+
+```
+输入:  
+<"a", 10>
+<"c", 41>
+<"b", 50>
+<"abc", 5>
+输出: <a[10,5]<b[5]<c[5]<>>>b[50]<>c[41]<>>
+```
+ ### 参考代码
+ 先遍历一遍数，然后重构树进行求解
+```python
+"""
+Definition of TrieNode:
+class TrieNode:
+    def __init__(self):
+        # <key, value>: <Character, TrieNode>
+        self.children = collections.OrderedDict()
+        self.top10 = []
+"""
+class TrieService:
+
+    def __init__(self):
+        self.root = TrieNode()
+
+    def get_root(self):
+        # Return root of trie root, and 
+        # lintcode will print the tree struct.
+        return self.root
+
+    # @param {str} word a string
+    # @param {int} frequency an integer
+    # @return nothing
+    def insert(self, word, frequency):
+        # Write your your code here
+        node = self.root
+        for letter in word:
+            child = node.children.get(letter, None)
+
+            if child is None:
+                child = TrieNode()
+
+            node.children[letter] = child
+            self.add_frequency(child.top10, frequency)
+
+            node = child
+
+    def add_frequency(self, top10, frequency):
+        top10.append(frequency)
+        index = len(top10) - 1
+        while index > 0:
+            if top10[index] > top10[index - 1]:
+                top10[index], top10[index - 1] = top10[index - 1], top10[index]
+                index -= 1
+            else:
+                break
+        if len(top10) > 10:
+            top10.pop()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/tweaked-identical-binary-tree.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/tweaked-identical-binary-tree.md"
new file mode 100644
index 0000000..d8848b7
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/tweaked-identical-binary-tree.md"
@@ -0,0 +1,58 @@
+# 扭转后等价的二叉树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/tweaked-identical-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 检查两棵二叉树是否在经过若干次扭转后可以等价。扭转的定义是，交换任意节点的左右子树。等价的定义是，两棵二叉树必须为相同的结构，并且对应位置上的节点的值要相等。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{1,2,3,4}，{1,3,2,#,#,#,4}
+输出：true
+解释：
+        1             1
+       / \           / \
+      2   3    和   3   2
+     /                   \
+    4                     4
+
+是相同的。
+```
+**样例 2:**
+```
+输入：{1,2,3,4}，{1,3,2,4}
+输出：false
+解释：
+
+        1             1
+       / \           / \
+      2   3    和   3   2
+     /             /
+    4             4
+
+不一样。
+```
+ ### 参考代码
+ 判断该子树不交换左右子树和交换左右子树是否能与对应的子树一致，往上回溯即可
+```python
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        this.val = val
+        this.left, this.right = None, None
+"""
+class Solution:
+    """
+    @param a, b, the root of binary trees.
+    @return true if they are tweaked identical, or false.
+    """
+    def isTweakedIdentical(self, a, b):
+        # Write your code here
+        if a == None and b == None: return True
+        if a and b and a.val == b.val:
+            return self.isTweakedIdentical(a.left, b.left) and \
+                    self.isTweakedIdentical(a.right, b.right) or \
+                    self.isTweakedIdentical(a.left, b.right) and \
+                    self.isTweakedIdentical(a.right, b.left)
+        return False
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/two-strings-are-anagrams.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/two-strings-are-anagrams.md"
new file mode 100644
index 0000000..8e25d0b
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/two-strings-are-anagrams.md"
@@ -0,0 +1,69 @@
+# 两个字符串是变位词
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/two-strings-are-anagrams/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 写出一个函数 `anagram(s, t)` 判断两个字符串是否可以通过改变字母的顺序变成一样的字符串。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param s: The first string
+     * @param b: The second string
+     * @return true or false
+     */
+    public boolean anagram(String s, String t) {
+        // write your code here
+        int[] cntS = new int[256];
+        int[] cntT = new int[256];
+        int i;
+        for (i = 0; i < 256; ++i) {
+            cntS[i] = cntT[i] = 0;
+        }
+        
+        for (i = 0; i < s.length(); ++i) {
+            cntS[(int)s.charAt(i)]++;
+        }
+        
+        for (i = 0; i < t.length(); ++i) {
+            cntT[(int)t.charAt(i)]++;
+        }
+        
+        for (i = 0; i < 256; i++) {
+            if (cntS[i] != cntT[i]) {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+}
+
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param s: The first string
+     * @param b: The second string
+     * @return true or false
+     */
+    public boolean anagram(String s, String t) {
+        // write your code here
+        int[] cntS = new int[256];
+        int[] cntT = new int[256];
+        for (char c : s.toCharArray()) {
+            cntS[c]++;
+        }
+        for (char c : t.toCharArray()) {
+            cntT[c]++;
+        }
+        for (int i = 0; i < 256; i++) {
+            if (cntS[i] != cntT[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/ugly-number.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/ugly-number.md"
new file mode 100644
index 0000000..bb0b8b3
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/ugly-number.md"
@@ -0,0 +1,43 @@
+# 丑数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/ugly-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 写一个程序来检测一个整数是不是`丑数`。
+
+丑数的定义是，只包含质因子 `2, 3, 5` 的正整数。比如 6, 8 就是丑数，但是 14 不是丑数因为他包含了质因子 7。
+ ### 样例说明
+ 例1:
+```
+输入: num = 8 
+输出: true
+解释:
+8=2*2*2
+```
+例2:
+```
+输入: num = 14 
+输出: false
+解释:
+14=2*7 
+```
+
+ ### 参考代码
+ 看这个数是否只有2，3，5的因子
+```java
+public class Solution {
+    /**
+     * @param num an integer
+     * @return true if num is an ugly number or false
+     */
+    public boolean isUgly(int num) {
+        if (num <= 0) return false;  
+        if (num == 1) return true;  
+          
+        while (num >= 2 && num % 2 == 0) num /= 2;  
+        while (num >= 3 && num % 3 == 0) num /= 3;  
+        while (num >= 5 && num % 5 == 0) num /= 5;  
+          
+        return num == 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/unique-binary-search-trees-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/unique-binary-search-trees-ii.md"
new file mode 100644
index 0000000..ad473c7
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/unique-binary-search-trees-ii.md"
@@ -0,0 +1,60 @@
+# 不同的二叉查找树 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/unique-binary-search-trees-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="color: rgb(113, 113, 113); font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;">给出n，生成所有由1...n为节点组成的不同的二叉查找树</span><br></p>
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:3
+输出:
+    1         3     3       2    1
+     \       /     /       / \    \
+      3     2     1       1   3    2
+     /     /       \                \
+    2     1         2                3
+```
+ ### 参考代码
+ Given n, generate all structurally unique BST's (binary search trees) that store values 1...n.
+
+For example,
+Given n = 3, your program should return all 5 unique BST's shown below.
+
+   1         3     3      2      1
+    \       /     /      / \      \
+     3     2     1      1   3      2
+    /     /       \                 \
+   2     1         2                 3
+```java
+public class Solution {
+    public ArrayList<TreeNode> generateTrees(int n) {
+        return generate(1, n);
+    }
+    
+    private ArrayList<TreeNode> generate(int start, int end){
+        ArrayList<TreeNode> rst = new ArrayList<TreeNode>();   
+    
+        if(start > end){
+            rst.add(null);
+            return rst;
+        }
+     
+        for(int i=start; i<=end; i++){
+            ArrayList<TreeNode> left = generate(start, i-1);
+            ArrayList<TreeNode> right = generate(i+1, end);
+            for(TreeNode l: left){
+                for(TreeNode r: right){
+                    // should new a root here because it need to 
+                    // be different for each tree
+                    TreeNode root = new TreeNode(i);  
+                    root.left = l;
+                    root.right = r;
+                    rst.add(root);
+                }
+            }
+        }
+        return rst;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/unique-binary-search-trees.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/unique-binary-search-trees.md"
new file mode 100644
index 0000000..bc184d5
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/unique-binary-search-trees.md"
@@ -0,0 +1,57 @@
+# 不同的二叉查找树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/unique-binary-search-trees/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出 *n*，问由 1...*n* 为节点组成的不同的二叉查找树有多少种？
+ ### 样例说明
+ **样例 1：**
+```
+输入：n = 3
+输出：5
+解释：有5种不同形态的二叉查找树：
+```
+
+	1           3    3       2      1
+	 \         /    /       / \      \
+	  3      2     1       1   3      2
+	 /      /       \                  \
+	2     1          2                  3
+ ### 参考代码
+ Given n, how many structurally unique BST's (binary search trees) that store values 1...n?
+
+For example,
+Given n = 3, there are a total of 5 unique BST's.
+
+   1         3     3      2      1
+    \       /     /      / \      \
+     3     2     1      1   3      2
+    /     /       \                 \
+   2     1         2                 3
+```java
+public class Solution {
+/*
+The case for 3 elements example
+Count[3] = Count[0]*Count[2]  (1 as root)
+              + Count[1]*Count[1]  (2 as root)
+              + Count[2]*Count[0]  (3 as root)
+
+Therefore, we can get the equation:
+Count[i] = ∑ Count[0...k] * [ k+1....i]     0<=k<i-1  
+
+*/
+    public int numTrees(int n) {
+        int[] count = new int[n + 2];
+        count[0] = 1;
+        count[1] = 1;
+        
+        for(int i = 2; i <= n; i++){
+            for(int j = 0; j < i; j++){
+                count[i] += count[j] * count[i - j - 1];
+            }
+        }
+        return count[n];
+    }
+}
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/utf-8-validation.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/utf-8-validation.md"
new file mode 100644
index 0000000..8e2303e
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/utf-8-validation.md"
@@ -0,0 +1,65 @@
+# UTF-8编码检查
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/utf-8-validation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ UTF-8编码中，一个字符的长度可以是**1到4字节**，服从如下的规则：
+
+1. 对于单字节的字符，第`1`位是一个`'0'`，后续二进制位为其unicode编码。
+2. 对于`n`字节的字符，第一个字节的前`n`位全是`'1'`，第`n+1`位是`'0'`；对于后续的`n-1`字节，每个字节最高两位是`'10'`。
+
+以下是字符编号范围与UTF-8编码对应表：
+```
+       字符编号范围     |        UTF-8编码的八位组序列
+      (十六进制形式)    |            (二进制形式)
+   --------------------+---------------------------------------------
+   0000 0000-0000 007F | 0xxxxxxx
+   0000 0080-0000 07FF | 110xxxxx 10xxxxxx
+   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
+   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+```
+给定一个用来表示数据的整数数组，判断其是否为一个合法的UTF-8编码。
+ ### 样例说明
+ **样例1**
+```
+输入：[197, 130, 1]
+输出：true
+解释：
+[197, 130, 1]，它代表的八位组序列为：11000101 10000010 00000001。
+这是一个合法的utf-8编码，在双字节编码的字符之后跟了一个单字节编码的字符。
+```
+**样例2**
+```
+输入：[235, 140, 4]
+输出：false
+解释：
+[235, 140, 4]，它代表的八位组序列为：11101011 10001100 00000100。
+前三位都是'1'，第四位是'0'说明这是一个三字节编码的字符。
+第二个字节是一个后续的字节，它以"10"起始，此处没问题。
+但是第三个字节，也就是第二个后续的字节没有从"10"起始，所以这个编码不合法。
+```
+ ### 参考代码
+ 这个题目主要是需要理解题面的意思。
+题目中给出的数组是一串二进制编码，他可能是由多个字符构成的，因此逐个字符去判断合理性即可。
+```python
+def check(nums, start, size):
+    for i in range(start + 1, start + size + 1):
+        if i >= len(nums) or (nums[i] >> 6) != 0b10:
+            return False
+    return True
+
+class Solution(object):
+    def validUtf8(self, nums, start=0):
+        while start < len(nums):
+            first = nums[start]
+            if (first >> 3) == 0b11110 and check(nums, start, 3):
+                start += 4
+            elif (first >> 4) == 0b1110  and check(nums, start, 2): 
+                start += 3
+            elif (first >> 5) == 0b110   and check(nums, start, 1): 
+                start += 2
+            elif (first >> 7) == 0:
+                start += 1
+            else:
+                return False
+        return True
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/valid-number.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/valid-number.md"
new file mode 100644
index 0000000..2eb6db4
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/valid-number.md"
@@ -0,0 +1,151 @@
+# 有效数字
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/valid-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串，验证其是否为数字。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "0"
+输出: true
+解释: "0" 可以被转换成 0
+```
+
+**样例 2:**
+
+```
+输入: "0.1"
+输出: true
+解释: "0.1" 可以被转换成 0.1
+```
+
+**样例 3:**
+
+```
+输入: "abc"
+输出: false
+```
+
+**样例 4:**
+
+```
+输入: "1 a"
+输出: false
+```
+
+**样例 5:**
+
+```
+输入: "2e10"
+输出: true
+解释: "2e10" 代表 20,000,000,000
+```
+ ### 参考代码
+ 首先应该明确合法的数字有哪些:
+
+1. 整数, 例如 "122", "114"
+2. 浮点数, 例如 "1.2", "2.", ".5", "1e10", "1E10"
+3. 上面两种数加上符号, 即 "+" 或 "-"
+
+"2.", ".5" 这两种形式可能让你有点迷惑, 你可以试一试, 在大多数编程语言中它们都是合法的字面量.
+
+为了方便, 我们可以先处理掉首尾的空白字符. 然后再判断第一个是否符号, 如果是也过滤掉. 
+
+然后, 剩下的字符串就只能包含 0-9, `.`, `e/E` 这三类字符了, 如果含有这三类之外的, 直接返回 false 即可. 然后根据以下原则判断即可:
+
+1. 小数点和 `e/E` 都至多只能出现 1 次
+2. 如果含有小数点, 则小数点前后至少有一个数字, 一个孤立的小数点是非法的.
+3. 如果含有 `e/E`, 则它的前后必须有数字.
+```java
+// Non-regex version
+
+public class Solution {
+    public boolean isNumber(String s) {
+        int len = s.length();
+        int i = 0, e = len - 1;
+        while (i <= e && Character.isWhitespace(s.charAt(i)))
+            i++;
+        if (i > len - 1)
+            return false;
+        while (e >= i && Character.isWhitespace(s.charAt(e)))
+            e--;
+        // skip leading +/-
+        if (s.charAt(i) == '+' || s.charAt(i) == '-')
+            i++;
+        boolean num = false; // is a digit
+        boolean dot = false; // is a '.'
+        boolean exp = false; // is a 'e'
+        while (i <= e) {
+            char c = s.charAt(i);
+            if (Character.isDigit(c)) {
+                num = true;
+            } else if (c == '.') {
+                if (exp || dot)
+                    return false;
+                dot = true;
+            } else if (c == 'e') {
+                if (exp || num == false)
+                    return false;
+                exp = true;
+                num = false;
+            } else if (c == '+' || c == '-') {
+                if (s.charAt(i - 1) != 'e')
+                    return false;
+            } else {
+                return false;
+            }
+            i++;
+        }
+        return num;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param s: the string that represents a number
+     * @return: whether the string is a valid number
+     */
+    public boolean isNumber(String s) {
+        // write your code here
+        int i = 0;
+        s = s.trim() + " "; // why +" "?
+        char[] sc = s.toCharArray();
+        int len = s.length() - 1;
+
+        if (sc[i] == '+' || sc[i] == '-') {
+            i++;
+        }
+        int nDigit = 0, nPoint = 0;
+        while (Character.isDigit(sc[i]) || sc[i] == '.') {
+            if (Character.isDigit(sc[i])) {
+                nDigit++;
+            }
+            if (sc[i] == '.') {
+                nPoint++;
+            }
+            i++;
+        }
+        if (nDigit <= 0 || nPoint > 1) {
+            return false;
+        }
+
+        if (sc[i] == 'e') {
+            i++;
+            if (sc[i] == '+' || sc[i] == '-') {
+                i++;
+            }
+            if (i == len) {
+                return false;
+            }
+            for (; i < len; i++) {
+                if (!Character.isDigit(sc[i])) {
+                    return false;
+                }
+            }
+        }
+        return i == len;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/valid-sudoku.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/valid-sudoku.md"
new file mode 100644
index 0000000..9d9af46
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/valid-sudoku.md"
@@ -0,0 +1,93 @@
+# 判断数独是否合法
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/valid-sudoku/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 请判定一个数独是否有效。
+
+该数独可能只填充了部分数字，其中缺少的数字用 `.` 表示。
+ ### 样例说明
+ **样例1:**
+
+```plain
+输入:
+["53..7....","6..195...",".98....6.","8...6...3","4..8.3..1","7...2...6",".6....28.","...419..5","....8..79"]
+输出: true
+样例说明: 
+这个数独如下图所示，他是合法的。
+```
+
+![Valid Sudoku](https://lintcode-media.s3.amazonaws.com/problem/valid-sudoku.png "Valid Sudoku")
+
+**样例 2:**
+
+```Input
+输入:
+["53..75...","6..195...",".98....6.","8...6...3","4..8.3..1","7...2...6",".6....28.","...419..5","....8..79"]
+输出: false
+样例说明: 
+这个数独如下图所示。他是不合法的因为他的第一行和第六列有两个5。
+```
+
+![Invaild Sudoku](https://ws3.sinaimg.cn/large/6a8de5f4ly1g0s5st12otj206y06yaa5.jpg)
+ ### 参考代码
+ Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.
+
+The Sudoku board could be partially filled, where empty cells are filled with the character '.'.
+
+
+A partially filled sudoku which is valid.
+
+Note:
+A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.<div><br></div><div>详细题解请见九章微博：<a href="http://weibo.com/3948019741/BukaG6vKY" target="_blank">http://weibo.com/3948019741/BukaG6vKY</a></div>
+```java
+public class Solution {
+    public boolean isValidSudoku(char[][] board) {
+        boolean[] visited = new boolean[9];
+        
+        // row
+        for(int i = 0; i<9; i++){
+            Arrays.fill(visited, false);
+            for(int j = 0; j<9; j++){
+                if(!process(visited, board[i][j]))
+                    return false;
+            }
+        }
+        
+        //col
+        for(int i = 0; i<9; i++){
+            Arrays.fill(visited, false);
+            for(int j = 0; j<9; j++){
+                if(!process(visited, board[j][i]))
+                    return false;
+            }
+        }
+        
+        // sub matrix
+        for(int i = 0; i<9; i+= 3){
+            for(int j = 0; j<9; j+= 3){
+                Arrays.fill(visited, false);
+                for(int k = 0; k<9; k++){
+                    if(!process(visited, board[i + k/3][ j + k%3]))
+                    return false;                   
+                }
+            }
+        }
+        return true;
+        
+    }
+    
+    private boolean process(boolean[] visited, char digit){
+        if(digit == '.'){
+            return true;
+        }
+        
+        int num = digit - '0';
+        if ( num < 1 || num > 9 || visited[num-1]){
+            return false;
+        }
+        
+        visited[num-1] = true;
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/verify-preorder-serialization-of-a-binary-tree.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/verify-preorder-serialization-of-a-binary-tree.md"
new file mode 100644
index 0000000..da85513
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/verify-preorder-serialization-of-a-binary-tree.md"
@@ -0,0 +1,83 @@
+# 验证二叉树的前序序列化
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/verify-preorder-serialization-of-a-binary-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 二叉树序列化的一种方法是使用先序遍历。 当我们遇到非空节点时，我们记录节点的值。如果是一个空节点，我们使用诸如#的标记值。
+~~~~.
+     _9_
+    /   \
+   3     2
+  / \   / \
+ 4   1  #  6
+/ \ / \   / \
+# # # #   # #
+~~~~
+例如，上面的二叉树可以序列化为字符串”9,3,4,#,#,1,#,#,2,#,6,#,#”，其中#表示空节点。
+
+给定一个用逗号分隔的字符串，验证它是否是二叉树序列化正确的前序遍历。 找到一个不需要重建树的算法。
+
+字符串中的每个逗号分隔的值必须是整数或表示空指针的字符“#”。
+
+您可以假设输入格式始终符合要求，例如它永远不能包含两个连续的逗号，例如“1,,3”。
+ ### 样例说明
+ ```
+样例 1:
+	输入:  tree = "#"
+	输出:  true
+	
+	解释:
+	空树是合法的BST。
+	
+样例 2:
+	输入: tree = "9,3,4,#,#,1,#,#,2,#,6,#,#"
+	输出:  true
+
+样例 3:
+	输入: tree = "1,#"
+	输出:  false
+	
+	解释:
+	不是一棵完整的树
+	
+样例 4:
+	输入: tree = "9,#,#,1"
+	输出:  false
+	
+	解释:
+	不是一棵树
+
+```
+
+ ### 参考代码
+ ```java
+public class Solution {
+    public boolean isValidSerialization(String preorder) {
+        String s = preorder;
+        boolean flag = true;
+        while (s.length() > 1) {
+            int index = s.indexOf(",#,#");
+            if (index < 0) {
+                flag = false;
+                break;
+            }
+            int start = index;
+            while (start > 0 && s.charAt(start - 1) != ',')
+            {
+                start --;
+            }
+            if (s.charAt(start) == '#') {
+                flag = false;
+                break;
+            }
+            s = s.substring(0, start) + s.substring(index + 3);
+        }
+        if (s.equals("#") && flag) 
+            return true;
+        else 
+            return false;
+    }
+}
+
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/word-count.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/word-count.md"
new file mode 100644
index 0000000..963dfa5
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/word-count.md"
@@ -0,0 +1,48 @@
+# 单词计数 (Map Reduce版本)
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-count/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 使用 map reduce 来计算单词频率
+https://hadoop.apache.org/docs/r1.2.1/mapred_tutorial.html#Example%3A+WordCount+v1.0
+
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/**
+ * Definition of OutputCollector:
+ * class OutputCollector<K, V> {
+ *     public void collect(K key, V value);
+ *         // Adds a key/value pair to the output buffer
+ * }
+ */
+public class WordCount {
+
+    public static class Map {
+        public void map(String key, String value, OutputCollector<String, Integer> output) {
+            // Write your code here
+            // Output the results into output buffer.
+            // Ps. output.collect(String key, int value);
+            StringTokenizer tokenizer = new StringTokenizer(value);
+            while (tokenizer.hasMoreTokens()) {
+                String word = tokenizer.nextToken();
+                output.collect(word, 1);
+            }
+        }
+    }
+
+    public static class Reduce {
+        public void reduce(String key, Iterator<Integer> values,
+                           OutputCollector<String, Integer> output) {
+            // Write your code here
+            // Output the results into output buffer.
+            // Ps. output.collect(String key, int value);
+            int sum = 0;
+            while (values.hasNext()) {
+                    sum += values.next();
+            }
+            output.collect(key, sum);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/zigzag-conversion.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/zigzag-conversion.md"
new file mode 100644
index 0000000..6d281eb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\205\266\344\273\226/zigzag-conversion.md"
@@ -0,0 +1,89 @@
+# 之字形转换
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/zigzag-conversion/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串 `s` 和一个整数 `numRows`. 你需要把 `s` 排布成一个 `numRows` 行的 "之" 字形. 然后返回逐行阅读的结果.
+
+注意, "之" 字形是按照 下->右上->下->右上...的方向延伸的.
+
+```
+|   /|   /|
+|  / |  / | ...
+| /  | /  | ...
+|/   |/   |/
+```
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "PAYPALISHIRING", numRows = 3
+输出: "PAHNAPLSIIGYIR"
+解释: 
+    转换之后我们会得到
+    P   A   H   N
+    A P L S I I G
+    Y   I   R
+    一行一行地读, 得到答案: "PAHNAPLSIIGYIR".
+```
+
+**样例 2:**
+
+```
+输入: "PAYPALISHIRING", numRows = 4
+输出: "PINALSIGYAHRPI"
+解释: 
+    转换之后我们会得到
+    P     I     N
+    A   L S   I G
+    Y A   H R
+    P     I
+    一行一行地读, 得到答案: "PINALSIGYAHRPI".
+```
+
+**样例 3:**
+
+```
+输入: "PAYPALISHIRING", numRows = 1
+输出: "PAYPALISHIRING"
+解释: 
+    转换之后我们会得到
+    PAYPALISHIRING
+    一行一行地读, 得到答案: "PAYPALISHIRING".
+```
+ ### 参考代码
+ The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
+
+P   A   H   N
+A P L S I I G
+Y   I   R
+And then read line by line: "PAHNAPLSIIGYIR"
+Write the code that will take a string and make this conversion given a number of rows:
+
+string convert(string text, int nRows);
+convert("PAYPALISHIRING", 3) should return "PAHNAPLSIIGYIR".
+```java
+public class Solution {
+    public String convert(String s, int nRows) {
+        int length = s.length();
+        if (length <= nRows || nRows == 1) return s;
+        char[] chars = new char[length];
+        int step = 2 * (nRows - 1);
+        int count = 0;
+	    for (int i = 0; i < nRows; i++){
+    		int interval = step - 2 * i;
+    		for (int j = i; j < length; j += step){
+    		   	chars[count] = s.charAt(j);
+    			count++;
+    			if (interval < step && interval > 0 
+    && j + interval < length && count <  length){
+    				chars[count] = s.charAt(j + interval);
+    				count++;
+    			}
+    		}
+    	}
+        return new String(chars);
+    }
+}
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/fast-power.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/fast-power.md"
new file mode 100644
index 0000000..76c6c15
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/fast-power.md"
@@ -0,0 +1,32 @@
+# 快速幂
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/fast-power/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>计算<b style="color: rgb(113, 113, 113); font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"><font color="#e76363"><i>a<span style="position: relative; font-size: 12px; line-height: 0; vertical-align: baseline; top: -0.5em;">n</span>&nbsp;% b</i></font></b><span style="line-height: 1.42857143;">，</span><span style="line-height: 1.42857143;">其中a，b和n都是32位的非负整数。</span></p>
+ ### 样例说明
+ <p style="font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"><font color="#424242">例如 2<span style="position: relative; font-size: 12px; line-height: 0; vertical-align: baseline; top: -0.5em;">31</span>&nbsp;% 3 = 2</font></p><p style="font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;"><font color="#424242">例如 100<span style="position: relative; font-size: 12px; line-height: 0; vertical-align: baseline; top: -0.5em;">1000</span>&nbsp;% 1000 = 0</font></p>
+ ### 参考代码
+ ```java
+class Solution {
+    /*
+     * @param a, b, n: 32bit integers
+     * @return: An integer
+     */
+    public int fastPower(int a, int b, int n) {
+        if (n == 1) {
+            return a % b;
+        }
+        if (n == 0) {
+            return 1 % b;
+        }
+        
+        long product = fastPower(a, b, n / 2);
+        product = (product * product) % b;
+        if (n % 2 == 1) {
+            product = (product * a) % b;
+        }
+        return (int) product;
+    }
+};
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/kth-smallest-numbers-in-unsorted-array.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/kth-smallest-numbers-in-unsorted-array.md"
new file mode 100644
index 0000000..463c0f7
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/kth-smallest-numbers-in-unsorted-array.md"
@@ -0,0 +1,67 @@
+# 无序数组K小元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-smallest-numbers-in-unsorted-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 找到一个无序数组中第K小的数
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [3, 4, 1, 2, 5], k = 3
+输出: 3
+```
+
+**样例 2:**
+
+```
+输入: [1, 1, 1], k = 2
+输出: 1
+```
+ ### 参考代码
+ Quick Select 快速选择算法的模板题. 与快速排序过程相似.
+
+维基百科: <https://zh.wikipedia.org/wiki/%E5%BF%AB%E9%80%9F%E9%80%89%E6%8B%A9>
+```java
+class Solution {
+    /*
+     * @param k an integer
+     * @param nums an integer array
+     * @return kth smallest element
+     */
+    public int kthSmallest(int k, int[] nums) {
+        return quickSelect(nums, 0, nums.length - 1, k - 1);
+    }
+
+    public int quickSelect(int[] A, int start, int end , int k) {
+        if (start == end)
+            return A[start];
+        
+        int left = start, right = end;
+        int pivot = A[(start + end) / 2];
+
+        while (left <= right) {
+            while (left <= right && A[left] < pivot) {
+                left++;
+            }
+            while (left <= right && A[right] > pivot) {
+                right--;
+            }
+            if (left <= right) {
+                int temp = A[left];
+                A[left] = A[right];
+                A[right] = temp;
+                
+                left++;
+                right--;
+            }
+        }
+
+        if (right >= k && start <= right)
+            return quickSelect(A, start, right, k);
+        else if (left <= k && left <= end)
+            return quickSelect(A, left, end, k);
+        else
+            return A[k];
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/nuts-bolts-problem.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/nuts-bolts-problem.md"
new file mode 100644
index 0000000..95910c4
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/nuts-bolts-problem.md"
@@ -0,0 +1,83 @@
+# Nuts 和 Bolts 的问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/nuts-bolts-problem/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一组 n 个不同大小的 nuts 和 n 个不同大小的 bolts. nuts 和 bolts 一一匹配. 
+
+不允许将 nut 之间互相比较, 也不允许将 bolt 之间互相比较. 也就是说, 只许将 nut 与 bolt 进行比较,  或将 bolt 与 nut 进行比较. 我们会提供一个比较函数, 用于nut和bolt的比较.
+
+利用我们提供的函数, 你需要将 nuts 或者 bolts 重新排列, 使得它们按照顺序一一匹配.
+
+
+ ### 样例说明
+ 给出 nuts = `['ab','bc','dd','gg']`, bolts = `['AB','GG', 'DD', 'BC']`
+
+你的程序应该找出bolts和nuts的匹配.
+
+根据比较函数, 一组可能的返回结果是：
+
+nuts = `['ab','bc','dd','gg']`, bolts = `['AB','BC','DD','GG']`
+
+如果我们给你另外的比较函数，可能返回的结果是：
+
+nuts = `['ab','bc','dd','gg'], bolts = ['BC','AB','DD','GG']`
+
+因此的结果完全取决于比较函数，而不是字符串本身。因为你必须使用比较函数来进行排序。
+
+各自的排序当中nuts和bolts的顺序是无关紧要的，只要他们一一匹配就可以。
+
+
+ ### 参考代码
+ 基于标准 Partition 模板算法。
+```python
+"""
+class Comparator:
+    def cmp(self, a, b)
+You can use Compare.cmp(a, b) to compare nuts "a" and bolts "b",
+if "a" is bigger than "b", it will return 1, else if they are equal,
+it will return 0, else if "a" is smaller than "b", it will return -1.
+When "a" is not a nut or "b" is not a bolt, it will return 2, which is not valid.
+"""
+
+
+class Solution:
+    # @param nuts: a list of integers
+    # @param bolts: a list of integers
+    # @param compare: a instance of Comparator
+    # @return: nothing
+    def sortNutsAndBolts(self, nuts, bolts, compare):
+        self.quick_sort(nuts, bolts, 0, len(nuts) - 1, compare.cmp)
+        
+    def quick_sort(self, nuts, bolts, start, end, cmp):
+        if start >= end:
+            return
+        
+        left, right = start, end
+        
+        index = self.partition(bolts, left, right, nuts[(left + right) // 2], cmp)
+        self.partition(nuts, left, right, bolts[index], cmp)
+        
+        self.quick_sort(nuts, bolts, start, index - 1, cmp)
+        self.quick_sort(nuts, bolts, index + 1, end, cmp)
+        
+    def partition(self, arr, start, end, pivot, cmp):
+        left, right = start, end
+        
+        for i in range(left, right + 1):
+            if cmp(arr[i], pivot) == 0 or cmp(pivot, arr[i]) == 0:
+                arr[i], arr[left] = arr[left], arr[i]
+                left += 1
+                break
+            
+        while left <= right:
+            while left <= right and (cmp(arr[left], pivot) == -1 or cmp(pivot, arr[left]) == 1):
+                left += 1
+            while left <= right and (cmp(arr[right], pivot) == 1 or cmp(pivot, arr[right]) == -1):
+                right -= 1
+            if left <= right:
+                arr[left], arr[right] = arr[right], arr[left]
+                left, right = left + 1, right - 1
+        
+        arr[start], arr[right] = arr[right], arr[start]
+        return right
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/sort-colors-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/sort-colors-ii.md"
new file mode 100644
index 0000000..8b6eb8c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/sort-colors-ii.md"
@@ -0,0 +1,80 @@
+# 排颜色 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sort-colors-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个有n个对象（包括k种不同的颜色，并按照1到k进行编号）的数组，将对象进行分类使相同颜色的对象相邻，并按照1,2，...k的顺序进行排序。
+ ### 样例说明
+ **样例1**
+
+```
+输入: 
+[3,2,2,1,4] 
+4
+输出: 
+[1,2,2,3,4]
+```
+
+**样例2**
+
+```
+输入: 
+[2,1,1,2,2] 
+2
+输出: 
+[1,1,2,2,2]
+```
+
+ ### 参考代码
+ 采用分治法
+```java
+// version 1: O(nlogk), the best algorithm based on comparing
+class Solution {
+    /**
+     * @param colors: A list of integer
+     * @param k: An integer
+     * @return: nothing
+     */
+    public void sortColors2(int[] colors, int k) {
+        if (colors == null || colors.length == 0) {
+            return;
+        }
+        rainbowSort(colors, 0, colors.length - 1, 1, k);
+    }
+    
+    public void rainbowSort(int[] colors,
+                            int left,
+                            int right,
+                            int colorFrom,
+                            int colorTo) {
+        if (colorFrom == colorTo) {
+            return;
+        }
+        
+        if (left >= right) {
+            return;
+        }
+        
+        int colorMid = (colorFrom + colorTo) / 2;
+        int l = left, r = right;
+        while (l <= r) {
+            while (l <= r && colors[l] <= colorMid) {
+                l++;
+            }
+            while (l <= r && colors[r] > colorMid) {
+                r--;
+            }
+            if (l <= r) {
+                int temp = colors[l];
+                colors[l] = colors[r];
+                colors[r] = temp;
+                
+                l++;
+                r--;
+            }
+        }
+        
+        rainbowSort(colors, left, r, colorFrom, colorMid);
+        rainbowSort(colors, l, right, colorMid + 1, colorTo);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/subtree-with-maximum-average.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/subtree-with-maximum-average.md"
new file mode 100644
index 0000000..b77dad9
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/subtree-with-maximum-average.md"
@@ -0,0 +1,84 @@
+# 具有最大平均数的子树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/subtree-with-maximum-average/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一棵二叉树，找到有最大平均值的子树。返回子树的根结点。
+ ### 样例说明
+ **样例1**
+
+```
+输入：
+{1,-5,11,1,2,4,-2}
+输出：11
+说明:
+这棵树如下所示：
+     1
+   /   \
+ -5     11
+ / \   /  \
+1   2 4    -2 
+11子树的平均值是4.333，为最大的。
+```
+
+**样例2**
+
+```
+输入：
+{1,-5,11}
+输出：11
+说明:
+     1
+   /   \
+ -5     11
+1,-5,11 三棵子树的平均值分别是 2.333,-5,11。因此11才是最大的
+```
+ ### 参考代码
+ 因为需要求平均数，所以要记录节点和以及接节点个数
+自定义一个ResultType，记录节点和以及接节点个数
+分治法计算每一颗子树的平均值，打擂台求出最大平均数的子树
+```java
+// version 1: Traverse + Divide Conquer
+public class Solution {
+    private class ResultType {
+        public int sum, size;
+        public ResultType(int sum, int size) {
+            this.sum = sum;
+            this.size = size;
+        }
+    }
+    
+    private TreeNode subtree = null;
+    private ResultType subtreeResult = null;
+    
+    /**
+     * @param root the root of binary tree
+     * @return the root of the maximum average of subtree
+     */
+    public TreeNode findSubtree2(TreeNode root) {
+        helper(root);
+        return subtree;
+    }
+    
+    private ResultType helper(TreeNode root) {
+        if (root == null) {
+            return new ResultType(0, 0);
+        }
+        // 分治法计算左右子树的平均值
+        ResultType left = helper(root.left);
+        ResultType right = helper(root.right);
+        // 当前subtree的结果是左右两颗子树的和的平均值加上自身
+        ResultType result = new ResultType(
+            left.sum + right.sum + root.val,
+            left.size + right.size + 1
+        );
+        // 打擂台比较得到最大平均值的子树
+        if (subtree == null ||
+            subtreeResult.sum * result.size < result.sum * subtreeResult.size
+        ) {
+            subtree = root;
+            subtreeResult = result;
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/symmetric-tree.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/symmetric-tree.md"
new file mode 100644
index 0000000..e549318
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/symmetric-tree.md"
@@ -0,0 +1,397 @@
+# 对称树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/symmetric-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定二叉树，返回它是否是自身的镜像（即这棵二叉树是否对称）。
+ ### 样例说明
+ **样例1**
+
+```
+输入: {1,2,2,3,4,4,3}
+输出: true
+解释:
+    1
+   / \
+  2   2
+ / \ / \
+3  4 4  3
+{1,2,2,3,4,4,3}这棵二叉树是对称的
+```
+
+**样例2**
+
+```
+输入: {1,2,2,#,3,#,3}
+输出: false
+解释:
+    1
+   / \
+  2   2
+   \   \
+   3    3
+很显然这棵二叉树并不对称
+```
+
+ ### 参考代码
+ 使用分治法 Divide Conquer 的版本
+
+```
+[[python]]
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param root: root of the given tree
+    @return: whether it is a mirror of itself 
+    """
+    def isSymmetric(self, root):
+        if not root:
+            return True
+        return self._is_symmetric(root.left, root.right)
+        
+    def _is_symmetric(self, left_root, right_root):
+        if left_root is None and right_root is None:
+            return True
+        if left_root is None or right_root is None:
+            return False
+        if left_root.val != right_root.val:
+            return False
+            
+        left = self._is_symmetric(left_root.left, right_root.right)
+        right = self._is_symmetric(left_root.right, right_root.left)
+        return left and right
+
+[[java]]
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+
+public class Solution {
+    /**
+     * @param root: root of the given tree
+     * @return: whether it is a mirror of itself 
+     */
+    public boolean isSymmetric(TreeNode root) {
+        // Write your code here
+        if (root == null) {
+            return true;
+        }
+        
+        return isSymmetric(root.left, root.right);
+    }
+    
+    private boolean isSymmetric(TreeNode leftRoot, TreeNode rightRoot) {
+        if (leftRoot == null && rightRoot == null) {
+            return true;
+        }
+        if (leftRoot == null || rightRoot == null) {
+            return false;
+        }
+        if (leftRoot.val != rightRoot.val) {
+            return false;
+        }
+        
+        boolean left = isSymmetric(leftRoot.left, rightRoot.right);
+        boolean right = isSymmetric(leftRoot.right, rightRoot.left);
+        
+        return left && right;
+    }
+}
+```
+
+使用Iteration的版本
+```
+[[python]]
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param root: root of the given tree
+    @return: whether it is a mirror of itself 
+    """
+    
+    def isSymmetric(self, root):
+        inorder = self.inorder(root, reverse=False)
+        reverse_inorder = self.inorder(root, reverse=True)
+        if inorder != reverse_inorder:
+            return False
+            
+        preorder = self.preorder(root, reverse=False)
+        reverse_preorder = self.preorder(root, reverse=True)
+        return preorder == reverse_preorder
+        
+    def get_left(self, node, reverse):
+        if reverse:
+            return node.right
+        return node.left
+        
+    def get_right(self, node, reverse):
+        if reverse:
+            return node.left
+        return node.right
+        
+    def preorder(self, root, reverse):
+        stack = [root]
+        order = []
+        while stack:
+            node = stack.pop()
+            order.append(node.val)
+            right = self.get_right(node, reverse)
+            if right:
+                stack.append(right)
+            left = self.get_left(node, reverse)
+            if left:
+                stack.append(left)
+        return order
+        
+    def inorder(self, root, reverse):
+        stack = []
+        while root is not None:
+            stack.append(root)
+            root = self.get_left(root, reverse)
+            
+        order = []
+        while stack:
+            node = stack[-1]
+            order.append(node.val)
+            right = self.get_right(node, reverse)
+            if right is not None:
+                node = right
+                while node is not None:
+                    stack.append(node)
+                    node = self.get_left(node, reverse)
+            else:
+                stack.pop()
+                while stack and self.get_right(stack[-1], reverse) == node:
+                    node = stack.pop()
+        
+        return order
+[[java]]
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+
+public class Solution {
+    /**
+     * @param root: root of the given tree
+     * @return: whether it is a mirror of itself 
+     */
+    public boolean isSymmetric(TreeNode root) {
+        if (root == null) {
+            return true;
+        }
+        
+        List<Integer> inorder = inorder(root, false);
+        List<Integer> reverseInorder = inorder(root, true);
+        for (int i = 0; i < inorder.size(); i++) {
+            if (inorder.get(i) != reverseInorder.get(i)) {
+                return false;
+            }
+        }
+        
+        List<Integer> preorder = this.preorder(root, false);
+        List<Integer> reversePreorder = this.preorder(root, true);
+        for (int i = 0; i < preorder.size(); i++) {
+            if (preorder.get(i) != reversePreorder.get(i)) {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+    
+    private TreeNode getLeft(TreeNode node, boolean reverse) {
+        if (reverse) {
+            return node.right;
+        }
+        return node.left;
+    }
+    
+    private TreeNode getRight(TreeNode node, boolean reverse) {
+        if (reverse) {
+            return node.left;
+        }
+        return node.right;
+    }
+    
+    private List<Integer> preorder(TreeNode root, boolean reverse) {
+        Stack<TreeNode> stack = new Stack<>();
+        List<Integer> order = new ArrayList<>();
+        stack.push(root);
+        
+        while (!stack.isEmpty()) {
+            TreeNode node = stack.pop();
+            order.add(node.val);
+            TreeNode right = getRight(node, reverse);
+            if (right != null) {
+                stack.push(right);
+            }
+            TreeNode left = getLeft(node, reverse);
+            if (left != null) {
+                stack.push(left);
+            }
+        }
+        
+        return order;
+    }
+    
+    private List<Integer> inorder(TreeNode root, boolean reverse) {
+        Stack<TreeNode> stack = new Stack<>();
+        List<Integer> order = new ArrayList<>();
+        
+        while (root != null) {
+            stack.push(root);
+            root = getLeft(root, reverse);
+        }
+        
+        while (!stack.isEmpty()) {
+            TreeNode node = stack.peek();
+            order.add(node.val);
+            TreeNode right = getRight(node, reverse);
+            if (right != null) {
+                node = right;
+                while (node != null) {
+                    stack.push(node);
+                    node = getLeft(node, reverse);
+                }
+            } else {
+                stack.pop();
+                while (!stack.isEmpty() && getRight(stack.peek(), reverse) == node) {
+                    node = stack.pop();
+                }
+            }
+        }
+        
+        return order;
+    }
+}
+```
+
+使用 BFS 算法的版本
+```
+[[python]]
+"""
+Definition of TreeNode:
+class TreeNode:
+    def __init__(self, val):
+        self.val = val
+        self.left, self.right = None, None
+"""
+
+class Solution:
+    """
+    @param root: root of the given tree
+    @return: whether it is a mirror of itself 
+    """
+    def isSymmetric(self, root):
+        queue = [root]
+        while queue:
+            next_queue = []
+            for i in range(len(queue)):
+                if queue[i] is None:
+                    continue
+                next_queue.append(queue[i].left)
+                next_queue.append(queue[i].right)
+            if not self.is_mirror(next_queue):
+                return False
+            queue = next_queue
+        return True
+        
+    def is_mirror(self, queue):
+        left, right = 0, len(queue) - 1
+        while left < right:
+            if not self.is_same(queue[left], queue[right]):
+                return False
+            left, right = left + 1, right - 1
+        return True
+        
+    def is_same(self, node1, node2):
+        if node1 and node2:
+            return node1.val == node2.val
+        return node1 is None and node2 is None
+[[java]]
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+
+public class Solution {
+    /**
+     * @param root: root of the given tree
+     * @return: whether it is a mirror of itself 
+     */
+    public boolean isSymmetric(TreeNode root) {
+        List<TreeNode> queue = new ArrayList<>();
+        queue.add(root);
+        while (!queue.isEmpty()) {
+            List<TreeNode> nextQueue = new ArrayList<>();
+            for (int i = 0; i < queue.size(); i++) {
+                if (queue.get(i) == null) {
+                    continue;
+                }
+                nextQueue.add(queue.get(i).left);
+                nextQueue.add(queue.get(i).right);
+            }
+            if (!isMirror(nextQueue)) {
+                return false;
+            }
+            queue = nextQueue;
+        }
+        return true;
+    }
+    
+    private boolean isMirror(List<TreeNode> queue) {
+        int left = 0, right = queue.size() - 1;
+        while (left < right) {
+            if (!isSame(queue.get(left), queue.get(right))) {
+                return false;
+            }
+            left++;
+            right--;
+        }
+        return true;
+    }
+    
+    private boolean isSame(TreeNode node1, TreeNode node2) {
+        if (node1 != null && node2 != null) {
+            return node1.val == node2.val;
+        }
+        return node1 == null && node2 == null;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/validate-binary-search-tree.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/validate-binary-search-tree.md"
new file mode 100644
index 0000000..3546e63
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\210\206\346\262\273\346\263\225/validate-binary-search-tree.md"
@@ -0,0 +1,98 @@
+# 验证二叉查找树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/validate-binary-search-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个二叉树，判断它是否是合法的二叉查找树(BST)
+
+一棵BST定义为：
+
+* 节点的左子树中的值要**严格**小于该节点的值。
+* 节点的右子树中的值要**严格**大于该节点的值。
+* 左右子树也必须是二叉查找树。
+* 一个节点的树也是二叉查找树。
+ ### 样例说明
+ **样例 1:**
+```
+输入：{-1}
+输出：true
+解释：
+二叉树如下(仅有一个节点）:
+	-1
+这是二叉查找树。
+```	
+
+**样例 2:**
+```
+输入：{2,1,4,#,#,3,5}
+输出：true
+解释：
+	二叉树如下：
+	  2
+	 / \
+	1   4
+	   / \
+	  3   5
+这是二叉查找树。
+```
+ ### 参考代码
+ 分治法，但是 minValue 和 maxValue 用 minNode 和 maxNode 来代替。
+```java
+/**
+ * Definition of TreeNode:
+ * public class TreeNode {
+ *     public int val;
+ *     public TreeNode left, right;
+ *     public TreeNode(int val) {
+ *         this.val = val;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+
+class ResultType {
+    public boolean isBST;
+    public TreeNode maxNode, minNode;
+    public ResultType(boolean isBST) {
+        this.isBST = isBST;
+        this.maxNode = null;
+        this.minNode = null;
+    }
+}
+
+public class Solution {
+    /**
+     * @param root: The root of binary tree.
+     * @return: True if the binary tree is BST, or false
+     */
+    public boolean isValidBST(TreeNode root) {
+        return divideConquer(root).isBST;
+    }
+    
+    private ResultType divideConquer(TreeNode root) {
+        if (root == null) {
+            return new ResultType(true);
+        }
+        
+        ResultType left = divideConquer(root.left);
+        ResultType right = divideConquer(root.right);
+        if (!left.isBST || !right.isBST) {
+            return new ResultType(false);
+        }
+        
+        if (left.maxNode != null && left.maxNode.val >= root.val) {
+            return new ResultType(false);
+        }
+        
+        if (right.minNode != null && right.minNode.val <= root.val) {
+            return new ResultType(false);
+        }
+        
+        // is bst
+        ResultType result = new ResultType(true);
+        result.minNode = left.minNode != null ? left.minNode : root;
+        result.maxNode = right.maxNode != null ? right.maxNode : root;
+        
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/3sum-closest.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/3sum-closest.md"
new file mode 100644
index 0000000..f5107dc
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/3sum-closest.md"
@@ -0,0 +1,48 @@
+# 最接近的三数之和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/3sum-closest/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个包含 *n* 个整数的数组 *S*, 找到和与给定整数 *target* 最接近的三元组，返回这三个数的和。
+ ### 样例说明
+ 例1:
+```
+输入:[2,7,11,15],3
+输出:20
+解释:
+2+7+11=20
+```
+
+例2:
+```
+输入:[-1,2,1,-4],1
+输出:2
+解释:
+-1+2+1=2
+```
+
+ ### 参考代码
+ 排序后。
+固定一个点，利用双指针的方式，扫描，记录答案即可。
+```python
+class Solution:
+    """
+    @param numbers: Give an array numbers of n integer
+    @param target: An integer
+    @return: return the sum of the three integers, the sum closest target.
+    """
+    def threeSumClosest(self, numbers, target):
+        numbers.sort()
+        ans = None
+        for i in range(len(numbers)):
+            left, right = i + 1, len(numbers) - 1
+            while left < right:
+                sum = numbers[left] + numbers[right] + numbers[i]
+                if ans is None or abs(sum - target) < abs(ans - target):
+                    ans = sum
+                    
+                if sum <= target:
+                    left += 1
+                else:
+                    right -= 1
+        return ans
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/3sum.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/3sum.md"
new file mode 100644
index 0000000..ea33fc5
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/3sum.md"
@@ -0,0 +1,167 @@
+# 三数之和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/3sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 30px;">给出一个有n个整数的数组S，在S中找到三个整数a, b, c，找到所有使得a + b + c = 0的三元组。</span><br></p>
+ ### 样例说明
+ **例1:**
+```
+输入:[2,7,11,15]
+输出:[]
+```
+
+
+**例2:**
+```
+输入:[-1,0,1,2,-1,-4]
+输出:[[-1, 0, 1],[-1, -1, 2]]
+```
+
+
+ ### 参考代码
+ 暴力枚举三个数复杂度为O(N^3)
+先考虑2Sum的做法，假设升序数列a，对于一组解ai,aj, 另一组解ak,al
+必然满足 i<k j>l 或 i>k j<l, 因此我们可以用两个指针，初始时指向数列两端
+指向数之和大于目标值时，右指针向左移使得总和减小，反之左指针向右移
+由此可以用 O(N)O(N) 的复杂度解决2Sum问题，3Sum则枚举第一个数 O(N^2)O(N 
+2
+ )
+使用有序数列的好处是，在枚举和移动指针时值相等的数可以跳过，省去去重部分
+```java
+public class Solution {
+    /**
+     * @param nums : Give an array numbers of n integer
+     * @return : Find all unique triplets in the array which gives the sum of zero.
+     */
+    public List<List<Integer>> threeSum(int[] nums) {
+        List<List<Integer>> results = new ArrayList<>();
+        
+        if (nums == null || nums.length < 3) {
+            return results;
+        }
+        
+        Arrays.sort(nums);
+
+        for (int i = 0; i < nums.length - 2; i++) {
+            // skip duplicate triples with the same first numebr
+            if (i > 0 && nums[i] == nums[i - 1]) {
+                continue;
+            }
+
+            int left = i + 1, right = nums.length - 1;
+            int target = -nums[i];
+            
+            twoSum(nums, left, right, target, results);
+        }
+        
+        return results;
+    }
+    
+    public void twoSum(int[] nums,
+                       int left,
+                       int right,
+                       int target,
+                       List<List<Integer>> results) {
+        while (left < right) {
+            if (nums[left] + nums[right] == target) {
+                ArrayList<Integer> triple = new ArrayList<>();
+                triple.add(-target);
+                triple.add(nums[left]);
+                triple.add(nums[right]);
+                results.add(triple);
+                
+                left++;
+                right--;
+                // skip duplicate pairs with the same left
+                while (left < right && nums[left] == nums[left - 1]) {
+                    left++;
+                }
+                // skip duplicate pairs with the same right
+                while (left < right && nums[right] == nums[right + 1]) {
+                    right--;
+                }
+            } else if (nums[left] + nums[right] < target) {
+                left++;
+            } else {
+                right--;
+            }
+        }
+    }
+}
+
+// 九章硅谷求职算法集训营版本
+public class Solution {
+    /**
+     * @param nums : Give an array numbers of n integer
+     * @return : Find all unique triplets in the array which gives the sum of zero.
+     */
+    List<List<Integer>> results = new ArrayList<>();
+    
+    // This is soring results using 1st number as 1st key, 2nd number as 2nd key...
+    class ListComparator<T extends Comparable<T>> implements Comparator<List<Integer>> {
+      @Override
+      public int compare(List<Integer> a, List<Integer> b) {
+        for (int i = 0; i < Math.min(a.size(), b.size()); i++) {
+          int c = a.get(i).compareTo(b.get(i));
+          if (c != 0) {
+            return c;
+          }
+        }
+        return Integer.compare(a.size(), b.size());
+      }
+    }
+    
+    public List<List<Integer>> threeSum(int[] A) {
+        if (A == null || A.length < 3) {
+            return results;
+        }
+        
+        Arrays.sort(A);
+        // enumerate c, the maximum element
+        int i;
+        int n = A.length;
+        for (i = 2; i < n; ++i) {
+            // c is always the last in a bunch of duplicates
+            if (i + 1 < n && A[i + 1] == A[i]) {
+                continue;
+            }
+            
+            // want to find all pairs of A[j]+A[k]=-A[i], such that
+            // j < k < i
+            twoSum(A, i - 1, -A[i]);
+        }
+        
+        Collections.sort(results, new ListComparator<>());
+        
+        return results;
+    }
+    
+    // find all unique pairs such that A[i]+A[j]=S, and i < j <= right
+    private void twoSum(int[] A, int right, int S) {
+        int i, j;
+        j = right;
+        for (i = 0; i <= right; ++i) {
+            // A[i] must be the first in its duplicates
+            if (i > 0 && A[i] == A[i - 1]) {
+                continue;
+            }
+            
+            while (j > i && A[j] > S - A[i]) {
+                --j;
+            }
+            
+            if (i >= j) {
+                break;
+            }
+            
+            if (A[i] + A[j] == S) {
+                List<Integer> t = new ArrayList<>();
+                t.add(A[i]);
+                t.add(A[j]);
+                t.add(-S); // t.add(A[right+1])
+                results.add(t);
+            }
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/4sum-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/4sum-ii.md"
new file mode 100644
index 0000000..84c1627
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/4sum-ii.md"
@@ -0,0 +1,88 @@
+# 4数和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/4sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出 A, B, C, D 四个整数列表，计算有多少的tuple `(i, j, k, l)`满足`A[i] + B[j] + C[k] + D[l]`为 0。
+
+为了简化问题，A, B, C, D 具有相同的长度，且长度N满足 0 ≤ N ≤ 500。所有的整数都在范围(-2^28, 2^28 - 1)内以及保证结果最多为2^31 - 1。
+ ### 样例说明
+ 例1:
+```
+输入:
+A = [ 1, 2]
+B = [-2,-1]
+C = [-1, 2]
+D = [ 0, 2]
+
+输出:
+2
+
+解释:
+这两个tuple为:
+1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0
+2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
+```
+例2:
+```
+输入:
+A = [0]
+B = [0]
+C = [0]
+D = [0]
+
+输出:
+1
+```
+
+ ### 参考代码
+ 时间复杂度和空间复杂度均为 $O(N^2)$
+将 a,b 组成的和及其组成方案个数统计在hash里，然后再去枚举 c,d 的组合，然后找 -(c+d) 在 hash 里的组合数。
+```
+[[python]]
+class Solution:
+    """
+    @param A: a list
+    @param B: a list
+    @param C: a list
+    @param D: a list
+    @return: how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero
+    """
+    def fourSumCount(self, A, B, C, D):
+        counter = {}
+        for a in A:
+            for b in B:
+                counter[a + b] = counter.get(a + b, 0) + 1
+        answer = 0
+        for c in C:
+            for d in D:
+                answer += counter.get(-c - d, 0)
+        return answer
+[[java]]
+public class Solution {
+    /**
+     * @param A: a list
+     * @param B: a list
+     * @param C: a list
+     * @param D: a list
+     * @return: how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero
+     */
+    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
+        Map<Integer, Integer> counter = new HashMap<>();
+        for (int i = 0; i < A.length; i++) {
+            for (int j = 0; j < B.length; j++) {
+                int sum = A[i] + B[j];
+                counter.put(sum, counter.getOrDefault(sum, 0) + 1);
+            }
+        }
+        
+        int answer = 0;
+        for (int i = 0; i < C.length; i++) {
+            for (int j = 0; j < D.length; j++) {
+                int sum = C[i] + D[j];
+                answer += counter.getOrDefault(-sum, 0);
+            }
+        }
+        return answer;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/4sum.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/4sum.md"
new file mode 100644
index 0000000..18a5b58
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/4sum.md"
@@ -0,0 +1,72 @@
+# 四数之和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/4sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 30px;">给一个包含n个数的整数数组S，在S中找到所有使得和为给定整数target的四元组(a, b, c, d)。</span></p>
+ ### 样例说明
+ 例1:
+```
+输入:[2,7,11,15],3
+输出:[]
+
+```
+
+例2:
+```
+输入:[1,0,-1,0,-2,2],0
+输出:
+[[-1, 0, 0, 1]
+,[-2, -1, 1, 2]
+,[-2, 0, 0, 2]]
+```
+
+
+ ### 参考代码
+ 固定两个点，然后用双指针的做法，扫描一下后续数组，记录答案即可。
+```java
+public class Solution {
+	public List<List<Integer>> fourSum(int[] num, int target) {
+		List<List<Integer>> rst = new ArrayList<List<Integer>>();
+		Arrays.sort(num);
+
+		for (int i = 0; i < num.length - 3; i++) {
+			if (i != 0 && num[i] == num[i - 1]) {
+				continue;
+			}
+
+			for (int j = i + 1; j < num.length - 2; j++) {
+				if (j != i + 1 && num[j] == num[j - 1])
+					continue;
+
+				int left = j + 1;
+				int right = num.length - 1;
+				while (left < right) {
+					int sum = num[i] + num[j] + num[left] + num[right];
+					if (sum < target) {
+						left++;
+					} else if (sum > target) {
+						right--;
+					} else {
+						ArrayList<Integer> tmp = new ArrayList<Integer>();
+						tmp.add(num[i]);
+						tmp.add(num[j]);
+						tmp.add(num[left]);
+						tmp.add(num[right]);
+						rst.add(tmp);
+						left++;
+						right--;
+						while (left < right && num[left] == num[left - 1]) {
+							left++;
+						}
+						while (left < right && num[right] == num[right + 1]) {
+							right--;
+						}
+					}
+				}
+			}
+		}
+
+		return rst;
+	}
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/container-with-most-water.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/container-with-most-water.md"
new file mode 100644
index 0000000..971ed60
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/container-with-most-water.md"
@@ -0,0 +1,88 @@
+# 装最多水的容器
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/container-with-most-water/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定 *n* 个非负整数 a<sub>1</sub>, a<sub>2</sub>, ..., a<sub>n</sub>, 每个数代表了坐标中的一个点 `(i, ai)`。画 *n* 条垂直线，使得 *i* 垂直线的两个端点分别为`(i, ai)`和`(i, 0)`。找到两条线，使得其与 *x* 轴共同构成一个容器，以容纳最多水。
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [1, 3, 2]
+输出: 2
+解释:
+选择 a1, a2, 容量为 1 * 1 = 1
+选择 a1, a3, 容量为 1 * 2 = 2
+选择 a2, a3, 容量为 2 * 1 = 2
+```
+
+**样例 2:**
+
+```
+输入: [1, 3, 2, 2]
+输出: 4
+解释:
+选择 a1, a2, 容量为 1 * 1 = 1
+选择 a1, a3, 容量为 1 * 2 = 2
+选择 a1, a4, 容量为 1 * 3 = 3
+选择 a2, a3, 容量为 2 * 1 = 2
+选择 a2, a4, 容量为 2 * 2 = 4
+选择 a3, a4, 容量为 2 * 1 = 2
+```
+
+ ### 参考代码
+ 题意: 给定一个非负整数数组, 选取i, j使得 $|i-j| \times min(a[i], a[j])| 最大
+
+设定两个指针, 初始在两端, 计算这两个组成的容量, 然后移动值较小的那个, 所有计算结果取最大.
+
+可以反证法证明这样可以得到最优答案
+```java
+public class Solution {
+    /**
+     * @param heights: an array of integers
+     * @return: an integer
+     */
+    int computeArea(int left, int right,  int[] heights) {
+        return (right-left)*Math.min(heights[left], heights[right]);
+    }
+    
+    public int maxArea(int[] heights) {
+        // write your code here
+        int left = 0, ans=  0 ; 
+        int right = heights.length - 1;
+        while (left <= right) {
+            ans = Math.max(ans,computeArea(left, right, heights));
+            if (heights[left]<=heights[right])
+                left++;
+            else
+                right--;
+        }
+        return ans;
+    }
+}
+
+--------------------------------------
+
+
+public class Solution {
+    // for any i, the maxium area will be the farthest j that has a[j] > a[i];
+    public int maxArea(int[] height) {
+        if (height == null || height.length < 2) {
+            return 0;
+        }
+        int max = 0;
+        int left = 0;
+        int right = height.length -1;
+        while (left < right) {
+            max = Math.max( max, (right - left) * Math.min(height[left], height[right]));
+            if (height[left] < height[right]){
+                left++;
+            } else {
+                right--;
+            }
+        }
+        return max;
+        
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/continuous-subarray-sum-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/continuous-subarray-sum-ii.md"
new file mode 100644
index 0000000..a71b61d
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/continuous-subarray-sum-ii.md"
@@ -0,0 +1,64 @@
+# 连续子数组求和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/continuous-subarray-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数循环数组（头尾相接），请找出一个连续的子数组，使得该子数组的和最大。输出答案时，请分别返回第一个数字和最后一个数字的值。
+
+如果多个答案，请返回其中任意一个。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [3, 1, -100, -3, 4]
+输出: [4, 1]
+```
+
+**样例 2:**
+
+```
+输入: [1,-1]
+输出: [0, 0]
+```
+ ### 参考代码
+ 分两种情况讨论：
+
+1. 最大数组仍然是中间的某一段
+2. 最大数组是去掉了中间的一段之后剩下的部分
+
+第一种情况用传统的最大子数组做法走一遍(参考[题解](https://www.jiuzhang.com/solution/continuous-subarray-sum))。第二种做法稍微想一下就可以证明中间被去掉的那一段是整个数组的 minimum subarray。
+所以求一遍 minimum subarray 之后，比较两种情况, 取最优解即可
+
+需要特殊考虑 minimum subarray 是取了所有数的情况。
+```python
+class Solution:
+    """
+    @param: A: An integer array
+    @return: A list of integers includes the index of the first number and the index of the last number
+    """
+    def continuousSubarraySumII(self, A):
+        max_start, max_end, max_sum = self.find_maximum_subarray(A)
+        min_start, min_end, min_sum = self.find_maximum_subarray([-a for a in A])
+        min_sum = -min_sum  # *-1 after reuse find maximum array
+        
+        total = sum(A)
+        if max_sum >= total - min_sum or min_end - min_start + 1 == len(A):
+            return [max_start, max_end]
+        
+        return [min_end + 1, min_start - 1]
+        
+    def find_maximum_subarray(self, nums):
+        max_sum = -sys.maxsize
+        curt_sum, start = 0, 0
+        max_range = []
+        
+        for index, num in enumerate(nums):
+            if curt_sum < 0:
+                curt_sum = 0
+                start = index
+            curt_sum += num
+            if curt_sum > max_sum:
+                max_sum = curt_sum
+                max_range = [start, index]
+                
+        return max_range[0], max_range[1], max_sum
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/find-the-duplicate-number.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/find-the-duplicate-number.md"
new file mode 100644
index 0000000..3e7f946
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/find-the-duplicate-number.md"
@@ -0,0 +1,83 @@
+# 寻找重复的数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-the-duplicate-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个数组 `nums` 包含 `n + 1` 个整数，每个整数是从 `1` 到 `n` (包括边界)，保证至少存在一个重复的整数。假设只有一个重复的整数，找出这个重复的数。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+[5,5,4,3,2,1]
+输出:
+5
+```
+
+**样例 2:**
+```
+输入:
+[5,4,4,3,2,1]
+输出:
+4
+```
+ ### 参考代码
+ 九章算法强化班中讲过的基于值的二分法。
+这个题比较好的理解方法是画一个坐标轴：
+
+- x轴是 0, 1, 2, ... n。
+- y轴是对应的 <=x 的数的个数，比如 <=0 的数的个数是0，就在（0,0）这个坐标画一个点。<=n 的数的个数是 n+1 个，就在 (n,n+1)画一个点。
+
+把所有的点连接起来之后，是一个类似下图的折线：
+
+![图片](https://media-cdn.jiuzhang.com/markdown/images/8/13/f2b4a1d0-9ecb-11e8-b810-0242ac110002.jpg)
+
+我们可以知道这个折线图的有如下的一些属性：
+
+1. 大部分时候，我们会沿着斜率为 1 的那条虚线前进
+2. 如果出现了一些空缺的数，就会有横向的折线
+3. 一旦出现了重复的数，就会出现一段斜率超过 1 的折线
+4. 斜率超过 1 的折线只会出现一次
+
+试想一下，对比 y=x 这条虚线，当折线冒过了这条虚线出现在这条虚线的上方的时候，一定是遇到了一个重复的数。
+一旦越过了这条虚线以后，就再也不会掉到虚线的下方或者和虚线重叠。
+因为折线最终会停在 (n,n+1) 这个位置，如果要从 y=x 这条虚线或者这条虚线的下方到达 (n,n+1) 这个位置，
+一定需要一个斜率 > 1的折线段，而这个与题目所说的重复的数只有一个就是矛盾的。因此可以证明，斜率超过1 的折线只会出现1次，
+且会将折线整体带上 y=x 这条虚线的上方。因此第一个在 y=x 上方的 x 点，就是我们要找的重复的数。
+
+时间复杂度是 $O(nlogn)$
+```java
+public class Solution {
+    /**
+     * @param nums an array containing n + 1 integers which is between 1 and n
+     * @return the duplicate one
+     */
+    public int findDuplicate(int[] nums) {
+        // Write your code here
+        int l = 1;
+        int r = nums.length - 1;  // n
+        
+        while (l + 1 < r) {
+            int mid = l + (r - l) / 2;
+            if (count(nums, mid) <= mid) {
+                l = mid;
+            } else {
+                r = mid;
+            }
+        }
+        
+        if (count(nums, l) <= l) {
+            return r;
+        }
+        return l;
+    }
+    
+    private int count(int[] nums, int mid) {
+        int cnt = 0;
+        for (int item : nums) {
+            if (item <= mid) {
+                cnt++;
+            }
+        }
+        return cnt;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/interleaving-positive-and-negative-numbers.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/interleaving-positive-and-negative-numbers.md"
new file mode 100644
index 0000000..82d6423
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/interleaving-positive-and-negative-numbers.md"
@@ -0,0 +1,109 @@
+# 交错正负数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/interleaving-positive-and-negative-numbers/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个含有正整数和负整数的数组，重新排列成一个正负数交错的数组。
+
+ ### 样例说明
+ ***样例 1***
+```
+输入 : [-1, -2, -3, 4, 5, 6]
+输出 : [-1, 5, -2, 4, -3, 6]
+解释 : 或者仍和满足条件的答案 
+```
+
+ ### 参考代码
+ 先把正负数 partition 开，然后再相向双指针进行交换。
+```
+[[python]]
+class Solution:
+    """
+    @param: A: An integer array.
+    @return: nothing
+    """
+    def rerange(self, A):
+        pos, neg = 0, 0
+        for num in A:
+            if num > 0:
+                pos += 1
+            else:
+                neg += 1
+        
+        self.partition(A, pos > neg)
+        self.interleave(A, pos == neg)
+            
+    def partition(self, A, start_positive):
+        flag = 1 if start_positive else -1
+        left, right = 0, len(A) - 1
+        while left <= right:
+            while left <= right and A[left] * flag > 0:
+                left += 1
+            while left <= right and A[right] * flag < 0:
+                right -= 1
+            if left <= right:
+                A[left], A[right] = A[right], A[left]
+                left += 1
+                right -= 1
+    
+    def interleave(self, A, has_same_length):
+        left, right = 1, len(A) - 1
+        if has_same_length:
+            right = len(A) - 2
+            
+        while left < right:
+            A[left], A[right] = A[right], A[left]
+            left, right = left + 2, right - 2
+[[java]]
+public class Solution {
+    public void rerange(int[] A) {
+        int pos = 0, neg = 0;
+        for (int i = 0; i < A.length; i++) {
+            if (A[i] > 0) {
+                pos++;
+            } else {
+                neg++;
+            }
+        }
+        
+        partition(A, pos > neg);
+        interleave(A, pos == neg);
+    }
+    
+    private void partition(int[] A, boolean startPositive) {
+        int flag = startPositive ? 1 : -1;
+        int left = 0, right = A.length - 1;
+        while (left <= right) {
+            while (left <= right && A[left] * flag > 0) {
+                left++;
+            }
+            while (left <= right && A[right] * flag < 0) {
+                right--;
+            }
+            
+            if (left <= right) {
+                int temp = A[left];
+                A[left] = A[right];
+                A[right] = temp;
+                
+                left++;
+                right--;
+            }
+        }
+    }
+    
+    private void interleave(int[] A, boolean has_same_length) {
+        int left = 1, right = A.length - 1;
+        if (has_same_length) {
+            right = A.length - 2;
+        }
+        while (left < right) {
+            int temp = A[left];
+            A[left] = A[right];
+            A[right] = temp;
+            
+            left += 2;
+            right -= 2;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/linked-list-cycle-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/linked-list-cycle-ii.md"
new file mode 100644
index 0000000..c9978de
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/linked-list-cycle-ii.md"
@@ -0,0 +1,68 @@
+# 带环链表 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/linked-list-cycle-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个链表，如果链表中存在环，则返回到链表中环的起始节点，如果没有环，返回null。</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：null,no cycle
+输出：no cycle
+解释：
+链表为空，所以没有环存在。
+```
+**样例 2:**
+```https://simplemde.com/markdown-guide
+输入：-21->10->4->5，tail connects to node index 1
+输出：10
+解释：
+最后一个节点5指向下标为1的节点，也就是10，所以环的入口为10。
+```
+ ### 参考代码
+ Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
+
+Follow up:
+Can you solve it without using extra space?
+
+考点：
+* 双指针链表判环
+
+题解：
+* 使用双指针判断链表中是否有环，慢指针每次走一步，快指针每次走两步，若链表中有环，则两指针必定相遇。
+* 假设环的长度为l，环上入口距离链表头距离为a，两指针第一次相遇处距离环入口为b，则另一段环的长度为c=l-b，由于快指针走过的距离是慢指针的两倍，则有a+l+b=2*(a+b),又有l=b+c，可得a=c，故当判断有环时(slow==fast)时，移动头指针，同时移动慢指针，两指针相遇处即为环的入口。
+```java
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+public class Solution {
+    public ListNode detectCycle(ListNode head) {
+        if (head == null || head.next==null) {
+            return null;
+        }
+
+        ListNode fast, slow;
+        fast = head.next;			//快指针
+        slow = head;				//慢指针
+        while (fast != slow) {		//快慢指针相遇
+            if(fast==null || fast.next==null)
+                return null;
+            fast = fast.next.next;
+            slow = slow.next;
+        } 
+        
+        while (head != slow.next) {  //同时移动head和慢指针
+            head = head.next;
+            slow = slow.next;
+        }
+        return head;				//两指针相遇处即为环的入口
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/linked-list-cycle.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/linked-list-cycle.md"
new file mode 100644
index 0000000..4c9e38f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/linked-list-cycle.md"
@@ -0,0 +1,46 @@
+# 带环链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/linked-list-cycle/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个链表，判断它是否有环。</p>
+ ### 样例说明
+ 	```
+	样例 1:
+		输入: 21->10->4->5,  then tail connects to node index 1(value 10).
+		输出: true
+		
+	样例 2:
+		输入: 21->10->4->5->null
+		输出: false
+	
+	```
+
+ ### 参考代码
+ Given a linked list, determine if it has a cycle in it.
+
+Follow up:
+Can you solve it without using extra space?
+
+快慢指针的经典题。
+快指针每次走两步，慢指针一次走一步。
+在慢指针进入环之后，快慢指针之间的距离每次缩小1，所以最终能相遇。
+```java
+public class Solution {
+    public Boolean hasCycle(ListNode head) {
+        if (head == null || head.next == null) {
+            return false;
+        }
+
+        ListNode fast, slow;
+        fast = head.next;
+        slow = head;
+        while (fast != slow) {
+            if(fast==null || fast.next==null)
+                return false;
+            fast = fast.next.next;
+            slow = slow.next;
+        } 
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/longest-substring-with-at-most-k-distinct-characters.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/longest-substring-with-at-most-k-distinct-characters.md"
new file mode 100644
index 0000000..7802296
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/longest-substring-with-at-most-k-distinct-characters.md"
@@ -0,0 +1,50 @@
+# 最多有k个不同字符的最长子字符串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-substring-with-at-most-k-distinct-characters/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定字符串*S*，找到最多有k个不同字符的最长子串*T*。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: S = "eceba" 并且 k = 3
+输出: 4
+解释: T = "eceb"
+```
+
+**样例 2:**
+
+```
+输入: S = "WORLD" 并且 k = 4
+输出: 4
+解释: T = "WORL" 或 "ORLD"
+ ### 参考代码
+ 一次遍历即可
+遍历的同时记录: 每个字符出现的次数, 当前子串中不同字符的个数
+其中定义一个变量记录左边界, 当前子串即左边界到遍历位置对应的子串
+如果不同字符的个数超过k, 则向右调整左边界即可, 遍历同时维护最长子串长度即可
+```python
+class Solution:
+    """
+    @param s: A string
+    @param k: An integer
+    @return: An integer
+    """
+    def lengthOfLongestSubstringKDistinct(self, s, k):
+        if not s:
+            return 0
+            
+        counter = {}
+        left = 0
+        longest = 0
+        for right in range(len(s)):
+            counter[s[right]] = counter.get(s[right], 0) + 1
+            while left <= right and len(counter) > k:
+                counter[s[left]] -= 1
+                if counter[s[left]] == 0:
+                    del counter[s[left]]
+                left += 1
+            
+            longest = max(longest, right - left + 1)
+        return longest
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/longest-substring-without-repeating-characters.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/longest-substring-without-repeating-characters.md"
new file mode 100644
index 0000000..b15f547
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/longest-substring-without-repeating-characters.md"
@@ -0,0 +1,77 @@
+# 最长无重复字符的子串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-substring-without-repeating-characters/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串，请找出其中无重复字符的最长子字符串。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "abcabcbb"
+输出: 3
+解释: 最长子串是 "abc".
+```
+
+**样例 2:**
+
+```
+输入: "bbbbb"
+输出: 1
+解释: 最长子串是 "b".
+```
+ ### 参考代码
+ 枚举, 记录每一个字母上一次出现的位置.
+ 
+ 再设定一个左边界, 到当前枚举到的位置之间的字符串为不含重复字符的子串.
+ 
+ 若新碰到的字符的上一次的位置在左边界右边, 则需要向右移动左边界, 枚举的过程中取最大值即可.
+```java
+public class Solution {
+    /**
+     * @param s: a string
+     * @return: an integer 
+     */
+     //方法一：
+    public int lengthOfLongestSubstring(String s) {
+        int[] map = new int[256]; // map from character's ASCII to its last occured index
+        
+        int j = 0;
+        int i = 0;
+        int ans = 0;
+        for (i = 0; i < s.length(); i++) {
+            while (j < s.length() && map[s.charAt(j)]==0) {
+                map[s.charAt(j)] = 1;
+                ans = Math.max(ans, j-i + 1);
+                j ++;
+            }
+            map[s.charAt(i)] = 0;
+        }
+        
+        return ans;
+    }
+}
+
+
+public class Solution {
+    /**
+     * @param s: a string
+     * @return: an integer
+     */
+    public int lengthOfLongestSubstring(String s) {
+        // write your code here
+        int[] cnt = new int[256];
+        char[] sc = s.toCharArray();
+
+        int ans = 0;
+        for (int l = 0, r = 0; r < s.length(); r++) {
+            cnt[sc[r]]++;
+            while (cnt[sc[r]] > 1) {
+                cnt[sc[l]]--;
+                l++;
+            }
+            ans = Math.max(ans, r - l + 1);
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/maximum-submatrix.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/maximum-submatrix.md"
new file mode 100644
index 0000000..fc07053
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/maximum-submatrix.md"
@@ -0,0 +1,110 @@
+# 最大子矩阵
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-submatrix/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个大小为 `n x n` 的矩阵，里面元素为 `正整数` 和 `负整数` ，找到具有最大和的子矩阵。
+ ### 样例说明
+ **样例1**
+
+```
+输入:
+matrix = [
+    [1,3,-1],
+    [2,3,-2],
+    [-1,-2,-3]
+]
+输出: 9
+解释:
+具有最大和的子矩阵是:
+[
+    [1,3],
+    [2,3]
+]
+```
+
+**样例2**
+
+```
+输入:
+matrix = [
+    [1,1,1],
+    [1,1,1],
+    [1,1,1]
+]
+输出: 9
+解释:
+具有最大和的子矩阵是:
+[
+    [1,1,1],
+    [1,1,1],
+    [1,1,1]
+]
+```
+ ### 参考代码
+ 枚举子矩阵的上下边界 up & down, 然后将这之间的数压缩为一个一维数组（降维攻击），剩下的任务就是一维数组如何求 Maximum Subarray 了。
+```java
+public class Solution {
+  int n, m;
+  
+  /**
+   * @param matrix: the given matrix
+   * @return: the largest possible sum
+   */
+  public int maxSubmatrix(int[][] matrix) {
+    if (matrix == null || matrix.length == 0) {
+      return 0;
+    }
+    if (matrix[0] == null || matrix[0].length == 0) {
+      return 0;
+    }
+    
+    n = matrix.length;
+    m = matrix[0].length;
+    
+    int[][] prefixColSum = getPrefixColSum(matrix);
+    
+    int max = Integer.MIN_VALUE;
+    for (int up = 0; up < n; up++) {
+      for (int down = up; down < n; down++) {
+        int[] arr = compression(matrix, up, down, prefixColSum);
+        max = Math.max(max, maximumSubarray(arr));
+      }
+    }
+    
+    return max;
+  };
+  
+  private int maximumSubarray(int[] arr) {
+    int min = 0, max = Integer.MIN_VALUE, sum = 0;
+    
+    for (int i = 0; i < m; i++) {
+      sum += arr[i];
+      max = Math.max(max, sum - min);
+      min = Math.min(min, sum);
+    }
+    
+    return max;
+  }
+  
+  private int[] compression(int[][] matrix, int up, int down, int[][] prefixColSum) {
+    int[] arr = new int[m];
+    for (int i = 0; i < m; i++) {
+      arr[i] = prefixColSum[down + 1][i] - prefixColSum[up][i];
+    }
+    
+    return arr;
+  }
+  
+  private int[][] getPrefixColSum(int[][] matrix) {
+    int[][] sum = new int[n + 1][m];
+    
+    for (int i = 0; i < n; i++) {
+      for (int j = 0; j < m; j++) {
+        sum[i + 1][j] = sum[i][j] + matrix[i][j];
+      }
+    }
+    
+    return sum;
+  }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/merge-sorted-array.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/merge-sorted-array.md"
new file mode 100644
index 0000000..268c581
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/merge-sorted-array.md"
@@ -0,0 +1,54 @@
+# 合并排序数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-sorted-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 合并两个排序的整数数组A和B变成一个新的数组。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[1, 2, 3]  3  [4,5]  2
+输出：[1,2,3,4,5]
+解释:
+经过合并新的数组为[1,2,3,4,5]
+```
+**样例 2:**
+```
+输入：[1,2,5] 3 [3,4] 2
+输出：[1,2,3,4,5]
+解释：
+经过合并新的数组为[1,2,3,4,5]
+```
+ ### 参考代码
+ Given two sorted integer arrays A and B, merge B into A as one sorted array.
+考点：
+* 双指针
+
+Note:
+You may assume that A has enough space (size that is greater or equal to m + n) to hold additional elements from B. The number of elements initialized in A and B are m and n respectively.
+分析:涉及两个有序数组合并,设置i和j双指针,分别从两个数组的尾部想头部移动,并判断A[i]和B[j]的大小关系,从而保证最终数组有序,同时每次index从尾部向头部移动。
+```java
+class Solution {
+    /**
+     * @param A: sorted integer array A which has m elements, 
+     *           but size of A is m+n
+     * @param B: sorted integer array B which has n elements
+     * @return: void
+     */
+    public void mergeSortedArray(int[] A, int m, int[] B, int n) {
+        int i = m-1, j = n-1, index = m + n - 1;
+        while (i >= 0 && j >= 0) {
+            if (A[i] > B[j]) {
+                A[index--] = A[i--];
+            } else {
+                A[index--] = B[j--];
+            }
+        }
+        while (i >= 0) {
+            A[index--] = A[i--];
+        }
+        while (j >= 0) {
+            A[index--] = B[j--];
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/minimum-size-subarray-sum.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/minimum-size-subarray-sum.md"
new file mode 100644
index 0000000..61870bb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/minimum-size-subarray-sum.md"
@@ -0,0 +1,52 @@
+# 和大于S的最小子数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-size-subarray-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个由 `n` 个正整数组成的数组和一个正整数 `s` ，请找出该数组中满足其和 ≥ s 的最小长度子数组。如果无解，则返回 -1。
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [2,3,1,2,4,3], s = 7
+输出: 2
+解释: 子数组 [4,3] 是该条件下的最小长度子数组。
+```
+
+**样例 2:**
+
+```
+输入: [1, 2, 3, 4, 5], s = 100
+输出: -1
+```
+ ### 参考代码
+ 用两根指针对数组进行一次遍历即可.
+
+如果当前和小于`s`, 右指针右移, 扩大区间, 反之左指针右移, 缩小区间.
+
+在这个过程中维持区间的和不小于`s`, 然后更新答案即可.
+```java
+public class Solution {
+    /**
+     * @param nums: an array of integers
+     * @param s: an integer
+     * @return: an integer representing the minimum size of subarray
+     */
+    public int minimumSize(int[] nums, int s) {
+        // write your code here
+        int sum = 0;
+        int ans = Integer.MAX_VALUE;
+
+        for (int l = 0, r = 0; r < nums.length; r++) {
+            sum += nums[r];
+
+            while (sum >= s) {
+                ans = Math.min(ans, r - l + 1);
+                sum -= nums[l++];
+            }
+        }
+
+        return ans == Integer.MAX_VALUE ? -1 : ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/minimum-window-substring.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/minimum-window-substring.md"
new file mode 100644
index 0000000..054fe02
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/minimum-window-substring.md"
@@ -0,0 +1,101 @@
+# 最小子串覆盖
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-window-substring/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个字符串 `source` 和 `target`. 求 `source` 中最短的包含 `target` 中每一个字符的子串.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: source = "abc", target = "ac"
+输出: "abc"
+```
+
+**样例 2:**
+
+```
+输入: source = "adobecodebanc", target = "abc"
+输出: "banc"
+解释: "banc" 是 source 的包含 target 的每一个字符的最短的子串.
+```
+
+**样例 3:**
+
+```
+输入: source = "abc", target = "aa"
+输出: ""
+解释: 没有子串包含两个 'a'.
+```
+ ### 参考代码
+ 利用双指针的方式，找到最短的子串
+```java
+public class Solution {
+    /**
+     * @param source : A string
+     * @param target: A string
+     * @return: A string denote the minimum window, return "" if there is no such a string
+     */
+    public String minWindow(String ss , String tt) {
+        char[] s = ss.toCharArray();
+        char[] t = tt.toCharArray();
+        if (t.length == 0) {
+            return "";
+        }
+        
+        int[] cntS = new int[256]; // number of appearances for each character in the window
+        int[] cntT = new int[256]; // how many times each character appears in T
+        int K = 0; // number of T's unique chracters
+        for (int i = 0; i < 256; ++i) {
+            cntS[i] = cntT[i] = 0;
+        }
+        
+        for (char c : t) {
+            ++cntT[c];
+            if (cntT[c] == 1) {
+                ++K;
+            }
+        }
+        
+        // abccba ==> K=3
+        int now = 0; // number of T's unique characters the window contains
+        // when now == K, we're good
+        
+        int ansl = -1, ansr = -1;
+        int l, r = 0;
+        for (l = 0; l < s.length; ++l) { // main pointer, st
+            // insert into window
+            while (r < s.length && now < K) {
+                ++cntS[s[r]];
+                // phase jump
+                if (cntS[s[r]] == cntT[s[r]]) {
+                    ++now;
+                }
+                
+                ++r;
+            }
+            
+            if (now == K) {
+                // this window is good
+                if (ansl == -1 || r - l < ansr - ansl) {
+                    ansl = l;
+                    ansr = r;
+                }
+            }
+            
+            // remove from window
+            --cntS[s[l]];
+            if (cntS[s[l]] == cntT[s[l]] - 1) {
+                --now;
+            }
+        }
+        
+        // s[l...(r-1)]
+        if (ansl == -1) {
+            return "";
+        }
+        else {
+            return ss.substring(ansl, ansr);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/move-zeroes.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/move-zeroes.md"
new file mode 100644
index 0000000..89f7a7f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/move-zeroes.md"
@@ -0,0 +1,66 @@
+# 移动零
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/move-zeroes/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个数组 *nums* 写一个函数将 `0` 移动到数组的最后面，非零元素保持原数组的顺序
+ ### 样例说明
+ 例1:
+```
+输入: nums = [0, 1, 0, 3, 12],
+输出: [1, 3, 12, 0, 0].
+```
+例2:
+```
+输入: nums = [0, 0, 0, 3, 1],
+输出: [3, 1, 0, 0, 0].
+```
+
+
+ ### 参考代码
+ 这个版本可以保证最小的“写”次数。
+```
+[[python]]
+class Solution:
+    """
+    @param nums: an integer array
+    @return: nothing
+    """
+    def moveZeroes(self, nums):
+        left, right = 0, 0
+        while right < len(nums):
+            if nums[right] != 0:
+                if left != right:
+                    nums[left] = nums[right]
+                left += 1
+            right += 1
+            
+        while left < len(nums):
+            if nums[left] != 0:
+                nums[left] = 0
+            left += 1
+[[java]]
+public class Solution {
+    /**
+     * @param nums: an integer array
+     * @return: nothing
+     */
+    public void moveZeroes(int[] nums) {
+        int left = 0, right = 0;
+        while (right < nums.length) {
+            if (nums[right] != 0) {
+                if (left != right) {
+                    nums[left] = nums[right];
+                }
+                left++;
+            }
+            right++;
+        }
+        while (left < nums.length) {
+            if (nums[left] != 0) {
+                nums[left] = 0;
+            }
+            left++;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/partition-array-by-odd-and-even.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/partition-array-by-odd-and-even.md"
new file mode 100644
index 0000000..d55b410
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/partition-array-by-odd-and-even.md"
@@ -0,0 +1,50 @@
+# 奇偶分割数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/partition-array-by-odd-and-even/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 分割一个整数数组，使得奇数在前偶数在后。
+
+ ### 样例说明
+ **样例1:**
+
+```plain
+输入: [1,2,3,4]
+输出: [1,3,2,4]
+```
+
+**样例2:**
+
+```plain
+输入: [1,4,2,3,5,6]
+输出: [1,3,5,4,2,6]
+```
+
+
+ ### 参考代码
+ 原题目很简单，只需要将原数组扫描两遍，第一遍加入奇数，第二遍加入偶数，然后把答案数组覆盖原数组即可。
+
+对于challenge问题，我们需要采用双指针（two pointer）的方法，一个从头开始，一个从尾开始，头指针定位到从前到后的第一个偶数，尾指针定位到从后到前的第一个奇数，两者交换即可。直到尾指针在头之前前面。
+```java
+public class Solution {
+    /**
+     * @param nums: an array of integers
+     * @return: nothing
+     */
+    public void partitionArray(int[] nums) {
+        int start = 0, end = nums.length - 1;
+        while (start < end) {
+            while (start < end && nums[start] % 2 == 1) {
+                start++;
+            }
+            while (start < end && nums[end] % 2 == 0) {
+                end--;
+            }
+            if (start < end) {
+                int temp = nums[start]; nums[start] = nums[end]; nums[end] = temp;
+                start++;
+                end--;
+            } 
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/partition-list.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/partition-list.md"
new file mode 100644
index 0000000..fd94be9
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/partition-list.md"
@@ -0,0 +1,74 @@
+# 链表划分
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/partition-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个单链表和数值x，划分链表使得所有小于x的节点排在大于等于x的节点之前。</p><p>你应该保留两部分内链表节点原有的相对顺序。</p><p><br></p>
+ ### 样例说明
+ **样例  1:**
+
+```
+输入: list = null, x = 0
+输出: null	
+样例解释: 空链表本身满足要求
+```
+
+**样例 2:**
+
+```
+输入: list = 1->4->3->2->5->2->null, x = 3
+输出: 1->2->2->4->3->5->null	
+样例解释: 要保持原有的相对顺序。
+```
+
+ ### 参考代码
+ Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
+
+You should preserve the original relative order of the nodes in each of the two partitions.
+
+For example,
+Given 1->4->3->2->5->2 and x = 3,
+return 1->2->2->4->3->5.
+
+双指针方法，用两个指针将两个部分分别串起来。最后在将两个部分拼接起来。
+left指针用来串起来所有小于x的结点，
+right指针用来串起来所有大于等于x的结点。
+得到两个链表，一个是小于x的，一个是大于等于x的，做一个拼接即可。
+```java
+/**
+ * Definition for singly-linked list.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int x) {
+ *         val = x;
+ *         next = null;
+ *     }
+ * }
+ */
+public class Solution {
+    public ListNode partition(ListNode head, int x) {
+        if (head == null) {
+            return null;
+        }
+        
+        ListNode leftDummy = new ListNode(0);
+        ListNode rightDummy = new ListNode(0);
+        ListNode left = leftDummy, right = rightDummy;
+        
+        while (head != null) {
+            if (head.val < x) {
+                left.next = head;
+                left = head;
+            } else {
+                right.next = head;
+                right = head;
+            }
+            head = head.next;
+        }
+        
+        right.next = null;
+        left.next = rightDummy.next;
+        return leftDummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/remove-duplicate-numbers-in-array.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/remove-duplicate-numbers-in-array.md"
new file mode 100644
index 0000000..b1974a5
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/remove-duplicate-numbers-in-array.md"
@@ -0,0 +1,82 @@
+# 去除重复元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-duplicate-numbers-in-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个整数数组，去除重复的元素。
+
+你应该做这些事
+
+1.在原数组上操作
+2.将去除重复之后的元素放在数组的开头
+3.返回去除重复元素之后的元素个数
+ ### 样例说明
+ 
+例1:
+```
+输入:
+nums = [1,3,1,4,4,2]
+输出:
+[1,3,4,2,?,?]
+4
+
+解释:
+1. 将重复的整数移动到 nums 的尾部 => nums = [1,3,4,2,?,?].
+2. 返回 nums 中唯一整数的数量  => 4.
+事实上我们并不关心你把什么放在了 ? 处, 只关心没有重复整数的部分.
+```
+
+
+例2:
+```
+输入:
+nums = [1,2,3]
+输出:
+[1,2,3]
+3
+```
+
+ ### 参考代码
+ 建立一个指针，指针指向目前位置不同的数的末尾，如果当前元素与末尾不同，则加入到末尾
+```java
+// O(n) time, O(n) space
+public class Solution {
+    /**
+     * @param nums an array of integers
+     * @return the number of unique integers
+     */
+    public int deduplication(int[] nums) {
+        // Write your code here
+        Set<Integer> set = new HashSet<Integer>();        
+        for (int i = 0; i < nums.length; ++i){
+            set.add(nums[i]);
+        }            
+        int result = 0;
+        for (Integer i : set){
+            nums[result++] = i;
+        }    
+        return result;
+    }
+}
+
+// O(nlogn) time, O(1) extra space
+public class Solution {
+    /**
+     * @param nums an array of integers
+     * @return the number of unique integers
+     */
+    public int deduplication(int[] nums) {
+        if (nums.length == 0) {
+            return 0;
+        }
+        
+        Arrays.sort(nums);
+        int len = 0;
+        for (int i = 0; i < nums.length; i++) {
+            if (nums[i] != nums[len]) {
+                nums[++len] = nums[i];
+            }
+        }
+        return len + 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/sliding-window-maximum.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/sliding-window-maximum.md"
new file mode 100644
index 0000000..dab15c1
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/sliding-window-maximum.md"
@@ -0,0 +1,120 @@
+# 滑动窗口的最大值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sliding-window-maximum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个可能包含重复的整数数组，和一个大小为 *k* 的滑动窗口, 从左到右在数组中滑动这个窗口，找到数组中每个窗口内的最大值。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+[1,2,7,7,8]
+3
+输出:
+[7,7,8]
+
+解释：
+最开始，窗口的状态如下：`[|1, 2 ,7| ,7 , 8]`, 最大值为 `7`;
+然后窗口向右移动一位：`[1, |2, 7, 7|, 8]`, 最大值为 `7`;
+最后窗口再向右移动一位：`[1, 2, |7, 7, 8|]`, 最大值为 `8`.
+```
+
+**样例 2:**
+```
+输入:
+[1,2,3,1,2,3]
+5
+输出:
+[3,3]
+
+解释:
+最开始，窗口的状态如下： `[|1,2,3,1,2 | ,3]` , 最大值为`3`;
+然后窗口向右移动一位.`[1, |2,3,1,2,3]`, 最大值为 `3`;
+```
+ ### 参考代码
+ 单调的双端队列
+```java
+// 九章算法强化班版本 
+// deque中存储位置
+public class Solution {
+    int[] a;
+    /**
+     * @param nums: A list of integers.
+     * @return: The maximum number inside the window at each moving.
+     */
+    void inQueue(Deque<Integer> deque, int pos) {
+        while (!deque.isEmpty() && a[deque.peekLast()] <= a[pos]) {
+            deque.pollLast();
+        }
+        deque.offer(pos);
+    }
+    
+    void outQueue(Deque<Integer> deque, int pos) {
+        if (deque.peekFirst() == pos) {
+            deque.pollFirst();
+        }
+    }
+    
+    public ArrayList<Integer> maxSlidingWindow(int[] nums, int k) {
+        a = nums;
+        // write your code here
+        ArrayList<Integer> ans = new ArrayList<Integer>();
+        Deque<Integer> deque = new ArrayDeque<Integer>();
+        if (nums.length == 0) {
+            return ans;
+        }
+        for (int i = 0; i < k - 1; i++) {
+            inQueue(deque, i);
+        }
+        
+        for(int i = k - 1; i < nums.length; i++) {
+            inQueue(deque, i);
+            ans.add(a[deque.peekFirst()]);
+            outQueue(deque, i - k + 1);
+        }
+        return ans;
+
+    }
+}
+
+// 方法二
+
+public class Solution {
+    
+    /**
+     * @param nums: A list of integers.
+     * @return: The maximum number inside the window at each moving.
+     */
+    void inQueue(Deque<Integer> deque, int num) {
+        while (!deque.isEmpty() && deque.peekLast() < num) {
+            deque.pollLast();
+        }
+        deque.offer(num);
+    }
+    
+    void outQueue(Deque<Integer> deque, int num) {
+        if (deque.peekFirst() == num) {
+            deque.pollFirst();
+        }
+    }
+    
+    public ArrayList<Integer> maxSlidingWindow(int[] nums, int k) {
+        // write your code here
+    	ArrayList<Integer> ans = new ArrayList<Integer>();
+        Deque<Integer> deque = new ArrayDeque<Integer>();
+        if (nums.length == 0) {
+            return ans;
+        }
+        for (int i = 0; i < k - 1; i++) {
+            inQueue(deque, nums[i]);
+        }
+        
+        for(int i = k - 1; i < nums.length; i++) {
+            inQueue(deque, nums[i]);
+            ans.add(deque.peekFirst());
+            outQueue(deque, nums[i - k + 1]);
+        }
+        return ans;
+
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/sliding-window-median.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/sliding-window-median.md"
new file mode 100644
index 0000000..2deb9ce
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/sliding-window-median.md"
@@ -0,0 +1,173 @@
+# 滑动窗口的中位数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sliding-window-median/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个包含 n 个整数的数组，和一个大小为 *k* 的滑动窗口,从左到右在数组中滑动这个窗口，找到数组中每个窗口内的中位数。(如果数组个数是偶数，则在该窗口排序数字后，返回第 N/2 个数字。)
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+[1,2,7,8,5]
+3
+输出:
+[2,7,7]
+
+解释:
+最初，窗口的数组是这样的：`[ | 1,2,7 | ,8,5]` , 返回中位数 `2`;
+接着，窗口继续向前滑动一次。`[1, | 2,7,8 | ,5]`, 返回中位数 `7`;
+接着，窗口继续向前滑动一次。`[1,2, | 7,8,5 | ]`, 返回中位数 `7`;
+```
+
+**样例 2:**
+```
+输入:
+[1,2,3,4,5,6,7]
+4
+输出:
+[2,3,4,5]
+
+解释:
+最初，窗口数组是这样的：`[ | 1,2,3,4, | 5,6,7]` , 返回中位数 `2`;
+接着，窗口向前滑动一次.`[1,| 2,3,4,5 | 6,7]`,返回中位数 `3`;
+接着，窗口向前滑动一次.`[1,2, | 3,4,5,6 | 7 ]`, 返回中位数 `4`;
+接着，窗口向前滑动一次`[1,2,3,| 4,5,6,7 ]`, 返回中位数 `5`;
+```
+ ### 参考代码
+ 使用九章算法强化班中讲到的 HashHeap。即一个 Hash + Heap。
+Hash 的 key 是 Heap 里的每个元素，值是这个元素在 Heap 中的下标。
+
+要做这个题首先需要先做一下 Data Stream Median。这个题是只在一个集合中增加数，不删除数，然后不断的求中点。
+Sliding Window Median，就是不断的增加数，删除数，然后求中点。比 Data Stream Median 难的地方就在于如何支持删除数。
+
+因为 Data Stream Median 的方法是用 两个 Heap，一个 max heap，一个min heap。所以删除的话，就需要让 heap 也支持删除操作。
+由于 Python 的 heapq 并不支持 logn 时间内的删除操作，因此只能自己实现一个 hash + heap 的方法。
+
+总体时间复杂度 $O(nlogk)$，n是元素个数，k 是 window 的大小。
+```python
+class HashHeap:
+    
+    def __init__(self, desc=False):
+        self.hash = dict()
+        self.heap = []
+        self.desc = desc
+        
+    @property
+    def size(self):
+        return len(self.heap)
+        
+    def push(self, item):
+        self.heap.append(item)
+        self.hash[item] = self.size - 1
+        self._sift_up(self.size - 1)
+        
+    def pop(self):
+        item = self.heap[0]
+        self.remove(item)
+        return item
+    
+    def top(self):
+        return self.heap[0]
+        
+    def remove(self, item):
+        if item not in self.hash:
+            return
+            
+        index = self.hash[item]
+        self._swap(index, self.size - 1)
+        
+        del self.hash[item]
+        self.heap.pop()
+        
+        # in case of the removed item is the last item
+        if index < self.size:
+            self._sift_up(index)
+            self._sift_down(index)
+
+    def _smaller(self, left, right):
+        return right < left if self.desc else left < right
+
+    def _sift_up(self, index):
+        while index != 0:
+            parent = index // 2
+            if self._smaller(self.heap[parent], self.heap[index]):
+                break
+            self._swap(parent, index)
+            index = parent
+    
+    def _sift_down(self, index):
+        if index is None:
+            return
+        while index * 2 < self.size:
+            smallest = index
+            left = index * 2
+            right = index * 2 + 1
+            
+            if self._smaller(self.heap[left], self.heap[smallest]):
+                smallest = left
+                
+            if right < self.size and self._smaller(self.heap[right], self.heap[smallest]):
+                smallest = right
+                
+            if smallest == index:
+                break
+            
+            self._swap(index, smallest)
+            index = smallest
+        
+    def _swap(self, i, j):
+        elem1 = self.heap[i]
+        elem2 = self.heap[j]
+        self.heap[i] = elem2
+        self.heap[j] = elem1
+        self.hash[elem1] = j
+        self.hash[elem2] = i
+    
+class Solution:
+    """
+    @param nums: A list of integers
+    @param k: An integer
+    @return: The median of the element inside the window at each moving
+    """
+    def medianSlidingWindow(self, nums, k):
+        if not nums or len(nums) < k:
+            return []
+            
+        self.maxheap = HashHeap(desc=True)
+        self.minheap = HashHeap()
+        
+        for i in range(0, k - 1):
+            self.add((nums[i], i))
+            
+        medians = []
+        for i in range(k - 1, len(nums)):
+            self.add((nums[i], i))
+            # print(self.maxheap.heap, self.median, self.minheap.heap)
+            medians.append(self.median)
+            self.remove((nums[i - k + 1], i - k + 1))
+            # print(self.maxheap.heap, self.median, self.minheap.heap)
+            
+        return medians
+            
+    def add(self, item):
+        if self.maxheap.size > self.minheap.size:
+            self.minheap.push(item)
+        else:
+            self.maxheap.push(item)
+            
+        if self.maxheap.size == 0 or self.minheap.size == 0:
+            return
+            
+        if self.maxheap.top() > self.minheap.top():
+            self.maxheap.push(self.minheap.pop())
+            self.minheap.push(self.maxheap.pop())
+        
+    def remove(self, item):
+        self.maxheap.remove(item)
+        self.minheap.remove(item)
+        if self.maxheap.size < self.minheap.size:
+            self.maxheap.push(self.minheap.pop())
+        
+    @property
+    def median(self):
+        return self.maxheap.top()[0]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/sort-colors.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/sort-colors.md"
new file mode 100644
index 0000000..8a631e5
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/sort-colors.md"
@@ -0,0 +1,44 @@
+# 颜色分类
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sort-colors/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个包含红，白，蓝且长度为 n 的数组，将数组元素进行分类使相同颜色的元素相邻，并按照红、白、蓝的顺序进行排序。
+
+我们可以使用整数 0，1 和 2 分别代表红，白，蓝。
+
+ ### 样例说明
+ ***样例 1***
+```
+输入 : [1, 0, 1, 2]
+输出 : [0, 1, 1, 2]
+解释 : 原地排序。
+```
+
+ ### 参考代码
+ 使用一次扫描的办法。
+设立三根指针，left, index, right。定义如下规则：
+
+- left 的左侧都是 0（不含 left）
+- right 的右侧都是 2（不含 right）
+
+index 从左到右扫描每个数，如果碰到 0 就丢给 left，碰到 2 就丢给 right。碰到 1 就跳过不管。
+```python
+class Solution:
+    """
+    @param nums: A list of integer which is 0, 1 or 2 
+    @return: nothing
+    """
+    def sortColors(self, A):
+        left, index, right = 0, 0, len(A) - 1
+        # be careful, index < right is not correct
+        while index <= right:
+            if A[index] == 0:
+                A[left], A[index] = A[index], A[left]
+                left += 1
+                index += 1 # move to next number
+            elif A[index] == 2:
+                A[right], A[index] = A[index], A[right]
+                right -= 1
+            else:  # == 1, skip
+                index += 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/subarray-sum-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/subarray-sum-ii.md"
new file mode 100644
index 0000000..1cdd312
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/subarray-sum-ii.md"
@@ -0,0 +1,77 @@
+# 子数组求和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/subarray-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个正整数数组 `A` 和一个区间. 返回和在给定区间范围内的子数组数量.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: A = [1, 2, 3, 4], start = 1, end = 3
+输出: 4
+解释: 所有可能的子数组: [1](和为1), [1, 2](和为3), [2](和为2), [3](和为3).
+```
+
+**样例 2:**
+
+```
+输入: A = [1, 2, 3, 4], start = 1, end = 100
+输出: 10
+解释: 任意子数组都可以.
+```
+ ### 参考代码
+ **O(N) 的两根指针的算法**
+
+其实需要三根指针, 因为需要额外记录一下从哪个位置开始的加和已经 >= start 了.
+
+对于每一个左端点 left, 求出对应的两个右端点 right_start, right_end. 前者表示最左边的使得 [left, right_start] 子数组的和不小于 start 的点, 而后者表示最右边的使得 [left, right_end] 子数组的和不大于 end 的点.
+
+right_end - right_start + 1 就是以 left 为左端点的合法子数组的数量.
+
+从左到右枚举 left, 而 right_start, right_end 随着left的增长也是只增不减的, 所以时间复杂度是 O(N)
+
+**O(NlogN) 的二分法**
+
+求出一个前缀和数组, 然后对于每一个前缀和 presum[right], 我们要求出两个点 left_start, left_end. 前者表示最左边的使得 [left_start, right] 子数组和不大于 end 的点, 后者表示最右边的使得 [left_end, right] 子数组和不小于 start 的点.
+
+枚举 right, 我们可以在 presum[0..right] 上二分查找确定 left_start, left_end.
+
+**总结**
+
+上面两种方法是相通的, 都是对于子数组的一个端点, 确认另外一个端点的范围. 在枚举其中一个端点的过程, 另外一个端点的范围是单调的, 所以可以使用两根指针 O(N) 地完成.
+
+可以把两根指针和二分法综合一下, 不过这样理论时间复杂度是不变的, 没有很大的必要. 以上两种方法推荐第一种, 复杂度更低.
+```python
+class Solution:
+    """
+    @param A: An integer array
+    @param start: An integer
+    @param end: An integer
+    @return: the number of possible answer
+    """
+    def subarraySumII(self, A, start, end):
+        n = len(A)
+        big_sum, small_sum = 0, 0
+        big_end, small_end = 0, 0
+        ans = 0
+        for i in range(n):
+            small_end = max(small_end, i)
+            big_end = max(big_end, i)
+            while small_end < n and small_sum + A[small_end] < start:
+                small_sum += A[small_end]
+                small_end += 1
+            while big_end < n and big_sum + A[big_end] <= end:
+                big_sum += A[big_end]
+                big_end += 1
+            
+            if big_end - small_end > 0:
+                ans += big_end - small_end
+                
+            if small_end > i:
+                small_sum -= A[i]
+            
+            if big_end > i:
+                big_sum -= A[i]
+            
+        return ans
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/the-smallest-difference.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/the-smallest-difference.md"
new file mode 100644
index 0000000..ce52adb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/the-smallest-difference.md"
@@ -0,0 +1,55 @@
+# 最小差
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/the-smallest-difference/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个整数数组（第一个是数组 `A`，第二个是数组 `B`），在数组 A 中取 A[i]，数组 B 中取 B[j]，A[i] 和 B[j]两者的差越小越好(|A[i] - B[j]|), 返回最小差。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: A = [3, 6, 7, 4], B = [2, 8, 9, 3] 
+输出: 0
+解释: A[0] - B[3] = 0
+```
+
+**样例 2:**
+
+```
+输入: A = [1, 2, 3, 4], B = [7, 6, 5]
+输出: 1
+解释: B[2] - A[3] = 1
+```
+ ### 参考代码
+ 对A, B排序, 默认升序. 
+
+设定两个指针开始遍历A, B, 每次向右移动值比较小的那个指针.
+
+遍历过程中求差的绝对值, 更新答案. 时间复杂度O(*nlogn*)
+```java
+public class Solution {
+    /**
+     * @param A, B: Two integer arrays.
+     * @return: Their smallest difference.
+     */
+    public int smallestDifference(int[] A, int[] B) {
+        if (A == null || A.length == 0 || B == null || B.length == 0) {
+            return 0;
+        }
+        
+        Arrays.sort(A);
+        Arrays.sort(B);
+        
+        int ai = 0, bi = 0;
+        int min = Integer.MAX_VALUE;
+        while (ai < A.length && bi < B.length) {
+            min = Math.min(min, Math.abs(A[ai] - B[bi]));
+            if (A[ai] < B[bi]) {
+                ai++;
+            } else {
+                bi++;
+            }
+        }
+        return min;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/triangle-count.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/triangle-count.md"
new file mode 100644
index 0000000..ea80975
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/triangle-count.md"
@@ -0,0 +1,75 @@
+# 三角形计数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/triangle-count/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，在该数组中，寻找三个数，分别代表三角形三条边的长度，问，可以寻找到多少组这样的三个数来组成三角形？
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [3, 4, 6, 7]
+输出: 3
+解释:
+可以组成的是 (3, 4, 6), 
+           (3, 6, 7),
+           (4, 6, 7)
+```
+
+**样例 2:**
+
+```
+输入: [4, 4, 4, 4]
+输出: 4
+解释:
+任何三个数都可以构成三角形
+所以答案为 C(3, 4) = 4
+```
+ ### 参考代码
+ 使用双指针算法。
+for 循环最大边的位置 i，接下来的任务就是在 0~i-1 之间找到两数之和 > S[i]
+```
+[[python]]
+class Solution:
+    """
+    @param S: A list of integers
+    @return: An integer
+    """
+    def triangleCount(self, S):
+        S.sort()
+        
+        ans = 0
+        for i in range(len(S)):
+            left, right = 0, i - 1
+            while left < right:
+                if S[left] + S[right] > S[i]:
+                    ans += right - left
+                    right -= 1
+                else:
+                    left += 1
+        return ans
+[[java]]
+public class Solution {
+    /**
+     * @param S: A list of integers
+     * @return: An integer
+     */
+    public int triangleCount(int S[]) {
+        int left = 0, right = S.length - 1;
+        int ans = 0;
+        Arrays.sort(S);
+        for (int i = 0; i < S.length; i++) {
+            left = 0;
+            right = i - 1;
+            while (left < right) {
+                if (S[left] + S[right] > S[i]) {
+                    ans = ans + (right - left);
+                    right --;
+                } else {
+                    left ++;
+                }
+            }
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-closest-to-target.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-closest-to-target.md"
new file mode 100644
index 0000000..6f30eaa
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-closest-to-target.md"
@@ -0,0 +1,93 @@
+# 两数和的最接近值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/two-sum-closest-to-target/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定整数数组`num`，从中找到两个数字使得他们和最接近`target`，返回两数和与 `target` 的差的 `绝对值`。
+ ### 样例说明
+ **样例1**
+
+```
+输入: nums = [-1, 2, 1, -4] 并且 target = 4
+输出: 1
+解释:
+最小的差距是1，(4 - (2 + 1) = 1).
+```
+
+**样例2**
+
+```
+输入: nums = [-1, -1, -1, -4] 并且 target = 4
+输出: 6
+解释:
+最小的差距是6，(4 - (- 1 - 1) = 6).
+```
+ ### 参考代码
+ <p>http://www.lintcode.com/problem/two-sum-closest-to-target/<br></p>
+```java
+public class Solution {
+    /**
+     * @param nums an integer array
+     * @param target an integer
+     * @return the difference between the sum and the target
+     */
+    public int twoSumClosest(int[] nums, int target) {
+        if (nums == null || nums.length < 2) {
+            return -1;
+        }
+        
+        Arrays.sort(nums);
+        
+        int left = 0, right = nums.length - 1;
+        int diff = Integer.MAX_VALUE;
+        
+        while (left < right) {
+            if (nums[left] + nums[right] < target) {
+                diff = Math.min(diff, target - nums[left] - nums[right]);
+                left++;
+            } else {
+                diff = Math.min(diff, nums[left] + nums[right] - target);
+                right--;
+            }
+        }
+        
+        return diff;
+    }
+}
+
+// 九章硅谷求职算法集训营版本
+public class Solution {
+    /**
+     * @param nums an integer array
+     * @param target an integer
+     * @return the difference between the sum and the target
+     */
+    int diff = Integer.MAX_VALUE;
+    int T = 0;
+    
+    public void update(int[] A, int x, int y) {
+        if (x != y && x >= 0 && x < A.length && y >= 0 && y < A.length) {
+            diff = Math.min(diff, Math.abs(A[x] + A[y] - T));
+        }
+    }
+    
+    public int twoSumClosest(int[] A, int target) {
+        // Write your code here
+        T = target;
+         if (A == null || A.length < 2) {
+            return -1;
+        }
+        
+        Arrays.sort(A);
+        
+        int j = A.length - 1;
+        for (int i = 0; i < A.length; ++i) {
+            while (j >= 0 && A[i] + A[j] > target) --j;
+            update(A, i, j + 1);
+            update(A, i, j);
+            update(A, i, j - 1);
+        }
+        
+        return diff;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-closest.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-closest.md"
new file mode 100644
index 0000000..05dc47b
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-closest.md"
@@ -0,0 +1,43 @@
+# 两数和的最接近值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/two-sum-closest/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定整数数组`num`，从中找到两个数字使得他们和最接近`target`，返回两数和与 `target` 的差的 `绝对值`。
+ ### 样例说明
+ 
+ ### 参考代码
+ 将数组排序后，双指针求解
+第一个指针初始位置在最前面，从前往后走
+第二个指针初始位置在最后面，从后往前走，
+在这个过程中迭代更新答案
+```java
+public class Solution {
+    /**
+     * @param nums an integer array
+     * @param target an integer
+     * @return the difference between the sum and the target
+     */
+    public int twoSumClosest(int[] nums, int target) {
+        if (nums == null || nums.length < 2) {
+            return -1;
+        }
+        
+        Arrays.sort(nums);
+        
+        int left = 0, right = nums.length - 1;
+        int diff = Integer.MAX_VALUE;
+        
+        while (left < right) {
+            if (nums[left] + nums[right] < target) {
+                diff = Math.min(diff, target - nums[left] - nums[right]);
+                left++;
+            } else {
+                diff = Math.min(diff, nums[left] + nums[right] - target);
+                right--;
+            }
+        }
+        
+        return diff;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-difference-equals-to-target.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-difference-equals-to-target.md"
new file mode 100644
index 0000000..fd9fa29
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-difference-equals-to-target.md"
@@ -0,0 +1,45 @@
+# 两数和 - 差等于目标值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/two-sum-difference-equals-to-target/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个排序后的整数数组，找到两个数的 `差` 等于目标值。
+你需要返回一个包含两个数字的列表`[num1, num2]`, 使得`num`1与`num2`的差为target，同时`num1`必须小于`num2`。
+ ### 样例说明
+ 例1:
+```
+输入: nums = [2, 7, 15, 24], target = 5 
+输出: [2, 7] 
+解释:
+(7 - 2 = 5)
+```
+例2:
+```
+输入: nums = [1, 1], target = 0
+输出: [1, 1] 
+解释:
+(1 - 1 = 0)
+```
+
+ ### 参考代码
+ 由于数组有序，我们可以用双指针来做
+对于双指针i,j,当num[j]-num[i]< target时，说明j太小，于是我们将j++，直到num[j]-num[i] >= target，若num[j]-num[i] > target，我们将i++，若num[j]-num[i] = target说明我们找到答案
+```python
+class Solution:
+    """
+    @param nums: an array of Integer
+    @param target: an integer
+    @return: [index1 + 1, index2 + 1] (index1 < index2)
+    """
+    def twoSum7(self, nums, target):
+        n = len(nums)
+        if target < 0:
+            target = -target
+        j = 0
+        for i in range(n):
+            if i == j:
+                j += 1
+            while j < n and nums[j] - nums[i] < target:
+                j += 1
+            if j < n and nums[j] - nums[i] == target:
+                return [nums[i],nums[j]]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-greater-than-target.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-greater-than-target.md"
new file mode 100644
index 0000000..73247c8
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-greater-than-target.md"
@@ -0,0 +1,63 @@
+# 两数之和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/two-sum-greater-than-target/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一组整数，问能找出多少对整数，他们的和大于一个给定的目标值。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [2, 7, 11, 15], target = 24
+输出: 1
+解释: 11 + 15 是唯一的一对
+```
+
+**样例 2:**
+
+```
+输入: [1, 1, 1, 1], target = 1
+输出: 6
+```
+ ### 参考代码
+ 总体思路是排序后使用两根指针进行遍历, 而遍历的过程有多种实现方式.
+
+本题解采用的思路是:
+
+- 定义左右端点指针`l = 0`, `r = n - 1` (n是数组长度)
+- 若 `l` 指向元素与 `r` 指向元素的和不大于 `target`, 则 `l` 右移; 反之, `result += r - l`, 并 `r` 左移
+- 终止条件为 `l >= r`
+
+上述思路利用了单调性: 若 `nums[l] + nums[r] > target`, 则 `nums[l + k] + nums[r] > target (k >= 0)`
+
+`result += r - l` 代表 `nums[r]` 可以与 `nums[l], nums[l + 1], ... , nums[r - 1]` 这 `r - l` 个元素成对, 加和大于 `target`.
+
+一个小优化: `l` 左移时可以用二分/倍增加速.
+```java
+public class Solution {
+    /**
+     * @param nums: an array of integer
+     * @param target: an integer
+     * @return: an integer
+     */
+    public int twoSum2(int[] nums, int target) {
+        if (nums == null || nums.length < 2) {
+            return 0;
+        }
+        
+        Arrays.sort(nums);
+        
+        int left = 0, right = nums.length - 1;
+        int count = 0;
+        while (left < right) {
+            if (nums[left] + nums[right] <= target) {
+                left++;
+            } else {
+                count += right - left;
+                right--;
+            }
+        }
+        
+        return count;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-input-array-is-sorted.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-input-array-is-sorted.md"
new file mode 100644
index 0000000..277e1c7
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-input-array-is-sorted.md"
@@ -0,0 +1,82 @@
+# 两数和 II-输入已排序的数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/two-sum-input-array-is-sorted/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个已经 *按升序排列* 的数组，找到两个数使他们加起来的和等于特定数。
+函数应该返回这两个数的下标，index1必须小于index2。注意返回的值不是 0-based。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    /*
+     * @param nums an array of Integer
+     * @param target = nums[index1] + nums[index2]
+     * @return [index1 + 1, index2 + 1] (index1 < index2)
+     */
+    public int[] twoSum(int[] nums, int target) {
+        if (nums == null || nums.length < 2) {
+            return null;
+        }
+        
+        int start = 0, end = nums.length - 1;
+        while (start < end) {
+            if (nums[start] + nums[end] == target) {
+                int[] pair = new int[2];
+                pair[0] = start + 1;
+                pair[1] = end + 1;
+                return pair;
+            }
+            if (nums[start] + nums[end] < target) {
+                start++;
+            } else {
+                end--;
+            }
+        }
+        
+        return null;
+    }
+}
+
+
+// 九章硅谷求职算法集训营版本
+public class Solution {
+    /*
+     * @param nums an array of Integer
+     * @param target = nums[index1] + nums[index2]
+     * @return [index1 + 1, index2 + 1] (index1 < index2)
+     */
+    public int[] twoSum(int[] A, int T) {
+        int[] res = new int[2];
+        if (A == null || A.length <= 1) {
+            return res;
+        }
+        
+        int n = A.length;
+        int i, j = n - 1;
+        for (i = 0; i < n; ++i) {
+            // i must point to the first number among a bunch of duplicates
+            if (i > 0 && A[i] == A[i - 1]) {
+                continue;
+            }
+            
+            while (j >= 0 && A[j] > T - A[i]) {
+                --j;
+            }
+            
+            if (j < 0 || i >= j) {
+                break;
+            }
+            
+            // i < j
+            if (A[i] + A[j] == T) {
+                res[0] = i + 1;
+                res[1] = j + 1;
+                return res;
+            }
+        }
+        
+        return res;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-less-than-or-equal-to-target.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-less-than-or-equal-to-target.md"
new file mode 100644
index 0000000..20505d7
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-less-than-or-equal-to-target.md"
@@ -0,0 +1,55 @@
+# 两数和-小于或等于目标值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/two-sum-less-than-or-equal-to-target/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找出这个数组中有多少对的和是小于或等于目标值。返回对数。
+ ### 样例说明
+ 例1:
+```
+输入: nums = [2, 7, 11, 15], target = 24. 
+输出: 5. 
+解释:
+2 + 7 < 24
+2 + 11 < 24
+2 + 15 < 24
+7 + 11 < 24
+7 + 15 < 24
+```
+
+例2:
+```
+输入: nums = [1], target = 1. 
+输出: 0. 
+```
+
+
+ ### 参考代码
+ 排序后双指针即可。
+```java
+public class Solution {
+    /**
+     * @param nums an array of integer
+     * @param target an integer
+     * @return an integer
+     */
+    public int twoSum5(int[] nums, int target) {
+        // Write your code here
+        if (nums == null || nums.length < 2)
+            return 0;
+
+        Arrays.sort(nums);
+        int cnt = 0;
+        int left = 0, right = nums.length - 1;
+        while (left < right) {
+            int v = nums[left] + nums[right];
+            if (v > target) {
+                right --;
+            } else {
+                cnt += right - left;
+                left ++;
+            }
+        }
+        return cnt;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-unique-pairs.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-unique-pairs.md"
new file mode 100644
index 0000000..ecd59f4
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/two-sum-unique-pairs.md"
@@ -0,0 +1,64 @@
+# 两数之和 - 不同组成
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/two-sum-unique-pairs/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一整数数组, 找到数组中有多少组 `不同的元素对` 有相同的和, 且和为给出的 target 值, 返回对数.
+ ### 样例说明
+ 
+
+**例1:**
+```
+输入: nums = [1,1,2,45,46,46], target = 47 
+输出: 2
+解释:
+
+1 + 46 = 47
+2 + 45 = 47
+
+```
+
+**例2:**
+```
+输入: nums = [1,1], target = 2 
+输出: 1
+解释:
+1 + 1 = 2
+```
+
+ ### 参考代码
+ 利用双指针的方法，扫描排序完的数组即可。
+```java
+public class Solution {
+    /**
+     * @param nums an array of integer
+     * @param target an integer
+     * @return an integer
+     */
+    public int twoSum6(int[] nums, int target) {
+        // Write your code here
+        if (nums == null || nums.length < 2)
+            return 0;
+
+        Arrays.sort(nums);
+        int cnt = 0;
+        int left = 0, right = nums.length - 1;
+        while (left < right) {
+            int v = nums[left] + nums[right];
+            if (v == target) {
+                cnt ++;
+                left ++;
+                right --;
+                while (left < right && nums[right] == nums[right + 1])
+                    right --;
+                while (left < right && nums[left] == nums[left - 1])
+                    left ++;
+            } else if (v > target) {
+                right --;
+            } else {
+                left ++;
+            }
+        }
+        return cnt;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/valid-palindrome-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/valid-palindrome-ii.md"
new file mode 100644
index 0000000..e341ece
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/valid-palindrome-ii.md"
@@ -0,0 +1,56 @@
+# 有效回文 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/valid-palindrome-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个非空字符串 `s`，你最多可以删除一个字符。判断是否可以把它变成回文串。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: s = "aba"
+输出: true
+解释: 原本就是回文串
+```
+
+**样例 2:**
+
+```
+输入: s = "abca"
+输出: true
+解释: 删除 'b' 或 'c'
+```
+
+**样例 3:**
+
+```
+输入: s = "abc"
+输出: false
+解释: 删除任何一个字符都不能使之变成回文串
+```
+ ### 参考代码
+ 双指针算法。从两头走到中间，发现第一对不一样的字符之后，要么删左边的，要么删右边的。
+```python
+class Solution:
+    """
+    @param s: a string
+    @return: nothing
+    """
+    def validPalindrome(self, s):
+        left, right = self.twoPointer(s, 0, len(s) - 1)            
+        if left >= right:
+            return True
+            
+        return self.isPalindrome(s, left + 1, right) or self.isPalindrome(s, left, right - 1)
+
+    def isPalindrome(self, s, left, right):
+        left, right = self.twoPointer(s, left, right)
+        return left >= right
+        
+    def twoPointer(self, s, left, right):
+        while left < right:
+            if s[left] != s[right]:
+                return left, right
+            left += 1
+            right -= 1
+        return left, right
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/valid-palindrome.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/valid-palindrome.md"
new file mode 100644
index 0000000..f3d5476
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/valid-palindrome.md"
@@ -0,0 +1,48 @@
+# 有效回文串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/valid-palindrome/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串，判断其是否为一个回文串。只考虑字母和数字，忽略大小写。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "A man, a plan, a canal: Panama"
+输出: true
+解释: "amanaplanacanalpanama"
+```
+
+**样例 2:**
+
+```
+输入: "race a car"
+输出: false
+解释: "raceacar"
+```
+ ### 参考代码
+ 使用两根指针遍历整个字符串即可.
+
+假定有指针i, j, 其中i是从前往后遍历, j是从后往前遍历.
+
+当i在j左边时继续循环, 每一次将i右移到数字/字母上, j左移到数字/字母上, 
+
+比较二者对应的字符串内的字符是否相同, 不相同则原字符串不是回文串. 
+
+如果全部的比较都相同, 说明是回文串.
+```python
+class Solution:
+    # @param {string} s A string
+    # @return {boolean} Whether the string is a valid palindrome
+    def isPalindrome(self, s):
+        start, end = 0, len(s) - 1
+        while start < end:
+            while start < end and not s[start].isalpha() and not s[start].isdigit():
+                start += 1
+            while start < end and not s[end].isalpha() and not s[end].isdigit():
+                end -= 1
+            if start < end and s[start].lower() != s[end].lower():
+                return False
+            start += 1
+            end -= 1
+        return True
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/valid-word-abbreviation.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/valid-word-abbreviation.md"
new file mode 100644
index 0000000..81fe37e
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/valid-word-abbreviation.md"
@@ -0,0 +1,79 @@
+# 检查缩写字
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/valid-word-abbreviation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个**非空字符串** `word` 和缩写 `abbr`，返回字符串是否可以和给定的缩写匹配。
+比如一个 `“word”` 的字符串仅包含以下有效缩写：
+```
+["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"]
+```
+ ### 样例说明
+ **样例 1:**
+```
+输入 : s = "internationalization", abbr = "i12iz4n"
+输出 : true
+```
+**样例 2:**
+```
+输入 : s = "apple", abbr = "a2e"
+输出 : false
+```
+ ### 参考代码
+ 用两个指针i,j分别从头开始匹配，j遇到数字，就先把数字x解析出来，然后i移动x位，继续匹配。如果不能匹配就返回false。
+```java
+public class Solution {
+    public boolean validWordAbbreviation(String word, String abbr) {
+        int i = 0, j = 0;
+        while (i < word.length() && j < abbr.length()) {
+            if (word.charAt(i) == abbr.charAt(j)) {
+                i++;
+                j++;
+            } else if ((abbr.charAt(j) > '0') && (abbr.charAt(j) <= '9')) {     //notice that 0 cannot be included
+                int start = j;
+                while (j < abbr.length() && Character.isDigit(abbr.charAt(j))) {
+                    j++;
+                }
+                i += Integer.valueOf(abbr.substring(start, j));
+            } else {
+                return false;
+            }
+        }
+        return (i == word.length()) && (j == abbr.length());
+    }
+}
+
+
+//version 高频班
+public class Solution {
+    /**
+     * @param word: a non-empty string
+     * @param abbr: an abbreviation
+     * @return: true if string matches with the given abbr or false
+     */
+    public boolean validWordAbbreviation(String word, String abbr) {
+        // write your code here
+        int i = 0, j =0;
+        char[] s = word.toCharArray();
+        char[] t = abbr.toCharArray();
+        
+        while (i < s.length && j < t.length) {
+            if (Character.isDigit(t[j])) {
+                if (t[j] == '0') {
+                    return false;
+                }
+                int val = 0;
+                while (j < t.length && Character.isDigit(t[j])) {
+                    val = val * 10 + t[j] - '0';
+                    j++;
+                }
+                i += val;
+            } else {
+                if (s[i++] != t[j++]) {
+                    return false;
+                }
+            }
+        }
+        return i == s.length && j == t.length;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/window-sum.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/window-sum.md"
new file mode 100644
index 0000000..221f96d
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/window-sum.md"
@@ -0,0 +1,35 @@
+# 滑动窗口内数的和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/window-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个大小为n的整型数组和一个大小为k的滑动窗口，将滑动窗口从头移到尾，输出从开始到结束每一个时刻滑动窗口内的数的和。
+ ### 样例说明
+ **样例 1**
+```
+输入：array = [1,2,7,8,5], k = 3
+输出：[10,17,20]
+解析：
+1 + 2 + 7 = 10
+2 + 7 + 8 = 17
+7 + 8 + 5 = 20
+```
+ ### 参考代码
+ ```python
+class Solution:
+    # @param nums {int[]} a list of integers
+    # @param k {int} size of window
+    # @return {int[]} the sum of element inside the window at each moving
+    def winSum(self, nums, k):
+        # Write your code here
+        n = len(nums)
+        if n < k or k <= 0:
+            return []
+        sums = [0] * (n - k + 1)
+        for i in range(k):
+            sums[0] += nums[i];
+
+        for i in range(1, n - k + 1):
+            sums[i] = sums[i - 1] - nums[i - 1] + nums[i + k - 1]
+
+        return sums
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/zigzag-iterator-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/zigzag-iterator-ii.md"
new file mode 100644
index 0000000..a07a8a7
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/zigzag-iterator-ii.md"
@@ -0,0 +1,59 @@
+# 左旋右旋迭代器 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/zigzag-iterator-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ *k* 个一维向量，循环地返回向量中的元素
+ ### 样例说明
+ **样例1**
+
+```
+输入: k = 3
+vecs = [
+    [1,2,3],
+    [4,5,6,7],
+    [8,9],
+]
+输出: [1,4,8,2,5,9,3,6,7]
+```
+
+**样例2**
+
+```
+输入: k = 3
+vecs = [
+    [1,1,1]
+    [2,2,2]
+    [3,3,3]
+]
+输出: [1,2,3,1,2,3,1,2,3]
+```
+ ### 参考代码
+ 用k个指针维护每个数组的当前最靠前的元素，循环枚举这k个指针，每次枚举到就在答案序列中将该数加入，如果指针到了该数组的尾部，那么就不作处理
+```python
+class ZigzagIterator2:
+
+    # @param {int[][]} a list of 1d vectors
+    def __init__(self, vecs):
+        # initialize your data structure here
+        self.queue = [v for v in vecs if v]
+
+
+    def next(self):
+        # Write your code here
+        v = self.queue.pop(0)
+        value = v.pop(0)
+        if v:
+            self.queue.append(v)
+        return value
+
+
+    def hasNext(self):
+        # Write your code here
+        return len(self.queue) > 0
+        
+
+# Your ZigzagIterator2 object will be instantiated and called as such:
+# solution, result = ZigzagIterator2(vecs), []
+# while solution.hasNext(): result.append(solution.next())
+# Output result
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/zigzag-iterator.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/zigzag-iterator.md"
new file mode 100644
index 0000000..3ec2995
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\217\214\346\214\207\351\222\210/zigzag-iterator.md"
@@ -0,0 +1,64 @@
+# 左旋右旋迭代器
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/zigzag-iterator/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你两个一维向量，实现一个迭代器，交替返回两个向量的元素
+ ### 样例说明
+ **样例1**
+
+```
+输入: v1 = [1, 2] 和 v2 = [3, 4, 5, 6]
+输出: [1, 3, 2, 4, 5, 6]
+解释:
+一开始轮换遍历两个数组，当v1数组遍历完后，就只遍历v2数组了，所以返回结果:[1, 3, 2, 4, 5, 6]
+```
+
+**样例2**
+
+```
+输入: v1 = [1, 1, 1, 1] 和 v2 = [3, 4, 5, 6]
+输出: [1, 3, 1, 4, 1, 5, 1, 6]
+```
+ ### 参考代码
+ 双指针水题，用双指针求解即可，交叉返回两数组当前位置的数，当一个数组被访问完后，就一直访问另一个数组
+```java
+public class ZigzagIterator {
+    
+    public Iterator<Integer> it1;
+    public Iterator<Integer> it2;
+    public int turns;
+
+    /**
+     * @param v1 v2 two 1d vectors
+     */
+    public ZigzagIterator(List<Integer> v1, List<Integer> v2) {
+        // initialize your data structure here.
+        this.it1 = v1.iterator();
+        this.it2 = v2.iterator();
+        turns = 0;
+    }
+
+    public int next() {
+        // Write your code here
+        turns++;
+        if((turns % 2 == 1 && it1.hasNext()) || (!it2.hasNext())) {
+            return it1.next();
+        } else if((turns % 2 == 0 && it2.hasNext()) || (!it1.hasNext())) {
+            return it2.next();
+        }
+        return -1;  
+    }
+
+    public boolean hasNext() {
+        // Write your code here
+        return it1.hasNext() || it2.hasNext();        
+    }
+}
+
+/**
+ * Your ZigzagIterator object will be instantiated and called as such:
+ * ZigzagIterator solution = new ZigzagIterator(v1, v2);
+ * while (solution.hasNext()) result.add(solution.next());
+ * Output result
+ */
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/inverted-index-map-reduce.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/inverted-index-map-reduce.md"
new file mode 100644
index 0000000..e908fbe
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/inverted-index-map-reduce.md"
@@ -0,0 +1,60 @@
+# 倒排索引 (Map Reduce版本)
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/inverted-index-map-reduce/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 使用 map reduce 来实现一个倒排索引
+ ### 样例说明
+ 看程序
+ ### 参考代码
+ ```java
+/**
+ * Definition of OutputCollector:
+ * class OutputCollector<K, V> {
+ *     public void collect(K key, V value);
+ *         // Adds a key/value pair to the output buffer
+ * }
+ * Definition of Document:
+ * class Document {
+ *     public int id;
+ *     public String content;
+ * }
+ */
+public class InvertedIndex {
+
+    public static class Map {
+        public void map(String _, Document value,
+                        OutputCollector<String, Integer> output) {
+            // Write your code here
+            // Output the results into output buffer.
+            // Ps. output.collect(String key, int value);
+            int id = value.id;
+            StringTokenizer tokenizer = new StringTokenizer(value.content);
+            while (tokenizer.hasMoreTokens()) {
+                String word = tokenizer.nextToken();
+                output.collect(word, id);
+            }
+            
+        }
+    }
+
+    public static class Reduce {
+        public void reduce(String key, Iterator<Integer> values,
+                           OutputCollector<String, List<Integer>> output) {
+            // Write your code here
+            // Output the results into output buffer.
+            // Ps. output.collect(String key, List<Integer> value);
+            List<Integer> results = new ArrayList<Integer>();
+            int previous = -1;
+            while (values.hasNext()) {
+                int now = values.next();
+                if(previous != now) {
+                    results.add(now);
+                }
+                previous = now;
+            }
+            output.collect(key, results);
+        }
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/inverted-index.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/inverted-index.md"
new file mode 100644
index 0000000..d80e44e
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/inverted-index.md"
@@ -0,0 +1,74 @@
+# 反向索引
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/inverted-index/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 创建给定文档的反向索引
+ ### 样例说明
+ 给出一个包括id与内容的文档list(我们提供了document类).
+返回一个反向索引(hashmap的key是单词, value是文档的id).
+
+例 1:
+```
+输入:
+[
+  {
+    "id": 1,
+    "content": "This is the content of document 1 it is very short"
+  },
+  {
+    "id": 2,
+    "content": "This is the content of document 2 it is very long bilabial bilabial heheh hahaha ..."
+  },
+]
+输出:
+{
+   "This": [1, 2],
+   "is": [1, 2],
+   ...
+}
+```
+
+例 2:
+```
+输入:
+[
+  {
+    "id": 1,
+    "content": "you are young"
+  },
+  {
+    "id": 2,
+    "content": "you are handsome"
+  },
+]
+输出:
+{
+   "are": [1, 2],
+   ...
+}
+```
+ ### 参考代码
+ 利用hashmap创立反向索引
+```python
+'''
+Definition of Document
+class Document:
+    def __init__(self, id, cotent):
+        self.id = id
+        self.content = content
+'''
+class Solution:
+    # @param {Document[]} docs a list of documents
+    # @return {dict(string, int[])} an inverted index
+    def invertedIndex(self, docs):
+        # Write your code here
+        rt = {}
+        for doc in docs:
+            for word in doc.content.split():
+                if word in rt:
+                    if rt[word][-1] != doc.id:
+                        rt[word].append(doc.id)
+                else:
+                    rt[word] = [doc.id]
+        return rt
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/permutation-index-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/permutation-index-ii.md"
new file mode 100644
index 0000000..1f93b46
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/permutation-index-ii.md"
@@ -0,0 +1,111 @@
+# 排列序号II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/permutation-index-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个可能包含重复数字的排列，求这些数字的所有排列按字典序排序后该排列在其中的编号。编号从1开始。</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入:[1,4,2,2]
+输出:3
+```
+
+**样例 2:**
+```
+输入 :[1,6,5,3,1]
+输出:24
+```
+
+ ### 参考代码
+ ```java
+// version 1
+public class Solution {
+    /**
+     * @param A an integer array
+     * @return a long integer
+     */
+    long fac(int numerator) {
+        long now = 1;
+        for (int i = 1; i <= numerator; i++) {
+            now *= (long) i;
+        }
+        return now;
+    }   
+    long generateNum(HashMap<Integer, Integer> hash) {
+        long denominator = 1;
+        int sum = 0;
+        for (int val : hash.values()) {
+            if(val == 0 )    
+                continue;       
+            denominator *= fac(val);
+            sum += val; 
+        }       
+        if(sum==0) {
+            return sum; 
+        }       
+        return fac(sum) / denominator;
+    }   
+
+    public long permutationIndexII(int[] A) {
+        HashMap<Integer, Integer> hash = new HashMap<Integer, Integer>();
+
+        for (int i = 0; i < A.length; i++) {
+            if (hash.containsKey(A[i]))
+                hash.put(A[i], hash.get(A[i]) + 1);
+            else {      
+                hash.put(A[i], 1);
+            }           
+        }       
+        long ans = 0;
+        for (int i = 0; i < A.length; i++) {
+            HashMap<Integer, Integer> flag = new HashMap<Integer, Integer>(); 
+
+            for (int j = i + 1; j < A.length; j++) {
+                if (A[j] < A[i] && !flag.containsKey(A[j])) {
+                    flag.put(A[j], 1);
+                    hash.put(A[j], hash.get(A[j])-1);
+                    ans += generateNum(hash);
+                    hash.put(A[j], hash.get(A[j])+1);
+                }
+
+            }
+            hash.put(A[i], hash.get(A[i])-1);
+        }
+        return ans + 1;
+    }
+}
+
+
+// version 2
+public class Solution {
+    /**
+     * @param A an integer array
+     * @return a long integer
+     */
+    public long permutationIndexII(int[] A) {
+        if (A == null || A.length == 0)
+            return 0L;
+
+        Map<Integer, Integer> counter = new HashMap<Integer, Integer>();
+        long index = 1, fact = 1, multiFact = 1;
+        for (int i = A.length - 1; i >= 0; i--) {
+            if (counter.containsKey(A[i])) {
+                counter.put(A[i], counter.get(A[i]) + 1);
+                multiFact *= counter.get(A[i]);
+            } else {
+                counter.put(A[i], 1);
+            }
+
+            int rank = 0;
+            for (int j = i + 1; j < A.length; j++) {
+                if (A[i] > A[j]) rank++;
+            }
+
+            index += rank * fact / multiFact;
+            fact *= (A.length - i);
+        }
+
+        return index;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/string-permutation.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/string-permutation.md"
new file mode 100644
index 0000000..f9b9fbb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/string-permutation.md"
@@ -0,0 +1,32 @@
+# 字符串置换
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/string-permutation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个字符串，请设计一个方法来判定其中一个字符串是否为另一个字符串的置换。
+
+置换的意思是，通过改变顺序可以使得两个字符串相等。
+ ### 样例说明
+ 
+ ### 参考代码
+ 统计字符数量，组成成分一致即可置换得到。
+```java
+public class Solution {
+    /**
+     * @param A a string
+     * @param B a string
+     * @return a boolean
+     */
+    public boolean stringPermutation(String A, String B) {
+        // Write your code here
+        int[] cnt = new int[1000];
+        for (int i = 0; i < A.length(); ++i)
+            cnt[(int)A.charAt(i)] += 1;
+        for (int i = 0; i < B.length(); ++i)
+            cnt[(int)B.charAt(i)] -= 1;
+        for (int i = 0; i < 1000; ++i)
+            if (cnt[i] != 0)
+                return false;
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/substring-with-at-least-k-distinct-characters.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/substring-with-at-least-k-distinct-characters.md"
new file mode 100644
index 0000000..d583a3c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/substring-with-at-least-k-distinct-characters.md"
@@ -0,0 +1,54 @@
+# 至少K个不同字符的子串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/substring-with-at-least-k-distinct-characters/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个仅包含小写字母的字符串 `S`.
+
+返回 `S` 中至少包含 `k` 个不同字符的子串的数量.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: S = "abcabcabca", k = 4
+输出: 0
+解释: 字符串中一共就只有 3 个不同的字符.
+```
+
+**样例 2:**
+
+```
+输入: S = "abcabcabcabc", k = 3
+输出: 55
+解释: 任意长度不小于 3 的子串都含有 a, b, c 这三个字符.
+    比如,长度为 3 的子串共有 10 个, "abc", "bca", "cab" ... "abc"
+    长度为 4 的子串共有 9 个, "abca", "bcab", "cabc" ... "cabc"
+    ...
+    长度为 12 的子串有 1 个, 就是 S 本身.
+    所以答案是 1 + 2 + ... + 10 = 55.
+```
+ ### 参考代码
+ ```python
+class Solution:
+    """
+    @param s: a string
+    @param k: an integer
+    @return: the number of substrings there are that contain at least k distinct characters
+    """
+    def kDistinctCharacters(self, s, k):
+        left = 0
+        counter = {}
+        answer = 0
+        for right in range(len(s)):
+            counter[s[right]] = counter.get(s[right], 0) + 1
+            while left <= right and len(counter) >= k:
+                counter[s[left]] -= 1
+                if counter[s[left]] == 0:
+                    del counter[s[left]]
+                left += 1
+                    
+            if len(counter) == k - 1 and left > 0 and s[left - 1] not in counter:
+                answer += left
+                
+        
+        return answer
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/top-k-frequent-words-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/top-k-frequent-words-ii.md"
new file mode 100644
index 0000000..1e89a4c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/top-k-frequent-words-ii.md"
@@ -0,0 +1,97 @@
+# 最常使用的K个单词II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/top-k-frequent-words-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在实时数据流中找到最常使用的k个单词.
+实现*TopK*类中的三个方法:
+`TopK(k)`, 构造方法
+`add(word)`, 增加一个新单词
+`topk()`, 得到当前最常使用的k个单词.
+ ### 样例说明
+ **样例 1:**
+```
+输入：
+TopK(2)
+add("lint")
+add("code")
+add("code")
+topk()
+输出：["code", "lint"]
+解释：
+"code" 出现两次并且 "lint" 出现一次， 它们是出现最频繁的两个单词。
+```
+
+**样例 2:**
+```
+输入：
+TopK(1)
+add("aa")
+add("ab")
+topk()
+输出：["aa"]
+解释：
+"aa" 和 "ab" 出现 , 但是aa的字典序小于ab。
+```
+ ### 参考代码
+ 考点：
+* set和map维护
+
+题解：
+查询前k大，考虑使用k大小的set维护即可，map存储每个单词出现的次数，然后重写compare排序方法，在set中自动排序维护，当set大小超出k后，删除最后即可。
+```java
+import java.util.NavigableSet;
+
+public class TopK {
+    private Map<String, Integer> words = null;
+    private NavigableSet<String> topk = null;
+    private int k;
+
+    private Comparator<String> myComparator = new Comparator<String>() {
+        public int compare(String left, String right) {
+            if (left.equals(right))
+                return 0;
+
+            int left_count = words.get(left);
+            int right_count = words.get(right);
+            if (left_count != right_count) {
+                return right_count - left_count;
+            }
+            return left.compareTo(right);
+        }
+    };
+
+    public TopK(int k) {
+        // initialize your data structure here
+        this.k = k;
+        words = new HashMap<String, Integer>();
+        topk = new TreeSet<String>(myComparator);
+    }
+
+    public void add(String word) {
+        // Write your code here
+        if (words.containsKey(word)) {
+            if (topk.contains(word))
+                topk.remove(word);
+            words.put(word, words.get(word) + 1);
+        } else {
+            words.put(word, 1);
+        }
+
+        topk.add(word);
+        if (topk.size() > k) {
+            topk.pollLast();
+        }
+    }
+
+    public List<String> topk() {
+        // Write your code here
+        List<String> results = new ArrayList<String>();
+        Iterator it = topk.iterator();
+        while(it.hasNext()) {
+             String str = (String)it.next();
+             results.add(str);
+        }
+        return results;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/two-sum-iii-data-structure-design.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/two-sum-iii-data-structure-design.md"
new file mode 100644
index 0000000..708c2c1
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/two-sum-iii-data-structure-design.md"
@@ -0,0 +1,55 @@
+# 两数之和 III-数据结构设计
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/two-sum-iii-data-structure-design/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计b并实现一个 TwoSum 类。他需要支持以下操作:`add` 和 `find`。
+`add` -把这个数添加到内部的数据结构。
+`find` -是否存在任意一对数字之和等于这个值
+ ### 样例说明
+ **样例 1:**
+```
+add(1);add(3);add(5);
+find(4)//返回true
+find(7)//返回false
+```
+ ### 参考代码
+ ```java
+public class TwoSum {
+
+    private List<Integer> list = null;
+    private Map<Integer, Integer> map = null;
+    public TwoSum() {
+        list = new ArrayList<Integer>();
+        map = new HashMap<Integer, Integer>();
+    }
+
+    // Add the number to an internal data structure.
+    public void add(int number) {
+        // Write your code here
+        if (map.containsKey(number)) {
+            map.put(number, map.get(number) + 1);
+        } else {
+            map.put(number, 1);
+            list.add(number);
+        }
+    }
+
+    // Find if there exists any pair of numbers which sum is equal to the value.
+    public boolean find(int value) {
+        // Write your code here
+        for (int i = 0; i < list.size(); i++) {
+            int num1 = list.get(i), num2 = value - num1;
+            if ((num1 == num2 && map.get(num1) > 1) || 
+                (num1 != num2 && map.containsKey(num2))) 
+                return true;
+        }
+        return false;
+    }
+}
+
+
+// Your TwoSum object will be instantiated and called as such:
+// TwoSum twoSum = new TwoSum();
+// twoSum.add(number);
+// twoSum.find(value);
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/two-sum.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/two-sum.md"
new file mode 100644
index 0000000..6f3fd72
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/two-sum.md"
@@ -0,0 +1,51 @@
+# 两数之和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/two-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个整数数组，找到两个数使得他们的和等于一个给定的数 *target*。
+
+你需要实现的函数`twoSum`需要返回这两个数的下标, 并且第一个下标小于第二个下标。注意这里下标的范围是 0 到 *n-1*。
+
+ ### 样例说明
+ ```
+Example1:
+给出 numbers = [2, 7, 11, 15], target = 9, 返回 [0, 1].
+Example2:
+给出 numbers = [15, 2, 7, 11], target = 9, 返回 [1, 2].
+```
+ ### 参考代码
+ Given an array of integers, find two numbers such that they add up to a specific target number.
+
+The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
+
+You may assume that each input would have exactly one solution.
+
+Input: numbers={2, 7, 11, 15}, target=9
+Output: index1=1, index2=2
+```java
+public class Solution {
+    /*
+     * @param numbers : An array of Integer
+     * @param target : target = numbers[index1] + numbers[index2]
+     * @return : [index1 + 1, index2 + 1] (index1 < index2)
+         numbers=[2, 7, 11, 15],  target=9
+         return [1, 2]
+     */
+    public int[] twoSum(int[] numbers, int target) {
+        //用一个hashmap来记录，key记录target-numbers[i]的值，value记录numbers[i]的i的值，如果碰到一个
+        //numbers[j]在hashmap中存在，那么说明前面的某个numbers[i]和numbers[j]的和为target，i和j即为答案
+        HashMap<Integer,Integer> map = new HashMap<>();
+
+        for (int i = 0; i < numbers.length; i++) {
+            if (map.get(numbers[i]) != null) {
+                int[] result = {map.get(numbers[i]), i};
+                return result;
+            }
+            map.put(target - numbers[i], i);
+        }
+        
+        int[] result = {};
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/typeahead.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/typeahead.md"
new file mode 100644
index 0000000..f22b113
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/typeahead.md"
@@ -0,0 +1,53 @@
+# 自动补全
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/typeahead/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个typeahead功能，给出一个字符串和一个字典，包含若干个单词，返回所有含有这个字符串子串的单词；字典不能被修改，并且这个方法可能被调用多次。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```cpp
+class Typeahead {
+private:
+    map<string, vector<int>> mp;
+    vector<string> strs; 
+public:
+    // @param dict: A dictionary of words dict
+    Typeahead(unordered_set<string> &dict) {
+        // do initialize if necessary
+        int cnt = 0;
+        for (string str : dict) {
+            strs.push_back(str);
+            int len = str.size();
+            for (int i = 0; i < len; ++i)
+                for (int j = i + 1; j <= len; ++j) {
+                    string tmp = str.substr(i, j - i);
+                    if (mp.find(tmp) == mp.end()) {
+                        mp[tmp] = vector<int>();
+                        mp[tmp].push_back(cnt);
+                    } else {
+                        if (mp[tmp][mp[tmp].size() - 1] != cnt)
+                            mp[tmp].push_back(cnt);
+                    }
+                }
+            cnt ++;
+        }
+    }
+    
+    // @param str: a string
+    // @return a set of words
+    vector<string> search(string &str) {
+        // Write your code here
+        if (mp.find(str) == mp.end()) {
+            return vector<string>();
+        } else {
+            vector<string> results;
+            int len = mp[str].size();
+            for (int i = 0; i < len; ++i) {
+                results.push_back(strs[mp[str][i]]);
+            }
+            return results;
+        }
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/unique-characters.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/unique-characters.md"
new file mode 100644
index 0000000..3733957
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/unique-characters.md"
@@ -0,0 +1,39 @@
+# 判断字符串是否没有重复字符
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/unique-characters/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个算法确定字符串中的字符是否均唯一出现
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:  "abc_____"
+输出:  false
+```
+
+**样例 2:**
+
+```
+输入:  "abc"
+输出:  true	
+```
+ ### 参考代码
+ 使用一个map或数组标记每个字符是否出现过。
+```java
+public class Solution {
+    /**
+     * @param str: a string
+     * @return: a boolean
+     */
+    public boolean isUnique(String str) {
+        // write your code here
+        boolean[] char_set = new boolean[256];
+        for (int i = 0; i < str.length(); i++) {
+        int val = str.charAt(i);
+        if (char_set[val]) return false;
+            char_set[val] = true;
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/word-abbreviation-set.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/word-abbreviation-set.md"
new file mode 100644
index 0000000..9c20030
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/word-abbreviation-set.md"
@@ -0,0 +1,116 @@
+# 单词缩写集
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/word-abbreviation-set/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 一个单词的缩写根据以下的形式。下面是一些缩写的例子
+```
+a) it                      --> it    (没有缩写)
+
+     1
+b) d|o|g                   --> d1g
+
+              1    1  1
+     1---5----0----5--8
+c) i|nternationalizatio|n  --> i18n
+
+              1
+     1---5----0
+d) l|ocalizatio|n          --> l10n
+```
+假设你有一个字典和给你一个单词，判断这个单词的缩写在字典中是否是唯一的。当字典中的**其他单词的缩写**均与它不同的时候， 这个单词的缩写是唯一的.
+ ### 样例说明
+ 
+ ### 参考代码
+ 判断待查找的单词在字典中出现的次数是否和缩写在缩写字典中出现的次数一样
+```java
+public class ValidWordAbbr {
+
+    private Map<String,Set<String>> d;
+
+    // @param dictionary a list of word
+    public ValidWordAbbr(String[] dictionary) {
+        // Write your code here
+        d = new HashMap<String, Set<String>>();
+        for (int i = 0;i < dictionary.length; i++) {
+            String w = dictionary[i];
+            String abbr = getAbbr(w); 
+        
+            if (d.containsKey(abbr)) {
+                Set<String> s = d.get(abbr);
+                if (!s.contains(w)) s.add(w);
+            } else {
+                Set<String> s = new HashSet<String>();
+                s.add(w);
+                d.put(abbr,s);
+            }
+        }
+    }
+
+    /**
+     * @param word a string
+     * @return true if its abbreviation is unique or false
+     */
+    public boolean isUnique(String word) {
+        // Write your code here
+        String a = getAbbr(word);
+        if (d.containsKey(a)) {
+            Set<String> s = d.get(a);
+            if (s.size() == 1 && s.contains(word)) {
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            return true;
+        }
+    }
+
+    private String getAbbr(String w){
+        int len = w.length() - 2;
+        if (len <= 0) {
+            return w;
+        }
+        return "" + w.charAt(0) + len + w.charAt(w.length() - 1);
+    }
+}
+
+/**
+ * Your ValidWordAbbr object will be instantiated and called as such:
+ * ValidWordAbbr obj = new ValidWordAbbr(dictionary);
+ * boolean param = obj.isUnique(word);
+ */
+
+
+
+// version: 高频题班
+public class ValidWordAbbr {
+    Map<String, Integer> dict = new HashMap<>();
+    Map<String, Integer> abbr = new HashMap<>();
+
+    // @param dictionary a list of word
+    public ValidWordAbbr(String[] dictionary) {
+        // Write your code here
+        for (String d : dictionary) {
+            dict.put(d, dict.getOrDefault(d, 0) + 1);
+            String a = getAbbr(d);
+            abbr.put(a, abbr.getOrDefault(a, 0) + 1);
+        }
+    }
+    /**
+     * @param word a string
+     * @return true if its abbreviation is unique or false
+     */
+    public boolean isUnique(String word) {
+        // Write your code here
+        String a = getAbbr(word);
+        return dict.get(word) == abbr.get(a);
+    }
+
+    String getAbbr(String str) {
+        if (str.length() <= 2) {
+            return str;
+        }
+        return "" + str.charAt(0) + (str.length() - 2) + str.charAt(str.length() - 1);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/words-abbreviation.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/words-abbreviation.md"
new file mode 100644
index 0000000..05474fd
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\255\227\345\205\270MAP/words-abbreviation.md"
@@ -0,0 +1,115 @@
+# 单词缩写
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/words-abbreviation/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一组 n 个不同的非空字符串，您需要按以下规则为每个单词生成 **最小** 的缩写。
+1. 从第一个字符开始，然后加上中间缩写掉的字符的长度，后跟最后一个字符。
+2. 如果有冲突，就是多个单词共享相同的缩写，使用较长的前缀，而不是仅使用第一个字符，直到使单词的缩写的映射变为唯一。 换句话说，最终得到的缩写不能映射到多个原始单词。
+3. 如果缩写不会使单词更短，则不进行缩写，保持原样。
+ ### 样例说明
+ 
+ ### 参考代码
+ map自动排序，判断重复。
+重复则缩写的位数 --，直到不重复
+不重复则判断是否进行缩写。
+```java
+public class Solution {
+    /**
+     * @param dict an array of n distinct non-empty strings
+     * @return an array of minimal possible abbreviations for every word
+     */
+    public String[] wordsAbbreviation(String[] dict) {
+        // Write your code here
+        if (dict == null || dict.length == 0) {
+            return new String[0];
+        }
+
+        int n = dict.length;
+        String[] res = new String[n];
+        List<Integer> results = new ArrayList<Integer>();
+        for (int i = 0; i < dict.length; i++) {
+            results.add(i);
+        }
+        int len = 2;
+        while (!results.isEmpty()) {
+            Map<String, Set<Integer>> map = new HashMap<String, Set<Integer>>();
+            for (int i : results) {
+                String curr = dict[i];
+                String abbr = curr.length() <= (len + 1) ?
+                    curr : curr.substring(0, len - 1) + (curr.length() - len) + curr.charAt(curr.length() - 1);
+                if (map.containsKey(abbr)) {
+                    map.get(abbr).add(i);
+                } else {
+                    Set<Integer> set = new HashSet<Integer>();
+                    set.add(i);
+                    map.put(abbr, set);
+                }
+            }
+            
+            List<Integer> next = new ArrayList<Integer>();
+            for (String word : map.keySet()) {
+                if (map.get(word).size() == 1) {
+                    int index = -1;
+                    for (int i : map.get(word)) {
+                        index = i;
+                    }
+                    res[index] = word;
+                } else {
+                    for (int i : map.get(word)) {
+                        next.add(i);
+                    }
+                }
+            }
+            results = next;
+            len++;
+        }
+        return res;
+    }
+}
+
+// version: 高频题班
+
+public class Solution {
+    /**
+     * @param dict an array of n distinct non-empty strings
+     * @return an array of minimal possible abbreviations for every word
+     */
+    public String[] wordsAbbreviation(String[] dict) {
+        int len = dict.length;
+        String[] ans = new String[len];
+        int[] prefix = new int[len];
+        Map<String, Integer> count = new HashMap<>();
+
+        for (int i = 0; i < len; i++) {
+            prefix[i] = 1;
+            ans[i] = getAbbr(dict[i], 1);
+            count.put(ans[i], count.getOrDefault(ans[i], 0) + 1);
+        }
+
+        while (true) {
+            boolean unique = true;
+            for (int i = 0; i < len; i++) {
+                if (count.get(ans[i]) > 1) {
+                    prefix[i]++;
+                    ans[i] = getAbbr(dict[i], prefix[i]);
+                    count.put(ans[i], count.getOrDefault(ans[i], 0) + 1);
+                    unique = false;
+                }
+            }
+            if (unique) {
+                break;
+            }
+        }
+        return ans;
+    }
+
+    String getAbbr(String s, int p) {
+        if (p >= s.length() - 2) {
+            return s;
+        }
+        String ans;
+        ans = s.substring(0, p) + (s.length() - 1 - p) + s.charAt(s.length() - 1);
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/accounts-merge.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/accounts-merge.md"
new file mode 100644
index 0000000..79afb2b
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/accounts-merge.md"
@@ -0,0 +1,127 @@
+# 账户合并
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/accounts-merge/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个帐户列表，每个元素`accounts [i]`是一个字符串列表，其中第一个元素`accounts [i] [0]`是账户名称，其余元素是这个帐户的电子邮件。
+现在，我们想合并这些帐户。
+如果两个帐户有相同的电子邮件地址，则这两个帐户肯定属于同一个人。
+请注意，即使两个帐户具有相同的名称，它们也可能属于不同的人，因为两个不同的人可能会使用相同的名称。
+一个人可以拥有任意数量的账户，但他的所有帐户肯定具有相同的名称。
+合并帐户后，按以下格式返回帐户：每个帐户的第一个元素是名称，其余元素是**按字典序排序**后的电子邮件。
+帐户本身可以按任何顺序返回。
+ ### 样例说明
+ ```
+样例 1:
+	输入:
+	[
+		["John", "johnsmith@mail.com", "john00@mail.com"],
+		["John", "johnnybravo@mail.com"],
+		["John", "johnsmith@mail.com", "john_newyork@mail.com"],
+		["Mary", "mary@mail.com"]
+	]
+	
+	输出: 
+	[
+		["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'],
+		["John", "johnnybravo@mail.com"],
+		["Mary", "mary@mail.com"]
+	]
+
+	解释: 
+	第一个第三个John是同一个人的账户，因为这两个账户有相同的邮箱："johnsmith@mail.com".
+	剩下的两个账户分别是不同的人。因为他们没有和别的账户有相同的邮箱。
+
+	你可以以任意顺序返回结果。比如：
+	
+	[
+		['Mary', 'mary@mail.com'],
+		['John', 'johnnybravo@mail.com'],
+		['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']
+	]
+	也是可以的。
+
+```
+ ### 参考代码
+ 使用算法强化版所讲的并查集。
+```java
+public class Solution {
+    Map<Integer, Integer> father;
+    /**
+     * @param accounts: List[List[str]]
+     * @return: return a List[List[str]]
+     */
+    public List<List<String>> accountsMerge(List<List<String>> accounts) {
+        father = new HashMap();
+        
+        // union
+        Map<String, List> emailToIds = getEmailToIds(accounts);
+        for (String email : emailToIds.keySet()) {
+            List<Integer> ids = emailToIds.get(email);
+            for (int i = 1; i < ids.size(); i++) {
+                union(ids.get(i), ids.get(0));
+            }
+        }
+        
+        // merge accounts
+        Map<Integer, Set<String>> idToEmailSet = getIdToEmailSet(accounts);
+        List<List<String>> mergedAccounts = new ArrayList<>();
+        for (Integer id : idToEmailSet.keySet()) {
+            List<String> sortedEmails = new ArrayList(idToEmailSet.get(id));
+            Collections.sort(sortedEmails);
+            sortedEmails.add(0, accounts.get(id).get(0));
+            mergedAccounts.add(sortedEmails);
+        }
+        
+        return mergedAccounts;
+    }
+    
+    private Map<String, List> getEmailToIds(List<List<String>> accounts) {
+        Map<String, List> emailToIds = new HashMap<>();
+        for (int user_id  = 0; user_id < accounts.size(); user_id++) {
+            List<String> account = accounts.get(user_id);
+            for (int i = 1; i < account.size(); i++) {
+                List<Integer> ids = emailToIds.getOrDefault(account.get(i), new ArrayList<Integer>());
+                ids.add(user_id);
+                emailToIds.put(account.get(i), ids);
+            }
+        }
+        return emailToIds;
+    }
+    
+    private Map<Integer, Set<String>> getIdToEmailSet(List<List<String>> accounts) {
+        Map<Integer, Set<String>> idToEmailSet = new HashMap<>();
+        for (int user_id  = 0; user_id < accounts.size(); user_id++) {
+            int root_id = find(user_id);
+            Set<String> emailSet = idToEmailSet.getOrDefault(root_id, new HashSet<String>());
+            List<String> account = accounts.get(user_id);
+            for (int i = 1; i < account.size(); i++) {
+                emailSet.add(account.get(i));
+            }
+            idToEmailSet.put(root_id, emailSet);
+        }
+        return idToEmailSet;
+    }
+    
+    private int find(int id) {
+        List<Integer> path = new ArrayList<>();
+        while (father.containsKey(id)) {
+            path.add(id);
+            id = father.get(id);
+        }
+        
+        for (Integer i : path) {
+            father.put(i, id);
+        }
+        
+        return id;
+    }
+    
+    private void union(int id1, int id2) {
+        int root1 = find(id1);
+        int root2 = find(id2);
+        if (root1 != root2) {
+            father.put(root1, root2);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connected-component-in-undirected-graph.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connected-component-in-undirected-graph.md"
new file mode 100644
index 0000000..16ace4e
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connected-component-in-undirected-graph.md"
@@ -0,0 +1,194 @@
+# 找无向图的连通块
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/connected-component-in-undirected-graph/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 找出无向图中所有的连通块。
+
+图中的每个节点包含一个label属性和一个邻接点的列表。
+
+（一个无向图的连通块是一个子图，其中任意两个顶点通过路径相连，且不与整个图中的其它顶点相连。）
+
+你需要返回 label 集合的列表.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,2,4#2,1,4#3,5#4,1,2#5,3}
+输出: [[1,2,4],[3,5]]
+解释: 
+
+  1------2  3
+   \     |  | 
+    \    |  |
+     \   |  |
+      \  |  |
+        4   5
+```
+
+**样例 2:**
+
+```
+输入: {1,2#2,1}
+输出: [[1,2]]
+解释:
+
+  1--2
+
+```
+ ### 参考代码
+ 无向图连通块, 可以使用BFS或者并查集union find求解                         .
+```java
+/**
+  * 本代码由九章算法编辑提供。版权所有，转发请注明出处。
+  * - 九章算法致力于帮助更多中国人找到好的工作，教师团队均来自硅谷和国内的一线大公司在职工程师。
+  * - 现有的面试培训课程包括：九章算法班，系统设计班，算法强化班，Java入门与基础算法班，Android 项目实战班，Big Data 项目实战班，
+  * - 更多详情请见官方网站：http://www.jiuzhang.com/?source=code
+  */ 
+
+// bfs 方法
+/**
+ * Definition for Undirected graph.
+ * class UndirectedGraphNode {
+ *     int label;
+ *     ArrayList<UndirectedGraphNode> neighbors;
+ *     UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
+ * };
+ */
+public class Solution {
+    /**
+     * @param nodes a array of Undirected graph node
+     * @return a connected set of a Undirected graph
+     */
+    public List<List<Integer>> connectedSet(List<UndirectedGraphNode> nodes) {
+        // Write your code here
+        
+        Map<UndirectedGraphNode, Boolean> visited = new HashMap<>();
+        
+       for (UndirectedGraphNode node : nodes){
+            visited.put(node, false);
+       }
+        
+        List<List<Integer>> result = new ArrayList<>();
+        
+        for (UndirectedGraphNode node : nodes){
+            if (visited.get(node) == false){
+                bfs(node, visited, result);
+            }
+        }
+        
+        return result;
+    }
+    
+    public void bfs(UndirectedGraphNode node, Map<UndirectedGraphNode, Boolean> visited, List<List<Integer>> result){
+        List<Integer>row = new ArrayList<>();
+        Queue<UndirectedGraphNode> queue = new LinkedList<>();
+        visited.put(node, true);
+        queue.offer(node);
+        while (!queue.isEmpty()){
+            UndirectedGraphNode u = queue.poll();
+            row.add(u.label);    
+            for (UndirectedGraphNode v : u.neighbors){
+                if (visited.get(v) == false){
+                    visited.put(v, true);
+                    queue.offer(v);
+                }
+            }
+        }
+        Collections.sort(row);
+        result.add(row);
+        
+    }
+}
+
+//------------------------我是分割线--------------------------------------
+// 并查集方法
+public
+class Solution {
+    class UnionFind {
+        HashMap<Integer, Integer> father = new HashMap<Integer, Integer>();
+        UnionFind(HashSet<Integer> hashSet)
+        {
+            for (Integer now : hashSet) {
+                father.put(now, now);
+            }
+        }
+        int find(int x)
+        {
+            int parent = father.get(x);
+            while (parent != father.get(parent)) {
+                parent = father.get(parent);
+            }
+            return parent;
+        }
+        int compressed_find(int x)
+        {
+            int parent = father.get(x);
+            while (parent != father.get(parent)) {
+                parent = father.get(parent);
+            }
+            int next;
+            while (x != father.get(x)) {
+                next = father.get(x);
+                father.put(x, parent);
+                x = next;
+            }
+            return parent;
+        }
+
+        void union(int x, int y)
+        {
+            int fa_x = find(x);
+            int fa_y = find(y);
+            if (fa_x != fa_y)
+                father.put(fa_x, fa_y);
+        }
+    }
+    
+    List<List<Integer> > print(HashSet<Integer> hashSet, UnionFind uf, int n) {
+        List<List<Integer> > ans = new ArrayList<List<Integer> >();
+        HashMap<Integer, List<Integer> > hashMap = new HashMap<Integer, List<Integer> >();
+        for (int i : hashSet) {
+            int fa = uf.find(i);
+            if (!hashMap.containsKey(fa)) {
+                hashMap.put(fa, new ArrayList<Integer>());
+            }
+            List<Integer> now = hashMap.get(fa);
+            now.add(i);
+            hashMap.put(fa, now);
+        }
+        for (List<Integer> now : hashMap.values()) {
+            Collections.sort(now);
+            ans.add(now);
+        }
+        return ans;
+    }
+
+public
+    List<List<Integer> > connectedSet(List<UndirectedGraphNode> nodes)
+    {
+        // Write your code here
+
+        HashSet<Integer> hashSet = new HashSet<Integer>();
+        for (UndirectedGraphNode now : nodes) {
+            hashSet.add(now.label);
+            for (UndirectedGraphNode neighbour : now.neighbors) {
+                hashSet.add(neighbour.label);
+            }
+        }
+        UnionFind uf = new UnionFind(hashSet);
+
+        for (UndirectedGraphNode now : nodes) {
+
+            for (UndirectedGraphNode neighbour : now.neighbors) {
+                int fnow = uf.find(now.label);
+                int fneighbour = uf.find(neighbour.label);
+                if (fnow != fneighbour) {
+                    uf.union(now.label, neighbour.label);
+                }
+            }
+        }
+
+        return print(hashSet, uf, nodes.size());
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connecting-graph-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connecting-graph-ii.md"
new file mode 100644
index 0000000..298ae35
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connecting-graph-ii.md"
@@ -0,0 +1,95 @@
+# 连接图 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/connecting-graph-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个图中的 `n` 个节点, 记为 `1` 到 `n` .在开始的时候图中没有边.
+你需要完成下面两个方法：
+1. 	`connect(a, b)`, 添加一条连接节点 a, b的边
+2. 	`query(a)`, 返回图中含 `a` 的联通区域内节点个数
+ ### 样例说明
+ 例1:
+```
+输入:
+ConnectingGraph2(5)
+query(1)
+connect(1, 2)
+query(1)
+connect(2, 4)
+query(1)
+connect(1, 4)
+query(1)
+
+输出:
+[1,2,3,3]
+
+
+```
+例2:
+```
+输入:
+ConnectingGraph2(6)
+query(1)
+query(2)
+query(1)
+query(5)
+query(1)
+
+
+输出:
+[1,1,1,1,1]
+
+
+```
+
+ ### 参考代码
+ 并查集。
+同时维护一下个数即可。
+```java
+public class ConnectingGraph2 { 
+
+    private int[] father = null;
+    private int[] size = null;
+
+    private int find(int x) {
+        int j, k, fx;
+        j = x;
+        while (father[j] != j){
+            j = father[j];
+        }
+        
+        while (x != j){
+            fx = father[x];
+            father[x] = j;
+            x = fx;
+        }
+        
+        return j;
+    }
+
+    public ConnectingGraph2(int n) {
+        // initialize your data structure here.
+        father = new int[n + 1];
+        size = new int[n + 1];
+        for (int i = 1; i <= n; ++i) {
+            father[i] = i;
+            size[i] = 1;
+        }
+    }
+
+    public void connect(int a, int b) {
+        // Write your code here
+        int root_a = find(a);
+        int root_b = find(b);
+        if (root_a != root_b) {
+            father[root_a] = root_b;
+            size[root_b] += size[root_a];
+        }
+    }
+        
+    public int query(int a) {
+        // Write your code here
+        int root_a = find(a);
+        return size[root_a];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connecting-graph-iii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connecting-graph-iii.md"
new file mode 100644
index 0000000..d8dd89a
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connecting-graph-iii.md"
@@ -0,0 +1,84 @@
+# 连接图 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/connecting-graph-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个图中的 `n` 个节点, 记为 `1` 到 `n` . 在开始的时候图中没有边.
+你需要完成下面两个方法:
+1. 	`connect(a, b)`, 添加一条连接节点 a, b的边
+2. 	`query()`, 返回图中联通区域个数
+ ### 样例说明
+ 例1:
+```
+输入:
+ConnectingGraph3(5)
+query()
+connect(1, 2)
+query()
+connect(2, 4)
+query()
+connect(1, 4)
+query()
+
+输出:[5,4,3,3]
+
+```
+
+例2:
+```
+输入:
+ConnectingGraph3(6)
+query()
+query()
+query()
+query()
+query()
+
+
+输出:
+[6,6,6,6,6]
+
+
+```
+
+ ### 参考代码
+ 并查集。
+实时维护区域的个数，即若在某一次合并中两个区域合并成一个，那么数量-1。
+```python
+class ConnectingGraph3:
+    """
+    @param: n: An integer
+    """
+    def __init__(self, n):
+        self.size = n
+        self.father = {}
+        for i in range(1, n + 1):
+            self.father[i] = i
+
+    """
+    @param: a: An integer
+    @param: b: An integer
+    @return: nothing
+    """
+    def connect(self, a, b):
+        root_a = self.find(a)
+        root_b = self.find(b)
+        if root_a != root_b:
+            self.father[root_a] = root_b
+            self.size -= 1
+            
+    """
+    @return: An integer
+    """
+    def query(self):
+        return self.size
+
+    def find(self, node):
+        path = []
+        while node != self.father[node]:
+            path.append(node)
+            node = self.father[node]
+        
+        for n in path:
+            self.father[n] = node
+        return node
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connecting-graph.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connecting-graph.md"
new file mode 100644
index 0000000..5a8d909
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/connecting-graph.md"
@@ -0,0 +1,49 @@
+# 连接图
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/connecting-graph/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个图中的`n`个节点, 记为 `1` 到 `n` . 在开始的时候图中没有边。
+你需要完成下面两个方法:
+1. `connect(a, b)`, 添加连接节点 `a`, `b` 的边.
+2. `query(a, b)`, 检验两个节点是否联通
+ ### 样例说明
+ 
+ ### 参考代码
+ 简单并查集实现并和查操作。
+```python
+class ConnectingGraph:
+    """
+    @param: n: An integer
+    """
+    def __init__(self, n):
+        self.father = {}
+        for i in range(1, n + 1):
+            self.father[i] = i
+
+    """
+    @param: a: An integer
+    @param: b: An integer
+    @return: nothing
+    """
+    def connect(self, a, b):
+        self.father[self.find(a)] = self.find(b)
+
+    """
+    @param: a: An integer
+    @param: b: An integer
+    @return: A boolean
+    """
+    def query(self, a, b):
+        return self.find(a) == self.find(b)
+        
+    def find(self, node):
+        path = []
+        while self.father[node] != node:
+            path.append(node)
+            node = self.father[node]
+            
+        for n in path:
+            self.father[n] = node
+            
+        return node
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/find-the-weak-connected-component-in-the-directed-graph.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/find-the-weak-connected-component-in-the-directed-graph.md"
new file mode 100644
index 0000000..3244182
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/find-the-weak-connected-component-in-the-directed-graph.md"
@@ -0,0 +1,82 @@
+# 找出有向图中的弱连通分量
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-the-weak-connected-component-in-the-directed-graph/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 请找出有向图中弱连通分量。图中的每个节点包含 1 个标签和1 个相邻节点列表。（有向图的弱连通分量是任意两点均有有向边相连的极大子图）
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: {1,2,4#2,4#3,5#4#5#6,5}
+输出: [[1,2,4],[3,5,6]]
+解释: 
+  1----->2    3-->5
+   \     |        ^
+    \    |        |
+     \   |        6
+      \  v
+       ->4
+```
+
+**样例 2:**
+
+```
+输入: {1,2#2,3#3,1}
+输出: [[1,2,3]]
+```
+ ### 参考代码
+ 可以把每条有向边看成无向边, 就等同于在无向图中寻找联通块. 
+
+两种做法: 1. BFS/DFS 2. 并查集 (但由于输入数据是有向边, 所以使用并查集更合适, 否则还需要先把有向边转换成无向边)
+
+可以参考 [431. 找无向图的连通块](https://www.lintcode.com/problem/connected-component-in-undirected-graph/description)
+```python
+# Definition for a directed graph node
+# class DirectedGraphNode:
+#     def __init__(self, x):
+#         self.label = x
+#         self.neighbors = []
+class Solution:
+    def __init__(self):
+        self.f = {}
+
+    def merge(self, x, y):
+        x = self.find(x)
+        y = self.find(y)
+        if x != y:
+            self.f[x] = y
+
+    def find(self, x):
+        if self.f[x] == x:
+            return x
+        
+        self.f[x] = self.find(self.f[x])
+        return self.f[x]
+
+    # @param {DirectedGraphNode[]} nodes a array of directed graph node
+    # @return {int[][]} a connected set of a directed graph
+    def connectedSet2(self, nodes):
+        for node in nodes:
+            self.f[node.label] = node.label
+
+        for node in nodes:
+            for nei in node.neighbors:
+                self.merge(node.label, nei.label)
+
+        result = []
+        g = {}
+        cnt = 0
+
+        for node in nodes:
+            x = self.find(node.label)
+            if not x in g:
+                cnt += 1
+                g[x] = cnt
+            
+            if len(result) < cnt:
+                result.append([])
+        
+            result[g[x] - 1].append(node.label)
+
+        return result
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/graph-valid-tree.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/graph-valid-tree.md"
new file mode 100644
index 0000000..e163ddb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/graph-valid-tree.md"
@@ -0,0 +1,131 @@
+# 图是否是树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/graph-valid-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出 `n` 个节点，标号分别从 `0` 到 `n - 1` 并且给出一个 `无向` 边的列表 (给出每条边的两个顶点), 写一个函数去判断这张｀无向｀图是否是一棵树
+
+ ### 样例说明
+ **样例 1:**
+```
+输入: n = 5 edges = [[0, 1], [0, 2], [0, 3], [1, 4]]
+输出: true.
+```
+
+**样例 2:**
+```
+输入: n = 5 edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
+输出: false.
+```
+ ### 参考代码
+ ```java
+// version 1: BFS
+public class Solution {
+    /**
+     * @param n an integer
+     * @param edges a list of undirected edges
+     * @return true if it's a valid tree, or false
+     */
+    public boolean validTree(int n, int[][] edges) {
+        if (n == 0) {
+            return false;
+        }
+        
+        if (edges.length != n - 1) {
+            return false;
+        }
+        
+        Map<Integer, Set<Integer>> graph = initializeGraph(n, edges);
+        
+        // bfs
+        Queue<Integer> queue = new LinkedList<>();
+        Set<Integer> hash = new HashSet<>();
+        
+        queue.offer(0);
+        hash.add(0);
+        while (!queue.isEmpty()) {
+            int node = queue.poll();
+            for (Integer neighbor : graph.get(node)) {
+                if (hash.contains(neighbor)) {
+                    continue;
+                }
+                hash.add(neighbor);
+                queue.offer(neighbor);
+            }
+        }
+        
+        return (hash.size() == n);
+    }
+    
+    private Map<Integer, Set<Integer>> initializeGraph(int n, int[][] edges) {
+        Map<Integer, Set<Integer>> graph = new HashMap<>();
+        for (int i = 0; i < n; i++) {
+            graph.put(i, new HashSet<Integer>());
+        }
+        
+        for (int i = 0; i < edges.length; i++) {
+            int u = edges[i][0];
+            int v = edges[i][1];
+            graph.get(u).add(v);
+            graph.get(v).add(u);
+        }
+        
+        return graph;
+    }
+}
+
+
+// version 2: Union Find
+public class Solution {
+      class UnionFind{
+        HashMap<Integer, Integer> father = new HashMap<Integer, Integer>();
+        UnionFind(int n){
+            for(int i = 0 ; i < n; i++) {
+                father.put(i, i); 
+            }
+        }
+        int compressed_find(int x){
+            int parent =  father.get(x);
+            while(parent!=father.get(parent)) {
+                parent = father.get(parent);
+            }
+            int temp = -1;
+            int fa = father.get(x);
+            while(fa!=father.get(fa)) {
+                temp = father.get(fa);
+                father.put(fa, parent) ;
+                fa = temp;
+            }
+            return parent;
+                
+        }
+        
+        void union(int x, int y){
+            int fa_x = compressed_find(x);
+            int fa_y = compressed_find(y);
+            if(fa_x != fa_y)
+                father.put(fa_x, fa_y);
+        }
+    }
+    /**
+     * @param n an integer
+     * @param edges a list of undirected edges
+     * @return true if it's a valid tree, or false
+     */
+    public boolean validTree(int n, int[][] edges) {
+        // tree should have n nodes with n-1 edges
+        if (n - 1 != edges.length) {
+            return false;
+        }
+        
+        UnionFind uf = new UnionFind(n);
+        
+        for (int i = 0; i < edges.length; i++) {
+            if (uf.compressed_find(edges[i][0]) == uf.compressed_find(edges[i][1])) {
+                return false;
+            }
+            uf.union(edges[i][0], edges[i][1]);
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/minimum-spanning-tree.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/minimum-spanning-tree.md"
new file mode 100644
index 0000000..920241a
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/minimum-spanning-tree.md"
@@ -0,0 +1,104 @@
+# 最小生成树
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-spanning-tree/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一些Connections，即Connections类，找到一些能够将所有城市都连接起来并且花费最小的边。
+如果说可以将所有城市都连接起来，则返回这个连接方法；不然的话返回一个空列表。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+["Acity","Bcity",1]
+["Acity","Ccity",2]
+["Bcity","Ccity",3]
+输出:
+["Acity","Bcity",1]
+["Acity","Ccity",2]
+```
+
+**样例 2:**
+```
+输入:
+["Acity","Bcity",2]
+["Bcity","Dcity",5]
+["Acity","Dcity",4]
+["Ccity","Ecity",1]
+输出:
+[]
+
+解释:
+没有办法连通
+```
+ ### 参考代码
+ 用map存储自动排序，再利用并查集，连通的点根应该相同。
+```cpp
+/**
+ * Definition for a Connection.
+ * class Connection {
+ * public:
+ *   string city1, city2;
+ *   int cost;
+ *   Connection(string& city1, string& city2, int cost) {
+ *       this->city1 = city1;
+ *       this->city2 = city2;
+ *       this->cost = cost;
+ * }
+ */
+bool cmp(const Connection& c1, const Connection& c2) {
+    if (c1.cost != c2.cost)
+        return c1.cost < c2.cost;
+
+    if (c1.city1 != c2.city1)
+        return c1.city1 < c2.city1;
+
+    return c1.city2 < c2.city2;
+}
+
+class Solution {
+public:
+    /**
+     * @param connections given a list of connections include two cities and cost
+     * @return a list of connections from results
+     */
+    vector<Connection> lowestCost(vector<Connection>& connections) {
+        // Write your code here
+        sort(connections.begin(), connections.end(), cmp);
+        unordered_map<string, int> hash;
+        int n = 0;
+        for (auto connection : connections) {
+            if (hash.find(connection.city1) == hash.end()) {
+                hash[connection.city1] = ++n;
+            }
+            if (hash.find(connection.city2) == hash.end()) {
+                hash[connection.city2] = ++n;
+            }
+        }
+
+        vector<int> father(n + 1, 0);
+
+        vector<Connection> results;
+        for (auto connection : connections) {
+            int num1 = hash[connection.city1];
+            int num2 = hash[connection.city2];
+
+            int root1 = find(num1, father);
+            int root2 = find(num2, father);
+            if (root1 != root2) {
+                father[root1] = root2;
+                results.push_back(connection);
+            }
+        }
+
+        if (results.size() != n - 1)
+            return vector<Connection>();
+        return results;
+    }
+
+    int find(int num, vector<int>& father) {
+        if (father[num] == 0)
+            return num;
+
+        return father[num] = find(father[num], father);
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/number-of-islands-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/number-of-islands-ii.md"
new file mode 100644
index 0000000..0602999
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/number-of-islands-ii.md"
@@ -0,0 +1,110 @@
+# 岛屿的个数II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/number-of-islands-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定 n, m, 分别代表一个二维矩阵的行数和列数, 并给定一个大小为 k 的二元数组A. 初始二维矩阵全0. 二元数组A内的k个元素代表k次操作, 设第i个元素为 `(A[i].x, A[i].y)`, 表示把二维矩阵中下标为A[i].x行A[i].y列的元素由海洋变为岛屿. 问在每次操作之后, 二维矩阵中岛屿的数量. 你需要返回一个大小为k的数组.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: n = 4, m = 5, A = [[1,1],[0,1],[3,3],[3,4]]
+输出: [1,1,2,2]
+解释: 
+0.  00000
+    00000
+    00000
+    00000
+1.  00000
+    01000
+    00000
+    00000
+2.  01000
+    01000
+    00000
+    00000
+3.  01000
+    01000
+    00000
+    00010
+4.  01000
+    01000
+    00000
+    00011
+```
+
+**样例 2:**
+
+```
+输入: n = 3, m = 3, A = [[0,0],[0,1],[2,2],[2,1]]
+输出: [1,1,2,2]
+```
+ ### 参考代码
+ 定义一个矩阵记录地图状态, 还需要定义初始含 $n \times m$ 个集合的并查集, 以及一个计数器, 记录当前岛屿的个数.
+
+对于每一次操作(x, y), 如果(x, y)的上下左右都是0, 那么计数器加一; 如果不全为0, 则:
+
+1. 并查集查询其四周的1所属的集合, 假设它们属于 k 个不同的集合
+2. 计数器减去 k-1
+3. 将这 k 个集合, 连同 (x, y), 合并
+
+并查集的实现可以利用Point结构体, 也可以将二维坐标转换成一维.
+```python
+"""
+Definition for a point.
+class Point:
+    def __init__(self, a=0, b=0):
+        self.x = a
+        self.y = b
+"""
+
+DIRECTIONS = [(0, -1), (0, 1), (-1, 0), (1, 0)]
+
+class Solution:
+    """
+    @param n: An integer
+    @param m: An integer
+    @param operators: an array of point
+    @return: an integer array
+    """
+    def numIslands2(self, n, m, operators):
+        results = []
+        island = set()
+        self.size = 0
+        self.father = {}
+        for operator in operators:
+            x, y = operator.x, operator.y
+            if (x, y) in island:
+                results.append(self.size)
+                continue
+            
+            island.add((x, y))
+            self.father[(x, y)] = (x, y)
+            self.size += 1
+            for delta_x, delta_y in DIRECTIONS:
+                x_ = x + delta_x
+                y_ = y + delta_y
+                if (x_, y_) in island:
+                    self.union((x_, y_), (x, y))
+                
+            results.append(self.size)
+            
+        return results
+
+    def union(self, point_a, point_b):
+        root_a = self.find(point_a)
+        root_b = self.find(point_b)
+        if root_a != root_b:
+            self.father[root_a] = root_b
+            self.size -= 1
+        
+    def find(self, point):
+        path = []
+        while point != self.father[point]:
+            path.append(point)
+            point = self.father[point]
+            
+        for p in path:
+            self.father[p] = point
+            
+        return point
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/number-of-islands.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/number-of-islands.md"
new file mode 100644
index 0000000..e624bdf
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\345\271\266\346\237\245\351\233\206/number-of-islands.md"
@@ -0,0 +1,299 @@
+# 岛屿的个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/number-of-islands/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个 01 矩阵，求不同的岛屿的个数。
+
+0 代表海，1 代表岛，如果两个 1 相邻，那么这两个 1 属于同一个岛。我们只考虑上下左右为相邻。
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入：
+[
+  [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]
+]
+输出：
+3
+```
+**样例 2：**
+```
+输入：
+[
+  [1,1]
+]
+输出：
+1
+```
+ ### 参考代码
+ 用九章算法班中讲到的 BFS 模板。
+```
+[[python]]
+from collections import deque
+
+DIRECTIONS = [(1, 0), (0, -1), (-1, 0), (0, 1)]
+
+class Solution:
+    """
+    @param grid: a boolean 2D matrix
+    @return: an integer
+    """
+    def numIslands(self, grid):
+        if not grid or not grid[0]:
+            return 0
+            
+        islands = 0
+        visited = set()
+        for i in range(len(grid)):
+            for j in range(len(grid[0])):
+                if grid[i][j] and (i, j) not in visited:
+                    self.bfs(grid, i, j, visited)
+                    islands += 1
+                    
+        return islands                    
+    
+    def bfs(self, grid, x, y, visited):
+        queue = deque([(x, y)])
+        visited.add((x, y))
+        while queue:
+            x, y = queue.popleft()
+            for delta_x, delta_y in DIRECTIONS:
+                next_x = x + delta_x
+                next_y = y + delta_y
+                if not self.is_valid(grid, next_x, next_y, visited):
+                    continue
+                queue.append((next_x, next_y))
+                visited.add((next_x, next_y))
+
+    def is_valid(self, grid, x, y, visited):
+        n, m = len(grid), len(grid[0])
+        if not (0 <= x < n and 0 <= y < m):
+            return False
+        if (x, y) in visited:
+            return False
+        return grid[x][y]
+
+# LeetCode 的用户请用下面的代码，因为 LeetCode 上的输入是 2D string array 而不是 boolean array
+# from collections import deque
+
+# class Solution:
+#     """
+#     @param grid: a boolean 2D matrix
+#     @return: an integer
+#     """
+#     def numIslands(self, grid):
+#         if not grid or not grid[0]:
+#             return 0
+        
+#         islands = 0
+#         for i in range(len(grid)):
+#             for j in range(len(grid[0])):
+#                 if grid[i][j] == '1':
+#                     self.bfs(grid, i, j)
+#                     islands += 1
+                    
+#         return islands                    
+    
+#     def bfs(self, grid, x, y):
+#         queue = deque([(x, y)])
+#         grid[x][y] = '0'
+#         while queue:
+#             x, y = queue.popleft()
+#             for delta_x, delta_y in [(1, 0), (0, -1), (-1, 0), (0, 1)]:
+#                 next_x = x + delta_x
+#                 next_y = y + delta_y
+#                 if not self.is_valid(grid, next_x, next_y):
+#                     continue
+#                 queue.append((next_x, next_y))
+#                 grid[next_x][next_y] = '0'
+                
+#     def is_valid(self, grid, x, y):
+#         n, m = len(grid), len(grid[0])
+#         return 0 <= x < n and 0 <= y < m and grid[x][y] == '1'
+[[java]]
+class Coordinate {
+    int x, y;
+    public Coordinate(int x, int y) {
+        this.x = x;
+        this.y = y;
+    }
+}
+
+public class Solution {
+    /**
+     * @param grid a boolean 2D matrix
+     * @return an integer
+     */
+    int[] deltaX = {0, 1, -1, 0};
+    int[] deltaY = {1, 0, 0, -1};
+    public int numIslands(boolean[][] grid) {
+        if (grid == null || grid.length == 0) {
+            return 0;
+        }
+        if (grid[0] == null || grid[0].length == 0) {
+            return 0;
+        }
+        
+        int islands = 0;
+        int n = grid.length, m = grid[0].length;
+        boolean[][] visited = new boolean[n][m];
+        
+        for (int i = 0; i < n; i++) {
+            for (int j = 0; j < m; j++) {
+                if (grid[i][j] && !visited[i][j]) {
+                    bfs(grid, i, j, visited);
+                    islands++;
+                }
+            }
+        }
+        
+        return islands;
+    }
+    
+    private void bfs(boolean[][] grid, int x, int y, boolean[][] visited) {
+        Queue<Coordinate> queue = new ArrayDeque<>();
+        queue.offer(new Coordinate(x, y));
+        visited[x][y] = true;
+        
+        while (!queue.isEmpty()) {
+            Coordinate coor = queue.poll();
+            for (int direction = 0; direction < 4; direction++) {
+                int newX = coor.x + deltaX[direction];
+                int newY = coor.y + deltaY[direction];
+                if (!isVaild(grid, newX, newY, visited)) {
+                    continue;
+                }
+                queue.offer(new Coordinate(newX, newY));
+                visited[newX][newY] = true;
+            }
+        }
+    }
+    
+    private boolean isVaild(boolean[][] grid, int x, int y, boolean[][] visited) {
+        int n = grid.length, m = grid[0].length;
+        if (x < 0 || x >= n || y < 0 || y >= m) {
+            return false;
+        }
+        if (visited[x][y]) {
+            return false;
+        }
+        return grid[x][y];
+    }
+}
+```
+
+也可以使用 DFS 的方法进行搜索。
+DFS 分为两类：
+
+1. 找所有路径的
+2. 找所有节点的
+
+第一类一般需要回溯，也就是把一个东西标记为使用过以后要把他标记回来。这样才能找到所有的路径。
+第二类不需要回溯，因为只需要把所有连通的节点都标记一下即可。
+
+DFS 来做这道题目虽然可以在 LintCode / LeetCode 等题库拿到 AC，但是在面试中并不推荐，因为 DFS 的深度可能会比较深，容易导致 StackOverflow。
+
+```
+[[python]]
+class Solution:
+    """
+    @param grid: a boolean 2D matrix
+    @return: an integer
+    """
+    def numIslands(self, grid):
+        if not grid or not grid[0]:
+            return 0
+        
+        n, m = len(grid), len(grid[0])
+        visited = [[False] * m for _ in range(n)]
+        
+        islands = 0
+        for row in range(n):
+            for col in range(m):
+                if self.is_island(grid, row, col, visited):
+                    visited[row][col] = True
+                    self.dfs(grid, row, col, visited)
+                    islands += 1
+                    
+        return islands
+        
+    def is_island(self, grid, x, y, visited):
+        n, m = len(grid), len(grid[0])
+        if not (0 <= x < n and 0 <= y < m):
+            return False
+        if not grid[x][y]:
+            return False
+        return not visited[x][y]
+
+    def dfs(self, grid, x, y, visited):
+        dx = [1, 0, -1, 0]
+        dy = [0, 1, 0, -1]
+        for direction in range(4):
+            newx = x + dx[direction]
+            newy = y + dy[direction]
+            
+            if self.is_island(grid, newx, newy, visited):
+                visited[newx][newy] = True
+                self.dfs(grid, newx, newy, visited)
+                # no backtracking
+[[java]]
+public class Solution {
+    /**
+     * @param grid: a boolean 2D matrix
+     * @return: an integer
+     */
+    public int numIslands(boolean[][] grid) {
+        if (grid == null || grid.length == 0) {
+            return 0;
+        }
+        if (grid[0] == null || grid[0].length == 0) {
+            return 0;
+        }
+        
+        int n = grid.length, m = grid[0].length;
+        boolean[][] visited = new boolean[n][m];
+        
+        int islands = 0;
+        for (int row = 0; row < n; row++) {
+            for (int col = 0; col < m; col++) {
+                if (isIsland(grid, row, col, visited)) {
+                    visited[row][col] = true;
+                    dfs(grid, row, col, visited);
+                    islands++;
+                }
+            }
+        }
+        return islands;
+    }
+    
+    private boolean isIsland(boolean[][] grid, int x, int y, boolean[][] visited) {
+        int n = grid.length, m = grid[0].length;
+        if (x < 0 || x >= n || y < 0 || y >= m) {
+            return false;
+        }
+        if (!grid[x][y]) {
+            return false;
+        }
+        return !visited[x][y];
+    }
+    
+    private void dfs(boolean[][] grid, int x, int y, boolean[][] visited) {
+        int[] dx = new int[]{1, 0, -1, 0};
+        int[] dy = new int[]{0, 1, 0, -1};
+        for (int direction = 0; direction < 4; direction++) {
+            int newX = x + dx[direction];
+            int newY = y + dy[direction];
+            
+            if (isIsland(grid, newX, newY, visited)) {
+                visited[newX][newY] = true;
+                dfs(grid, newX, newY, visited);
+            }
+        }
+        // no backtracking
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/data-stream-median.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/data-stream-median.md"
new file mode 100644
index 0000000..c7ba84e
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/data-stream-median.md"
@@ -0,0 +1,52 @@
+# 数据流中位数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/data-stream-median/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 数字是不断进入数组的，在每次添加一个新的数进入数组的同时返回当前新数组的中位数。
+ ### 样例说明
+ 
+ ### 参考代码
+ 把比 median 小的放在 maxheap 里，把比 median 大的放在 minheap 里。median 单独放在一个变量里。
+每次新增一个数的时候，先根据比当前的 median 大还是小丢到对应的 heap 里。
+丢完以后，再处理左右两边的平衡性:
+
+1. 如果左边太少了，就把 median 丢到左边，从右边拿一个最小的出来作为 median。
+2. 如果右边太少了，就把 median 丢到右边，从左边拿一个最大的出来作为新的 median。
+```python
+import heapq
+
+
+class Solution:
+    """
+    @param nums: A list of integers
+    @return: the median of numbers
+    """
+    def medianII(self, nums):
+        if not nums:
+            return []
+            
+        self.median = nums[0]
+        self.maxheap = []
+        self.minheap = []
+        
+        medians = [nums[0]]
+        for num in nums[1:]:
+            self.add(num)
+            medians.append(self.median)
+            
+        return medians
+
+    def add(self, num):
+        if num < self.median:
+            heapq.heappush(self.maxheap, -num)
+        else:
+            heapq.heappush(self.minheap, num)
+            
+        # balanace
+        if len(self.maxheap) > len(self.minheap):
+            heapq.heappush(self.minheap, self.median)
+            self.median = -heapq.heappop(self.maxheap)
+        elif len(self.maxheap) + 1 < len(self.minheap):
+            heapq.heappush(self.maxheap, -self.median)
+            self.median = heapq.heappop(self.minheap)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/find-median-from-data-stream.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/find-median-from-data-stream.md"
new file mode 100644
index 0000000..718c924
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/find-median-from-data-stream.md"
@@ -0,0 +1,73 @@
+# 数据流中位数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/find-median-from-data-stream/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 数字是不断进入数组的，在每次添加一个新的数进入数组的同时返回当前新数组的中位数。
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: [1,2,3,4,5]
+输出: [1,1,2,2,3]
+样例说明：
+[1] 和 [1,2] 的中位数是 1.
+[1,2,3] 和 [1,2,3,4] 的中位数是 2.
+[1,2,3,4,5] 的中位数是 3.
+```
+
+**样例2**
+
+```plain
+输入: [4,5,1,3,2,6,0]
+输出: [4,4,4,3,3,3,3]
+样例说明：
+[4], [4,5] 和 [4,5,1] 的中位数是 4.
+[4,5,1,3], [4,5,1,3,2], [4,5,1,3,2,6] 和 [4,5,1,3,2,6,0] 的中位数是 3.
+```
+
+
+ ### 参考代码
+ 把比 median 小的放在 maxheap 里，把比 median 大的放在 minheap 里。median 单独放在一个变量里。
+每次新增一个数的时候，先根据比当前的 median 大还是小丢到对应的 heap 里。
+丢完以后，再处理左右两边的平衡性:
+
+如果左边太少了，就把 median 丢到左边，从右边拿一个最小的出来作为 median。
+如果右边太少了，就把 median 丢到右边，从左边拿一个最大的出来作为新的 median。
+```python
+import heapq
+
+
+class Solution:
+    """
+    @param nums: A list of integers
+    @return: the median of numbers
+    """
+    def medianII(self, nums):
+        if not nums:
+            return []
+            
+        self.median = nums[0]
+        self.maxheap = []
+        self.minheap = []
+        
+        medians = [nums[0]]
+        for num in nums[1:]:
+            self.add(num)
+            medians.append(self.median)
+            
+        return medians
+
+    def add(self, num):
+        if num < self.median:
+            heapq.heappush(self.maxheap, -num)
+        else:
+            heapq.heappush(self.minheap, num)
+            
+        # balanace
+        if len(self.maxheap) > len(self.minheap):
+            heapq.heappush(self.minheap, self.median)
+            self.median = -heapq.heappop(self.maxheap)
+        elif len(self.maxheap) + 1 < len(self.minheap):
+            heapq.heappush(self.maxheap, -self.median)
+            self.median = heapq.heappop(self.minheap)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/insert-into-a-cyclic-sorted-list.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/insert-into-a-cyclic-sorted-list.md"
new file mode 100644
index 0000000..921aef3
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/insert-into-a-cyclic-sorted-list.md"
@@ -0,0 +1,67 @@
+# 向循环有序链表插入节点
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/insert-into-a-cyclic-sorted-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个来自已经排过序的循环链表的节点，写一个函数来将一个值插入到循环链表中，并且保持还是有序循环链表。给出的节点可以是链表中的任意一个单节点。返回插入后的新链表。
+ ### 样例说明
+ 例1:
+```
+输入:
+3->5->1
+4
+输出:
+5->1->3->4
+```
+
+例2:
+```
+输入:
+2->2->2
+3
+输出:
+3->2->2->2
+```
+
+ ### 参考代码
+ 由于已经是排序好的链表。
+所以只需顺序扫描一遍链表即可。
+需要注意的是，若为最大或是最小，需要额外判断。
+```python
+"""
+Definition of ListNode
+class ListNode(object):
+
+    def __init__(self, val, next=None):
+        self.val = val
+        self.next = next
+"""
+class Solution:
+    # @param {ListNode} node a list node in the list
+    # @param {int} x an integer
+    # @return {ListNode} the inserted new list node
+    def insert(self, node, x):
+        # Write your code here
+        if node is None:
+            node = ListNode(x)
+            node.next = node
+            return node
+
+        p = node
+        prev = None
+        while True:
+            prev = p
+            p = p.next
+            if x <= p.val and x >= prev.val:
+                break
+
+            if (prev.val > p.val) and (x < p.val or x > prev.val):
+                break
+
+            if p is node:
+                break
+
+        newNode = ListNode(x)
+        newNode.next = p
+        prev.next = newNode
+        return newNode
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/insertion-sort-list.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/insertion-sort-list.md"
new file mode 100644
index 0000000..fc6ff88
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/insertion-sort-list.md"
@@ -0,0 +1,45 @@
+# 链表插入排序
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/insertion-sort-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 用插入排序对链表排序
+ ### 样例说明
+ ```
+样例 1:
+	输入: 0->null
+	输出: 0->null
+
+
+样例 2:
+	输入:  1->3->2->0->null
+	输出 :0->1->2->3->null
+	
+
+```
+
+ ### 参考代码
+ Sort a linked list using insertion sort.
+
+与数组普通插入排序一样的做法。
+```java
+public class Solution {
+    public ListNode insertionSortList(ListNode head) {
+        ListNode dummy = new ListNode(0);
+        // 这个dummy的作用是，把head开头的链表一个个的插入到dummy开头的链表里
+        // 所以这里不需要dummy.next = head;
+
+        while (head != null) {
+            ListNode node = dummy;
+            while (node.next != null && node.next.val < head.val) {
+                node = node.next;
+            }
+            ListNode temp = head.next;
+            head.next = node.next;
+            node.next = head;
+            head = temp;
+        }
+
+        return dummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/median-in-data-stream.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median-in-data-stream.md"
similarity index 100%
rename from "\351\242\230\350\247\243/median-in-data-stream.md"
rename to "\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median-in-data-stream.md"
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median-of-k-sorted-arrays.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median-of-k-sorted-arrays.md"
new file mode 100644
index 0000000..68f293c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median-of-k-sorted-arrays.md"
@@ -0,0 +1,87 @@
+# K 个有序数组的中位数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/median-of-k-sorted-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有 `k` 个有序数组 `nums`。找到这 `k` 个有序数组的中位数。
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+[[1],[2],[3]]
+输出:
+2.00
+```
+
+**样例 2:**
+```
+输入:
+[[1,1,2],[2,4,8],[3,7,10,20]]
+输出:
+3.50
+```
+ ### 参考代码
+ 使用二分答案的方法。
+可以在《九章算法强化班》中学到哦！
+```python
+class Solution:
+    """
+    @param nums: the given k sorted arrays
+    @return: the median of the given k sorted arrays
+    """
+    def findMedian(self, nums):
+        if not nums:
+            return 0.0
+            
+        n = sum(len(arr) for arr in nums)
+        if n == 0:
+            return 0.0
+            
+        if n % 2 == 1:
+            return self.find_kth(nums, n // 2 + 1) * 1.0
+        return (self.find_kth(nums, n // 2) + self.find_kth(nums, n // 2 + 1)) / 2.0
+
+    # k is one-based, from 1 to n
+    def find_kth(self, arrs, k):
+        start, end = self.get_range(arrs)
+        
+        # find the first num that there are >= k nums <= num
+        while start + 1 < end:
+            mid = (start + end) // 2
+            if self.get_smaller_or_equal(arrs, mid) >= k:
+                end = mid
+            else:
+                start = mid
+        if self.get_smaller_or_equal(arrs, start) >= k:
+            return start
+        return end
+            
+    def get_range(self, arrs):
+        start = min(arr[0] for arr in arrs if len(arr))
+        end = max(arr[-1] for arr in arrs if len(arr))
+        return start, end
+        
+    def get_smaller_or_equal(self, arrs, val):
+        count = 0
+        for arr in arrs:
+            count += self.get_smaller_or_equal_in_arr(arr, val)
+        return count
+        
+    def get_smaller_or_equal_in_arr(self, arr, val):
+        if not arr:
+            return 0
+            
+        # find the first num > val
+        start, end = 0, len(arr) - 1
+        while start + 1 < end:
+            mid = (start + end) // 2
+            if arr[mid] > val:
+                end = mid
+            else:
+                start = mid
+        
+        if arr[start] > val:
+            return start
+        if arr[end] > val:
+            return end
+        return end + 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median-of-two-sorted-arrays.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median-of-two-sorted-arrays.md"
new file mode 100644
index 0000000..550f0e1
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median-of-two-sorted-arrays.md"
@@ -0,0 +1,72 @@
+# 两个排序数组的中位数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/median-of-two-sorted-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">两个排序的数组</span><span style="line-height: 1.42857143;">A和B</span><span style="line-height: 1.42857143;">分别含有m和n个数，找到两个排序数组的中位数，要求时间复杂度应为O(log (m+n))。</span></p>
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+A = [1,2,3,4,5,6]
+B = [2,3,4,5]
+输出: 3.5
+```
+
+**样例2**
+
+```plain
+输入:
+A = [1,2,3]
+B = [4,5]
+输出: 3
+```
+
+
+ ### 参考代码
+ 分治法。时间复杂度 $log(n + m)$
+```java
+public class Solution {
+    public double findMedianSortedArrays(int A[], int B[]) {
+        int n = A.length + B.length;
+        
+        if (n % 2 == 0) {
+            return (
+                findKth(A, 0, B, 0, n / 2) + 
+                findKth(A, 0, B, 0, n / 2 + 1)
+            ) / 2.0;
+        }
+        
+        return findKth(A, 0, B, 0, n / 2 + 1);
+    }
+
+    // find kth number of two sorted array
+    public static int findKth(int[] A, int startOfA,
+                              int[] B, int startOfB,
+                              int k){       
+        if (startOfA >= A.length) {
+            return B[startOfB + k - 1];
+        }
+        if (startOfB >= B.length) {
+            return A[startOfA + k - 1];
+        }
+
+        if (k == 1) {
+            return Math.min(A[startOfA], B[startOfB]);
+        }
+        
+        int halfKthOfA = startOfA + k / 2 - 1 < A.length
+            ? A[startOfA + k / 2 - 1]
+            : Integer.MAX_VALUE;
+        int halfKthOfB = startOfB + k / 2 - 1 < B.length
+            ? B[startOfB + k / 2 - 1]
+            : Integer.MAX_VALUE; 
+        
+        if (halfKthOfA < halfKthOfB) {
+            return findKth(A, startOfA + k / 2, B, startOfB, k - k / 2);
+        } else {
+            return findKth(A, startOfA, B, startOfB + k / 2, k - k / 2);
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median.md"
new file mode 100644
index 0000000..74b6591
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/median.md"
@@ -0,0 +1,55 @@
+# 中位数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/median/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给定一个未排序的整数数组，找到其中位数。</p><p>中位数是排序后数组的中间值，如果数组的个数是偶数个，则返回排序后数组的第N/2个数。</p>
+ ### 样例说明
+ **样例 1:**
+```
+输入：[4, 5, 1, 2, 3]
+输出：3
+解释：
+经过排序，得到数组[1,2,3,4,5]，中间数字为3
+```
+**样例 2:**
+```
+输入：[7, 9, 4, 5]
+输出：5
+解释：
+经过排序，得到数组[4,5,7,9]，第二个(4/2)数字为5
+```
+ ### 参考代码
+ 考点：
+* 区间第k大元素的查找
+
+题解：
+使用优先队列维护大小为k的有序集合，优先队列大小小于k时直接压入，等于k时与首个元素判断大小关系，小于时直接压入，并将首个元素弹出。最后输出优先队列的头部元素即可。
+优先队列：
+* 优先队列中，元素被赋予优先级。当访问元素时，具有最高优先级的元素最先删除。优先队列具有最高级先出的行为特征。通常采用堆数据结构来实现。
+* 默认情况下，优先队列按照非递增顺序排列。
+```cpp
+class Solution {
+public:
+    /**
+     * @param nums: A list of integers.
+     * @return: An integer denotes the middle number of the array.
+     */
+    int median(vector<int> &nums) {
+        // write your code here
+        int k = (nums.size() + 1) / 2;
+        priority_queue<int> que;
+        int len = nums.size();
+        for(int i = 0; i < len; i ++) {
+            if(que.size() == k) {
+                if(nums[i] < que.top()) {
+                    que.pop();
+                    que.push(nums[i]);
+                }
+            }else {
+                que.push(nums[i]);
+            }
+        }
+        return que.top();
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/meeting-rooms.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/meeting-rooms.md"
new file mode 100644
index 0000000..df03064
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/meeting-rooms.md"
@@ -0,0 +1,48 @@
+# 会议室
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/meeting-rooms/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一系列的会议时间间隔，包括起始和结束时间[[s1,e1]，[s2,e2]，…(si < ei)，确定一个人是否可以参加所有会议。
+ ### 样例说明
+ **样例1**
+
+```
+输入: intervals = [(0,30),(5,10),(15,20)]
+输出: false
+解释:
+(0,30), (5,10) 和 (0,30),(15,20) 这两对会议会冲突
+```
+
+**样例2**
+
+```
+输入: intervals = [(5,8),(9,15)]
+输出: true
+解释:
+这两个时间段不会冲突
+```
+
+
+
+
+ ### 参考代码
+ ```java
+public class Solution {
+    public boolean canAttendMeetings(Interval[] intervals) {
+        if(intervals == null || intervals.length == 0) return true;
+        Arrays.sort(intervals, new Comparator<Interval>(){
+            public int compare(Interval i1, Interval i2){
+                return i1.start - i2.start;
+            }
+        });
+        int end = intervals[0].end;
+        for(int i = 1; i < intervals.length; i++){
+            if(intervals[i].start < end) {
+                return false;
+            }
+            end = Math.max(end, intervals[i].end);
+        }
+        return true;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-k-sorted-lists.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-k-sorted-lists.md"
new file mode 100644
index 0000000..2145767
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-k-sorted-lists.md"
@@ -0,0 +1,177 @@
+# 合并k个排序链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-k-sorted-lists/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>合并k个排序链表，并且返回合并后的排序链表。尝试分析和描述其复杂度。<br></p>
+ ### 样例说明
+ ```
+样例 1:
+	输入:   [2->4->null,null,-1->null]
+	输出:  -1->2->4->null
+
+样例 2:
+	输入: [2->6->null,5->null,7->null]
+	输出:  2->5->6->7->null
+	
+```
+ ### 参考代码
+ Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
+
+有序数组合并，使用两个指针向后移动，每次比较，小的一个数字取出来，并将指针后移一位。
+
+K个有序链表可以每次合并一个链表进结果链表中。合并k次
+```java
+// version 1: Divide & Conquer
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+public class Solution {
+    /**
+     * @param lists: a list of ListNode
+     * @return: The head of one sorted list.
+     */
+    public ListNode mergeKLists(List<ListNode> lists) {
+        if (lists.size() == 0) {
+            return null;
+        }
+        return mergeHelper(lists, 0, lists.size() - 1);
+    }
+    
+    private ListNode mergeHelper(List<ListNode> lists, int start, int end) {
+        if (start == end) {
+            return lists.get(start);
+        }
+        
+        int mid = start + (end - start) / 2;
+        ListNode left = mergeHelper(lists, start, mid);
+        ListNode right = mergeHelper(lists, mid + 1, end);
+        return mergeTwoLists(left, right);
+    }
+    
+    private ListNode mergeTwoLists(ListNode list1, ListNode list2) {
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (list1 != null && list2 != null) {
+            if (list1.val < list2.val) {
+                tail.next = list1;
+                tail = list1;
+                list1 = list1.next;
+            } else {
+                tail.next = list2;
+                tail = list2;
+                list2 = list2.next;
+            }
+        }
+        if (list1 != null) {
+            tail.next = list1;
+        } else {
+            tail.next = list2;
+        }
+        
+        return dummy.next;
+    }
+}
+
+// version 2: Heap
+public class Solution {
+    private Comparator<ListNode> ListNodeComparator = new Comparator<ListNode>() {
+        public int compare(ListNode left, ListNode right) {
+            return left.val - right.val;
+        }
+    };
+    
+    public ListNode mergeKLists(List<ListNode> lists) {
+        if (lists == null || lists.size() == 0) {
+            return null;
+        }
+        
+        Queue<ListNode> heap = new PriorityQueue<ListNode>(lists.size(), ListNodeComparator);
+        for (int i = 0; i < lists.size(); i++) {
+            if (lists.get(i) != null) {
+                heap.add(lists.get(i));
+            }
+        }
+        
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (!heap.isEmpty()) {
+            ListNode head = heap.poll();
+            tail.next = head;
+            tail = head;
+            if (head.next != null) {
+                heap.add(head.next);
+            }
+        }
+        return dummy.next;
+    }
+}
+
+// Version 3: merge two by two
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+public class Solution {
+    /**
+     * @param lists: a list of ListNode
+     * @return: The head of one sorted list.
+     */
+    public ListNode mergeKLists(List<ListNode> lists) {  
+        if (lists == null || lists.size() == 0) {
+            return null;
+        }
+        
+        while (lists.size() > 1) {
+            List<ListNode> new_lists = new ArrayList<ListNode>();
+            for (int i = 0; i + 1 < lists.size(); i += 2) {
+                ListNode merged_list = merge(lists.get(i), lists.get(i+1));
+                new_lists.add(merged_list);
+            }
+            if (lists.size() % 2 == 1) {
+                new_lists.add(lists.get(lists.size() - 1));
+            }
+            lists = new_lists;
+        }
+        
+        return lists.get(0);
+    }
+    
+    private ListNode merge(ListNode a, ListNode b) {
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (a != null && b != null) {
+            if (a.val < b.val) {
+                tail.next = a;
+                a = a.next;
+            } else {
+                tail.next = b;
+                b = b.next;
+            }
+            tail = tail.next;
+        }
+        
+        if (a != null) {
+            tail.next = a;
+        } else {
+            tail.next = b;
+        }
+        
+        return dummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-two-sorted-arrays.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-two-sorted-arrays.md"
new file mode 100644
index 0000000..892e542
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-two-sorted-arrays.md"
@@ -0,0 +1,59 @@
+# 合并排序数组 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-two-sorted-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>合并两个有序升序的整数数组A和B变成一个新的数组。新数组也要有序。</p>
+ ### 样例说明
+ **样例  1:**
+
+```
+输入: A=[1], B=[1]
+输出:[1,1]	
+样例解释: 返回合并后的数组。
+```
+
+**样例 2:**
+
+```
+输入: A=[1,2,3,4], B=[2,4,5,6]
+输出: [1,2,2,3,4,4,5,6]	
+样例解释: 返回合并后的数组。
+```
+ ### 参考代码
+ 使用两个指针分别对数组从小到大遍历，每次取二者中较小的放在新数组中。
+直到某个指针先到结尾，另一个数组中剩余的数字直接放在新数组后面。
+
+时间复杂度O(n)
+```java
+class Solution {
+    /**
+     * @param A and B: sorted integer array A and B.
+     * @return: A new sorted integer array
+     */
+    public int[] mergeSortedArray(int[] A, int[] B) {
+        if (A == null || B == null) {
+            return null;
+        }
+        
+        int[] result = new int[A.length + B.length];
+        int i = 0, j = 0, index = 0;
+        
+        while (i < A.length && j < B.length) {
+            if (A[i] < B[j]) {
+                result[index++] = A[i++];
+            } else {
+                result[index++] = B[j++];
+            }
+        }
+        
+        while (i < A.length) {
+            result[index++] = A[i++];
+        }
+        while (j < B.length) {
+            result[index++] = B[j++];
+        }
+        
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-two-sorted-interval-lists.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-two-sorted-interval-lists.md"
new file mode 100644
index 0000000..bce811c
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-two-sorted-interval-lists.md"
@@ -0,0 +1,90 @@
+# 合并两个排序的间隔列表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-two-sorted-interval-lists/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 合并两个已排序的区间列表，并将其作为一个新的有序区间列表返回。新的区间列表应该通过拼接两个列表的区间并按升序排序。
+ ### 样例说明
+ **样例1**
+
+```
+输入: [(1,2),(3,4)] and list2 = [(2,3),(5,6)]
+输出: [(1,4),(5,6)]
+解释:
+(1,2),(2,3),(3,4) --> (1,4)
+(5,6) --> (5,6)
+```
+
+
+
+**样例2**
+
+```
+输入: [(1,2),(3,4)] 和 list2 = [(4,5),(6,7)]
+输出: [(1,2),(3,5),(6,7)]
+解释:
+(1,2) --> (1,2)
+(3,4),(4,5) --> (3,5)
+(6,7) --> (6,7)
+```
+ ### 参考代码
+ 正如课上说的，用一个 last 来记录最后一个还没有被放到 merge results 里的 Interval，用于和新加入的 interval 比较看看能不能合并到一起。
+
+时间复杂度 $O(n + m)$
+```java
+public class Solution {
+    /**
+     * @param list1: one of the given list
+     * @param list2: another list
+     * @return: the new sorted list of interval
+     */
+    public List<Interval> mergeTwoInterval(List<Interval> list1, List<Interval> list2) {
+        List<Interval> results = new ArrayList<>();
+        if (list1 == null || list2 == null) {
+            return results;
+        }
+        
+        Interval last = null, curt = null;
+        int i = 0, j = 0;
+        while (i < list1.size() && j < list2.size()) {
+            if (list1.get(i).start < list2.get(j).start) {
+                curt = list1.get(i);
+                i++;
+            } else {
+                curt = list2.get(j);
+                j++;
+            }
+            
+            last = merge(results, last, curt);
+        }
+        
+        while (i < list1.size()) {
+            last = merge(results, last, list1.get(i));
+            i++;
+        }
+        
+        while (j < list2.size()) {
+            last = merge(results, last, list2.get(j));
+            j++;
+        }
+        
+        if (last != null) {
+        	results.add(last);
+        }
+        return results;
+    }
+    
+    private Interval merge(List<Interval> results, Interval last, Interval curt) {
+        if (last == null) {
+            return curt;
+        }
+        
+        if (curt.start > last.end) {
+            results.add(last);
+            return curt;
+        }
+        
+        last.end = Math.max(last.end, curt.end);
+        return last;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-two-sorted-lists.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-two-sorted-lists.md"
new file mode 100644
index 0000000..8a2c488
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/merge-two-sorted-lists.md"
@@ -0,0 +1,49 @@
+# 合并两个排序链表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-two-sorted-lists/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将两个排序链表合并为一个新的排序链表
+ ### 样例说明
+ ```
+样例 1:
+	输入: list1 = null, list2 = 0->3->3->null
+	输出: 0->3->3->null
+
+
+样例2:
+	输入:  list1 =  1->3->8->11->15->null, list2 = 2->null
+	输出: 1->2->3->8->11->15->null
+
+```
+
+ ### 参考代码
+ Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
+
+与合并数组一个方法，两个指针往后走。
+```java
+public class Solution {
+    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
+        ListNode dummy = new ListNode(0);
+        ListNode lastNode = dummy;
+        
+        while (l1 != null && l2 != null) {
+            if (l1.val < l2.val) {
+                lastNode.next = l1;
+                l1 = l1.next;
+            } else {
+                lastNode.next = l2;
+                l2 = l2.next;
+            }
+            lastNode = lastNode.next;
+        }
+        
+        if (l1 != null) {
+            lastNode.next = l1;
+        } else {
+            lastNode.next = l2;
+        }
+        
+        return dummy.next;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/nuts-bolts-problem.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/nuts-bolts-problem.md"
new file mode 100644
index 0000000..95910c4
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/nuts-bolts-problem.md"
@@ -0,0 +1,83 @@
+# Nuts 和 Bolts 的问题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/nuts-bolts-problem/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一组 n 个不同大小的 nuts 和 n 个不同大小的 bolts. nuts 和 bolts 一一匹配. 
+
+不允许将 nut 之间互相比较, 也不允许将 bolt 之间互相比较. 也就是说, 只许将 nut 与 bolt 进行比较,  或将 bolt 与 nut 进行比较. 我们会提供一个比较函数, 用于nut和bolt的比较.
+
+利用我们提供的函数, 你需要将 nuts 或者 bolts 重新排列, 使得它们按照顺序一一匹配.
+
+
+ ### 样例说明
+ 给出 nuts = `['ab','bc','dd','gg']`, bolts = `['AB','GG', 'DD', 'BC']`
+
+你的程序应该找出bolts和nuts的匹配.
+
+根据比较函数, 一组可能的返回结果是：
+
+nuts = `['ab','bc','dd','gg']`, bolts = `['AB','BC','DD','GG']`
+
+如果我们给你另外的比较函数，可能返回的结果是：
+
+nuts = `['ab','bc','dd','gg'], bolts = ['BC','AB','DD','GG']`
+
+因此的结果完全取决于比较函数，而不是字符串本身。因为你必须使用比较函数来进行排序。
+
+各自的排序当中nuts和bolts的顺序是无关紧要的，只要他们一一匹配就可以。
+
+
+ ### 参考代码
+ 基于标准 Partition 模板算法。
+```python
+"""
+class Comparator:
+    def cmp(self, a, b)
+You can use Compare.cmp(a, b) to compare nuts "a" and bolts "b",
+if "a" is bigger than "b", it will return 1, else if they are equal,
+it will return 0, else if "a" is smaller than "b", it will return -1.
+When "a" is not a nut or "b" is not a bolt, it will return 2, which is not valid.
+"""
+
+
+class Solution:
+    # @param nuts: a list of integers
+    # @param bolts: a list of integers
+    # @param compare: a instance of Comparator
+    # @return: nothing
+    def sortNutsAndBolts(self, nuts, bolts, compare):
+        self.quick_sort(nuts, bolts, 0, len(nuts) - 1, compare.cmp)
+        
+    def quick_sort(self, nuts, bolts, start, end, cmp):
+        if start >= end:
+            return
+        
+        left, right = start, end
+        
+        index = self.partition(bolts, left, right, nuts[(left + right) // 2], cmp)
+        self.partition(nuts, left, right, bolts[index], cmp)
+        
+        self.quick_sort(nuts, bolts, start, index - 1, cmp)
+        self.quick_sort(nuts, bolts, index + 1, end, cmp)
+        
+    def partition(self, arr, start, end, pivot, cmp):
+        left, right = start, end
+        
+        for i in range(left, right + 1):
+            if cmp(arr[i], pivot) == 0 or cmp(pivot, arr[i]) == 0:
+                arr[i], arr[left] = arr[left], arr[i]
+                left += 1
+                break
+            
+        while left <= right:
+            while left <= right and (cmp(arr[left], pivot) == -1 or cmp(pivot, arr[left]) == 1):
+                left += 1
+            while left <= right and (cmp(arr[right], pivot) == 1 or cmp(pivot, arr[right]) == -1):
+                right -= 1
+            if left <= right:
+                arr[left], arr[right] = arr[right], arr[left]
+                left, right = left + 1, right - 1
+        
+        arr[start], arr[right] = arr[right], arr[start]
+        return right
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/partition-array-by-odd-and-even.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/partition-array-by-odd-and-even.md"
new file mode 100644
index 0000000..d55b410
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/partition-array-by-odd-and-even.md"
@@ -0,0 +1,50 @@
+# 奇偶分割数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/partition-array-by-odd-and-even/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 分割一个整数数组，使得奇数在前偶数在后。
+
+ ### 样例说明
+ **样例1:**
+
+```plain
+输入: [1,2,3,4]
+输出: [1,3,2,4]
+```
+
+**样例2:**
+
+```plain
+输入: [1,4,2,3,5,6]
+输出: [1,3,5,4,2,6]
+```
+
+
+ ### 参考代码
+ 原题目很简单，只需要将原数组扫描两遍，第一遍加入奇数，第二遍加入偶数，然后把答案数组覆盖原数组即可。
+
+对于challenge问题，我们需要采用双指针（two pointer）的方法，一个从头开始，一个从尾开始，头指针定位到从前到后的第一个偶数，尾指针定位到从后到前的第一个奇数，两者交换即可。直到尾指针在头之前前面。
+```java
+public class Solution {
+    /**
+     * @param nums: an array of integers
+     * @return: nothing
+     */
+    public void partitionArray(int[] nums) {
+        int start = 0, end = nums.length - 1;
+        while (start < end) {
+            while (start < end && nums[start] % 2 == 1) {
+                start++;
+            }
+            while (start < end && nums[end] % 2 == 0) {
+                end--;
+            }
+            if (start < end) {
+                int temp = nums[start]; nums[start] = nums[end]; nums[end] = temp;
+                start++;
+                end--;
+            } 
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/partition-array-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/partition-array-ii.md"
new file mode 100644
index 0000000..84ba2f7
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/partition-array-ii.md"
@@ -0,0 +1,94 @@
+# 数组划分II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/partition-array-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一个没有经过排序的整数数组划分为 3 部分:
+1.第一部分中所有的值都 < low
+2.第二部分中所有的值都 >= low并且 <= high
+3.第三部分中所有的值都 > high
+返回任意一种可能的情况。
+ ### 样例说明
+ 例1:
+```
+输入:
+[4,3,4,1,2,3,1,2]
+2
+3
+输出:
+[1,1,2,3,2,3,4,4]
+解释:
+[1,1,2,2,3,3,4,4] 也对, 但 [1,2,1,2,3,3,4,4] 不对
+```
+
+例2:
+```
+输入:
+[3,2,1]
+2
+3
+输出:
+[1,2,3]
+```
+
+
+ ### 参考代码
+ 类似快速排序的思路去分割即可，遇到不满足即交换。
+```python
+# 参考程序1
+class Solution:
+    # @param {int[]} nums an integer array
+    # @param {int} low an integer
+    # @param {int} high an integer
+    # @return {int[]} any of the possible solutions
+    def partition2(self, nums, low, high):
+        # Write your code here
+        if len(nums) <= 1:
+            return
+        
+        pl, pr = 0, len(nums) - 1
+        i = 0
+        while i <= pr:
+            if nums[i] < low:
+                nums[pl], nums[i] = nums[i], nums[pl]
+                pl += 1
+                i += 1
+            elif nums[i] > high:
+                nums[pr], nums[i] = nums[i], nums[pr]
+                pr -= 1
+            else:
+                i += 1
+
+# 参考程序2
+class Solution:
+    # @param {int[]} nums an integer array
+    # @param {int} low an integer
+    # @param {int} high an integer
+    # @return nothing
+    def partition2(self, nums, low, high):
+        # Write your code here
+        left = 0
+        right = len(nums) - 1
+
+        # 首先把区间分为 < low 和 >= low 的两个部分 
+        while left <= right:
+            while left <= right and nums[left] < low:
+                left = left + 1
+            while left <= right and nums[right] >= low:
+                right = right - 1
+            if left <= right:
+                nums[right],nums[left] = nums[left],nums[right]
+                left = left + 1
+                right = right - 1
+
+        right = len(nums) - 1
+        # 然后从 >= low 的部分里分出 <= high 和 > high 的两个部分
+        while left <= right:
+            while left <= right and nums[left] <= high:
+                left = left + 1
+            while left <= right and nums[right] > high:
+                right = right - 1
+            if left <= right:
+                nums[right],nums[left] = nums[left],nums[right]
+                left = left + 1
+                right = right - 1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/partition-array.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/partition-array.md"
new file mode 100644
index 0000000..cd2661b
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/partition-array.md"
@@ -0,0 +1,52 @@
+# 数组划分
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/partition-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个整数数组 *nums* 和一个整数 *k*。划分数组（即移动数组 *nums* 中的元素），使得：
+
+- 所有小于k的元素移到左边
+- 所有大于等于k的元素移到右边
+
+返回数组划分的位置，即数组中第一个位置 *i*，满足 *nums*[*i*] 大于等于 *k*。
+ ### 样例说明
+ 例1:
+```
+输入:
+[],9
+输出:
+0
+
+```
+
+例2:
+```
+输入:
+[3,2,2,1],2
+输出:1
+解释:
+真实的数组为[1,2,2,3].所以返回 1
+```
+
+
+ ### 参考代码
+ 快速选择算法
+```python
+class Solution:
+    """
+    @param nums: The integer array you should partition
+    @param k: As description
+    @return: The index after partition
+    """
+    def partitionArray(self, nums, k):
+        left, right = 0, len(nums) - 1
+        while left <= right:
+            while left <= right and nums[left] < k:
+                left += 1
+            while left <= right and nums[right] >= k:
+                right -= 1
+            if left <= right:
+                nums[left], nums[right] = nums[right], nums[left]
+                left += 1
+                right -= 1
+        return left
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/recover-rotated-sorted-array.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/recover-rotated-sorted-array.md"
new file mode 100644
index 0000000..a80eb63
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/recover-rotated-sorted-array.md"
@@ -0,0 +1,21 @@
+# 恢复旋转排序数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/recover-rotated-sorted-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个**旋转**排序数组，在原地恢复其排序。（升序）
+ ### 样例说明
+ 
+ ### 参考代码
+ Given a rotated sorted array, recover it to sorted array in-place.
+
+Example
+[4, 5, 1, 2, 3] -> [1, 2, 3, 4, 5]
+```python
+class Solution:
+    """
+    @param nums: The rotated sorted array
+    @return:  The recovered sorted array
+    """
+    def recoverRotatedSortedArray(self, nums):
+        nums.sort()
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/remove-duplicates-from-sorted-list.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/remove-duplicates-from-sorted-list.md"
new file mode 100644
index 0000000..b5471cb
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/remove-duplicates-from-sorted-list.md"
@@ -0,0 +1,49 @@
+# 删除排序链表中的重复元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-duplicates-from-sorted-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个排序链表，删除所有重复的元素每个元素只留下一个。
+ ### 样例说明
+ ```
+样例 1:
+	输入:  null
+	输出: null
+
+
+样例 2:
+	输入: 1->1->2->null
+	输出: 1->2->null
+
+样例 3:
+	输入: 1->1->2->3->3->null
+	输出: 1->2->3->null
+
+
+```
+ ### 参考代码
+ Given a sorted linked list, delete all duplicates such that each element appear only once.
+
+For example,
+Given 1->1->2, return 1->2.
+Given 1->1->2->3->3, return 1->2->3.
+
+跳过相同的元素，指向再后一个元素。
+```java
+public class Solution {
+    public ListNode deleteDuplicates(ListNode head) {
+        if (head == null) {
+            return null;
+        }
+
+        ListNode node = head;
+        while (node.next != null) {
+            if (node.val == node.next.val) {
+                node.next = node.next.next;
+            } else {
+                node = node.next;
+            }
+        }
+        return head;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/reverse-pairs.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/reverse-pairs.md"
new file mode 100644
index 0000000..de9edbd
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/reverse-pairs.md"
@@ -0,0 +1,67 @@
+# 逆序对
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reverse-pairs/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在数组中的两个数字如果前面一个数字大于后面的数字，则这两个数字组成一个逆序对。给你一个数组，求出这个数组中逆序对的总数。
+概括：如果a[i] > a[j] 且 i < j， a[i] 和 a[j] 构成一个逆序对。
+ ### 样例说明
+ **样例1**
+
+```
+输入: A = [2, 4, 1, 3, 5]
+输出: 3
+解释:
+(2, 1), (4, 1), (4, 3) 是逆序对
+```
+
+**样例2**
+
+```
+输入: A = [1, 2, 3, 4]
+输出: 0
+解释:
+没有逆序对
+```
+
+ ### 参考代码
+ 利用归并排序的思想求逆序对，复杂度O(nlogn)
+当然也可以用树状数组或者线段树求解
+```python
+class Solution:
+    # @param {int[]} A an array
+    # @return {int} total of reverse pairs
+    def reversePairs(self, A):
+        # Write your code here
+        self.tmp = [0] * len(A)
+        return self.mergeSort(A, 0, len(A) - 1)
+
+    def mergeSort(self, A, l, r):
+        if l >= r:
+            return 0
+        
+        m = (l + r) >> 1
+        ans = self.mergeSort(A, l, m) + self.mergeSort(A, m + 1, r)
+        i, j, k = l, m + 1, l
+        while i <= m and j <= r:
+            if A[i] > A[j]:
+                self.tmp[k] = A[j]
+                j += 1
+                ans += m - i + 1
+            else:
+                self.tmp[k] = A[i]
+                i += 1
+            k += 1
+    
+        while i <= m:
+            self.tmp[k] = A[i]
+            k += 1
+            i += 1
+        while j <= r:
+            self.tmp[k] = A[j]
+            k += 1
+            j += 1
+        for i in xrange(l, r + 1):
+            A[i] = self.tmp[i]
+
+        return ans
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sliding-window-median.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sliding-window-median.md"
new file mode 100644
index 0000000..2deb9ce
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sliding-window-median.md"
@@ -0,0 +1,173 @@
+# 滑动窗口的中位数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sliding-window-median/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个包含 n 个整数的数组，和一个大小为 *k* 的滑动窗口,从左到右在数组中滑动这个窗口，找到数组中每个窗口内的中位数。(如果数组个数是偶数，则在该窗口排序数字后，返回第 N/2 个数字。)
+ ### 样例说明
+ **样例 1:**
+```
+输入:
+[1,2,7,8,5]
+3
+输出:
+[2,7,7]
+
+解释:
+最初，窗口的数组是这样的：`[ | 1,2,7 | ,8,5]` , 返回中位数 `2`;
+接着，窗口继续向前滑动一次。`[1, | 2,7,8 | ,5]`, 返回中位数 `7`;
+接着，窗口继续向前滑动一次。`[1,2, | 7,8,5 | ]`, 返回中位数 `7`;
+```
+
+**样例 2:**
+```
+输入:
+[1,2,3,4,5,6,7]
+4
+输出:
+[2,3,4,5]
+
+解释:
+最初，窗口数组是这样的：`[ | 1,2,3,4, | 5,6,7]` , 返回中位数 `2`;
+接着，窗口向前滑动一次.`[1,| 2,3,4,5 | 6,7]`,返回中位数 `3`;
+接着，窗口向前滑动一次.`[1,2, | 3,4,5,6 | 7 ]`, 返回中位数 `4`;
+接着，窗口向前滑动一次`[1,2,3,| 4,5,6,7 ]`, 返回中位数 `5`;
+```
+ ### 参考代码
+ 使用九章算法强化班中讲到的 HashHeap。即一个 Hash + Heap。
+Hash 的 key 是 Heap 里的每个元素，值是这个元素在 Heap 中的下标。
+
+要做这个题首先需要先做一下 Data Stream Median。这个题是只在一个集合中增加数，不删除数，然后不断的求中点。
+Sliding Window Median，就是不断的增加数，删除数，然后求中点。比 Data Stream Median 难的地方就在于如何支持删除数。
+
+因为 Data Stream Median 的方法是用 两个 Heap，一个 max heap，一个min heap。所以删除的话，就需要让 heap 也支持删除操作。
+由于 Python 的 heapq 并不支持 logn 时间内的删除操作，因此只能自己实现一个 hash + heap 的方法。
+
+总体时间复杂度 $O(nlogk)$，n是元素个数，k 是 window 的大小。
+```python
+class HashHeap:
+    
+    def __init__(self, desc=False):
+        self.hash = dict()
+        self.heap = []
+        self.desc = desc
+        
+    @property
+    def size(self):
+        return len(self.heap)
+        
+    def push(self, item):
+        self.heap.append(item)
+        self.hash[item] = self.size - 1
+        self._sift_up(self.size - 1)
+        
+    def pop(self):
+        item = self.heap[0]
+        self.remove(item)
+        return item
+    
+    def top(self):
+        return self.heap[0]
+        
+    def remove(self, item):
+        if item not in self.hash:
+            return
+            
+        index = self.hash[item]
+        self._swap(index, self.size - 1)
+        
+        del self.hash[item]
+        self.heap.pop()
+        
+        # in case of the removed item is the last item
+        if index < self.size:
+            self._sift_up(index)
+            self._sift_down(index)
+
+    def _smaller(self, left, right):
+        return right < left if self.desc else left < right
+
+    def _sift_up(self, index):
+        while index != 0:
+            parent = index // 2
+            if self._smaller(self.heap[parent], self.heap[index]):
+                break
+            self._swap(parent, index)
+            index = parent
+    
+    def _sift_down(self, index):
+        if index is None:
+            return
+        while index * 2 < self.size:
+            smallest = index
+            left = index * 2
+            right = index * 2 + 1
+            
+            if self._smaller(self.heap[left], self.heap[smallest]):
+                smallest = left
+                
+            if right < self.size and self._smaller(self.heap[right], self.heap[smallest]):
+                smallest = right
+                
+            if smallest == index:
+                break
+            
+            self._swap(index, smallest)
+            index = smallest
+        
+    def _swap(self, i, j):
+        elem1 = self.heap[i]
+        elem2 = self.heap[j]
+        self.heap[i] = elem2
+        self.heap[j] = elem1
+        self.hash[elem1] = j
+        self.hash[elem2] = i
+    
+class Solution:
+    """
+    @param nums: A list of integers
+    @param k: An integer
+    @return: The median of the element inside the window at each moving
+    """
+    def medianSlidingWindow(self, nums, k):
+        if not nums or len(nums) < k:
+            return []
+            
+        self.maxheap = HashHeap(desc=True)
+        self.minheap = HashHeap()
+        
+        for i in range(0, k - 1):
+            self.add((nums[i], i))
+            
+        medians = []
+        for i in range(k - 1, len(nums)):
+            self.add((nums[i], i))
+            # print(self.maxheap.heap, self.median, self.minheap.heap)
+            medians.append(self.median)
+            self.remove((nums[i - k + 1], i - k + 1))
+            # print(self.maxheap.heap, self.median, self.minheap.heap)
+            
+        return medians
+            
+    def add(self, item):
+        if self.maxheap.size > self.minheap.size:
+            self.minheap.push(item)
+        else:
+            self.maxheap.push(item)
+            
+        if self.maxheap.size == 0 or self.minheap.size == 0:
+            return
+            
+        if self.maxheap.top() > self.minheap.top():
+            self.maxheap.push(self.minheap.pop())
+            self.minheap.push(self.maxheap.pop())
+        
+    def remove(self, item):
+        self.maxheap.remove(item)
+        self.minheap.remove(item)
+        if self.maxheap.size < self.minheap.size:
+            self.maxheap.push(self.minheap.pop())
+        
+    @property
+    def median(self):
+        return self.maxheap.top()[0]
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-integers-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-integers-ii.md"
new file mode 100644
index 0000000..c1ba482
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-integers-ii.md"
@@ -0,0 +1,61 @@
+# 整数排序 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sort-integers-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一组整数，请将其在原地按照升序排序。使用归并排序，快速排序，堆排序或者任何其他 O(*n* log *n*) 的排序算法。
+ ### 样例说明
+ **例1：**
+```
+输入：[3,2,1,4,5]，
+输出：[1,2,3,4,5]。
+```
+**例2：**
+```
+输入：[2,3,1]，
+输出：[1,2,3]。
+```
+ ### 参考代码
+ 快速排序实现
+```java
+public class Solution {
+    /**
+     * @param A an integer array
+     * @return void
+     */
+    public void sortIntegers2(int[] A) {
+        quickSort(A, 0, A.length - 1);
+    }
+    
+    private void quickSort(int[] A, int start, int end) {
+        if (start >= end) {
+            return;
+        }
+        
+        int left = start, right = end;
+        // key point 1: pivot is the value, not the index
+        int pivot = A[(start + end) / 2];
+
+        // key point 2: every time you compare left & right, it should be 
+        // left <= right not left < right
+        while (left <= right) {
+            while (left <= right && A[left] < pivot) {
+                left++;
+            }
+            while (left <= right && A[right] > pivot) {
+                right--;
+            }
+            if (left <= right) {
+                int temp = A[left];
+                A[left] = A[right];
+                A[right] = temp;
+                
+                left++;
+                right--;
+            }
+        }
+        
+        quickSort(A, start, right);
+        quickSort(A, left, end);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-integers-map-reduce.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-integers-map-reduce.md"
new file mode 100644
index 0000000..839225a
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-integers-map-reduce.md"
@@ -0,0 +1,110 @@
+# 排序(Map Reduce)
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sort-integers-map-reduce/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 通过Map Reduce框架对整数进行排序
+在mapper中， key为可以忽略的文档id， value是待排序的整数.
+在reducer中, 你可以指定什么是key或者value(取决于你是如何实现你的mapper类的).对于输出的reducer类, key可以是任意， 但value需要有序(顺序取决于你什么时候输出) 
+ ### 样例说明
+ 例1:
+```
+输入:
+1: [14,7,9]
+2: [10,1]
+3: [2,5,6,3]
+4: []
+输出:
+[1,2,3,5,6,7,9,10,14]
+
+```
+
+例2:
+```
+输入:
+1: [14,7]
+输出:
+[7,14]
+
+```
+
+
+ ### 参考代码
+ 在reduce里，对相应的Integer利用PriorityQueue排序即可
+```cpp
+/**
+ * Definition of Input:
+ * template<class T>
+ * class Input {
+ * public:
+ *     bool done(); 
+ *         // Returns true if the iteration has elements or false.
+ *     void next();
+ *         // Move to the next element in the iteration
+ *         // Runtime error if the iteration has no more elements
+ *     T value();
+ *        // Get the current element, Runtime error if
+ *        // the iteration has no more elements
+ * }
+ */
+class SortIntegersMapper: public Mapper {
+public:
+    void Map(int _, Input<vector<int>>* input) {
+        // Write your code here
+        // Please directly use func 'output' to output 
+        // the results into output buffer.
+        // void output(string &key, vector<int>& value);
+        while (!input->done()) {
+            vector<int> value = input->value();
+            sort(value.begin(), value.end());
+            string temp = "ignore_key";
+            output(temp, value);
+            input->next();
+        }
+    }
+};
+
+class Node {
+public:
+    int row, col, val;
+    Node(int _r, int _c, int _v): row(_r), col(_c), val(_v){};
+    bool operator < (const Node& obj) const {
+        return val > obj.val;
+    }
+};
+
+class SortIntegersReducer: public Reducer {
+public:
+    void Reduce(string &key, vector<vector<int>>& input) {
+        // Write your code here
+        // Please directly use func 'output' to output 
+        // the results into output buffer.
+        // void output(string &key, vector<int>& value);
+        vector<int> results;
+        if (input.size() == 0) {
+            output(key, results);
+            return;
+        }
+
+        int k = input.size();
+        priority_queue<Node> queue;
+
+        for (int i = 0; i < k; ++i) {
+            if (input[i].size() > 0)
+                queue.push(Node(i, 0, input[i][0]));
+        }
+
+        while (!queue.empty()) {
+            Node temp = queue.top();
+            queue.pop();
+            int row = temp.row;
+            int col = temp.col;
+            int val = temp.val;
+            results.push_back(val);
+            if (col + 1 < input[row].size())
+                queue.push(Node(row, col + 1, input[row][col + 1]));
+        }
+
+        output(key, results);
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-integers.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-integers.md"
new file mode 100644
index 0000000..7b65a69
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-integers.md"
@@ -0,0 +1,115 @@
+# 整数排序
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sort-integers/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一组整数，按照升序排序，使用选择排序，冒泡排序，插入排序或者任何 O(n<sup>2</sup>) 的排序算法。
+
+ ### 样例说明
+ ```
+样例  1:
+	输入:  [3, 2, 1, 4, 5]
+	输出:  [1, 2, 3, 4, 5]
+	
+	样例解释: 
+	返回排序后的数组。
+
+样例 2:
+	输入:  [1, 1, 2, 1, 1]
+	输出:  [1, 1, 1, 1, 2]
+	
+	样例解释: 
+	返回排好序的数组。
+
+```
+ ### 参考代码
+ 几种$O(n^2)$时间复杂度的排序算法。
+```java
+//选择排序
+public class Solution {
+    /*
+     * @param A: an integer array
+     * @return: 
+     */
+    public void sortIntegers(int[] A) {
+        // write your code here
+        for (int i = 0; i < A.length; i++) {
+            int minIdx = i;
+            for (int j = i; j < A.length; j++) {
+                if (A[j] < A[minIdx]) {
+                    minIdx = j;
+                }
+            }
+            int tmp = A[i];
+            A[i] = A[minIdx];
+            A[minIdx] = tmp;
+        }
+    }
+}
+
+
+//选择排序2
+public class Solution {
+    /*
+     * @param A: an integer array
+     * @return: 
+     */
+    public void sortIntegers(int[] A) {
+        // write your code here
+        for (int i = 0; i < A.length; i++) {
+            for (int j = i + 1; j < A.length; j++) {
+                if (A[i] > A[j]) {
+                    int tmp = A[i];
+                    A[i] = A[j];
+                    A[j] = tmp;
+                }
+            }
+        }
+    }
+}
+
+//插入排序
+public class Solution {
+    /*
+     * @param A: an integer array
+     * @return: 
+     */
+    public void sortIntegers(int[] A) {
+        // write your code here
+        for (int i = 0; i < A.length; i++) {
+            int newVal = A[i];
+            int j = i - 1;
+
+            while (j >= 0 && A[j] > newVal) {
+                A[j + 1] = A[j];
+                j--;
+            }
+            A[j + 1] = newVal;
+        }
+    }
+}
+
+//冒泡排序
+public class Solution {
+    /*
+     * @param A: an integer array
+     * @return: 
+     */
+    public void sortIntegers(int[] A) {
+        // write your code here
+        while (true) {
+            boolean exchange = false;
+            for (int i = 0; i < A.length - 1; i++) {
+                if (A[i] > A[i + 1]) {
+                    int tmp = A[i];
+                    A[i] = A[i + 1];
+                    A[i + 1] = tmp;
+                    exchange = true;
+                }
+            }
+            if (!exchange) {
+                break;
+            }
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-letters-by-case.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-letters-by-case.md"
new file mode 100644
index 0000000..47b63cd
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-letters-by-case.md"
@@ -0,0 +1,40 @@
+# 字符大小写排序
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sort-letters-by-case/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">给定一个只包含字母的字符串，按照先小写字母后大写字母的顺序进行排序。</span></p>
+ ### 样例说明
+ ```
+样例 1:
+	输入:  "abAcD"
+	输出:  "acbAD"
+
+样例 2:
+	输入: "ABC"
+	输出:  "ABC"
+	
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    public void sortLetters(char[] chars) {
+        int i = 0, j = chars.length - 1;
+        
+        while (i <= j) {
+            while (i <= j && Character.isLowerCase(chars[i])) {
+                i++;
+            }
+            while (i <= j && Character.isUpperCase(chars[j])) {
+                j--;
+            }
+            if (i <= j) {
+                char tmp = chars[i];
+                chars[i] = chars[j];
+                chars[j] = tmp;
+                i++;
+                j--;
+            }
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-list.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-list.md"
new file mode 100644
index 0000000..fe9dc4f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/sort-list.md"
@@ -0,0 +1,239 @@
+# 链表排序
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sort-list/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在 O(*n* log *n*) 时间复杂度和常数级的空间复杂度下给链表排序。
+
+ ### 样例说明
+ ```
+样例 1:
+	输入:  1->3->2->null
+	输出:  1->2->3->null
+
+样例 2:
+	输入: 1->7->2->6->null
+	输出: 1->2->6->7->null
+	
+```
+ ### 参考代码
+ Sort a linked list in O(n log n) time using constant space complexity.<div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博:&nbsp;</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/ByB4LtgnG" target="_blank">http://weibo.com/3948019741/ByB4LtgnG</a></span></font><br></div>
+
+
+快速排序算法可以在链表中使用。
+```java
+// version 1: Merge Sort
+public class Solution {            
+    private ListNode findMiddle(ListNode head) {
+        ListNode slow = head, fast = head.next;
+        while (fast != null && fast.next != null) {
+            fast = fast.next.next;
+            slow = slow.next;
+        }
+        return slow;
+    }    
+
+    private ListNode merge(ListNode head1, ListNode head2) {
+        ListNode dummy = new ListNode(0);
+        ListNode tail = dummy;
+        while (head1 != null && head2 != null) {
+            if (head1.val < head2.val) {
+                tail.next = head1;
+                head1 = head1.next;
+            } else {
+                tail.next = head2;
+                head2 = head2.next;
+            }
+            tail = tail.next;
+        }
+        if (head1 != null) {
+            tail.next = head1;
+        } else {
+            tail.next = head2;
+        }
+
+        return dummy.next;
+    }
+
+    public ListNode sortList(ListNode head) {
+        if (head == null || head.next == null) {
+            return head;
+        }
+
+        ListNode mid = findMiddle(head);
+
+        ListNode right = sortList(mid.next);
+        mid.next = null;
+        ListNode left = sortList(head);
+
+        return merge(left, right);
+    }
+}
+
+// version 2: Quick Sort 1
+public class Solution {
+    public ListNode sortList(ListNode head) {
+        if (head == null || head.next == null) {
+            return head;
+        }
+        
+        ListNode mid = findMedian(head); // O(n)
+        
+        ListNode leftDummy = new ListNode(0), leftTail = leftDummy;
+        ListNode rightDummy = new ListNode(0), rightTail = rightDummy;
+        ListNode middleDummy = new ListNode(0), middleTail = middleDummy;
+        while (head != null) {
+            if (head.val < mid.val) {
+                leftTail.next = head;
+                leftTail = head;
+            } else if (head.val > mid.val) {
+                rightTail.next = head;
+                rightTail = head;
+            } else {
+                middleTail.next = head;
+                middleTail = head;
+            }
+            head = head.next;
+        }
+        
+        leftTail.next = null;
+        middleTail.next = null;
+        rightTail.next = null;
+        
+        ListNode left = sortList(leftDummy.next);
+        ListNode right = sortList(rightDummy.next);
+        
+        return concat(left, middleDummy.next, right);
+    }
+    
+    private ListNode findMedian(ListNode head) {
+        ListNode slow = head, fast = head.next;
+        while (fast != null && fast.next != null) {
+            slow = slow.next;
+            fast = fast.next.next;
+        }
+        return slow;
+    }
+    
+    private ListNode concat(ListNode left, ListNode middle, ListNode right) {
+        ListNode dummy = new ListNode(0), tail = dummy;
+        
+        tail.next = left; tail = getTail(tail);
+        tail.next = middle; tail = getTail(tail);
+        tail.next = right; tail = getTail(tail);
+        return dummy.next;
+    }
+    
+    private ListNode getTail(ListNode head) {
+        if (head == null) {
+           return null;
+        } 
+       
+        while (head.next != null) {
+            head = head.next;
+        }
+        return head;
+    }
+}
+
+// version 3: Quick Sort 2
+/**
+ * Definition for ListNode.
+ * public class ListNode {
+ *     int val;
+ *     ListNode next;
+ *     ListNode(int val) {
+ *         this.val = val;
+ *         this.next = null;
+ *     }
+ * }
+ */ 
+class Pair {
+    public ListNode first, second; 
+    public Pair(ListNode first, ListNode second) {
+        this.first = first;
+        this.second = second;
+    }
+}
+
+public class Solution {
+    /**
+     * @param head: The head of linked list.
+     * @return: You should return the head of the sorted linked list,
+                    using constant space complexity.
+     */
+    public ListNode sortList(ListNode head) {
+        if (head == null || head.next == null) {
+            return head;
+        }
+        
+        ListNode mid = findMedian(head); // O(n)
+        Pair pair = partition(head, mid.val); // O(n)
+        
+        ListNode left = sortList(pair.first);
+        ListNode right = sortList(pair.second);
+        
+        getTail(left).next = right; // O(n)
+        
+        return left;
+    }
+    
+    // 1->2->3 return 2
+    // 1->2 return 1
+    private ListNode findMedian(ListNode head) {
+        ListNode slow = head, fast = head.next;
+        while (fast != null && fast.next != null) {
+            slow = slow.next;
+            fast = fast.next.next;
+        }
+        return slow;
+    }
+    
+    // < value in the left, > value in the right
+    private Pair partition(ListNode head, int value) {
+        ListNode leftDummy = new ListNode(0), leftTail = leftDummy;
+        ListNode rightDummy = new ListNode(0), rightTail = rightDummy;
+        ListNode equalDummy = new ListNode(0), equalTail = equalDummy;
+        while (head != null) {
+            if (head.val < value) {
+                leftTail.next = head;
+                leftTail = head;
+            } else if (head.val > value) {
+                rightTail.next = head;
+                rightTail = head;
+            } else {
+                equalTail.next = head;
+                equalTail = head;
+            }
+            head = head.next;
+        }
+        
+        leftTail.next = null;
+        rightTail.next = null;
+        equalTail.next = null;
+        
+        if (leftDummy.next == null && rightDummy.next == null) {
+            ListNode mid = findMedian(equalDummy.next);
+            leftDummy.next = equalDummy.next;
+            rightDummy.next = mid.next;
+            mid.next = null;
+        } else if (leftDummy.next == null) {
+            leftTail.next = equalDummy.next;
+        } else {
+            rightTail.next = equalDummy.next;
+        }
+        
+        return new Pair(leftDummy.next, rightDummy.next);
+    }
+    
+    private ListNode getTail(ListNode head) {
+        if (head == null) {
+           return null;
+        } 
+       
+        while (head.next != null) {
+            head = head.next;
+        }
+        return head;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/top-k-frequent-elements.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/top-k-frequent-elements.md"
new file mode 100644
index 0000000..e9cac99
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/top-k-frequent-elements.md"
@@ -0,0 +1,61 @@
+# 前K个高频元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/top-k-frequent-elements/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个非空的整数数组，返回其中出现频率前 $k$ 高的元素。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: nums = [1,1,1,2,2,3], k = 2
+输出: [1,2]
+```
+
+**样例 2:**
+
+```
+输入: nums = [1], k = 1
+输出: [1]
+```
+
+
+ ### 参考代码
+ 这题可以通过最小堆或者桶排实现：
+- 最小堆
+因为最终需要返回前 k 个频率最大的元素，通过维护一个元素数目为 k 的最小堆，每次都将新的元素与堆顶端的元素（堆中频率最小的元素）进行比较，如果新的元素的频率比堆顶端的元素大，则弹出堆顶端的元素，将新的元素添加进堆中。最终，堆中的 k 个元素即为前 k 个高频元素。
+- 桶排
+将数组中的元素按照出现频次进行分组，即出现频次为 i 的元素存放在第 i 个桶。最后，从桶中逆序取出前 k 个元素。
+```java
+public class Solution {
+    public List<Integer> topKFrequent(int[] nums, int k) {
+        Map<Integer, Integer> hashmap = new HashMap<Integer, Integer>();
+        PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<Map.Entry<Integer, Integer>>(
+            new Comparator<Map.Entry<Integer, Integer>>() {
+                public int compare(Map.Entry<Integer, Integer> e1, Map.Entry<Integer, Integer> e2) {
+                    return e1.getValue() - e2.getValue();
+                }
+            });
+        for (int i = 0; i < nums.length; i++) {
+            if (!hashmap.containsKey(nums[i])) {
+                hashmap.put(nums[i], 1);
+            } else {
+                hashmap.put(nums[i], hashmap.get(nums[i]) + 1);
+            }
+        }
+        
+        for (Map.Entry<Integer, Integer> entry : hashmap.entrySet()) {
+            if (queue.size() < k) {
+                queue.offer(entry);
+            } else if (queue.peek().getValue() < entry.getValue()) {
+                queue.poll();
+                queue.offer(entry);
+            }
+        }
+        
+        List<Integer> ans = new ArrayList<Integer>();
+        for (Map.Entry<Integer, Integer> entry : queue)
+            ans.add(entry.getKey());
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/top-k-frequent-words-map-reduce.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/top-k-frequent-words-map-reduce.md"
new file mode 100644
index 0000000..b1e2fd5
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/top-k-frequent-words-map-reduce.md"
@@ -0,0 +1,109 @@
+# 最常使用的k个单词(Map Reduce)
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/top-k-frequent-words-map-reduce/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 使用map reduce框架查找最常使用的k个单词.
+mapper的key为文档的id, 值是文档的内容, 文档中的单词由空格分割.
+对于reducer，应该输出最多为k个key-value对, 包括最常用的k个单词以及他们在当前reducer中的使用频率.评判系统会合并不同的reducer中的结果以得到 全局 最常使用的k个单词, 所以你不需要关注这一环节. `k` 在TopK类的构造器中给出. 
+
+ ### 样例说明
+ 
+ ### 参考代码
+ 利用map来维护单词出现的次数
+```java
+/**
+ * Definition of OutputCollector:
+ * class OutputCollector<K, V> {
+ *     public void collect(K key, V value);
+ *         // Adds a key/value pair to the output buffer
+ * }
+ * Definition of Document:
+ * class Document {
+ *     public int id;
+ *     public String content;
+ * }
+ */
+class Pair {
+    String key;
+    int value;
+    
+    Pair(String key, int value) {
+        this.key = key;
+        this.value = value;
+    }
+}
+
+public class TopKFrequentWords {
+
+    public static class Map {
+        public void map(String _, Document value,
+                        OutputCollector<String, Integer> output) {
+            // Write your code here
+            // Output the results into output buffer.
+            // Ps. output.collect(String key, int value);
+            int id = value.id;
+            String content = value.content;
+            String[] words = content.split(" ");
+            for (String word : words)
+                if (word.length() > 0) {
+                    output.collect(word, 1);
+                }
+        }
+    }
+
+    public static class Reduce {
+        private PriorityQueue<Pair> Q = null;
+        private int k;
+
+        private Comparator<Pair> pairComparator = new Comparator<Pair>() {
+            public int compare(Pair left, Pair right) {
+                if (left.value != right.value) {
+                    return left.value - right.value;
+                }
+                return right.key.compareTo(left.key);
+            }
+        };
+
+        public void setup(int k) {
+            // initialize your data structure here
+            this.k = k;
+            Q = new PriorityQueue<Pair>(k, pairComparator);
+        }   
+
+        public void reduce(String key, Iterator<Integer> values) {
+            // Write your code here
+            int sum = 0;
+            while (values.hasNext()) {
+                    sum += values.next();
+            }
+
+            Pair pair = new Pair(key, sum);
+            if (Q.size() < k) {
+                Q.add(pair);
+            } else {
+                Pair peak = Q.peek();
+                if (pairComparator.compare(pair, peak) > 0) {
+                    Q.poll();
+                    Q.add(pair);
+                }
+            }
+        }
+
+        public void cleanup(OutputCollector<String, Integer> output) {
+            // Output the top k pairs <word, times> into output buffer.
+            // Ps. output.collect(String key, Integer value);
+            List<Pair> pairs = new ArrayList<Pair>();
+            while (!Q.isEmpty()) {
+                pairs.add(Q.poll());
+            }
+
+            // reverse result
+            int n = pairs.size();
+            for (int i = n - 1; i >= 0; --i) {
+                Pair pair = pairs.get(i);
+                output.collect(pair.key, pair.value);
+            }
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/top-k-largest-numbers.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/top-k-largest-numbers.md"
new file mode 100644
index 0000000..4b6260f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/top-k-largest-numbers.md"
@@ -0,0 +1,113 @@
+# 前K大数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/top-k-largest-numbers/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一个数组中找到前K大的数
+ ### 样例说明
+ **样例1**
+
+```
+输入: [3, 10, 1000, -99, 4, 100] 并且 k = 3
+输出: [1000, 100, 10]
+```
+
+**样例2**
+
+```
+输入: [8, 7, 6, 5, 4, 3, 2, 1] 并且 k = 5
+输出: [8, 7, 6, 5, 4]
+```
+
+ ### 参考代码
+ 用堆排序求出前K大数即可
+```java
+// base on heap
+class Solution {
+    /*
+     * @param nums an integer array
+     * @param k an integer
+     * @return the top k largest numbers in array
+     */
+     public int[] topk(int[] nums, int k) {
+         PriorityQueue<Integer> minheap = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
+             public int compare(Integer o1, Integer o2) {
+                 return o1 - o2;
+             }
+         });
+
+         for (int i : nums) {
+             minheap.add(i);
+             if (minheap.size() > k) {
+                minheap.poll();
+             }
+         }
+
+         int[] result = new int[k];
+         for (int i = 0; i < result.length; i++) {
+             result[k - i - 1] = minheap.poll();
+         }
+         return result;
+    }
+};
+
+// base on quicksort
+import java.util.Random;
+
+class Solution {
+    /*
+     * @param nums an integer array
+     * @param k an integer
+     * @return the top k largest numbers in array
+     */
+    public int[] topk(int[] nums, int k) {
+        // Write your code here
+        quickSort(nums, 0, nums.length - 1, k);
+
+        int[] topk = new int[k];
+        for (int i = 0; i < k; ++i)
+            topk[i] = nums[i];
+
+        return topk;
+    }
+    
+    private void quickSort(int[] A, int start, int end, int k) {
+        if (start >= k)
+            return;
+
+        if (start >= end) {
+            return;
+        }
+        
+        int left = start, right = end;
+        // key point 1: pivot is the value, not the index
+        Random rand =new Random(end - start + 1);
+        int index = rand.nextInt(end - start + 1) + start;
+        int pivot = A[index];
+
+        // key point 2: every time you compare left & right, it should be 
+        // left <= right not left < right
+        while (left <= right) {
+            // key point 3: A[left] < pivot not A[left] <= pivot
+            while (left <= right && A[left] > pivot) {
+                left++;
+            }
+            // key point 3: A[right] > pivot not A[right] >= pivot
+            while (left <= right && A[right] < pivot) {
+                right--;
+            }
+
+            if (left <= right) {
+                int temp = A[left];
+                A[left] = A[right];
+                A[right] = temp;
+                
+                left++;
+                right--;
+            }
+        }
+        
+        quickSort(A, start, right, k);
+        quickSort(A, left, end, k);
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/wiggle-sort.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/wiggle-sort.md"
new file mode 100644
index 0000000..da5abaa
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225/wiggle-sort.md"
@@ -0,0 +1,66 @@
+# 摆动排序
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/wiggle-sort/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个没有排序的数组，请将原数组**就地**重新排列满足如下性质
+
+```
+nums[0] <= nums[1] >= nums[2] <= nums[3]....
+```
+
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [3, 5, 2, 1, 6, 4]
+输出: [1, 6, 2, 5, 3, 4]
+解释: 这个问题可能有多种答案, [2, 6, 1, 5, 3, 4] 同样可以.
+```
+
+**样例 2:**
+
+```
+输入: [1, 2, 3, 4]
+输出: [1, 4, 2, 3]
+```
+ ### 参考代码
+ 从左到右扫一遍，不满足条件的交换就好了。
+需要证明的是，当我们 交换了 `nums[i]` 和 `nums[i - 1]` 以后：
+
+```
+... nums[i - 2], nums[i], nums[i - 1]
+```
+
+nums[i - 2] 不会和 nums[i] 形成逆序（不满足条件的大小关系）
+
+那假如原来是 nums[i - 2] <= nums[i - 1]，那么 nums[i - 1] 和 nums[i] 交换的条件是，nums[i - 1] <= nums[i]。
+那我们就推导出此时 nums[i] >= nums[i - 2]，因此交换之后，不会让 nums[i] 和 nums[i - 2] 的大小关系出现变化。
+
+反过来如果 nums[i - 2] >= nums[i - 1] 的情况同理。
+
+---
+
+或者, 老老实实快排(不需要额外空间的 nlogn 的排序算法), 然后从第2个数开始两两交换.
+```java
+public class Solution {
+    /**
+     * @param nums a list of integer
+     * @return void
+     */
+    public void wiggleSort(int[] nums) {
+        // Write your code here
+        for(int i=1; i<nums.length; i++) {
+            if((i%2==1 && (nums[i] < nums[i-1]) || 
+              (i%2==0) && (nums[i] > nums[i-1]))) {
+                swap(nums, i-1, i);
+            }
+        }
+    }
+    
+    public void swap(int[] nums, int i, int j) {
+        int temp = nums[i];
+        nums[i] = nums[j];
+        nums[j] = temp;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/assign-cookies.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/assign-cookies.md"
new file mode 100644
index 0000000..1c89a63
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/assign-cookies.md"
@@ -0,0 +1,41 @@
+# 分饼干
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/assign-cookies/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假设你是一个了不起的家长，准备给你的孩子们一些饼干吃，但是你只能给每个孩子至多一块饼干。每一块饼干$j$都有一个尺寸$s_{j}$；同时每一个孩子$i$都有一个贪吃指数$g_{i}$，代表了能使他满足的最小的饼干尺寸。如果$s_{j} \geq g_{i}$，那么就可以将饼干$j$分给孩子$i$使他得到满足。你的目标是使最多的孩子得到满足，输出这个最大值。
+ ### 样例说明
+ **样例1：**
+
+```
+输入：[1,2,3], [1,1]
+输出：1
+说明：你有三个孩子和两块饼干，三个孩子的贪吃指数分别是1，2，3
+虽然你有两块饼干，但是因为它们的大小都为1，你只能满足让贪吃指数为1的孩子满足，因此你应该输出1
+```
+
+**样例2：**
+
+```
+输入：[1,2], [1,2,3]
+输出：2
+说明：你有两个孩子和三块饼干，两个孩子的贪吃指数分别是1和2
+这三块饼干的大小足以满足所有的孩子，因此你应该输出2
+```
+ ### 参考代码
+ <p><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><p><br></p></blockquote></p>
+```cpp
+class Solution {
+public:
+    int findContentChildren(vector<int>& g, vector<int>& s) {
+        sort(s.begin(), s.end());
+        sort(g.begin(), g.end());
+        int i, j;
+        for (i = j = 0; i < g.size() && j < s.size(); j++) {
+            if (g[i] <= s[j]) {
+                i++;
+            }
+        }
+        return i;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/course-schedule-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/course-schedule-ii.md"
new file mode 100644
index 0000000..8dba2fd
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/course-schedule-ii.md"
@@ -0,0 +1,57 @@
+# 安排课程
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/course-schedule-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 你需要去上n门九章的课才能获得offer，这些课被标号为 `0` 到 `n-1` 。
+有一些课程需要“前置课程”，比如如果你要上课程0，你需要先学课程1，我们用一个匹配来表示他们： `[0,1]`
+
+给你课程的总数量和一些前置课程的需求，返回你为了学完所有课程所安排的学习顺序。
+
+可能会有多个正确的顺序，你只要返回一种就可以了。如果不可能完成所有课程，返回一个空数组。
+ ### 样例说明
+ **例1:**
+```
+输入: n = 2, prerequisites = [[1,0]] 
+输出: [0,1]
+```
+**例2:**
+```
+输入: n = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]] 
+输出: [0,1,2,3] or [0,2,1,3]
+```
+
+ ### 参考代码
+ 拓扑排序，输出任意一种拓扑序列。
+```python
+class Solution:
+    # @param {int} numCourses a total of n courses
+    # @param {int[][]} prerequisites a list of prerequisite pairs
+    # @return {int[]} the course order
+    def findOrder(self, numCourses, prerequisites):
+        # Write your code here
+        edges = {i: [] for i in xrange(numCourses)}
+        degrees = [0 for i in xrange(numCourses)] 
+        for i, j in prerequisites:
+            edges[j].append(i)
+            degrees[i] += 1
+        import Queue
+        queue = Queue.Queue(maxsize = numCourses)
+        
+        for i in xrange(numCourses):
+            if degrees[i] == 0:
+                queue.put(i)
+
+        order = []
+        while not queue.empty():
+            node = queue.get()
+            order.append(node)
+
+            for x in edges[node]:
+                degrees[x] -= 1
+                if degrees[x] == 0:
+                    queue.put(x)
+
+        if len(order) == numCourses:
+            return order
+        return []
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/course-schedule-iii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/course-schedule-iii.md"
new file mode 100644
index 0000000..eef559a
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/course-schedule-iii.md"
@@ -0,0 +1,34 @@
+# 课程表 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/course-schedule-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 这里有 `n` 门不同的线上课程, 编号为 `1` 到 `n`. 每一节课都有持续时间(课程长度) `t` 和 在第 `d` 天关闭. 课程应连续持续 `t` 天，必须在第`d `天或之前完成, 你将从第一天开始.
+给出 `n` 门线上课程用 `pairs (t, d)` 来表示, 你的任务是找到可以上的最大数量的课程数.
+ ### 样例说明
+ 
+ ### 参考代码
+ 贪心法 Greedy
+课程按照 deadline 排序，从左到右扫描每个课程，依次学习。如果发现学了之后超过 deadline 的，就从之前学过的课程里扔掉一个耗时最长的。
+因为这样可以使得其他的课程往前挪，而往前挪是没影响的。
+所以挑最大值这个事情就是 Heap 的事情了
+```python
+import heapq
+
+
+class Solution:
+    """
+    @param courses: duration and close day of each course
+    @return: the maximal number of courses that can be taken
+    """
+    def scheduleCourse(self, courses):
+        courses = sorted(courses, key=lambda x: x[1])
+        curt_time = 0
+        heap = []
+        for duration, deadline in courses:
+            curt_time += duration
+            heapq.heappush(heap, -duration)
+            if curt_time > deadline:
+                curt_time -= (-heapq.heappop(heap))
+                
+        return len(heap)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/course-schedule.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/course-schedule.md"
new file mode 100644
index 0000000..fb867cd
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/course-schedule.md"
@@ -0,0 +1,66 @@
+# 课程表
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/course-schedule/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 现在你总共有 n 门课需要选，记为 `0` 到 `n - 1`.
+一些课程在修之前需要先修另外的一些课程，比如要学习课程 0 你需要先学习课程 1 ，表示为[0,1]
+给定n门课以及他们的先决条件，判断是否可能完成所有课程？
+ ### 样例说明
+ 例1:
+```
+输入: n = 2, prerequisites = [[1,0]] 
+输出: true
+```
+例2:
+```
+输入: n = 2, prerequisites = [[1,0],[0,1]] 
+输出: false
+```
+
+ ### 参考代码
+ 裸拓扑排序
+```java
+public class Solution {
+    /**
+     * @param numCourses a total of n courses
+     * @param prerequisites a list of prerequisite pairs
+     * @return true if can finish all courses or false
+     */
+    public boolean canFinish(int numCourses, int[][] prerequisites) {
+        // Write your code here
+        List[] edges = new ArrayList[numCourses];
+        int[] degree = new int[numCourses];
+        
+        for (int i = 0;i < numCourses; i++)
+            edges[i] = new ArrayList<Integer>();
+            
+        for (int i = 0; i < prerequisites.length; i++) {
+            degree[prerequisites[i][0]] ++ ;
+            edges[prerequisites[i][1]].add(prerequisites[i][0]);
+        }
+
+        Queue queue = new LinkedList();
+        for(int i = 0; i < degree.length; i++){
+            if (degree[i] == 0) {
+                queue.add(i);
+            }
+        }
+        
+        int count = 0;
+        while(!queue.isEmpty()){
+            int course = (int)queue.poll();
+            count ++;
+            int n = edges[course].size();
+            for(int i = 0; i < n; i++){
+                int pointer = (int)edges[course].get(i);
+                degree[pointer]--;
+                if (degree[pointer] == 0) {
+                    queue.add(pointer);
+                }
+            }
+        }
+        
+        return count == numCourses;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/delete-digits.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/delete-digits.md"
new file mode 100644
index 0000000..fd601c9
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/delete-digits.md"
@@ -0,0 +1,49 @@
+# 删除数字
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/delete-digits/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个字符串 *A*, 表示一个 *n* 位正整数, 删除其中 *k* 位数字, 使得剩余的数字仍然按照原来的顺序排列产生一个新的正整数。
+
+找到删除 *k* 个数字之后的最小正整数。
+
+*N* <= 240, *k* <= *N*
+
+ ### 样例说明
+ **样例 1：**
+```
+输入: A = "178542", k = 4
+输出:"12"
+```
+
+**样例 2：**
+```
+输入: A = "568431", k = 3
+输出:"431"
+```
+ ### 参考代码
+ ```python
+class Solution:
+    """
+    @param A: A positive integer which has N digits, A is a string.
+    @param k: Remove k digits.
+    @return: A string
+    """
+    def DeleteDigits(self, A, k):
+        # write you code here
+        A = list(A)
+        while k > 0:
+            f = True
+            for i in xrange(len(A)-1):
+                if A[i] > A[i+1]:
+                    del A[i]
+                    f = False
+                    break	 
+            if f and len(A)>1:
+                A.pop()
+            k -= 1
+        while len(A)>1 and A[0]=='0':
+            del A[0]
+        return ''.join(A)   
+ 
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/gas-station.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/gas-station.md"
new file mode 100644
index 0000000..b31800f
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/gas-station.md"
@@ -0,0 +1,49 @@
+# 加油站
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/gas-station/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在一条环路上有 _N_ 个加油站，其中第 _i_ 个加油站有汽油`gas[i]`，并且从第_i_个加油站前往第_i_+1个加油站需要消耗汽油`cost[i]`。
+
+你有一辆油箱容量无限大的汽车，现在要从某一个加油站出发绕环路一周，一开始油箱为空。
+
+求可环绕环路一周时出发的加油站的编号，若不存在环绕一周的方案，则返回`-1`。
+ ### 样例说明
+ **样例 1:**
+```
+输入:gas[i]=[1,1,3,1],cost[i]=[2,2,1,1]
+输出:2
+```
+
+**样例 2:**
+```
+输入:gas[i]=[1,1,3,1],cost[i]=[2,2,10,1]
+输出:-1
+```
+
+ ### 参考代码
+ There are N gas stations along a circular route, where the amount of gas at station i is gas[i].&nbsp;<div>You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.&nbsp;</div><div>Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.&nbsp;</div><div>Note:&nbsp;</div><div>The solution is guaranteed to be unique.<div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博:</span><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">&nbsp;&nbsp;</span><a href="http://weibo.com/3948019741/BC431fkFU" target="_blank">http://weibo.com/3948019741/BC431fkFU</a><br></div></div>
+```java
+public class Solution {
+    public int canCompleteCircuit(int[] gas, int[] cost) {
+        if (gas == null || cost == null || gas.length == 0 || cost.length == 0) {
+            return -1;
+        }
+
+        int sum = 0;
+        int total = 0;
+        int index = -1;
+
+        for(int i = 0; i<gas.length; i++) {
+            sum += gas[i] - cost[i];
+            total += gas[i] - cost[i];
+            if(sum < 0) {
+                index = i;
+                sum = 0;
+            }
+        }
+        return total < 0 ? -1 : index + 1;
+        // index should be updated here for cases ([5], [4]);
+        // total < 0 is for case [2], [2]
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/increasing-triplet-subsequence.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/increasing-triplet-subsequence.md"
new file mode 100644
index 0000000..b3718c3
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/increasing-triplet-subsequence.md"
@@ -0,0 +1,52 @@
+# 递增的三元子序列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/increasing-triplet-subsequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定未排序的数组，返回是否在数组中存在递增的长度为3的子序列。
+
+完整的功能应为：
+如果存在i, j, k，使得arr[i] < arr[j] < arr[k]，且0 ≤ i < j < k ≤ n-1，则返回true，否则返回false。
+您的算法应该以O(n)时间复杂度和O(1)空间复杂度运行。
+ ### 样例说明
+ **样例1**
+```
+输入： [1, 2, 3, 4, 5]
+输出： true
+```
+**样例2**
+```
+输入： [5, 4, 3, 2, 1]
+输出： false
+```
+ ### 参考代码
+ 直接遍历一遍数组，用一个维护一个最小值以及次小值，如果当前值小于最小值则更新最小值，若大于最小值小于次小值则更新次小值，若大于次小值则返回true。
+```java
+// O(n) memory, if you want O(1)memory take a look at the c++ version
+public class Solution {
+    public boolean increasingTriplet(int[] nums) {
+        if (nums.length < 2)
+            return false;
+        int n = nums.length;
+        boolean []has_first_small = new boolean[n];
+        int smallest = nums[0];
+        has_first_small[0] = false;
+        for (int i = 0; i < n; i ++) {
+            if (smallest < nums[i]) {
+                has_first_small[i] = true;
+            }
+            smallest = Math.min(smallest, nums[i]);
+        }
+        
+        int biggest = nums[n-1];
+        for (int i = n-2; i >=0; i--) {
+            if(has_first_small[i] == true) {
+                if (nums[i] < biggest) {
+                    return true;
+                }
+                biggest = Math.max(biggest, nums[i]);
+            }
+        }
+        return false;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/jump-game-ii.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/jump-game-ii.md"
new file mode 100644
index 0000000..585da68
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/jump-game-ii.md"
@@ -0,0 +1,74 @@
+# 跳跃游戏 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/jump-game-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个非负整数数组，你最初定位在数组的第一个位置。<br></p><p><span style="line-height: 1.42857143;">数组中的每个元素代表你在那个位置可以跳跃的最大长度。</span>　　　</p><p>你的目标是使用最少的跳跃次数到达数组的最后一个位置。</p>
+ ### 样例说明
+ ***样例 1***
+```
+输入 : [2,3,1,1,4]
+输出 : 2
+解释 : 到达最后位置的最小跳跃次数是2(从下标0到1跳跃1个距离长度，然后跳跃3个距离长度到最后位置)
+```
+ ### 参考代码
+ Given an array of non-negative integers, you are initially positioned at the first index of the array.
+
+Each element in the array represents your maximum jump length at that position.
+
+Your goal is to reach the last index in the minimum number of jumps.
+
+For example:
+Given array A = [2,3,1,1,4]
+
+The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)<div><br></div><div>更优化详细题解请至九章微博：<a href="http://weibo.com/3948019741/BFp8AtIKi" target="_blank">http://weibo.com/3948019741/BFp8AtIKi</a></div>
+```java
+// version 1: Dynamic Programming
+// 这个方法，复杂度是 O(n^2)，会超时，但是依然需要掌握。
+public class Solution {
+    public int jump(int[] A) {
+        // state
+        int[] steps = new int[A.length];
+
+        // initialize
+        steps[0] = 0;
+        for (int i = 1; i < A.length; i++) {
+            steps[i] = Integer.MAX_VALUE;
+        }
+
+        // function
+        for (int i = 1; i < A.length; i++) {
+            for (int j = 0; j < i; j++) {
+                if (steps[j] != Integer.MAX_VALUE && j + A[j] >= i) {
+                    steps[i] = Math.min(steps[i], steps[j] + 1);
+                }
+            }
+        }
+        
+        // answer
+        return steps[A.length - 1];
+    }
+}
+
+
+// version 2: Greedy
+public class Solution {
+    public int jump(int[] A) {
+        if (A == null || A.length == 0) {
+            return -1;
+        }
+        int start = 0, end = 0, jumps = 0;
+        while (end < A.length - 1) {
+            jumps++;
+            int farthest = end;
+            for (int i = start; i <= end; i++) {
+                if (A[i] + i > farthest) {
+                    farthest = A[i] + i;
+                }
+            }
+            start = end + 1;
+            end = farthest;
+        }
+        return jumps;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/maximum-gap.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/maximum-gap.md"
new file mode 100644
index 0000000..abd7523
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/maximum-gap.md"
@@ -0,0 +1,90 @@
+# 最大间距
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/maximum-gap/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个未经排序的数组, 请找出这个数组排序之后的两个相邻元素之间最大的间距.
+
+如果数组中少于 2 个元素, 返回 0.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [1, 9, 2, 5]
+输出: 4
+解释: 排序之后的数组是 [1, 2, 5, 9], 最大的间距是在 5 和 9 之间.
+```
+
+**样例 2:**
+
+```
+输入: [1]
+输出: 0
+解释: 数组中的元素少于 2 个.
+ ### 参考代码
+ 很多人用基数排序(桶排序)做这道题目, 时间复杂度接近线性, 当然比基于比较的快速排序等一众 O(nlogn) 的算法要优秀一些, 但是这道题可以有更巧妙的方法.
+
+首先我们定义 maxNum 和 minNum 表示这个数组的最大/最小元素, N 表示这个数组元素的个数. 那么这个数组一共有 N - 1 个间距.
+
+这 N - 1 个间距的平均值就是 avgGap = (maxNum - minNum) / (N - 1), 这个平均值也是答案的最小值. 因为这 N 个元素平均分配时, 最大的间距最小.
+
+然后我们**对这 N 个元素分类, 分类依据就是这个元素与 minNum 的间距是 avgGap 的多少倍**. 为什么这样分类呢? 因为这样分类, **同一组内的元素的间距必然不会是最大间距**. 
+
+这时我们要找的**最大间距处于组与组之间, 即某一组里最小的元素与它上一组的最大的元素的间距的最大值**. 因此, 我们只需要**维护每一组里最小与最大的元素**即可.
+
+设定 maxNums 和 minNums 数组, maxNums[i] 表示原数组中与 minNum 的差为 avgGap 的 i 倍(向下取整)的最大的元素, 同理 minNums[i] 表示相同含义下的最小的元素.
+
+然后我们遍历 maxNums, minNums, 将第 i 组的最小值 minNums[i] 与第 i - 1 组的最大值 maxNums[i - 1] 做差, 维护最大值就可以得到答案了.
+```cpp
+class Block {
+public:
+    int maxNum;
+    int minNum;
+    Block(): maxNum(INT_MIN), minNum(INT_MAX) {}
+};
+
+class Solution {
+public:
+    /**
+     * @param nums: an array of integers
+     * @return: the maximun difference
+     */
+    int maximumGap(vector<int> &nums) {
+        int N = nums.size();
+        int maxNum = nums[0];
+        int minNum = nums[0];
+        for (int num : nums) {
+            maxNum = max(num, maxNum);
+            minNum = min(num, minNum);
+        }
+        if (N < 2 || maxNum == minNum) {
+            return 0;
+        }
+        
+        vector<Block> blocks(N);
+        
+        int avgGap = ceil(double(maxNum - minNum) / (N - 1));
+        
+        for (int num : nums) {
+            if (num == maxNum || num == minNum) {
+                continue;
+            }
+            int pos = (num - minNum) / avgGap;
+            blocks[pos].minNum = min(num, blocks[pos].minNum);
+            blocks[pos].maxNum = max(num, blocks[pos].maxNum);
+        }
+        
+        int maxGap = 0;
+        int lastMax = minNum;
+        for (int i = 0; i < N; i++) {
+            if (blocks[i].minNum == INT_MAX || blocks[i].maxNum == INT_MIN) {
+                continue;
+            }
+            maxGap = max(blocks[i].minNum - lastMax, maxGap);
+            lastMax = blocks[i].maxNum;
+        }
+        maxGap = max(maxNum - lastMax, maxGap);
+        
+        return maxGap;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/minimum-number-of-arrows-to-burst-balloons.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/minimum-number-of-arrows-to-burst-balloons.md"
new file mode 100644
index 0000000..10f50fd
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/minimum-number-of-arrows-to-burst-balloons.md"
@@ -0,0 +1,52 @@
+# 爆破气球的最小箭头数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-number-of-arrows-to-burst-balloons/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在二维空间中有许多球形气球。 对于每个气球，提供的输入是水平直径的起点和终点坐标。 由于它是水平的，因此y坐标无关紧要，因此直径的起点和终点的x坐标就足够了。 起点总是小于终点。 最多将有10^4个气球。
+
+可以沿x轴从不同点垂直向上发射箭头。 如果xstart≤x≤xend，则坐标为xstart和xend的气球被在x处发射的箭头戳爆。 可以发射的箭头数量没有限制。 一次射击的箭头一直无限地向上移动。 问题是要找到戳破所有气球的最小发射箭头数。
+ ### 样例说明
+ **样例1**
+```
+输入:
+[[10,16], [2,8], [1,6], [7,12]]
+输出:
+2
+说明：
+一种方法是发射一个箭头，例如在x = 6（爆破气球[2,8]和[1,6]），发射另一个箭头在x = 11（爆破其他两个气球）。
+```
+**样例2**
+```
+输入:
+[[1,2],[3,4],[5,6],[7,8]]
+输出:
+4
+```
+ ### 参考代码
+ 使用贪心算法解决此问题。
+我们首先将气球按照end从小到大进行排序，首先将第一个气球的end作为参考。
+从左到右遍历，若当前气球的起点小于等于参考点则continue；
+若当前气球的起点大于参考点，则将参考点更新为当前气球的终点，同时答案+1。
+```java
+public class Solution {
+    public int findMinArrowShots(int[][] points) {
+        if (points == null || points.length == 0) return 0;
+        Arrays.sort(points, new IntervalComparator());
+        int ans = 1;
+        int lastEnd = points[0][1];
+        for(int i = 1; i < points.length; i++) {
+            if (points[i][0] > lastEnd) {
+                ans++;
+                lastEnd = points[i][1];
+            }
+        }
+        return ans;
+    }
+    
+    class IntervalComparator implements Comparator<int[]> {
+        public int compare(int[] a, int[] b) {
+            return a[1] - b[1];
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/queue-reconstruction-by-height.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/queue-reconstruction-by-height.md"
new file mode 100644
index 0000000..9a713d2
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/queue-reconstruction-by-height.md"
@@ -0,0 +1,45 @@
+# 根据身高重排队列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/queue-reconstruction-by-height/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假设你有一个顺序被随机打乱的列表，代表了站成一列的人群。每个人被表示成一个二元组`(h, k)`，其中`h`表示他的身高，`k`表示站在他之前的身高高于或等于`h`的人数。你需要将这个队列重新排列以恢复其原有的顺序。
+ ### 样例说明
+ **样例1**
+```
+输入：
+[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
+输出：
+[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
+```
+**样例2**
+```
+输入：
+[[2,0],[1,1]]
+输出：
+[[2,0],[1,1]]
+```
+
+ ### 参考代码
+ 贪心。
+将身高从高到低排序后依次插入即可。对于某个人[h,k]来说，插入答案的第k位。
+```java
+public class Solution {
+    public int[][] reconstructQueue(int[][] people) {
+        Arrays.sort(people, (new Comparator<int[]>() {
+            @Override
+            public int compare(int[] o1, int[] o2) {
+                if (o1[0] == o2[0]) {
+                    return o1[1] - o2[1];
+                } else {
+                    return o2[0] - o1[0];
+                }
+            }
+        }));
+        List<int[]> resultList = new LinkedList<>();
+        for(int[] cur : people){
+            resultList.add(cur[1], cur);
+        }
+        return resultList.toArray(new int[people.length][]);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/russian-doll-envelopes.md" "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/russian-doll-envelopes.md"
new file mode 100644
index 0000000..98bfc33
--- /dev/null
+++ "b/\347\256\227\346\263\225\346\200\235\347\273\264\351\242\230/\350\264\252\345\277\203\347\256\227\346\263\225/russian-doll-envelopes.md"
@@ -0,0 +1,63 @@
+# 俄罗斯套娃信封
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/russian-doll-envelopes/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一定数量的信封，带有整数对 `(w, h)` 分别代表信封宽度和高度。一个信封的宽高均大于另一个信封时可以放下另一个信封。
+求最大的信封嵌套层数。
+ ### 样例说明
+ **样例 1:**
+```
+输入：[[5,4],[6,4],[6,7],[2,3]]
+输出：3
+解释：
+最大的信封嵌套层数是 3 ([2,3] => [5,4] => [6,7])。
+```
+
+**样例 2:**
+```
+输入：[[4,5],[4,6],[6,7],[2,3],[1,1]]
+输出：4
+解释：
+最大的信封嵌套层数是 4 ([1,1] => [2,3] => [4,5] / [4,6] => [6,7])。
+```
+ ### 参考代码
+ 考点：
+* 贪心
+* dp
+
+题解：
+* 信封存在两个维度，首先贪心按照其中一个维度将信封排序，一个维然后在另度上面寻找最长上升子序列。
+* 此处使用二分优化最长上升子序列，在dp数组中二分查找envelope[1]的位置，当envelope[1]超出范围时会返回-（maxlength+1）需要特殊处理，dp[index] = envelope[1]，当返回的位置为最后为len时，说明插入位置为len，则长度可以+1。
+```java
+public class Solution {
+    /**
+     * @param envelopes a number of envelopes with widths and heights
+     * @return the maximum number of envelopes
+     */
+    public int maxEnvelopes(int[][] envelopes) {
+        // Write your code here
+        if(envelopes == null || envelopes.length == 0 
+            || envelopes[0] == null || envelopes[0].length != 2)
+            return 0;
+        Arrays.sort(envelopes, new Comparator<int[]>(){
+            public int compare(int[] arr1, int[] arr2){
+                if(arr1[0] == arr2[0])
+                    return arr2[1] - arr1[1];
+                else
+                    return arr1[0] - arr2[0];
+            } 
+        });
+        int dp[] = new int[envelopes.length];
+        int len = 0;
+        for(int[] envelope : envelopes){
+            int index = Arrays.binarySearch(dp, 0, len, envelope[1]);
+                if(index < 0)
+                    index = -index - 1;
+            dp[index] = envelope[1];
+            if (index == len)
+                len++;
+        }
+        return len;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\347\274\226\347\250\213\346\226\260\346\211\213\345\277\205\345\210\26750\351\242\230 V1.0.docx" "b/\347\274\226\347\250\213\346\226\260\346\211\213\345\277\205\345\210\26750\351\242\230 V1.0.docx"
new file mode 100644
index 0000000..ad0e9c4
Binary files /dev/null and "b/\347\274\226\347\250\213\346\226\260\346\211\213\345\277\205\345\210\26750\351\242\230 V1.0.docx" differ
diff --git "a/\351\235\242\350\257\225\345\270\270\350\200\203\347\256\227\346\263\225\345\277\205\345\210\267\351\242\230\345\272\223.pdf" "b/\351\235\242\350\257\225\345\270\270\350\200\203\347\256\227\346\263\225\345\277\205\345\210\267\351\242\230\345\272\223.pdf"
new file mode 100644
index 0000000..658e555
Binary files /dev/null and "b/\351\235\242\350\257\225\345\270\270\350\200\203\347\256\227\346\263\225\345\277\205\345\210\267\351\242\230\345\272\223.pdf" differ
diff --git "a/\351\242\230\350\247\243/2-sum.md" "b/\351\242\230\350\247\243/2-sum.md"
deleted file mode 100644
index 8105faa..0000000
--- "a/\351\242\230\350\247\243/2-sum.md"
+++ /dev/null
@@ -1,25 +0,0 @@
-# 2 Sum
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/2-sum/?utm_source=sc-github-wzz)
- ## 题目描述
- 1754
- ### 样例说明
- 1754
- ### 参考代码
- ```java
-  public class Solution {
-    public int[] twoSum(int[] nums, int target) {
-      Map<Integer, Integer> hash = new HashMap<Integer, Integer> ();
-      int[] result = new int[2];
-      for (int i = 0; i < nums.length; ++i) {
-        if (hash.containsKey(target - nums[i])) {
-          result[0] = hash.get(target - nums[i]) + 1;
-          result[1] = i + 1;
-          break;
-        }
-        hash.put(nums[i], i);
-      }
-      return result;
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/bfs-template.md" "b/\351\242\230\350\247\243/bfs-template.md"
deleted file mode 100644
index ba5152d..0000000
--- "a/\351\242\230\350\247\243/bfs-template.md"
+++ /dev/null
@@ -1,40 +0,0 @@
-# BFS Template
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/bfs-template/?utm_source=sc-github-wzz)
- ## 题目描述
- 1748
- ### 样例说明
- 1748
- ### 参考代码
- Binary Tree BFS Template
-```java
-public class Solution {
-    public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
-        ArrayList result = new ArrayList();
-        
-        if (root == null)
-            return result;
-            
-        Queue<TreeNode> queue = new LinkedList<TreeNode>();
-        queue.offer(root);
-        
-        while (!queue.isEmpty()) {
-            ArrayList<Integer> level = new ArrayList<Integer>();
-            int size = queue.size();
-            for (int i = 0; i < size; i++) {
-                TreeNode head = queue.poll();
-                level.add(head.val);
-                if (head.left != null)
-                    queue.offer(head.left);
-                if (head.right != null)
-                    queue.offer(head.right);
-            }
-            result.add(level);
-        }
-        
-        return result;
-    }
-}
-
-
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/big-integer-addition.md" "b/\351\242\230\350\247\243/big-integer-addition.md"
deleted file mode 100644
index 93fc9d1..0000000
--- "a/\351\242\230\350\247\243/big-integer-addition.md"
+++ /dev/null
@@ -1,62 +0,0 @@
-# big integer addition
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/big-integer-addition/?utm_source=sc-github-wzz)
- ## 题目描述
- 1784
- ### 样例说明
- 1784
- ### 参考代码
- ```java
-public class Solution {
-    /**
-     * @param num1 a non-negative integers
-     * @param num2 a non-negative integers
-     * @return return sum of num1 and num2
-     */
-    public String addStrings(String num1, String num2) {
-        // Write your code here
-        int i = num1.length() - 1;
-        int j = num2.length() - 1;
-        int carry = 0;
-        String result = "";
-        while (i >= 0 || j >= 0) {
-            if (i >= 0) {
-                carry += num1.charAt(i--) - '0';
-            }
-            if (j >= 0) {
-                carry += num2.charAt(j--) - '0';
-            }
-            result = carry % 10 + result;
-            carry /= 10;
-        }
-        return carry > 0 ? "1" + result : result;
-    }
-}
-
-
-// version: 高频题班
-public class Solution {
-    /**
-     * @param num1 a non-negative integers
-     * @param num2 a non-negative integers
-     * @return return sum of num1 and num2
-     */
-    public String addStrings(String num1, String num2) {
-        // Write your code here
-        String ans = "";
-
-        int carry = 0;
-        for (int i = num1.length() - 1, j = num2.length() - 1; i >= 0 || j >= 0; i--, j--) {
-            int sum = carry;
-            sum += (i >= 0) ? num1.charAt(i) - '0' : 0;
-            sum += (j >= 0) ? num2.charAt(j) - '0' : 0;
-            ans = (sum % 10) + ans;
-            carry = sum / 10;
-        }
-        if (carry != 0) {
-            ans = carry + ans;
-        }
-        return ans;
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/big-integer-multiplication.md" "b/\351\242\230\350\247\243/big-integer-multiplication.md"
deleted file mode 100644
index e70f373..0000000
--- "a/\351\242\230\350\247\243/big-integer-multiplication.md"
+++ /dev/null
@@ -1,92 +0,0 @@
-# big integer multiplication
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/big-integer-multiplication/?utm_source=sc-github-wzz)
- ## 题目描述
- 1783
- ### 样例说明
- 1783
- ### 参考代码
- ```java
-public class Solution {
-    /**
-     * @param num1 a non-negative integers
-     * @param num2 a non-negative integers
-     * @return return product of num1 and num2
-     */
-    public String multiply(String num1, String num2) {
-        // Write your code here
-        if (num1 == null || num2 == null) {
-            return null;
-        }
-        
-        int len1 = num1.length(), len2 = num2.length();
-        int len3 = len1 + len2;
-        int i, j, product, carry;
-
-        int[] num3 = new int[len3];
-        for (i = len1 - 1; i >= 0; i--) {
-            carry = 0;
-            for (j = len2 - 1; j >= 0; j--) {
-                product = carry + num3[i + j + 1] +
-                    Character.getNumericValue(num1.charAt(i)) *
-                    Character.getNumericValue(num2.charAt(j));
-                num3[i + j + 1] = product % 10;
-                carry = product / 10;
-            }
-            num3[i + j + 1] = carry;
-        }
-
-        StringBuilder sb = new StringBuilder();
-        i = 0;
-
-        while (i < len3 - 1 && num3[i] == 0) {
-            i++;
-        }
-
-        while (i < len3) {
-            sb.append(num3[i++]);
-        }
-
-        return sb.toString();
-    }
-}
-
-
-
-// version: 高频题班
-public class Solution {
-    /**
-     * @param num1 a non-negative integers
-     * @param num2 a non-negative integers
-     * @return return product of num1 and num2
-     */
-    public String multiply(String num1, String num2) {
-        // Write your code here
-        int l1 = num1.length();
-        int l2 = num2.length();
-
-        int[] ans = new int[l1 + l2 + 1];
-        for (int i = 0; i < l1; i++) {
-            for (int j = 0; j < l2; j++) {
-                ans[i + j] += (num1.charAt(l1 - 1 - i) - '0') * (num2.charAt(l2 - 1 - j) - '0');
-            }
-        }
-
-        for (int i = 0; i < l1 + l2; i++) {
-            ans[i + 1] += ans[i] / 10;
-            ans[i] %= 10;
-        }
-
-        int i = l1 + l2;
-        while (ans[i] == 0 && i >= 1) {
-            i--;
-        }
-        String str = "";
-        while (i >= 0) {
-            str += ans[i--];
-        }
-        return str;
-    }
-}
-
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/check-word-abbreviation.md" "b/\351\242\230\350\247\243/check-word-abbreviation.md"
deleted file mode 100644
index e609968..0000000
--- "a/\351\242\230\350\247\243/check-word-abbreviation.md"
+++ /dev/null
@@ -1,75 +0,0 @@
-# Check Word Abbreviation
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/check-word-abbreviation/?utm_source=sc-github-wzz)
- ## 题目描述
- 1780
- ### 样例说明
- 1780
- ### 参考代码
- ```java
-public class Solution {
-    /**
-     * @param word a non-empty string
-     * @param abbr an abbreviation
-     * @return true if string matches with the given abbr or false
-     */
-    public boolean validWordAbbreviation(String word, String abbr) {
-        // Write your code here
-        int number = 0;
-        int i = 0, j = 0;
-        while (i < word.length() && j < abbr.length()) {
-            if (Character.isDigit(abbr.charAt(j))) {
-                number = number * 10 + abbr.charAt(j) - '0';
-                if (number == 0)
-                    return false;
-                j ++;
-            } else {
-                i += number;
-                if (i >= word.length() ||
-                    word.charAt(i) != abbr.charAt(j))
-                    return false;
-                number = 0;
-                i ++;
-                j ++;
-            }
-        }
-        i += number;
-        return i == word.length() && j == abbr.length();
-    }
-}
-
-// version: 高频题班
-
-public class Solution {
-    /**
-     * @param word a non-empty string
-     * @param abbr an abbreviation
-     * @return true if string matches with the given abbr or false
-     */
-    public boolean validWordAbbreviation(String word, String abbr) {
-        // Write your code here
-        int i = 0, j = 0;
-        char[] s = word.toCharArray();
-        char[] t = abbr.toCharArray();
-
-        while (i < s.length && j < t.length) {
-            if (Character.isDigit(t[j])) {
-                if (t[j] == '0') {
-                    return false;
-                }
-                int val = 0;
-                while (j < t.length && Character.isDigit(t[j])) {
-                    val = val * 10 + t[j] - '0';
-                    j++;
-                }
-                i += val;
-            } else {
-                if (s[i++] != t[j++]) {
-                    return false;
-                }
-            }
-        }
-        return i == s.length && j == t.length;
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/design-snake-game.md" "b/\351\242\230\350\247\243/design-snake-game.md"
deleted file mode 100644
index c6a17ea..0000000
--- "a/\351\242\230\350\247\243/design-snake-game.md"
+++ /dev/null
@@ -1,81 +0,0 @@
-# Design Snake Game
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/design-snake-game/?utm_source=sc-github-wzz)
- ## 题目描述
- 1777
- ### 样例说明
- 1777
- ### 参考代码
- ```java
-public class SnakeGame {
-    /** Initialize your data structure here.
-        @param width - screen width
-        @param height - screen height 
-        @param food - A list of food positions
-        E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. */
-    private class Position {
-        public int x, y;
-        public Position(int x, int y) {
-            this.x = x;
-            this.y = y;
-        }
-    }
-    private boolean gameOver;
-    private int[][] food;
-    private int foodGet;
-    private int width, height;
-    private HashSet<Integer> usedMap;
-    private Deque<Position> queue;
-    public SnakeGame(int width, int height, int[][] food) {
-        this.width = width;
-        this.height = height;
-        gameOver = false;
-        foodGet = 0;
-        usedMap = new HashSet<Integer>();
-        this.food = food;
-        queue = new LinkedList<Position>();
-        usedMap.add(0);
-        queue.offer(new Position(0, 0));
-        if (food.length > 0 && food[foodGet][0] == 0 && food[foodGet][1] == 0) {
-            foodGet++;
-        }
-    }
-    
-    /** Moves the snake.
-        @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down 
-        @return The game's score after the move. Return -1 if game over. 
-        Game over when snake crosses the screen boundary or bites its body. */
-    public int move(String direction) {
-        if (gameOver) {
-            return -1;
-        }
-        int incx = 0, incy = 0;
-        switch (direction) {
-            case "U": incx = -1; incy = 0; break;
-            case "L": incx = 0; incy = -1; break;
-            case "R": incx = 0; incy = 1; break;
-            case "D": incx = 1; incy = 0; break;
-            default: break;
-        }
-        int x = queue.peekLast().x + incx, y = queue.peekLast().y + incy;
-        if (x >= 0 && x < height && y >= 0 && y < width) {
-            queue.offerLast(new Position(x, y));
-            if (foodGet < food.length && x == food[foodGet][0] && y == food[foodGet][1]) {
-                foodGet++;
-            } else {
-                usedMap.remove(queue.peekFirst().x * width + queue.peekFirst().y);
-                queue.pollFirst();
-            }
-            if (usedMap.contains(x * width + y)) {
-                return -1;
-            } else {
-                usedMap.add(x * width + y);
-            }
-            return foodGet;
-        } else {
-            gameOver = true;
-            return -1;
-        }
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/dfs-template.md" "b/\351\242\230\350\247\243/dfs-template.md"
deleted file mode 100644
index 330905e..0000000
--- "a/\351\242\230\350\247\243/dfs-template.md"
+++ /dev/null
@@ -1,46 +0,0 @@
-# DFS Template
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/dfs-template/?utm_source=sc-github-wzz)
- ## 题目描述
- 1736
- ### 样例说明
- 1736
- ### 参考代码
- Binary Tree DFS template
-```java
-Template 1: Traverse
-
-public class Solution {
-    public void traverse(TreeNode root) {
-        if (root == null) {
-            return;
-        }
-        // do something with root
-        traverse(root.left);
-        // do something with root
-        traverse(root.right);
-        // do something with root
-    }
-}
-
-
-Tempate 2: Divide & Conquer
-
-public class Solution {
-    public ResultType traversal(TreeNode root) {
-        // null or leaf
-        if (root == null) {
-            // do something and return;
-        }
-        
-        // Divide
-        ResultType left = traversal(root.left);
-        ResultType right = traversal(root.right);
-        
-        // Conquer
-        ResultType result = Merge from left and right.
-        return result;
-    }
-}
-
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/evaluate-division.md" "b/\351\242\230\350\247\243/evaluate-division.md"
deleted file mode 100644
index 42b9bb9..0000000
--- "a/\351\242\230\350\247\243/evaluate-division.md"
+++ /dev/null
@@ -1,71 +0,0 @@
-# 598
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/evaluate-division/?utm_source=sc-github-wzz)
- ## 题目描述
- 598
- ### 样例说明
- 598
- ### 参考代码
- ```java
-public class Solution {
-    public void addArc(Map<String, Map<String, Double>> graph, String vexStart, String vexEnd, double value) {
-        Map<String, Double> arcMap;
-        if (graph.containsKey(vexStart)) {
-            arcMap = graph.get(vexStart);
-        } else {
-            arcMap = new HashMap<>();
-        }
-        arcMap.put(vexEnd, value);
-        graph.put(vexStart, arcMap);
-    }
-
-    public double getValue(Map<String, Map<String, Double>> graph, String vexStart, String vexEnd) {
-        if (graph.get(vexStart) == null || graph.get(vexEnd) == null) {
-            return -1;
-        }
-
-        Queue<String> queue = new LinkedList<>();   //queue uesd for bfs
-        Map<String, Double> value = new HashMap<>();    //distance from vexStart
-        Set<String> validation = new HashSet<>();   //check if the vertex has been in the queue
-
-        //init
-        queue.add(vexStart);
-        validation.add(vexStart);
-        value.put(vexStart, 1d);
-
-        String currentNode, nextNode;
-        while (!queue.isEmpty()) {
-            currentNode = queue.remove();
-            for (Map.Entry<String, Double> arc : graph.get(currentNode).entrySet()) {
-                nextNode = arc.getKey();
-                value.put(nextNode, value.get(currentNode) * arc.getValue());
-                if (nextNode.equals(vexEnd)) {
-                    return value.get(vexEnd);
-                } else if (!validation.contains(nextNode)) {
-                    queue.add(nextNode);
-                    validation.add(nextNode);
-                }
-            }
-        }
-        return -1;
-    }
-
-    public double[] calcEquation(String[][] equations, double[] values, String[][] queries) {
-
-        Map<String, Map<String, Double>> graph = new HashMap<>();
-
-        for (int i = 0; i < equations.length; i++) {
-            //add arcs for both directions
-            addArc(graph, equations[i][0], equations[i][1], values[i]);
-            addArc(graph, equations[i][1], equations[i][0], 1 / values[i]);
-        }
-
-        double[] answer = new double[queries.length];
-        for (int i = 0; i < answer.length; i++) {
-            answer[i] = getValue(graph, queries[i][0], queries[i][1]);
-        }
-
-        return answer;
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/hashheap.md" "b/\351\242\230\350\247\243/hashheap.md"
deleted file mode 100644
index 2fe5b9b..0000000
--- "a/\351\242\230\350\247\243/hashheap.md"
+++ /dev/null
@@ -1,177 +0,0 @@
-# hashheap
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/hashheap/?utm_source=sc-github-wzz)
- ## 题目描述
- 1757
- ### 样例说明
- 1757
- ### 参考代码
- <br>
-```java
-class HashHeap {
-    ArrayList<Integer> heap;
-    String mode;
-    int size_t;
-    HashMap<Integer, Node> hash;
-
-    class Node {
-        public Integer id;
-        public Integer num;
-
-        Node(Node now) {
-            id = now.id;
-            num = now.num;
-        }
-
-        Node(Integer first, Integer second) {
-
-            this.id = first;
-            this.num = second;
-        }
-    }
-
-    public HashHeap(String mod) { // 传入min 表示最小堆，max 表示最大堆
-        // TODO Auto-generated constructor stub
-        heap = new ArrayList<Integer>();
-        mode = mod;
-        hash = new HashMap<Integer, Node>();
-        size_t = 0;
-    }
-
-    int peak() {
-        return heap.get(0);
-    }
-
-    int size() {
-        return size_t;
-    }
-
-    Boolean empty() {
-        return (heap.size() == 0);
-    }
-
-    int parent(int id) {
-        if (id == 0) {
-            return -1;
-        }
-        return (id - 1) / 2;
-    }
-
-    int lson(int id) {
-        return id * 2 + 1;
-    }
-
-    int rson(int id) {
-        return id * 2 + 2;
-    }
-
-    boolean comparesmall(int a, int b) {
-        if (a <= b) {
-            if (mode == "min")
-                return true;
-            else
-                return false;
-        } else {
-            if (mode == "min")
-                return false;
-            else
-                return true;
-        }
-
-    }
-
-    void swap(int idA, int idB) {
-        int valA = heap.get(idA);
-        int valB = heap.get(idB);
-
-        int numA = hash.get(valA).num;
-        int numB = hash.get(valB).num;
-        hash.put(valB, new Node(idA, numB));
-        hash.put(valA, new Node(idB, numA));
-        heap.set(idA, valB);
-        heap.set(idB, valA);
-    }
-
-    Integer poll() {
-        size_t--;
-        Integer now = heap.get(0);
-        Node hashnow = hash.get(now);
-        if (hashnow.num == 1) {
-            swap(0, heap.size() - 1);
-            hash.remove(now);
-            heap.remove(heap.size() - 1);
-            if (heap.size() > 0) {
-                siftdown(0);
-            }
-        } else {
-            hash.put(now, new Node(0, hashnow.num - 1));
-        }
-        return now;
-    }
-
-    void add(int now) {
-        size_t++;
-        if (hash.containsKey(now)) {
-            Node hashnow = hash.get(now);
-            hash.put(now, new Node(hashnow.id, hashnow.num + 1));
-
-        } else {
-            heap.add(now);
-            hash.put(now, new Node(heap.size() - 1, 1));
-        }
-
-        siftup(heap.size() - 1);
-    }
-
-    void delete(int now) {
-        size_t--;
-        ;
-        Node hashnow = hash.get(now);
-        int id = hashnow.id;
-        int num = hashnow.num;
-        if (hashnow.num == 1) {
-
-            swap(id, heap.size() - 1);
-            hash.remove(now);
-            heap.remove(heap.size() - 1);
-            if (heap.size() > id) {
-                siftup(id);
-                siftdown(id);
-            }
-        } else {
-            hash.put(now, new Node(id, num - 1));
-        }
-    }
-
-    void siftup(int id) {
-        while (parent(id) > -1) {
-            int parentId = parent(id);
-            if (comparesmall(heap.get(parentId), heap.get(id)) == true) {
-                break;
-            } else {
-                swap(id, parentId);
-            }
-            id = parentId;
-        }
-    }
-
-    void siftdown(int id) {
-        while (lson(id) < heap.size()) {
-            int leftId = lson(id);
-            int rightId = rson(id);
-            int son;
-            if (rightId >= heap.size() || (comparesmall(heap.get(leftId), heap.get(rightId)) == true)) {
-                son = leftId;
-            } else {
-                son = rightId;
-            }
-            if (comparesmall(heap.get(id), heap.get(son)) == true) {
-                break;
-            } else {
-                swap(id, son);
-            }
-            id = son;
-        }
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/identify-celebrity.md" "b/\351\242\230\350\247\243/identify-celebrity.md"
deleted file mode 100644
index 8141bc0..0000000
--- "a/\351\242\230\350\247\243/identify-celebrity.md"
+++ /dev/null
@@ -1,39 +0,0 @@
-# identify celebrity
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/identify-celebrity/?utm_source=sc-github-wzz)
- ## 题目描述
- 1786
- ### 样例说明
- 1786
- ### 参考代码
- ```java
-/* The knows API is defined in the parent class Relation.
-      boolean knows(int a, int b); */
-
-public class Solution extends Relation {
-    /**
-     * @param n a party with n people
-     * @return the celebrity's label or -1
-     */
-    public int findCelebrity(int n) {
-        // Write your code here
-        int candidate = 0;
-        for(int i = 1; i < n; i++) {
-            if (knows(candidate, i)) {
-                candidate = i;
-            }
-        }
-        for(int i = 0; i < candidate; i++) {
-            if(knows(candidate, i) || !knows(i, candidate)) {
-                return -1;
-            }
-        }
-        for(int i = candidate + 1; i < n; i++) {
-            if(!knows(i, candidate)) {
-                return -1;
-            }
-        }
-        return candidate;
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/kth-smallest-element-in-bst.md" "b/\351\242\230\350\247\243/kth-smallest-element-in-bst.md"
deleted file mode 100644
index 1c993eb..0000000
--- "a/\351\242\230\350\247\243/kth-smallest-element-in-bst.md"
+++ /dev/null
@@ -1,45 +0,0 @@
-# Kth Smallest Element in BST
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/kth-smallest-element-in-bst/?utm_source=sc-github-wzz)
- ## 题目描述
- 1799
- ### 样例说明
- 1799
- ### 参考代码
- 简单的使用 inorder traversal 就可以在 O(k + h) 的时间内得到结果。h 是树的高度
-```java
-/**
- * Definition for a binary tree node.
- * public class TreeNode {
- *     int val;
- *     TreeNode left;
- *     TreeNode right;
- *     TreeNode(int x) { val = x; }
- * }
- */
-class Solution {
-    private int index, kth;
-    
-    public int kthSmallest(TreeNode root, int k) {
-        index = 0;
-        inorder(root, k);
-        return kth;
-    }
-    
-    private void inorder(TreeNode root, int k) {
-        if (root == null) {
-            return;
-        }
-        
-        inorder(root.left, k);
-        index++;
-        if (index == k) {
-            kth = root.val;
-        }
-        
-        if (index < k) {
-        	inorder(root.right, k);
-        }
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/merge-sort.md" "b/\351\242\230\350\247\243/merge-sort.md"
deleted file mode 100644
index 0ae0f47..0000000
--- "a/\351\242\230\350\247\243/merge-sort.md"
+++ /dev/null
@@ -1,61 +0,0 @@
-# Merge Sort
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/merge-sort/?utm_source=sc-github-wzz)
- ## 题目描述
- 1772
- ### 样例说明
- 1772
- ### 参考代码
- ```java
-public class Solution {
-    /**
-     * @param A an integer array
-     * @return void
-     */
-    public void sortIntegers2(int[] A) {
-        // use a shared temp array, the extra memory is O(n) at least
-        int[] temp = new int[A.length];
-        mergeSort(A, 0, A.length - 1, temp);
-    }
-    
-    private void mergeSort(int[] A, int start, int end, int[] temp) {
-        if (start >= end) {
-            return;
-        }
-        
-        int left = start, right = end;
-        int mid = (start + end) / 2;
-
-        mergeSort(A, start, mid, temp);
-        mergeSort(A, mid+1, end, temp);
-        merge(A, start, mid, end, temp);
-    }
-    
-    private void merge(int[] A, int start, int mid, int end, int[] temp) {
-        int left = start;
-        int right = mid+1;
-        int index = start;
-        
-        // merge two sorted subarrays in A to temp array
-        while (left <= mid && right <= end) {
-            if (A[left] < A[right]) {
-                temp[index++] = A[left++];
-            } else {
-                temp[index++] = A[right++];
-            }
-        }
-        while (left <= mid) {
-            temp[index++] = A[left++];
-        }
-        while (right <= end) {
-            temp[index++] = A[right++];
-        }
-        
-        // copy temp back to A
-        for (index = start; index <= end; index++) {
-            A[index] = temp[index];
-        }
-    }
-}
-
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/mini-parse.md" "b/\351\242\230\350\247\243/mini-parse.md"
deleted file mode 100644
index c959282..0000000
--- "a/\351\242\230\350\247\243/mini-parse.md"
+++ /dev/null
@@ -1,92 +0,0 @@
-# Mini Parse
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/mini-parse/?utm_source=sc-github-wzz)
- ## 题目描述
- 1807
- ### 样例说明
- 1807
- ### 参考代码
- ```java
-/**
- * // This is the interface that allows for creating nested lists.
- * // You should not implement it, or speculate about its implementation
- * public interface NestedInteger {
- *     // Constructor initializes an empty nested list.
- *     public NestedInteger();
- *
- *     // Constructor initializes a single integer.
- *     public NestedInteger(int value);
- *
- *     // @return true if this NestedInteger holds a single integer, rather than a nested list.
- *     public boolean isInteger();
- *
- *     // @return the single integer that this NestedInteger holds, if it holds a single integer
- *     // Return null if this NestedInteger holds a nested list
- *     public Integer getInteger();
- *
- *     // Set this NestedInteger to hold a single integer.
- *     public void setInteger(int value);
- *
- *     // Set this NestedInteger to hold a nested list and adds a nested integer to it.
- *     public void add(NestedInteger ni);
- *
- *     // @return the nested list that this NestedInteger holds, if it holds a nested list
- *     // Return null if this NestedInteger holds a single integer
- *     public List<NestedInteger> getList();
- * }
- */
-public class Solution {
-    public NestedInteger deserialize(String s) {
-        
-        // return a NestedInteger with a single integer
-        if (s.charAt(0) != '[') {
-            return new NestedInteger(Integer.parseInt(s));
-        }
-        
-        int len = s.length();
-        Stack<NestedInteger> stack = new Stack<>();
-        StringBuilder num = new StringBuilder();
-        
-        for (int i = 0; i < len; i++) {
-            switch (s.charAt(i)) {
-                case '[':
-                    stack.push(new NestedInteger());
-                    break;
-                    
-                case ',':
-                    // judge if it's a num before ','
-                    if (num.length() != 0) {
-                        stack.peek().add(new NestedInteger(Integer.parseInt(num.toString())));
-                        clearNum(num);
-                    }
-                    break;
-                    
-                case ']':
-                    // judge if it's a num before ']'
-                    if (num.length() != 0) {
-                        stack.peek().add(new NestedInteger(Integer.parseInt(num.toString())));
-                        clearNum(num);
-                    }
-                    NestedInteger ni = stack.pop();
-                    
-                    if (!stack.isEmpty()) {
-                        stack.peek().add(ni);
-                    } else {
-                        return ni;
-                    }
-                    break;
-                    
-                default:
-                    num.append(s.charAt(i));
-                    break;
-            }
-        }
-        
-        return null;
-    }
-    
-    public void clearNum(StringBuilder sb) {
-        sb.delete(0, sb.length());
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/populating-next-right-pointers-in-each-node.md" "b/\351\242\230\350\247\243/populating-next-right-pointers-in-each-node.md"
deleted file mode 100644
index 9052770..0000000
--- "a/\351\242\230\350\247\243/populating-next-right-pointers-in-each-node.md"
+++ /dev/null
@@ -1,37 +0,0 @@
-# Populating Next Right Pointers in Each Node
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/populating-next-right-pointers-in-each-node/?utm_source=sc-github-wzz)
- ## 题目描述
- 1730
- ### 样例说明
- 1730
- ### 参考代码
- Given a binary tree&nbsp;<div><br></div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct TreeLinkNode {&nbsp;</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;&nbsp;&nbsp;&nbsp;TreeLinkNode *left;&nbsp;</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeLinkNode *right;&nbsp;</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeLinkNode *next;&nbsp;</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;}&nbsp;</div><div><br></div><div>Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.&nbsp;</div><div><span style="line-height: 1.42857143;">Initially, all next pointers are set to NULL.&nbsp;</span></div><div><span style="line-height: 1.42857143;"><br></span></div><div><span style="line-height: 1.42857143;">Note:&nbsp;</span></div><div><span style="line-height: 1.42857143;">You may only use constant extra space.&nbsp;</span></div><div><span style="line-height: 1.42857143;">You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).&nbsp;</span></div><div><span style="line-height: 1.42857143;"><br></span></div><div><span style="line-height: 1.42857143;">For example,&nbsp;</span></div><div><span style="line-height: 1.42857143;">Given the following perfect binary tree,&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp; &nbsp; 1&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp; / &nbsp; &nbsp;\&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; 2 &nbsp; &nbsp; &nbsp;3&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp;/ \ &nbsp; &nbsp; / \&nbsp;</span></div><div><span style="line-height: 1.42857143;">4 &nbsp;5 &nbsp;6 &nbsp;7&nbsp;</span></div><div><span style="line-height: 1.42857143;">After calling your function, the tree should look like:&nbsp;</span></div><div><span style="line-height: 1.42857143;"><br></span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 -&gt; NULL&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp; &nbsp; &nbsp;/ &nbsp; &nbsp; &nbsp;\&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp; &nbsp; 2 &nbsp; &nbsp;-&gt; &nbsp;3 -&gt; NULL</span></div><div><span style="line-height: 1.42857143;">&nbsp; / &nbsp; \ &nbsp; &nbsp; &nbsp;/ &nbsp; \&nbsp;</span></div><div><span style="line-height: 1.42857143;">&nbsp;4-&gt;5-&gt;6-&gt;7 -&gt; NULL</span><br></div><div><span style="line-height: 1.42857143;"><br></span></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博：</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/BsKGT8TXu" target="_blank">http://weibo.com/3948019741/BsKGT8TXu</a></span></font><span style="line-height: 1.42857143;"><br></span></div>
-```java
-public class Solution {
-    public void connect(TreeLinkNode root) {
-        if (root == null) {
-            return;
-        }
-
-        TreeLinkNode parent = root;
-        TreeLinkNode next = parent.left;
-        while (parent != null && next != null) {
-            TreeLinkNode prev = null;
-            while (parent != null) {
-                if (prev == null) {
-                    prev = parent.left;
-                } else {
-                    prev.next = parent.left;
-                    prev = prev.next;
-                }
-                prev.next = parent.right;
-                prev = prev.next;
-                parent = parent.next;
-            }
-            parent = next;
-            next = parent.left;
-        }
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/push-dominoes.md" "b/\351\242\230\350\247\243/push-dominoes.md"
deleted file mode 100644
index c314fc4..0000000
--- "a/\351\242\230\350\247\243/push-dominoes.md"
+++ /dev/null
@@ -1,99 +0,0 @@
-# 推多米诺
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/push-dominoes/?utm_source=sc-github-wzz)
- ## 题目描述
- 432
- ### 样例说明
- 432
- ### 参考代码
- BFS解法
-```
-[[python]]
-class Solution:
-    """
-    @param dominoes: a string
-    @return: a string representing the final state
-    """
-    def pushDominoes(self, dominoes):
-        queue = []
-        dominoes = list(dominoes)
-        for index, c in enumerate(dominoes):
-            if c != '.':
-                queue.append((index, c))
-        
-        while queue:
-            falling = {}
-            for (index, c) in queue:
-                if c == 'L' and index > 0 and dominoes[index - 1] == '.':
-                    if index - 1 in falling:
-                        falling[index - 1] = '.'
-                    else:
-                        falling[index - 1] = 'L'
-                if c == 'R' and index + 1 < len(dominoes) and dominoes[index + 1] == '.':
-                    if index + 1 in falling:
-                        falling[index + 1] = '.'
-                    else:
-                        falling[index + 1] = 'R'
-            queue = []
-            for index, c in falling.items():
-                if c != '.':
-                    queue.append((index, c))
-                    dominoes[index] = c
-        
-        return ''.join(dominoes)
-[[java]]
-class IndexValuePair {
-    int index;
-    char value;
-    public IndexValuePair(int index, char value) {
-        this.index = index;
-        this.value = value;
-    }
-}
-
-public class Solution {
-    /**
-     * @param dominoes: a string
-     * @return: a string representing the final state
-     */
-    public String pushDominoes(String dominoes) {
-        List<IndexValuePair> queue = new ArrayList<>();
-        char[] chars = dominoes.toCharArray();
-        for (int index = 0; index < chars.length; index++) {
-            if (chars[index] != '.') {
-                queue.add(new IndexValuePair(index, chars[index]));
-            }
-        }
-        
-        while (!queue.isEmpty()) {
-            Map<Integer, Character> falling = new HashMap<>();
-            for (IndexValuePair pair: queue) {
-                int index = pair.index, value = pair.value;
-                if (value == 'L' && index > 0 && chars[index - 1] == '.') {
-                    if (falling.containsKey(index - 1)) {
-                        falling.put(index - 1, '.');
-                    } else {
-                        falling.put(index - 1, 'L');
-                    }
-                }
-                if (value == 'R' && index + 1 < chars.length && chars[index + 1] == '.') {
-                    if (falling.containsKey(index + 1)) {
-                        falling.put(index + 1, '.');
-                    } else {
-                        falling.put(index + 1, 'R');
-                    }
-                }
-            }
-            queue = new ArrayList<>();
-            for (int index: falling.keySet()) {
-                char value = falling.get(index);
-                if (value != '.') {
-                    queue.add(new IndexValuePair(index, value));
-                    chars[index] = value;
-                }
-            }
-        }
-        return String.valueOf(chars);
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/quick-sort.md" "b/\351\242\230\350\247\243/quick-sort.md"
deleted file mode 100644
index 04ebb45..0000000
--- "a/\351\242\230\350\247\243/quick-sort.md"
+++ /dev/null
@@ -1,43 +0,0 @@
-# Quick Sort
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/quick-sort/?utm_source=sc-github-wzz)
- ## 题目描述
- 1771
- ### 样例说明
- 1771
- ### 参考代码
- ```
-代码
-```
-Python实现的快速排序                     .
-```python
-class Solution:
-    # @param {int[]} A an integer array
-    # @return nothing
-    def sortIntegers2(self, A):
-        # Write your code here
-        self.quickSort(A, 0, len(A) - 1)
-    
-    def quickSort(self, A, start, end):
-        if start >= end:
-            return
-        
-        left, right = start, end
-        # key point 1: pivot is the value, not the index
-        pivot = A[(start + end) // 2]
-
-        # key point 2: every time you compare left & right, it should be 
-        # left <= right not left < right
-        while left <= right:
-            while left <= right and A[left] < pivot:
-                left += 1
-            while left <= right and A[right] > pivot:
-                right -= 1
-            if left <= right:
-                A[left], A[right] = A[right], A[left]
-                left += 1
-                right -= 1
-        
-        self.quickSort(A, start, right)
-        self.quickSort(A, left, end)
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/rate-limiter.md" "b/\351\242\230\350\247\243/rate-limiter.md"
deleted file mode 100644
index 33fd2e9..0000000
--- "a/\351\242\230\350\247\243/rate-limiter.md"
+++ /dev/null
@@ -1,69 +0,0 @@
-# 限制器
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/rate-limiter/?utm_source=sc-github-wzz)
- ## 题目描述
- 1367
- ### 样例说明
- 1367
- ### 参考代码
- ```java
-public class RateLimiter {
-    private HashMap<String, List<Integer>> map = new HashMap<>();
-    
-    /**
-     * @param timestamp the current timestamp
-     * @param event the string to distinct different event
-     * @param rate the format is [integer]/[s/m/h/d]
-     * @param increment whether we should increase the counter
-     * @return true of false to indicate the event is limited or not
-     */
-    public boolean isRatelimited(int current_timestamp, String event, String rate, boolean increment) {
-        // Write your code here
-        int start = rate.indexOf("/");
-        int limit = Integer.parseInt(rate.substring(0, start));
-        String type = rate.substring(start + 1, rate.length());
-
-        int duration = 1;
-        if (type.equals("m"))
-            duration = duration * 60;
-        else if (type.equals("h"))
-            duration = duration * 60 * 60;
-        else if (type.equals("d"))
-            duration = duration * 60 * 60 * 24;
-        int start_timestamp = current_timestamp - duration + 1;
-        
-        if (!map.containsKey(event))
-            map.put(event, new ArrayList<Integer>());
-
-        int count = count_events(map.get(event), start_timestamp);
-        boolean is_ratelimited = count >= limit;
-        if (increment && !is_ratelimited)
-            insert_event(map.get(event), current_timestamp);
-        return is_ratelimited;
-    }
-
-    public void insert_event(List<Integer> event, int timestamp) {
-        event.add(timestamp);
-    }
-
-    // use binary search algorithm to count how many events happened
-    // after start_timestamp because event is sorted by timestamp
-    public int count_events(List<Integer> event, int start_timestamp) {
-        int l = 0, r = event.size() - 1;
-        if (r == -1)
-            return 0;
-        if (event.get(r) < start_timestamp) 
-            return 0;
-        int ans = 0;
-        while (l <= r) {
-            int mid = (l + r) >> 1;
-            if (event.get(mid) >= start_timestamp) {
-                ans = mid;
-                r = mid - 1;
-            } else
-                l = mid + 1;
-        }
-        return event.size() - 1 - ans + 1;
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/read-characters-from-file-multiple-calls.md" "b/\351\242\230\350\247\243/read-characters-from-file-multiple-calls.md"
deleted file mode 100644
index 16ccf60..0000000
--- "a/\351\242\230\350\247\243/read-characters-from-file-multiple-calls.md"
+++ /dev/null
@@ -1,65 +0,0 @@
-# read characters from file multiple calls
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/read-characters-from-file-multiple-calls/?utm_source=sc-github-wzz)
- ## 题目描述
- 1781
- ### 样例说明
- 1781
- ### 参考代码
- ```cpp
-// version 1
-// Forward declaration of the read4 API.
-int read4(char *buf);
-
-class Solution {
-public:
-  /**
-   * @param buf Destination buffer
-   * @param n   Maximum number of characters to read
-   * @return  The number of characters read
-   */
-  char buffer[4];
-  int bufferPtr = 0, bufferCnt = 0;
-  
-  int read(char *buf, int n) {
-    // Write your code here
-    int ptr = 0;
-
-    while (ptr < n) {
-      if (bufferPtr == bufferCnt) {
-        bufferCnt = read4(buffer);
-        bufferPtr = 0;
-      }
-      if (bufferCnt == 0) {
-        break;
-      }
-      while (ptr < n && bufferPtr < bufferCnt) {  
-        buf[ptr++] = buffer[bufferPtr++];
-      }
-    } 
-    return ptr;
-  }
-};
-
-// version 2
-// Forward declaration of the read4 API.
-int read4(char *buf);
-
-class Solution {
-public:
-    /**
-     * @param buf destination buffer
-     * @param n maximum number of characters to read
-     * @return the number of characters read
-     */
-    int read(char *buf, int n) {
-        // Write your code here
-        int i = 0;
-        while (i < n && (i4 < n4 || (i4 = 0) < (n4 = read4(buf4))))
-            buf[i++] = buf4[i4++];
-        return i;
-    }
-    char buf4[4];
-    int i4 = 0, n4 = 0;
-};
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/read-n-characters-given-read4.md" "b/\351\242\230\350\247\243/read-n-characters-given-read4.md"
deleted file mode 100644
index 522b6e6..0000000
--- "a/\351\242\230\350\247\243/read-n-characters-given-read4.md"
+++ /dev/null
@@ -1,34 +0,0 @@
-# Read N Characters Given Read4
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/read-n-characters-given-read4/?utm_source=sc-github-wzz)
- ## 题目描述
- 1774
- ### 样例说明
- 1774
- ### 参考代码
- ```java
-/* The read4 API is defined in the parent class Reader4.
-      int read4(char[] buf); */
-
-public class Solution extends Reader4 {
-    /**
-     * @param buf Destination buffer
-     * @param n   Maximum number of characters to read
-     * @return    The number of characters read
-     */
-    public int read(char[] buf, int n) {
-        char[] buf4 = new char[4];
-        int offset = 0;
-        
-        while (true) {
-            int size = read4(buf4);
-            for (int i = 0; i < size && offset < n; i++) {
-                buf[offset++] = buf4[i];
-            }
-            if (size == 0 || offset == n) {
-                return offset;
-            }
-        }
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/segmemt-tree-build-ii.md" "b/\351\242\230\350\247\243/segmemt-tree-build-ii.md"
deleted file mode 100644
index a71d156..0000000
--- "a/\351\242\230\350\247\243/segmemt-tree-build-ii.md"
+++ /dev/null
@@ -1,54 +0,0 @@
-# segmemt-tree-build-ii
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/segmemt-tree-build-ii/?utm_source=sc-github-wzz)
- ## 题目描述
- 1763
- ### 样例说明
- 1763
- ### 参考代码
- ```java
-
-/**
- * Definition of SegmentTreeNode:
- * public class SegmentTreeNode {
- *     public int start, end, max;
- *     public SegmentTreeNode left, right;
- *     public SegmentTreeNode(int start, int end, int max) {
- *         this.start = start;
- *         this.end = end;
- *         this.max = max
- *         this.left = this.right = null;
- *     }
- * }
- */
-public class Solution {
-    /**
-     *@param A: a list of integer
-     *@return: The root of Segment Tree
-     */
-    public SegmentTreeNode build(int[] A) {
-        // write your code here
-        return build(0,A.length-1, A);
-    }
-    
-    public SegmentTreeNode build(int start, int end, int[]array) {
-        // write your code here
-        if(start > end) {  // check core case
-            return null;
-        }
-        
-        SegmentTreeNode root = new SegmentTreeNode(start, end, Integer.MIN_VALUE);
-        
-        if(start != end) {
-            int mid = (start + end) / 2;
-            root.left = build(start, mid, array);
-            root.right = build(mid+1, end, array);
-            
-            root.max = Math.max(root.left.max, root.right.max);
-        } else {
-            root.max = array[start];
-        }
-        return root;
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/segment-tree-build-ii.md" "b/\351\242\230\350\247\243/segment-tree-build-ii.md"
index 5dde1bc..f129f79 100644
--- "a/\351\242\230\350\247\243/segment-tree-build-ii.md"
+++ "b/\351\242\230\350\247\243/segment-tree-build-ii.md"
@@ -23,7 +23,7 @@
   (max=3)(max=2)  (max=1)(max=4)
  ### 参考代码
  模板题, 递归构造线段树即可. 注意内存要分配在堆上, 而不是栈上.
-
+ ```
 Python代码为Python2版本
 ```python
 """
diff --git "a/\351\242\230\350\247\243/string-to-integer-ii.md" "b/\351\242\230\350\247\243/string-to-integer-ii.md"
deleted file mode 100644
index a19bdf3..0000000
--- "a/\351\242\230\350\247\243/string-to-integer-ii.md"
+++ /dev/null
@@ -1,31 +0,0 @@
-# String to Integer II
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/string-to-integer-ii/?utm_source=sc-github-wzz)
- ## 题目描述
- 1769
- ### 样例说明
- 1769
- ### 参考代码
- ```python
-class Solution:
-    # @param str: a string
-    # @return an integer
-    def atoi(self, str):
-        if len(str) == 0:
-            return 0
-        sgn, num, p = 0, 0, 0
-        imin, imax = -1<<31, (1<<31)-1
-        while str[p] == ' ':
-            p  = p + 1
-        if str[p] == '-' or str[p] == '+':
-            sgn = 1 if str[p] == '-' else 0
-            p = p + 1
-        while p < len(str) and str[p] >= '0' and str[p] <= '9':
-            num = num * 10 + ord(str[p]) - ord('0')
-            x = -num if sgn else num
-            if x < imin: return imin
-            if x > imax: return imax
-            p = p + 1
-        return -num if sgn else num
-
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/strstr.md" "b/\351\242\230\350\247\243/strstr.md"
deleted file mode 100644
index 5c5f8e7..0000000
--- "a/\351\242\230\350\247\243/strstr.md"
+++ /dev/null
@@ -1,36 +0,0 @@
-# strstr
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/strstr/?utm_source=sc-github-wzz)
- ## 题目描述
- 1770
- ### 样例说明
- 1770
- ### 参考代码
- ```python
-class Solution:
-    """
-    @param: source: source string to be scanned.
-    @param: target: target string containing the sequence of characters to match
-    @return: a index to the first occurrence of target in source, or -1  if target is not part of source.
-    """
-    def strStr(self, source, target):
-        # write your code here
-        if source is None or target is None:
-            return -1
-
-        if len(source) < len(target):
-            return -1
-        if len(target) == 0:
-            return 0
-        for i in range(len(source)-len(target) + 1):
-            j = 0
-            while j < len(target):
-                if source[i + j] == target[j]:
-                    j = j + 1
-                else:
-                    j = 0
-                    break
-            if j == len(target):
-                return i
-        return -1
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/test.md" "b/\351\242\230\350\247\243/test.md"
deleted file mode 100644
index 21c7a7e..0000000
--- "a/\351\242\230\350\247\243/test.md"
+++ /dev/null
@@ -1,39 +0,0 @@
-# Test
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/test/?utm_source=sc-github-wzz)
- ## 题目描述
- 1778
- ### 样例说明
- 1778
- ### 参考代码
- ```java
-public class Solution {
-    public int[] singleNumber(int[] nums) {
-        //用于记录，区分“两个”数组
-        int diff = 0;
-        for(int i = 0; i < nums.length; i ++) {
-            diff ^= nums[i];
-        }
-        //取最后一位1
-        //先介绍一下原码，反码和补码
-        //原码，就是其二进制表示（注意，有一位符号位）
-        //反码，正数的反码就是原码，负数的反码是符号位不变，其余位取反
-        //补码，正数的补码就是原码，负数的补码是反码+1
-        //在机器中都是采用补码形式存
-        //diff & (-diff)就是取diff的最后一位1的位置
-        diff &= -diff;
-        
-        int[] rets = {0, 0}; 
-        for(int i = 0; i < nums.length; i ++) {
-            //分属两个“不同”的数组
-            if ((nums[i] & diff) == 0) {
-                rets[0] ^= nums[i];
-            }
-            else {
-                rets[1] ^= nums[i];
-            }
-        }
-        return rets;
-    }
-}
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/top-k-largest-number-ii.md" "b/\351\242\230\350\247\243/top-k-largest-number-ii.md"
deleted file mode 100644
index cd666f9..0000000
--- "a/\351\242\230\350\247\243/top-k-largest-number-ii.md"
+++ /dev/null
@@ -1,41 +0,0 @@
-# Top k largest Number II
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/top-k-largest-number-ii/?utm_source=sc-github-wzz)
- ## 题目描述
- 1773
- ### 样例说明
- 1773
- ### 参考代码
- <p><br></p>
-```java
-public class Solution {
-    private int maxSize;
-    private Queue<Integer> minheap;
-    public Solution(int k) {
-        minheap = new PriorityQueue<>();
-        maxSize = k;
-    }
-
-    public void add(int num) {
-        if (minheap.size() < maxSize) {
-            minheap.offer(num);
-            return;
-        }
-        
-        if (num > minheap.peek()) {
-            minheap.poll();
-            minheap.offer(num);
-        }
-    }
-
-    public List<Integer> topk() {
-        Iterator it = minheap.iterator();
-        List<Integer> result = new ArrayList<Integer>();
-        while (it.hasNext()) {
-            result.add((Integer) it.next());
-        }
-        Collections.sort(result, Collections.reverseOrder());
-        return result;
-    }
-};
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\242\230\350\247\243/trie-serialization.md" "b/\351\242\230\350\247\243/trie-serialization.md"
deleted file mode 100644
index 8f09da8..0000000
--- "a/\351\242\230\350\247\243/trie-serialization.md"
+++ /dev/null
@@ -1,76 +0,0 @@
-# 序列化Trie
- > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/trie-serialization/?utm_source=sc-github-wzz)
- ## 题目描述
- 1274
- ### 样例说明
- 1274
- ### 参考代码
- ```java
-/**
- * Definition of TrieNode:
- * public class TrieNode {
- *     public NavigableMap<Character, TrieNode> children;
- *     public TrieNode() {
- *         children = new TreeMap<Character, TrieNode>();
- *     }
- * }
- */
-class Solution {
-    /**
-     * This method will be invoked first, you should design your own algorithm 
-     * to serialize a trie which denote by a root node to a string which
-     * can be easily deserialized by your own "deserialize" method later.
-     */
-    public String serialize(TrieNode root) {
-        // Write your code here
-        if (root == null)
-            return "";
-
-        StringBuffer sb = new StringBuffer();
-        sb.append("<");
-        Iterator iter = root.children.entrySet().iterator(); 
-        while (iter.hasNext()) {
-            Map.Entry entry = (Map.Entry)iter.next(); 
-            Character key = (Character)entry.getKey(); 
-            TrieNode child = (TrieNode)entry.getValue();
-            sb.append(key);
-            sb.append(serialize(child));
-        }
-        sb.append(">");
-        return sb.toString();
-    }
-
-    /**
-     * This method will be invoked second, the argument data is what exactly
-     * you serialized at method "serialize", that means the data is not given by
-     * system, it's given by your own serialize method. So the format of data is
-     * designed by yourself, and deserialize it here as you serialize it in 
-     * "serialize" method.
-     */
-    public TrieNode deserialize(String data) {
-        // Write your code here
-        if (data == null || data.length() == 0)
-            return null;
-
-        TrieNode root = new TrieNode();
-        TrieNode current = root;
-        Stack<TrieNode> path = new Stack<TrieNode>();
-        for (Character c : data.toCharArray()) {
-            switch (c) {
-            case '<':
-                path.push(current);
-                break;
-            case '>':
-                path.pop();
-                break;
-            default:
-                current = new TrieNode();
-                path.peek().children.put(c, current);
-            }
-        }
-        return root;
-    }
-}
-
-```
- 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/anagrams.md" "b/\351\253\230\351\242\221/anagrams.md"
new file mode 100644
index 0000000..a48bf3a
--- /dev/null
+++ "b/\351\253\230\351\242\221/anagrams.md"
@@ -0,0 +1,38 @@
+# 乱序字符串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/anagrams/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出一个字符串数组S，找到其中所有的乱序字符串(Anagram)。如果一个字符串是乱序字符串，那么他存在一个字母集合相同，但顺序不同的字符串也在S中。</p>
+ ### 样例说明
+ **样例1:**
+```
+输入:["lint", "intl", "inlt", "code"]
+输出:["lint", "inlt", "intl"]
+```
+
+**样例 2:**
+```
+输入:["ab", "ba", "cd", "dc", "e"]
+输出: ["ab", "ba", "cd", "dc"]
+```
+ ### 参考代码
+ Given an array of strings, return all groups of strings that are anagrams.
+
+Note: All inputs will be in lower-case
+```python
+class Solution:
+    # @param strs: A list of strings
+    # @return: A list of strings
+    def anagrams(self, strs):
+        # write your code here
+        dict = {}
+        for word in strs:
+            sortedword = ''.join(sorted(word))
+            dict[sortedword] = [word] if sortedword not in dict else dict[sortedword] + [word]
+        res = []
+        for item in dict:
+            if len(dict[item]) >= 2:
+                res += dict[item]
+        return res
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/char-to-integer.md" "b/\351\253\230\351\242\221/char-to-integer.md"
new file mode 100644
index 0000000..c617a22
--- /dev/null
+++ "b/\351\253\230\351\242\221/char-to-integer.md"
@@ -0,0 +1,35 @@
+# 字符转整数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/char-to-integer/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将字符转换为一个整数。你可以假设字符是ASCII码，也就是说转换后的整数在0~255之间。
+ ### 样例说明
+ ```
+样例  1:
+	输入:  'a'
+	输出: 97
+	
+	样例解释: 
+	返回ASCII码中对应的数字.
+
+样例 2:
+	输入:  '%'
+	输出: 37
+	
+	样例解释: 
+	返回ASCII码中对应的数字.
+
+```
+ ### 参考代码
+ 类型转换
+```java
+public class Solution {
+    /**
+     * @param character a character
+     * @return an integer
+     */
+    public int charToInteger(char character) {
+        return (int) character;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/compare-strings.md" "b/\351\253\230\351\242\221/compare-strings.md"
new file mode 100644
index 0000000..b858d59
--- /dev/null
+++ "b/\351\253\230\351\242\221/compare-strings.md"
@@ -0,0 +1,35 @@
+# 比较字符串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/compare-strings/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 比较两个字符串A和B，确定A中是否包含B中所有的字符。字符串A和B中的字符都是 **大写字母**
+ ### 样例说明
+ 给出 A = `"ABCD"` B = `"ACD"`，返回 `true`
+
+给出 A = `"ABCD"`  B = `"AABC"`， 返回 `false`
+ ### 参考代码
+ ```python
+class Solution:
+    """
+    @param A : A string includes Upper Case letters
+    @param B : A string includes Upper Case letters
+    @return :  if string A contains all of the characters in B return True else return False
+    """
+    def compareStrings(self, A, B):
+        # write your code here
+        if len(B) == 0:
+            return True
+        if len(A) == 0:
+            return False
+        #trackTable首先记录A中所有的字符以及它们的个数，然后遍历B,如果出现trackTable[i]小于0的情况，说明B中该字符出现的次数
+        #大于在A中出现的次数
+        trackTable = [0 for _ in range(26)]
+        for i in A:
+            trackTable[ord(i) - 65] += 1
+        for i in B:
+            if trackTable[ord(i) - 65] == 0:
+                return False
+            else:
+                trackTable[ord(i) -65] -= 1
+        return True
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/count-and-say.md" "b/\351\253\230\351\242\221/count-and-say.md"
new file mode 100644
index 0000000..58baebc
--- /dev/null
+++ "b/\351\253\230\351\242\221/count-and-say.md"
@@ -0,0 +1,60 @@
+# 报数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/count-and-say/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 报数指的是，按照其中的整数的顺序进行报数，然后得到下一个数。如下所示：
+
+`1, 11, 21, 1211, 111221, ...`
+
+`1` 读作 `"one 1"` -> `11`
+
+`11` 读作 `"two 1s"` -> `21`
+
+`21` 读作 `"one 2, then one 1"` -> `1211`
+
+给定一个整数 `n`, 返回 第 `n` 个顺序。 
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入：1
+输出："1"
+```
+**样例 2：**
+```
+输入：5
+输出："111221"
+```
+ ### 参考代码
+ The count-and-say sequence is the sequence of integers beginning as follows:
+1, 11, 21, 1211, 111221, ...
+
+1 is read off as "one 1" or 11.
+11 is read off as "two 1s" or 21.
+21 is read off as "one 2, then one 1" or 1211.
+Given an integer n, generate the nth sequence.
+
+Note: The sequence of integers will be represented as a string.
+```java
+public class Solution {
+    public String countAndSay(int n) {
+        String oldString = "1";
+        while (--n > 0) {
+            StringBuilder sb = new StringBuilder();
+            char [] oldChars = oldString.toCharArray();
+
+            for (int i = 0; i < oldChars.length; i++) {
+                int count = 1;
+                while ((i+1) < oldChars.length && oldChars[i] == oldChars[i+1]) {
+                    count++;
+                    i++;
+                }
+                sb.append(String.valueOf(count) + String.valueOf(oldChars[i]));
+            }
+            oldString = sb.toString();
+        }
+
+        return oldString;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/edit-distance-ii.md" "b/\351\253\230\351\242\221/edit-distance-ii.md"
new file mode 100644
index 0000000..2defc1e
--- /dev/null
+++ "b/\351\253\230\351\242\221/edit-distance-ii.md"
@@ -0,0 +1,78 @@
+# 一次编辑距离
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/edit-distance-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个字符串 S 和 T, 判断T是否可以通过对S做刚好一次编辑得到。
+每次编辑可以选择以下任意一个操作：
+- 在S的任意位置插入一个字符
+- 删除S中的任意一个字符
+- 将S中的任意字符替换成其他字符
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param s a string
+     * @param t a string
+     * @return true if they are both one edit distance apart or false
+     */
+    public boolean isOneEditDistance(String s, String t) {
+        // Write your code here
+        int m = s.length();
+        int n = t.length();
+        if (Math.abs(m - n) > 1)
+            return false;
+
+        if (m > n)
+            return isOneEditDistance(t, s);
+        for (int i = 0; i < m; i++) {
+            if (s.charAt(i) != t.charAt(i)) {
+                if (m == n) {
+                    return s.substring(i + 1).equals(t.substring(i + 1));
+                }
+                return s.substring(i).equals(t.substring(i + 1));
+            }
+        }
+        return m != n;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param s a string
+     * @param t a string
+     * @return true if they are both one edit distance apart or false
+     */
+    public boolean isOneEditDistance(String s, String t) {
+        // Write your code here
+        if (s.length() > t.length()) {
+            return isOneEditDistance(t, s);
+        }
+        int diff = t.length() - s.length();
+
+        if (diff > 1) {
+            return false;
+        }
+        if (diff == 0) {
+            int cnt = 0;
+            for (int i = 0; i < s.length(); i++) {
+                if (t.charAt(i) != s.charAt(i)) {
+                    cnt++;
+                }
+            }
+            return (cnt == 1);
+        }
+        if (diff == 1) {
+            for (int i = 0; i < s.length(); i++) {
+                if (t.charAt(i) != s.charAt(i)) {
+                    return (s.substring(i).equals(t.substring(i + 1)));
+                }
+            }
+        }
+        return true;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/excel-sheet-column-title.md" "b/\351\253\230\351\242\221/excel-sheet-column-title.md"
new file mode 100644
index 0000000..4cc2d71
--- /dev/null
+++ "b/\351\253\230\351\242\221/excel-sheet-column-title.md"
@@ -0,0 +1,31 @@
+# Excel表列标题
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/excel-sheet-column-title/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个正整数，返回相应的列标题，如Excel表中所示。
+ ### 样例说明
+ **样例1**
+
+```
+输入: 28
+输出: "AB"
+```
+
+**样例2**
+
+```
+输入: 29
+输出: "AC"
+```
+ ### 参考代码
+ ```cpp
+class Solution {
+public:
+    string convertToTitle(int n) {
+        if (n == 0) {
+            return "";
+        }
+        return convertToTitle((n - 1) / 26) + (char)((n - 1) % 26 + 'A');
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/expression-expand.md" "b/\351\253\230\351\242\221/expression-expand.md"
new file mode 100644
index 0000000..132be36
--- /dev/null
+++ "b/\351\253\230\351\242\221/expression-expand.md"
@@ -0,0 +1,37 @@
+# 字符串解码
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/expression-expand/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个表达式 `s`，此表达式包括数字，字母以及方括号。在方括号前的数字表示方括号内容的重复次数(括号内的内容可以是字符串或另一个表达式)，请将这个表达式展开成一个字符串。
+ ### 样例说明
+ 
+ ### 参考代码
+ 把所有字符一个个放到 stack 里，当碰到 "]" 的时候，就从 stack 把对应的字符串和重复次数找到，展开，然后再丢回 stack 里，
+```python
+class Solution:
+    """
+    @param s: an expression includes numbers, letters and brackets
+    @return: a string
+    """
+    def expressionExpand(self, s):
+        stack = []
+        for c in s:
+            if c == ']':
+                strs = []
+                while stack and stack[-1] != '[':
+                    strs.append(stack.pop())
+                
+                # skip '['
+                stack.pop()
+                
+                repeats = 0
+                base = 1
+                while stack and stack[-1].isdigit():
+                    repeats += (ord(stack.pop()) - ord('0')) * base
+                    base *= 10
+                stack.append(''.join(reversed(strs)) * repeats)
+            else:
+                stack.append(c)
+        
+        return ''.join(stack)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/expression-tree-build.md" "b/\351\253\230\351\242\221/expression-tree-build.md"
new file mode 100644
index 0000000..d3c3f2f
--- /dev/null
+++ "b/\351\253\230\351\242\221/expression-tree-build.md"
@@ -0,0 +1,212 @@
+# 表达树构造
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/expression-tree-build/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 表达树是一个二叉树的结构，用于衡量特定的表达。所有表达树的叶子都有一个数字字符串值。而所有表达树的非叶子都有另一个操作字符串值。
+
+给定一个表达数组，请构造该表达的表达树，并返回该表达树的根。
+ ### 样例说明
+ **样例 1:**
+```
+输入: ["2","*","6","-","(","23","+","7",")","/","(","1","+","2",")"]
+输出: {[-],[*],[/],[2],[6],[+],[+],#,#,#,#,[23],[7],[1],[2]} 
+解释:
+其表达树如下：
+
+	                 [ - ]
+	             /          \
+	        [ * ]              [ / ]
+	      /     \           /         \
+	    [ 2 ]  [ 6 ]      [ + ]        [ + ]
+	                     /    \       /      \
+	                   [ 23 ][ 7 ] [ 1 ]   [ 2 ] .
+
+在构造该表达树后，你只需返回根节点`[-]`。
+```
+
+**样例 2:**
+```
+输入: ["10","+","(","3","-","5",")","+","7","*","7","-","2"]
+输出: {[-],[+],[2],[+],[*],#,#,[10],[-],[7],[7],#,#,[3],[5]}
+解释:
+其表达树如下：
+ 	                       [ - ]
+	                   /          \
+	               [ + ]          [ 2 ]
+	           /          \      
+	       [ + ]          [ * ]
+              /     \         /     \
+	  [ 10 ]  [ - ]    [ 7 ]   [ 7 ]
+	          /    \ 
+                [3]    [5]
+在构造该表达树后，你只需返回根节点`[-]`。
+```
+
+ ### 参考代码
+ 根据运算符的优先级来构造单调递增栈，最后弹出栈中元素，最后一个就是根节点，返回即可。
+```java
+// version 1
+/**
+ * Definition of ExpressionTreeNode:
+ * public class ExpressionTreeNode {
+ *     public String symbol;
+ *     public ExpressionTreeNode left, right;
+ *     public ExpressionTreeNode(String symbol) {
+ *         this.symbol = symbol;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+
+public class Solution {
+    class TreeNode {
+        int val;
+        ExpressionTreeNode eNode;
+        public TreeNode(int val, String s) {
+            this.val = val;
+            eNode = new ExpressionTreeNode(s);
+        }
+    }
+    /**
+     * @param expression: A string array
+     * @return: The root of expression tree
+     */
+    public ExpressionTreeNode build(String[] expression) {
+        if (expression == null || expression.length == 0) {
+            return null;
+        }
+        Stack<TreeNode> stack = new Stack<TreeNode>();
+        int base = 0;
+        int val = 0;
+
+        for (int i = 0; i < expression.length; i++) {
+            if (expression[i].equals("(")) {
+                base += 10;
+                continue;
+            }
+            if (expression[i].equals(")")) {
+                base -= 10;
+                continue;
+            }
+            val = getWeight(base, expression[i]);
+            TreeNode node = new TreeNode(val, expression[i]);
+            while (!stack.isEmpty() && node.val <= stack.peek().val) {
+                node.eNode.left = stack.pop().eNode;
+            }
+            if (!stack.isEmpty()) {
+                stack.peek().eNode.right = node.eNode;
+            }
+            stack.push(node);
+        }
+        if (stack.isEmpty()) {
+            return null;
+        }
+        TreeNode rst = stack.pop();
+        while (!stack.isEmpty()) {
+            rst = stack.pop();
+        }
+        return rst.eNode;
+    }
+    //Calculate weight for characters
+    public int getWeight(int base, String s) {
+        if (s.equals("+") || s.equals("-")) {
+            return base + 1;
+        }
+        if (s.equals("*") || s.equals("/")) {
+            return base + 2;
+        }
+        return Integer.MAX_VALUE;
+    }
+}
+
+// version 2
+/**
+ * Definition of ExpressionTreeNode:
+ * public class ExpressionTreeNode {
+ *     public String symbol;
+ *     public ExpressionTreeNode left, right;
+ *     public ExpressionTreeNode(rooting symbol) {
+ *         this.symbol = symbol;
+ *         this.left = this.right = null;
+ *     }
+ * }
+ */
+class TreeNode {
+	public int val;
+	public String s;
+	public ExpressionTreeNode root; 
+
+	public TreeNode(int val, String ss) {
+		this.val = val;
+		this.root = new ExpressionTreeNode(ss);
+	}
+
+}
+
+public class Solution {
+
+	int get(String a, Integer base) {
+		if (a.equals("+") || a.equals("-"))
+			return 1 + base;
+		if (a.equals("*") || a.equals("/"))
+			return 2 + base;
+
+		return Integer.MAX_VALUE;
+	}
+
+
+
+	public ExpressionTreeNode build(String[] expression) {
+		// write your code here
+		Stack<TreeNode> stack = new Stack<TreeNode>();
+		TreeNode root = null;
+		int val = 0;
+		Integer base = 0;
+		for (int i = 0; i <= expression.length; i++) {
+			if(i != expression.length)
+			{
+				
+				if (expression[i].equals("(")) {
+					base += 10;
+					continue;
+				}
+				if (expression[i].equals(")")) {
+					base -= 10;
+					continue;
+				}
+				val = get(expression[i], base);
+
+			}
+			TreeNode right = i == expression.length ? new TreeNode(
+					Integer.MIN_VALUE, "") : new TreeNode(val,
+					expression[i]);
+			while (!stack.isEmpty()) {
+				if (right.val <= stack.peek().val) {
+					TreeNode nodeNow = stack.pop();
+
+					if (stack.isEmpty()) {
+						right.root.left = nodeNow.root;
+
+					} else {
+						TreeNode left = stack.peek();
+						if (left.val < right.val) {
+							right.root.left = nodeNow.root;
+						} else {
+							left.root.right = nodeNow.root;
+						}
+					}
+				} else {
+					break;
+				}
+			}
+			stack.push(right);
+		}
+
+	
+		
+		return stack.peek().root.left;
+	}
+
+
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/first-position-unique-character.md" "b/\351\253\230\351\242\221/first-position-unique-character.md"
new file mode 100644
index 0000000..ed05833
--- /dev/null
+++ "b/\351\253\230\351\242\221/first-position-unique-character.md"
@@ -0,0 +1,64 @@
+# 第一个独特字符位置
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/first-position-unique-character/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个字符串。找到字符串中第一个不重复的字符然后返回它的下标。如果不存在这样的字符，返回 `-1`。
+ ### 样例说明
+ **样例 1:**
+```
+输入 : s = "lintcode"
+输出 : 0
+```
+**样例 2:**
+```
+输入 : s = "lovelintcode"
+输出 : 2
+```
+ ### 参考代码
+ 先将所有字符扫一遍，保存出现过的字符，然后再扫一遍，遇到第一个出现一次的字符就是答案。
+```java
+public class Solution {
+    /**
+     * @param s a string
+     * @return it's index
+     */
+    public int firstUniqChar(String s) {
+        // Write your code here
+        int[] alp = new int[256];
+        char[] arr =s.toCharArray();
+
+        for(char c : arr ){
+            alp[c]++;
+        }
+
+        for(int i = 0; i < arr.length; i++){
+            if (alp[arr[i]]==1) return i;
+        }
+
+        return -1;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param s a string
+     * @return it's index
+     */
+    public int firstUniqChar(String s) {
+        // Write your code here
+        int[] cnt = new int[256];
+
+        for (char c : s.toCharArray()) {
+            cnt[c]++;
+        }
+
+        for (int i = 0; i < s.length(); i++) {
+            if (cnt[s.charAt(i)] == 1) {
+                return i;
+            }
+        }
+        return -1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/first-unique-character-in-a-string.md" "b/\351\253\230\351\242\221/first-unique-character-in-a-string.md"
new file mode 100644
index 0000000..585baa2
--- /dev/null
+++ "b/\351\253\230\351\242\221/first-unique-character-in-a-string.md"
@@ -0,0 +1,42 @@
+# 第一个只出现一次的字符
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/first-unique-character-in-a-string/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个字符串，找出第一个只出现一次的字符。
+ ### 样例说明
+ ```
+样例 1:
+	输入: "abaccdeff"
+	输出:  'b'
+	
+	解释:
+	'b' 是第一个出现一次的字符
+
+
+样例 2:
+	输入: "aabccd"
+	输出:  'b'
+	
+	解释:
+	'b' 是第一个出现一次的字符
+
+
+```
+ ### 参考代码
+ 辅助数组记录字符出现次数。
+```python
+class Solution:
+    """
+    @param str: str: the given string
+    @return: char: the first unique character in a given string
+    """
+    def firstUniqChar(self, str):
+        counter = {}
+
+        for c in str:
+            counter[c] = counter.get(c, 0) + 1
+
+        for c in str:
+            if counter[c] == 1:
+                return c
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/implement-strstr.md" "b/\351\253\230\351\242\221/implement-strstr.md"
new file mode 100644
index 0000000..ca14e66
--- /dev/null
+++ "b/\351\253\230\351\242\221/implement-strstr.md"
@@ -0,0 +1,57 @@
+# 字符串查找
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/implement-strstr/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 对于一个给定的 source 字符串和一个 target 字符串，你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在，则返回 `-1`。
+ ### 样例说明
+ **样例  1:**
+
+```
+输入: source = "source" ， target = "target"
+输出:-1	
+样例解释: 如果source里没有包含target的内容，返回-1
+```
+
+**样例 2:**
+
+```
+输入: source = "abcdabcdefg" ，target = "bcd"
+输出: 1	
+样例解释: 如果source里包含target的内容，返回target在source里第一次出现的位置
+```
+
+
+ ### 参考代码
+ Implement strStr().
+
+Returns a pointer to the first occurrence of needle in haystack, or null if needle is not part of haystack.
+```java
+class Solution {
+    /**
+     * Returns a index to the first occurrence of target in source,
+     * or -1  if target is not part of source.
+     * @param source string to be scanned.
+     * @param target string containing the sequence of characters to match.
+     */
+    public int strStr(String source, String target) {
+        if (source == null || target == null) {
+            return -1;
+        }
+        
+        for (int i = 0; i < source.length() - target.length() + 1; i++) {
+            int j = 0;
+            for (j = 0; j < target.length(); j++) {
+                if (source.charAt(i + j) != target.charAt(j)) {
+                    break;
+                }
+            }
+            // finished loop, target found
+            if (j == target.length()) {
+                return i;
+            }
+        }
+        return -1;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/integer-to-english-words.md" "b/\351\253\230\351\242\221/integer-to-english-words.md"
new file mode 100644
index 0000000..c54317d
--- /dev/null
+++ "b/\351\253\230\351\242\221/integer-to-english-words.md"
@@ -0,0 +1,36 @@
+# 整数转单词
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/integer-to-english-words/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 把一个非负整数转成英文单词的形式。给定的输入一定比`2^31-1`小。
+ ### 样例说明
+ ```
+123 -> "One Hundred Twenty Three"
+12345 -> "Twelve Thousand Three Hundred Forty Five"
+1234567 -> "One Million Two Hundred Thirty Four Thousand Five Hundred Sixty Seven"
+```
+ ### 参考代码
+ ```cpp
+class Solution {
+public:
+    string numberToWords(int num) {
+        string res = convertHundred(num % 1000);
+        vector<string> v = {"Thousand", "Million", "Billion"};
+        for (int i = 0; i < 3; ++i) {
+            num /= 1000;
+            res = num % 1000 ? convertHundred(num % 1000) + " " + v[i] + " " + res : res;
+        }
+        while (res.back() == ' ') res.pop_back();
+        return res.empty() ? "Zero" : res;
+    }
+    string convertHundred(int num) {
+        vector<string> v1 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
+        vector<string> v2 = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
+        string res;
+        int a = num / 100, b = num % 100, c = num % 10;
+        res = b < 20 ? v1[b] : v2[b / 10] + (c ? " " + v1[c] : "");
+        if (a > 0) res = v1[a] + " Hundred" + (b ? " " + res : "");
+        return res;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/integer-to-roman.md" "b/\351\253\230\351\242\221/integer-to-roman.md"
new file mode 100644
index 0000000..918a518
--- /dev/null
+++ "b/\351\253\230\351\242\221/integer-to-roman.md"
@@ -0,0 +1,61 @@
+# 整数转罗马数字
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/integer-to-roman/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数，将其转换成罗马数字。
+
+保证给定的整数在`1`到`3999`的范围内。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 1
+输出: "I"
+```
+
+**样例 2:**
+
+```
+输入: 99
+输出: "XCIX"
+```
+ ### 参考代码
+ 根据罗马数字的计数规则进行转换即可.
+```java
+public class Solution {
+	public String intToRoman(int num) {
+		if(num <= 0) {
+			return "";
+		}
+	    int[] nums = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
+	    String[] symbols = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
+	    StringBuilder res = new StringBuilder();
+	    int digit=0;
+	    while (num > 0) {
+	        int times = num / nums[digit];
+	        num -= nums[digit] * times;
+	        for ( ; times > 0; times--) {
+	            res.append(symbols[digit]);
+	        }
+	        digit++;
+	    }
+	    return res.toString();
+	}
+}
+
+/////////////// version: 高频题班
+
+public class Solution {
+    /**
+     * @param n The integer
+     * @return Roman representation
+     */
+    public String intToRoman(int n) {
+        String M[] = {"", "M", "MM", "MMM"};
+        String C[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
+        String X[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
+        String I[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
+        return M[n / 1000] + C[(n / 100) % 10] + X[(n / 10) % 10] + I[n % 10];
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/is-subsequence.md" "b/\351\253\230\351\242\221/is-subsequence.md"
new file mode 100644
index 0000000..7367574
--- /dev/null
+++ "b/\351\253\230\351\242\221/is-subsequence.md"
@@ -0,0 +1,36 @@
+# 是子序列吗？
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/is-subsequence/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定字符串`s`和`t`，判断`s`是否为`t`的子序列。
+
+你可以认为在`s`和`t`中都只包含小写字母。`t`可能是一个非常长（`length ~= 500,000`）的字符串，而`s`是一个较短的字符串（`length <= 100`）。
+
+一个字符串的子序列是在原字符串中删去一些字符（也可以不删除）后，不改变剩余字符的相对位置形成的新字符串（例如，`"ace"`是`"abcde"`的子序列而`"aec"`不是）。
+ ### 样例说明
+ **样例1：**
+```
+输入：s = "abc"，t = "ahbgdc"
+输出：true
+```
+**样例2：**
+```
+输入：s = "axc"，t = "ahbgdc"
+输出：false
+```
+ ### 参考代码
+ 直接按s串的顺序去遍历t串即可。
+```java
+public class Solution {
+    public boolean isSubsequence(String s, String t) {
+        int i = 0, j = 0;
+        while(i<s.length() && j < t.length()) {
+            if(s.charAt(i) == t.charAt(j)) {
+                i++;
+            }
+            j++;
+        }
+        return i == s.length();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/left-pad.md" "b/\351\253\230\351\242\221/left-pad.md"
new file mode 100644
index 0000000..26d8855
--- /dev/null
+++ "b/\351\253\230\351\242\221/left-pad.md"
@@ -0,0 +1,58 @@
+# 左填充
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/left-pad/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个leftpad库，如果不知道什么是leftpad可以看样例
+ ### 样例说明
+ 例1:
+```
+输入:
+leftpad("foo", 5)
+输出:
+"  foo"
+```
+例2:
+```
+输入:
+leftpad("foobar", 6)
+输出:
+"foobar"
+```
+例3:
+```
+输入:
+leftpad("1", 2, "0")
+输出:
+"01"
+```
+
+ ### 参考代码
+ 按要求填充即可
+```java
+public class StringUtils {
+    /**
+     * @param originalStr the string we want to append to with spaces
+     * @param size the target length of the string
+     * @return a string
+     */
+    static public String leftPad(String originalStr, int size) {
+        // Write your code here
+        return leftPad(originalStr, size, ' ');
+    }
+
+    /**
+     * @param originalStr the string we want to append to
+     * @param size the target length of the string
+     * @param padChar the character to pad to the left side of the string
+     * @return a string
+     */
+    static public String leftPad(String originalStr, int size, char padChar) {
+        // Write your code here
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < size - originalStr.length(); ++i)
+            sb.append(padChar);
+        sb.append(originalStr);
+        return sb.toString();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/length-of-last-word.md" "b/\351\253\230\351\242\221/length-of-last-word.md"
new file mode 100644
index 0000000..b47de43
--- /dev/null
+++ "b/\351\253\230\351\242\221/length-of-last-word.md"
@@ -0,0 +1,54 @@
+# 最后一个单词的长度
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/length-of-last-word/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串， 包含大小写字母、空格 `' '`，请返回其最后一个单词的长度。
+
+如果不存在最后一个单词，请返回 `0` 。
+ ### 样例说明
+ 
+**样例 1：**
+```
+输入："Hello World"
+输出：5
+```
+**样例 2：**
+```
+输入："Hello LintCode"
+输出：8
+```
+ ### 参考代码
+ Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the length of last word in the string.
+
+If the last word does not exist, return 0.
+
+Note: A word is defined as a character sequence consists of non-space characters only.
+
+For example, 
+Given s = "Hello World",
+return 5.
+```java
+public class Solution {
+    public int lengthOfLastWord(String s) {
+        int length = 0;
+        char[] chars = s.toCharArray();
+        for (int i = s.length() - 1; i >= 0; i--) {
+            if (length == 0) {
+                if (chars[i] == ' ') {
+                    continue;
+                } else {
+                    length++;
+                }
+            } else {
+                if (chars[i] == ' ') {
+                    break;
+                } else {
+                    length++;
+                }
+            }
+        }
+
+        return length;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/longest-common-prefix.md" "b/\351\253\230\351\242\221/longest-common-prefix.md"
new file mode 100644
index 0000000..7cb913b
--- /dev/null
+++ "b/\351\253\230\351\242\221/longest-common-prefix.md"
@@ -0,0 +1,48 @@
+# 最长公共前缀
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-common-prefix/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给k个字符串，求出他们的最长公共前缀(LCP)</p>
+ ### 样例说明
+ ```
+样例 1:
+	输入:  "ABCD", "ABEF", "ACEF"
+	输出:  "A"
+	
+
+样例 2:
+	输入: "ABCDEFG", "ABCEFG" and "ABCEFA"
+	输出:  "ABC"
+
+```
+ ### 参考代码
+ Write a function to find the longest common prefix string amongst an array of strings.
+
+
+直接模拟比较即可。
+```java
+public class Solution {
+    
+    // 1. Method 1, start from the first one, compare prefix with next string, until end;
+    // 2. Method 2, start from the first char, compare it with all string, and then the second char
+    // I am using method 1 here
+    public String longestCommonPrefix(String[] strs) {
+        if (strs == null || strs.length == 0) {
+            return "";
+        }
+        String prefix = strs[0];
+        for(int i = 1; i < strs.length; i++) {
+            int j = 0;
+            while( j < strs[i].length() && j < prefix.length() && strs[i].charAt(j) == prefix.charAt(j)) {
+                j++;
+            }
+            if( j == 0) {
+                return "";
+	    }
+            prefix = prefix.substring(0, j);
+        }
+        return prefix;
+    }
+
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/longest-common-substring.md" "b/\351\253\230\351\242\221/longest-common-substring.md"
new file mode 100644
index 0000000..6150ead
--- /dev/null
+++ "b/\351\253\230\351\242\221/longest-common-substring.md"
@@ -0,0 +1,76 @@
+# 最长公共子串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-common-substring/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>给出两个字符串，找到最长公共子串，并返回其长度。</p><p><br></p>
+ ### 样例说明
+ 
+```
+样例 1:
+	输入:  "ABCD" and "CBCE"
+	输出:  2
+	
+	解释:
+	最长公共子串是 "BC"
+
+
+样例 2:
+	输入: "ABCD" and "EACB"
+	输出:  1
+	
+	解释: 
+	最长公共子串是 'A' 或 'C' 或 'B'
+```
+ ### 参考代码
+ http://www.lintcode.com/en/problem/longest-common-substring/
+
+Given two strings, find the longest common substring.
+
+Return the length of it.
+
+Note
+The characters in substring should occur continiously in original string. This is different with subsequnce.
+
+
+Dp[i][j] 表示A的前i个字符与B的前j个字符中，且以第i个和第j个为结尾的公共子串的长度。
+暴力枚举所有的结尾。
+```java
+// 严格的说，这个算法是递推，而不是动态规划，但是可以用动态规划的四要素去分析换个解答。
+// 为什么不是动态规划？因为最暴力的方式也就是 O(n^3) 可以找到A所有的Substring然后看看在不在B里。
+public class Solution {
+    /**
+     * @param A, B: Two string.
+     * @return: the length of the longest common substring.
+     */
+    public int longestCommonSubstring(String A, String B) {
+        // state: f[i][j] is the length of the longest lcs
+        // ended with A[i - 1] & B[j - 1] in A[0..i-1] & B[0..j-1]
+        int n = A.length();
+        int m = B.length();
+        int[][] f = new int[n + 1][m + 1];
+        
+        // initialize: f[i][j] is 0 by default
+        
+        // function: f[i][j] = f[i - 1][j - 1] + 1 or 0
+        for (int i = 1; i <= n; i++) {
+            for (int j = 1; j <= m; j++) {
+                if (A.charAt(i - 1) == B.charAt(j - 1)) {
+                    f[i][j] = f[i - 1][j - 1] + 1;
+                } else {
+                    f[i][j] = 0;
+                }
+            }
+        }
+        
+        // answer: max{f[i][j]}
+        int max = 0;
+        for (int i = 1; i <= n; i++) {
+            for (int j = 1; j <= m; j++) {
+                max = Math.max(max, f[i][j]);
+            }
+        }
+        
+        return max;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/longest-palindromic-substring.md" "b/\351\253\230\351\242\221/longest-palindromic-substring.md"
new file mode 100644
index 0000000..a368c0f
--- /dev/null
+++ "b/\351\253\230\351\242\221/longest-palindromic-substring.md"
@@ -0,0 +1,77 @@
+# 最长回文子串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-palindromic-substring/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个字符串（假设长度最长为1000），求出它的最长回文子串，你可以假定只有一个满足条件的最长回文串。
+ ### 样例说明
+ **样例 1:**
+```
+输入:"abcdzdcab"
+输出:"cdzdc"
+```
+**样例 2:**
+```
+输入:"aba"
+输出:"aba"
+```
+ ### 参考代码
+ 基于中心点枚举的算法，时间复杂度 O(n^2)
+```
+[[java]]
+public class Solution {
+    public String longestPalindrome(String s) {
+        if (s == null || s.length() == 0) {
+            return "";
+        }
+        
+        int start = 0, len = 0, longest = 0;
+        for (int i = 0; i < s.length(); i++) {
+            len = findLongestPalindromeFrom(s, i, i);
+            if (len > longest) {
+                longest = len;
+                start = i - len / 2;
+            }
+            
+            len = findLongestPalindromeFrom(s, i, i + 1);
+            if (len > longest) {
+                longest = len;
+                start = i - len / 2 + 1;
+            }
+        }
+        
+        return s.substring(start, start + longest);
+    }
+    
+    private int findLongestPalindromeFrom(String s, int left, int right) {
+        int len = 0;
+        while (left >= 0 && right < s.length()) {
+            if (s.charAt(left) != s.charAt(right)) {
+                break;
+            }
+            len += left == right ? 1 : 2;
+            left--;
+            right++;
+        }
+        
+        return len;
+    }
+}
+[[python]]
+class Solution:
+    def longestPalindrome(self, s):
+        if not s:
+            return ""
+            
+        answer = (0, 0)
+        for mid in range(len(s)):
+            answer = max(answer, self.get_palindrom_from(s, mid, mid))
+            answer = max(answer, self.get_palindrom_from(s, mid, mid + 1))
+        
+        return s[answer[1]: answer[0] + answer[1]]    
+        
+    def get_palindrom_from(self, s, left, right):
+        while left >= 0 and right < len(s) and s[left] == s[right]:
+            left -= 1
+            right += 1
+        return (right - left - 1, left + 1)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/longest-substring-with-at-least-k-repeating-characters.md" "b/\351\253\230\351\242\221/longest-substring-with-at-least-k-repeating-characters.md"
new file mode 100644
index 0000000..31d5ea3
--- /dev/null
+++ "b/\351\253\230\351\242\221/longest-substring-with-at-least-k-repeating-characters.md"
@@ -0,0 +1,67 @@
+# 字符至少出现K次的最长子串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-substring-with-at-least-k-repeating-characters/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 找出给定字符串的最长子串，使得该子串中的每一个字符都出现了至少k次，返回这个子串的长度。
+
+
+ ### 样例说明
+ **样例1：**
+~~~~.
+输入：
+s = "aaabb", k = 3
+输出：
+3
+解释：
+最长子串为"aaa"，因为'a'重复了3次。
+~~~~
+**样例2：**
+~~~~.
+输入：
+s = "ababbc", k = 2
+输出：
+5
+解释：
+最长子串为"ababb"，因为'a'重复了2次，同时'b'重复了3次。
+~~~~
+ ### 参考代码
+ 贪心法 + 递归。
+如果一个字符出现次数 < k 说明最长的要么在它左边，要么在它右边（不可能跨过他），从它拆开往下递归计算即可。
+```java
+class Solution {
+    public int longestSubstring(String s, int k) {
+        HashMap<Character, Integer> counter = getCharCounter(s);
+        
+        int left = 0;
+        int longest = 0;
+        for (int i = 0; i < s.length(); i++) {
+            if (counter.get(s.charAt(i)) < k) {
+                int sub_longest = longestSubstring(s.substring(left, i), k);
+                longest = Math.max(longest, sub_longest);
+                left = i + 1;
+            }
+        }
+        
+        if (left == 0) {
+            return s.length();
+        }
+        
+        int sub_longest = longestSubstring(s.substring(left, s.length()), k);
+        longest = Math.max(longest, sub_longest);
+        
+        return longest;
+    }
+    
+    private HashMap<Character, Integer> getCharCounter(String s) {
+        HashMap<Character, Integer> counter = new HashMap<>();
+        
+        for (int i = 0; i < s.length(); i++) {
+            Character c = s.charAt(i);
+            Integer val = counter.getOrDefault(c, 0);
+            counter.put(c, val + 1);
+        }
+        
+        return counter;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/longest-words.md" "b/\351\253\230\351\242\221/longest-words.md"
new file mode 100644
index 0000000..564a66a
--- /dev/null
+++ "b/\351\253\230\351\242\221/longest-words.md"
@@ -0,0 +1,27 @@
+# 最长单词
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/longest-words/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个词典，找出其中所有最长的单词。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+class Solution {
+    /**
+     * @param dictionary: an array of strings
+     * @return: an arraylist of strings
+     */
+    ArrayList<String> longestWords(String[] dictionary) {
+        // write your code here
+        int maxLen = 0;
+        ArrayList<String> ans = new ArrayList<String>();
+        for (int i=0; i<dictionary.length; ++i) 
+            if (dictionary[i].length()>maxLen) maxLen = dictionary[i].length();
+        for (int i=0; i<dictionary.length; ++i)
+            if (dictionary[i].length()==maxLen) ans.add(dictionary[i]);
+        return ans;
+    }
+};
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/lowercase-to-uppercase-ii.md" "b/\351\253\230\351\242\221/lowercase-to-uppercase-ii.md"
new file mode 100644
index 0000000..04dc437
--- /dev/null
+++ "b/\351\253\230\351\242\221/lowercase-to-uppercase-ii.md"
@@ -0,0 +1,45 @@
+# 大小写转换 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/lowercase-to-uppercase-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一个字符串中的小写字母转换为大写字母。不是字母的字符不需要做改变。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: str = "abc"
+输出: "ABC"
+```
+**样例 2:**
+
+```
+输入: str = "aBc"
+输出: "ABC"
+```
+**样例 3:**
+
+```
+输入: str = "abC12"
+输出: "ABC12"
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param str a string
+     * @return a string
+     */
+    public String lowercaseToUppercase2(String str) {
+        // Write your code here
+        StringBuilder sb = new StringBuilder(str);
+        //遍历整个字符串，将所有的小写字母转成大写字母
+        for (int index = 0; index < sb.length(); index++) {
+            char c = sb.charAt(index);
+            if (Character.isLowerCase(c)) {
+                sb.setCharAt(index, Character.toUpperCase(c));
+            }
+        }
+        return sb.toString();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/lowercase-to-uppercase.md" "b/\351\253\230\351\242\221/lowercase-to-uppercase.md"
new file mode 100644
index 0000000..f706b62
--- /dev/null
+++ "b/\351\253\230\351\242\221/lowercase-to-uppercase.md"
@@ -0,0 +1,32 @@
+# 大小写转换
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/lowercase-to-uppercase/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一个字符由小写字母转换为大写字母
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 'a'
+输出: 'A'
+```
+**样例 2:**
+
+```
+输入: 'b'
+输出: 'B'
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param character a character
+     * @return a character
+     */
+    public char lowercaseToUppercase(char character) {
+        // Write your code here
+        //获得character与'a'的差值，在'A'的基础上加上这个差值
+        return (char)(character - 'a' + 'A');
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/lru-cache.md" "b/\351\253\230\351\242\221/lru-cache.md"
new file mode 100644
index 0000000..ded797d
--- /dev/null
+++ "b/\351\253\230\351\242\221/lru-cache.md"
@@ -0,0 +1,139 @@
+# LRU缓存策略
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/lru-cache/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 为最近最少使用（LRU）缓存策略设计一个数据结构，它应该支持以下操作：获取数据和写入数据。
+
+- `get(key)` 获取数据：如果缓存中存在key，则获取其数据值（通常是正数），否则返回-1。
+- `set(key, value)` 写入数据：如果key还没有在缓存中，则写入其数据值。当缓存达到上限，它应该在写入新数据之前删除最近最少使用的数据用来腾出空闲位置。
+
+最终, 你需要返回每次 `get` 的数据.
+ ### 样例说明
+ **样例 1:**
+```
+输入：
+LRUCache(2)
+set(2, 1)
+set(1, 1)
+get(2)
+set(4, 1)
+get(1)
+get(2)
+输出：[1,-1,1]
+解释：
+cache上限为2，set(2,1)，set(1, 1)，get(2) 然后返回 1，set(4,1) 然后 delete (1,1)，因为 （1,1）最少使用，get(1) 然后返回 -1，get(2) 然后返回 1。
+```
+
+**样例 2:**
+```
+输入：
+LRUCache(1)
+set(2, 1)
+get(2)
+set(3, 2)
+get(2)
+get(3)
+输出：[1,-1,2]
+解释：
+cache上限为 1，set(2,1)，get(2) 然后返回 1，set(3,2) 然后 delete (2,1)，get(2) 然后返回 -1，get(3) 然后返回 2。
+```
+ ### 参考代码
+ Singly Linked List 的版本
+```
+[[java]]
+public class LRUCache {
+    class ListNode {
+        public int key, val;
+        public ListNode next;
+        
+        public ListNode(int key, int val) {
+            this.key = key;
+            this.val = val;
+            this.next = null;
+        }
+    }
+    
+    private int capacity, size;
+    private ListNode dummy, tail;
+    private Map<Integer, ListNode> keyToPrev;
+
+    /*
+    * @param capacity: An integer
+    */
+    public LRUCache(int capacity) {
+        this.capacity = capacity;
+        this.keyToPrev = new HashMap<Integer, ListNode>();
+        this.dummy = new ListNode(0, 0);
+        this.tail = this.dummy;
+    }
+
+    private void moveToTail(int key) {
+        ListNode prev = keyToPrev.get(key);
+        ListNode curt = prev.next;
+        
+        if (tail == curt) {
+            return;
+        }
+        
+        prev.next = prev.next.next;
+        tail.next = curt;
+        curt.next = null;
+        
+        if (prev.next != null) {
+            keyToPrev.put(prev.next.key, prev);
+        }
+        keyToPrev.put(curt.key, tail);
+        
+        tail = curt;
+    }
+    
+    /*
+     * @param key: An integer
+     * @return: An integer
+     */
+    public int get(int key) {
+        if (!keyToPrev.containsKey(key)) {
+            return -1;
+        }
+        
+        moveToTail(key);
+        
+        // the key has been moved to the end
+        return tail.val;
+    }
+    
+    /*
+     * @param key: An integer
+     * @param value: An integer
+     * @return: nothing
+     */
+    public void set(int key, int value) {
+        // get method will move the key to the end of the linked list
+        if (get(key) != -1) {
+            ListNode prev = keyToPrev.get(key);
+            prev.next.val = value;
+            return;
+        }
+        
+        if (size < capacity) {
+            size++;
+            ListNode curt = new ListNode(key, value);
+            tail.next = curt;
+            keyToPrev.put(key, tail);
+            
+            tail = curt;
+            return;
+        }
+        
+        // replace the first node with new key, value
+        ListNode first = dummy.next;
+        keyToPrev.remove(first.key);
+        
+        first.key = key;
+        first.val = value;
+        keyToPrev.put(key, dummy);
+        
+        moveToTail(key);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/mini-twitter.md" "b/\351\253\230\351\242\221/mini-twitter.md"
new file mode 100644
index 0000000..9397b61
--- /dev/null
+++ "b/\351\253\230\351\242\221/mini-twitter.md"
@@ -0,0 +1,169 @@
+# 迷你推特
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/mini-twitter/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个迷你的推特，支持下列几种方法
+
+1. `postTweet(user_id, tweet_text).` 发布一条推特.
+2. `getTimeline(user_id).` 获得给定用户最新发布的十条推特，按照发布时间从最近的到之前排序
+3. `getNewsFeed(user_id).` 获得给定用户的朋友或者他自己发布的最新十条推特，从发布时间最近到之前排序
+4. `follow(from_user_id, to_user_id).` from_user_id 关注 to_user_id.
+5. `unfollow(from_user_id, to_user_id).` from_user_id 取消关注 to_user_id.
+ ### 样例说明
+ 
+ ### 参考代码
+ 因为题目里涉及到对推文按照时间排序, 同时 Tweet 类本身不含时间信息, 所以我们需要额外地记录每条推文发出的时间.
+
+可以定义一个类的静态变量作为计数器来实现.
+
+然后分析我们需要的数据结构:
+
+- `class Node {Tweet, int};` 对原有的Tweet类的扩展, 使其可以记录时间 (当然, 也可以用类的继承来实现)
+- `map<int, vector<Node>>` 用户id到这个用户发送了的推文的映射
+- `map<int, set<int>>` 用户id到这个用户关注的人的id的映射
+
+然后对应每种方法的实现:
+
+- `postTweet()` 直接添加到`map<int, vector<Node>>`中即可
+- `getTimeline()` 根据`map<int, vector<Node>>`获得该用户的最新推文, 返回即可
+- `getNewsFeed()` 同时用到上面定义的两个映射, 比较暴力的做法是获取这些用户的所有推文, 排序, 拿出前十个; 或者可以利用堆进行 "多路归并"
+- `follow()` 在 `map<int, set<int>>` 中添加即可
+- `unfollow()` 在 `map<int, set<int>>` 中删除即可
+
+(本题解使用C++相关数据结构描述, 不过映射和集合在其他语言中也有对应的实现)
+```java
+/**
+ * Definition of Tweet:
+ * public class Tweet {
+ *     public int id;
+ *     public int user_id;
+ *     public String text;
+ *     public static Tweet create(int user_id, String tweet_text) {
+ *         // This will create a new tweet object,
+ *         // and auto fill id
+ *     }
+ * }
+ */
+public class MiniTwitter {
+    class Node {
+        public int order;
+        public Tweet tweet;
+
+        public Node(int o, Tweet t) {
+            this.order = o;
+            this.tweet = t;
+        }
+    }
+
+    class SortByOrder implements Comparator {
+        public int compare(Object obj1, Object obj2) {
+            Node node1 = (Node) obj1;
+            Node node2 = (Node) obj2;
+            if (node1.order < node2.order)
+                return 1;
+            else
+                return -1;
+        }
+    }
+
+    private Map<Integer, Set<Integer>> friends;
+    private Map<Integer, List<Node>> users_tweets;
+    private int order;
+
+    public List<Node> getLastTen(List<Node> tmp) {
+        int last = 10;
+        if (tmp.size() < 10)
+            last = tmp.size();
+        return tmp.subList(tmp.size() - last, tmp.size());
+    }
+
+    public List<Node> getFirstTen(List<Node> tmp) {
+        int last = 10;
+        if (tmp.size() < 10)
+            last = tmp.size();
+        return tmp.subList(0, last);
+    }
+
+    public MiniTwitter() {
+        // initialize your data structure here.
+        this.friends = new HashMap<Integer, Set<Integer>>();
+        this.users_tweets = new HashMap<Integer, List<Node>>();
+        this.order = 0;
+    }
+
+    // @param user_id an integer
+    // @param tweet a string
+    // return a tweet
+    public Tweet postTweet(int user_id, String tweet_text) {
+        // Write your code here
+        Tweet tweet = Tweet.create(user_id, tweet_text);
+        if (!users_tweets.containsKey(user_id))
+            users_tweets.put(user_id, new ArrayList<Node>());
+        order += 1;
+        users_tweets.get(user_id).add(new Node(order, tweet));
+        return tweet;
+    }
+
+    // @param user_id an integer
+    // return a list of 10 new feeds recently
+    // and sort by timeline
+    public List<Tweet> getNewsFeed(int user_id) {
+        // Write your code here
+        List<Node> tmp = new ArrayList<Node>();
+        if (users_tweets.containsKey(user_id))
+            tmp.addAll(getLastTen(users_tweets.get(user_id)));
+
+        if (friends.containsKey(user_id)) {
+            for (Integer user : friends.get(user_id)) {
+                if (users_tweets.containsKey(user))
+                    tmp.addAll(getLastTen(users_tweets.get(user)));
+            }
+        }
+
+        Collections.sort(tmp, new SortByOrder());
+        List<Tweet> rt = new ArrayList<Tweet>();
+        tmp = getFirstTen(tmp);
+        for (Node node : tmp) {
+            rt.add(node.tweet);
+        }
+        return rt;
+    }
+
+    // @param user_id an integer
+    // return a list of 10 new posts recently
+    // and sort by timeline
+    public List<Tweet> getTimeline(int user_id) {
+        // Write your code here
+        List<Node> tmp = new ArrayList<Node>();
+        if (users_tweets.containsKey(user_id))
+            tmp.addAll(getLastTen(users_tweets.get(user_id)));
+
+        Collections.sort(tmp, new SortByOrder());
+        List<Tweet> rt = new ArrayList<Tweet>();
+        tmp = getFirstTen(tmp);
+        for (Node node : tmp)
+            rt.add(node.tweet);
+        return rt;
+    }
+
+    // @param from_user_id an integer
+    // @param to_user_id an integer
+    // from user_id follows to_user_id
+    public void follow(int from_user_id, int to_user_id) {
+        // Write your code here
+        if (!friends.containsKey(from_user_id))
+            friends.put(from_user_id, new HashSet<Integer>());
+
+        friends.get(from_user_id).add(to_user_id);
+    }
+
+    // @param from_user_id an integer
+    // @param to_user_id an integer
+    // from user_id unfollows to_user_id
+    public void unfollow(int from_user_id, int to_user_id) {
+        // Write your code here
+        if (friends.containsKey(from_user_id))
+            friends.get(from_user_id).remove(to_user_id);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/mini-yelp.md" "b/\351\253\230\351\242\221/mini-yelp.md"
new file mode 100644
index 0000000..8319a65
--- /dev/null
+++ "b/\351\253\230\351\242\221/mini-yelp.md"
@@ -0,0 +1,163 @@
+# 迷你Yelp
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/mini-yelp/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个小的Yelp系统支持下列操作
+1.添加一个新餐馆的名字和地址
+2.去除一个餐馆
+3.在给定地点找一个临近的餐馆
+
+临近餐馆是指距离小于 k km
+
+Restaurant类已近建立好了并且有`Restaurant.create()` 和`Helper.get_distance(location1, location2)`两个函数可以使用.
+
+GeoHash类也已经提供了`GeoHash.encode(location)`和`GeoHash.decode(string)`可以帮助转换地址
+ ### 样例说明
+ **样例1**
+
+```plain
+输入:
+addRestaurant("Lint Cafe", 10.4999999, 11.599999)
+addRestaurant("Code Cafe", 10.4999999, 11.512109)
+neighbors(10.5, 11.6, 6.7)
+neighbors(10.5, 9.6, 6.7)
+
+输出:
+1
+2
+["Lint Cafe"]
+[]
+
+说明:
+当我们添加两个饭店的时候，我们返回1和2
+当查找饭店的时候第一次我们找到Lint Cafe，第二次什么都找不到
+```
+
+**样例 2**
+
+```plain
+输入:
+addRestaurant("Lint Cafe", 10.4999999, 11.599999)
+addRestaurant("Code Cafe", 10.4999999, 11.512109)
+neighbors(10.5, 11.6, 6.7)
+removeRestaurant(1)
+neighbors(10.5, 11.6, 6.7)
+
+输出:
+1
+2
+["Lint Cafe"]
+[]
+
+说明：
+当第二次查找饭店的时候，Lint Cafe已经被删除了
+```
+
+
+ ### 参考代码
+ ```python
+'''
+Definition of Location:
+class Location:
+    # @param {double} latitude, longitude
+    # @param {Location}
+    @classmethod
+    def create(cls, latitude, longitude):
+        # This will create a new location object
+
+Definition of Restaurant:
+class Restaurant:
+    # @param {str} name
+    # @param {Location} location
+    # @return {Restaurant}
+    @classmethod
+    def create(cls, name, location):
+        # This will create a new restaurant object,
+        # and auto fill id
+
+Definition of Helper
+class Helper:
+    # @param {Location} location1, location2
+    @classmethod
+    def get_distance(cls, location1, location2):
+        # return calculate the distance between two location
+
+Definition of GeoHash
+class GeoHash:
+    # @param {Location} location
+    # @return a string
+    @classmethom
+    def encode(cls, location):
+        # return convert location to a geohash string
+    
+    # @param {str} hashcode
+    # @return {Location}
+    @classmethod
+    def decode(cls, hashcode):
+        # return convert a geohash string to location
+'''
+import bisect
+from YelpHelper import Location, Restaurant, GeoHash, Helper
+
+class MiniYelp:
+
+    def __init__(self):
+        # initialize your data structure here.
+        self.restaurants = {}
+        self.ids = {}
+        self.geo_value  = []
+
+    # @param {str} name
+    # @param {Location} location
+    # @return {int} restaurant's id
+    def add_restaurant(self, name, location):
+        # Write your code here
+        restaurant = Restaurant.create(name, location)
+        hashcode = "%s.%s" % (GeoHash.encode(location), restaurant.id)
+        bisect.insort(self.geo_value, hashcode)
+        self.restaurants[hashcode] = restaurant
+        self.ids[restaurant.id] = hashcode
+        return restaurant.id
+
+    # @param {int} restaurant_id
+    # @return nothing
+    def remove_restaurant(self, restaurant_id):
+        # Write your code here
+        hashcode = self.ids[restaurant_id]
+        index = bisect.bisect_left(self.geo_value, hashcode)
+        self.geo_value.pop(index)
+        del self.restaurants[hashcode]
+        del self.ids[restaurant_id]
+
+    # @param {Location} location
+    # @param {double} k, distance smaller than k miles
+    # @return a list of restaurant's name and sort by 
+    # distance from near to far.
+    def neighbors(self, location, k):
+        # Write your code here
+        length = self.get_length(k)
+        hashcode = GeoHash.encode(location)[0:length]
+        left = bisect.bisect_left(self.geo_value, hashcode)
+        right = bisect.bisect_right(self.geo_value, hashcode + '{')
+
+        results = []
+        # print left, right, hashcode
+        for index in range(left, right):
+            hashcode = self.geo_value[index]
+            restaurant = self.restaurants[hashcode]
+            distance = Helper.get_distance(location, restaurant.location)
+            if  distance <= k:
+                results.append((distance, restaurant))
+
+        results = sorted(results, key=lambda obj: obj[0])
+        return [rt[1].name for rt in results]
+
+    def get_length(self, k):
+        ERROR = [2500, 630, 78, 20, 2.4, 0.61, 0.076, 0.01911, 0.00478, 0.0005971, 0.0001492, 0.0000186]
+        for i, error in enumerate(ERROR):
+            if k  > error:
+                return i
+
+        return len(ERROR)
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/monochrome-screen.md" "b/\351\253\230\351\242\221/monochrome-screen.md"
new file mode 100644
index 0000000..9a08b5f
--- /dev/null
+++ "b/\351\253\230\351\242\221/monochrome-screen.md"
@@ -0,0 +1,84 @@
+# 黑白屏
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/monochrome-screen/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 一个黑白显示屏由一个单独的字节数组组成，这个屏幕允许 8 个连续像素由一个字节进行存储。该显示屏宽 w ，被分割为 8 （也就是说，任意字节都不可能被行切断）。该显示屏高，则取决于数组的长度及显示屏的宽。请设计一个函数 `drawHorizontalLine(byte[] screen, int width, int x1, int x2, int y)` 从(x1, y) 到 (x2, y) 画出一条水平线。
+ ### 样例说明
+ **样例1**
+```plain
+输入:
+初始屏幕 = [0]
+屏宽 = 8
+x1 = 0
+x2 = 7 
+y = 0
+输出: [255]
+样例解释:
+[0] 意味着一开始屏幕的二进制表示是 00000000。你需要把他转换为 [255](11111111)
+```
+
+**样例2**
+```plain
+输入:
+初始屏幕 = [0,0,0,0]
+屏宽 = 16
+x1 = 5
+x2 = 11 
+y = 1
+输出: [0,0,7,240]
+样例解释:
+[0,0,0,0] 意味着初始屏幕的第一行是 00000000,00000000 ，第二行是 00000000,00000000。你需要把他转换为[0,0,7,240](00000000,00000000,00000111,11110000)
+```
+ ### 参考代码
+ 此题按照题目要求，找到起始点和终点在屏幕表示里的位置，然后再对应的二进制里面进行修改即可。
+```java
+public class Solution {
+    /**
+     * @param screen an array of 8bit integer(byte)
+     * @param width the width of screen
+     * @param x1 an integer
+     * @param x2 an integer
+     * @param y an integer
+     * @return nothing
+     */
+    public void drawHorizontalLine(byte[] screen, int width, int x1, int x2, int y) {
+        // Write your code here
+        //找到起始点和终点的对应区域范围
+        int start_offset = x1 % 8;
+        int first_full_byte = x1 / 8;
+        if (start_offset != 0) {
+            first_full_byte++;
+        }
+        
+        int end_offset = x2 % 8;
+        int last_full_byte = x2 / 8;
+        if (end_offset != 7) {
+            last_full_byte--;
+        }
+
+        // Set full bytes
+        for (int b = first_full_byte; b <= last_full_byte; b++) {
+            screen[(width / 8) * y + b] = (byte) 0xFF;
+        }
+
+        // Create masks for start and end of line
+        byte start_mask = (byte) (0xFF >> start_offset);
+        byte end_mask = (byte) ~(0xFF >> (end_offset +1));
+        // Set start and end of line
+        if ((x1 / 8) == (x2 / 8)) { // x1 and x2 are in the same byte
+            byte mask = (byte) (start_mask & end_mask);
+            screen[(width / 8) * y + (x1 / 8)] |= mask;
+        } else {
+            if (start_offset != 0) {
+                int byte_number = (width / 8) * y + first_full_byte - 1;
+                screen[byte_number] |= start_mask;
+            }
+
+            if (end_offset != 7) {
+                int byte_number = (width / 8) * y + last_full_byte + 1;
+                screen[byte_number] |= end_mask;
+            }
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/multiply-strings.md" "b/\351\253\230\351\242\221/multiply-strings.md"
new file mode 100644
index 0000000..5e31a0a
--- /dev/null
+++ "b/\351\253\230\351\242\221/multiply-strings.md"
@@ -0,0 +1,69 @@
+# 大整数乘法
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/multiply-strings/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 以字符串的形式给定两个非负整数 `num1` 和 `num2`，返回 `num1` 和 `num2` 的乘积。
+ ### 样例说明
+ **样例1**
+```
+输入：
+"123"
+"45"
+输出：
+"5535"
+解释：
+123 x 45 = 5535
+```
+**样例2**
+```
+输入：
+"0"
+"0"
+输出：
+"0"
+```
+ ### 参考代码
+ Given two numbers represented as strings, return multiplication of the numbers as a string.
+
+Note: The numbers can be arbitrarily large and are non-negative.
+
+模拟竖式的计算过程来计算结果。
+```java
+public class Solution {
+    public String multiply(String num1, String num2) {
+        if (num1 == null || num2 == null) {
+            return null;
+        }
+        
+        int len1 = num1.length(), len2 = num2.length();
+        int len3 = len1 + len2;
+        int i, j, product, carry;
+
+        int[] num3 = new int[len3];
+        for (i = len1 - 1; i >= 0; i--) {
+            carry = 0;
+            for (j = len2 - 1; j >= 0; j--) {
+                product = carry + num3[i + j + 1] +
+                    Character.getNumericValue(num1.charAt(i)) *
+                    Character.getNumericValue(num2.charAt(j));
+                num3[i + j + 1] = product % 10;
+                carry = product / 10;
+            }
+            num3[i + j + 1] = carry;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        i = 0;
+
+        while (i < len3 - 1 && num3[i] == 0) {
+            i++;
+        }
+
+        while (i < len3) {
+            sb.append(num3[i++]);
+        }
+
+        return sb.toString();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/null-terminated-string.md" "b/\351\253\230\351\242\221/null-terminated-string.md"
new file mode 100644
index 0000000..4ce403b
--- /dev/null
+++ "b/\351\253\230\351\242\221/null-terminated-string.md"
@@ -0,0 +1,34 @@
+# NULL 结尾的字符串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/null-terminated-string/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 用 C 或 C++ 设计一个 void reverse `(char* str)` 功能，实现把一个以 NULL 结尾字符串翻转的功能。
+ ### 样例说明
+ 
+ ### 参考代码
+ 首尾双指针，依次交换，直至相遇。
+```cpp
+class Solution {
+public:
+    /**
+     * @param str C-String
+     * @return void
+     */
+    void reverse(char *str) {
+        // Write your code here
+        char * end = str;
+        char tmp;
+        if (str) {
+            while (*end != NULL) {
+                ++end;
+            }
+        }
+        --end;
+        while (str < end) {
+            tmp = *str;
+            *str++ = *end;
+            *end-- = tmp;
+        }
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/palindrome-number.md" "b/\351\253\230\351\242\221/palindrome-number.md"
new file mode 100644
index 0000000..1d187d9
--- /dev/null
+++ "b/\351\253\230\351\242\221/palindrome-number.md"
@@ -0,0 +1,47 @@
+# 回文数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/palindrome-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 判断一个正整数是不是回文数。
+
+回文数的定义是，将这个数反转之后，得到的数仍然是同一个数。
+ ### 样例说明
+ 例1：
+```
+输入：11
+输出：true
+
+```
+例2：
+```
+输入：1232
+输出：false
+解释：
+1232!=2321
+```
+ ### 参考代码
+ Determine whether an integer is a palindrome. Do this without extra space.&nbsp;<div><br></div><div>Some hints:&nbsp;</div><div>Could negative integers be palindromes? (ie, -1)&nbsp;</div><div>&nbsp;If you are thinking of converting the integer to string, note the restriction of using extra space.&nbsp;</div><div>You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case?&nbsp;</div><div>&nbsp;There is a more generic way of solving this problem.</div>
+翻转整数，判断是否相等
+```java
+public class Solution {
+    /**
+     * @param num a positive number
+     * @return true if it's a palindrome or false
+     */
+    public boolean isPalindrome(int x) {
+        if(x < 0) {
+            return false;
+        }
+        return x == reverse(x);    
+    }
+    
+    public int reverse(int x) {
+        int rst = 0;
+        while(x != 0) {
+            rst = rst * 10 + x % 10;
+            x = x / 10;
+        }
+        return rst;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/parking-lot.md" "b/\351\253\230\351\242\221/parking-lot.md"
new file mode 100644
index 0000000..4b3f526
--- /dev/null
+++ "b/\351\253\230\351\242\221/parking-lot.md"
@@ -0,0 +1,323 @@
+# 停车场
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/parking-lot/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个停车场
+1. 一共有*n*层，每层*m*列，每列*k*个位置
+2. 停车场可以停摩托车，公交车，汽车
+3. 停车位分别有摩托车位，汽车位，大型停车位
+4. 每一列，摩托车位编号范围为`[0,k/4)(注：包括0，不包括k/4)`,汽车停车位编号范围为`[k/4,k/4*3)(注：不包括k/4*3)`,大型停车位编号范围为`[k/4*3,k)(注：不包括k)`
+5. 一辆摩托车可以停在任何停车位
+6. 一辆汽车可以停在一个汽车位或者大型停车位
+7. 一辆公交车可以停在一列里的连续5个大型停车位。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+// enum type for Vehicle
+enum VehicleSize {
+	Motorcycle,
+	Compact,
+	Large,
+}
+
+//abstract Vehicle class
+abstract class Vehicle {
+    // Write your code here
+	protected int spotsNeeded;
+	protected VehicleSize size;
+	protected String licensePlate;  // id for a vehicle
+
+	protected ArrayList<ParkingSpot> parkingSpots = new ArrayList<ParkingSpot>(); // id for parking where may occupy multi
+
+	public int getSpotsNeeded() {
+		return spotsNeeded;
+	}
+	
+	public VehicleSize getSize() {
+		return size;
+	}
+
+	/* Park vehicle in this spot (among others, potentially) */
+	public void parkInSpot(ParkingSpot spot) {
+		parkingSpots.add(spot);
+	}
+	
+	/* Remove car from spot, and notify spot that it's gone */
+	public void clearSpots() {
+		for (int i = 0; i < parkingSpots.size(); i++) {
+			parkingSpots.get(i).removeVehicle();
+		}
+		parkingSpots.clear();
+	}
+	//this need to be implement in subclass
+	public abstract boolean canFitInSpot(ParkingSpot spot);
+    public abstract void print(); 
+}
+
+class Motorcycle extends Vehicle {
+    // Write your code here
+	public Motorcycle() {
+		spotsNeeded = 1;
+		size = VehicleSize.Motorcycle;
+	}
+	
+	public boolean canFitInSpot(ParkingSpot spot) {
+		return true;
+	}
+    
+    public void print() {  
+        System.out.print("M");  
+    }
+}
+
+class Car extends Vehicle {
+    // Write your code here
+	public Car() {
+		spotsNeeded = 1;
+		size = VehicleSize.Compact;
+	}
+	
+	public boolean canFitInSpot(ParkingSpot spot) {
+		return spot.getSize() == VehicleSize.Large || spot.getSize() == VehicleSize.Compact;
+	}
+
+    public void print() {  
+        System.out.print("C");  
+    } 
+}
+
+class Bus extends Vehicle {
+    // Write your code here
+	public Bus() {
+		spotsNeeded = 5;
+		size = VehicleSize.Large;
+	}
+
+	public boolean canFitInSpot(ParkingSpot spot) {
+		return spot.getSize() == VehicleSize.Large;
+	}
+
+    public void print() {  
+        System.out.print("B");  
+    } 
+}
+
+class ParkingSpot {
+    // Write your code here
+	private Vehicle vehicle;
+	private VehicleSize spotSize;
+	private int row;
+	private int spotNumber;
+	private Level level;
+
+	public ParkingSpot(Level lvl, int r, int n, VehicleSize sz) {
+		level = lvl;
+		row = r;
+		spotNumber = n;
+		spotSize = sz;
+	}
+	
+	public boolean isAvailable() {
+		return vehicle == null;
+	}
+	/* Checks if the spot is big enough for the vehicle (and is available). This compares
+	 * the SIZE only. It does not check if it has enough spots. */
+	public boolean canFitVehicle(Vehicle vehicle) {
+		return isAvailable() && vehicle.canFitInSpot(this);
+	}
+	/* Park vehicle in this spot. */
+	public boolean park(Vehicle v) {
+		if (!canFitVehicle(v)) {
+			return false;
+		}
+		vehicle = v;
+		vehicle.parkInSpot(this);
+		return true;
+	}
+	/* Remove vehicle from spot, and notify level that a new spot is available */
+	public void removeVehicle() {
+		level.spotFreed();
+		vehicle = null;
+	}
+	
+	public int getRow() {
+		return row;
+	}
+	
+	public int getSpotNumber() {
+		return spotNumber;
+	}
+	
+	public VehicleSize getSize() {
+		return spotSize;
+	}
+
+    public void print() {  
+        if (vehicle == null) {  
+            if (spotSize == VehicleSize.Compact) {  
+                System.out.print("c");  
+            } else if (spotSize == VehicleSize.Large) {  
+                System.out.print("l");  
+            } else if (spotSize == VehicleSize.Motorcycle) {  
+                System.out.print("m");  
+            }  
+        } else {  
+            vehicle.print();  
+        }  
+    }
+}
+
+/* Represents a level in a parking garage */
+class Level {
+    // Write your code here
+	private int floor;
+	private ParkingSpot[] spots;
+	private int availableSpots = 0; // number of free spots
+	private int SPOTS_PER_ROW;
+
+
+	public Level(int flr, int num_rows, int spots_per_row) {
+		floor = flr;
+        int SPOTS_PER_ROW = spots_per_row;
+        int numberSpots  = 0;
+		spots = new ParkingSpot[num_rows * spots_per_row];
+
+		//init size for each spot in array spots
+        for (int row = 0; row < num_rows; ++row) {
+            for (int spot = 0; spot < spots_per_row / 4; ++spot) {
+                VehicleSize sz = VehicleSize.Motorcycle;
+                spots[numberSpots] = new ParkingSpot(this, row, numberSpots, sz);
+                numberSpots ++;
+            }
+            for (int spot = spots_per_row / 4; spot < spots_per_row / 4 * 3; ++spot) {
+                VehicleSize sz = VehicleSize.Compact;
+                spots[numberSpots] = new ParkingSpot(this, row, numberSpots, sz);
+                numberSpots ++;
+            }
+            for (int spot = spots_per_row / 4 * 3; spot < spots_per_row; ++spot) {
+                VehicleSize sz = VehicleSize.Large;
+                spots[numberSpots] = new ParkingSpot(this, row, numberSpots, sz);
+                numberSpots ++;
+            }
+        }
+
+        availableSpots = numberSpots;
+	}
+
+	/* Try to find a place to park this vehicle. Return false if failed. */
+	public boolean parkVehicle(Vehicle vehicle) {
+		if (availableSpots() < vehicle.getSpotsNeeded()) {
+			return false; // no enough spots
+		}
+		int spotNumber = findAvailableSpots(vehicle);
+		if(spotNumber < 0) {
+			return false;
+		}
+		return parkStartingAtSpot(spotNumber, vehicle);
+	}
+
+	/* find a spot to park this vehicle. Return index of spot, or -1 on failure. */
+	private int findAvailableSpots(Vehicle vehicle) {
+		int spotsNeeded = vehicle.getSpotsNeeded();
+		int lastRow = -1;
+		int spotsFound = 0;
+
+		for(int i = 0; i < spots.length; i++){
+			ParkingSpot spot = spots[i];
+			if(lastRow != spot.getRow()){
+				spotsFound = 0;
+				lastRow = spot.getRow();
+			}
+			if(spot.canFitVehicle(vehicle)){
+				spotsFound++;
+			}else{
+				spotsFound = 0;
+			}
+			if(spotsFound == spotsNeeded){
+				return i - (spotsNeeded - 1); // index of spot
+			}
+		}
+		return -1;
+	}
+
+	/* Park a vehicle starting at the spot spotNumber, and continuing until vehicle.spotsNeeded. */
+	private boolean parkStartingAtSpot(int spotNumber, Vehicle vehicle) {
+		vehicle.clearSpots();
+
+		boolean success = true;
+		
+		for (int i = spotNumber; i < spotNumber + vehicle.spotsNeeded; i++) {
+			 success &= spots[i].park(vehicle);
+		}
+		
+		availableSpots -= vehicle.spotsNeeded;
+		return success;
+	}
+
+	/* When a car was removed from the spot, increment availableSpots */
+	public void spotFreed() {
+		availableSpots++;
+	}
+
+	public int availableSpots() {
+		return availableSpots;
+	}
+
+    public void print() {  
+        int lastRow = -1;  
+        for (int i = 0; i < spots.length; i++) {  
+            ParkingSpot spot = spots[i];  
+            if (spot.getRow() != lastRow) {  
+                System.out.print("  ");  
+                lastRow = spot.getRow();  
+            }  
+            spot.print();  
+        }  
+    }
+}
+
+public class ParkingLot {
+	private Level[] levels;
+	private int NUM_LEVELS;
+	
+    // @param n number of leves
+    // @param num_rows  each level has num_rows rows of spots
+    // @param spots_per_row each row has spots_per_row spots
+	public ParkingLot(int n, int num_rows, int spots_per_row) {
+        // Write your code here
+        NUM_LEVELS = n;
+		levels = new Level[NUM_LEVELS];
+		for (int i = 0; i < NUM_LEVELS; i++) {
+			levels[i] = new Level(i, num_rows, spots_per_row);
+		}
+	}
+
+	// Park the vehicle in a spot (or multiple spots)
+    // Return false if failed
+	public boolean parkVehicle(Vehicle vehicle) {
+        // Write your code here
+		for (int i = 0; i < levels.length; i++) {
+			if (levels[i].parkVehicle(vehicle)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+    // unPark the vehicle
+	public void unParkVehicle(Vehicle vehicle) {
+        // Write your code here
+		vehicle.clearSpots();
+	}
+
+    public void print() {  
+        for (int i = 0; i < levels.length; i++) {  
+            System.out.print("Level" + i + ": ");  
+            levels[i].print();
+            System.out.println("");  
+        }  
+        System.out.println("");  
+    } 
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/pascals-triangle-ii.md" "b/\351\253\230\351\242\221/pascals-triangle-ii.md"
new file mode 100644
index 0000000..0b78621
--- /dev/null
+++ "b/\351\253\230\351\242\221/pascals-triangle-ii.md"
@@ -0,0 +1,53 @@
+# 杨辉三角形II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/pascals-triangle-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定非负索引k，其中k≤33，返回杨辉三角形的第k个索引行。
+ ### 样例说明
+ **样例1**
+
+```
+输入: 3
+输出: [1,3,3,1]
+```
+
+**样例2**
+
+```
+输入: 4
+输出: [1,4,6,4,1]
+```
+ ### 参考代码
+ Given an index k, return the kth row of the Pascal's triangle.
+
+For example, given k = 3,
+Return [1,3,3,1].
+
+Note:
+Could you optimize your algorithm to use only O(k) extra space?
+```java
+public class Solution {
+    public ArrayList<Integer> getRow(int rowIndex) {
+        ArrayList<Integer> rst = new ArrayList<Integer>();
+        rowIndex += 1;
+        if (rowIndex == 0) {
+            return rst;
+        }
+
+        rst.add(1);
+        for (int i = 1; i < rowIndex; i++) {
+            ArrayList<Integer> tmp = new ArrayList<Integer>(i+1);
+            for (int j = 0; j < i + 1; j++) {
+                tmp.add(-1);
+            }
+            tmp.set(0, rst.get(0));
+            tmp.set(i, rst.get(i - 1));
+            for (int j = 1; j < i; j++) {
+                tmp.set(j, rst.get(j - 1) + rst.get(j));
+            }
+            rst = tmp;
+        }
+        return rst;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/pascals-triangle.md" "b/\351\253\230\351\242\221/pascals-triangle.md"
new file mode 100644
index 0000000..83b5471
--- /dev/null
+++ "b/\351\253\230\351\242\221/pascals-triangle.md"
@@ -0,0 +1,76 @@
+# 杨辉三角
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/pascals-triangle/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个非负整数 *numRows，*生成杨辉三角的前 *numRows* 行。
+
+![图片](https://media-cdn.jiuzhang.com/markdown/images/7/6/60e49d2e-9ffa-11e9-a15b-0242ac110002.jpg)
+
+在杨辉三角中，每个数是它左上方和右上方的数的和。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 5
+输出:
+[
+     [1],
+    [1,1],
+   [1,2,1],
+  [1,3,3,1],
+ [1,4,6,4,1]
+]
+```
+
+**样例 2:**
+
+```
+输入: 3
+输出:
+[
+     [1],
+    [1,1],
+   [1,2,1]
+]
+```
+
+
+ ### 参考代码
+ ```java
+class Solution {
+    public List<List<Integer>> generate(int numRows) {
+        List<List<Integer>> triangle = new ArrayList<List<Integer>>();
+
+        // First base case; if user requests zero rows, they get zero rows.
+        if (numRows == 0) {
+            return triangle;
+        }
+
+        // Second base case; first row is always [1].
+        triangle.add(new ArrayList<>());
+        triangle.get(0).add(1);
+
+        for (int rowNum = 1; rowNum < numRows; rowNum++) {
+            List<Integer> row = new ArrayList<>();
+            List<Integer> prevRow = triangle.get(rowNum-1);
+
+            // The first row element is always 1.
+            row.add(1);
+
+            // Each triangle element (other than the first and last of each row)
+            // is equal to the sum of the elements above-and-to-the-left and
+            // above-and-to-the-right.
+            for (int j = 1; j < rowNum; j++) {
+                row.add(prevRow.get(j-1) + prevRow.get(j));
+            }
+
+            // The last row element is always 1.
+            row.add(1);
+
+            triangle.add(row);
+        }
+
+        return triangle;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/pass-interview.md" "b/\351\253\230\351\242\221/pass-interview.md"
new file mode 100644
index 0000000..cbbebfe
--- /dev/null
+++ "b/\351\253\230\351\242\221/pass-interview.md"
@@ -0,0 +1,29 @@
+# 通过面试
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/pass-interview/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出面试者的性别和面试成绩，判断求职者是否通过面试。
+
+* 如果面试者是男性，那么面试成绩必须大于等于4分。
+* 如果面试者是女性，那么面试成绩必须大于等于3分。
+
+参数sex是boolean类型，sex为true时，代表求职者是女性，因为女人永远都是对的。相反sex为false时，代表求职者为男性，因为男人永远都是错的。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param sex the sex of a candidate
+     * @param score the interview score of a candidate
+     * @return a boolean
+     */
+    public boolean passInterview(boolean sex, double score) {
+        if (sex) {
+            return score >= 3;
+        }
+        return score >= 4;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/permutation-index.md" "b/\351\253\230\351\242\221/permutation-index.md"
new file mode 100644
index 0000000..46ebb7a
--- /dev/null
+++ "b/\351\253\230\351\242\221/permutation-index.md"
@@ -0,0 +1,71 @@
+# 排列序号
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/permutation-index/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个不含重复数字的排列，求这些数字的所有排列按字典序排序后该排列的编号。其中，编号从1开始。
+ ### 样例说明
+ **样例 1:**
+```
+输入:[1,2,4]
+输出:1
+```
+
+**样例 2:**
+```
+输入:[3,2,1]
+输出:6
+```
+ ### 参考代码
+ ```java
+public class Solution {
+	/**
+	 * @param A an integer array
+	 * @return a long integer
+	 */
+	long fac(int numerator) {
+		long now = 1;
+		for (int i = 1; i <= numerator; i++) {
+			now *= (long) i;
+		}
+		return now;
+	}
+
+	long generateNum(HashMap<Integer, Integer> hash) {
+		long denominator = 1;
+		int sum = 0;
+		for (int val : hash.values()) {
+			if(val == 0 )	
+				continue;
+			denominator *= fac(val);
+			sum += val;
+		}
+		if(sum==0) {
+			return sum;
+		}
+		return fac(sum) / denominator;
+	}
+
+	public long permutationIndex(int[] A) {
+		HashMap<Integer, Integer> hash = new HashMap<Integer, Integer>();
+		for (int i = 0; i < A.length; i++) {
+			if (hash.containsKey(A[i]))
+				hash.put(A[i], hash.get(A[i]) + 1);
+			else {
+				hash.put(A[i], 1);
+			}
+		}
+		long ans = 0;
+		for (int i = 0; i < A.length; i++) {
+			for (int j = i + 1; j < A.length; j++) {
+				if (A[j] < A[i]) {
+					hash.put(A[j], hash.get(A[j]) - 1);
+					ans += generateNum(hash);
+					hash.put(A[j], hash.get(A[j]) + 1);
+				}
+			}
+			hash.put(A[i], hash.get(A[i])-1);
+		}
+		return ans+1;
+	}
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/plus-one.md" "b/\351\253\230\351\242\221/plus-one.md"
new file mode 100644
index 0000000..d3aee13
--- /dev/null
+++ "b/\351\253\230\351\242\221/plus-one.md"
@@ -0,0 +1,49 @@
+# 加一
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/plus-one/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个非负数，表示一个数字数组，在该数的基础上+1，返回一个新的数组。
+
+该数字按照数位高低进行排列，最高位的数在列表的最前面。
+ ### 样例说明
+ **样例 1：**
+```
+输入：[1,2,3]
+输出：[1,2,4]
+```
+**样例 2：**
+```
+输入：[9,9,9]
+输出：[1,0,0,0]
+```
+ ### 参考代码
+ Given a non-negative number represented as an array of digits, plus one to the number.
+
+The digits are stored such that the most significant digit is at the head of the list.
+```java
+public class Solution {
+    // The complexity is O(1)
+    // f(n) = 9/10 + 1/10 * O(n-1)
+    //  ==>  O(n) =  10 / 9 = 1.1111 = O(1)
+    
+    public int[] plusOne(int[] digits) {
+        int carries = 1;
+        for(int i = digits.length-1; i>=0 && carries > 0; i--){  // fast break when carries equals zero
+            int sum = digits[i] + carries;
+            digits[i] = sum % 10;
+            carries = sum / 10;
+        }
+        if(carries == 0)
+            return digits;
+            
+        int[] rst = new int[digits.length+1];
+        rst[0] = 1;
+        for(int i=1; i< rst.length; i++){
+            rst[i] = digits[i-1];
+        }
+        return rst;
+    }
+}
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/prime-factorization.md" "b/\351\253\230\351\242\221/prime-factorization.md"
new file mode 100644
index 0000000..ab8480b
--- /dev/null
+++ "b/\351\253\230\351\242\221/prime-factorization.md"
@@ -0,0 +1,42 @@
+# 分解质因数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/prime-factorization/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 将一个整数分解为若干质因数之乘积。
+ ### 样例说明
+ **样例 1：**
+```
+输入：10
+输出：[2, 5]
+```
+**样例 2：**
+```
+输入：660
+输出：[2, 2, 3, 5, 11]
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param num an integer
+     * @return an integer array
+     */
+    public List<Integer> primeFactorization(int num) {
+        List<Integer> factors = new ArrayList<Integer>();
+
+        for (int i = 2; i * i <= num; i++) {
+            while (num % i == 0) {
+                num = num / i;
+                factors.add(i);
+            }
+        }
+        
+        if (num != 1) {
+            factors.add(num);
+        }
+        
+        return factors;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/rat-jump.md" "b/\351\253\230\351\242\221/rat-jump.md"
new file mode 100644
index 0000000..2ff3c03
--- /dev/null
+++ "b/\351\253\230\351\242\221/rat-jump.md"
@@ -0,0 +1,110 @@
+# 老鼠跳跃
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/rat-jump/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有一个老鼠从高为`n`的楼梯顶部跳跃下来，这个老鼠在偶数次跳跃时可以跳1, 3或者4个台阶，奇数次可以跳跃1, 2或者4个台阶。但是楼梯中间会有一些台阶上有胶水，如果跳到那些台阶上，老鼠就会被直接粘住，无法继续跳跃。你需要求出从这个楼梯顶部开始，老鼠有多少种方法能够到达地面，即第0层。若超过地面，也算是可以到达。例如从1跳跃到-1，和从1跳跃到0的方案不同。楼梯有无胶水的状态是从高往低输入的，即arr[0]代表当前老鼠所在的位置无胶水。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```
+[[python]]
+MOD = 10 ** 9 + 7
+
+
+class Solution:
+    """
+    @param arr: the steps whether have glue
+    @return: the sum of the answers
+    """
+    def ratJump(self, arr):
+        n = len(arr)
+
+        # state: dp[i][0] 代表从 0 的位置跳偶数步后到 i 的位置的方案数
+        #        dp[i][1] 代表从 0 的位置跳奇数步后到 i 的位置的方案数
+        dp = [[0, 0] for _ in range(n)]
+        
+        # initialization: 一开始站在 0 的位置, 已经跳过了 0 步(偶数步)
+        dp[0][0] = 1
+        
+        even_jumps = [1, 3, 4]
+        odd_jumps = [1, 2, 4]
+        
+        # function: dp[i][0] = dp[i - 1][1] + dp[i - 3][1] + dp[i - 4][1]
+        #           dp[i][1] = dp[i - 1][0] + dp[i - 2][0] + dp[i - 4][0]
+        for i in range(1, n - 1):
+            if arr[i] == 1:
+                continue
+            for jump in even_jumps:
+                if i - jump >= 0:
+                    dp[i][0] = (dp[i][0] + dp[i - jump][1]) % MOD
+            for jump in odd_jumps:
+                if i - jump >= 0:
+                    dp[i][1] = (dp[i][1] + dp[i - jump][0]) % MOD
+        
+        # answer: 研究跳到地板之前的那一步是从哪儿出发的，跳了多远
+        plans = 0
+        for jump in even_jumps:
+            for i in range(max(0, n - jump - 1), n - 1):
+                plans = (plans + dp[i][1]) % MOD
+        for jump in odd_jumps:
+            for i in range(max(0, n - jump - 1), n - 1):
+                plans = (plans + dp[i][0]) % MOD
+        return plans
+[[java]]
+public class Solution {
+    /**
+     * @param arr: the steps whether have glue
+     * @return: the sum of the answers
+     */
+    private int MOD = 1000000007; 
+    
+    public int ratJump(int[] arr) {
+        int n = arr.length;
+
+        // state: dp[i][0] 代表从 0 的位置跳偶数步后到 i 的位置的方案数
+        //        dp[i][1] 代表从 0 的位置跳奇数步后到 i 的位置的方案数
+        int[][] dp = new int[n][2];
+        
+        // initialization: 一开始站在 0 的位置, 已经跳过了 0 步(偶数步)
+        dp[0][0] = 1;
+        
+        int[] evenJumps = {1, 3, 4};
+        int[] oddJumps = {1, 2, 4};
+        
+        // function: dp[i][0] = dp[i - 1][1] + dp[i - 3][1] + dp[i - 4][1]
+        //           dp[i][1] = dp[i - 1][0] + dp[i - 2][0] + dp[i - 4][0]
+        for (int i = 1; i < n - 1; i++) {
+            if (arr[i] == 1) {
+                continue;
+            }
+            for (int jump: evenJumps) {
+                if (i - jump >= 0) {
+                    dp[i][0] = (dp[i][0] + dp[i - jump][1]) % MOD;
+                }
+            }
+                
+            for (int jump: oddJumps) {
+                if (i - jump >= 0) {
+                    dp[i][1] = (dp[i][1] + dp[i - jump][0]) % MOD;
+                }
+            }
+        }
+            
+        
+        // answer: 研究跳到地板之前的那一步是从哪儿出发的，跳了多远
+        int plans = 0;
+        for (int jump: evenJumps) {
+            for (int i = Math.max(0, n - jump - 1); i < n - 1; i++) {
+                plans = (plans + dp[i][1]) % MOD;
+            }
+        }
+            
+        for (int jump: oddJumps) {
+            for (int i = Math.max(0, n - jump - 1); i < n - 1; i++) {
+                plans = (plans + dp[i][0]) % MOD;
+            }
+        }
+        return plans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/read-n-characters-given-read4-ii-call-multiple-times.md" "b/\351\253\230\351\242\221/read-n-characters-given-read4-ii-call-multiple-times.md"
new file mode 100644
index 0000000..1d33a15
--- /dev/null
+++ "b/\351\253\230\351\242\221/read-n-characters-given-read4-ii-call-multiple-times.md"
@@ -0,0 +1,78 @@
+# 用Read4从文件中读取N个字符 II-多次调用
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/read-n-characters-given-read4-ii-call-multiple-times/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 接口：`int read4(char * buf)`一次从文件中读取 `4` 个字符。
+返回值是实际读取的字符数。 例如，如果文件中只剩下 3 个字符，则返回 3。
+通过使用read4 接口，实现从文件读取 n 个字符的函数`int read(char * buf，int n)`。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+/* The read4 API is defined in the parent class Reader4.
+      int read4(char[] buf); */
+
+public class Solution extends Reader4 {
+    private char[] buf4 = new char[4];
+    private int buf4Index = 4;
+    private int buf4Size = 4;
+    
+    private boolean readNext(char[] buf, int index) {
+        if (buf4Index >= buf4Size) {
+            buf4Size = read4(buf4);
+            buf4Index = 0;
+            if (buf4Size == 0) {
+                return false;
+            }
+        }
+
+        buf[index] = buf4[buf4Index++];
+        return true;
+    }
+    
+    /**
+     * @param buf Destination buffer
+     * @param n   Maximum number of characters to read
+     * @return    The number of characters read
+     */
+    public int read(char[] buf, int n) {
+        for (int i = 0; i < n; i++) {
+            if (!readNext(buf, i)) {
+                return i;
+            }
+        }
+        
+        return n;
+    }
+}
+
+
+//version:高频题班
+public class Solution extends Reader4 {
+    /**
+     * @param buf destination buffer
+     * @param n maximum number of characters to read
+     * @return the number of characters read
+     */
+    char[] buffer = new char[4];
+    int head = 0, tail = 0;
+
+    public int read(char[] buf, int n) {
+        // Write your code here
+        int i = 0;
+        while (i < n) {
+            if (head == tail) {               // queue is empty
+                head = 0;
+                tail = read4(buffer);         // enqueue
+                if (tail == 0) {
+                    break;
+                }
+            }
+            while (i < n && head < tail) {
+                buf[i++] = buffer[head++];    // dequeue
+            }
+        }
+        return i;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/readme.md" "b/\351\253\230\351\242\221/readme.md"
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ "b/\351\253\230\351\242\221/readme.md"
@@ -0,0 +1 @@
+
diff --git "a/\351\253\230\351\242\221/rectangle-area.md" "b/\351\253\230\351\242\221/rectangle-area.md"
new file mode 100644
index 0000000..3a69de5
--- /dev/null
+++ "b/\351\253\230\351\242\221/rectangle-area.md"
@@ -0,0 +1,52 @@
+# 矩阵面积
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/rectangle-area/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个矩阵类`Rectangle`，包含如下的一些成员变量与函数：
+
+1. 两个共有的成员变量 `width` 和 `height` 分别代表宽度和高度。
+1. 一个构造函数，接受2个参数 width 和 height 来设定矩阵的宽度和高度。
+2. 一个成员函数 `getArea`，返回这个矩阵的面积。
+ ### 样例说明
+ ```
+样例1:
+Java:
+    Rectangle rec = new Rectangle(3, 4);
+    rec.getArea(); // should get 12，3*4=12
+
+Python:
+    rec = Rectangle(3, 4)
+    rec.getArea()
+
+样例2:
+Java:
+    Rectangle rec = new Rectangle(4, 4);
+    rec.getArea(); // should get 16，4*4=16
+
+Python:
+    rec = Rectangle(4, 4)
+    rec.getArea()
+```
+ ### 参考代码
+ Python课题解 简单的实现类的函数。。。。。。。。。。。
+```python
+class Rectangle:
+
+    '''
+     * Define a constructor which expects two parameters width and height here.
+    '''
+    # write your code here
+    #初始化
+    def __init__(self, width, height):
+        self.width = width
+        self.height = height
+    
+    '''
+     * Define a public method `getArea` which can calculate the area of the
+     * rectangle and return.
+    '''
+    # write your code here
+    #返回矩阵面积
+    def getArea(self):
+        return self.width * self.height
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/reference.md" "b/\351\253\230\351\242\221/reference.md"
new file mode 100644
index 0000000..a491351
--- /dev/null
+++ "b/\351\253\230\351\242\221/reference.md"
@@ -0,0 +1,43 @@
+# 引用
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reference/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个类 *ReferenceManager* 包含如下两种方法
+
+1.`copyValue(Node obj)` 只拷贝参数*obj*的权值，*obj*和*node*仍然是两个指针
+
+2.`copyReference(Node obj)` *obj*和*node*指向同一个地方
+ ### 样例说明
+ ```
+ReferenceManager ref = ReferenceManager();
+Node obj = new Node(0);
+ref.copyValue(obj);
+ref.node.val; // 值为0
+ref.node; // 与obj不同.
+
+Node obj2 = new Node(1);
+ref.copyReference(obj2);
+ref.node.val; // 值为1
+ref.node; // 与 obj2相同，指向同一个地址
+```
+ ### 参考代码
+ java中直接赋值是同一个变量，指向同一个地址
+```java
+public class ReferenceManager {
+    public Node node;
+
+    public void copyValue(Node obj) {
+        if (obj == null) {
+            return;
+        }
+        if (node == null) {
+            node = new Node(obj.val);
+        }
+        node.val = obj.val;
+    }
+
+    public void copyReference(Node obj) {
+        node = obj;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/repeated-dna-sequences.md" "b/\351\253\230\351\242\221/repeated-dna-sequences.md"
new file mode 100644
index 0000000..5ca2bcd
--- /dev/null
+++ "b/\351\253\230\351\242\221/repeated-dna-sequences.md"
@@ -0,0 +1,59 @@
+# 重复的DNA序列 
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/repeated-dna-sequences/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 所有DNA由一系列缩写为A，C，G和T的核苷酸组成，例如：“ACGAATTCCG”。 在研究DNA时，有时识别DNA中的重复序列是非常必要的。
+
+编写一个函数来查找DNA分子中，长度为10个字母的，不止一次出现的序列（子串）。
+ ### 样例说明
+ **样例1**
+
+```
+输入: "A"
+输出: []
+```
+
+**样例2**
+
+```
+输入: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
+输出: ["AAAAACCCCC", "CCCCCAAAAA"]
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    public int encode(String s) {
+        int sum = 0;
+        for (int i = 0; i < s.length(); i++) {
+            if (s.charAt(i) == 'A') {
+                sum = sum * 4;
+            } else if (s.charAt(i) == 'C') {
+                sum = sum * 4 + 1;
+            } else if (s.charAt(i) == 'G') {
+                sum = sum * 4 + 2;
+            } else {
+                sum = sum * 4 + 3;
+            }
+        }
+        return sum;
+    }
+    public List<String> findRepeatedDnaSequences(String s) {
+        HashSet<Integer> hash = new HashSet<Integer>();
+        HashSet<String> dna = new HashSet<String>();
+        for (int i = 9; i < s.length(); i++) {
+            String subString = s.substring(i - 9, i + 1);
+            int encoded = encode(subString);
+            if (hash.contains(encoded)) {
+                dna.add(subString);
+            } else {
+                hash.add(encoded);
+            }
+        }
+        List<String> result = new ArrayList<String>();
+        for (String d: dna) {
+            result.add(d);
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/repeated-substring-pattern.md" "b/\351\253\230\351\242\221/repeated-substring-pattern.md"
new file mode 100644
index 0000000..6109975
--- /dev/null
+++ "b/\351\253\230\351\242\221/repeated-substring-pattern.md"
@@ -0,0 +1,56 @@
+# 重复的子串模式
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/repeated-substring-pattern/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个非空字符串，判断它能否通过重复它的某一个子串若干次（两次及以上）得到。字符串由小写字母组成，并且它的长度不会超过10000。
+
+
+ ### 样例说明
+ **样例1：**
+~~~~.
+输入："abab"
+
+输出：True
+
+说明：可以由它的子串"ab"重复两次得到。
+~~~~
+**样例2：**
+~~~~.
+输入："aba"
+
+输出：False
+~~~~
+**样例3：**
+~~~~.
+输入："abcabcabcabc"
+
+输出：True
+
+说明：可以由它的子串"abc"重复四次得到（同时也可以是"abcabc"重复两次）。
+~~~~
+ ### 参考代码
+ KMP算法对于next数组的应用。
+next\[i\]是指对于字符串s\[0,i-1\]中，前缀与后缀的最大匹配长度。
+例如对于"abcabcabc"来说，其next\[8\] = 5，也即对于s\[0,7\]="abcabcab"，前缀与后缀最大匹配的串为"abcab"，长度为5。
+用字符串长度减1减去最后一位的next数组值之后得到的应为重复串的长度。
+```java
+public class Solution {
+    public boolean repeatedSubstringPattern(String s) {
+        int l = s.length();
+        int[] next = new int[l];
+        next[0] = -1;
+        int i, j = -1;
+        for (i = 1; i < l; i++) {
+            while (j >= 0 && s.charAt(i) != s.charAt(j + 1)) {
+                j = next[j];
+            }
+            if (s.charAt(i) == s.charAt(j + 1)) {
+                j++;
+            }
+            next[i] = j;
+        }
+        int lenSub = l - 1 - next[l - 1];
+        return lenSub != l && l % lenSub ==0;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/reverse-words-in-a-string.md" "b/\351\253\230\351\242\221/reverse-words-in-a-string.md"
new file mode 100644
index 0000000..8fb4047
--- /dev/null
+++ "b/\351\253\230\351\242\221/reverse-words-in-a-string.md"
@@ -0,0 +1,56 @@
+# 翻转字符串中的单词
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reverse-words-in-a-string/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <span style="line-height: 1.42857143;">给定一个字符串，逐个翻转字符串中的每个单词。</span>
+ ### 样例说明
+ ```
+样例  1:
+	输入:  "the sky is blue"
+	输出:  "blue is sky the"
+	
+	样例解释: 
+	返回逐字反转的字符串.
+
+样例 2:
+	输入:  "hello world"
+	输出:  "world hello"
+	
+	样例解释: 
+	返回逐字反转的字符串.
+
+```
+ ### 参考代码
+ Given an input string, reverse the string word by word.
+
+For example,
+Given s = "the sky is blue",
+return "blue is sky the".
+```java
+public class Solution {
+    /*
+     * @param s: A string
+     * @return: A string
+     */
+    public String reverseWords(String s) {
+        // write your code here
+        if(s.length() == 0 || s == null){
+            return " ";
+        }
+        //按照空格将s切分
+        String[] array = s.split(" ");
+        StringBuilder sb = new StringBuilder();
+    	//从后往前遍历array，在sb中插入单词
+        for(int i = array.length - 1; i >= 0; i--){
+            if(!array[i].equals("")) {
+                if (sb.length() > 0) {
+                    sb.append(" ");
+                }
+                
+                sb.append(array[i]);
+            }
+        }
+        return sb.toString();
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/roman-to-integer.md" "b/\351\253\230\351\242\221/roman-to-integer.md"
new file mode 100644
index 0000000..a5d36fa
--- /dev/null
+++ "b/\351\253\230\351\242\221/roman-to-integer.md"
@@ -0,0 +1,85 @@
+# 罗马数字转整数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/roman-to-integer/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个罗马数字，将其转换成整数。
+
+输入数据保证返回的结果1到3999的范围内。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: "IV"
+输出: 4
+```
+
+**样例 2:**
+
+```
+输入: "XCIX"
+输出: 99
+```
+ ### 参考代码
+ 根据罗马数字的计数规则, 模拟运算即可.
+```java
+public class Solution {
+ 	public int romanToInt(String s) {
+	    if (s == null || s.length()==0) {
+                return 0;
+	    }
+	    Map<Character, Integer> m = new HashMap<Character, Integer>();
+	    m.put('I', 1);
+	    m.put('V', 5);
+	    m.put('X', 10);
+	    m.put('L', 50);
+	    m.put('C', 100);
+	    m.put('D', 500);
+	    m.put('M', 1000);
+
+	    int length = s.length();
+	    int result = m.get(s.charAt(length - 1));
+	    for (int i = length - 2; i >= 0; i--) {
+	        if (m.get(s.charAt(i + 1)) <= m.get(s.charAt(i))) {
+	            result += m.get(s.charAt(i));
+	        } else {
+	            result -= m.get(s.charAt(i));
+	        }
+	    }
+	    return result;
+	}
+}
+
+///////////////// version: 高频题班
+
+public class Solution {
+    /**
+     * @param s Roman representation
+     * @return an integer
+     */
+    public int romanToInt(String s) {
+        int ans;
+        char[] sc = s.toCharArray();
+        ans = toInt(sc[0]);                        //0 special
+        for (int i = 1; i < s.length(); i++) {
+            ans += toInt(sc[i]);
+            if (toInt(sc[i - 1]) < toInt(sc[i])) {
+                ans -= toInt(sc[i - 1]) * 2;
+            }
+        }
+        return ans;
+    }
+
+    int toInt(char s) {
+        switch(s) {
+            case 'I': return 1;
+            case 'V': return 5;
+            case 'X': return 10;
+            case 'L': return 50;
+            case 'C': return 100;
+            case 'D': return 500;
+            case 'M': return 1000;
+        }
+        return 0;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/rotate-string.md" "b/\351\253\230\351\242\221/rotate-string.md"
new file mode 100644
index 0000000..36dd7a4
--- /dev/null
+++ "b/\351\253\230\351\242\221/rotate-string.md"
@@ -0,0 +1,79 @@
+# 旋转字符串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/rotate-string/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个字符串（以字符数组的形式给出）和一个偏移量，根据偏移量`原地`旋转字符串(从左向右旋转)。
+ ### 样例说明
+ **样例  1:**
+
+```
+输入:  str="abcdefg", offset = 3
+输出:  str = "efgabcd"	
+样例解释:  注意是原地旋转，即str旋转后为"efgabcd"
+```
+
+**样例 2:**
+
+```
+输入: str="abcdefg", offset = 0
+输出: str = "abcdefg"	
+样例解释: 注意是原地旋转，即str旋转后为"abcdefg"
+```
+
+
+**样例 3:**
+
+```
+输入: str="abcdefg", offset = 1
+输出: str = "gabcdef"	
+样例解释: 注意是原地旋转，即str旋转后为"gabcdef"
+```
+
+**样例 4:**
+
+```
+输入: str="abcdefg", offset =2
+输出: str = "fgabcde"	
+样例解释: 注意是原地旋转，即str旋转后为"fgabcde"
+```
+
+**样例 5:**
+
+```
+输入: str="abcdefg", offset = 10
+输出: str = "efgabcd"	
+样例解释: 注意是原地旋转，即str旋转后为"efgabcd"
+```
+
+ ### 参考代码
+ 通过将原本的字符串倒置，可以将后面的旋转到前面。
+但是结果两段分别倒置了，再分别将两段倒置回来即可。
+
+时间复杂度O(n)
+```java
+public class Solution {
+    /**
+     * @param str: an array of char
+     * @param offset: an integer
+     * @return: nothing
+     */
+    public void rotateString(char[] str, int offset) {
+        // write your code here
+        if (str == null || str.length == 0)
+            return;
+            
+        offset = offset % str.length;
+        reverse(str, 0, str.length - offset - 1);
+        reverse(str, str.length - offset, str.length - 1);
+        reverse(str, 0, str.length - 1);
+    }
+    
+    private void reverse(char[] str, int start, int end) {
+        for (int i = start, j = end; i < j; i++, j--) {
+            char temp = str[i];
+            str[i] = str[j];
+            str[j] = temp;
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/shortest-palindrome.md" "b/\351\253\230\351\242\221/shortest-palindrome.md"
new file mode 100644
index 0000000..1de6bd6
--- /dev/null
+++ "b/\351\253\230\351\242\221/shortest-palindrome.md"
@@ -0,0 +1,58 @@
+# 最短回文串
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/shortest-palindrome/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个字符串 `S`, 你可以通过在前面添加字符将其转换为回文串.找到并返回用这种方式转换的最短回文串.
+ ### 样例说明
+ **样例1**
+```
+输入： "aacecaaa"
+输出： "aaacecaaa"
+解释：
+在输入字符串前面添加一个'a'。
+```
+**样例2**
+```
+输入： "abcd"
+输出： "dcbabcd"
+````
+ ### 参考代码
+ 从后往前每次减去一个字符后子串是否为回文串。
+答案为将减去的部分翻转后接入最前面。
+```java
+public class Solution {
+
+    public String shortestPalindrome(String s) {
+
+        int j = 0;
+
+        for (int i = s.length() - 1; i >= 0; i--) {//找到第一个使他不回文的位置
+
+           if (s.charAt(i) == s.charAt(j)) { 
+
+               j += 1; 
+
+           }
+
+        }
+
+        if (j == s.length()) {  //本身是回文
+
+            return s; 
+
+        }
+
+        String suffix = s.substring(j); // 后缀不能够匹配的字符串
+
+        String prefix = new StringBuilder(suffix).reverse().toString(); // 前面补充prefix让他和suffix回文匹配
+
+        String mid = shortestPalindrome(s.substring(0, j)); //递归调用找 [0,j]要最少可以补充多少个字符让他回文
+
+        String ans = prefix + mid  + suffix;
+
+        return  ans;
+
+    }
+
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/space-replacement.md" "b/\351\253\230\351\242\221/space-replacement.md"
new file mode 100644
index 0000000..af5760f
--- /dev/null
+++ "b/\351\253\230\351\242\221/space-replacement.md"
@@ -0,0 +1,59 @@
+# 空格替换
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/space-replacement/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一种方法，将一个字符串中的所有空格替换成 `%20` 。你可以假设该字符串有足够的空间来加入新的字符，且你得到的是“真实的”字符长度。
+
+你的程序还需要返回被替换后的字符串的长度。
+ ### 样例说明
+ **样例 1：**
+```
+输入：string[] = "Mr John Smith" and length = 13
+输出：string[] = "Mr%20John%20Smith" and return 17
+解释：
+对于字符串 "Mr John Smith"，长度为 13。替换空格之后，参数中的字符串需要变为 "Mr%20John%20Smith"，并且把新长度 17 作为结果返回。
+```
+**样例 2：**
+```
+输入：string[] = "LintCode and Jiuzhang" and length = 21
+输出：string[] = "LintCode%20and%20Jiuzhang" and return 25
+解释：
+对于字符串 "LintCode and Jiuzhang"，长度为 21。替换空格之后，参数中的字符串需要变为 "LintCode%20and%20Jiuzhang"，并且把新长度 25 作为结果返回。
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /*
+     * @param string: An array of Char
+     * @param length: The true length of the string
+     * @return: The true length of new string
+     */
+    public int replaceBlank(char[] string, int length) {
+        // write your code here
+        if(0==length) return 0;
+        int num = 0;
+        for(int i=0;i<length;i++){
+            if(string[i] == ' ') num++;
+        }
+        
+        int newLen = length + num*2;
+        string[newLen] = 0;
+        int j = 1;
+        for(int i=length-1;i>=0;i--){
+            if(string[i] != ' '){
+                string[newLen - j] = string[i];
+                j++;
+            }
+            else{
+                string[newLen - j] = '0';
+                j++;
+                string[newLen - j] = '2';
+                j++;
+                string[newLen - j] = '%';
+                j++; 
+            }
+        }
+        return newLen;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/string-compression.md" "b/\351\253\230\351\242\221/string-compression.md"
new file mode 100644
index 0000000..b6cec75
--- /dev/null
+++ "b/\351\253\230\351\242\221/string-compression.md"
@@ -0,0 +1,86 @@
+# 字符串压缩
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/string-compression/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一种方法，通过给重复字符计数来进行基本的字符串压缩。
+
+例如，字符串 `aabcccccaaa` 可压缩为 `a2b1c5a3` 。而如果压缩后的字符数不小于原始的字符数，则返回原始的字符串。
+
+可以假设字符串仅包括 a-z 的字母。
+ ### 样例说明
+ **样例 1：**
+```
+输入：str = "aabcccccaaa"
+输出："a2b1c5a3"
+```
+**样例 2：**
+```
+输入：str = "aabbcc"
+输出："aabbcc"
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param str a string
+     * @return a compressed string
+     */
+    public String compress(String str) {
+        // Write your code here
+        /* Check if compression would create a longer string */
+        int size = countCompression(str);
+        if (size >= str.length()) {
+            return str;
+        }
+
+        char[] array = new char[size];
+        int index = 0;
+        char last = str.charAt(0);
+        int count = 1;
+        for (int i = 1; i < str.length(); i++) {
+            if (str.charAt(i) == last) { // Found repeated character
+                count++;
+            } else {
+                /* Update the repeated character count */
+                index = setChar(array, last, index, count);
+                last = str.charAt(i);
+                count = 1;
+            }
+        }
+        /* Update string with the last set of repeated characters. */
+        index = setChar(array, last, index, count);
+        return String.valueOf(array);
+    }
+
+    public int setChar(char[] array, char c, int index, int count) {
+        array[index] = c;
+        index++;
+        char[] cnt = String.valueOf(count).toCharArray();
+
+        /* Copy characters from biggest digit to smallest */
+        for (char x : cnt) {
+            array[index] = x;
+            index++;
+        }
+        return index;
+    }
+
+    int countCompression(String str) {
+        if (str == null || str.isEmpty()) return 0;
+        char last = str.charAt(0);
+        int size = 0;
+        int count = 1;
+        for (int i = 1; i < str.length(); i++) {
+            if (str.charAt(i) == last) {
+                count++;
+            } else {
+                last = str.charAt(i);
+                size += 1 + String.valueOf(count).length();
+                count = 1;
+            }
+        }
+        size += 1 + String.valueOf(count).length();
+        return size;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/string-to-integer-atoi.md" "b/\351\253\230\351\242\221/string-to-integer-atoi.md"
new file mode 100644
index 0000000..c285927
--- /dev/null
+++ "b/\351\253\230\351\242\221/string-to-integer-atoi.md"
@@ -0,0 +1,65 @@
+# 转换字符串到整数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/string-to-integer-atoi/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>实现atoi这个函数，将一个字符串转换为整数。如果没有合法的整数，返回0。如果整数超出了32位整数的范围，返回INT_MAX(2147483647)如果是正整数，或者INT_MIN(-2147483648)如果是负整数。</p>
+ ### 样例说明
+ 
+ ### 参考代码
+ Implement atoi to convert a string to an integer.
+
+Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.
+
+Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.
+
+spoilers alert... click to show requirements for atoi.
+
+Requirements for atoi:
+The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.
+
+The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.
+
+If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.
+
+If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX (2147483647) or INT_MIN (-2147483648) is returned.
+```java
+public class Solution {
+   public int atoi(String str) {
+        // Start typing your Java solution below
+        // DO NOT write main() function
+        if(str == null) {
+            return 0;
+        }
+        str = str.trim();
+        if (str.length() == 0) {
+            return 0;
+        }
+            
+        int sign = 1;
+        int index = 0;
+    
+        if (str.charAt(index) == '+') {
+            index++;
+        } else if (str.charAt(index) == '-') {
+            sign = -1;
+            index++;
+        }
+        long num = 0;
+        for (; index < str.length(); index++) {
+            if (str.charAt(index) < '0' || str.charAt(index) > '9')
+                break;
+            num = num * 10 + (str.charAt(index) - '0');
+            if (num > Integer.MAX_VALUE ) {
+                break;
+            }
+        }   
+        if (num * sign >= Integer.MAX_VALUE) {
+            return Integer.MAX_VALUE;
+        }
+        if (num * sign <= Integer.MIN_VALUE) {
+            return Integer.MIN_VALUE;
+        }
+        return (int)num * sign;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/string-to-integer.md" "b/\351\253\230\351\242\221/string-to-integer.md"
new file mode 100644
index 0000000..41b5925
--- /dev/null
+++ "b/\351\253\230\351\242\221/string-to-integer.md"
@@ -0,0 +1,66 @@
+# 转换字符串到整数（容易版）
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/string-to-integer/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个字符串, 转换为整数. 你可以假设这个字符串是一个有效的整数的字符串形式， 且范围在32位整数之间 (-2<sup>31</sup> ~ 2<sup>31</sup> - 1)。
+ ### 样例说明
+ ```
+样例  1:
+	输入:  "123"
+	输出: 123
+	
+	样例解释: 
+	返回对应的数字.
+
+样例 2:
+	输入:  "-2"
+	输出: -2
+	
+	样例解释: 
+	返回对应的数字，注意负数.
+
+```
+ ### 参考代码
+ 要考虑给的字符串是否有符号。
+
+然后从高位开始循环累加。
+转换公示如下
+字符串：$S_1S_2S_3S_4$ --> 数字：$((S_1*10+S_2)*10+S_3)*10+S_4$
+```java
+//version 1(use library function)
+public class Solution {
+    /**
+     * @param str a string
+     * @return an integer
+     */
+    public int stringToInteger(String str) {
+        return Integer.valueOf(str);
+    }
+}
+
+//version 2 
+public class Solution {
+    /**
+     * @param str a string
+     * @return an integer
+     */
+    public int stringToInteger(String str) {
+        // Write your code here
+        int integer = 0;
+        int Minus = 0;
+        
+        if (str.charAt(0) == '-'){
+            Minus = 1;
+        }
+        
+        for (int i = Minus; i < str.length(); i++){
+            integer = integer * 10 + str.charAt(i)-'0';
+        }
+        
+        if (Minus == 1){
+            integer = -integer;
+        }
+        return integer;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/system-longest-file-path.md" "b/\351\253\230\351\242\221/system-longest-file-path.md"
new file mode 100644
index 0000000..94d2386
--- /dev/null
+++ "b/\351\253\230\351\242\221/system-longest-file-path.md"
@@ -0,0 +1,83 @@
+# 最长绝对文件路径
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/system-longest-file-path/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假设我们通过以下的方式用字符串来抽象我们的文件系统：
+字符串`"dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext"`代表了：
+```
+dir
+	subdir1
+	subdir2
+		file.ext
+```
+目录 `dir` 包含一个空子目录 `subdir1` 和一个包含文件file.ext的子目录 `subdir2`。
+字符串
+```
+"dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext"
+```
+代表了：
+```
+dir
+	subdir1
+		file1.ext
+		subsubdir1
+	subdir2
+		subsubdir2
+			file2.ext
+```
+目录 `dir` 包含两个子目录 `subdir1` 和 `subdir2` 。 `subdir1` 包含一个文件 file1.ext 和一个空的二级子目录 `subsubdir1` 。 `subdir2` 包含一个包含文件 file2.ext 的二级子目录 `subsubdir2`。 
+我们有兴趣找到文件系统中文件的最长绝对路径（字符数）。例如，在上面的第二个例子中，最长的绝对路径是`“dir/subdir2/subsubdir2/file2.ext”`，其长度为 `32` (不包括双引号)。
+给定一个以上述格式表示文件系统的字符串，返回抽象文件系统中文件最长绝对路径的长度。如果系统中没有文件，则返回 `0` 。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param input an abstract file system
+     * @return return the length of the longest absolute path to file
+     */
+    public int lengthLongestPath(String input) {
+        // Write your code here
+        int result = 0;
+        int[] path = new int[input.length() + 2];
+        String[] st = input.split("\n");
+        for (String line : st){
+            String name = line.replaceAll("(\t)+", "");
+            int depth = line.length() - name.length();
+            if(name.contains("."))
+                result = Math.max(result, path[depth] + name.length());
+            else
+                path[depth + 1] = path[depth] + name.length() + 1;
+        }
+        return result;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /*
+     * @param input an abstract file system
+     * @return return the length of the longest absolute path to file
+     */
+    public int lengthLongestPath(String input) {
+        // Write your code here
+        if (input.length() == 0) {
+            return 0;
+        }
+        int ans = 0;
+        int[] sum = new int[input.length() + 1];
+
+        for (String line : input.split("\n")) {
+            int level = line.lastIndexOf('\t') + 2;
+            int len = line.length() - (level - 1);
+            if (line.contains(".")) {
+                ans = Math.max(ans, sum[level - 1] + len);
+            } else {
+                sum[level] = sum[level - 1] + len + 1;
+            }
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/url-parser.md" "b/\351\253\230\351\242\221/url-parser.md"
new file mode 100644
index 0000000..bb5bd18
--- /dev/null
+++ "b/\351\253\230\351\242\221/url-parser.md"
@@ -0,0 +1,89 @@
+# 网址分析
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/url-parser/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 分析一段html语言中的网址
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+  <html>
+    <body>
+      <div>
+        <a href="http://www.google.com" class="text-lg">Google</a>
+        <a href="http://www.facebook.com" style="display:none">Facebook</a>
+      </div>
+      <div>
+        <a href="https://www.linkedin.com">Linkedin</a>
+        <a href = "http://github.io">LintCode</a>
+      </div>
+    </body>
+  </html>
+输出: 
+  [
+    "http://www.google.com",
+    "http://www.facebook.com",
+    "https://www.linkedin.com",
+    "http://github.io"
+  ]
+```
+
+**样例 2:**
+
+```
+输入: 
+  <html>
+    <body>
+      <div>
+        <a  HREF =    "http://www.google.com" class="text-lg">Google</a>
+        <a  HREF = "http://www.facebook.com" style="display:none">Facebook</a>
+      </div>
+      <div>
+        <a href="https://www.linkedin.com">Linkedin</a>
+        <a href = "http://github.io">LintCode</a>
+      </div>
+    </body>
+  </html>
+输出: 
+  [
+    "http://github.io",
+    "http://www.facebook.com",
+    "http://www.google.com",
+    "https://www.linkedin.com"
+  ]
+```
+ ### 参考代码
+ 这是一道字符串处理题目, 你可以手写循环, 遍历字符串, 或者是使用KMP之类的算法查找. 
+
+但是, 正如题目中的提示, 使用正则表达式是高效并且简洁的.
+
+需要查找的是被 `href = ""` 的双引号包含的链接, 注意 `href` 不区分大小写, 并且 `=` 前后的空格数量是随意的, 因为这些都是符合 html 语法的.
+
+另外两点: 确保你查找到的不是空串, 确保你查找到的不是 #.
+```java
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+public class HtmlParser {
+    private static final String HTML_HREF_TAG_PATTERN =  "\\s*(?i)href\\s*=\\s*(\"|')+([^\"'>\\s]*)";
+    /**
+     * @param content source code
+     * @return a list of links
+     */
+    public List<String> parseUrls(String content) {
+        List<String> links = new ArrayList<String>();
+        Pattern pattern = Pattern.compile(HTML_HREF_TAG_PATTERN, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(content);
+        String url = null;
+        while (matcher.find()) {
+            url = matcher.group(2);
+            if (url.length() == 0 || url.startsWith("#"))
+                continue;
+            links.add(url);
+        }
+        return links;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/validate-ip-address.md" "b/\351\253\230\351\242\221/validate-ip-address.md"
new file mode 100644
index 0000000..68e843c
--- /dev/null
+++ "b/\351\253\230\351\242\221/validate-ip-address.md"
@@ -0,0 +1,121 @@
+# 检验IP地址
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/validate-ip-address/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个函数来检查输入字符串是一个合法的IPv4地址，还是一个合法的IPv6地址，抑或是两者都不是。
+
+**IPv4**地址被规范地表示为点分十进制，包含四个取值为0到255的十进制数，其间使用点号(".")来进行分隔，例如，`172.16.254.1`；
+
+此外，前导零在IPv4地址中是非法的。例如，地址`172.16.254.01`就是非法的。
+
+**IPv6**地址被表示为十六进制数位，每4个十六进制数位归为一组，共八组，每组可表示16个二进制位。每组之间使用冒号(":")来进行分隔。例如，地址`2001:0db8:85a3:0000:0000:8a2e:0370:7334`是合法的。同时，去掉每组十六进制数位中的一些前导零，或是将表示十六进制数位的小写字母写作大写字母，也都是合法的，所以`2001:db8:85a3:0:0:8A2E:0370:7334`同样是一个合法的IPv6地址（它忽略了前导零同时使用了大写字母）。
+
+然而，我们不能为了追求简洁就使用两个冒号("::")将连续的值为0的组替换为一个空组。例如，`2001:0db8:85a3::8A2E:0370:7334`就是一个非法的IPv6地址。
+
+此外，额外的前导零在IPv6中也是非法的。例如，地址`02001:0db8:85a3:0000:0000:8a2e:0370:7334`就是非法的。
+ ### 样例说明
+ 例1:
+```
+输入："172.16.254.1"
+
+输出："IPv4"
+
+说明：这是一个合法的IPv4地址，因此返回"IPv4"。
+```
+
+例2:
+```
+输入："2001:0db8:85a3:0:0:8A2E:0370:7334"
+
+输出："IPv6"
+
+说明：这是一个合法的IPv6地址，因此返回"IPv6"。
+```
+
+例3:
+```
+输入："256.256.256.256"
+
+输出："Neither"
+
+说明：这既不是一个合法的IPv4地址，也不是一个合法的IPv6地址，因此返回"Neither"。
+```
+ ### 参考代码
+ 字符串处理题，要注意特殊情况的判断。
+```java
+public class Solution {
+    String IPv6char = "0123456789abcdefABCDEF";
+    public boolean isVaild_IPv4Number(String str){
+        int num = 0;
+        if(str.equals("") || str.length() > 3) {    
+            return false;
+        }
+        if(str.length() > 1 && str.charAt(0) == '0' ) {
+            return false;
+        }
+        for (int i = 0; i < str.length(); ++i){    
+            if ( !Character.isDigit(str.charAt(i))) {    
+                return false;    
+            }
+            else num = num * 10 + str.charAt(i)-'0';
+        }
+        if(num >= 0 && num < 256) {
+            return true;
+        }
+        else return false;
+    }
+    
+    public boolean isVaild_IPv6Number(String str) {
+        if(str.equals("") || str.length() > 4) {    
+            return false;    
+        }  
+        for (int i = 0; i < str.length(); ++i) {    
+            if ( IPv6char.indexOf(str.charAt(i)) == -1) {    
+                return false;    
+            }
+        }
+        return true;
+    }
+    
+    public int NumberOftoken(String IP,char token){
+        int num = 0;
+        for (int i = 0; i< IP.length(); ++i){
+            if( IP.charAt(i) == token) {
+                num ++;
+            }
+        }
+        return num;
+    }
+    public String validIPAddress(String IP) {
+        
+        String[] IPv4 = IP.split("\\.");
+        boolean is_IPv4 = true;
+        if(IPv4.length == 4 && NumberOftoken(IP,'.') == 3) {
+            for(int i = 0; i < 4; i++) {
+                if(!isVaild_IPv4Number(IPv4[i])){
+                    is_IPv4 = false;
+                    break;
+                }
+            }
+        }
+        else is_IPv4 = false ;
+        if(is_IPv4)return "IPv4";
+        
+        String[] IPv6 = IP.split(":");
+        boolean is_IPv6 = true;
+        if(IPv6.length == 8 && NumberOftoken(IP,':') == 7) {
+            for(int i = 0; i < 8; i++){
+                if(!isVaild_IPv6Number(IPv6[i])){
+                    is_IPv6 = false;
+                    break;
+                }
+                
+            }
+        }
+        else is_IPv6 = false;
+        if(is_IPv6)return "IPv6";
+        
+        return "Neither";
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/arraylist.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/arraylist.md"
new file mode 100644
index 0000000..36b53fc
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/arraylist.md"
@@ -0,0 +1,148 @@
+# 动态数组 ArrayList
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/arraylist/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 用 ArrayList 实现一些操作：
+
+1. `create(n)`. 创建一个大小为n的ArrayList，包含n个整数，依次为[0, 1, 2, ... n-1]
+2. `clone(list)`. 克隆一个list。使得克隆后的list与原来的list是完全独立无关的。
+3. `get(list, index)`. 查询list中index这个位置的数。
+4. `set(list, index, val)`. 将list中index这个位置的数改为val。
+5. `remove(list, index)`. 移除list中index这个位置的数。
+6. `indexOf(list, val)`. 在list中查找值为val的数，返回它的index。如果没有返回-1。
+
+请使用 ArrayList 的原生方法完成这些操作。参见Java文档：[ArrayList参考文档](https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html "ArrayList 文档")
+ ### 样例说明
+ 输入:
+
+```plain
+create(5)
+get([0,1,2,3,4], 0)
+get([0,1,2,3,4], 1)
+get([0,1,2,3,4], 4)
+clone([0,1,2,3,4])
+get([0,1,2,3,4], 2)
+indexOf([0,1,2,3,4], 1)
+indexOf([0,1,2,3,4], 10)
+remove([0,1,2,3,4], 3)
+get([0,1,2,4], 3)
+set([0,1,2,4], 2, 3)
+get([0,1,2,3,4], 2)
+get([0,1,2,3,4], 3)
+```
+
+输出:
+
+```plain
+[0,1,2,3,4]
+0
+1
+4
+[0,1,2,3,4]
+2
+1
+-1
+[0,1,2,4]
+4
+[0,1,3,4]
+2
+3
+```
+
+Explanation:
+
+The code for java is like this:
+
+```java
+ArrayList<Integer> list = ArrayListManager.create(5);
+list.get(0);  // 应该返回 0
+list.get(1);  // 应该返回 1
+list.get(4);  // 应该返回 4
+
+// 被克隆的列表应该是 [0,1,2,3,4]
+ArrayList<Integer> clone_list = ArrayListManager.clone(list);
+
+ArrayListManager.get(list, 2);  // 应该返回 2
+ArrayListManager.indexOf(list, 1); // 应该返回 1
+ArrayListManager.indexOf(list, 10); // 应该返回 -1
+ArrayListManager.remove(list, 3); // 列表将变成 [0, 1, 2, 4]
+ArrayListManager.get(list, 3); // 因为3已经被移除，所以应该返回4
+ArrayListManager.set(list, 2, 3); // 列表将变成 [0, 1, 3, 4]
+
+clone_list.get(2); // 应该返回 2
+clone_list.get(3); // 应该返回 3
+```
+
+
+ ### 参考代码
+ ```java
+public class ArrayListManager {
+    /**
+     * @param n: You should generate an array list of n elements.
+     * @return: The array list your just created.
+     */
+    public static ArrayList<Integer> create(int n) {
+        // Write your code here
+        ArrayList<Integer> list = new ArrayList<Integer>();
+        for (int i = 0; i < n; i++) {
+            list.add(i);
+        }
+        return list;
+    }
+    
+    /**
+     * @param list: The list you need to clone
+     * @return: A deep copyed array list from the given list
+     */
+    public static ArrayList<Integer> clone(ArrayList<Integer> list) {
+        // Write your code here
+        ArrayList<Integer> dist = new ArrayList<Integer>();
+        for (Integer a : list)
+            dist.add(a);
+        return dist;
+        //return list;
+    }
+    
+    /**
+     * @param list: The array list to find the kth element
+     * @param k: Find the kth element
+     * @return: The kth element
+     */
+    public static int get(ArrayList<Integer> list, int k) {
+        // Write your code here
+        return list.get(k);
+    }
+    
+    /**
+     * @param list: The array list
+     * @param k: Find the kth element, set it to val
+     * @param val: Find the kth element, set it to val
+     */
+    public static void set(ArrayList<Integer> list, int k, int val) {
+        // write your code here
+        list.set(k, val);
+    }
+    
+    /**
+     * @param list: The array list to remove the kth element
+     * @param k: Remove the kth element
+     */
+    public static void remove(ArrayList<Integer> list, int k) {
+        // write tour code here
+        list.remove(k);
+    }
+    
+    /**
+     * @param list: The array list.
+     * @param val: Get the index of the first element that equals to val
+     * @return: Return the index of that element
+     */
+    public static int indexOf(ArrayList<Integer> list, int val) {
+        // Write your code here
+        if (list == null)
+            return -1;
+        return list.indexOf(val);
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/battleships-in-a-board.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/battleships-in-a-board.md"
new file mode 100644
index 0000000..6db0e7e
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/battleships-in-a-board.md"
@@ -0,0 +1,86 @@
+# 2D战舰
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/battleships-in-a-board/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个 2D 板, 计数上面有多少战舰. 战舰用 `'X'` 表示，空地用 `'.'` 表示。你可以假设有一下规则：
+* 你会得到一个有效的板，上面只有战舰跟空地。
+* 战舰只能横着或者竖着放。换句话说，它们的大小只能是  `1xN` (1 行, N 列) 或者 `Nx1` (N 行, 1 列), N 可以是任意数。
+* 在两艘战舰之间至少有一个横向的或者纵向的格子分隔 - 没有相邻的战舰
+ ### 样例说明
+ **样例1**
+```
+输入：
+X..X
+...X
+...X
+输出： 2
+解释：
+在上述板上有两艘战舰。
+```
+**样例2**
+```
+输入：
+...X
+XXXX
+...X
+解释：
+这是一个你不会得到的无效输入 - 因为战舰之间始终会有一个单元格分隔。
+```
+
+ ### 参考代码
+ 我们发现对于船头，他的左边和上面一定为空地（或边界），因此只需要统计船头的个数即可知道战舰的个数。
+```java
+// 方法一
+public class Solution {
+    public int countBattleships(char[][] board) {
+        int len1 = board.length;
+        if(len1 == 0){
+            return 0;
+        }
+        int len2 = board[0].length;
+        int ans = 0;
+        for (int i = 0; i < len1; i++){
+            for(int j=0 ; j < len2; j++){
+                if(board[i][j] == 'X' && (i == 0 || board[i-1][j] == '.') && (j == 0 || board[i][j-1] == '.')){
+                    ans ++;
+                }
+            }
+        }
+        return ans;
+    }
+}
+
+// 方法二
+class Solution {
+public:
+    int countBattleships(vector<vector<char>>& board) {
+        int len1 = board.size();
+        if(len1 == 0) {
+            return 0;
+        }
+        int len2 = board[0].size();
+        int ans = 0;
+        int dx[4] = {0,0,-1,1};
+        int dy[4] = {-1,1,0,0};
+        for(int i=0; i < len1; i++){
+            for(int j =0; j < len2; j++){
+                if(board[i][j] == 'X'){
+                    board[i][j] = '.';//标记已经访问过
+                    ans++;
+                    int pos1 = i;
+                    int pos2 = j;
+                    for(int k =0; k < 4; k++){
+                        //一直沿着同一个方向搜索
+                        while(pos1+dx[k] >=0 && pos1+dx[k] < len1 && pos2 + dy[k] >=0 && pos2+dy[k]<len2 && board[pos1+[k]][pos2+dy[k]] == 'X'){
+                                board[pos1+dx[k]][pos2+dy[k]] = '.';
+                                pos1 += dx[k];
+                                pos2 += dy[k];
+                            }
+                    }
+                }
+            }
+        }
+        return ans;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock-ii.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock-ii.md"
new file mode 100644
index 0000000..5a3c7d8
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock-ii.md"
@@ -0,0 +1,46 @@
+# 买卖股票的最佳时机 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数组 `prices` 表示一支股票每天的价格. 
+
+你可以完成任意次数的交易, 不过你不能同时参与多个交易 (也就是说, 如果你已经持有这支股票, 在再次购买之前, 你必须先卖掉它).
+
+设计一个算法求出最大的利润.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [2, 1, 2, 0, 1]
+输出: 2
+解释: 
+    1. 在第 2 天以 1 的价格买入, 然后在第 3 天以 2 的价格卖出, 利润 1
+    2. 在第 4 天以 0 的价格买入, 然后在第 5 天以 1 的价格卖出, 利润 1
+    总利润 2.
+```
+
+**样例 2:**
+
+```
+输入: [4, 3, 2, 1]
+输出: 0
+解释: 不进行任何交易, 利润为0.
+```
+ ### 参考代码
+ 贪心法: 只要相邻的两天股票的价格是上升的, 我们就进行一次交易, 获得一定利润.
+
+这样的策略不一定是最小的交易次数, 但是一定会得到最大的利润.
+```java
+public class Solution {
+    public int maxProfit(int[] prices) {
+        int profit = 0;
+        for (int i = 0; i < prices.length - 1; i++) {
+            int diff = prices[i + 1] - prices[i];
+            if (diff > 0) {
+                profit += diff;
+            }
+        }
+        return profit;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock-iii.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock-iii.md"
new file mode 100644
index 0000000..a25880f
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock-iii.md"
@@ -0,0 +1,142 @@
+# 买卖股票的最佳时机 III
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p>假设你有一个数组，它的第i个元素是一支给定的股票在第i天的价格。<span style="line-height: 1.42857143;">设计一个算法来找到最大的利润。你最多可以完成两笔交易。</span></p>
+ ### 样例说明
+ ***样例 1***
+```
+输入 : [4,4,6,1,1,4,2,5]
+输出 : 6
+```
+ ### 参考代码
+ Say you have an array for which the ith element is the price of a given stock on day i.
+
+Design an algorithm to find the maximum profit. You may complete at most two transactions.
+
+Note:
+You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
+```java
+// 动态规划专题班版本
+public class Solution {
+    /**
+     * @param prices: Given an integer array
+     * @return: Maximum profit
+     */
+    public int maxProfit(int[] prices) {
+        // write your code here
+        int n = prices.length;
+        if (n == 0) {
+            return 0;
+        }
+        int [][]dp = new int[n + 1][5 + 1];
+        
+        for (int k = 1; k <= 5; k++) {
+            dp[0][k] = Integer.MIN_VALUE;
+        }
+        dp[0][1] = 0;
+        for (int i = 1; i <= n; i++) {
+            // 手中未持有股票
+            for (int j = 1; j <= 5; j += 2) {
+                // 前一天也未持有
+                dp[i][j] = dp[i - 1][j];
+                if (j > 1 && i > 1 && dp[i - 1][j - 1] != Integer.MIN_VALUE) {
+                    //                            前一天持有，今天卖了获利。
+                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + prices[i - 1] - prices[i - 2]);
+                }
+            }
+            // 手中持有股票
+            for (int j = 2; j <= 5; j += 2) {
+                //前一天未持有，今天买进
+                dp[i][j] = dp[i - 1][j - 1];
+                if (i > 1 && dp[i - 1][j] != Integer.MIN_VALUE) {
+                    //                            前一天持有了，计算今天的利润
+                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j] + prices[i - 1] - prices[i - 2]);
+                }
+            }
+        }
+        
+        int res = 0;
+        for (int j = 1; j <= 5; j += 2) {
+            res = Math.max(res, dp[n][j]);
+        }
+        return res;
+    }
+}
+
+// 方法二
+class Solution {
+    /**
+     * @param k: An integer
+     * @param prices: Given an integer array
+     * @return: Maximum profit
+     */
+    private int update(int a, int b, int delta) {
+        if (b == Integer.MIN_VALUE) {
+            return a;
+        }
+        
+        if (b + delta > a) {
+            return b + delta;
+        }
+        
+        return a;
+    }  
+     
+    public int maxProfit(int K, int[] prices) {
+        int n = prices.length;
+        int i, j, k;
+        if (K == 0) {
+            return 0;
+        }
+        
+        if (K >= n - 1) {
+            j = 0;
+            for (i = 1; i < n; ++i) {
+                if (prices[i] > prices[i - 1]) {
+                    j += prices[i] - prices[i - 1];
+                }
+            }
+            
+            return j;
+        }
+        
+        int[][] f = new int[n+1][2*K+1];
+        for (i = 0; i <= n; ++i) {
+            for (j = 0; j <= 2*K; ++j) {
+                f[i][j] = Integer.MIN_VALUE;
+            }
+        }
+        
+        f[0][0] = 0;
+        for (i = 1; i <= n; ++i) {
+            int delta;
+            if (i == 1) {
+                delta = 0;
+            }
+            else {
+                delta = prices[i-1] - prices[i - 2];
+            }
+            
+            f[i][0] = update(f[i][0], f[i-1][0], 0);
+            for (j = 1; j <= 2 * K; j += 2) {
+                if (i > 1) f[i][j] = update(f[i][j], f[i-1][j], delta);
+                if (i > 1) f[i][j] = update(f[i][j], f[i-1][j-1], delta);
+            }
+            
+            for (j = 2; j <= 2 * K; j += 2) {
+                f[i][j] = update(f[i][j], f[i-1][j], 0);
+                if (i > 1) f[i][j] = update(f[i][j], f[i-1][j-1], delta);
+                if (i > 1) f[i][j] = update(f[i][j], f[i-1][j-2], delta);
+            }
+        }
+        
+        int res = Integer.MIN_VALUE;
+        for (j = 2; j <= 2 * K; j += 2) {
+            res = update(res, f[n][j], 0);
+        }
+        
+        return res;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock-iv.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock-iv.md"
new file mode 100644
index 0000000..80aa31a
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock-iv.md"
@@ -0,0 +1,218 @@
+# 买卖股票的最佳时机 IV
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iv/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定数组 `prices`, 其中第 `i` 个元素代表某只股票在第 `i` 天第价格.
+
+**你最多可以完成 `k` 笔交易.** 问最大的利润是多少?
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: k = 2, prices = [4, 4, 6, 1, 1, 4, 2 ,5]
+输出: 6
+解释: 以 4 买入, 以 6 卖出. 然后再以 1 买入, 以 5 卖出. 利润为 2 + 4 = 6.
+```
+
+**样例 2:**
+
+```
+输入: k = 1, prices = [3, 2, 1]
+输出: 0
+解释: 不进行交易
+```
+ ### 参考代码
+ 假设一共有 n 天, 那么这 n 天最多能够完成 n / 2 比交易, 也就是说, 当 k * 2 >= n 时, 就变成了 [买卖股票的最佳时机 II](https://www.jiuzhang.com/solution/best-time-to-buy-and-sell-stock-ii/), 反之, 我们可以作为动态规划问题解决:
+
+定义:
+
+- globalbest[i][j] 表示前i天，至多进行j次交易时的最大获益
+- mustsell[i][j] 表示前i天，至多进行j次交易，并且第i天卖出手中的股票时的最大获益
+
+状态转移:
+
+- `mustsell[i][j] = max(globalbest[i - 1][j - 1], mustsell[i - 1][j]) + prices[i] - prices[i - 1]`
+- `globalbest[i][j] = max(globalbest[i - 1][j], mustsell[i][j])`
+
+边界: `mustsell[0][i] = globalbest[0][i] = 0`
+
+优化: 滚动数组优化两个状态的空间至一维数组.
+```java
+// 动态规划专题班版本
+class Solution {
+    /**
+     * @param prices: Given an integer array
+     * @return: Maximum profit
+     */
+
+    public int maxProfit(int K, int[] P) {
+        int n = P.length;
+        if (n == 0) {
+            return 0;
+        }
+
+        int i, j, k;
+        if (K > n / 2) {
+            // best time to buy and sell stock ii
+            int tmp = 0;
+            for (i = 0; i < n - 1; ++i) {
+                tmp += Math.max(0, P[i + 1] - P[i]);
+            }
+
+            return tmp;
+        }
+
+        int[][] f = new int[n + 1][2 * K + 1 + 1];
+        for (k = 1; k <= 2 * K + 1; ++k) {
+            f[0][k] = Integer.MIN_VALUE; // impossible
+        }
+
+        f[0][1] = 0;
+        for (i = 1; i <= n; ++i) {
+            // 阶段1, 3, .. 2 * K + 1: f[i][j] = max{f[i-1][j], f[i-1][j-1] + Pi-1 – Pi-2}
+            for (j = 1; j <= 2 * K + 1; j += 2) {
+                f[i][j] = f[i - 1][j];
+                if (j > 1 && i > 1 && f[i - 1][j - 1] != Integer.MIN_VALUE) {
+                    f[i][j] = Math.max(f[i][j], f[i - 1][j - 1] + P[i - 1] - P[i - 2]);
+                }
+            }
+
+            // 阶段2, 4.., 2K: f[i][j] = max{f[i-1][j] + Pi-1 – Pi-2, f[i-1][j-1]}
+            for (j = 2; j <= 2 * K + 1; j += 2) {
+                f[i][j] = f[i - 1][j - 1];
+                if (i > 1 && f[i - 1][j] != Integer.MIN_VALUE) {
+                    f[i][j] = Math.max(f[i][j], f[i - 1][j] + P[i - 1] - P[i - 2]);
+                }
+            }
+        }
+
+        int res = 0;
+        for (j = 1; j <= 2 * K + 1; j += 2) {
+            res = Math.max(res, f[n][j]);
+        }
+
+        return res;
+    }
+}
+
+// version 2
+class Solution {
+    /**
+     * @param k:      An integer
+     * @param prices: Given an integer array
+     * @return: Maximum profit
+     */
+    public int maxProfit(int k, int[] prices) {
+        // write your code here
+        if (k == 0) {
+            return 0;
+        }
+        if (k >= prices.length / 2) {
+            int profit = 0;
+            for (int i = 1; i < prices.length; i++) {
+                if (prices[i] > prices[i - 1]) {
+                    profit += prices[i] - prices[i - 1];
+                }
+            }
+            return profit;
+        }
+        int n = prices.length;
+        int[][] mustsell = new int[n + 1][n + 1]; // mustSell[i][j] 表示前i天，至多进行j次交易，第i天必须sell的最大获益
+        int[][] globalbest = new int[n + 1][n + 1]; // globalbest[i][j] 表示前i天，至多进行j次交易，第i天可以不sell的最大获益
+
+        mustsell[0][0] = globalbest[0][0] = 0;
+        for (int i = 1; i <= k; i++) {
+            mustsell[0][i] = globalbest[0][i] = 0;
+        }
+
+        for (int i = 1; i < n; i++) {
+            int gainorlose = prices[i] - prices[i - 1];
+            mustsell[i][0] = 0;
+            for (int j = 1; j <= k; j++) {
+                mustsell[i][j] = Math.max(globalbest[(i - 1)][j - 1] + gainorlose, mustsell[(i - 1)][j] + gainorlose);
+                globalbest[i][j] = Math.max(globalbest[(i - 1)][j], mustsell[i][j]);
+            }
+        }
+        return globalbest[(n - 1)][k];
+    }
+};
+
+// 方法二
+class Solution {
+    /**
+     * @param k:      An integer
+     * @param prices: Given an integer array
+     * @return: Maximum profit
+     */
+    private int update(int a, int b, int delta) {
+        if (b == Integer.MIN_VALUE) {
+            return a;
+        }
+
+        if (b + delta > a) {
+            return b + delta;
+        }
+
+        return a;
+    }
+
+    public int maxProfit(int K, int[] prices) {
+        int n = prices.length;
+        int i, j, k;
+        if (K == 0) {
+            return 0;
+        }
+
+        if (K >= n - 1) {
+            j = 0;
+            for (i = 1; i < n; ++i) {
+                if (prices[i] > prices[i - 1]) {
+                    j += prices[i] - prices[i - 1];
+                }
+            }
+
+            return j;
+        }
+
+        int[][] f = new int[n + 1][2 * K + 1];
+        for (i = 0; i <= n; ++i) {
+            for (j = 0; j <= 2 * K; ++j) {
+                f[i][j] = Integer.MIN_VALUE;
+            }
+        }
+
+        f[0][0] = 0;
+        for (i = 1; i <= n; ++i) {
+            int delta;
+            if (i == 1) {
+                delta = 0;
+            } else {
+                delta = prices[i - 1] - prices[i - 2];
+            }
+
+            f[i][0] = update(f[i][0], f[i - 1][0], 0);
+            for (j = 1; j <= 2 * K; j += 2) {
+                if (i > 1)
+                    f[i][j] = update(f[i][j], f[i - 1][j], delta);
+                if (i > 1)
+                    f[i][j] = update(f[i][j], f[i - 1][j - 1], delta);
+            }
+
+            for (j = 2; j <= 2 * K; j += 2) {
+                f[i][j] = update(f[i][j], f[i - 1][j], 0);
+                if (i > 1)
+                    f[i][j] = update(f[i][j], f[i - 1][j - 1], delta);
+                if (i > 1)
+                    f[i][j] = update(f[i][j], f[i - 1][j - 2], delta);
+            }
+        }
+
+        int res = Integer.MIN_VALUE;
+        for (j = 2; j <= 2 * K; j += 2) {
+            res = update(res, f[n][j], 0);
+        }
+
+        return res;
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock.md"
new file mode 100644
index 0000000..dca8fe7
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/best-time-to-buy-and-sell-stock.md"
@@ -0,0 +1,53 @@
+# 买卖股票的最佳时机
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <span style="line-height: 1.42857143;">假设有一个数组，它的第i个元素是一支给定的股票在第i天的价格。</span><span style="line-height: 1.42857143;">如果你最多只允许完成一次交易(例如,一次买卖股票),设计一个算法来找出最大利润。</span>
+ ### 样例说明
+ **样例1**
+
+```plain
+输入: [3, 2, 3, 1, 2]
+输出: 1
+说明：你可以在第三天买入，第四天卖出，利润是 2 - 1 = 1
+```
+
+**样例2**
+
+```plain
+输入: [1, 2, 3, 4, 5]
+输出: 4
+说明：你可以在第0天买入，第四天卖出，利润是 5 - 1 = 4
+```
+
+**样例3**
+
+```plain
+输入: [5, 4, 3, 2, 1]
+输出: 0
+说明：你可以不进行任何操作然后也得不到任何利润
+```
+
+
+ ### 参考代码
+ Say you have an array for which the ith element is the price of a given stock on day i.
+
+If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
+```java
+public class Solution {
+    public int maxProfit(int[] prices) {
+        if (prices == null || prices.length == 0) {
+            return 0;
+        }
+
+        int min = Integer.MAX_VALUE;  //just remember the smallest price
+        int profit = 0;
+        for (int i : prices) {
+            min = i < min ? i : min;
+            profit = (i - min) > profit ? i - min : profit;
+        }
+
+        return profit;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/can-place-flowers.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/can-place-flowers.md"
new file mode 100644
index 0000000..ccad4dc
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/can-place-flowers.md"
@@ -0,0 +1,38 @@
+# 能否放置花
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/can-place-flowers/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假设你有一个长花圃，其中有些地块已经被种植了，但是有些地块没有。但是，花不能够在相邻的地块下种植 - 他们会争夺水从而导致两者的死亡。
+
+给定一个花圃（用一个包含0和1的数组来表示，其中0代表空，1代表非空），和一个数字**n**，返回n朵新的花在这个花圃上以能否在不违反“无相邻花”的规则种植。
+ ### 样例说明
+ **样例1**
+```
+输入: flowerbed = [1,0,0,0,1], n = 1
+输出: True
+```
+**样例2**
+```
+输入: flowerbed = [1,0,0,0,1], n = 2
+输出: False
+```
+ ### 参考代码
+ 比较基础的模拟题，按照题目要求从头开始模拟种植即可。
+```java
+public class Solution {
+    public boolean canPlaceFlowers(int[] flowerbed, int n) {
+        int count = 0;
+        for (int i = 0; i < flowerbed.length; i++) {
+            if (flowerbed[i] == 0 && (i == 0 || flowerbed[i - 1] == 0)
+            && (i == flowerbed.length - 1 || flowerbed[i + 1] == 0)) {
+                flowerbed[i] = 1;
+                count++;
+            }
+            if (count >= n) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/candy.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/candy.md"
new file mode 100644
index 0000000..376ce3d
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/candy.md"
@@ -0,0 +1,41 @@
+# 分糖果
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/candy/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 有 `N` 个小孩站成一列。每个小孩有一个评级。给定数组 `ratings` 代表这些小孩的评级。
+
+现在你需要按照以下要求，给小孩们分糖果：
+
+* 每个小孩至少得到一颗糖果。 
+
+* 评级越高的小孩可以比他相邻的两个小孩得到更多的糖果。
+
+你最少要准备多少糖果？
+ ### 样例说明
+ 
+ ### 参考代码
+ 初始假定给每个小孩都分一颗糖果, 即设定一个全1的 count 数组.
+
+然后我们开始修正这个数组:
+
+首先从左到右遍历, 如果发现一个小孩左边的小孩比自己的 rating 低, 那么把这个小孩的糖果数设为他左边的小孩 + 1
+
+这时我们分配的糖果已经满足了: 评分更高的小孩比他左边的小孩获得更多的糖果. 然后我们再从右往左遍历一次就可以了. 
+
+但是这时还应该注意一点: 当一个小孩右边的小孩比自己的 rating 低时, 这个小孩的糖果可能已经比他右边的小孩多了, 而且可能多不止一个, 这时应该保留他的糖果数目不变.
+
+比如这组数据: [1, 2, 3, 4, 1], 初始 count 数组为 [1, 1, 1, 1, 1], 第一次遍历之后变成 [1, 2, 3, 4, 1], 第二次遍历不应该再改变这个数组了.
+```python
+class Solution:
+    # @param ratings, a list of integer
+    # @return an integer
+    def candy(self, ratings):
+        candynum = [1 for i in range(len(ratings))]
+        for i in range(1, len(ratings)):
+            if ratings[i] > ratings[i-1]:
+                candynum[i] = candynum[i-1] + 1
+        for i in range(len(ratings)-2, -1, -1):
+            if ratings[i+1] < ratings[i] and candynum[i+1] >= candynum[i]:
+                candynum[i] = candynum[i+1] + 1
+        return sum(candynum)
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/continuous-subarray-sum-ii.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/continuous-subarray-sum-ii.md"
new file mode 100644
index 0000000..a71b61d
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/continuous-subarray-sum-ii.md"
@@ -0,0 +1,64 @@
+# 连续子数组求和 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/continuous-subarray-sum-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数循环数组（头尾相接），请找出一个连续的子数组，使得该子数组的和最大。输出答案时，请分别返回第一个数字和最后一个数字的值。
+
+如果多个答案，请返回其中任意一个。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [3, 1, -100, -3, 4]
+输出: [4, 1]
+```
+
+**样例 2:**
+
+```
+输入: [1,-1]
+输出: [0, 0]
+```
+ ### 参考代码
+ 分两种情况讨论：
+
+1. 最大数组仍然是中间的某一段
+2. 最大数组是去掉了中间的一段之后剩下的部分
+
+第一种情况用传统的最大子数组做法走一遍(参考[题解](https://www.jiuzhang.com/solution/continuous-subarray-sum))。第二种做法稍微想一下就可以证明中间被去掉的那一段是整个数组的 minimum subarray。
+所以求一遍 minimum subarray 之后，比较两种情况, 取最优解即可
+
+需要特殊考虑 minimum subarray 是取了所有数的情况。
+```python
+class Solution:
+    """
+    @param: A: An integer array
+    @return: A list of integers includes the index of the first number and the index of the last number
+    """
+    def continuousSubarraySumII(self, A):
+        max_start, max_end, max_sum = self.find_maximum_subarray(A)
+        min_start, min_end, min_sum = self.find_maximum_subarray([-a for a in A])
+        min_sum = -min_sum  # *-1 after reuse find maximum array
+        
+        total = sum(A)
+        if max_sum >= total - min_sum or min_end - min_start + 1 == len(A):
+            return [max_start, max_end]
+        
+        return [min_end + 1, min_start - 1]
+        
+    def find_maximum_subarray(self, nums):
+        max_sum = -sys.maxsize
+        curt_sum, start = 0, 0
+        max_range = []
+        
+        for index, num in enumerate(nums):
+            if curt_sum < 0:
+                curt_sum = 0
+                start = index
+            curt_sum += num
+            if curt_sum > max_sum:
+                max_sum = curt_sum
+                max_range = [start, index]
+                
+        return max_range[0], max_range[1], max_sum
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/continuous-subarray-sum.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/continuous-subarray-sum.md"
new file mode 100644
index 0000000..db9bed2
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/continuous-subarray-sum.md"
@@ -0,0 +1,64 @@
+# 连续子数组求和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/continuous-subarray-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，请找出一个连续子数组，使得该子数组的和最大。输出答案时，请分别返回第一个数字和最后一个数字的下标。（如果存在多个答案，请返回字典序最小的）
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [-3, 1, 3, -3, 4]
+输出: [1, 4]
+```
+
+**样例 2:**
+
+```
+输入: [0, 1, 0, 1]
+输出: [0, 3]
+解释: 字典序最小.
+```
+ ### 参考代码
+ 枚举即可, 枚举的过程中维护以当前元素结尾的最大和.
+
+每次循环把当前元素加到这个和中, 在加上之前判断: 
+
+- 如果这个和是负数, 则放弃之前的元素, 把和置为0, 区间左端点设为当前元素
+- 如果是正数, 则直接累加.
+
+同时, 在枚举的过程中维护答案.
+
+详细过程见C++注释
+```java
+public class Solution {
+    /**
+     * @param A an integer array
+     * @return  A list of integers includes the index of the first number and the index of the last number
+     */
+    public ArrayList<Integer> continuousSubarraySum(int[] A) {
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        result.add(0);
+        result.add(0);
+
+        int len = A.length;
+        int start = 0, end = 0;
+        int sum = 0;
+        int ans = -0x7fffffff;
+        for (int i = 0; i < len; i++) {
+            if (sum < 0) {
+                sum = A[i];
+                start = end = i;
+            } else {
+                sum += A[i];
+                end = i;
+            }
+            if (sum > ans) {
+                ans = sum;
+                result.set(0, start);
+                result.set(1, end);
+            }
+        }
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/convert-a-number-to-hexadecimal.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/convert-a-number-to-hexadecimal.md"
new file mode 100644
index 0000000..bd8c4d4
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/convert-a-number-to-hexadecimal.md"
@@ -0,0 +1,89 @@
+# 将数字转换为16进制
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/convert-a-number-to-hexadecimal/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数，写一个函数将其转换为16进制。对于负整数，需要使用[**二进制补码**](https://en.wikipedia.org/wiki/Two%27s_complement "")。
+ ### 样例说明
+ **样例1**
+```
+输入：26
+输出："1a"
+```
+**样例2**
+```
+输入：-1
+输出："ffffffff"
+```
+ ### 参考代码
+ 辗转相除求十六进制
+```java
+// 方法一
+public class Solution {
+    public String toHex(int num) {
+        if(num == 0) {
+            return "0";
+        }
+        String ans = "";
+        int len = 0;
+        while(num != 0 && len < 8) {
+            //15的二进制：1111
+            int bit = num & 15;
+            if(bit < 10) {
+                //0 - 9
+                ans = (char)('0' + bit) + ans;
+            }
+            else {
+                //a - f
+                ans = (char)('a' + bit - 10) + ans;
+            }
+            //位运算，对二进制的num右移4位相当于除以16
+            num >>= 4;
+            len++;
+        }
+        return ans;
+    }
+}
+
+// 方法二：普通的辗转相除，区分正负整数分别计算
+public class Solution {
+    public String toHex(int num) {
+        if(num == 0) {
+            return "0";
+        }
+        int bit[] = new int[10];
+        int len = 0;
+        String ans = "";
+        for(int i=0; i<9; i++) {
+            bit[i] = 0;
+        }
+        long n = num;
+        n = n > 0? n : -n;
+        while(n > 0) {
+            bit[len++] = (int)n % 16;
+            n /= 16;
+        }
+        if(num < 0) {
+            for(int i=0; i<8; i++)
+            {
+                bit[i] = 15 - bit[i];
+            }
+            int pos = 0;
+            while(bit[pos] == 15)
+            {
+                bit[pos] = 0;
+                pos++;
+            }
+            bit[pos]++;
+        }
+        int leader0 = 1;
+        for(int i=7; i>=0; i--)
+        {    
+            if(bit[i] != 0) leader0 = 0;
+            if(leader0 == 1) continue;
+            if(bit[i] < 10) ans += (char)('0' + bit[i]);
+            else ans += (char)('a' + bit[i] - 10);
+        }
+        return ans;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/first-missing-positive.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/first-missing-positive.md"
new file mode 100644
index 0000000..a11d2e0
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/first-missing-positive.md"
@@ -0,0 +1,49 @@
+# 丢失的第一个正整数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/first-missing-positive/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出一个无序的整数数组，找出其中没有出现的最小正整数。
+ ### 样例说明
+ **样例 1:**
+```
+输入:[1,2,0]
+输出:3
+```
+
+**样例 2:**
+```
+输入:[3,4,-1,1]
+输出:2
+```
+ ### 参考代码
+ Given an unsorted integer array, find the first missing positive integer.&nbsp;<div><br></div><div>For example,&nbsp;</div><div>Given [1,2,0] return 3,&nbsp;</div><div>and [3,4,-1,1] return 2.&nbsp;</div><div><br></div><div>&nbsp;Your algorithm should run in O(n) time and uses constant space.</div><div><br></div><div><span style="color: rgb(102, 110, 112); font-family: 'Open Sans', Arial, sans-serif; line-height: 22.3999996185303px;">详细题解请见九章算法微博:&nbsp;</span><font color="#666e70" face="Open Sans, Arial, sans-serif"><span style="line-height: 22.3999996185303px;"><a href="http://weibo.com/3948019741/BDSXrEVB3" target="_blank">http://weibo.com/3948019741/BDSXrEVB3</a></span></font><br></div>
+```java
+public class Solution {
+
+    public int firstMissingPositive(int[] A) {
+        if (A == null) {
+            return 1;
+        }
+
+        for (int i = 0; i < A.length; i++) {
+            while (A[i] > 0 && A[i] <= A.length && A[i] != (i+1)) {
+                int tmp = A[A[i]-1];
+                if (tmp == A[i]) {
+                    break;
+                }
+                A[A[i]-1] = A[i];
+                A[i] = tmp;
+            }
+        }
+
+        for (int i = 0; i < A.length; i ++) {
+                if (A[i] != i + 1) {
+                    return i + 1;
+                }
+        }
+
+        return A.length + 1;
+    }
+}
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/flatten-2d-vector.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/flatten-2d-vector.md"
new file mode 100644
index 0000000..14c48a9
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/flatten-2d-vector.md"
@@ -0,0 +1,58 @@
+# 摊平二维向量
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/flatten-2d-vector/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 设计一个迭代器来实现摊平二维向量的功能
+ ### 样例说明
+ 例1:
+```
+输入:[[1,2],[3],[4,5,6]]
+输出:[1,2,3,4,5,6]
+```
+例2:
+```
+输入:[[7,9],[5]]
+输出:[7,9,5]
+```
+
+ ### 参考代码
+ 记录横纵坐标。这个版本的代码复杂一些，但是无所谓 next 和 hasNext 的调用顺序和次数。
+```python
+class Vector2D(object):
+
+    # @param vec2d {List[List[int]]}
+    def __init__(self, vec2d):
+        self.vec2d = vec2d
+        self.row, self.col = 0, -1
+        self.next_elem = None
+
+    # @return {int} a next element
+    def next(self):
+        if self.next_elem is None:
+            self.hasNext()
+            
+        temp, self.next_elem = self.next_elem, None
+        return temp
+
+    # @return {boolean} true if it has next element
+    # or false
+    def hasNext(self):
+        if self.next_elem:
+            return True
+        
+        self.col += 1
+        while self.row < len(self.vec2d) and self.col >= len(self.vec2d[self.row]):
+            self.row += 1
+            self.col = 0
+            
+        if self.row < len(self.vec2d) and self.col < len(self.vec2d[self.row]):
+            self.next_elem = self.vec2d[self.row][self.col]
+            return True
+            
+        return False
+        
+
+# Your Vector2D object will be instantiated and called as such:
+# i, v = Vector2D(vec2d), []
+# while i.hasNext(): v.append(i.next())
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/flip-string-to-monotone-increasing.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/flip-string-to-monotone-increasing.md"
new file mode 100644
index 0000000..c21d1ba
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/flip-string-to-monotone-increasing.md"
@@ -0,0 +1,51 @@
+# 将字符串翻转到单调递增
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/flip-string-to-monotone-increasing/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 如果一个由 `'0'` 和 `'1'` 组成的字符串，是以一些 `'0'`（可能没有 `'0'`）后面跟着一些 `'1'`（也可能没有 `'1'`）的形式组成的，那么该字符串是*单调递增*的。
+
+我们给出一个由字符 `'0'` 和 `'1'` 组成的字符串 `S`，我们可以将任何 `'0'` 翻转为 `'1'` 或者将 `'1'` 翻转为 `'0'`。
+
+返回使 `S` 单调递增的最小翻转次数。
+ ### 样例说明
+ **样例 1:**
+```
+输入："00110"
+输出：1
+解释：
+我们翻转最后一位得到 00111.
+```
+**样例 2:**
+```
+输入："010110"
+输出：2
+解释：
+我们翻转得到 011111，或者是 000111。
+```
+ ### 参考代码
+ 枚举法（Enumeration）
+使用 PrefixSum 记录某个位置及往左的位置上有多少个 1。
+循环每个位置，计算左侧变为 0，右侧变为 1 的耗费，记录下所有的耗费中的最小耗费。
+```java
+class Solution {
+    public int minFlipsMonoIncr(String S) {
+        int[] leftOnes = new int[S.length()];
+        int ones = 0;
+        for (int i = 0; i < S.length(); i++) {
+            if (S.charAt(i) == '1') {
+                ones++;
+            }
+            leftOnes[i] = ones;
+        }
+        
+        int flips = S.length() - ones;
+        for (int i = 0; i < S.length(); i++) {
+            int rightOnes = ones - leftOnes[i];
+            int rightZeroes = S.length() - i - 1 - rightOnes;
+            flips = Math.min(flips, leftOnes[i] + rightZeroes);
+        }
+                             
+        return flips;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/generate-arraylist-with-given-size.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/generate-arraylist-with-given-size.md"
new file mode 100644
index 0000000..4977ca8
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/generate-arraylist-with-given-size.md"
@@ -0,0 +1,40 @@
+# 生成给定大小的数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/generate-arraylist-with-given-size/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个大小size,生成一个元素`从1 到 size`的数组
+ ### 样例说明
+ ```
+样例 1:
+	输入:  size = 4
+	输出: [1, 2, 3, 4]
+	
+	样例解释: 
+	 返回一个顺序填充1到4的数组。
+	 
+样例 2:
+	输入:  size = 1
+	输出: [1]
+	
+	样例解释: 
+	返回一个顺序填充1到1的数组
+	
+```
+
+ ### 参考代码
+ 基本模拟
+```java
+public class Solution {
+    /**
+     * @param size an integer
+     * @return an array list
+     */
+    public ArrayList<Integer> generate(int size) {
+        // Write your code here
+        ArrayList<Integer> result = new ArrayList<Integer>();
+        for (int i = 1; i <= size; ++i)
+            result.add(i);
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/implement-deque-by-circulant-array.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/implement-deque-by-circulant-array.md"
new file mode 100644
index 0000000..7b51357
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/implement-deque-by-circulant-array.md"
@@ -0,0 +1,192 @@
+# 用循环数组实现双向队列
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/implement-deque-by-circulant-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 用循环数组来实现双端队列。你需要支持下列方法：
+CircularDeque(n): 初始化一个大小为n的循环数组来存储元素
+boolean isFull(): 如果数组满了就返回 true
+boolean isEmpty(): 如果数组为空则返回 true
+void pushFront(element): 往队列的头部添加一个元素
+int popFront(): 从队列的头部弹出一个元素
+void pushBack(element): 往队列的尾部添加一个元素
+int popBack(): 从队列的尾部弹出一个元素
+ ### 样例说明
+ 
+ ### 参考代码
+ ### 数据结构设计
+#### 算法思路
+设计一个管理下标的函数，将任意下标转化为合法下标$(0 \leq i \le n)$
+用$front$ $rear$ $size$分别记录数组的头、尾、大小
+对于构造函数$CircularDeque$，需要初始化数组和$front$ $rear$ $size$，因为一开始数组大小为$0$，所以$front$需要比$rear$后一个位置
+对于$isEmpty$ $isFull$两个方法，可以对$size$进行判断
+对于四个涉及数组操作的方法，先找到需要处理的位置，处理完毕之后再修改数组的$front$ $rear$ $size$信息
+
+#### 复杂度分析
+- 时间复杂度为 $O(n)$
+    - n为数组的大小，因为初始化数组需要开辟大小为n的空间，除了构造函数$CircularDeque$外的函数时间复杂度均为 $O(1)$
+- 空间复杂度为 $O(n)$
+    - n为数组的大小，因为初始化数组需要开辟大小为n的空间
+
+```
+[[java]]
+public class CircularDeque {    
+    int[] circularArray;
+    int front;
+    int rear;
+    int size;
+    
+    public CircularDeque(int n) {
+        this.circularArray = new int[n];
+        front = getCircularIndex(1);
+        rear = getCircularIndex(0);
+        size = 0;
+    }
+    
+    private int getCircularIndex(int p) {
+        int len = circularArray.length;
+        return (p % len + len) % len;
+    }
+    
+    public boolean isFull() {
+        return size == circularArray.length;
+    }
+
+    public boolean isEmpty() {
+        return size == 0;
+    }
+
+    public void pushFront(int element) {
+        int index = getCircularIndex(front - 1);
+        circularArray[index] = element;
+        front = index;
+        size++;
+    }
+     
+    public void pushBack(int element) {
+        int index = getCircularIndex(rear + 1);
+        circularArray[index] = element;
+        rear = index;
+        size++;
+    }
+
+    public int popFront() {
+        int index = front;
+        int ele = circularArray[index];
+        front = getCircularIndex(index + 1);
+        size--;
+        return ele;
+    }
+    
+    public int popBack() {
+        int index = rear;
+        int ele = circularArray[index];
+        rear = getCircularIndex(index - 1);
+        size--;
+        return ele;
+    }
+}
+
+[[cpp]]
+class CircularDeque {
+public:
+    vector<int> circularArray;
+    int front;
+    int rear;
+    int size;
+    
+    CircularDeque(int n) {
+        circularArray.resize(n, 0);
+        front = getCircularIndex(1);
+        rear = getCircularIndex(0);
+        size = 0;
+    }
+    
+    bool isFull() {
+        return size == circularArray.size();
+    }
+
+    bool isEmpty() {
+        return size == 0;
+    }
+
+    void pushFront(int element) {
+        int index = getCircularIndex(front - 1);
+        circularArray[index] = element;
+        front = index;
+        size++;
+    }
+
+    int popFront() {
+        int index = front;
+        int ele = circularArray[index];
+        front = getCircularIndex(index + 1);
+        size--;
+        return ele;
+    }
+
+    void pushBack(int element) {
+        int index = getCircularIndex(rear + 1);
+        circularArray[index] = element;
+        rear = index;
+        size++;
+    }
+
+    int popBack() {
+        int index = rear;
+        int ele = circularArray[index];
+        rear = getCircularIndex(index - 1);
+        size--;
+        return ele;
+    }
+    
+private:
+    int getCircularIndex(int p) {
+        int len = circularArray.size();
+        return (p % len + len) % len;
+    }
+};
+
+[[python]]
+class CircularDeque:
+    def __init__(self, n):
+        self.circularArray = [0] * n
+        self.front, self.rear = 1, 0
+        self.size = 0
+    
+    def getCircularIndex(self, p):
+        length = len(self.circularArray)
+        return (p % length + length) % length
+    
+    def isFull(self):
+        return self.size == len(self.circularArray)
+
+    def isEmpty(self):
+        return self.size == 0
+
+    def pushFront(self, element):
+        index = self.getCircularIndex(self.front - 1);
+        self.circularArray[index] = element;
+        self.front = index;
+        self.size += 1;
+        
+    def popFront(self):
+        index = self.front;
+        ele = self.circularArray[index];
+        self.front = self.getCircularIndex(index + 1);
+        self.size -= 1;
+        return ele;
+        
+    def pushBack(self, element):
+        index = self.getCircularIndex(self.rear + 1);
+        self.circularArray[index] = element;
+        self.rear = index;
+        self.size += 1;
+
+    def popBack(self):
+        index = self.rear;
+        ele = self.circularArray[index];
+        self.rear = self.getCircularIndex(index - 1);
+        self.size -= 1;
+        return ele;
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/implement-stack.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/implement-stack.md"
new file mode 100644
index 0000000..2885bf5
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/implement-stack.md"
@@ -0,0 +1,59 @@
+# 实现栈
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/implement-stack/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 实现一个栈，可以使用除了栈之外的数据结构
+ ### 样例说明
+ 例1:
+```
+输入：
+push(1)
+pop()
+push(2)
+top()  // return 2
+pop()
+isEmpty() // return true
+push(3)
+isEmpty() // return false
+```
+例2:
+```
+输入：
+isEmpty()
+
+```
+ ### 参考代码
+ 实现栈的基本操作
+```java
+class Stack {
+    // Push a new item into the stack
+    public void push(int x) {
+        // Write your code here
+        array.add(x);
+    }
+
+    // Pop the top of the stack
+    public void pop() {
+        // Write your code here
+        int n = array.size();
+        if (n > 0)
+            array.remove(n-1);
+        return;
+    }
+
+    // Return the top of the stack
+    public int top() {
+        // Write your code here
+        int n = array.size();
+        return array.get(n-1);
+    }
+
+    // Check the stack is empty or not.
+    public boolean isEmpty() {
+        // Write your code here
+        return array.size() == 0;
+    }
+
+    private List<Integer> array = new ArrayList<Integer>();
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/intersection-of-arrays.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/intersection-of-arrays.md"
new file mode 100644
index 0000000..f3ff255
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/intersection-of-arrays.md"
@@ -0,0 +1,98 @@
+# 多个数组的交集
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/intersection-of-arrays/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出多个数组，求它们的交集。输出他们交集的大小。
+ ### 样例说明
+ **样例 1:**
+```
+	输入:  [[1,2,3],[3,4,5],[3,9,10]]
+	输出:  1
+	
+	解释:
+	只有3出现在三个数组中。
+```
+	
+**样例 2:**
+```
+	输入: [[1,2,3,4],[1,2,5,6,7][9,10,1,5,2,3]]
+	输出:  2
+	
+	解释:
+	交集是[1,2].
+```
+
+
+ ### 参考代码
+ 基于 Priority Queue 的版本。
+假设每个数组长度为 n, 一共 k 个数组。
+时间复杂度为 $O(knlogn + nklogk)$
+其中 $knlogn$ 是 k 个数组进行分别排序的时间复杂度
+$nklogk$ 是 总共 nk 个数从 PriorityQueue 中进出，每次进出 logk。
+
+相比使用 HashMap 的算法的时间复杂度 $O(nk)$ 这个方法并没有什么时间上的优势。
+但是这个方法的空间复杂度很低，只有 $O(k)$，即多少个数组就花费多少的额外空间。
+
+在面试中也是很有可能会被要求不用 HashMap 或者实现一个比 $O(n)$ 更低的空间复杂度的算法。因此这个程序的方法也是需要掌握的。
+```java
+public class Solution {
+    class Pair {
+        public int row, col;
+        
+        public Pair(int row, int col) {
+            this.row = row;
+            this.col = col;
+        }
+    }
+    
+    /**
+     * @param arrs: the arrays
+     * @return: the number of the intersection of the arrays
+     */
+    public int intersectionOfArrays(int[][] arrs) {
+        Comparator<Pair> comparator = new Comparator<Pair>() {
+          public int compare(Pair x, Pair y) {
+            return arrs[x.row][x.col] - arrs[y.row][y.col];
+          }
+        };
+        
+        Queue<Pair> queue = new PriorityQueue<>(arrs.length, comparator);
+        
+        for (int i = 0; i < arrs.length; i++) {
+            if (arrs[i].length == 0) {
+                return 0;
+            }
+            
+            Arrays.sort(arrs[i]);
+            queue.offer(new Pair(i, 0));
+        }
+        
+        int lastValue = 0, count = 0;
+        int intersection = 0;
+        while (!queue.isEmpty()) {
+            Pair pair = queue.poll();
+            if (arrs[pair.row][pair.col] != lastValue || count == 0) {
+                if (count == arrs.length) {
+                  intersection++;
+                }
+                lastValue = arrs[pair.row][pair.col];
+                count = 1;
+            } else {
+                count++;
+            }
+            
+            pair.col++;
+            if (pair.col < arrs[pair.row].length) {
+              queue.offer(pair);
+            }
+        }
+        
+        // kickoff the last number
+        if (count == arrs.length) {
+            intersection++;
+        }
+        
+        return intersection;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/k-closest-numbers-in-sorted-array.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/k-closest-numbers-in-sorted-array.md"
new file mode 100644
index 0000000..be9c46c
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/k-closest-numbers-in-sorted-array.md"
@@ -0,0 +1,72 @@
+# 在排序数组中找最接近的K个数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/k-closest-numbers-in-sorted-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个目标数 `target`, 一个非负整数 `k`, 一个按照升序排列的数组 `A`。在`A`中找与`target`最接近的`k`个整数。返回这`k`个数并按照与`target`的接近程度从小到大排序，如果接近程度相当，那么小的数排在前面。
+ ### 样例说明
+ 
+ ### 参考代码
+ 直接在数组中二分查找 `target`, 如果不存在则返回大于 `target` 的最小的或者小于 `target` 的最大的元素均可.
+
+然后使用两根指针从该位置开始向两端遍历, 每次把差值比较小的元素放入答案中然后将该指针向边界方向移动一下即可.
+```java
+public class Solution {
+    /**
+     * @param A      an integer array
+     * @param target an integer
+     * @param k      a non-negative integer
+     * @return an integer array
+     */
+    public int[] kClosestNumbers(int[] A, int target, int k) {
+        int[] result = new int[k];
+
+        if (A == null || A.length == 0) {
+            return A;
+        }
+        if (k > A.length) {
+            return A;
+        }
+
+        int index = firstIndex(A, target);
+
+        int start = index - 1;
+        int end = index;
+        for (int i = 0; i < k; i++) {
+            if (start < 0) {
+                result[i] = A[end++];
+            } else if (end >= A.length) {
+                result[i] = A[start--];
+            } else {
+                if (target - A[start] <= A[end] - target) {
+                    result[i] = A[start--];
+                } else {
+                    result[i] = A[end++];
+                }
+            }
+        }
+        return result;
+    }
+
+    private int firstIndex(int[] A, int target) {
+        int start = 0, end = A.length - 1;
+        while (start + 1 < end) {
+            int mid = start + (end - start) / 2;
+            if (A[mid] < target) {
+                start = mid;
+            } else if (A[mid] > target) {
+                end = mid;
+            } else {
+                end = mid;
+            }
+        }
+
+        if (A[start] >= target) {
+            return start;
+        }
+        if (A[end] >= target) {
+            return end;
+        }
+        return A.length;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/max-of-array.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/max-of-array.md"
new file mode 100644
index 0000000..76f6150
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/max-of-array.md"
@@ -0,0 +1,39 @@
+# 数组的最大值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/max-of-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个浮点数数组，求数组中的最大值。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:  [1.0, 2.1, -3.3]
+输出: 2.1	
+样例解释: 返回最大的数字
+```
+**样例 2:**
+
+```
+输入:  [1.0, 1.0, -3.3]
+输出: 1.0	
+样例解释: 返回最大的数字。
+```
+ ### 参考代码
+ 模拟过程
+```java
+public class Solution {
+    /**
+     * @param A a float array
+     * @return a float number
+     */
+    public float maxOfArray(float[] A) {
+        float max = A[0];
+        for (int i = 1; i < A.length; i++) {
+            if (A[i] > max) {
+                max = A[i];
+            }
+        }
+        return max;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/minimum-moves-to-equal-array-elements-ii.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/minimum-moves-to-equal-array-elements-ii.md"
new file mode 100644
index 0000000..ed41b37
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/minimum-moves-to-equal-array-elements-ii.md"
@@ -0,0 +1,73 @@
+# 使数组元素相同的最少步数 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-moves-to-equal-array-elements-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个**非空**的整数数组，找出使得数组中所有元素相同的最少步数，其中一步被定义为将数组内任一元素加一或减一。
+
+数组中最多包含10,000个元素。
+ ### 样例说明
+ 例1:
+```
+输入：
+[1,2,3]
+
+输出：
+2
+
+说明：
+只需要两步即可（每一步将一个元素加一或减一）：
+
+[1,2,3]  =>  [2,2,3]  =>  [2,2,2]
+```
+
+例2:
+```
+输入：
+[1,2]
+
+输出：
+1
+
+说明：
+只需要一步即可（每一步将一个元素加一或减一）：
+
+[1,2]  =>  [2,2]
+```
+ ### 参考代码
+ 先找到数组的中位值，查找过程基于快速排序的思想，再计算所有的数与中位数之差的和作为结果。
+```java
+public class Solution {
+    public int minMoves2(int[] nums) {
+
+        int median = quickselect(nums, 0, nums.length-1, (nums.length + 1) / 2);
+        int minmoves = 0;
+
+        for(int i = 0; i < nums.length; ++ i){
+            minmoves += Math.abs( median - nums[i] );
+        }
+        return minmoves;
+    }
+    private int quickselect(int[] nums, int start, int end, int size) {
+        int mid = (start + end) / 2;
+        int pivot = nums[mid];
+        int i = start - 1, j = end + 1;
+        for (int k = start; k < j; k++) {
+            if (nums[k] < pivot) {
+                i++;
+                swap(nums[i],nums[k]);
+            } else if (nums[k] > pivot) {
+                j--;
+                swap(nums[j],nums[k]);
+                k--;
+            }
+        }
+        if (i - start + 1 >= size) {
+            return quickselect(nums, start, i, size);
+        } else if (j - start >= size) {
+            return nums[j-1];
+        } else {
+            return quickselect(nums, j, end, size - (j - start));
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/minimum-moves-to-equal-array-elements.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/minimum-moves-to-equal-array-elements.md"
new file mode 100644
index 0000000..37583c5
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/minimum-moves-to-equal-array-elements.md"
@@ -0,0 +1,33 @@
+# 使数组元素相同的最少步数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/minimum-moves-to-equal-array-elements/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个大小为`n`的**非空**整数数组，找出使得数组中所有元素相同的最少步数，其中一步被定义为将数组中`n - 1`个元素加一。
+ ### 样例说明
+ ```
+输入：
+[1,2,3]
+
+输出：
+3
+
+说明：
+只需要三步即可（每一步将其中两个元素加一）：
+
+[1,2,3]  =>  [2,3,3]  =>  [3,4,3]  =>  [4,4,4]
+```
+ ### 参考代码
+ ```cpp
+class Solution {
+public:
+    int minMoves(vector<int>& nums) {
+        int sumNum = 0;
+        int minNum = INT_MAX;
+        for (int num : nums) {
+            sumNum += num;
+            minNum = min(minNum, num);
+        }
+        return sumNum - minNum * nums.size();
+    }
+};
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/missing-interval.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/missing-interval.md"
new file mode 100644
index 0000000..360d76d
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/missing-interval.md"
@@ -0,0 +1,112 @@
+# 丢失的间隔
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/missing-interval/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个排序整数数组，**其中元素的取值范围为[lower，upper] (包括边界)**，返回其缺少的范围。
+ ### 样例说明
+ 
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param nums a sorted integer array
+     * @param lower an integer
+     * @param upper an integer
+     * @return a list of its missing ranges
+     */
+    public List<String> findMissingRanges(int[] nums, int lower, int upper) {
+        // Write your code here
+        List<String> results = new ArrayList<String>();
+    
+        int n = nums.length;
+        for (int i = 0; i < n; ++i) {
+            if (nums[i] == Integer.MIN_VALUE) {
+                lower = nums[i] + 1; 
+                continue;
+            }
+            if (lower == nums[i] - 1) {
+                results.add(lower + "");
+            } else if (lower < nums[i] - 1) {
+                results.add(lower + "->" + (nums[i] - 1));
+            }
+            if (nums[i] == Integer.MAX_VALUE) {
+                return results;
+            }
+            lower = nums[i] + 1;
+        }
+        if (lower == upper) {
+            results.add(lower + "");
+        } else if (lower < upper) {
+            results.add(lower + "->" + upper);
+        }
+        return results;
+    }
+}
+
+// version: 高频题班
+public class Solution {
+    /**
+     * @param nums  a sorted integer array
+     * @param lower an integer
+     * @param upper an integer
+     * @return a list of its missing ranges
+     */
+
+    /*
+    public List<String> findMissingRanges(int[] nums, int lower, int upper) {
+        // Write your code here
+        List<String> ans = new ArrayList<>();
+
+        addRange(ans, lower, nums[0] - 1);
+
+        for (int i = 1; i < nums.length; i++) {
+            addRange(ans, nums[i - 1] + 1, nums[i] - 1);
+        }
+        addRange(ans, nums[nums.length - 1] + 1, upper);
+
+        return ans;
+    }
+
+    void addRange(List<String> ans, int st, int ed) {
+        if (st > ed) {
+            return;
+        }
+        if (st == ed) {
+            ans.add(st + "");
+            return;
+        }
+        ans.add(st + "->" + ed);
+    }*/
+
+    
+    public List<String> findMissingRanges(int[] nums, int lower, int upper) {
+        // Write your code here
+        List<String> ans = new ArrayList<>();
+        if (nums.length == 0) {
+            addRange(ans, lower, upper);
+            return ans;
+        }
+
+        addRange(ans, lower, (long) nums[0] - 1);
+
+        for (int i = 1; i < nums.length; i++) {
+            addRange(ans, (long) nums[i - 1] + 1, (long) nums[i] - 1);
+        }
+        addRange(ans, (long) nums[nums.length - 1] + 1, upper);
+
+        return ans;
+    }
+
+    void addRange(List<String> ans, long st, long ed) {
+        if (st > ed) {
+            return;
+        }
+        if (st == ed) {
+            ans.add(st + "");
+            return;
+        }
+        ans.add(st + "->" + ed);
+    }
+    
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/number-of-airplanes-in-the-sky.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/number-of-airplanes-in-the-sky.md"
new file mode 100644
index 0000000..4606198
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/number-of-airplanes-in-the-sky.md"
@@ -0,0 +1,55 @@
+# 数飞机
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/number-of-airplanes-in-the-sky/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出飞机的起飞和降落时间的列表，用序列 `interval` 表示. 请计算出天上同时最多有多少架飞机？
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [(1, 10), (2, 3), (5, 8), (4, 7)]
+输出: 3
+解释: 
+第一架飞机在1时刻起飞, 10时刻降落.
+第二架飞机在2时刻起飞, 3时刻降落.
+第三架飞机在5时刻起飞, 8时刻降落.
+第四架飞机在4时刻起飞, 7时刻降落.
+在5时刻到6时刻之间, 天空中有三架飞机.
+```
+
+**样例 2:**
+
+```
+输入: [(1, 2), (2, 3), (3, 4)]
+输出: 1
+解释: 降落优先于起飞.
+```
+ ### 参考代码
+ 使用九章算法强化班中讲过的扫描线算法
+```python
+"""
+Definition of Interval.
+class Interval(object):
+    def __init__(self, start, end):
+        self.start = start
+        self.end = end
+"""
+
+class Solution:
+    """
+    @param airplanes: An interval array
+    @return: Count of airplanes are in the sky.
+    """
+    def countOfAirplanes(self, airplanes):
+        points = []
+        for airplane in airplanes:
+            points.append([airplane.start, 1])
+            points.append([airplane.end, -1])
+            
+        number_of_airplane, max_number_of_airplane = 0, 0
+        for _, count_delta in sorted(points):
+            number_of_airplane += count_delta
+            max_number_of_airplane = max(max_number_of_airplane, number_of_airplane)
+            
+        return max_number_of_airplane
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/product-of-array-exclude-itself.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/product-of-array-exclude-itself.md"
new file mode 100644
index 0000000..e6945bd
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/product-of-array-exclude-itself.md"
@@ -0,0 +1,60 @@
+# 数组剔除元素后的乘积
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/product-of-array-exclude-itself/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组A。
+定义`B[i] = A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1]`， 计算B的时候请不要使用除法。请输出B。
+ ### 样例说明
+ **样例 1**
+```
+输入: A = [1, 2, 3]
+输出: [6, 3, 2]
+解析：B[0] = A[1] * A[2] = 6; B[1] = A[0] * A[2] = 3; B[2] = A[0] * A[1] = 2
+```
+**样例 2**
+```
+输入: A = [2, 4, 6]
+输出: [24, 12, 8]
+```
+ ### 参考代码
+ 分两次循环
+第一次记录数组从后往前的累乘结果，f[i]代表i位之后所有元素的乘积
+第二次循环，从左往右，跳过 i 左侧累乘，右侧直接乘以f[i + 1]
+```java
+import java.util.ArrayList;
+
+public class Solution {
+    /**
+     * @param nums: Given an integers array A
+     * @return: A Long array B and B[i]= A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1]
+     */
+    public ArrayList<Long> productExcludeItself(ArrayList<Integer> A) {
+        int len = A.size();
+        ArrayList<Long> B = new  ArrayList<Long>();
+        long[] f = new long[len];
+
+        long tmp = 1;
+        long now = 1;
+        f[len-1] = A.get(len-1);
+        int i ;
+        for ( i = len-2; i >= 0; --i)
+        {
+            f[i] = A.get(i);
+            f[i] = f[i] * f[i+1];
+        }
+
+        for ( i = 0; i < len; ++i) {
+			
+            now = tmp;
+            if(i+1<len)
+                B.add( now * f[i+1] );
+            else
+                B.add( now );
+            now = A.get(i);
+            tmp = tmp * now;
+
+        }
+        return B;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/remove-duplicates-from-sorted-array-ii.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/remove-duplicates-from-sorted-array-ii.md"
new file mode 100644
index 0000000..4ba2fb7
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/remove-duplicates-from-sorted-array-ii.md"
@@ -0,0 +1,48 @@
+# 删除排序数组中的重复数字 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-duplicates-from-sorted-array-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个排序数组，删除其中的重复元素，使得每个数字最多出现两次，返回新的数组的长度。
+如果一个数字出现超过2次，则这个数字最后保留两个。
+ ### 样例说明
+ ```
+样例 1:
+	输入: []
+	输出: 0
+
+
+样例 2:
+	输入:  [1,1,1,2,2,3]
+	输出: 5
+	
+	样例解释: 
+	长度为 5，  数组为：[1,1,2,2,3]
+```
+ ### 参考代码
+ 从重复的第三个开始删除即可
+```java
+public class Solution {
+    /**
+     * @param A: a array of integers
+     * @return : return an integer
+     */
+    public int removeDuplicates(int[] nums) {
+        if (nums == null || nums.length == 0) {
+            return 0;
+        }
+        int index = 0, count = 1;
+        for (int i = 1; i < nums.length; i++) {
+            if (nums[i] == nums[index]) {
+                if (count < 2) {
+                    nums[++index] = nums[i];
+                    count ++;
+                }
+            } else {
+                nums[++index] = nums[i];
+                count = 1;
+            }
+        }
+        return index + 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/remove-duplicates-from-sorted-array.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/remove-duplicates-from-sorted-array.md"
new file mode 100644
index 0000000..e17b720
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/remove-duplicates-from-sorted-array.md"
@@ -0,0 +1,51 @@
+# 删除排序数组中的重复数字
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/remove-duplicates-from-sorted-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个排序数组，在原数组中“删除”重复出现的数字，使得每个元素只出现一次，并且返回“新”数组的长度。
+
+不要使用额外的数组空间，必须在不使用额外空间的条件下原地完成。
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:  []
+输出: 0
+```
+
+**样例 2:**
+
+```
+输入:  [1,1,2]
+输出: 2	
+解释:  数字只出现一次的数组为: [1,2]
+```
+ ### 参考代码
+ Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.
+
+Do not allocate extra space for another array, you must do this in place with constant memory.
+
+For example,
+Given input array A = [1,1,2],
+
+Your function should return length = 2, and A is now [1,2].
+
+由于有序，所以相同的数字排在一起。
+用一个游标变量指向已经去重的部分的下一个空位，只要$a[i] != a[i-1]$,就将a[i]填入之前的空位。
+```java
+public class Solution {
+    public int removeDuplicates(int[] A) {
+        if (A == null || A.length == 0) {
+            return 0;
+        }
+        
+        int size = 0;
+        for (int i = 0; i < A.length; i++) {
+            if (A[i] != A[size]) {
+                A[++size] = A[i];
+            }
+        }
+        return size + 1;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/reorder-array-to-construct-the-minimum-number.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/reorder-array-to-construct-the-minimum-number.md"
new file mode 100644
index 0000000..dcc76ad
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/reorder-array-to-construct-the-minimum-number.md"
@@ -0,0 +1,70 @@
+# 将数组重新排序以构造最小值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/reorder-array-to-construct-the-minimum-number/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，请将其重新排序，以构造最小值。
+ ### 样例说明
+ **样例 1：**
+```
+输入：[2, 1]
+输出：[1, 2]
+解释：通过将数组重新排序，可构造 2 个可能性数字：
+           1+2=12
+           2+1=21
+其中，最小值为 12，所以，将数组重新排序后，该数组变为 [1, 2]。
+```
+
+**样例 2：**
+```
+输入：[3, 32, 321]
+输出：[321, 32, 3]
+解释：通过将数组重新排序，可构造 6 个可能性数字：
+	3+32+321=332321
+	3+321+32=332132
+	32+3+321=323321
+	32+321+3=323213
+	321+3+32=321332
+	321+32+3=321323
+其中，最小值为 321323，所以，将数组重新排序后，该数组变为 [321, 32, 3]。
+```
+ ### 参考代码
+ ```java
+public class Solution {
+    /**
+     * @param nums n non-negative integer array
+     * @return a string
+     */
+    public String minNumber(int[] nums) {
+        // Write your code here
+        int n = nums.length;
+        if (n < 1) return "";
+        
+        String[] strs = new String[n];
+        for (int i = 0; i < n; i++) {
+            strs[i] = String.valueOf(nums[i]);
+        }
+        
+        Arrays.sort(strs, new Cmp());
+        
+        String ans = "";
+        for (int i = n - 1; i >= 0; i--) {
+        	ans = ans.concat(strs[i]);
+        }
+        
+        int i = 0;
+        while (i < n && ans.charAt(i) == '0')
+            i ++;
+
+        if (i == n) return "0";
+        return ans.substring(i);
+    }
+}
+class Cmp implements Comparator<String>{
+    @Override
+    public int compare(String a, String b) {
+        String ab = a.concat(b);
+        String ba = b.concat(a);
+        return ba.compareTo(ab);
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/rotate-image.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/rotate-image.md"
new file mode 100644
index 0000000..ea35079
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/rotate-image.md"
@@ -0,0 +1,95 @@
+# 旋转图像
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/rotate-image/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">给定一个N×N的二维矩阵表示图像，90度顺时针旋转图像。</span><br></p><p><br></p>
+ ### 样例说明
+ **样例1：**
+```
+输入:[[1,2],[3,4]]
+输出:[[3,1],[4,2]]
+```
+
+**样例 2:**
+```
+输入:[[1,2,3],[4,5,6],[7,8,9]]
+输出:[[7,4,1],[8,5,2],[9,6,3]]
+```
+
+ ### 参考代码
+ You are given an n x n 2D matrix representing an image.
+
+Rotate the image by 90 degrees (clockwise).
+
+Follow up:
+Could you do this in-place?
+```java
+public class Solution {
+    public void rotate(int[][] matrix) {
+        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
+            return;
+        }
+
+        int length = matrix.length;
+
+        for (int i = 0; i < length / 2; i++) {
+            for (int j = 0; j < (length + 1) / 2; j++){
+                int tmp = matrix[i][j];
+                matrix[i][j] = matrix[length - j - 1][i];
+                matrix[length -j - 1][i] = matrix[length - i - 1][length - j - 1];
+                matrix[length - i - 1][length - j - 1] = matrix[j][length - i - 1];
+                matrix[j][length - i - 1] = tmp;
+            }
+        }   
+    }
+}
+
+
+// version: 高频题班
+//方法一
+public class Solution {
+    /**
+     * @param matrix: A list of lists of integers
+     * @return: Void
+     */
+    public void rotate(int[][] matrix) {
+        // write your code here
+        int n = matrix.length;
+        for (int r = 0; r < (n + 1) / 2; r++) {
+            for (int c = 0; c < n / 2; c++) {
+                int tmp = matrix[r][c];
+                matrix[r][c] = matrix[n - 1 - c][r];
+                matrix[n - 1 - c][r] = matrix[n - 1 - r][n - 1 - c];
+                matrix[n - 1 - r][n - 1 - c] = matrix[c][n - 1 - r];
+                matrix[c][n - 1 - r] = tmp;
+            }
+        }
+    }
+}
+
+//方法二：
+public class Solution {
+    /**
+     * @param matrix: A list of lists of integers
+     * @return: Void
+     */
+    public void rotate(int[][] matrix) {
+        // write your code here
+        int n = matrix.length;
+        for (int r = 0; r < n / 2; r++) {
+            for (int c = 0; c < n; c++) {
+                int tmp = matrix[r][c];
+                matrix[r][c] = matrix[n - r - 1][c];
+                matrix[n - r - 1][c] = tmp;
+            }
+        }
+        for (int r = 0; r < n; r++) {
+            for (int c = r; c < n; c++) {
+                int tmp = matrix[r][c];
+                matrix[r][c] = matrix[c][r];
+                matrix[c][r] = tmp;
+            }
+        }
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/search-a-2d-matrix-ii.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/search-a-2d-matrix-ii.md"
new file mode 100644
index 0000000..ca0bd86
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/search-a-2d-matrix-ii.md"
@@ -0,0 +1,52 @@
+# 搜索二维矩阵 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/search-a-2d-matrix-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ <p><span style="line-height: 1.42857143;">写出一个高效的算法来搜索m×n矩阵中的值，返回这个值出现的次数。</span></p><p><span style="line-height: 1.42857143;">这个矩阵具有以下特性：</span><br></p><p><ul><li><span style="line-height: 1.42857143;">每行中的整数从左到右是排序的。</span><br></li><li><span style="line-height: 1.42857143;">每一列的整数从上到下是排序的。</span><br></li><li><span style="line-height: 1.42857143;">在每一行或每一列中没有重复的整数。</span></li></ul></p>
+ ### 样例说明
+ 例1:
+```
+输入:
+[[3,4]]
+target=3
+输出:1
+```
+例2:
+```
+输入:
+    [
+      [1, 3, 5, 7],
+      [2, 4, 7, 8],
+      [3, 5, 9, 10]
+    ]
+    target = 3
+输出:2
+```
+
+ ### 参考代码
+ 从左下角开始，往右上角逼近
+```python
+class Solution:
+    """
+    @param matrix: An list of lists of integers
+    @param target: An integer you want to search in matrix
+    @return: An integer indicates the total occurrence of target in the given matrix
+    """
+    def searchMatrix(self, matrix, target):
+        if matrix == [] or matrix[0] == []:
+            return 0
+            
+        row, column = len(matrix), len(matrix[0])
+        i, j = row - 1, 0
+        count = 0
+        while i >= 0 and j < column:
+            if matrix[i][j] == target:
+                count += 1
+                i -= 1
+                j += 1
+            elif matrix[i][j] < target:
+                j += 1
+            elif matrix[i][j] > target:
+                i -= 1
+        return count
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/search-in-rotated-sorted-array.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/search-in-rotated-sorted-array.md"
new file mode 100644
index 0000000..91054f3
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/search-in-rotated-sorted-array.md"
@@ -0,0 +1,51 @@
+# 搜索旋转排序数组
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/search-in-rotated-sorted-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 假设有一个排序的按未知的旋转轴旋转的数组(比如，`0 1 2 4 5 6 7` 可能成为`4 5 6 7 0 1 2`)。给定一个目标值进行搜索，如果在数组中找到目标值返回数组中的索引位置，否则返回-1。你可以假设数组中不存在重复的元素。
+ ### 样例说明
+ 例1:
+```
+输入: [4, 5, 1, 2, 3] and target=1, 
+输出: 2.
+```
+例2:
+```
+输入: [4, 5, 1, 2, 3] and target=0, 
+输出: -1.
+```
+
+ ### 参考代码
+ 用一次二分法（按照九章算法课上的讲法）。
+```
+[[python]]
+class Solution:
+    """
+    @param A: an integer rotated sorted array
+    @param target: an integer to be searched
+    @return: an integer
+    """
+    def search(self, A, target):
+        if not A:
+            return -1
+            
+        start, end = 0, len(A) - 1
+        while start + 1 < end:
+            mid = (start + end) // 2
+            if A[mid] >= A[start]:
+                if A[start] <= target <= A[mid]:
+                    end = mid
+                else:
+                    start = mid
+            else:
+                if A[mid] <= target <= A[end]:
+                    start = mid
+                else:
+                    end = mid
+                    
+        if A[start] == target:
+            return start
+        if A[end] == target:
+            return end
+        return -1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/second-max-of-array.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/second-max-of-array.md"
new file mode 100644
index 0000000..39b85ea
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/second-max-of-array.md"
@@ -0,0 +1,41 @@
+# 数组第二大数
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/second-max-of-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 在数组中找到第二大的数。
+ ### 样例说明
+ 例1：
+```
+输入：[1,3,2,4]
+输出：3
+```
+例2：
+```
+输入：[1,1,2,2]
+输出：2
+```
+ ### 参考代码
+ 维护最大数和此大数即可
+```java
+public class Solution {
+    /**
+     * @param nums: An integer array.
+     * @return: The second max number in the array.
+     */
+    public int secondMax(int[] nums) {
+        int max = Math.max(nums[0], nums[1]);
+        int second = Math.min(nums[0], nums[1]);
+        
+        for (int i = 2; i < nums.length; i++) {
+            if (nums[i] > max) {
+                second = max;
+                max = nums[i];
+            } else if (nums[i] > second) {
+                second = nums[i];
+            }
+        }
+        
+        return second;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/set-matrix-zeroes.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/set-matrix-zeroes.md"
new file mode 100644
index 0000000..fc5e193
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/set-matrix-zeroes.md"
@@ -0,0 +1,89 @@
+# 矩阵归零
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/set-matrix-zeroes/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个m×n矩阵，如果一个元素是0，则将其所在行和列全部元素变成0。
+
+需要在原矩阵上完成操作。
+
+ ### 样例说明
+ **样例 1:**
+```
+输入:[[1,2],[0,3]]
+输出:[[0,2],[0,0]]
+```
+
+**样例 2:**
+```
+输入:[[1,2,3],[4,0,6],[7,8,9]]
+输出:[[1,0,3],[0,0,0],[7,0,9]]
+```
+ ### 参考代码
+ Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.
+
+click to show follow up.
+
+Follow up:
+Did you use extra space?
+A straight forward solution using O(mn) space is probably a bad idea.
+A simple improvement uses O(m + n) space, but still not the best solution.
+Could you devise a constant space solution?
+```java
+public class Solution {
+     // using O(m+n) is easy, to enable O(1), we have to use the space within the matrix   
+    public void setZeroes(int[][] matrix) {
+        if(matrix == null || matrix.length == 0)
+            return;
+        
+        int rows = matrix.length;
+        int cols = matrix[0].length;
+        
+        boolean empty_row0 = false;
+        boolean empty_col0 = false;
+        for(int i = 0; i < cols; i++){
+            if(matrix[0][i] == 0){
+                empty_row0 = true;
+                break;
+            }
+        }
+        
+        for(int i = 0; i < rows; i++){
+            if(matrix[i][0] == 0){
+                empty_col0 = true;
+                break;
+            }
+        }
+        
+        for(int i = 1; i < rows; i++) {
+            for(int j =1; j<cols; j++){
+                if(matrix[i][j] == 0){
+                    matrix[0][j] = 0;
+                    matrix[i][0] = 0;
+                }
+            }
+        }
+        
+        for(int i = 1; i<rows; i++) {
+            for (int j=1; j< cols; j++) {
+                if(matrix[0][j] == 0 || matrix[i][0] == 0)
+                    matrix[i][j] = 0;
+            }
+        }
+      
+        if(empty_row0){
+            for(int i = 0; i < cols; i++){
+                matrix[0][i] = 0;
+            }           
+        }
+        
+        if(empty_col0){
+            for(int i = 0; i < rows; i++){
+                matrix[i][0] = 0;
+            }           
+        }
+
+    }
+}
+
+
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/sliding-window-matrix-maximum.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/sliding-window-matrix-maximum.md"
new file mode 100644
index 0000000..4f399cc
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/sliding-window-matrix-maximum.md"
@@ -0,0 +1,99 @@
+# 滑动窗口矩阵的最大值
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sliding-window-matrix-maximum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给一个 `n * m` 的一个矩阵, 以及一个移动的矩阵窗口 (大小为 `k * k`), 移动窗口从左上角到右下角, 找到每一次移动窗口得到的和中的最大值, 返回 `0`, 如果结果不存在 
+ ### 样例说明
+ **样例 1:**
+```
+输入：[[1,5,3],[3,2,1],[4,1,9]]，k=2
+输出：13
+解释：
+最初窗口位于矩阵的起点如下
+	[
+	  [|1, 5|, 3],
+	  [|3, 2|, 1],
+	  [4, 1, 9],
+	]
+,得到和为 11;
+
+然后窗口向前移动一步
+	[
+	  [1, |5, 3|],
+	  [3, |2, 1|],
+	  [4, 1, 9],
+	]
+,得到和为 11;
+
+然后窗口继续移动一步
+	[
+	  [1, 5, 3],
+	  [|3, 2|, 1],
+	  [|4, 1|, 9],
+	]
+,得到和为 10;
+
+然后窗口继续移动一步
+	[
+	  [1, 5, 3],
+	  [3, |2, 1|],
+	  [4, |1, 9|],
+	]
+,得到和为 13;
+所以最终，从所有窗口中得到最大值为13。
+```
+
+**样例 2:**
+```
+输入：[[10]，k=1
+输出：10
+解释：
+滑动窗口的大小为 1*1，返回 10。
+```
+
+ ### 参考代码
+ 考点：
+* 二维前缀和
+
+题解：
+* sum[i][j]存储左上角坐标为(0,0),右下角坐标为(i,j)的子矩阵的和。
+* sum[i][j] = matrix[i - 1][j - 1] + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];递推求值即可，两部分相加，减去重复计算部分。
+* int value = sum[i][j] - sum[i - k][j] -sum[i][j - k] + sum[i - k][j - k];可求得一个k * k大小子矩阵的和。
+```java
+public class Solution {
+    /**
+     * @param matrix an integer array of n * m matrix
+     * @param k an integer
+     * @return the maximum number
+     */
+    public int maxSlidingWindow2(int[][] matrix, int k) {
+        // Write your code here
+        int n = matrix.length;
+        if (n == 0 || n < k)
+            return 0;
+        int m = matrix[0].length;
+        if (m == 0 || m < k)
+            return 0;
+
+        int[][] sum = new int[n + 1][m + 1];
+        for (int i = 0; i <= n; ++i) sum[i][0] = 0;
+        for (int i = 0; i <= m; ++i) sum[0][i] = 0;
+
+        for (int i = 1; i <= n; ++i)
+            for (int j = 1; j <= m; ++j)
+                sum[i][j] = matrix[i - 1][j - 1] + 
+                            sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
+
+        int max_value = Integer.MIN_VALUE;
+        for (int i = k; i <= n; ++i)
+            for (int j = k; j <= m; ++j) {
+                int value = sum[i][j] - sum[i - k][j] -
+                            sum[i][j - k] + sum[i - k][j - k];
+
+                if (value > max_value)
+                    max_value = value;
+            }
+        return max_value;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/sparse-matrix-multiplication.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/sparse-matrix-multiplication.md"
new file mode 100644
index 0000000..1f750e4
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/sparse-matrix-multiplication.md"
@@ -0,0 +1,63 @@
+# 稀疏矩阵乘法
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/sparse-matrix-multiplication/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定两个 [稀疏矩阵](https://en.wikipedia.org/wiki/Sparse_matrix) A 和 B，返回AB的结果。
+您可以假设A的列数等于B的行数。
+ ### 样例说明
+ **样例1**
+```
+输入：
+[[1,0,0],[-1,0,3]]
+[[7,0,0],[0,0,0],[0,0,1]]
+输出：
+[[7,0,0],[-7,0,3]]
+解释：
+A = [
+  [ 1, 0, 0],
+  [-1, 0, 3]
+]
+
+B = [
+  [ 7, 0, 0 ],
+  [ 0, 0, 0 ],
+  [ 0, 0, 1 ]
+]
+
+
+     |  1 0 0 |   | 7 0 0 |   |  7 0 0 |
+AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 |
+                  | 0 0 1 |
+```
+**样例2**
+```
+输入：
+[[1,0],[0,1]]
+[[0,1],[1,0]]
+输出：
+[[0,1],[1,0]]
+```
+ ### 参考代码
+ 一种时间复杂度也为 $O(k * n^2)$ 的办法（k 为一行中的非零位个数）
+这种办法比较巧妙，通过初始化结果矩阵，然后把非零位逐个累乘累加的办法，而不是按照原来的矩阵乘法顺序在做。
+```python
+class Solution:
+    """
+    @param A: a sparse matrix
+    @param B: a sparse matrix
+    @return: the result of A * B
+    """
+    def multiply(self, A, B):
+        n = len(A)
+        m = len(A[0])
+        k = len(B[0])
+
+        C = [[0] * k for i in range(n)]
+
+        for i in range(n):
+            for j in range(m):
+                if A[i][j] != 0:
+                    for l in range(k):
+                        C[i][l] += A[i][j] * B[j][l]
+        return C
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/spiral-matrix-ii.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/spiral-matrix-ii.md"
new file mode 100644
index 0000000..ee9581b
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/spiral-matrix-ii.md"
@@ -0,0 +1,91 @@
+# 螺旋矩阵 II
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/spiral-matrix-ii/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个数n, 生成一个包含1~$n^2$的螺旋形矩阵. 
+
+(螺旋由外向内顺时针旋转, 可参照样例)
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: 2
+输出:
+[
+  [1, 2],
+  [4, 3]
+]
+```
+
+**样例 2:**
+```
+输入: 3
+输出:
+[
+  [ 1, 2, 3 ],
+  [ 8, 9, 4 ],
+  [ 7, 6, 5 ]
+]
+```
+ ### 参考代码
+ **方法1:**
+
+模拟螺旋形, 依次填入.
+
+定义x, y为当前应填入数字的位置, d标志该位置前进的方向.
+
+初始x, y在左上角, 即第一个位置, d标志右方.
+
+每填入一个数字, 根据方向移动(x, y), 如果移动后的位置超过了边界或者已经被填过, 则转弯.
+
+d转弯的顺序依次是: 右下左上. 直到填入了n\*n个数字为止即可.
+
+**方法2:**
+
+填数过程同上, 而写法不同, 类似"循环展开"的优化, 速度更快.
+
+Java实现只提供了方法2, 方法1的实现参考C++
+```java
+public class Solution {
+    public int[][] generateMatrix(int n) {
+        if (n < 0) {
+            return null;
+        }
+
+        int[][] result = new int[n][n];
+
+        int xStart = 0;
+        int yStart = 0;
+        int num = 1;
+
+        while (n > 0) {
+            if (n == 1) {
+                result[yStart][xStart] = num++;
+                break;
+            }
+
+            for (int i = 0; i < n - 1; i++) {
+                result[yStart][xStart + i] = num++;
+            }
+
+            for (int i = 0; i < n - 1; i++) {
+                result[yStart + i][xStart + n - 1] = num++;
+            }
+
+            for (int i = 0; i < n - 1; i++) {
+                result[yStart + n - 1][xStart + n - 1 - i] = num++;
+            }
+
+            for (int i = 0; i < n - 1; i++) {
+                result[yStart + n - 1 - i][xStart] = num++;
+            }
+
+            xStart++;
+            yStart++;
+            n = n - 2;
+        }
+
+        return result;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/spiral-matrix.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/spiral-matrix.md"
new file mode 100644
index 0000000..2cfc2dd
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/spiral-matrix.md"
@@ -0,0 +1,61 @@
+# 螺旋矩阵
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/spiral-matrix/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个包含 *m* x *n* 个要素的矩阵，（*m* 行, *n* 列），按照螺旋顺序，返回该矩阵中的所有要素。
+ ### 样例说明
+ **样例 1:**
+```
+输入:[[ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ]]
+输出: [1,2,3,6,9,8,7,4,5]
+```
+
+**样例 2**
+```
+输入:[[ 6,4,1 ], [ 7,8,9 ]]
+输出: [6,4,1,9,8,7]
+```
+ ### 参考代码
+ Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
+
+For example,
+Given the following matrix:
+
+[
+ [ 1, 2, 3 ],
+ [ 4, 5, 6 ],
+ [ 7, 8, 9 ]
+]
+You should return [1,2,3,6,9,8,7,4,5].
+```python
+class Solution:
+    # @param {int[][]} matrix a matrix of m x n elements
+    # @return {int[]} an integer array
+    def spiralOrder(self, matrix):
+        # Write your code here
+        if matrix == []: return []
+        up = 0; left = 0
+        down = len(matrix)-1
+        right = len(matrix[0])-1
+        direct = 0  # 0: go right   1: go down  2: go left  3: go up
+        res = []
+        while True:
+            if direct == 0:
+                for i in range(left, right+1):
+                    res.append(matrix[up][i])
+                up += 1
+            if direct == 1:
+                for i in range(up, down+1):
+                    res.append(matrix[i][right])
+                right -= 1
+            if direct == 2:
+                for i in range(right, left-1, -1):
+                    res.append(matrix[down][i])
+                down -= 1
+            if direct == 3:
+                for i in range(down, up-1, -1):
+                    res.append(matrix[i][left])
+                left += 1
+            if up > down or left > right: return res
+            direct = (direct+1) % 4
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/subarray-sum-closest.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/subarray-sum-closest.md"
new file mode 100644
index 0000000..ff5e2fb
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/subarray-sum-closest.md"
@@ -0,0 +1,92 @@
+# 最接近零的子数组和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/subarray-sum-closest/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找到一个和最接近于零的子数组。返回第一个和最右一个指数。你的代码应该返回满足要求的子数组的起始位置和结束位置
+ ### 样例说明
+ **样例1**
+
+```
+输入: 
+[-3,1,1,-3,5] 
+输出: 
+[0,2]
+解释: [0,2], [1,3], [1,1], [2,2], [0,4]
+```
+
+ ### 参考代码
+ ```java
+class Pair {
+    int sum;
+    int index;
+    public Pair(int s, int i) {
+        sum = s;
+        index = i;
+    }
+}
+    
+public class Solution {
+    /**
+     * @param nums: A list of integers
+     * @return: A list of integers includes the index of the first number 
+     *          and the index of the last number
+     */
+    public int[] subarraySumClosest(int[] nums) {
+        int[] res = new int[2];
+        if (nums == null || nums.length == 0) {
+            return res;
+        } 
+        
+        int len = nums.length;
+        if(len == 1) {
+            res[0] = res[1] = 0;
+            return res;
+        }
+        Pair[] sums = new Pair[len+1];
+        int prev = 0;
+        sums[0] = new Pair(0, 0);
+        for (int i = 1; i <= len; i++) {
+            sums[i] = new Pair(prev + nums[i-1], i);
+            prev = sums[i].sum;
+        }
+        Arrays.sort(sums, new Comparator<Pair>() {
+           public int compare(Pair a, Pair b) {
+               return a.sum - b.sum;
+           } 
+        });
+        int ans = Integer.MAX_VALUE;
+        for (int i = 1; i <= len; i++) {
+            
+            if (ans > sums[i].sum - sums[i-1].sum) {
+                ans = sums[i].sum - sums[i-1].sum;
+                int[] temp = new int[]{sums[i].index - 1, sums[i - 1].index - 1};
+                Arrays.sort(temp);
+                res[0] = temp[0] + 1;
+                res[1] = temp[1];
+            }
+        }
+        
+        return res;
+    }
+}
+
+
+/*
+问：为什么需要一个 (0,0) 的初始 Pair?
+答：
+我们首先需要回顾一下，在 subarray 这节课里，我们讲过一个重要的知识点，叫做 Prefix Sum
+比如对于数组 [1,2,3,4]，他的 Prefix Sum 是 [1,3,6,10]
+分别表示 前1个数之和，前2个数之和，前3个数之和，前4个数之和
+这个时候如果你想要知道 子数组 从下标  1 到下标 2 的这一段的和(2+3)，就用前 3个数之和 减去 前1个数之和 = PrefixSum[2] - PrefixSum[0] = 6 - 1 = 5
+你可以看到这里的 前 x 个数，和具体对应的下标之间，存在 +-1 的问题
+第 x 个数的下标是 x - 1，反之 下标 x 是第 x + 1 个数
+那么问题来了，如果要计算 下标从 0~2 这一段呢？也就是第1个数到第3个数，因为那样会访问到 PrefixSum[-1]
+所以我们把 PrefixSum 整体往后面移动一位，把第0位空出来表示前0个数之和，也就是0. => [0,1,3,6,10]
+那么此时就用 PrefixSum[3] - PrefixSum[0] ，这样计算就更方便了。
+此时，PrefixSum[i] 代表 前i个数之和，也就是 下标区间在 0 ~ i-1 这一段的和
+
+那么回过头来看看，为什么我们需要一个 (0,0) 的 pair 呢？
+因为 这个 0,0 代表的就是前0个数之和为0
+一个 n 个数的数组， 变成了 prefix Sum 数组之后，会多一个数出来
+*/
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/subarray-sum.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/subarray-sum.md"
new file mode 100644
index 0000000..09de43c
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/subarray-sum.md"
@@ -0,0 +1,42 @@
+# 子数组之和
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/subarray-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数数组，找到和为 $0$ 的子数组。你的代码应该返回满足要求的子数组的起始位置和结束位置
+ ### 样例说明
+ **样例 1:**
+
+```
+输入: [-3, 1, 2, -3, 4]
+输出: [0,2] 或 [1,3]	
+样例解释： 返回任意一段和为0的区间即可。
+```
+
+**样例 2:**
+
+```
+输入: [-3, 1, -4, 2, -3, 4]
+输出: [1,5]
+```
+ ### 参考代码
+ 用九章算法班里讲过的前缀和
+
+某一段[l, r]的和为0， 则其对应presum[l-1] = presum[r].
+presum 为数组前缀和。只要保存每个前缀和，找是否有相同的前缀和即可。
+```python
+class Solution:
+    """
+    @param nums: A list of integers
+    @return: A list of integers includes the index of the first number and the index of the last number
+    """
+    def subarraySum(self, nums):
+        prefix_hash = {0: -1}
+        prefix_sum = 0
+        for i, num in enumerate(nums):
+            prefix_sum += num
+            if prefix_sum in prefix_hash:
+                return prefix_hash[prefix_sum] + 1, i
+            prefix_hash[prefix_sum] = i
+            
+        return -1, -1
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/submatrix-sum.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/submatrix-sum.md"
new file mode 100644
index 0000000..29b4566
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/submatrix-sum.md"
@@ -0,0 +1,59 @@
+# 和为零的子矩阵
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/submatrix-sum/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给定一个整数矩阵，请找出一个子矩阵，使得其数字之和等于0.输出答案时，请返回左上数字和右下数字的坐标。
+
+如果有多个答案, 你可以返回其中任意一个.
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:
+[
+  [1, 5, 7],
+  [3, 7, -8],
+  [4, -8 ,9]
+]
+输出: [[1, 1], [2, 2]]
+```
+
+**样例 2:**
+
+```
+输入: 
+[
+  [0, 1],
+  [1, 0]
+]
+输出: [[0, 0], [0, 0]]
+```
+ ### 参考代码
+ 用前缀和优化, 令 `sum[i][j] = sum[0][j] + sum[1][j] + ... + sum[i][j]`
+
+然后枚举上下边界, 这样就相当于在一行内, 求一个数组连续子串和为0的问题了.
+```python
+class Solution:
+    """
+    @param: matrix: an integer matrix
+    @return: the coordinate of the left-up and right-down number
+    """
+    def submatrixSum(self, matrix):
+        if not matrix or not matrix[0]:
+            return None
+            
+        n, m = len(matrix), len(matrix[0])
+        for top in range(n):
+            arr = [0] * m
+            for down in range(top, n):
+                prefix_hash = {0: -1}
+                prefix_sum = 0
+                for col in range(m):
+                    arr[col] += matrix[down][col]
+                    prefix_sum += arr[col]
+                    if prefix_sum in prefix_hash:
+                        return [(top, prefix_hash[prefix_sum] + 1), (down, col)]
+                    prefix_hash[prefix_sum] = col
+                    
+        return None
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/swap-two-integers-in-array.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/swap-two-integers-in-array.md"
new file mode 100644
index 0000000..20cf281
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/swap-two-integers-in-array.md"
@@ -0,0 +1,38 @@
+# 交换数组两个元素
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/swap-two-integers-in-array/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给你一个数组和两个索引，交换下标为这两个索引的数字
+ ### 样例说明
+ **样例 1:**
+
+```
+输入:  [1, 2, 3, 4], index1 = 2, index2 = 3
+输出:  交换后你的数组应该是[1, 2, 4, 3]， 不需要返回任何值，只要就地对数组进行交换即可。
+样例解释: 就地交换，不需要返回值。
+```
+**样例 2:**
+
+```	 
+输入:  [1, 2, 2, 2], index1 = 0, index2 = 3
+输出: 交换后你的数组应该是[2, 2, 2, 1]， 不需要返回任何值，只要就地对数组进行交换即可。	
+样例解释: 就地交换，不需要返回值。
+```
+ ### 参考代码
+ 模拟即可
+```java
+public class Solution {
+    /**
+     * @param A an integer array
+     * @param index1 the first index
+     * @param index2 the second index
+     * @return void
+     */
+    public void swapIntegers(int[] A, int index1, int index2) {
+        // Write your code here
+        int tmp = A[index1];
+        A[index1] = A[index2];
+        A[index2] = tmp;
+    }
+}
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/trapping-rain-water.md" "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/trapping-rain-water.md"
new file mode 100644
index 0000000..1bbda90
--- /dev/null
+++ "b/\351\253\230\351\242\221/\346\225\260\347\273\204\351\242\230/trapping-rain-water.md"
@@ -0,0 +1,56 @@
+# 接雨水
+ > 题目来源: [LintCode 算法题库](https://www.lintcode.com/problem/trapping-rain-water/?utm_source=sc-github-wzz)
+ ## 题目描述
+ 给出 *n* 个非负整数，代表一张X轴上每个区域宽度为 `1` 的海拔图, 计算这个海拔图最多能接住多少（面积）雨水。
+
+![Trapping Rain Water](https://lintcode-media.s3.amazonaws.com/problem/rainwatertrap.png "Trapping Rain Water I")
+ ### 样例说明
+ **样例 1:**
+```
+输入: [0,1,0]
+输出: 0
+```
+
+**样例 2:**
+```
+输入: [0,1,0,2,1,0,1,3,2,1,2,1]
+输出: 6
+```
+ ### 参考代码
+ 每个位置上的盛水数目 = `min(左侧最高，右侧最高) - 当前高度`
+
+从左到右扫描一边数组，获得每个位置往左这一段的最大值，再从右到左扫描一次获得每个位置向右的最大值。
+然后最后再扫描一次数组，计算每个位置上的盛水数目。
+
+时间复杂度 $O(n)$，空间复杂度 $O(n)$
+```python
+class Solution:
+    """
+    @param heights: a list of integers
+    @return: a integer
+    """
+    def trapRainWater(self, heights):
+        if not heights:
+            return 0
+            
+        left_max = []
+        curt_max = -sys.maxsize
+        for height in heights:
+            curt_max = max(curt_max, height)
+            left_max.append(curt_max)
+            
+        right_max = []
+        curt_max = -sys.maxsize
+        for height in reversed(heights):
+            curt_max = max(curt_max, height)
+            right_max.append(curt_max)
+            
+        right_max = right_max[::-1]
+            
+        water = 0
+        n = len(heights)
+        for i in range(n):
+            water += (min(left_max[i], right_max[i]) - heights[i])
+        return water
+```
+ 更多题解请参考: [LintCode 提供 2000+ 算法题和名企阶梯训练](https://www.lintcode.com/problem/?utm_source=sc-github-wzz)
\ No newline at end of file
diff --git "a/\351\253\230\351\242\221/\347\256\227\346\263\225\351\235\242\350\257\225\345\277\205\345\210\267100\351\242\230.xlsx" "b/\351\253\230\351\242\221/\347\256\227\346\263\225\351\235\242\350\257\225\345\277\205\345\210\267100\351\242\230.xlsx"
new file mode 100644
index 0000000..2d1661c
Binary files /dev/null and "b/\351\253\230\351\242\221/\347\256\227\346\263\225\351\235\242\350\257\225\345\277\205\345\210\267100\351\242\230.xlsx" differ
