y,这样对于每个y,只需要扫一遍点数组就可以成功执行转移
+
+* 复杂度是o(n^2)
+
+代码:
+
+```java
+class Solution {
+ public boolean canCross(int[] stones) {
+ int n = stones.length;
+
+ if (stones[1] != 1) {
+ return false;
+ }
+
+ boolean[][] flag = new boolean[n][n];
+ for (int i = 0;i < n;i++) {
+ for (int j = 0;j < n;j++) {
+ flag[i][j] = false;
+ }
+ }
+
+ flag[1][0] = true;
+
+ for (int i = 1;i < n;i++) {
+ int left = i - 1;
+ int right = i + 1;
+
+ while (left >= 0 && right < n) {
+ while (left >= 0 && !flag[i][left]) left--;
+ if (left >= 0) {
+ while (right < n && stones[right] - stones[i] <= stones[i] - stones[left] + 1) {
+ if (stones[right] - stones[i] == stones[i] - stones[left] - 1
+ || stones[right] - stones[i] == stones[i] - stones[left]
+ || stones[right] - stones[i] == stones[i] - stones[left] + 1) {
+ flag[right][i] = true;
+ }
+ right++;
+ }
+ left--;
+ }
+ }
+ }
+
+ for (int i = 0;i < n;i++) {
+ if (flag[n - 1][i]) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+```
+
diff --git a/docs/leetcode/java/0757._Set_Intersection_Size_At_Least_Two.md b/docs/Leetcode_Solutions/Java/757._Set_Intersection_Size_At_Least_Two.md
similarity index 100%
rename from docs/leetcode/java/0757._Set_Intersection_Size_At_Least_Two.md
rename to docs/Leetcode_Solutions/Java/757._Set_Intersection_Size_At_Least_Two.md
diff --git a/docs/leetcode/java/0768._Max_Chunks_To_Make_Sorted_II.md b/docs/Leetcode_Solutions/Java/768._Max_Chunks_To_Make_Sorted_II.md
similarity index 100%
rename from docs/leetcode/java/0768._Max_Chunks_To_Make_Sorted_II.md
rename to docs/Leetcode_Solutions/Java/768._Max_Chunks_To_Make_Sorted_II.md
diff --git a/docs/leetcode/java/0780._Reaching_Points.md b/docs/Leetcode_Solutions/Java/780._Reaching_Points.md
similarity index 100%
rename from docs/leetcode/java/0780._Reaching_Points.md
rename to docs/Leetcode_Solutions/Java/780._Reaching_Points.md
diff --git a/docs/leetcode/java/0793._Preimage_Size_of_Factorial_Zeroes_Function.md b/docs/Leetcode_Solutions/Java/793._Preimage_Size_of_Factorial_Zeroes_Function.md
similarity index 100%
rename from docs/leetcode/java/0793._Preimage_Size_of_Factorial_Zeroes_Function.md
rename to docs/Leetcode_Solutions/Java/793._Preimage_Size_of_Factorial_Zeroes_Function.md
diff --git a/docs/leetcode/java/0827._Making_A_Large_Island.md b/docs/Leetcode_Solutions/Java/827._Making_A_Large_Island.md
similarity index 100%
rename from docs/leetcode/java/0827._Making_A_Large_Island.md
rename to docs/Leetcode_Solutions/Java/827._Making_A_Large_Island.md
diff --git a/docs/leetcode/java/0828._Unique_Letter_String.md b/docs/Leetcode_Solutions/Java/828._Unique_Letter_String.md
similarity index 100%
rename from docs/leetcode/java/0828._Unique_Letter_String.md
rename to docs/Leetcode_Solutions/Java/828._Unique_Letter_String.md
diff --git a/docs/leetcode/java/0834._Sum_of_Distances_in_Tree.md b/docs/Leetcode_Solutions/Java/834._Sum_of_Distances_in_Tree.md
similarity index 100%
rename from docs/leetcode/java/0834._Sum_of_Distances_in_Tree.md
rename to docs/Leetcode_Solutions/Java/834._Sum_of_Distances_in_Tree.md
diff --git a/docs/leetcode/java/0843._Guess_the_Word.md b/docs/Leetcode_Solutions/Java/843._Guess_the_Word.md
similarity index 100%
rename from docs/leetcode/java/0843._Guess_the_Word.md
rename to docs/Leetcode_Solutions/Java/843._Guess_the_Word.md
diff --git a/docs/leetcode/java/0847._Shortest_Path_Visiting_All_Nodes.md b/docs/Leetcode_Solutions/Java/847._Shortest_Path_Visiting_All_Nodes.md
similarity index 100%
rename from docs/leetcode/java/0847._Shortest_Path_Visiting_All_Nodes.md
rename to docs/Leetcode_Solutions/Java/847._Shortest_Path_Visiting_All_Nodes.md
diff --git a/docs/leetcode/java/0850._Rectangle_Area_II.md b/docs/Leetcode_Solutions/Java/850._Rectangle_Area_II.md
similarity index 100%
rename from docs/leetcode/java/0850._Rectangle_Area_II.md
rename to docs/Leetcode_Solutions/Java/850._Rectangle_Area_II.md
diff --git a/docs/leetcode/java/0854._K-Similar_Strings.md b/docs/Leetcode_Solutions/Java/854._K-Similar_Strings.md
similarity index 100%
rename from docs/leetcode/java/0854._K-Similar_Strings.md
rename to docs/Leetcode_Solutions/Java/854._K-Similar_Strings.md
diff --git a/docs/leetcode/java/0857._Minimum_Cost_to_Hire_K_Workers.md b/docs/Leetcode_Solutions/Java/857._Minimum_Cost_to_Hire_K_Workers.md
similarity index 100%
rename from docs/leetcode/java/0857._Minimum_Cost_to_Hire_K_Workers.md
rename to docs/Leetcode_Solutions/Java/857._Minimum_Cost_to_Hire_K_Workers.md
diff --git a/docs/leetcode/java/0862._Shortest_Subarray_with_Sum_at_Least_K.md b/docs/Leetcode_Solutions/Java/862._Shortest_Subarray_with_Sum_at_Least_K.md
similarity index 100%
rename from docs/leetcode/java/0862._Shortest_Subarray_with_Sum_at_Least_K.md
rename to docs/Leetcode_Solutions/Java/862._Shortest_Subarray_with_Sum_at_Least_K.md
diff --git a/docs/leetcode/java/0864._Shortest_Path_to_Get_All_Keys.md b/docs/Leetcode_Solutions/Java/864._Shortest_Path_to_Get_All_Keys.md
similarity index 100%
rename from docs/leetcode/java/0864._Shortest_Path_to_Get_All_Keys.md
rename to docs/Leetcode_Solutions/Java/864._Shortest_Path_to_Get_All_Keys.md
diff --git a/docs/leetcode/java/0871._Minimum_Number_of_Refueling_Stops.md b/docs/Leetcode_Solutions/Java/871._Minimum_Number_of_Refueling_Stops.md
similarity index 100%
rename from docs/leetcode/java/0871._Minimum_Number_of_Refueling_Stops.md
rename to docs/Leetcode_Solutions/Java/871._Minimum_Number_of_Refueling_Stops.md
diff --git a/docs/Leetcode_Solutions/Java/878._Nth_Magical_Number.md b/docs/Leetcode_Solutions/Java/878._Nth_Magical_Number.md
new file mode 100644
index 000000000..be2d4a31e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Java/878._Nth_Magical_Number.md
@@ -0,0 +1,103 @@
+# 878. Nth Magical Number
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/nth-magical-number/description/
+
+> 内容描述
+
+```
+A positive integer is magical if it is divisible by either A or B.
+
+Return the N-th magical number. Since the answer may be very large, return it modulo 10^9 + 7.
+
+
+
+Example 1:
+
+Input: N = 1, A = 2, B = 3
+Output: 2
+Example 2:
+
+Input: N = 4, A = 2, B = 3
+Output: 6
+Example 3:
+
+Input: N = 5, A = 2, B = 4
+Output: 10
+Example 4:
+
+Input: N = 3, A = 6, B = 4
+Output: 8
+
+
+Note:
+
+1 <= N <= 10^9
+2 <= A <= 40000
+2 <= B <= 40000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(log(A*B))******- 空间复杂度: O(N)******
+
+* 从数据范围看来,N高达10^9,直接遍历不现实
+* 注意到魔法数是有循环的,我们令P=A和B的最小公倍数,那么在每P个数中,魔法数的数量和位置都是相同的,因此我们只需要计算1-P中间的魔法数
+* 1~P的魔法数数量是 P/A+P/B-1,注意到,P是A和B的最小公倍数,因此1~P中,既能被A整除,也能被B整除,只有一个数,就是P
+* 现在问题变成,在1~P中,求第n个魔法数
+* 解法一:A和B的数据范围只有40000,因此,1~P中魔法数,不超过80000个,只需要把所有的魔法数求出来,排个序,就能求出第n个魔法数,复杂度是O(A+B)
+* 解法二:注意到,我们在1~p中任取一个数x(x 1) {
+ int mid = (left + right) / 2;
+ if (mid / a + mid / b >= n) {
+ right = mid;
+ } else {
+ left = mid;
+ }
+ }
+
+ return right;
+ }
+
+ public int nthMagicalNumber(int N, int A, int B) {
+ int repeat = lcm(A, B);
+ int num = repeat / A + repeat / B - 1;
+
+ int ret = find(A, B, (N - 1) % num + 1);
+ ret += (long)((N - 1) / num) * repeat % MOD;
+ if (ret > MOD) {
+ ret -= MOD;
+ }
+ return ret;
+ }
+}
+```
+
diff --git a/docs/leetcode/java/0879._Profitable_Schemes.md b/docs/Leetcode_Solutions/Java/879._Profitable_Schemes.md
similarity index 100%
rename from docs/leetcode/java/0879._Profitable_Schemes.md
rename to docs/Leetcode_Solutions/Java/879._Profitable_Schemes.md
diff --git a/docs/leetcode/java/0882._Reachable_Nodes_In_Subdivided_Graph.md b/docs/Leetcode_Solutions/Java/882._Reachable_Nodes_In_Subdivided_Graph.md
similarity index 100%
rename from docs/leetcode/java/0882._Reachable_Nodes_In_Subdivided_Graph.md
rename to docs/Leetcode_Solutions/Java/882._Reachable_Nodes_In_Subdivided_Graph.md
diff --git a/docs/leetcode/java/0887._Super_Egg_Drop.md b/docs/Leetcode_Solutions/Java/887._Super_Egg_Drop.md
similarity index 100%
rename from docs/leetcode/java/0887._Super_Egg_Drop.md
rename to docs/Leetcode_Solutions/Java/887._Super_Egg_Drop.md
diff --git a/docs/Leetcode_Solutions/Java/891._Sum_of_Subsequence_Widths.md b/docs/Leetcode_Solutions/Java/891._Sum_of_Subsequence_Widths.md
new file mode 100644
index 000000000..69ab46ed5
--- /dev/null
+++ b/docs/Leetcode_Solutions/Java/891._Sum_of_Subsequence_Widths.md
@@ -0,0 +1,90 @@
+# 891. Sum of Subsequence Widths
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/sum-of-subsequence-widths/description/
+
+> 内容描述
+
+```
+
+Given an array of integers A, consider all non-empty subsequences of A.
+
+For any sequence S, let the width of S be the difference between the maximum and minimum element of S.
+
+Return the sum of the widths of all subsequences of A.
+
+As the answer may be very large, return the answer modulo 10^9 + 7.
+
+
+
+Example 1:
+
+Input: [2,1,3]
+Output: 6
+Explanation:
+Subsequences are [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3].
+The corresponding widths are 0, 0, 0, 1, 1, 2, 2.
+The sum of these widths is 6.
+
+
+Note:
+
+1 <= A.length <= 20000
+1 <= A[i] <= 20000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+* 我们逆向思路解决这个问题。结果要求最大数减去最小数的差之和,我们可以认为是,把所有的子序列的最大值累加,减去所有的子序列的最小值的累加值
+* 数组中最大数,在子数组中也是最大数的,有2^(n-1)个子数组,同理,第二大数,在子数组是最大数的,有2^(n-2)个子数组,以此类推
+* 同理,最小数也是这样计算
+* 复杂度是O(nlgn)
+
+代码:
+
+```java
+class Solution {
+ private static int MOD = 1000000007;
+
+ private static int[] pow2;
+
+ private void init() {
+ if (pow2 == null) {
+ pow2 = new int[20000];
+ pow2[0] = 1;
+ for (int i = 1;i < pow2.length;i++) {
+ pow2[i] = pow2[i - 1] * 2;
+ if (pow2[i] >= MOD) {
+ pow2[i] -= MOD;
+ }
+ }
+ }
+ }
+
+ public int sumSubseqWidths(int[] A) {
+ init();
+ Arrays.sort(A);
+ int ret = 0;
+ for (int i = 0;i < A.length;i++) {
+ ret += (long)A[i] * pow2[i] % MOD;
+ if (ret >= MOD) {
+ ret -= MOD;
+ }
+ ret -= (long)A[i] * pow2[A.length - i - 1] % MOD;
+ if (ret < 0) {
+ ret += MOD;
+ }
+ }
+ return ret;
+ }
+}
+```
+
diff --git a/docs/leetcode/java/0895._Maximum_Frequency_Stack.md b/docs/Leetcode_Solutions/Java/895._Maximum_Frequency_Stack.md
similarity index 100%
rename from docs/leetcode/java/0895._Maximum_Frequency_Stack.md
rename to docs/Leetcode_Solutions/Java/895._Maximum_Frequency_Stack.md
diff --git a/docs/leetcode/java/0899._Orderly_Queue.md b/docs/Leetcode_Solutions/Java/899._Orderly_Queue.md
similarity index 100%
rename from docs/leetcode/java/0899._Orderly_Queue.md
rename to docs/Leetcode_Solutions/Java/899._Orderly_Queue.md
diff --git a/docs/leetcode/java/0902._Numbers_At_Most_N_Given_Digit_Set.md b/docs/Leetcode_Solutions/Java/902._Numbers_At_Most_N_Given_Digit_Set.md
similarity index 100%
rename from docs/leetcode/java/0902._Numbers_At_Most_N_Given_Digit_Set.md
rename to docs/Leetcode_Solutions/Java/902._Numbers_At_Most_N_Given_Digit_Set.md
diff --git a/docs/leetcode/java/0903._Valid_Permutations_for_DI_Sequence.md b/docs/Leetcode_Solutions/Java/903._Valid_Permutations_for_DI_Sequence.md
similarity index 100%
rename from docs/leetcode/java/0903._Valid_Permutations_for_DI_Sequence.md
rename to docs/Leetcode_Solutions/Java/903._Valid_Permutations_for_DI_Sequence.md
diff --git a/docs/leetcode/java/0906._Super_Palindromes.md b/docs/Leetcode_Solutions/Java/906._Super_Palindromes.md
similarity index 100%
rename from docs/leetcode/java/0906._Super_Palindromes.md
rename to docs/Leetcode_Solutions/Java/906._Super_Palindromes.md
diff --git a/docs/leetcode/java/0913._Cat_and_Mouse.md b/docs/Leetcode_Solutions/Java/913._Cat_and_Mouse.md
similarity index 100%
rename from docs/leetcode/java/0913._Cat_and_Mouse.md
rename to docs/Leetcode_Solutions/Java/913._Cat_and_Mouse.md
diff --git a/docs/leetcode/java/0920._Number_of_Music_Playlists.md b/docs/Leetcode_Solutions/Java/920._Number_of_Music_Playlists.md
similarity index 100%
rename from docs/leetcode/java/0920._Number_of_Music_Playlists.md
rename to docs/Leetcode_Solutions/Java/920._Number_of_Music_Playlists.md
diff --git a/docs/Leetcode_Solutions/JavaScript/001._Two_Sum.md b/docs/Leetcode_Solutions/JavaScript/001._Two_Sum.md
new file mode 100644
index 000000000..db181811c
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/001._Two_Sum.md
@@ -0,0 +1,56 @@
+# 001. Two Sum
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/two-sum/description/
+
+> 内容描述
+
+```
+Given an array of integers, return indices of the two numbers such that they add up to a specific target.
+
+You may assume that each input would have exactly one solution, and you may not use the same element twice.
+
+Example:
+
+Given nums = [2, 7, 11, 15], target = 9,
+
+Because nums[0] + nums[1] = 2 + 7 = 9,
+return [0, 1].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+算法来源于知乎文章——[趣味算法思想](https://zhuanlan.zhihu.com/p/46223775)
+
+先定义一个Object类型的数据结构obj,它的key为target - numbers[i](比如数组第一项为2),value为索引。然后每次都看看obj[numbers[i]] 是否存在,如果存在,那我们就找到了这样的一组数据,返回当前索引以及obj[numbers[i]]。
+
+代码:
+
+```javascript
+/**
+ * @param {number[]} nums
+ * @param {number} target
+ * @return {number[]}
+ */
+var twoSum = function(nums, target) {
+ var obj = {};
+
+ for(var i=0; i< nums.length;i++) {
+ const item = nums[i];
+ if(obj[item] >= 0) {
+ return [obj[item], i]
+ } else {
+ obj[target - item] = i;
+ }
+ }
+};
+```
+
diff --git a/docs/Leetcode_Solutions/JavaScript/058._Length_of_Last_Word.md b/docs/Leetcode_Solutions/JavaScript/058._Length_of_Last_Word.md
new file mode 100644
index 000000000..4d10c40a3
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/058._Length_of_Last_Word.md
@@ -0,0 +1,49 @@
+# 58. Length of Last Word
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/length-of-last-word/description/
+
+> 内容描述
+
+```
+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.
+
+Example:
+
+Input: "Hello World"
+
+Output: 5
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+* 将数组以空格分割,找到最后一个字符串输出长度
+* 注意以空格结尾以及输入空字符串
+
+代码:
+
+```javascript
+/**
+ * @param {string} s
+ * @return {number}
+ */
+var lengthOfLastWord = function(s) {
+ var temp = s.split(' ').filter(function (value) {
+ return value!='';
+ });
+ return temp.length>0?temp.pop().length:0;
+};
+```
+
diff --git a/docs/Leetcode_Solutions/JavaScript/067._Add_Binary.md b/docs/Leetcode_Solutions/JavaScript/067._Add_Binary.md
new file mode 100644
index 000000000..fe9448a9c
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/067._Add_Binary.md
@@ -0,0 +1,65 @@
+# 67. Add Binary
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/add-binary/description/
+
+> 内容描述
+
+```
+Given two binary strings, return their sum (also a binary string).
+
+The input strings are both non-empty and contains only characters 1 or 0.
+
+Example 1:
+
+Input: a = "11", b = "1"
+Output: "100"
+Example 2:
+
+Input: a = "1010", b = "1011"
+Output: "10101"
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+* 对于每一位数进行加法,如有进位单独计算
+* 注意需使用字符串进行存储,整型无法计算大型数据
+
+代码:
+
+```javascript
+/**
+ * @param {string} a
+ * @param {string} b
+ * @return {string}
+ */
+var addBinary = function(a, b) {
+ var tempA = a.split('');
+ var tempB = b.split('');
+ var result =[];
+ var aLen=tempA.length,bLen=tempB.length;
+ var carry = 0;
+ while(aLen>0||bLen>0){
+ var charA=0,charB=0;
+ if(aLen>0)
+ charA = tempA[--aLen]-0;
+ if(bLen>0)
+ charB = tempB[--bLen]-0;
+ var temp = charA + charB + carry;
+ carry = temp>1?1:0;
+ result.unshift(temp%2);
+ }
+ if(carry===1)
+ result.unshift(1);
+ return result.toString().replace(/,/g,'');
+};
+```
+
diff --git a/docs/Leetcode_Solutions/JavaScript/104._Maximum_Depth_of_Binary_Tree.md b/docs/Leetcode_Solutions/JavaScript/104._Maximum_Depth_of_Binary_Tree.md
new file mode 100644
index 000000000..ee3e9d7a6
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/104._Maximum_Depth_of_Binary_Tree.md
@@ -0,0 +1,49 @@
+# 104. Maximum Depth of Binary Tree
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/maximum-depth-of-binary-tree/description/
+
+> 内容描述
+
+```
+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.
+
+Note: A leaf is a node with no children.
+
+Example:
+
+Given binary tree [3,9,20,null,null,15,7],
+
+ 3
+ / \
+ 9 20
+ / \
+ 15 7
+return its depth = 3.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(log2 N)******- 空间复杂度: O(N)******
+
+* 这道题使用递归进行解决,因为对于树的每一个儿子的处理方法是一致的。
+* 将左儿子和右儿子中最大的数进行返回再加上当前的深度1即可解决。
+
+代码:
+
+```javascript
+var maxDepth = function(root) {
+ if(root===null||root === undefined)
+ return 0;
+ return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
+};
+```
+
diff --git a/docs/Leetcode_Solutions/JavaScript/167._Two-Sum-II-Input-Array-is-Sorted.md b/docs/Leetcode_Solutions/JavaScript/167._Two-Sum-II-Input-Array-is-Sorted.md
new file mode 100644
index 000000000..0a84fe77f
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/167._Two-Sum-II-Input-Array-is-Sorted.md
@@ -0,0 +1,62 @@
+# 167. Two Sum II - Input array is sorted
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/
+
+> 内容描述
+
+```
+Given an array of integers that is already sorted in ascending order, 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.
+
+Note:
+
+Your returned answers (both index1 and index2) are not zero-based.
+You may assume that each input would have exactly one solution and you may not use the same element twice.
+Example:
+
+Input: numbers = [2,7,11,15], target = 9
+Output: [1,2]
+Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+算法来源于知乎文章——[趣味算法思想](https://zhuanlan.zhihu.com/p/46223775)
+* 由于数组是有序的,所以可以从两边向中间逐渐收敛地进行查找,好处在于避免了双重循环
+* 如果最两端的和小于目标数,则可以让左侧下标+1,然后重新进行运算比较
+* 如果最两端的和大于目标数,则可以让右侧下标-1,然后重新进行运算比较
+
+代码:
+
+```javascript
+/**
+ * @param {number[]} numbers
+ * @param {number} target
+ * @return {number[]}
+ */
+var twoSum = function(nums, target) {
+ var number=[];
+ var left = 0;
+ var right = nums.length - 1 ;
+ while(left < right ) {
+ if(nums[left] + nums[right] === target) {
+ return [left+1, right+1]
+ } else if(nums[left] + nums[right] > target ) {
+ right--;
+ } else {
+ left++;
+ }
+ }
+};
+```
+
diff --git a/docs/Leetcode_Solutions/JavaScript/209._Minimum-Size-Subarray-Sum.md b/docs/Leetcode_Solutions/JavaScript/209._Minimum-Size-Subarray-Sum.md
new file mode 100644
index 000000000..210419da5
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/209._Minimum-Size-Subarray-Sum.md
@@ -0,0 +1,80 @@
+# 209. Minimum Size Subarray Sum
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-size-subarray-sum/description/
+
+> 内容描述
+
+```
+Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.
+
+Example:
+
+Input: s = 7, nums = [2,3,1,2,4,3]
+Output: 2
+Explanation: the subarray [4,3] has the minimal length under the problem constraint.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+算法来源于知乎文章——[趣味算法思想](https://zhuanlan.zhihu.com/p/46223775)
+ * 这里可以看到由于需要找连续的子数组,所以依旧可以设置两个指针,往同一方向移动。
+ * 如果两个指针中间的值加起来>sum的时候,记录此时数组的长度,接着左指针移动,减小sum的值 ;
+ * 如果< sum的话,右指针移动扩大范围。
+ * 最后返回最短的长度值。
+
+
+
+代码:
+
+```javascript
+/**
+ * @param {number} s
+ * @param {number[]} nums
+ * @return {number}
+ */
+var minSubArrayLen = function(s, nums) {
+ var left = 0;
+ var right = -1; // right 的起始位置很重要,这里选择-1 [left, right]这个区间刚开始是没有值的
+ var tmpSum = 0;
+ var minLength;
+
+ // 循环停止的条件是左指针小于长度
+ while (left < nums.length - 1) {
+ if(tmpSum < s) {
+ // 这里要注意边界的处理,当右指针移动到最后一个元素的时候结束
+ if(right >= nums.length -1) {
+ return minLength || 0;
+ }
+ right ++;
+ // 这里tmpSum的计算也很巧妙,直接用累加的方式,节省计算量
+ tmpSum = tmpSum + nums[right]
+ } else {
+ var tmp = right - left + 1;
+ if(minLength) {
+ if(tmp < minLength) {
+ minLength = tmp;
+ }
+ } else {
+ minLength = tmp;
+ }
+ // 左边指针移动减少sum的值
+ tmpSum = tmpSum - nums[left];
+ left ++;
+ }
+ }
+ if(!minLength) {
+ return 0;
+ }
+ return minLength;
+};
+```
+
diff --git a/docs/Leetcode_Solutions/JavaScript/258._Add_Digits.md b/docs/Leetcode_Solutions/JavaScript/258._Add_Digits.md
new file mode 100644
index 000000000..785ee7ffd
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/258._Add_Digits.md
@@ -0,0 +1,56 @@
+# 258. Add Digits
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/add-digits/description/
+
+> 内容描述
+
+```
+Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.
+
+Example:
+
+Input: 38
+Output: 2
+Explanation: The process is like: 3 + 8 = 11, 1 + 1 = 2.
+ Since 2 has only one digit, return it.
+
+Follow up:
+Could you do it without any loop/recursion in O(1) runtime?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+* 原理:
+* 假设输入的数字是一个5位数字num,则num的各位分别为a、b、c、d、e
+* 有如下关系:num = a * 10000 + b * 1000 + c * 100 + d * 10 + e
+* 即:num = (a + b + c + d + e) + (a * 9999 + b * 999 + c * 99 + d * 9)
+* 因为 a * 9999 + b * 999 + c * 99 + d * 9 一定可以被9整除,因此num模除9的结果与 a + b + c + d + e 模除9的结果是一样的。
+* 对数字 a + b + c + d + e 反复执行同类操作,最后的结果就是一个 1-9 的数字加上一串数字,最左边的数字是 1-9 之间的,右侧的数字永远都是可以被9整除的。
+* 这道题最后的目标,就是不断将各位相加,相加到最后,当结果小于10时返回。因为最后结果在1-9之间,得到9之后将不会再对各位进行相加,因此不会出现结果为0的情况。
+* 因为 (x + y) % z = (x % z + y % z) % z,又因为 x % z % z = x % z,因此结果为 (num - 1) % 9 + 1,只模除9一次,并将模除后的结果加一返回。
+
+代码:
+
+```javascript
+/**
+ * @param {number} num
+ * @return {number}
+ */
+var addDigits = function(num) {
+ if(num==0)
+ return num;
+ if(num%9==0)
+ return 9;
+ else return num%9;
+};
+```
+
diff --git a/docs/Leetcode_Solutions/JavaScript/402._Remove_K_Digits.md b/docs/Leetcode_Solutions/JavaScript/402._Remove_K_Digits.md
new file mode 100644
index 000000000..3dbff985d
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/402._Remove_K_Digits.md
@@ -0,0 +1,67 @@
+# 402. Remove K Digits
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/remove-k-digits/description/
+
+> 内容描述
+
+```
+Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.
+
+Note:
+The length of num is less than 10002 and will be ≥ k.
+The given num does not contain any leading zero.
+Example 1:
+
+Input: num = "1432219", k = 3
+Output: "1219"
+Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.
+Example 2:
+
+Input: num = "10200", k = 1
+Output: "200"
+Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.
+Example 3:
+
+Input: num = "10", k = 2
+Output: "0"
+Explanation: Remove all the digits from the number and it is left with nothing which is 0.
+
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+* 使用栈的思路
+* 如果n是num的长度,我们要去除k个,那么需要剩下n-k个数,定义一个result数组用于保存剩下的字符,与result中最后一个字符相比,比它小,
+* 栈中最后一个字符出栈,该字符进栈,否则该字符直接进栈。值得注意的是在删除k个数之后,若剩下的数前面有0,应该去掉。
+
+代码:
+
+```javascript
+/**
+ * @param {string} num
+ * @param {number} k
+ * @return {string}
+ */
+var removeKdigits = function(num, k) {
+ let stack = [], numDigits = num.length;
+ for (let i = 0; i < numDigits; i++) {
+ while(k > 0 && stack.length && stack[stack.length - 1] > num[i]) {
+ stack.pop();
+ k--;
+ }
+ stack.push(num[i]);
+ }
+ stack = k > 0 ? stack.slice(0, -k) : stack;
+ return stack.join('').replace(/^0+/, '') || '0';
+};
+```
+
diff --git a/docs/Leetcode_Solutions/JavaScript/485._Max_Consecutive_Ones.md b/docs/Leetcode_Solutions/JavaScript/485._Max_Consecutive_Ones.md
new file mode 100644
index 000000000..535fd6664
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/485._Max_Consecutive_Ones.md
@@ -0,0 +1,53 @@
+# 485. Max Consecutive Ones
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/max-consecutive-ones/description/
+
+> 内容描述
+
+```
+Given a binary array, find the maximum number of consecutive 1s in this array.
+
+Example 1:
+Input: [1,1,0,1,1,1]
+Output: 3
+Explanation: The first two digits or the last three digits are consecutive 1s.
+ The maximum number of consecutive 1s is 3.
+Note:
+
+The input array will only contain 0 and 1.
+The length of input array is a positive integer and will not exceed 10,000
+
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+* 使用temp保存每个0之间的差值
+* 找出最大的差值即可
+
+代码:
+
+```javascript
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var findMaxConsecutiveOnes = function(nums) {
+ var max = 0,temp = 0;
+ for(var i =0;i难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-time-difference/description/
+
+> 内容描述
+
+```
+Given a list of 24-hour clock time points in "Hour:Minutes" format, find the minimum minutes difference between any two time points in the list.
+
+Example 1:
+Input: ["23:59","00:00"]
+Output: 1
+
+Note:
+The number of time points in the given list is at least 2 and won't exceed 20000.
+The input time is legal and ranges from 00:00 to 23:59.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+* 将所有时间转换成分钟数,然后进行sort排序
+* 计算两个数之间的差值,找出最小差值即可
+* 不要忘记第一个时间与最后一个时间相比较
+
+代码:
+
+```javascript
+/**
+ * @param {string[]} timePoints
+ * @return {number}
+ */
+var findMinDifference = function(timePoints) {
+ var dayTime = 24*60;
+ var minTime = 24*60;
+ var temp = timePoints.map(function (value) {
+ var t = value.split(':');
+ return parseInt(t[0])*60+parseInt(t[1]);
+ });
+ temp.sort(function (a,b) {
+ return a-b;
+ });
+ for(var i =0;i(dayTime/2)){
+ diff = Math.abs(temp[f]-(temp[b]+dayTime));
+ minTime = diff难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/plus-one/description/
+
+> 内容描述
+
+```
+Given a non-empty array of digits representing a non-negative integer, plus one to the integer.
+
+The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit.
+
+You may assume the integer does not contain any leading zero, except the number 0 itself.
+
+Example 1:
+
+Input: [1,2,3]
+Output: [1,2,4]
+Explanation: The array represents the integer 123.
+Example 2:
+
+Input: [4,3,2,1]
+Output: [4,3,2,2]
+Explanation: The array represents the integer 4321.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+* 如果数字小于9则不会发生进位,仅当前位置++即可
+* 因进位和plus one 都是数字加一
+* 数字大于9则进位与初始加一的处理方式一样
+
+代码:
+
+```javascript
+/**
+ * @param {number[]} digits
+ * @return {number[]}
+ */
+var plusOne = function(digits) {
+ for(var i=digits.length-1;i>=0;i--){
+ if(digits[i]<9){
+ digits[i]++;
+ return digits;
+ }
+ digits[i]=0;
+ }
+ digits.unshift(1);
+ return digits;
+};
+```
+
diff --git a/docs/Leetcode_Solutions/JavaScript/881._Boats_to_Save_People.md b/docs/Leetcode_Solutions/JavaScript/881._Boats_to_Save_People.md
new file mode 100644
index 000000000..c15a59751
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/881._Boats_to_Save_People.md
@@ -0,0 +1,70 @@
+# 881. Boats to Save People
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/boats-to-save-people/description/
+
+> 内容描述
+
+```
+The i-th person has weight people[i], and each boat can carry a maximum weight of limit.
+
+Each boat carries at most 2 people at the same time, provided the sum of the weight of those people is at most limit.
+
+Return the minimum number of boats to carry every given person. (It is guaranteed each person can be carried by a boat.)
+
+
+
+Example 1:
+
+Input: people = [1,2], limit = 3
+Output: 1
+Explanation: 1 boat (1, 2)
+Example 2:
+
+Input: people = [3,2,2,1], limit = 3
+Output: 3
+Explanation: 3 boats (1, 2), (2) and (3)
+Example 3:
+
+Input: people = [3,5,3,4], limit = 5
+Output: 4
+Explanation: 4 boats (3), (3), (4), (5)
+Note:
+
+1 <= people.length <= 50000
+1 <= people[i] <= limit <= 30000
+
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N logN)******- 空间复杂度: O(N)******
+
+* 使用贪心算法,将数组进行排序之后进行处理
+
+代码:
+
+```javascript
+/**
+ * @param {number[]} people
+ * @param {number} limit
+ * @return {number}
+ */
+var numRescueBoats = function(people, limit) {
+ people.sort(function (a,b) { return a-b });
+ var num=0;
+ for(var left = 0,right = people.length-1;right-left>=0;right--){
+ if(people[left]+people[right]<=limit)
+ left++;
+ num++;
+ }
+ return num;
+};
+```
+
diff --git a/docs/Leetcode_Solutions/JavaScript/9._Palindrome_Number.md b/docs/Leetcode_Solutions/JavaScript/9._Palindrome_Number.md
new file mode 100644
index 000000000..b0905df78
--- /dev/null
+++ b/docs/Leetcode_Solutions/JavaScript/9._Palindrome_Number.md
@@ -0,0 +1,72 @@
+# 9. Palindrome Number
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/palindrome-number/description/
+
+> 内容描述
+
+```
+Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward.
+
+Example 1:
+
+Input: 121
+Output: true
+Example 2:
+
+Input: -121
+Output: false
+Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
+Example 3:
+
+Input: 10
+Output: false
+Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
+Follow up:
+
+Coud you solve it without converting the integer to a string?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(log2 N)******- 空间复杂度: O(1)******
+
+* 不使用字符串,使用除法分别从首尾获得数字,最后对比是否相同
+
+代码:
+
+```javascript
+/**
+ * @param {number} x
+ * @return {boolean}
+ */
+var isPalindrome = function(x) {
+ if(x<0||x!==0&&x%10===0)
+ return false;
+ var reverse = 0;
+ while (x>reverse){
+ reverse = reverse*10 +x%10;
+ x = Math.floor(x/10);
+ }
+ return reverse === x||Math.floor(reverse/10) === x;
+};
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+* 转化为字符串,reverse字符串
+
+代码:
+
+```javascript
+var isPalindrome = function(x) {
+ return x.toString().split('').reverse().join('')==x.toString()?true:false;
+};
+```
diff --git a/docs/Leetcode_Solutions/Python/001._two_sum.md b/docs/Leetcode_Solutions/Python/001._two_sum.md
new file mode 100644
index 000000000..32ec043b8
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/001._two_sum.md
@@ -0,0 +1,80 @@
+# 1. Two Sum
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/two-sum
+
+> 内容描述
+
+```
+Given an array of integers, return indices of the two numbers such that they add up to a specific target.
+
+You may assume that each input would have exactly one solution, and you may not use the same element twice.
+
+Example:
+
+Given nums = [2, 7, 11, 15], target = 9,
+
+Because nums[0] + nums[1] = 2 + 7 = 9,
+return [0, 1].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+暴力解法,两轮遍历
+
+beats 27.6%
+```python
+class Solution(object):
+ def twoSum(self, nums, target):
+ """
+ :type nums: List[int]
+ :type target: int
+ :rtype: List[int]
+ """
+ for i in range(len(nums)):
+ for j in range(i+1, len(nums)):
+ if nums[i] + nums[j] == target:
+ return [i, j]
+```
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+上面的思路1太慢了,我们可以牺牲空间换取时间
+
+```
+ 2 7 11 15
+ 不存在 存在之中
+lookup {2:0} [0,1]
+```
+
+* 建立字典 lookup 存放第一个数字,并存放该数字的 index
+* 判断 lookup 种是否存在: `target - 当前数字`, 则表面 当前值和 lookup中的值加和为 target.
+* 如果存在,则返回: `target - 当前数字` 的 index 和 当前值的 index
+
+beats 100%
+
+```python
+class Solution(object):
+ def twoSum(self, nums, target):
+ """
+ :type nums: List[int]
+ :type target: int
+ :rtype: List[int]
+ """
+ lookup = {}
+ for i, num in enumerate(nums):
+ if target - num in lookup:
+ return [lookup[target-num], i]
+ else:
+ lookup[num] = i
+```
diff --git a/docs/leetcode/python/002._add_two_numbers.md b/docs/Leetcode_Solutions/Python/002._add_two_numbers.md
similarity index 75%
rename from docs/leetcode/python/002._add_two_numbers.md
rename to docs/Leetcode_Solutions/Python/002._add_two_numbers.md
index 177706bbd..641248641 100644
--- a/docs/leetcode/python/002._add_two_numbers.md
+++ b/docs/Leetcode_Solutions/Python/002._add_two_numbers.md
@@ -1,90 +1,94 @@
-# 2. Add Two Numbers
-**难度: 中等**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/add-two-numbers
-
-> 内容描述
-
-```
-You are given two non-empty linked lists representing two non-negative integers. 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.
-
-You may assume the two numbers do not contain any leading zero, except the number 0 itself.
-
-Example:
-
-Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
-Output: 7 -> 0 -> 8
-Explanation: 342 + 465 = 807.
-```
-
-## 解题方案
-
-> 思路 1
-
-全部变成数字做加法再换回去呗,这多暴力,爽!
-
-```python
-class Solution(object):
- def addTwoNumbers(self, l1, l2):
- """
- :type l1: ListNode
- :type l2: ListNode
- :rtype: ListNode
- """
- if not l1:
- return l2
- if not l2:
- return l1
-
- val1, val2 = [l1.val], [l2.val]
- while l1.next:
- val1.append(l1.next.val)
- l1 = l1.next
- while l2.next:
- val2.append(l2.next.val)
- l2 = l2.next
-
- num1 = ''.join([str(i) for i in val1[::-1]])
- num2 = ''.join([str(i) for i in val2[::-1]])
-
- tmp = str(int(num1) + int(num2))[::-1]
- res = ListNode(tmp[0])
- run_res = res
- for i in range(1, len(tmp)):
- run_res.next = ListNode(tmp[i])
- run_res = run_res.next
- return res
-```
-> 思路 2
-
-可以使用递归,每次算一位的相加
-
-
-```python
-class Solution(object):
- def addTwoNumbers(self, l1, l2):
- """
- :type l1: ListNode
- :type l2: ListNode
- :rtype: ListNode
- """
- if not l1:
- return l2
- if not l2:
- return l1
-
- if l1.val + l2.val < 10:
- l3 = ListNode(l1.val + l2.val)
- l3.next = self.addTwoNumbers(l1.next, l2.next)
-
- else:
- l3 = ListNode(l1.val + l2.val - 10)
- tmp = ListNode(1)
- tmp.next = None
- l3.next = self.addTwoNumbers(l1.next, self.addTwoNumbers(l2.next ,tmp))
- return l3
-```
+# 2. Add Two Numbers
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/add-two-numbers/description/
+
+> 内容描述
+
+```
+You are given two non-empty linked lists representing two non-negative integers. 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.
+
+You may assume the two numbers do not contain any leading zero, except the number 0 itself.
+
+Example:
+
+Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
+Output: 7 -> 0 -> 8
+Explanation: 342 + 465 = 807.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+全部变成数字做加法再换回去呗,这多暴力,爽!
+
+beats 54.35%
+
+```python
+class Solution(object):
+ def addTwoNumbers(self, l1, l2):
+ """
+ :type l1: ListNode
+ :type l2: ListNode
+ :rtype: ListNode
+ """
+ if not l1:
+ return l2
+ if not l2:
+ return l1
+
+ val1, val2 = [l1.val], [l2.val]
+ while l1.next:
+ val1.append(l1.next.val)
+ l1 = l1.next
+ while l2.next:
+ val2.append(l2.next.val)
+ l2 = l2.next
+
+ num1 = ''.join([str(i) for i in val1[::-1]])
+ num2 = ''.join([str(i) for i in val2[::-1]])
+
+ tmp = str(int(num1) + int(num2))[::-1]
+ res = ListNode(int(tmp[0]))
+ run_res = res
+ for i in range(1, len(tmp)):
+ run_res.next = ListNode(int(tmp[i]))
+ run_res = run_res.next
+ return res
+```
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+可以使用递归,每次算一位的相加, beats 73.53%
+
+
+```python
+class Solution(object):
+ def addTwoNumbers(self, l1, l2):
+ """
+ :type l1: ListNode
+ :type l2: ListNode
+ :rtype: ListNode
+ """
+ if not l1:
+ return l2
+ if not l2:
+ return l1
+
+ if l1.val + l2.val < 10:
+ l3 = ListNode(l1.val+l2.val)
+ l3.next = self.addTwoNumbers(l1.next, l2.next)
+ else:
+ l3 = ListNode(l1.val+l2.val-10)
+ tmp = ListNode(1)
+ tmp.next = None
+ l3.next = self.addTwoNumbers(l1.next, self.addTwoNumbers(l2.next, tmp))
+
+ return l3
+```
diff --git a/docs/Leetcode_Solutions/Python/003._longest_substring_without_repeating_characters.md b/docs/Leetcode_Solutions/Python/003._longest_substring_without_repeating_characters.md
new file mode 100644
index 000000000..728538d01
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/003._longest_substring_without_repeating_characters.md
@@ -0,0 +1,104 @@
+# 3. Longest Substring Without Repeating Characters
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/longest-substring-without-repeating-characters/description/
+
+> 内容描述
+
+```
+
+Given a string, find the length of the longest substring without repeating characters.
+
+Example 1:
+
+Input: "abcabcbb"
+Output: 3
+Explanation: The answer is "abc", with the length of 3.
+Example 2:
+
+Input: "bbbbb"
+Output: 1
+Explanation: The answer is "b", with the length of 1.
+Example 3:
+
+Input: "pwwkew"
+Output: 3
+Explanation: The answer is "wke", with the length of 3.
+ Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+思路
+
+粗一看是dp,细一看是greedy
+
+我们先从第一个字符开始,只要碰到已经出现过的字符我们就必须从之前出现该字符的index开始重新往后看。
+
+例如‘xyzxlkjh’,当看到第二个‘x’时我们就应该从y开始重新往后看了。
+
+那么怎么判断字符已经出现过了呢?我们使用一个hashmap,将每一个已经阅读过的字符作为键,而它的值就是它在原字符串中的index,如果我们现在的字符不在hashmap里面我们就把它加进hashmap中去,因此,只要目前的这个字符在该hashmap中的值大于等于了这一轮字符串的首字符,就说明它已经出现过了,我们就将首字符的index加1,即从后一位又重新开始读,然后比较目前的子串长度与之前的最大长度,取大者。
+
+### 程序变量解释
+
+- l(字母L) 代表目前最大子串的长度
+- start 是这一轮未重复子串首字母的index
+- maps 放置每一个字符的index,如果maps.get(s[i], -1)大于等于start的话,就说明字符重复了,此时就要重置 l(字母L) 和start的值了,
+
+
+
+```python
+class Solution(object):
+ def lengthOfLongestSubstring(self, s):
+ """
+ :type s: str
+ :rtype: int
+
+ """
+ l, start, n = 0, 0, len(s)
+ maps = {}
+ for i in range(n):
+ start = max(start, maps.get(s[i], -1)+1)
+ l = max(l, i - start+1)
+ maps[s[i]] = i
+ return l
+```
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+slide window全家桶,第159题和第340题几乎一摸一样,改几个数字就AC了
+
+```python
+class Solution(object):
+ def lengthOfLongestSubstring(self, s):
+ """
+ :type s: str
+ :rtype: int
+ """
+ lookup = {}
+ start, end, counter, length = 0, 0, 0, 0
+ while end < len(s):
+ lookup[s[end]] = lookup.get(s[end], 0) + 1
+ if lookup[s[end]] == 1:
+ counter += 1
+ end += 1
+ while start < end and counter < end - start:
+ lookup[s[start]] -= 1
+ if lookup[s[start]] == 0:
+ counter -= 1
+ start += 1
+ length = max(length, end - start)
+ return length
+```
diff --git a/docs/leetcode/python/004._median_of_two_sorted_arrays.md b/docs/Leetcode_Solutions/Python/004._median_of_two_sorted_arrays.md
similarity index 83%
rename from docs/leetcode/python/004._median_of_two_sorted_arrays.md
rename to docs/Leetcode_Solutions/Python/004._median_of_two_sorted_arrays.md
index 655bc4f9c..bbba55a2c 100644
--- a/docs/leetcode/python/004._median_of_two_sorted_arrays.md
+++ b/docs/Leetcode_Solutions/Python/004._median_of_two_sorted_arrays.md
@@ -1,260 +1,254 @@
-### 4. Median of Two Sorted Arrays
-
-题目:
-
-
-
-难度:
-
-Hard
-
-
-一看到的时候,觉得跟CLRS书上的一道习题类似
-求X[1....n] Y[1....n] 的 median
-
-习题 9.3-8
-
-
-Let X[1..n] and Y [1..n] be two arrays, each containing n numbers already in sorted order. Give an O(lg n)-time algorithn to find the median of all 2n elements in arrays X and Y .
-
-
-> The median can be obtained recursively as follows. Pick the median of the sorted array A. This is just O(1) time as median is the n/2th element in the sorted array. Now compare the median of A, call is a∗ with median of B, b∗. We have two cases.
-
-- a∗ < b∗ : In this case, the elements in B[n/2 ···n] are also greater than a . So the median cannot lie in either A[1 · · · n/2 ] or B[n/2 · · · n]. So we can just throw these away and recursively
-
-- a∗ > b∗ : In this case, we can still throw away B[1··· n/2] and also A[ n/ · · · n] and solve a smaller subproblem recursively.
-
-
-In either case, our subproblem size reduces by a factor of half and we spend only constant time to compare the medians of A and B. So the recurrence relation would be T (n) = T (n/2) + O(1) which has a solution T (n) = O(log n).
-
-
-divide and conquer
-
-- 如果X[n/2] == Y[n/2],则找到,return
-- 如果X[n/2] < Y[n/2],找X[n/2+1….n]和Y[1,2…n/2]之间
-- 否则找X[1..n/2]和Y[n/2…n]
-
-
-
-
-但是实际上不同,这里需要考虑的问题更多:
-
-- 两个数组长度不一样
-- 并不是只找一个median,如果median有两个,需要算平均
-
-思路
-
-把它转化成经典的findKth问题
-
-参考:
-
-
-首先转成求A和B数组中第k小的数的问题, 然后用k/2在A和B中分别找。
-
-
-比如k = 6, 分别看A和B中的第3个数, 已知 A1 < A2 < A3 < A4 < A5... 和 B1 < B2 < B3 < B4 < B5..., 如果A3 <= B3, 那么第6小的数肯定不会是A1, A2, A3, 因为最多有两个数小于A1, 三个数小于A2, 四个数小于A3。 关键点是从 k/2 开始来找。
-
-
-
-B3至少大于5个数, 所以第6小的数有可能是B1 (A1 < A2 < A3 < A4 < A5 < B1), 有可能是B2 (A1 < A2 < A3 < B1 < A4 < B2), 有可能是B3 (A1 < A2 < A3 < B1 < B2 < B3)。那就可以排除掉A1, A2, A3, 转成求A4, A5, ... B1, B2, B3, ...这些数中第3小的数的问题, k就被减半了。每次都假设A的元素个数少, pa = min(k/2, lenA)的结果可能导致k == 1或A空, 这两种情况都是终止条件。
-
-
-发问,为什么要从k/2开始寻找,依旧k = 6, 我可以比较A1 和 B5的关系么,可以这样做,但是明显的问题出现在如果A1 > B5,那么这个第6小的数应该存在于B6和A1中。
-
-如果A1 < B5,这个时间可能性就很多了,比如A1 < A2 < A3 < A4 < B1 < B2,各种可能,无法排除元素,所以还是要从k/2开始寻找。
-
-这个跟习题算法的区别是每次扔的东西明显少一些,但是k也在不断变小。下面的代码的时间复杂度是O(lg(m+n))
-
-
-```python
-class Solution(object):
- def findMedianSortedArrays(self, nums1, nums2):
- """
- :type nums1: List[int]
- :type nums2: List[int]
- :rtype: float
- """
- n = len(nums1) + len(nums2)
- if n % 2 == 1:
- return self.findKth(nums1, nums2, n / 2 + 1)
- else:
- smaller = self.findKth(nums1, nums2, n / 2)
- bigger = self.findKth(nums1, nums2, n / 2 + 1)
- return (smaller + bigger) / 2.0
-
-
- def findKth(self, A, B, k):
- if len(A) == 0:
- return B[k-1]
- if len(B) == 0:
- return A[k-1]
- if k == 1 :
- return min(A[0],B[0])
-
-
- a = A[ k / 2 - 1 ] if len(A) >= k / 2 else None
- b = B[ k / 2 - 1 ] if len(B) >= k / 2 else None
-
- if b is None or (a is not None and a < b):
- return self.findKth(A[k/2:], B, k - k/2)
- return self.findKth(A, B[k/2:],k - k/2) #这里要注意:因为 k/2 不一定 等于 (k - k/2),
-
-
-```
-```python
-#python3里面要用向下取整函数才可以AC,否则报错,TypeError: list indices must be integers or slices, not float
-
-from math import floor
-class Solution:
- def findMedianSortedArrays(self, nums1, nums2):
- """
- :type nums1: List[int]
- :type nums2: List[int]
- :rtype: float
- """
- n = len(nums1) + len(nums2)
- if n % 2 == 1:
- return self.findKth(nums1, nums2, floor(n/2)+1)
- else:
- smaller = self.findKth(nums1, nums2, floor(n/2))
- bigger = self.findKth(nums1, nums2, floor(n/2)+1)
- return (smaller + bigger) / 2.0
- def findKth(self, A, B, k):
-
- if len(A) == 0:
- return B[k-1]
- if len(B) == 0:
- return A[k-1]
- if k == 1:
- return min(A[0], B[0])
- a = A[floor(k/2)-1] if len(A) >= k/2 else None
- b = B[floor(k/2)-1] if len(B) >= k/2 else None
- if b is None or (a is not None and a < b):
- return self.findKth(A[floor(k/2):], B, k - floor(k/2))
- else:
- return self.findKth(A, B[floor(k/2):], k - floor(k/2))
-```
-
-这个findKth的算法单独抽出来也是题目。
-### 寻找最小的k个数
-
-题目描述
-
-输入n个整数,输出其中最小的k个。
-分析与解法
-
-## 解法一
-
-要求一个序列中最小的k个数,按照惯有的思维方式,则是先对这个序列从小到大排序,然后输出前面的最小的k个数。
-至于选取什么的排序方法,我想你可能会第一时间想到快速排序(我们知道,快速排序平均所费时间为n*logn),然后再遍历序列中前k个元素输出即可。因此,总的时间复杂度:```O(n * log n)+O(k)=O(n * log n)```。
-## 解法二
-
-咱们再进一步想想,题目没有要求最小的```k```个数有序,也没要求最后```n-k```个数有序。既然如此,就没有必要对所有元素进行排序。这时,咱们想到了用选择或交换排序,即:
-1. 遍历```n```个数,把最先遍历到的k个数存入到大小为```k```的数组中,假设它们即是最小的```k```个数;
-2. 对这```k```个数,利用选择或交换排序找到这k个元素中的最大值```kmax```(找最大值需要遍历这```k```个数,时间复杂度为```O(k))```;
-3. 继续遍历剩余```n-k```个数。假设每一次遍历到的新的元素的值为```x```,把```x```与```kmax```比较:如果```x``` < ```kmax``` ,用```x```替换```kmax```,并回到第二步重新找出k个元素的数组中最大元素kmax‘;如果```x >= kmax```,则继续遍历不更新数组。
-每次遍历,更新或不更新数组的所用的时间为```O(k)```或```O(0)```。故整趟下来,时间复杂度为```n*O(k)=O(n*k)```。
-## 解法三
-
-更好的办法是维护容量为k的最大堆,原理跟解法二的方法相似:
-1. 用容量为```k```的最大堆存储最先遍历到的```k```个数,同样假设它们即是最小的```k```个数;
-2. 堆中元素是有序的,令```k1 pivot ){ }
- if( i < j )
- swap( &a[ i ], &a[ j ] );
- else
- break;
- }
- //重置枢纽元
- swap( &a[ i ], &a[ right - 1 ] );
-
- if( k <= i )
- QuickSelect( a, k, left, i - 1 );
- else if( k > i + 1 )
- QuickSelect( a, k, i + 1, right );
- }
- else
- InsertSort( a + left, right - left + 1 );
-}
-```
-这个快速选择SELECT算法,类似快速排序的划分方法。N个数存储在数组S中,再从数组中选取“中位数的中位数”作为枢纽元X,把数组划分为Sa和Sb俩部分,Sa<=X<=Sb,如果要查找的k个元素小于Sa的元素个数,则返回Sa中较小的k个元素,否则返回Sa中所有元素+Sb中小的k-|Sa|个元素,这种解法在平均情况下能做到O(n)的复杂度。
-更进一步,《算法导论》第9章第9.3节介绍了一个最坏情况下亦为O(n)时间的SELECT算法,有兴趣的读者可以参看。
-
-给定两个已经排序好的数组,求第k大的,算法有O(m+n).类似merge sort的原理。否则利用的就是之上提到的,利用已经有序的原理,然后每次丢。
-
-之所以这里还有一个丢弃条件是b is None 丢A的一部分,是因为B的数组长度是有限的,这个时候很明显丢A的k/2是不影响的,因为无论B[-1]是如何大或者小,因为整个B的长度没有达到k/2小,所以丢掉的这部分最大的A[k/2-1]也不可能是第k个,因为即使整个B都比A[k/2-1]小,拼起来也不能使A[k/2-1]第k大,所以可以放心丢弃。
-
-
-这里是两个sorted list/array findKth,想到了类似的题目,如果给一个n个linked list,findKth,能想到的办法也只能是用heap吧,类似merge k sorted lists.
-
-
-再写一个O(m+n)类似merge sort的也可以AC的代码
-
-```python
-class Solution(object):
- def findMedianSortedArrays(self, nums1, nums2):
- """
- :type nums1: List[int]
- :type nums2: List[int]
- :rtype: float
- """
- def findKth(A, pa, B, pb, k):
- res = 0
- m = 0
- while pa < len(A) and pb < len(B) and m < k:
- if A[pa] < B[pb]:
- res = A[pa]
- m += 1
- pa += 1
- else:
- res = B[pb]
- m += 1
- pb += 1
-
- while pa < len(A) and m < k:
- res = A[pa]
- pa += 1
- m += 1
-
-
- while pb < len(B) and m < k:
- res = B[pb]
- pb += 1
- m += 1
- return res
-
- n = len(nums1) + len(nums2)
- if n % 2 == 1:
- return findKth(nums1,0, nums2,0, n / 2 + 1)
- else:
- smaller = findKth(nums1,0, nums2,0, n / 2)
- bigger = findKth(nums1,0, nums2,0, n / 2 + 1)
- return (smaller + bigger) / 2.0
-
-```
+# 4. Median of Two Sorted Arrays
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/median-of-two-sorted-arrays/description/
+
+> 内容描述
+
+```
+
+There are two sorted arrays nums1 and nums2 of size m and n respectively.
+
+Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
+
+You may assume nums1 and nums2 cannot be both empty.
+
+Example 1:
+
+nums1 = [1, 3]
+nums2 = [2]
+
+The median is 2.0
+Example 2:
+
+nums1 = [1, 2]
+nums2 = [3, 4]
+
+The median is (2 + 3)/2 = 2.5
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(lg(m+n))******- 空间复杂度: O(1)******
+
+
+一看到的时候,觉得跟CLRS书上的一道习题类似
+求X[1....n] Y[1....n] 的 median
+
+习题 9.3-8
+
+
+Let X[1..n] and Y [1..n] be two arrays, each containing n numbers already in sorted order. Give an O(lg n)-time algorithn to find the median of all 2n elements in arrays X and Y .
+
+
+> The median can be obtained recursively as follows. Pick the median of the sorted array A. This is just O(1) time as median is the n/2th element in the sorted array. Now compare the median of A, call is a∗ with median of B, b∗. We have two cases.
+
+- a∗ < b∗ : In this case, the elements in B[n/2 ···n] are also greater than a . So the median cannot lie in either A[1 · · · n/2 ] or B[n/2 · · · n]. So we can just throw these away and recursively
+
+- a∗ > b∗ : In this case, we can still throw away B[1··· n/2] and also A[ n/ · · · n] and solve a smaller subproblem recursively.
+
+
+In either case, our subproblem size reduces by a factor of half and we spend only constant time to compare the medians of A and B. So the recurrence relation would be T (n) = T (n/2) + O(1) which has a solution T (n) = O(log n).
+
+
+divide and conquer
+
+- 如果X[n/2] == Y[n/2],则找到,return
+- 如果X[n/2] < Y[n/2],找X[n/2+1….n]和Y[1,2…n/2]之间
+- 否则找X[1..n/2]和Y[n/2…n]
+
+
+
+
+但是实际上不同,这里需要考虑的问题更多:
+
+- 两个数组长度不一样
+- 并不是只找一个median,如果median有两个,需要算平均
+
+思路
+
+把它转化成经典的findKth问题
+
+参考:
+
+
+首先转成求A和B数组中第k小的数的问题, 然后用k/2在A和B中分别找。
+
+
+比如k = 6, 分别看A和B中的第3个数, 已知 A1 < A2 < A3 < A4 < A5... 和 B1 < B2 < B3 < B4 < B5..., 如果A3 <= B3, 那么第6小的数肯定不会是A1, A2, A3, 因为最多有两个数小于A1, 三个数小于A2, 四个数小于A3。 关键点是从 k/2 开始来找。
+
+
+
+B3至少大于5个数, 所以第6小的数有可能是B1 (A1 < A2 < A3 < A4 < A5 < B1), 有可能是B2 (A1 < A2 < A3 < B1 < A4 < B2), 有可能是B3 (A1 < A2 < A3 < B1 < B2 < B3)。那就可以排除掉A1, A2, A3, 转成求A4, A5, ... B1, B2, B3, ...这些数中第3小的数的问题, k就被减半了。每次都假设A的元素个数少, pa = min(k/2, lenA)的结果可能导致k == 1或A空, 这两种情况都是终止条件。
+
+
+发问,为什么要从k/2开始寻找,依旧k = 6, 我可以比较A1 和 B5的关系么,可以这样做,但是明显的问题出现在如果A1 > B5,那么这个第6小的数应该存在于B6和A1中。
+
+如果A1 < B5,这个时间可能性就很多了,比如A1 < A2 < A3 < A4 < B1 < B2,各种可能,无法排除元素,所以还是要从k/2开始寻找。
+
+这个跟习题算法的区别是每次扔的东西明显少一些,但是k也在不断变小。下面的代码的时间复杂度是O(lg(m+n))
+
+beats 64.27%
+
+```python
+class Solution(object):
+ def findMedianSortedArrays(self, nums1, nums2):
+ """
+ :type nums1: List[int]
+ :type nums2: List[int]
+ :rtype: float
+ """
+ def findKth(A, B, k):
+ if len(A) == 0:
+ return B[k-1]
+ if len(B) == 0:
+ return A[k-1]
+ if k == 1:
+ return min(A[0], B[0])
+
+ a = A[k // 2 - 1] if len(A) >= k // 2 else None
+ b = B[k // 2 - 1] if len(B) >= k // 2 else None
+
+ if b is None or (a is not None and a < b):
+ return findKth(A[k // 2:], B, k - k // 2)
+ return findKth(A, B[k // 2:], k - k // 2) # 这里要注意:因为 k/2 不一定 等于 (k - k/2)
+
+ n = len(nums1) + len(nums2)
+ if n % 2 == 1:
+ return findKth(nums1, nums2, n // 2 + 1)
+ else:
+ smaller = findKth(nums1, nums2, n // 2)
+ bigger = findKth(nums1, nums2, n // 2 + 1)
+ return (smaller + bigger) / 2.0
+```
+
+
+# 这个findKth的算法单独抽出来也是题目。
+### 寻找最小的k个数
+
+题目描述
+
+输入n个整数,输出其中最小的k个。
+分析与解法
+
+## 解法一
+
+要求一个序列中最小的k个数,按照惯有的思维方式,则是先对这个序列从小到大排序,然后输出前面的最小的k个数。
+至于选取什么的排序方法,我想你可能会第一时间想到快速排序(我们知道,快速排序平均所费时间为n*logn),然后再遍历序列中前k个元素输出即可。因此,总的时间复杂度:```O(n * log n)+O(k)=O(n * log n)```。
+## 解法二
+
+咱们再进一步想想,题目没有要求最小的```k```个数有序,也没要求最后```n-k```个数有序。既然如此,就没有必要对所有元素进行排序。这时,咱们想到了用选择或交换排序,即:
+1. 遍历```n```个数,把最先遍历到的k个数存入到大小为```k```的数组中,假设它们即是最小的```k```个数;
+2. 对这```k```个数,利用选择或交换排序找到这k个元素中的最大值```kmax```(找最大值需要遍历这```k```个数,时间复杂度为```O(k))```;
+3. 继续遍历剩余```n-k```个数。假设每一次遍历到的新的元素的值为```x```,把```x```与```kmax```比较:如果```x``` < ```kmax``` ,用```x```替换```kmax```,并回到第二步重新找出k个元素的数组中最大元素kmax‘;如果```x >= kmax```,则继续遍历不更新数组。
+每次遍历,更新或不更新数组的所用的时间为```O(k)```或```O(0)```。故整趟下来,时间复杂度为```n*O(k)=O(n*k)```。
+## 解法三
+
+更好的办法是维护容量为k的最大堆,原理跟解法二的方法相似:
+1. 用容量为```k```的最大堆存储最先遍历到的```k```个数,同样假设它们即是最小的```k```个数;
+2. 堆中元素是有序的,令```k1 pivot ){ }
+ if( i < j )
+ swap( &a[ i ], &a[ j ] );
+ else
+ break;
+ }
+ //重置枢纽元
+ swap( &a[ i ], &a[ right - 1 ] );
+
+ if( k <= i )
+ QuickSelect( a, k, left, i - 1 );
+ else if( k > i + 1 )
+ QuickSelect( a, k, i + 1, right );
+ }
+ else
+ InsertSort( a + left, right - left + 1 );
+}
+```
+这个快速选择SELECT算法,类似快速排序的划分方法。N个数存储在数组S中,再从数组中选取“中位数的中位数”作为枢纽元X,把数组划分为Sa和Sb俩部分,Sa<=X<=Sb,如果要查找的k个元素小于Sa的元素个数,则返回Sa中较小的k个元素,否则返回Sa中所有元素+Sb中小的k-|Sa|个元素,这种解法在平均情况下能做到O(n)的复杂度。
+更进一步,《算法导论》第9章第9.3节介绍了一个最坏情况下亦为O(n)时间的SELECT算法,有兴趣的读者可以参看。
+
+给定两个已经排序好的数组,求第k大的,算法有O(m+n).类似merge sort的原理。否则利用的就是之上提到的,利用已经有序的原理,然后每次丢。
+
+之所以这里还有一个丢弃条件是b is None 丢A的一部分,是因为B的数组长度是有限的,这个时候很明显丢A的k/2是不影响的,因为无论B[-1]是如何大或者小,因为整个B的长度没有达到k/2小,所以丢掉的这部分最大的A[k/2-1]也不可能是第k个,因为即使整个B都比A[k/2-1]小,拼起来也不能使A[k/2-1]第k大,所以可以放心丢弃。
+
+
+这里是两个sorted list/array findKth,想到了类似的题目,如果给一个n个linked list,findKth,能想到的办法也只能是用heap吧,类似merge k sorted lists.
+
+
+再写一个O(m+n)类似merge sort的也可以AC的代码
+
+```python
+class Solution(object):
+ def findMedianSortedArrays(self, nums1, nums2):
+ """
+ :type nums1: List[int]
+ :type nums2: List[int]
+ :rtype: float
+ """
+ def findKth(A, pa, B, pb, k):
+ res = 0
+ m = 0
+ while pa < len(A) and pb < len(B) and m < k:
+ if A[pa] < B[pb]:
+ res = A[pa]
+ m += 1
+ pa += 1
+ else:
+ res = B[pb]
+ m += 1
+ pb += 1
+
+ while pa < len(A) and m < k:
+ res = A[pa]
+ pa += 1
+ m += 1
+
+
+ while pb < len(B) and m < k:
+ res = B[pb]
+ pb += 1
+ m += 1
+ return res
+
+ n = len(nums1) + len(nums2)
+ if n % 2 == 1:
+ return findKth(nums1,0, nums2,0, n / 2 + 1)
+ else:
+ smaller = findKth(nums1,0, nums2,0, n / 2)
+ bigger = findKth(nums1,0, nums2,0, n / 2 + 1)
+ return (smaller + bigger) / 2.0
+
+```
diff --git a/docs/Leetcode_Solutions/Python/005._longest_palindromic_substring.md b/docs/Leetcode_Solutions/Python/005._longest_palindromic_substring.md
new file mode 100644
index 000000000..c79d8932e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/005._longest_palindromic_substring.md
@@ -0,0 +1,257 @@
+# 5. Longest Palindromic Substring
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/longest-palindromic-substring/description/
+
+> 内容描述
+
+```
+Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
+
+Example 1:
+
+Input: "babad"
+Output: "bab"
+Note: "aba" is also a valid answer.
+Example 2:
+
+Input: "cbbd"
+Output: "bb"
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N^2)******
+
+
+所以一个好的想法是 s 和 reverse(s) 共有的最长的 substring就是longest palindromic substring -> 问题转成求Longest common substring problem
+
+参见wikipedia
+
+,典型动归
+
+LCSuff(S1...p, T1...q) = LCS(S1...p1, T1...q-1) if S[p] = T[q] else 0
+
+
+
+伪码也有了,代码也有:
+
+https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring#Python_2
+
+这样也超时?
+```
+class Solution(object):
+ def longestPalindrome(self, s):
+ """
+ :type s: str
+ :rtype: str
+ """
+ def lcs(s1, s2):
+ m = [[0] * (1 + len(s2)) for i in xrange(1 + len(s1))]
+ longest, x_longest = 0, 0
+ for x in xrange(1, 1 + len(s1)):
+ for y in xrange(1, 1 + len(s2)):
+ if s1[x - 1] == s2[y - 1]:
+ m[x][y] = m[x - 1][y - 1] + 1
+ if m[x][y] > longest:
+ longest = m[x][y]
+ x_longest = x
+ else:
+ m[x][y] = 0
+ return s1[x_longest - longest: x_longest]
+
+ return lcs(s, s[::-1])
+```
+因为以为这样s[::-1]已经很快了.
+
+这个方法是buggy的,看字符串abcxgcba,它reverse之后是abcgxcba,它们有公共字符串,但是这里面没有回文,修复方式是:
+
+we check if the substring’s indices are the same as the reversed substring’s original indices. If it is, then we attempt to update the longest palindrome found so far; if not, we skip this and find the next candidate.
+
+我觉得的修复方式这样么:
+
+ 原本 翻转
+ ABXYBA ABYXBA
+
+ 求出来的substring indices是 0:2 但是这个s1[0:2] 和 s2[0:2]一样,所以不行
+ 同理common substring indices还是s[4:6] 和s2[4:6]一样,不行
+
+ 而比如ABAD和 DABA
+
+ substring indice 一个是0:3, 一个是1:4,这样就没问题
+
+
+
+
+> 思路 2
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+
+依次把每一个字符当做回文字符串的中间字符,找到以该字符为中间字符的回文串的最大长度。分别对奇偶的情况进行讨论,接下来的关键就是对边界的把握,确保下标不要越界。当子串已经包含首字符或最后一个字符且此时还是回文串的时候,下标分别会向两边多移一位,需要补回来。
+
+参考https://shenjie1993.gitbooks.io/leetcode-python/content/005%20Longest%20Palindromic%20Substring.html
+```python
+class Solution(object):
+ def longestPalindrome(self, s):
+ """
+ :type s: str
+ :rtype: str
+ """
+ n = len(s)
+
+ # empty or one char
+ if n < 2:
+ return s
+
+ # left index of the target substring
+ l = 0
+ # right index of the target substring
+ r = 0
+ # length of the longest palindromic substring for now
+ m = 0
+ # length of the current substring
+ c = 0
+
+ # Whether the substring contains the first character or last character and is palindromic
+ b = True
+ for i in range(n):
+ # Odd situation
+ for j in range(min(n-i,i+1)):
+ if s[i-j] != s [i+j]:
+ b = False
+ break
+ else:
+ c = 2 * j + 1
+
+ if c > m :
+ l = i - j + 1 - b
+ r = i + j + b
+ m = c
+ b = True
+
+ # Even situation
+ for j in range(min(n - i - 1, i + 1)):
+ if (s[i - j] != s[i + j + 1]):
+ b = False
+ break
+ else:
+ c = 2 * j + 2
+ if (c > m):
+ l = i - j + 1 - b
+ r = i + j + 1 + b
+ m = c
+ b = True
+ return s[l:r]
+```
+以上是参考版本,自己写的版本:
+```python
+class Solution(object):
+ def longestPalindrome(self, s):
+ """
+ :type s: str
+ :rtype: str
+ """
+ n = len(s)
+
+ m,l,r = 0,0,0
+
+ for i in range(n):
+ # odd case
+ for j in range(min(i+1,n-i)):
+ if s[i-j] != s[i+j]:
+ break
+ if 2*j + 1 > m :
+ m = 2 * j + 1
+ l = i-j
+ r = i+j
+
+
+ if i+1 < n and s[i] == s[i+1]:
+ for j in range(min(i+1,n-i-1)):
+ if s[i-j] != s[i+j+1]:
+ break
+ if 2 * j + 2 > m :
+ m = 2*j +2
+ l = i-j
+ r = i+j+1
+ return s[l:r+1]
+```
+
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+[Manacher算法](https://www.felix021.com/blog/read.php?2040)
+
+[useful link](https://articles.leetcode.com/longest-palindromic-substring-part-ii/)
+
+Manacher算法增加两个辅助变量id和mx,其中id表示最大回文子串中心的位置,mx则为id+P[id],也就是最大回文子串的边界。得到一个很重要的结论:
+
+- 如果mx > i,那么P[i] >= Min(P[2 * id - i], mx - i) . 为什么这样说呢,下面解释
+
+下面,令j = 2*id - i,也就是说j是i关于id的对称点。
+
+- 当 mx - i > P[j] 的时候,以S[j]为中心的回文子串包含在以S[id]为中心的回文子串中,由于i和j对称,以S[i]为中心的回文子串必然包含在以S[id]为中心的回文子串中,所以必有P[i] = P[j];
+
+
+- 当 P[j] >= mx - i 的时候,以S[j]为中心的回文子串不一定完全包含于以S[id]为中心的回文子串中,但是基于对称性可知,下图中两个绿框所包围的部分是相同的,也就是说以S[i]为中心的回文子串,其向右至少会扩张到mx的位置,也就是说 P[i] >= mx - i。至于mx之后的部分是否对称,再具体匹配。
+
+所以P[i] >= Min(P[2 * id - i], mx - i),因为以j为中心的绘回文子串的左边界可能会比mx关于id的对称点要大,此时只能证明P[i]=P[2 * id - i]
+- 此外,对于 mx <= i 的情况,因为无法对 P[i]做更多的假设,只能让P[i] = 1,然后再去匹配。
+
+在下面的程序中我的P数组保存的是,以当前字符为回文子串中心时,该回文子串的长度(不包含当前字符自身)
+
+
+简单地用一个小例子来解释:原字符串为'qacbcaw',一眼就可以看出来最大回文子串是'acbca',
+下面是我做的图,累shi了!
+
+
+
+
+
+所以最终代码中的max_i就是字符'b'所对应的index8,start的值就是(max_i - P[max_i] - 1) / 2 = 1,最终输出结果为s[1:6],即‘acbca’
+
+```python
+class Solution(object):
+ def longestPalindrome(self, s):
+ """
+ :type s: str
+ :rtype: str
+ """
+ def preProcess(s):
+ if not s:
+ return ['^', '&']
+ T = ['^']
+ for i in s:
+ T += ['#', i]
+ T += ['#', '$']
+ return T
+ T = preProcess(s)
+ P = [0] * len(T)
+ id, mx = 0, 0
+ for i in range(1, len(T)-1):
+ j = 2 * id - i
+ if mx > i:
+ P[i] = min(P[j], mx-i)
+ else:
+ P[i]= 0
+ while T[i+P[i]+1] == T[i-P[i]-1]:
+ P[i] += 1
+ if i + P[i] > mx:
+ id, mx = i, i + P[i]
+ max_i = P.index(max(P)) #保存的是当前最大回文子串中心位置的index
+ start = (max_i - P[max_i] - 1) / 2
+ res = s[start:start+P[max_i]]
+ return res
+```
+run code的时候结果会跟expected不一样,但是该input确实2个结果都可以,所以放心地submit吧
+还可以转到[647题](https://github.com/Lisanaaa/thinking_in_lc/blob/master/647._Palindromic_Substrings.md)去看一看,也可以用这个算法解
+
+
diff --git a/docs/leetcode/python/006._ZigZag_Conversion.md b/docs/Leetcode_Solutions/Python/006._ZigZag_Conversion.md
similarity index 100%
rename from docs/leetcode/python/006._ZigZag_Conversion.md
rename to docs/Leetcode_Solutions/Python/006._ZigZag_Conversion.md
diff --git a/docs/Leetcode_Solutions/Python/007._Reverse_Integer.md b/docs/Leetcode_Solutions/Python/007._Reverse_Integer.md
new file mode 100644
index 000000000..b3a00f61b
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/007._Reverse_Integer.md
@@ -0,0 +1,107 @@
+# 7. Reverse Integer 反转整数
+
+## 题目
+
+* https://leetcode.com/problems/Reverse-Integer
+* https://leetcode-cn.com/problems/reverse-integer/description/
+
+```
+给定一个 32 位有符号整数,将整数中的数字进行反转。
+
+> 示例 1:
+
+输入: 123
+输出: 321
+
+
+> 示例 2:
+
+输入: -123
+输出: -321
+
+
+> 示例 3:
+
+输入: 120
+输出: 21
+
+注意:
+假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。
+根据这个假设,如果反转后的整数溢出,则返回 0。
+```
+
+## 难度: Easy
+
+翻转数字问题需要注意的就是溢出问题,为什么会存在溢出问题呢,我们知道int型的数值范围是 -2147483648~2147483647(负的2的31次方~2的31次方-1), 那么如果我们要翻转 1000000009 这个在范围内的数得到 9000000001,而翻转后的数就超过了范围。
+
+> 思路1
+
+如果输入的是负数,就递归调用原函数,参数变成-x即可
+
+```python
+class Solution(object):
+ def reverse(self, x):
+ """
+ :type x: int
+ :rtype: int
+ """
+ if x < 0:
+ return -self.reverse(-x)
+ res = 0
+ while x:
+ res = res * 10 + x % 10
+ x /= 10
+ return res if res <= 0x7fffffff else 0
+```
+
+> 思路2
+
+按照参数正负号先将其转成字符串,然后再反转,根据是否溢出决定输出0还是反转结果
+
+```python
+class Solution(object):
+ def reverse(self, x):
+ """
+ :type x: int
+ :rtype: int
+ """
+ x = -int(str(x)[::-1][:-1]) if x < 0 else int(str(x)[::-1]) # [:-1]相当于把负号去掉
+ x = 0 if abs(x) > 0x7FFFFFFF else x
+ return x
+```
+
+> 思路3(StefanPochmann大神):
+
+看这个解法前先看[backticks](https://docs.python.org/2.7/reference/expressions.html#string-conversions)
+
+cmp函数在python3.x中用不了了,import operator用gt或者lt吧,或者回归if/else condition爸爸的怀抱吧!
+```python
+class Solution(object):
+ def reverse(self, x):
+ """
+ :type x: int
+ :rtype: int
+ """
+ s = cmp(x, 0)
+ r = int(`s * x`[::-1])
+ return s * r * (r < 2 ** 31)
+```
+
+> 思路4
+
+* 1.记录符号
+* 2.将数字当字符串处理
+* 3.判断是否阈值区间,进行比较就行
+
+```python
+class Solution:
+ def reverse(self, x):
+ """
+ :type x: int
+ :rtype: int
+ """
+ mark = 1 if x>=0 else -1
+ x_abs = abs(x)
+ result = mark * int(str(x_abs)[::-1])
+ return result if -2**31 <= result <= 2**31-1 else 0
+```
diff --git a/docs/leetcode/python/008._string_to_integer_(atoi).md b/docs/Leetcode_Solutions/Python/008._string_to_integer_(atoi).md
similarity index 100%
rename from docs/leetcode/python/008._string_to_integer_(atoi).md
rename to docs/Leetcode_Solutions/Python/008._string_to_integer_(atoi).md
diff --git a/docs/Leetcode_Solutions/Python/009._Palindrome_Number.md b/docs/Leetcode_Solutions/Python/009._Palindrome_Number.md
new file mode 100644
index 000000000..96714ac87
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/009._Palindrome_Number.md
@@ -0,0 +1,74 @@
+# 9. Palindrome Number 回文数
+
+## 题目
+
+* https://leetcode.com/problems/palindrome-number
+* https://leetcode-cn.com/problems/palindrome-number/description
+
+```
+判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
+
+示例 1:
+
+输入: 121
+输出: true
+示例 2:
+
+输入: -121
+输出: false
+解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
+示例 3:
+
+输入: 10
+输出: false
+解释: 从右向左读, 为 01 。因此它不是一个回文数。
+进阶:
+
+你能不将整数转为字符串来解决这个问题吗?
+```
+
+## 难度:Medium
+
+> 思路1 (满足Follow up)
+
+- 首先负数肯定不是palindrome
+- 其次如果一个数字是一个正数,并且能被我0整除那它肯定也不是palindrome
+
+这样降低了复杂度
+
+```python
+class Solution(object):
+ def isPalindrome(self, x):
+ """
+ :type x: int
+ :rtype: bool
+ """
+ if x < 0 or (x != 0 and x % 10 == 0):
+ return False
+ rev, y = 0, x
+ while x > 0:
+ rev = rev * 10 + x % 10
+ x /= 10
+ return y == rev
+
+```
+
+> 思路2
+
+* 排除小于0的数
+* 通过字符串进行反转,对比数字是否相等就行
+
+```python
+class Solution:
+ def isPalindrome(self, x):
+ """
+ :type x: int
+ :rtype: bool
+ """
+ if x < 0:
+ return False
+ elif x != int(str(x)[::-1]):
+ return False
+ else:
+ return True
+```
diff --git a/docs/leetcode/python/010._regular_expression_matching.md b/docs/Leetcode_Solutions/Python/010._regular_expression_matching.md
similarity index 80%
rename from docs/leetcode/python/010._regular_expression_matching.md
rename to docs/Leetcode_Solutions/Python/010._regular_expression_matching.md
index f3d51b109..a0a7ec103 100644
--- a/docs/leetcode/python/010._regular_expression_matching.md
+++ b/docs/Leetcode_Solutions/Python/010._regular_expression_matching.md
@@ -1,26 +1,74 @@
-### 010. Regular Expression Matching
+# 10. Regular Expression Matching
-题目:
-
+**难度: Easy**
+## 刷题内容
-难度:
+> 原题连接
-Hard
+* https://leetcode.com/problems/regular-expression-matching/description/
+> 内容描述
+```
+Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.
+
+'.' Matches any single character.
+'*' Matches zero or more of the preceding element.
+The matching should cover the entire input string (not partial).
+
+Note:
+
+s could be empty and contains only lowercase letters a-z.
+p could be empty and contains only lowercase letters a-z, and characters like . or *.
+Example 1:
+
+Input:
+s = "aa"
+p = "a"
+Output: false
+Explanation: "a" does not match the entire string "aa".
+Example 2:
+
+Input:
+s = "aa"
+p = "a*"
+Output: true
+Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
+Example 3:
+
+Input:
+s = "ab"
+p = ".*"
+Output: true
+Explanation: ".*" means "zero or more (*) of any character (.)".
+Example 4:
+
+Input:
+s = "aab"
+p = "c*a*b"
+Output: true
+Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".
+Example 5:
+
+Input:
+s = "mississippi"
+p = "mis*is*p*."
+Output: false
+```
+## 解题方案
-先尝试暴力解法,难点就在 * 身上, * 不会单独出现,它一定是和前面一个字母或"."配成一对。看成一对后"X*",它的性质就是:要不匹配0个,要不匹配连续的“X”.所以尝试暴力解法的时候一个trick是从后往前匹配.
-
+> 思路 1
+先尝试暴力解法,难点就在 * 身上, * 不会单独出现,它一定是和前面一个字母或"."配成一对。看成一对后"X*",它的性质就是:要不匹配0个,要不匹配连续的“X”.所以尝试暴力解法的时候一个trick是从后往前匹配.
暴力解法居然也能AC?
是这样来分情况看得:
- 如果s[i] = p[j] 或者 p[j]= . : 往前匹配一位
-- 如果p[j] = ' * ', 检查一下,如果这个时候p[j-1] = . 或者p[j-1] = s[i] ,那么就往前匹配,如果这样能匹配过,就return True, 否者我们忽略 ' X* ',这里注意里面的递推关系
+- 如果p[j] = ' * ', 检查一下,如果这个时候p[j-1] = . 或者p[j-1] = s[i] ,那么就往前匹配,如果这样能匹配过,就return True(注意如果这样不能最终匹配成功的话我们不能直接返回False,因为还可以直接忽略' X* '进行一下匹配试试是否可行), 否则我们忽略 ' X* ',这里注意里面的递推关系
- 再处理一下边界状况:
- s已经匹配完了, 如果此时p还有,那么如果剩下的是 X* 这种可以过,所以检查
- p匹配完毕,如果s还有那么报错
@@ -53,8 +101,8 @@ class Solution(object):
```
+> 思路 2
-----------
dp优化,感觉和edit distance很像。 DP优化待代码化,感觉学DP的一个重点除了递归学好以外,另一点是一定要会画表格。
diff --git a/docs/Leetcode_Solutions/Python/011._container_with_most_water.md b/docs/Leetcode_Solutions/Python/011._container_with_most_water.md
new file mode 100644
index 000000000..efd438c1d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/011._container_with_most_water.md
@@ -0,0 +1,90 @@
+# 11. Container With Most Water
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/container-with-most-water/description/
+
+> 内容描述
+
+```
+Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
+
+Note: You may not slant the container and n is at least 2.
+```
+
+
+
+```
+The above vertical lines are represented by array [1,8,6,2,5,4,8,3,7]. In this case, the max area of water (blue section) the container can contain is 49.
+
+
+
+Example:
+
+Input: [1,8,6,2,5,4,8,3,7]
+Output: 49
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+由于ai和aj (i ```S(left, j) = min(height[left], height[j]) * (j-left)```
+
+这就排除了所有以left为左边界的组合,因此需要右移left。
+
+因此:
+- ```height[left] < height[right],需要右移left.```
+
+- `同理,当height[left] > height[right]时,需要左移right`。
+
+- `而当height[left] = height[right]时,需要同时移动left和right。`
+
+思路整理:
+left = 0, right = n-1
+1. height[left] < height[right], left++
+2. height[left] > height[right], right--
+3. height[left] = height[right], left++, right--
+
+终止条件:left > right
+
+这个证明大快人心
+
+
+beats 82.89%
+
+
+```python
+class Solution(object):
+ def maxArea(self, height):
+ """
+ :type height: List[int]
+ :rtype: int
+ """
+ left, right, most_water = 0, len(height)-1, 0
+ while left <= right:
+ water = (right - left) * min(height[left], height[right])
+ most_water = max(water, most_water)
+ if height[left] < height[right]:
+ left += 1
+ elif height[left] > height[right]:
+ right -= 1
+ else:
+ left += 1
+ right -= 1
+ return most_water
+```
diff --git a/docs/Leetcode_Solutions/Python/012._Integer_to_Roman.md b/docs/Leetcode_Solutions/Python/012._Integer_to_Roman.md
new file mode 100644
index 000000000..3f7fdd8ef
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/012._Integer_to_Roman.md
@@ -0,0 +1,121 @@
+# 12. Integer to Roman
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/integer-to-roman/description/
+
+> 内容描述
+
+```
+Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
+
+Symbol Value
+I 1
+V 5
+X 10
+L 50
+C 100
+D 500
+M 1000
+For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.
+
+Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:
+
+I can be placed before V (5) and X (10) to make 4 and 9.
+X can be placed before L (50) and C (100) to make 40 and 90.
+C can be placed before D (500) and M (1000) to make 400 and 900.
+Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999.
+
+Example 1:
+
+Input: 3
+Output: "III"
+Example 2:
+
+Input: 4
+Output: "IV"
+Example 3:
+
+Input: 9
+Output: "IX"
+Example 4:
+
+Input: 58
+Output: "LVIII"
+Explanation: L = 50, V = 5, III = 3.
+Example 5:
+
+Input: 1994
+Output: "MCMXCIV"
+Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+首先我学习了一下罗马字母是如何表示的。然后感慨,这个阿拉伯数字是多么好的发明
+
+
+
+上图
+
+
+
+基于的是这些个Symbol:
+
+```
+1 5 10 50 100 500 1000
+I V X L C D M
+```
+
+
+
+罗马数字表示法见[Leetcode 013](https://github.com/Lisanaaa/thinking_in_lc/blob/master/013._Roman_to_Integer.md)
+
+这里有一个很棒的[算法](https://gist.github.com/imilu/00f32c61e50b7ca296f91e9d96d8e976)
+
+
+beats 51.51%
+
+```python
+class Solution(object):
+ def intToRoman(self, num):
+ """
+ :type num: int
+ :rtype: str
+ """
+ lookup = {
+ 'M': 1000,
+ 'CM': 900,
+ 'D': 500,
+ 'CD': 400,
+ 'C': 100,
+ 'XC': 90,
+ 'L': 50,
+ 'XL': 40,
+ 'X': 10,
+ 'IX': 9,
+ 'V': 5,
+ 'IV': 4,
+ 'I': 1
+ }
+ roman = ''
+
+ for symbol, val in sorted(lookup.items(), key = lambda t: t[1])[::-1]:
+ while num >= val:
+ roman += symbol
+ num -= val
+ return roman
+```
+
+
+
+
+
+因为dict本身是无序的,这里做了一个排序的操作,否则可能会出现IIII这种状况。
diff --git a/docs/Leetcode_Solutions/Python/013._Roman_to_Integer.md b/docs/Leetcode_Solutions/Python/013._Roman_to_Integer.md
new file mode 100644
index 000000000..b7bbb7a74
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/013._Roman_to_Integer.md
@@ -0,0 +1,128 @@
+# 13.Roman to Integer
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/roman-to-integer/
+
+> 内容描述
+
+```
+Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
+
+Symbol Value
+I 1
+V 5
+X 10
+L 50
+C 100
+D 500
+M 1000
+For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.
+
+Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:
+
+I can be placed before V (5) and X (10) to make 4 and 9.
+X can be placed before L (50) and C (100) to make 40 and 90.
+C can be placed before D (500) and M (1000) to make 400 and 900.
+Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.
+
+Example 1:
+
+Input: "III"
+Output: 3
+Example 2:
+
+Input: "IV"
+Output: 4
+Example 3:
+
+Input: "IX"
+Output: 9
+Example 4:
+
+Input: "LVIII"
+Output: 58
+Explanation: C = 100, L = 50, XXX = 30 and III = 3.
+Example 5:
+
+Input: "MCMXCIV"
+Output: 1994
+Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
+```
+
+## 解题方案
+
+> 思路 1
+
+
+```
+罗马数字是最古老的数字表示方式,比阿拉伯数组早2000多年,起源于罗马
+
+罗马数字有如下符号:
+
+基本字符 I V X L C D M
+对应阿拉伯数字 1 5 10 50 100 500 1000
+
+计数规则:
+- 相同的数字连写,所表示的数等于这些数字相加得到的数,例如:III = 3
+- 小的数字在大的数字右边,所表示的数等于这些数字相加得到的数,例如:VIII = 8
+- 小的数字,限于(I、X和C)在大的数字左边,所表示的数等于大数减去小数所得的数,例如:IV = 4,这条规则好像这题不管
+- 正常使用时,连续的数字重复不得超过三次
+- 在一个数的上面画横线,表示这个数扩大1000倍(本题只考虑3999以内的数,所以用不到这条规则)
+- 从前向后遍历罗马数字,如果某个数比前一个数小,则加上该数。反之,减去前一个数的两倍然后加上该数
+```
+
+
+
+integer to Roman 是 Medium,这个roman to integer是easy
+
+
+- 从前往后扫描,用一个临时变量记录分段数字。
+- 如果当前比前一个大,说明这一段的值应当是这个值减去上一个值。比如IV = 5-1 =4; 否则,将当前值加入到结果中,然后开始下一段记录,比如VI = 5 + 1, II = 1 +1
+
+
+
+
+AC代码
+
+```python
+class Solution(object):
+ def romanToInt(self, s):
+ """
+ :type s: str
+ :rtype: int
+ """
+ lookup = {
+ 'I': 1,
+ 'V': 5,
+ 'X': 10,
+ 'L': 50,
+ 'C': 100,
+ 'D': 500,
+ 'M': 1000
+ }
+ res = 0
+ for i in range(len(s)):
+ if i > 0 and lookup[s[i]] > lookup[s[i-1]]:
+ res += lookup[s[i]] - 2 * lookup[s[i-1]]
+ else:
+ res += lookup[s[i]]
+ return res
+```
+或者甚至可以建立一个新函数用于取对应数值:
+```
+ def table(x):
+ return {
+ 'I':1,
+ 'V':5,
+ 'X':10,
+ 'L':50,
+ 'C':100,
+ 'D':500,
+ 'M':1000
+ }.get(x)
+```
diff --git a/docs/leetcode/python/014._longest_common_prefix.md b/docs/Leetcode_Solutions/Python/014._longest_common_prefix.md
similarity index 100%
rename from docs/leetcode/python/014._longest_common_prefix.md
rename to docs/Leetcode_Solutions/Python/014._longest_common_prefix.md
diff --git a/docs/leetcode/python/015._3sum.md b/docs/Leetcode_Solutions/Python/015._3sum.md
similarity index 75%
rename from docs/leetcode/python/015._3sum.md
rename to docs/Leetcode_Solutions/Python/015._3sum.md
index 26a95fe2f..cdea768cd 100644
--- a/docs/leetcode/python/015._3sum.md
+++ b/docs/Leetcode_Solutions/Python/015._3sum.md
@@ -1,106 +1,134 @@
-### 15. 3Sum
-
-题目:
-
-
-
-难度:
-
-Medium
-
-
-第一想法,先把nums排序,用三个loop,无法AC
-
-```
-class Solution(object):
- def threeSum(self, nums):
- """
- :type nums: List[int]
- :rtype: List[List[int]]
- """
- n = len(nums)
- res = []
- nums.sort()
- for i in range(n):
- for j in range(i,n):
- for k in range(j,n):
- if nums[i] + nums[j] + nums[k] == 0 and j != i and k != j and k != i:
- curRes = [nums[i],nums[j],nums[k]]
- if curRes not in res:
- res.append(curRes)
-
- return res
-```
-
-
-然后查了一下2sum,用2sum的花样,因为要排除重复以及输出是按照从小到大的输出:但是还是超时
-
-
-```
-class Solution(object): # 此法也超时
- def threeSum(self, nums):
- """
- :type nums: List[int]
- :rtype: List[List[int]]
- """
- def twoSum(nums, target):
- """
- :type nums: List[int]
- :type target: int
- :rtype: List[int]
- """
- lookup = {}
- for num in nums:
- if target - num in lookup:
- if (-target ,target - num, num) not in res:
- res.append((-target ,target - num, num))
- lookup[num] = target - num
-
- n = len(nums)
- nums.sort()
- res = []
- for i in range(n):
- twoSum(nums[i+1:], 0-nums[i])
- return [list(i) for i in res]
-```
-
-
-谷歌看别人的代码,思路非常清晰的,运行起来比直接调用 Two Sum快.
-
-清晰的思路:
-
-- 排序
-- 固定左边,如果左边重复,继续
-- 左右弄边界,去重,针对不同的左右边界情况处理
-
-
-```python
-class Solution(object):
- def threeSum(self, nums):
- """
- :type nums: List[int]
- :rtype: List[List[int]]
- """
- n, res = len(nums), []
- nums.sort()
- for i in range(n):
- if i > 0 and nums[i] == nums[i-1]: # 因为i=0这个元素会直接往下执行
- continue
- l, r = i+1, n-1
- while l < r:
- tmp = nums[i] + nums[l] + nums[r]
- if tmp == 0:
- res.append([nums[i], nums[l], nums[r]])
- l += 1
- r -= 1
- while l < r and nums[l] == nums[l-1]:
- l += 1
- while l < r and nums[r] == nums[r+1]:
- r -= 1
- elif tmp > 0:
- r -= 1
- else:
- l += 1
- return res
-```
-
+# 15. 3Sum
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/3sum/
+
+> 内容描述
+
+```
+Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
+
+Note:
+
+The solution set must not contain duplicate triplets.
+
+Example:
+
+Given array nums = [-1, 0, 1, 2, -1, -4],
+
+A solution set is:
+[
+ [-1, 0, 1],
+ [-1, -1, 2]
+]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^3)******- 空间复杂度: O(N)******
+
+第一想法,先把nums排序,用三个loop,无法AC
+
+```
+class Solution(object):
+ def threeSum(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: List[List[int]]
+ """
+ n = len(nums)
+ res = []
+ nums.sort()
+ for i in range(n):
+ for j in range(i,n):
+ for k in range(j,n):
+ if nums[i] + nums[j] + nums[k] == 0 and j != i and k != j and k != i:
+ curRes = [nums[i],nums[j],nums[k]]
+ if curRes not in res:
+ res.append(curRes)
+
+ return res
+```
+
+> 思路 2
+******- 时间复杂度: O(N^3)******- 空间复杂度: O(N)******
+
+然后查了一下2sum,用2sum的花样,因为要排除重复以及输出是按照从小到大的输出:但是还是超时
+
+
+```
+class Solution(object): # 此法也超时
+ def threeSum(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: List[List[int]]
+ """
+ def twoSum(nums, target):
+ """
+ :type nums: List[int]
+ :type target: int
+ :rtype: List[int]
+ """
+ lookup = {}
+ for num in nums:
+ if target - num in lookup:
+ if (-target ,target - num, num) not in res:
+ res.append((-target ,target - num, num))
+ lookup[num] = target - num
+
+ n = len(nums)
+ nums.sort()
+ res = []
+ for i in range(n):
+ twoSum(nums[i+1:], 0-nums[i])
+ return [list(i) for i in res]
+```
+
+> 思路 3
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+谷歌看别人的代码,思路非常清晰的,运行起来比直接调用 Two Sum快.
+
+清晰的思路:
+
+- 排序
+- 固定左边,如果左边重复,继续
+- 左右弄边界,去重,针对不同的左右边界情况处理
+
+
+```python
+class Solution(object):
+ def threeSum(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: List[List[int]]
+ """
+ n, res = len(nums), []
+ nums.sort()
+ for i in range(n):
+ if i > 0 and nums[i] == nums[i-1]: # 因为i=0这个元素会直接往下执行
+ continue
+ l, r = i+1, n-1
+ while l < r:
+ tmp = nums[i] + nums[l] + nums[r]
+ if tmp == 0:
+ res.append([nums[i], nums[l], nums[r]])
+ l += 1
+ r -= 1
+ while l < r and nums[l] == nums[l-1]:
+ l += 1
+ while l < r and nums[r] == nums[r+1]:
+ r -= 1
+ elif tmp > 0:
+ r -= 1
+ else:
+ l += 1
+ return res
+```
+
diff --git a/docs/Leetcode_Solutions/Python/016._3sum_closest.md b/docs/Leetcode_Solutions/Python/016._3sum_closest.md
new file mode 100644
index 000000000..8c2525cd1
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/016._3sum_closest.md
@@ -0,0 +1,69 @@
+# 16. 3Sum Closest
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/3sum-closest/description/
+
+> 内容描述
+
+```
+
+Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
+
+Example:
+
+Given array nums = [-1, 2, 1, -4], and target = 1.
+
+The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+思路:
+跟3 Sum一样,固定一个元素
+
+用两个指针来循环
+
+
+```python
+class Solution(object):
+ def threeSumClosest(self, nums, target):
+ """
+ :type nums: List[int]
+ :rtype: List[List[int]]
+ """
+ n, res, diff = len(nums), None, float('inf')
+ nums.sort()
+ for i in range(n):
+ if i > 0 and nums[i] == nums[i-1]:
+ continue
+ l, r = i+1, n-1
+ while l < r:
+ tmp = nums[i] + nums[l] + nums[r]
+ if tmp == target:
+ return target
+ elif tmp > target:
+ r -= 1
+ if abs(tmp-target) < diff:
+ diff = abs(tmp-target)
+ res = tmp
+ while l < r and nums[r] == nums[r+1]:
+ r -= 1
+ else:
+ l += 1
+ if abs(tmp-target) < diff:
+ diff = abs(tmp-target)
+ res = tmp
+ while l < r and nums[l] == nums[l-1]:
+ l += 1
+ return res
+
+```
diff --git a/docs/Leetcode_Solutions/Python/017._letter_combinations_of_a_phone_number.md b/docs/Leetcode_Solutions/Python/017._letter_combinations_of_a_phone_number.md
new file mode 100644
index 000000000..0bee9cea5
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/017._letter_combinations_of_a_phone_number.md
@@ -0,0 +1,72 @@
+# 17. Letter Combinations of a Phone Number
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/
+
+> 内容描述
+
+```
+Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent.
+
+A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.
+
+
+
+Example:
+
+Input: "23"
+Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
+Note:
+
+Although the above answer is in lexicographical order, your answer could be in any order you want.
+```
+
+## 解题方案
+
+> 思路 1
+
+
+ - hash table一个,用来对应digit -> letter
+ - s用来记录结果,每次从digits里面去一个,然后寻找其可能的char,加到s中,digits长度减小
+ - digits长度为0时候,把它加入结果
+
+
+```python
+class Solution(object):
+ def letterCombinations(self, digits):
+ """
+ :type digits: str
+ :rtype: List[str]
+ """
+ lookup = {
+ '2':['a','b','c'],
+ '3':['d','e','f'],
+ '4':['g','h','i'],
+ '5':['j','k','l'],
+ '6':['m','n','o'],
+ '7':['p','q','r','s'],
+ '8':['t','u','v'],
+ '9':['w','x','y','z']
+ }
+ res = []
+
+ def helper(s, digits):
+ if len(digits) == 0:
+ res.append(s)
+ else:
+ cur_digit = digits[0]
+ for char in lookup[cur_digit]:
+ helper(s+char, digits[1:])
+
+ if not digits or len(digits) == 0:
+ return res
+ helper('', digits)
+ return res
+```
+
+
diff --git a/docs/leetcode/python/018._4sum.md b/docs/Leetcode_Solutions/Python/018._4sum.md
similarity index 100%
rename from docs/leetcode/python/018._4sum.md
rename to docs/Leetcode_Solutions/Python/018._4sum.md
diff --git a/docs/leetcode/python/019._remove_nth_node_from_end_of_list.md b/docs/Leetcode_Solutions/Python/019._remove_nth_node_from_end_of_list.md
similarity index 95%
rename from docs/leetcode/python/019._remove_nth_node_from_end_of_list.md
rename to docs/Leetcode_Solutions/Python/019._remove_nth_node_from_end_of_list.md
index 5de9f6673..5bdefb7a0 100644
--- a/docs/leetcode/python/019._remove_nth_node_from_end_of_list.md
+++ b/docs/Leetcode_Solutions/Python/019._remove_nth_node_from_end_of_list.md
@@ -1,42 +1,42 @@
-### 19. Remove Nth Node From End of List
-
-题目:
-
-
-
-
-难度: Medium
-
-
-AC击败了95.80%的Python用户,技巧 dummy head 和双指针。
-
-切记最后要返回```dummy.next```而不是```head```,因为有这样一种情况,删掉节点后```linked list```空了,那返回```head```的话结果显然不同。如:
-输入链表为```[1]```, ```n = 1```, 应该返回```None```而不是```[1]```
-
-```python
-class Solution(object):
- def removeNthFromEnd(self, head, n):
- """
- :type head: ListNode
- :type n: int
- :rtype: ListNode
- """
- dummy = ListNode(-1)
- dummy.next = head
- p, q = dummy, dummy
-
- for i in range(n):
- q = q.next
-
- while q.next:
- p = p.next
- q = q.next
-
- p.next = p.next.next
- return dummy.next
-
-```
-
-
-
-
+### 19. Remove Nth Node From End of List
+
+题目:
+
+
+
+
+难度: Medium
+
+
+AC击败了95.80%的Python用户,技巧 dummy head 和双指针。
+
+切记最后要返回```dummy.next```而不是```head```,因为有这样一种情况,删掉节点后```linked list```空了,那返回```head```的话结果显然不同。如:
+输入链表为```[1]```, ```n = 1```, 应该返回```None```而不是```[1]```
+
+```python
+class Solution(object):
+ def removeNthFromEnd(self, head, n):
+ """
+ :type head: ListNode
+ :type n: int
+ :rtype: ListNode
+ """
+ dummy = ListNode(-1)
+ dummy.next = head
+ p, q = dummy, dummy
+
+ for i in range(n):
+ q = q.next
+
+ while q.next:
+ p = p.next
+ q = q.next
+
+ p.next = p.next.next
+ return dummy.next
+
+```
+
+
+
+
diff --git a/docs/leetcode/python/020._valid_parentheses.md b/docs/Leetcode_Solutions/Python/020._valid_parentheses.md
similarity index 93%
rename from docs/leetcode/python/020._valid_parentheses.md
rename to docs/Leetcode_Solutions/Python/020._valid_parentheses.md
index fee842370..85442a225 100644
--- a/docs/leetcode/python/020._valid_parentheses.md
+++ b/docs/Leetcode_Solutions/Python/020._valid_parentheses.md
@@ -1,123 +1,123 @@
-# 20. Valid Parentheses 有效的括号
-
-**难度: Easy**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/valid-parentheses
-* https://leetcode-cn.com/problems/valid-parentheses
-
-> 内容描述
-
-```
-给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
-
-有效字符串需满足:
-
-左括号必须用相同类型的右括号闭合。
-左括号必须以正确的顺序闭合。
-注意空字符串可被认为是有效字符串。
-
-示例 1:
-
-输入: "()"
-输出: true
-示例 2:
-
-输入: "()[]{}"
-输出: true
-示例 3:
-
-输入: "(]"
-输出: false
-示例 4:
-
-输入: "([)]"
-输出: false
-示例 5:
-
-输入: "{[]}"
-输出: true
-```
-
-## 解题方案
-
-> 思路 1
-
-因为一共只有三种状况"(" -> ")", "[" -> "]", "{" -> "}".
-
-一遇到左括号就入栈,右括号出栈,这样来寻找对应
-
-需要检查几件事:
-
-- 出现右括号时stack里还有没有东西
-- 出stack时是否对应
-- 最终stack是否为空
-
-```python
-class Solution(object):
- def isValid(self, s):
- """
- :type s: str
- :rtype: bool
- """
- leftP = '([{'
- rightP = ')]}'
- stack = []
- for char in s:
- if char in leftP:
- stack.append(char)
- if char in rightP:
- if not stack:
- return False
- tmp = stack.pop()
- if char == ')' and tmp != '(':
- return False
- if char == ']' and tmp != '[':
- return False
- if char == '}' and tmp != '{':
- return False
- return stack == []
-```
-
-> 思路 2
-
-* 扩展性和可理解性强
-
-```python
-class Solution:
- def isValid(self, s):
- """
- :type s: str
- :rtype: bool
- """
- if len(s) % 2 == 1:
- return False
-
- index = 0
- stack = [i for i in s]
- map1 = {"(": ")", "[": "]", "{": "}"}
-
- while len(stack) > 0:
- # 判断索引是否超过边界
- if index >= len(stack)-1:
- return False
-
- b = stack[index]
- e = stack[index+1]
-
- if b not in map1.keys():
- return False
- elif e in map1.keys():
- index += 1
- elif map1[b] == e:
- stack.pop(index+1)
- stack.pop(index)
- index = 0 if index-1<0 else index-1
- else:
- return False
-
- return stack == []
-```
+# 20. Valid Parentheses 有效的括号
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/valid-parentheses
+* https://leetcode-cn.com/problems/valid-parentheses/description
+
+> 内容描述
+
+```
+给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
+
+有效字符串需满足:
+
+左括号必须用相同类型的右括号闭合。
+左括号必须以正确的顺序闭合。
+注意空字符串可被认为是有效字符串。
+
+示例 1:
+
+输入: "()"
+输出: true
+示例 2:
+
+输入: "()[]{}"
+输出: true
+示例 3:
+
+输入: "(]"
+输出: false
+示例 4:
+
+输入: "([)]"
+输出: false
+示例 5:
+
+输入: "{[]}"
+输出: true
+```
+
+## 解题方案
+
+> 思路 1
+
+因为一共只有三种状况"(" -> ")", "[" -> "]", "{" -> "}".
+
+一遇到左括号就入栈,右括号出栈,这样来寻找对应
+
+需要检查几件事:
+
+- 出现右括号时stack里还有没有东西
+- 出stack时是否对应
+- 最终stack是否为空
+
+```python
+class Solution(object):
+ def isValid(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ leftP = '([{'
+ rightP = ')]}'
+ stack = []
+ for char in s:
+ if char in leftP:
+ stack.append(char)
+ if char in rightP:
+ if not stack:
+ return False
+ tmp = stack.pop()
+ if char == ')' and tmp != '(':
+ return False
+ if char == ']' and tmp != '[':
+ return False
+ if char == '}' and tmp != '{':
+ return False
+ return stack == []
+```
+
+> 思路 2
+
+* 扩展性和可理解性强
+
+```python
+class Solution:
+ def isValid(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ if len(s) % 2 == 1:
+ return False
+
+ index = 0
+ stack = [i for i in s]
+ map1 = {"(": ")", "[": "]", "{": "}"}
+
+ while len(stack) > 0:
+ # 判断索引是否超过边界
+ if index >= len(stack)-1:
+ return False
+
+ b = stack[index]
+ e = stack[index+1]
+
+ if b not in map1.keys():
+ return False
+ elif e in map1.keys():
+ index += 1
+ elif map1[b] == e:
+ stack.pop(index+1)
+ stack.pop(index)
+ index = 0 if index-1<0 else index-1
+ else:
+ return False
+
+ return stack == []
+```
diff --git a/docs/Leetcode_Solutions/Python/021._merge_two_sorted_lists.md b/docs/Leetcode_Solutions/Python/021._merge_two_sorted_lists.md
new file mode 100644
index 000000000..1409c7e71
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/021._merge_two_sorted_lists.md
@@ -0,0 +1,57 @@
+# 21. Merge Two Sorted Lists
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/merge-two-sorted-lists/description/
+
+> 内容描述
+
+```
+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.
+
+Example:
+
+Input: 1->2->4, 1->3->4
+Output: 1->1->2->3->4->4
+```
+
+## 解题方案
+
+> 思路 1
+
+同样适用dummy head, beats 93.49%
+
+```python
+class Solution(object):
+ def mergeTwoLists(self, l1, l2):
+ """
+ :type l1: ListNode
+ :type l2: ListNode
+ :rtype: ListNode
+ """
+ if not l1:
+ return l2
+ if not l2:
+ return l1
+
+ dummy = cur = ListNode(-1)
+ while l1 and l2:
+ if l1.val < l2.val:
+ cur.next = l1
+ l1 = l1.next
+ else:
+ cur.next = l2
+ l2 = l2.next
+ cur = cur.next
+
+ cur.next = l1 if l1 else l2
+ return dummy.next
+```
+
+
+
+
diff --git a/docs/leetcode/python/022._generate_parentheses.md b/docs/Leetcode_Solutions/Python/022._generate_parentheses.md
similarity index 97%
rename from docs/leetcode/python/022._generate_parentheses.md
rename to docs/Leetcode_Solutions/Python/022._generate_parentheses.md
index 06282a26e..ae14c9089 100644
--- a/docs/leetcode/python/022._generate_parentheses.md
+++ b/docs/Leetcode_Solutions/Python/022._generate_parentheses.md
@@ -1,88 +1,88 @@
-### 22. Generate Parentheses
-
-题目:
-
-
-
-难度:
-
-Medium
-
-
-
-
-
-```python
-class Solution(object):
- def generateParenthesis(self,n):
- """
- :type n: int
- :rtype: List[str]
- """
- self.res = []
- self.singleStr('', 0, 0, n)
- return self.res
-
- def singleStr(self, s, left, right, n):
- if left == n and right == n:
- self.res.append(s)
- if left < n:
- self.singleStr(s + '(',left + 1, right,n)
- if right < left:
- self.singleStr(s + ')',left, right + 1, n)
-
-```
-
-
-非常牛逼的讲解,需要这样的人来给我们讲算法
-
-####以Generate Parentheses为例,backtrack的题到底该怎么去思考?
-
-
-所谓Backtracking都是这样的思路:在当前局面下,你有若干种选择。那么尝试每一种选择。如果已经发现某种选择肯定不行(因为违反了某些限定条件),就返回;如果某种选择试到最后发现是正确解,就将其加入解集
-
-所以你思考递归题时,只要明确三点就行:选择 (Options),限制 (Restraints),结束条件 (Termination)。即“ORT原则”(这个是我自己编的)
-
-
-
-
-对于这道题,在任何时刻,你都有两种选择:
-1. 加左括号。
-2. 加右括号。
-
-同时有以下限制:
-1. 如果左括号已经用完了,则不能再加左括号了。
-2. 如果已经出现的右括号和左括号一样多,则不能再加右括号了。因为那样的话新加入的右括号一定无法匹配。
-
-结束条件是:
-左右括号都已经用完。
-
-结束后的正确性:
-左右括号用完以后,一定是正确解。因为1. 左右括号一样多,2. 每个右括号都一定有与之配对的左括号。因此一旦结束就可以加入解集(有时也可能出现结束以后不一定是正确解的情况,这时要多一步判断)。
-
-递归函数传入参数:
-限制和结束条件中有“用完”和“一样多”字样,因此你需要知道左右括号的数目。
-当然你还需要知道当前局面sublist和解集res。
-
-因此,把上面的思路拼起来就是代码:
-
- if (左右括号都已用完) {
- 加入解集,返回
- }
- //否则开始试各种选择
- if (还有左括号可以用) {
- 加一个左括号,继续递归
- }
- if (右括号小于左括号) {
- 加一个右括号,继续递归
- }
-
-
-
-你帖的那段代码逻辑中加了一条限制:“3. 是否还有右括号剩余。如有才加右括号”。这是合理的。不过对于这道题,如果满足限制1、2时,3一定自动满足,所以可以不判断3。
-
-这题其实是最好的backtracking初学练习之一,因为ORT三者都非常简单明显。你不妨按上述思路再梳理一遍,还有问题的话再说。
-
-
-
-以上文字来自 1point3arces的牛人解答
+### 22. Generate Parentheses
+
+题目:
+
+
+
+难度:
+
+Medium
+
+
+
+
+
+```python
+class Solution(object):
+ def generateParenthesis(self,n):
+ """
+ :type n: int
+ :rtype: List[str]
+ """
+ self.res = []
+ self.singleStr('', 0, 0, n)
+ return self.res
+
+ def singleStr(self, s, left, right, n):
+ if left == n and right == n:
+ self.res.append(s)
+ if left < n:
+ self.singleStr(s + '(',left + 1, right,n)
+ if right < left:
+ self.singleStr(s + ')',left, right + 1, n)
+
+```
+
+
+非常牛逼的讲解,需要这样的人来给我们讲算法
+
+####以Generate Parentheses为例,backtrack的题到底该怎么去思考?
+
+
+所谓Backtracking都是这样的思路:在当前局面下,你有若干种选择。那么尝试每一种选择。如果已经发现某种选择肯定不行(因为违反了某些限定条件),就返回;如果某种选择试到最后发现是正确解,就将其加入解集
+
+所以你思考递归题时,只要明确三点就行:选择 (Options),限制 (Restraints),结束条件 (Termination)。即“ORT原则”(这个是我自己编的)
+
+
+
+
+对于这道题,在任何时刻,你都有两种选择:
+1. 加左括号。
+2. 加右括号。
+
+同时有以下限制:
+1. 如果左括号已经用完了,则不能再加左括号了。
+2. 如果已经出现的右括号和左括号一样多,则不能再加右括号了。因为那样的话新加入的右括号一定无法匹配。
+
+结束条件是:
+左右括号都已经用完。
+
+结束后的正确性:
+左右括号用完以后,一定是正确解。因为1. 左右括号一样多,2. 每个右括号都一定有与之配对的左括号。因此一旦结束就可以加入解集(有时也可能出现结束以后不一定是正确解的情况,这时要多一步判断)。
+
+递归函数传入参数:
+限制和结束条件中有“用完”和“一样多”字样,因此你需要知道左右括号的数目。
+当然你还需要知道当前局面sublist和解集res。
+
+因此,把上面的思路拼起来就是代码:
+
+ if (左右括号都已用完) {
+ 加入解集,返回
+ }
+ //否则开始试各种选择
+ if (还有左括号可以用) {
+ 加一个左括号,继续递归
+ }
+ if (右括号小于左括号) {
+ 加一个右括号,继续递归
+ }
+
+
+
+你帖的那段代码逻辑中加了一条限制:“3. 是否还有右括号剩余。如有才加右括号”。这是合理的。不过对于这道题,如果满足限制1、2时,3一定自动满足,所以可以不判断3。
+
+这题其实是最好的backtracking初学练习之一,因为ORT三者都非常简单明显。你不妨按上述思路再梳理一遍,还有问题的话再说。
+
+
+
+以上文字来自 1point3arces的牛人解答
diff --git a/docs/Leetcode_Solutions/Python/023._merge_k_sorted_lists.md b/docs/Leetcode_Solutions/Python/023._merge_k_sorted_lists.md
new file mode 100644
index 000000000..aaaace11f
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/023._merge_k_sorted_lists.md
@@ -0,0 +1,169 @@
+# 23. Merge k Sorted Lists
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/merge-k-sorted-lists/description/
+
+> 内容描述
+
+```
+Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
+
+Example:
+
+Input:
+[
+ 1->4->5,
+ 1->3->4,
+ 2->6
+]
+Output: 1->1->2->3->4->4->5->6
+```
+
+## 解题方案
+
+> 思路 1
+
+
+看到思路有heap,similar question有ugly number|| -> 这个是用heapq来解决的
+
+那么就用heap吧? heapsort
+
+最简单的做法是只要每个list里面还有node,就把他们扔到minheap里面去,然后再把minheap pop,一个一个node连起来,听起来时间复杂度和空间复杂度都蛮高的。
+直接merge必然是不好的,因为没有利用有序这个点,应该做的是每次取来一个,然后再把应该的下一个放入
+
+写到这里瞬间明白和ugly number ii像的点了,甚至感觉跟find in sorted matrix ii也像
+
+beats 96.26%
+
+```python
+class Solution(object):
+ def mergeKLists(self, lists):
+ """
+ :type lists: List[ListNode]
+ :rtype: ListNode
+ """
+ from heapq import heappush, heappop
+ nodes_pool = []
+ dummy = cur = ListNode(-1)
+ for head in lists:
+ if head:
+ heappush(nodes_pool, [head.val, head])
+ while nodes_pool:
+ smallest_node = heappop(nodes_pool)[1]
+ cur.next = smallest_node
+ cur = cur.next
+ if smallest_node.next:
+ heappush(nodes_pool, [smallest_node.next.val, smallest_node.next])
+ return dummy.next
+```
+
+但是上面这个程序只能在python2里面用,如果在python3里面会报错:```TypeError: unorderable types: ListNode() < ListNode()```,
+这是因为python3里面ListNode类型不能用于order了
+
+因此对于python3我修改了一下程序,多用了一个dict来存放对应的node,这样就可以达到相同的效果了,见下面:
+
+beats 96.50%
+
+```python
+class Solution:
+ def mergeKLists(self, lists):
+ """
+ :type lists: List[ListNode]
+ :rtype: ListNode
+ """
+ from heapq import heappush, heappop
+ node_pools = []
+ lookup = collections.defaultdict(list)
+ for head in lists:
+ if head:
+ heappush(node_pools, head.val)
+ lookup[head.val].append(head)
+ dummy = cur = ListNode(None)
+ while node_pools:
+ smallest_val = heappop(node_pools)
+ smallest_node = lookup[smallest_val].pop(0)
+ cur.next = smallest_node
+ cur = cur.next
+ if smallest_node.next:
+ heappush(node_pools, smallest_node.next.val)
+ lookup[smallest_node.next.val].append(smallest_node.next)
+ return dummy.next
+```
+
+
+
+
+## Follow up
+
+> 问题描述
+
+```
+一个double array length为n,有k个区间,n >> k,每个区间是单调递增的
+比如 [2.3, 5, 8.4, 3, 5, 1, 3, 9],这里k是3,三个区间是[2.3, 5, 8.4],[3, 5], [1,3,9]
+要求输出sort好的array
+比如 [1,2.3,3,3,5,5,8.4,9]
+```
+
+## 解题方案
+
+> 思路 1
+
+跟上面一样的思路,维护一个当前num pool就行了
+
+```python
+class Solution(object):
+ def mergeKLists(self, nums, k):
+ """
+ :type list: int
+ :rtype: list
+ """
+ num_pool = [] # current nums we are comparing
+ interval_idx = [] # current k interval
+ start, end = 0, 0
+ for i in range(len(nums)-1):
+ if nums[i] > nums[i+1]:
+ end = i
+ interval_idx.append([start, end])
+ start = i+1
+ interval_idx.append([start, len(nums)-1])
+ # record which start is invalid in arr_idx
+ invalid_interval_idx = set()
+ res = []
+ while len(invalid_interval_idx) != k:
+ for i in range(len(interval_idx)):
+ # we have to make sure start <= end
+ if interval_idx[i][0] <= interval_idx[i][1]:
+ num_pool.append(nums[interval_idx[i][0]])
+ interval_idx[i][0] += 1
+ else:
+ invalid_interval_idx.add(i)
+ num_pool.sort()
+ # begin to handle current k (maybe) nums
+ for i in range(len(num_pool)):
+ res.append(num_pool[i])
+ num_pool = []
+ return res
+```
+
+
+写一下测试用例
+
+```python
+import unittest
+
+
+class TestSolution(unittest.TestCase):
+ def test_none_0(self):
+ nums = [2.3, 5, 8.4, 3, 5, 1, 3, 9]
+ res = [1, 2.3, 3, 3, 5, 5, 8.4, 9]
+ self.assertTrue(Solution().mergeKLists(nums, 3) == res)
+
+
+if __name__ == "__main__":
+ unittest.main()
+```
diff --git a/docs/leetcode/python/024._swap_nodes_in_pairs.md b/docs/Leetcode_Solutions/Python/024._swap_nodes_in_pairs.md
similarity index 100%
rename from docs/leetcode/python/024._swap_nodes_in_pairs.md
rename to docs/Leetcode_Solutions/Python/024._swap_nodes_in_pairs.md
diff --git a/docs/Leetcode_Solutions/Python/026._Remove_Duplicates_from_Sorted_Array.md b/docs/Leetcode_Solutions/Python/026._Remove_Duplicates_from_Sorted_Array.md
new file mode 100644
index 000000000..c3dd0e500
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/026._Remove_Duplicates_from_Sorted_Array.md
@@ -0,0 +1,137 @@
+# 26. Remove Duplicates from Sorted Array
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/
+
+> 内容描述
+
+```
+Given a sorted array nums, 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 by modifying the input array in-place with O(1) extra memory.
+
+Example 1:
+
+Given nums = [1,1,2],
+
+Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.
+
+It doesn't matter what you leave beyond the returned length.
+Example 2:
+
+Given nums = [0,0,1,1,1,2,2,3,3,4],
+
+Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively.
+
+It doesn't matter what values are set beyond the returned length.
+Clarification:
+
+Confused why the returned value is an integer but your answer is an array?
+
+Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.
+
+Internally you can think of this:
+
+// nums is passed in by reference. (i.e., without making a copy)
+int len = removeDuplicates(nums);
+
+// any modification to nums in your function would be known by the caller.
+// using the length returned by your function, it prints the first len elements.
+for (int i = 0; i < len; i++) {
+ print(nums[i]);
+}
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+因为题目说了是```sorted array```,所以只需要不停判断当前位置值和下一位置是否相等,若相等则```pop掉当前值```,否则```move```到下一位置做重复判断
+
+beats 39.49%
+
+```python
+class Solution(object):
+ def removeDuplicates(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ idx = 0
+ while idx < len(nums) - 1:
+ if nums[idx] == nums[idx+1]:
+ nums.pop(idx)
+ else:
+ idx += 1
+ return len(nums)
+```
+
+
+这里代码用```while loop```而不用```for loop```是因为```pop```操作之后```nums```的长度会变化
+
+如:```for i in range(len(nums)-1)```实际上固定了```range```里面的值了,不会二次判断
+
+```
+n = 10
+for i in range(n):
+ n = n - 1 # 尽管n在变化
+ print(i)
+
+上面这段代码的输出结果为:
+
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+思路直接看代码就能明白或者去看[leetcode 第80题](https://github.com/apachecn/awesome-algorithm/blob/master/docs/Leetcode_Solutions/Python/080._remove_duplicates_from_sorted_array_ii.md)
+
+beats 99.62%
+
+```python
+class Solution(object):
+ def removeDuplicates(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ idx = 0
+ for num in nums:
+ if idx < 1 or num != nums[idx-1]:
+ nums[idx] = num
+ idx += 1
+ return idx
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/027._Remove_Element.md b/docs/Leetcode_Solutions/Python/027._Remove_Element.md
new file mode 100644
index 000000000..3603a5b3d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/027._Remove_Element.md
@@ -0,0 +1,25 @@
+### 27. Remove Element
+
+
+
+题目:
+
+
+
+难度:
+Easy
+
+瞬秒
+
+```python
+class Solution(object):
+ def removeElement(self, nums, val):
+ """
+ :type nums: List[int]
+ :type val: int
+ :rtype: int
+ """
+ while val in nums:
+ nums.remove(val)
+ return len(nums)
+```
diff --git a/docs/Leetcode_Solutions/Python/028._implement_strstr().md b/docs/Leetcode_Solutions/Python/028._implement_strstr().md
new file mode 100644
index 000000000..4428a8c55
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/028._implement_strstr().md
@@ -0,0 +1,74 @@
+# 28. Implement strStr()
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/implement-strstr/description/
+
+> 内容描述
+
+```
+
+Implement strStr().
+
+Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
+
+Example 1:
+
+Input: haystack = "hello", needle = "ll"
+Output: 2
+Example 2:
+
+Input: haystack = "aaaaa", needle = "bba"
+Output: -1
+Clarification:
+
+What should we return when needle is an empty string? This is a great question to ask during an interview.
+
+For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf().
+```
+
+## 解题方案
+
+> 思路 1
+
+一行解法如何?
+```python
+class Solution(object):
+ def strStr(self, haystack, needle):
+ """
+ :type haystack: str
+ :type needle: str
+ :rtype: int
+ """
+ return haystack.find(needle)
+```
+
+> 思路 2
+
+这个题目其实可以引来一大类,那就是关于string的算法,但是此处先用暴力算法来AC,然后再来细读/品味别的string相关算法吧。
+
+虽然是暴力算法,但是也不容易写对啊
+
+```python
+class Solution(object):
+ def strStr(self, haystack, needle):
+ """
+ :type haystack: str
+ :type needle: str
+ :rtype: int
+ """
+ if not needle or len(needle) == 0:
+ return 0
+ for i in range(len(haystack)-len(needle)+1):
+ if haystack[i] == needle[0]:
+ j = 1
+ while j < len(needle) and haystack[i+j] == needle[j]:
+ j += 1
+ if j == len(needle):
+ return i
+ return -1
+```
diff --git a/docs/leetcode/python/030._Substring_with_Concatenation_of_All_Words.md b/docs/Leetcode_Solutions/Python/030._Substring_with_Concatenation_of_All_Words.md
similarity index 98%
rename from docs/leetcode/python/030._Substring_with_Concatenation_of_All_Words.md
rename to docs/Leetcode_Solutions/Python/030._Substring_with_Concatenation_of_All_Words.md
index 24d5c0849..0dd9eea26 100644
--- a/docs/leetcode/python/030._Substring_with_Concatenation_of_All_Words.md
+++ b/docs/Leetcode_Solutions/Python/030._Substring_with_Concatenation_of_All_Words.md
@@ -1,7 +1,7 @@
### 30. Substring with Concatenation of All Words
题目:
-
+
难度 : Hard
diff --git a/docs/leetcode/python/031._next_permutation.md b/docs/Leetcode_Solutions/Python/031._next_permutation.md
similarity index 100%
rename from docs/leetcode/python/031._next_permutation.md
rename to docs/Leetcode_Solutions/Python/031._next_permutation.md
diff --git a/docs/leetcode/python/032._longest_valid_parentheses.md b/docs/Leetcode_Solutions/Python/032._longest_valid_parentheses.md
similarity index 97%
rename from docs/leetcode/python/032._longest_valid_parentheses.md
rename to docs/Leetcode_Solutions/Python/032._longest_valid_parentheses.md
index 68c6e238f..7042c1767 100644
--- a/docs/leetcode/python/032._longest_valid_parentheses.md
+++ b/docs/Leetcode_Solutions/Python/032._longest_valid_parentheses.md
@@ -7,7 +7,7 @@
> 原题连接
* https://leetcode.com/problems/longest-valid-parentheses
-* https://leetcode-cn.com/problems/longest-valid-parentheses
+* https://leetcode-cn.com/problems/longest-valid-parentheses/description
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/033._search_in_rotated_sorted_array.md b/docs/Leetcode_Solutions/Python/033._search_in_rotated_sorted_array.md
new file mode 100644
index 000000000..3bf70b36b
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/033._search_in_rotated_sorted_array.md
@@ -0,0 +1,80 @@
+# 33. Search in Rotated Sorted Array
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/search-in-rotated-sorted-array/description/
+
+> 内容描述
+
+```
+Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
+
+(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
+
+You are given a target value to search. If found in the array return its index, otherwise return -1.
+
+You may assume no duplicate exists in the array.
+
+Your algorithm's runtime complexity must be in the order of O(log n).
+
+Example 1:
+
+Input: nums = [4,5,6,7,0,1,2], target = 0
+Output: 4
+Example 2:
+
+Input: nums = [4,5,6,7,0,1,2], target = 3
+Output: -1
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+
+
+下面是rotated-array图解,
+
+
+
+
+所以直接用二分,O(lg(n))
+- 如果是mid,return mid
+- 如果mid在绿色线上,就对绿色线进行二分
+- 如果mid在红色线上,就对红色线进行二分
+- 都没找到,return -1
+
+beats 100%
+
+```python
+class Solution(object):
+ def search(self, nums, target):
+ """
+ :type nums: List[int]
+ :type target: int
+ :rtype: int
+ """
+ l, r = 0, len(nums) - 1
+ while l <= r:
+ mid = l + ((r - l) >> 2)
+ if nums[mid] == target:
+ return mid
+ if nums[mid] < nums[r]:
+ if nums[mid] < target <= nums[r]:
+ l = mid + 1
+ else:
+ r = mid - 1
+ else:
+ if nums[l] <= target < nums[mid]:
+ r = mid - 1
+ else:
+ l = mid + 1
+ return -1
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/034._Search for a Range.md b/docs/Leetcode_Solutions/Python/034._Search for a Range.md
new file mode 100644
index 000000000..dc54844fd
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/034._Search for a Range.md
@@ -0,0 +1,162 @@
+# 34. Find First and Last Position of Element in Sorted Array
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array/description/
+
+> 内容描述
+
+```
+Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value.
+
+Your algorithm's runtime complexity must be in the order of O(log n).
+
+If the target is not found in the array, return [-1, -1].
+
+Example 1:
+
+Input: nums = [5,7,7,8,8,10], target = 8
+Output: [3,4]
+Example 2:
+
+Input: nums = [5,7,7,8,8,10], target = 6
+Output: [-1,-1]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+二分法,先找```target```出现的左边界,判断是否有```target```后再判断右边界
+
+- 找左边界:二分,找到一个```index```
+ - 该```index```对应的值为```target```
+ - 并且它左边```index-1```对应的值不是```target```(如果```index```为```0```则不需要判断此条件)
+ - 如果存在```index```就将其```append```到```res```中
+- 判断此时```res```是否为空,如果为空,说明压根不存在```target```,返回```[-1, -1]```
+- 找右边界:二分,找到一个```index```(但是此时用于二分循环的```l```可以保持不变,```r```重置为```len(nums)-1```,这样程序可以更快一些)
+ - 该```index```对应的值为```target```
+ - 并且它右边```index+1```对应的值不是```target```(如果```index```为```len(nums)-1```则不需要判断此条件)
+ - 如果存在```index```就将其```append```到```res```中
+
+
+
+AC 代码
+
+```python
+class Solution(object):
+ def searchRange(self, nums, target):
+ """
+ :type nums: List[int]
+ :type target: int
+ :rtype: List[int]
+ """
+ if not nums or len(nums) == 0:
+ return [-1, -1]
+
+ res = []
+ l, r = 0, len(nums)-1
+ # search for left bound
+ while l <= r:
+ mid = l + ((r - l) >> 2)
+ if nums[mid] == target and (mid == 0 or nums[mid-1] != target):
+ res.append(mid)
+ break
+ if nums[mid] < target:
+ l = mid + 1
+ else:
+ r = mid - 1
+ if not res:
+ return [-1, -1]
+
+ # search for right bound
+ r = len(nums)-1
+ while l <= r:
+ mid = l + ((r - l) >> 2)
+ if nums[mid] == target and (mid == len(nums)-1 or nums[mid+1] != target):
+ res.append(mid)
+ break
+ if nums[mid] > target:
+ r = mid - 1
+ else:
+ l = mid + 1
+ # 这里直接返回res是因为前面如果判断左边界没返回的话就说明我们判断右边界的时候一定会append元素
+ return res
+```
+
+
+
+> 思路 2
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+跟第35题一样的思路,先找到第一个大于等于target的值的index,再找到最后一个小于等于target的值的index,然后做一些边界判断,就可以了。
+
+```python
+class Solution(object):
+ def searchRange(self, nums, target):
+ """
+ :type nums: List[int]
+ :type target: int
+ :rtype: List[int]
+ """
+ if not nums or len(nums) == 0:
+ return [-1, -1]
+ res = []
+ l, r = 0, len(nums) - 1
+ while l <= r:
+ mid = l + ((r-l) >> 1)
+ if nums[mid] < target:
+ l = mid + 1
+ else:
+ r = mid - 1
+ if l <= len(nums) - 1:
+ if nums[l] != target:
+ return [-1, -1]
+ else:
+ res.append(l)
+ else:
+ if nums[l-1] != target:
+ return [-1, -1]
+ else:
+ res.append(l-1)
+
+ r = len(nums) - 1
+ while l <= r:
+ mid = l + ((r-l) >> 1)
+ if nums[mid] > target:
+ r = mid - 1
+ else:
+ l = mid + 1
+ if r >= 0:
+ if nums[r] != target:
+ res.append(-1)
+ else:
+ res.append(r)
+ else:
+ if nums[r+1] != target:
+ res.append(-1)
+ else:
+ res.append(r+1)
+ return res
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/035._search_insert_position.md b/docs/Leetcode_Solutions/Python/035._search_insert_position.md
new file mode 100644
index 000000000..ef3ab0a02
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/035._search_insert_position.md
@@ -0,0 +1,82 @@
+# 35. Search Insert Position
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/search-insert-position/description/
+
+> 内容描述
+
+```
+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.
+
+Example 1:
+
+Input: [1,3,5,6], 5
+Output: 2
+Example 2:
+
+Input: [1,3,5,6], 2
+Output: 1
+Example 3:
+
+Input: [1,3,5,6], 7
+Output: 4
+Example 4:
+
+Input: [1,3,5,6], 0
+Output: 0
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+找到第一个比```target```大的值的```index```,如果没找到则返回```len(nums)```,但是代码中直接返回```i```值就行了
+
+
+```python
+class Solution(object):
+ def searchInsert(self, nums, target):
+ """
+ :type nums: List[int]
+ :type target: int
+ :rtype: int
+ """
+ i = 0
+ while nums[i] < target:
+ i += 1
+ if i == len(nums):
+ return i
+ return i
+```
+
+> 思路 2
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+```python
+class Solution(object):
+ def searchInsert(self, nums, target):
+ """
+ :type nums: List[int]
+ :type target: int
+ :rtype: int
+ """
+ l, r = 0, len(nums) - 1
+ while l <= r:
+ mid = l + ((r-l) >> 1)
+ if nums[mid] < target:
+ l = mid + 1
+ else:
+ r = mid - 1
+ return l
+```
+
+
+这题值得一提的随时将上面的移位变成一次移动2位,瞬间beats 100%,可能跟测试用例有关系吧,结果对应索引比较靠前
diff --git a/docs/Leetcode_Solutions/Python/038._Count_and_Say.md b/docs/Leetcode_Solutions/Python/038._Count_and_Say.md
new file mode 100644
index 000000000..3076d72e3
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/038._Count_and_Say.md
@@ -0,0 +1,107 @@
+# 38. Count and Say
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/count-and-say/description/
+
+> 内容描述
+
+```
+
+The count-and-say sequence is the sequence of integers with the first five terms as following:
+
+1. 1
+2. 11
+3. 21
+4. 1211
+5. 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 term of the count-and-say sequence.
+
+Note: Each term of the sequence of integers will be represented as a string.
+
+Example 1:
+
+Input: 1
+Output: "1"
+Example 2:
+
+Input: 4
+Output: "1211"
+```
+
+## 解题方案
+
+> 思路 1
+
+
+1. i代表字符下标,从0开始取值,也就是从第一个字符开始,因为要让i取到最后一个字符,并且后面还要进行i+1的操作,所以将原字符串随意加上一个‘*’字符防止溢出
+2. count代表此时已经连续相同的字符个数
+3. res代表最终输出的字符串
+
+- 只要i下标对应的字符等于下一个字符,则sum和i都加1,无限循环
+- 如果i下标对应的字符不等于下一个字符了,则res应该加上str(sum)和i下标对应的那个字符,并且i加1,sum复原回0
+
+```
+Examples of nth sequence
+
+ 1. 1
+ 2. 11
+ 3. 21
+ 4. 1211
+ 5. 111221
+ 6. 312211
+ 7. 13112221
+ 8. 1113213211
+ 9. 31131211131221
+ 10. 13211311123113112211
+
+```
+
+```python
+class Solution(object):
+ def countAndSay(self, n):
+ """
+ :type n: int
+ :rtype: str
+ """
+ if n == 1:
+ return '1'
+ s = self.countAndSay(n-1) + '*'
+ res, count = '', 1
+ for i in range(len(s)-1):
+ if s[i] == s[i+1]:
+ count += 1
+ else:
+ res += str(count) + str(s[i])
+ count = 1
+ return res
+```
+
+> 思路 2
+
+```python
+class Solution(object):
+ def countAndSay(self, n):
+ """
+ :type n: int
+ :rtype: str
+ """
+ res = '1'
+ for i in range(n-1):
+ res = ''.join([str(len(list(group))) + digit for digit, group in itertools.groupby(res)])
+ return res
+```
+
+
+详见[python进阶-ITERTOOLS模块小结](http://www.wklken.me/posts/2013/08/20/python-extra-itertools.html#itertoolsgroupbyiterable-key)
+
+
+
+
diff --git a/docs/leetcode/python/039._combination_sum.md b/docs/Leetcode_Solutions/Python/039._combination_sum.md
similarity index 100%
rename from docs/leetcode/python/039._combination_sum.md
rename to docs/Leetcode_Solutions/Python/039._combination_sum.md
diff --git a/docs/leetcode/python/040._combination_sum_ii.md b/docs/Leetcode_Solutions/Python/040._combination_sum_ii.md
similarity index 100%
rename from docs/leetcode/python/040._combination_sum_ii.md
rename to docs/Leetcode_Solutions/Python/040._combination_sum_ii.md
diff --git a/docs/Leetcode_Solutions/Python/041._First_Missing_Positive.md b/docs/Leetcode_Solutions/Python/041._First_Missing_Positive.md
new file mode 100644
index 000000000..70c764a31
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/041._First_Missing_Positive.md
@@ -0,0 +1,125 @@
+# 41. First Missing Positive
+**难度: 困难**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/first-missing-positive/description/
+
+> 内容描述
+
+```
+Given an unsorted integer array, find the smallest missing positive integer.
+
+Example 1:
+
+Input: [1,2,0]
+Output: 3
+Example 2:
+
+Input: [3,4,-1,1]
+Output: 2
+Example 3:
+
+Input: [7,8,9,11,12]
+Output: 1
+Note:
+
+Your algorithm should run in O(n) time and uses constant extra space.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+题目要求O(n)时间和O(1)空间,所以我们知道先排序再循环找是不行的
+
+因此我们可以这样,第一轮循环,找1(因为1是最小的正整数),如果1在,立马原地开始继续找2,以此类推,一轮循环结束后,我们记录下当前正在找的值i,
+并开始第二轮循环,但是这次从i开始找了,然后以此类推,直到有一次循环我们要找的值没有变过,则代表它没出现过,返回它即可
+
+可以看一个例子
+```
+[3,4,-1,1]
+
+第一轮循环:[1,1,1,2]
+第二轮循环:[2,2,2,2]
+
+然后我们发现第二轮循环2没有变过了,所以2就是我们要的结果
+```
+
+```python
+class Solution(object):
+ def firstMissingPositive(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ old_missing, missing = 0, 1
+ while old_missing != missing:
+ old_missing = missing
+ for i in range(len(nums)):
+ if nums[i] == missing:
+ missing += 1
+ return missing
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+如果不限制空间的话,我们用一个dict就可以解决, 时间是O(N)
+
+
+```python
+class Solution(object):
+ def firstMissingPositive(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ if not nums:
+ return 1
+ lookup = {}
+ for i in nums:
+ lookup[i] = 1
+ for i in range(1, len(nums)+2):
+ if i not in lookup:
+ return i
+```
+
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+参考[eeetcoders@gmail.com](https://leetcode.com/problems/first-missing-positive/discuss/158842/Python-O(1)-Space-O(N)-Time)
+先把所有的数字都放到该放的地方去,最后来一个for循环看哪个位置上没有对应的数字,就返回那个数字
+
+- 1st sweep through the array and swap the number to its appropriate index (i.e 3 should go to index 3 - 1 = 2)
+ - Ignore the useless numbers such as duplicates, negatives or 0 and place them at the end of the array
+ - How to do this is similar to https://leetcode.com/problems/move-zeroes/description/
+- 2nd sweep check if the number is at the appropriate index (i.e at index 2 nums[i] should be 3)
+ - if not return i + 1
+- Edge case when all the numbers are in the appropriate indices then return n + 1
+
+```python
+class Solution(object):
+ def firstMissingPositive(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ if not nums or len(nums) == 0:
+ return 1
+
+ for i in range(len(nums)):
+ # swap nums[i] to i - 1 then use nums[i - 1] as new target to swap
+ while nums[i] > 0 and nums[i] <= len(nums) and nums[nums[i]-1] != nums[i]:
+ nums[nums[i]-1], nums[i] = nums[i], nums[nums[i]-1]
+ for i in range(len(nums)):
+ if nums[i] != i + 1:
+ return i + 1
+ return len(nums) + 1
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/042._trapping_rain_water.md b/docs/Leetcode_Solutions/Python/042._trapping_rain_water.md
new file mode 100644
index 000000000..ac356bbe9
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/042._trapping_rain_water.md
@@ -0,0 +1,56 @@
+# 42. Trapping Rain Water
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/trapping-rain-water/description/
+
+> 内容描述
+
+```
+Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
+```
+
+
+
+The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!
+```
+Example:
+
+Input: [0,1,0,2,1,0,1,3,2,1,2,1]
+Output: 6
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+题目有几个特性可用,bar width = 1,然后第一个和最后一个是不能trap water,其次中间的部分能trap多少水是看`左右高度差较低的那个 - 本身的高度`
+
+The basic idea is that we set two pointers ```l``` and ```r``` to the left and right end of ```height```. Then we get the minimum height (```min_height```) of these pointers (similar to Container with Most Water due to the Leaking Bucket Effect) since the level of the water cannot be higher than it. Then we move the two pointers towards the center. If the coming level is less than ```min_height```, then it will hold some water. Fill the water until we meet some “barrier” (with height larger than ```min_height```) and update ```l``` and ```r``` to repeat this process in a new interval.
+
+AC代码:
+
+beats 100%
+```python
+class Solution(object):
+ def trap(self, height):
+ """
+ :type height: List[int]
+ :rtype: int
+ """
+ l, r, water, min_height = 0, len(height) - 1, 0, 0
+ while l < r:
+ min_height = min(height[l], height[r])
+ while l < r and height[l] <= min_height:
+ water += min_height - height[l]
+ l += 1
+ while l < r and height[r] <= min_height:
+ water += min_height - height[r]
+ r -= 1
+ return water
+```
diff --git a/docs/Leetcode_Solutions/Python/043._multiply_strings.md b/docs/Leetcode_Solutions/Python/043._multiply_strings.md
new file mode 100644
index 000000000..cede77572
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/043._multiply_strings.md
@@ -0,0 +1,103 @@
+# 43. Multiply Strings 字符串相乘
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/multiply-strings/>
+* https://leetcode-cn.com/problems/multiply-strings/description/
+
+> 内容描述
+
+```
+Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string.
+
+Example 1:
+
+Input: num1 = "2", num2 = "3"
+Output: "6"
+Example 2:
+
+Input: num1 = "123", num2 = "456"
+Output: "56088"
+Note:
+
+The length of both num1 and num2 is < 110.
+Both num1 and num2 contain only digits 0-9.
+Both num1 and num2 do not contain any leading zero, except the number 0 itself.
+You must not use any built-in BigInteger library or convert the inputs to integer directly.
+```
+
+## 解题方案
+
+
+> 思路 1
+
+
+直接一位一位的搞,最后转string, 但是考虑到这样kennel最后str2int(num1) * str2int(num2)是一个极大的数字可能会导致溢出,所以有了后面的思路2
+
+```python
+class Solution(object):
+ def multiply(self, num1, num2):
+ """
+ :type num1: str
+ :type num2: str
+ :rtype: str
+ """
+ def str2int(num):
+ res = 0
+ for i in range(len(num)-1, -1, -1):
+ res += int(num[i]) * pow(10, len(num)-1-i)
+ return res
+ return str(str2int(num1) * str2int(num2))
+```
+
+> 思路 2
+
+
+参考了别人的思路:
+
+1. m位的数字乘以n位的数字的结果最大为m+n位:
+ * 999*99 < 1000*100 = 100000,最多为3+2 = 5位数。
+2. 先将字符串逆序便于从最低位开始计算。
+
+
+```python
+class Solution(object):
+ def multiply(self, num1, num2):
+ """
+ :type num1: str
+ :type num2: str
+ :rtype: str
+ """
+ lookup = {"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9} # 节省查找时间,避免无休止使用ord函数来得到数字
+ if num1 == '0' or num2 == '0':
+ return '0'
+ num1, num2 = num1[::-1], num2[::-1]
+
+ tmp_res = [0 for i in range(len(num1)+len(num2))]
+ for i in range(len(num1)):
+ for j in range(len(num2)):
+ tmp_res[i+j] += lookup[num1[i]] * lookup[num2[j]]
+
+ res = [0 for i in range(len(num1)+len(num2))]
+ for i in range(len(num1)+len(num2)):
+ res[i] = tmp_res[i] % 10
+ if i < len(num1)+len(num2)-1:
+ tmp_res[i+1] += tmp_res[i]/10
+ return ''.join(str(i) for i in res[::-1]).lstrip('0') # 去掉最终结果头部可能存在的‘0’
+```
+
+觉得这样写才是最容易理解的,看一个具体的🌰:
+```
+input: num1, num2 = '91', '91'
+tmp_res = [1,18,81,0]
+res = [1,8,2,8]
+
+最终返回 "8281"
+
+要注意最终返回头部可能会有‘0’,所以我们用lstrip去除一下
+```
+
diff --git a/docs/Leetcode_Solutions/Python/044._wildcard_matching.md b/docs/Leetcode_Solutions/Python/044._wildcard_matching.md
new file mode 100644
index 000000000..582e04822
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/044._wildcard_matching.md
@@ -0,0 +1,165 @@
+# 44. Wildcard Matching
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/wildcard-matching/description/
+
+> 内容描述
+
+```
+Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for '?' and '*'.
+
+'?' Matches any single character.
+'*' Matches any sequence of characters (including the empty sequence).
+The matching should cover the entire input string (not partial).
+
+Note:
+
+s could be empty and contains only lowercase letters a-z.
+p could be empty and contains only lowercase letters a-z, and characters like ? or *.
+Example 1:
+
+Input:
+s = "aa"
+p = "a"
+Output: false
+Explanation: "a" does not match the entire string "aa".
+Example 2:
+
+Input:
+s = "aa"
+p = "*"
+Output: true
+Explanation: '*' matches any sequence.
+Example 3:
+
+Input:
+s = "cb"
+p = "?a"
+Output: false
+Explanation: '?' matches 'c', but the second letter is 'a', which does not match 'b'.
+Example 4:
+
+Input:
+s = "adceb"
+p = "*a*b"
+Output: true
+Explanation: The first '*' matches the empty sequence, while the second '*' matches the substring "dce".
+Example 5:
+
+Input:
+s = "acdcb"
+p = "a*c?b"
+Output: false
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(len(s) * len(p))******- 空间复杂度: O(len(s) * len(p))******
+
+
+
+dp, 看完下面的代码就知道思路了
+
+beats 61.92%
+
+```python
+class Solution(object):
+ def isMatch(self, s, p):
+ """
+ :type s: str
+ :type p: str
+ :rtype: bool
+ """
+ t = [[False] * (len(s) + 1) for i in range(len(p) + 1)]
+ t[0][0] = True
+ for i in range(1, len(p) + 1):
+ t[i][0] = t[i-1][0] and p[i-1] == '*'
+ for i in range(1, len(p)+1):
+ for j in range(1, len(s) + 1):
+ if p[i-1] != '*':
+ t[i][j] = (p[i-1] == s[j-1] or p[i-1] == '?') and t[i-1][j-1]
+ else:
+ t[i][j] = t[i][j-1] or t[i-1][j]
+ return t[-1][-1]
+```
+
+
+> 思路 2
+******- 时间复杂度: O(len(s) * len(p))******- 空间复杂度: O(1)******
+
+双指针
+
+```
+Worst case Should be O(NM)
+think that s ="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" to match p ="*aaaaaab"( '*' in the beginning)
+It's easy to see 'match' is moving step by step to almost the end, each time we move 'match', we will go through the whole tail of p (after '*') until we found out 'b' is not a match. Thus it's O(NM)
+```
+
+beats 94.80%
+
+```python
+class Solution(object):
+ def isMatch(self, s, p):
+ """
+ :type s: str
+ :type p: str
+ :rtype: bool
+ """
+ ps, pp, match, star_idx = 0, 0, 0, -1
+ while ps < len(s):
+ if pp < len(p) and (p[pp] == '?' or s[ps] == p[pp]): # advancing both pointers
+ ps += 1
+ pp += 1
+ elif pp < len(p) and p[pp] == '*': # found '*', only advancing pattern pointer
+ star_idx = pp
+ match = ps
+ pp += 1
+ elif star_idx != -1: # last pattern pointer was *, advancing string pointer
+ pp = star_idx + 1
+ match += 1
+ ps = match
+ else: # current pattern pointer is not star, last patter pointer was not *, characters do not match
+ return False
+ while pp < len(p) and p[pp] == '*': # check for remaining characters in pattern
+ pp += 1
+ return pp == len(p)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/045._Jump_Game_II.md b/docs/Leetcode_Solutions/Python/045._Jump_Game_II.md
similarity index 100%
rename from docs/leetcode/python/045._Jump_Game_II.md
rename to docs/Leetcode_Solutions/Python/045._Jump_Game_II.md
diff --git a/docs/Leetcode_Solutions/Python/046._permutations.md b/docs/Leetcode_Solutions/Python/046._permutations.md
new file mode 100644
index 000000000..083376946
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/046._permutations.md
@@ -0,0 +1,60 @@
+# 46. Permutations
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/permutations/description/
+
+> 内容描述
+
+```
+Given a collection of distinct integers, return all possible permutations.
+
+Example:
+
+Input: [1,2,3]
+Output:
+[
+ [1,2,3],
+ [1,3,2],
+ [2,1,3],
+ [2,3,1],
+ [3,1,2],
+ [3,2,1]
+]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N!)******- 空间复杂度: O(N)******
+
+
+每次取一个作为prefix, 剩下的继续做permutation,然后连接起来加入res中
+
+beats 87.18%
+
+```python
+class Solution(object):
+ def permute(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: List[List[int]]
+ """
+ if len(nums) == 0:
+ return []
+ if len(nums) == 1:
+ return [nums]
+ res = []
+ for i in range(len(nums)):
+ prefix = nums[i]
+ rest = nums[:i] + nums[i+1:]
+ for j in self.permute(rest):
+ res.append([prefix]+j)
+ return res
+```
+
+
diff --git a/docs/leetcode/python/047._permutations_ii.md b/docs/Leetcode_Solutions/Python/047._permutations_ii.md
similarity index 100%
rename from docs/leetcode/python/047._permutations_ii.md
rename to docs/Leetcode_Solutions/Python/047._permutations_ii.md
diff --git a/docs/leetcode/python/048._rotate_image.md b/docs/Leetcode_Solutions/Python/048._rotate_image.md
similarity index 100%
rename from docs/leetcode/python/048._rotate_image.md
rename to docs/Leetcode_Solutions/Python/048._rotate_image.md
diff --git a/docs/Leetcode_Solutions/Python/049._group_anagrams.md b/docs/Leetcode_Solutions/Python/049._group_anagrams.md
new file mode 100644
index 000000000..02fd269c1
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/049._group_anagrams.md
@@ -0,0 +1,52 @@
+# 49. Group Anagrams
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/group-anagrams/description/
+
+> 内容描述
+
+```
+Given an array of strings, group anagrams together.
+
+Example:
+
+Input: ["eat", "tea", "tan", "ate", "nat", "bat"],
+Output:
+[
+ ["ate","eat","tea"],
+ ["nat","tan"],
+ ["bat"]
+]
+Note:
+
+All inputs will be in lowercase.
+The order of your output does not matter.
+```
+
+## 解题方案
+
+> 思路 1
+
+每一个字符串都先排个序看看是不是一样,这样更好判断
+
+```python
+class Solution(object):
+ def groupAnagrams(self, strs):
+ """
+ :type strs: List[str]
+ :rtype: List[List[str]]
+ """
+ mapx = {}
+ for i in strs:
+ tmp = ''.join(sorted(list(i)))
+ if tmp in mapx:
+ mapx[tmp].append(i)
+ else:
+ mapx[tmp] = [i]
+ return mapx.values()
+```
diff --git a/docs/Leetcode_Solutions/Python/050._pow(x,_n).md b/docs/Leetcode_Solutions/Python/050._pow(x,_n).md
new file mode 100644
index 000000000..4854a5942
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/050._pow(x,_n).md
@@ -0,0 +1,82 @@
+# 50. Pow(x, n)
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/powx-n/description/
+
+> 内容描述
+
+```
+Implement pow(x, n), which calculates x raised to the power n (xn).
+
+Example 1:
+
+Input: 2.00000, 10
+Output: 1024.00000
+Example 2:
+
+Input: 2.10000, 3
+Output: 9.26100
+Example 3:
+
+Input: 2.00000, -2
+Output: 0.25000
+Explanation: 2-2 = 1/22 = 1/4 = 0.25
+Note:
+
+-100.0 < x < 100.0
+n is a 32-bit signed integer, within the range [−231, 231 − 1]
+```
+
+## 解题方案
+
+> 思路 1
+
+Recursive, beats 100%
+
+```python
+class Solution(object):
+ def myPow(self, x, n):
+ """
+ :type x: float
+ :type n: int
+ :rtype: float
+ """
+ if n == 0:
+ return 1
+ if n < 0:
+ return 1 / self.myPow(x, -n)
+ if n & 1: # n 为 奇数
+ return x * self.myPow(x*x, n>>1)
+ else:
+ return self.myPow(x*x, n>>1)
+```
+
+> 思路 2
+
+iterative
+
+
+```python
+class Solution(object):
+ def myPow(self, x, n):
+ """
+ :type x: float
+ :type n: int
+ :rtype: float
+ """
+ if n < 0:
+ x = 1 / x
+ n = -n
+ res = 1
+ while n:
+ if n & 1:
+ res *= x
+ x *= x
+ n >>= 1
+ return res
+```
diff --git a/docs/Leetcode_Solutions/Python/051._n-queens.md b/docs/Leetcode_Solutions/Python/051._n-queens.md
new file mode 100644
index 000000000..d4c8325ba
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/051._n-queens.md
@@ -0,0 +1,74 @@
+# 51. N-Queens
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/n-queens/description/
+
+> 内容描述
+
+```
+The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens attack each other.
+```
+
+
+
+```
+Given an integer n, return all distinct solutions to the n-queens puzzle.
+
+Each solution contains a distinct board configuration of the n-queens' placement, where 'Q' and '.' both indicate a queen and an empty space respectively.
+
+Example:
+
+Input: 4
+Output: [
+ [".Q..", // Solution 1
+ "...Q",
+ "Q...",
+ "..Q."],
+
+ ["..Q.", // Solution 2
+ "Q...",
+ "...Q",
+ ".Q.."]
+]
+Explanation: There exist two distinct solutions to the 4-queens puzzle as shown above.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当n = 1或n ≥ 4时问题有解[1]。
+
+对于任意(x,y),如果要让新的点和它不能处于同一条横行、纵行或斜线上,则新点(p,q)必须要满足p+q != x+y 和p-q!= x-y, 前者针对左下右上斜线,后者针对左上右下斜线,两者同时都保证了不在同一条横行和纵行上。
+
+代码中变量的含义:
+- cols_lst: 每一行皇后的column位置组成的列表
+- cur_row:目前正在判断的row的index
+- xy_diff:所有x-y组成的列表
+- xy_sum:所有x+y组成的列表
+
+```python
+class Solution(object):
+ def solveNQueens(self, n):
+ """
+ :type n: int
+ :rtype: List[List[str]]
+ """
+ def dfs(cols_lst, xy_diff, xy_sum):
+ cur_row = len(cols_lst)
+ if cur_row == n:
+ ress.append(cols_lst)
+ for col in range(n):
+ if col not in cols_lst and cur_row - col not in xy_diff and cur_row + col not in xy_sum:
+ dfs(cols_lst+[col], xy_diff+[cur_row-col], xy_sum+[cur_row+col])
+ ress = []
+ dfs([], [], [])
+ return [['.' * i + 'Q' + '.' * (n-i-1) for i in res] for res in ress]
+
+```
diff --git a/docs/leetcode/python/052._n-queens_ii.md b/docs/Leetcode_Solutions/Python/052._n-queens_ii.md
similarity index 100%
rename from docs/leetcode/python/052._n-queens_ii.md
rename to docs/Leetcode_Solutions/Python/052._n-queens_ii.md
diff --git a/docs/Leetcode_Solutions/Python/053._maximum_subarray.md b/docs/Leetcode_Solutions/Python/053._maximum_subarray.md
new file mode 100644
index 000000000..48f12b384
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/053._maximum_subarray.md
@@ -0,0 +1,163 @@
+# 53. Maximum Subarray
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/maximum-subarray/description/
+
+> 内容描述
+
+```
+
+Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
+
+Example:
+
+Input: [-2,1,-3,4,-1,2,1,-5,4],
+Output: 6
+Explanation: [4,-1,2,1] has the largest sum = 6.
+Follow up:
+
+If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+从i开始,计算i到n,存比较大的sum,会超时
+
+```
+class Solution(object):
+ def maxSubArray(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ n = len(nums)
+ m = float('-inf')
+ for i in range(n):
+ s = 0
+ for j in range(i, n):
+ s = s + nums[j]
+ m = max(m, s)
+ return m
+```
+
+
+> 思路 2
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+参见clrs 第71页,用divide and conquer,有伪码
+
+最大的subarray sum有三个可能,左半段或者右半段,或者跨越左右半段,
+
+速度比较慢,AC代码,复杂度O(NlogN)
+
+```
+class Solution(object):
+ def maxSubArray(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ def find_max_crossing_subarray(nums, low, mid, high):
+ left_sum = float('-inf')
+ sum = 0
+ for i in xrange(mid,low-1,-1):
+ sum = sum + nums[i]
+ if sum > left_sum:
+ left_sum = sum
+
+ right_sum = float('-inf')
+ sum = 0
+ for j in range(mid+1,high+1):
+ sum = sum + nums[j]
+ if sum > right_sum:
+ right_sum = sum
+
+ return left_sum + right_sum
+
+ def find_max_subarray(nums,low,high):
+ if low == high:
+ return nums[low]
+ else:
+ mid = (low + high) / 2
+ left_sum = find_max_subarray(nums, low, mid)
+ right_sum = find_max_subarray(nums,mid+1,high)
+ cross_sum = find_max_crossing_subarray(nums,low,mid,high)
+ # print left_sum, right_sum, cross_sum
+ # print mid, low, high
+ return max(left_sum, right_sum, cross_sum)
+
+ return find_max_subarray(nums, 0, len(nums)-1)
+```
+
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+* 动态规划(只关注:当然值 和 当前值+过去的状态,是变好还是变坏,一定是回看容易理解)
+* ms(i) = max(ms[i-1]+ a[i],a[i])
+* 到i处的最大值两个可能,一个是加上a[i], 另一个从a[i]起头,重新开始。可以AC
+
+```python
+class Solution(object):
+ def maxSubArray(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ n = len(nums)
+ maxSum = [nums[0] for i in range(n)]
+ for i in range(1, n):
+ maxSum[i] = max(maxSum[i - 1] + nums[i], nums[i])
+ return max(maxSum)
+```
+
+
+
+> 思路 4
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+Kadane’s Algorithm wikipedia可以查到,然后一般的是负的可以还回0,这里需要稍作修改,参考
+
+
+
+
+```
+start:
+ max_so_far = a[0]
+ max_ending_here = a[0]
+
+loop i= 1 to n
+ (i) max_end_here = Max(arrA[i], max_end_here+a[i]);
+ (ii) max_so_far = Max(max_so_far,max_end_here);
+
+return max_so_far
+
+```
+
+AC代码:
+
+```python
+class Solution(object):
+ def maxSubArray(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ max_sum, max_end = nums[0], nums[0]
+ for i in range(1, len(nums)):
+ max_end = max(max_end + nums[i], nums[i])
+ max_sum = max(max_sum, max_end)
+ return max_sum
+```
+
+
+
diff --git a/docs/leetcode/python/054._spiral_matrix.md b/docs/Leetcode_Solutions/Python/054._spiral_matrix.md
similarity index 100%
rename from docs/leetcode/python/054._spiral_matrix.md
rename to docs/Leetcode_Solutions/Python/054._spiral_matrix.md
diff --git a/docs/leetcode/python/055._jump_game.md b/docs/Leetcode_Solutions/Python/055._jump_game.md
similarity index 100%
rename from docs/leetcode/python/055._jump_game.md
rename to docs/Leetcode_Solutions/Python/055._jump_game.md
diff --git a/docs/Leetcode_Solutions/Python/056._Merge_Intervals.md b/docs/Leetcode_Solutions/Python/056._Merge_Intervals.md
new file mode 100644
index 000000000..5b3d9cba1
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/056._Merge_Intervals.md
@@ -0,0 +1,53 @@
+# 56. Merge Intervals
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/merge-intervals/description/
+
+> 内容描述
+
+```
+Given a collection of intervals, merge all overlapping intervals.
+
+Example 1:
+
+Input: [[1,3],[2,6],[8,10],[15,18]]
+Output: [[1,6],[8,10],[15,18]]
+Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
+Example 2:
+
+Input: [[1,4],[4,5]]
+Output: [[1,5]]
+Explanation: Intervals [1,4] and [4,5] are considerred overlapping.
+```
+
+## 解题方案
+
+> 思路 1
+
+Just go through the intervals sorted by start coordinate and
+either combine the current interval with the previous one if they overlap, or add it to the output by itself if they don’t.
+
+beats 95.48%
+
+```python
+class Solution(object):
+ def merge(self, intervals):
+ """
+ :type intervals: List[Interval]
+ :rtype: List[Interval]
+ """
+ res = []
+ for i in sorted(intervals, key = lambda x: x.start):
+ if res and i.start <= res[-1].end:
+ res[-1].end = max(res[-1].end, i.end)
+ else:
+ res.append(i)
+ return res
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/057._Insert_Interval.md b/docs/Leetcode_Solutions/Python/057._Insert_Interval.md
new file mode 100644
index 000000000..dbc46f0d0
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/057._Insert_Interval.md
@@ -0,0 +1,141 @@
+# 57. Insert Interval
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/insert-interval/description/
+
+> 内容描述
+
+```
+Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
+
+You may assume that the intervals were initially sorted according to their start times.
+
+Example 1:
+
+Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
+Output: [[1,5],[6,9]]
+Example 2:
+
+Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
+Output: [[1,2],[3,10],[12,16]]
+Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+
+
+因为原intervals是有序且non-overlapping的,所以打算直接用56题的代码AC,beats 73.53%
+
+```python
+class Solution(object):
+ def insert(self, intervals, newInterval):
+ """
+ :type intervals: List[Interval]
+ :type newInterval: Interval
+ :rtype: List[Interval]
+ """
+ if not intervals or len(intervals) == 0:
+ return [newInterval]
+ res = []
+ for interval in sorted(intervals+[newInterval], key = lambda x: (x.start, x.end)):
+ if res and res[-1].end >= interval.start:
+ res[-1].end = max(res[-1].end, interval.end)
+ else:
+ res.append(interval)
+ return res
+```
+
+
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+考虑到之前的题目条件中的intervals本身就是有序这个特征,觉得排序没有必要,只要先插入,再看看是否需要merge即可
+
+这样时间复杂度减到了O(N), beats 97.49%
+
+```python
+class Solution(object):
+ def insert(self, intervals, newInterval):
+ """
+ :type intervals: List[Interval]
+ :type newInterval: Interval
+ :rtype: List[Interval]
+ """
+ if not intervals or len(intervals) == 0:
+ return [newInterval]
+ idx = -1
+ for i in range(len(intervals)):
+ if intervals[i].start > newInterval.start:
+ idx = i
+ break
+ if idx != -1:
+ intervals.insert(i, newInterval)
+ else:
+ intervals.append(newInterval)
+ res = []
+ for interval in intervals:
+ if res and res[-1].end >= interval.start:
+ res[-1].end = max(res[-1].end, interval.end)
+ else:
+ res.append(interval)
+ return res
+```
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+寒神的二分法, beats 97.49%
+
+```python
+from bisect import bisect_left, bisect
+class Solution(object):
+ def insert(self, intervals, newInterval):
+ """
+ :type intervals: List[Interval]
+ :type newInterval: Interval
+ :rtype: List[Interval]
+ """
+ inter = [v for i in intervals for v in (i.start, i.end)]
+ start, end = newInterval.start, newInterval.end
+ i, j = bisect_left(inter, start), bisect(inter, end)
+ if i & 1:
+ i -= 1
+ start = inter[i]
+ if j & 1:
+ end = inter[j]
+ j += 1
+ inter[i:j] = [start, end]
+ return [Interval(s, e) for s, e in zip(inter[::2], inter[1::2])]
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/058._length_of_last_word.md b/docs/Leetcode_Solutions/Python/058._length_of_last_word.md
similarity index 100%
rename from docs/leetcode/python/058._length_of_last_word.md
rename to docs/Leetcode_Solutions/Python/058._length_of_last_word.md
diff --git a/docs/leetcode/python/059._spiral_matrix_ii.md b/docs/Leetcode_Solutions/Python/059._spiral_matrix_ii.md
similarity index 100%
rename from docs/leetcode/python/059._spiral_matrix_ii.md
rename to docs/Leetcode_Solutions/Python/059._spiral_matrix_ii.md
diff --git a/docs/Leetcode_Solutions/Python/060._permutation_sequence.md b/docs/Leetcode_Solutions/Python/060._permutation_sequence.md
new file mode 100644
index 000000000..d67e9dfcf
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/060._permutation_sequence.md
@@ -0,0 +1,193 @@
+# 60. Permutation Sequence
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/permutation-sequence/description/
+
+> 内容描述
+
+```
+The set [1,2,3,...,n] contains a total of n! unique permutations.
+
+By listing and labeling all of the permutations in order, we get the following sequence for n = 3:
+
+"123"
+"132"
+"213"
+"231"
+"312"
+"321"
+Given n and k, return the kth permutation sequence.
+
+Note:
+
+Given n will be between 1 and 9 inclusive.
+Given k will be between 1 and n! inclusive.
+Example 1:
+
+Input: n = 3, k = 3
+Output: "213"
+Example 2:
+
+Input: n = 4, k = 9
+Output: "2314"
+```
+
+## 解题方案
+
+> 思路 1
+
+
+当然是暴力直接算出所有的排列然后取第k个,但是会超时
+
+```
+class Solution(object):
+ def getPermutation(self, n, k):
+ """
+ :type n: int
+ :type k: int
+ :rtype: str
+ """
+ s = ''.join([str(i) for i in range(1, n+1)])
+ print(s)
+ def permunation(s):
+ if len(s) == 0:
+ return
+ if len(s) == 1:
+ return [s]
+ res = []
+ for i in range(len(s)):
+ x = s[i]
+ xs = s[:i] + s[i+1:]
+ for j in permunation(xs):
+ res.append(x+j)
+ return res
+ return permunation(s)[k-1]
+```
+
+> 思路 2
+
+参考大神[tso](https://leetcode.com/problems/permutation-sequence/discuss/22507/%22Explain-like-I'm-five%22-Java-Solution-in-O(n))的思路
+
+```
+I'm sure somewhere can be simplified so it'd be nice if anyone can let me know. The pattern was that:
+
+say n = 4, you have {1, 2, 3, 4}
+
+If you were to list out all the permutations you have
+
+1 + (permutations of 2, 3, 4)
+
+2 + (permutations of 1, 3, 4)
+
+3 + (permutations of 1, 2, 4)
+
+4 + (permutations of 1, 2, 3)
+
+
+We know how to calculate the number of permutations of n numbers... n! So each of those with permutations of 3 numbers means there are 6 possible permutations. Meaning there would be a total of 24 permutations in this particular one. So if you were to look for the (k = 14) 14th permutation, it would be in the
+
+3 + (permutations of 1, 2, 4) subset.
+
+To programmatically get that, you take k = 13 (subtract 1 because of things always starting at 0) and divide that by the 6 we got from the factorial, which would give you the index of the number you want. In the array {1, 2, 3, 4}, k/(n-1)! = 13/(4-1)! = 13/3! = 13/6 = 2. The array {1, 2, 3, 4} has a value of 3 at index 2. So the first number is a 3.
+
+Then the problem repeats with less numbers.
+
+The permutations of {1, 2, 4} would be:
+
+1 + (permutations of 2, 4)
+
+2 + (permutations of 1, 4)
+
+4 + (permutations of 1, 2)
+
+But our k is no longer the 14th, because in the previous step, we've already eliminated the 12 4-number permutations starting with 1 and 2. So you subtract 12 from k.. which gives you 1. Programmatically that would be...
+
+k = k - (index from previous) * (n-1)! = k - 2*(n-1)! = 13 - 2*(3)! = 1
+
+In this second step, permutations of 2 numbers has only 2 possibilities, meaning each of the three permutations listed above a has two possibilities, giving a total of 6. We're looking for the first one, so that would be in the 1 + (permutations of 2, 4) subset.
+
+Meaning: index to get number from is k / (n - 2)! = 1 / (4-2)! = 1 / 2! = 0.. from {1, 2, 4}, index 0 is 1
+
+
+so the numbers we have so far is 3, 1... and then repeating without explanations.
+
+
+{2, 4}
+
+k = k - (index from pervious) * (n-2)! = k - 0 * (n - 2)! = 1 - 0 = 1;
+
+third number's index = k / (n - 3)! = 1 / (4-3)! = 1/ 1! = 1... from {2, 4}, index 1 has 4
+
+Third number is 4
+
+
+{2}
+
+k = k - (index from pervious) * (n - 3)! = k - 1 * (4 - 3)! = 1 - 1 = 0;
+
+third number's index = k / (n - 4)! = 0 / (4-4)! = 0/ 1 = 0... from {2}, index 0 has 2
+
+Fourth number is 2
+
+
+Giving us 3142. If you manually list out the permutations using DFS method, it would be 3142. Done! It really was all about pattern finding.
+```
+
+```python
+class Solution(object):
+ def getPermutation(self, n, k):
+ """
+ :type n: int
+ :type k: int
+ :rtype: str
+ """
+ res = ''
+
+ factorial = [1] * (n+1)
+ # factorial[] = [1, 1, 2, 6, 24, ... n!]
+ for i in range(1, n+1):
+ factorial[i] = factorial[i-1] * i
+
+ # create a list of numbers to get indices
+ nums = [i for i in range(1, n+1)]
+ # because we start from index 0
+ k -= 1
+
+ for i in range(1, n+1):
+ # this is the idx of first num each time we will get
+ idx = k / factorial[n-i]
+ res += str(nums[idx])
+ # delete this num, since we have got it
+ nums.pop(idx)
+ # update k
+ k -= idx * factorial[n-i]
+ return res
+```
+或者空间复杂度更低一点
+
+```python
+class Solution(object):
+ def getPermutation(self, n, k):
+ """
+ :type n: int
+ :type k: int
+ :rtype: str
+ """
+ seq, k, fact = '', k-1, math.factorial(n-1)
+ perm = [i for i in range(1, n+1)]
+ for i in range(n)[::-1]:
+ curr = perm[k/fact]
+ seq += str(curr)
+ perm.remove(curr)
+ if i > 0:
+ k %= fact
+ fact /= i
+ return seq
+```
+
+
diff --git a/docs/leetcode/python/061._rotate_list.md b/docs/Leetcode_Solutions/Python/061._rotate_list.md
similarity index 100%
rename from docs/leetcode/python/061._rotate_list.md
rename to docs/Leetcode_Solutions/Python/061._rotate_list.md
diff --git a/docs/leetcode/python/062._unique_paths.md b/docs/Leetcode_Solutions/Python/062._unique_paths.md
similarity index 94%
rename from docs/leetcode/python/062._unique_paths.md
rename to docs/Leetcode_Solutions/Python/062._unique_paths.md
index 75a7edc52..759ada816 100644
--- a/docs/leetcode/python/062._unique_paths.md
+++ b/docs/Leetcode_Solutions/Python/062._unique_paths.md
@@ -7,7 +7,7 @@
> 原题连接
* https://leetcode.com/problems/unique-paths
-* https://leetcode-cn.com/problems/unique-paths
+* https://leetcode-cn.com/problems/unique-paths/description
> 内容描述
@@ -19,7 +19,7 @@
问总共有多少条不同的路径?
```
-
+
```
例如,上图是一个7 x 3 的网格。有多少可能的路径?
diff --git a/docs/Leetcode_Solutions/Python/063.unique_paths_ii.md b/docs/Leetcode_Solutions/Python/063.unique_paths_ii.md
new file mode 100644
index 000000000..6c16b47bd
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/063.unique_paths_ii.md
@@ -0,0 +1,84 @@
+ ###63.Unique Paths II
+
+题目:
+
+
+
+
+tag : DP
+
+难度 : Medium
+
+
+
+
+
+```
+BASE CASE( i = 0 , j = 0):
+//第一排和第一列,如果没有obstacle, 则走法为1, 一旦有了obstacle,则之后的格子走法都为0
+
+非BASE CASE :
+//一旦有obstacle,则dp为0
+dp(i, j) = dp(i,j-1) + dp(i-1,j)
+
+```
+
+Python代码
+
+```
+class Solution(object):
+ def uniquePathsWithObstacles(self, obstacleGrid):
+ """
+ :type obstacleGrid: List[List[int]]
+ :rtype: int
+ """
+ row = len(obstacleGrid)
+ col = len(obstacleGrid[0])
+ dp = [[0 for i in range(col)] for j in range(row)]
+
+ dp[0][0] = int(obstacleGrid[0][0] == 0)
+
+ #first row
+ for j in range(1,col):
+ if obstacleGrid[0][j] == 1:
+ dp[0][j] = 0
+ else:
+ dp[0][j] = dp[0][j-1]
+ #first col
+ for i in range(1,row):
+ if obstacleGrid[i][0] == 1:
+ dp[i][0] = 0
+ else:
+ dp[i][0] = dp[i-1][0]
+
+ for i in range(1,row):
+ for j in range(1,col):
+ if obstacleGrid[i][j] == 1:
+ dp[i][j] = 0
+ else:
+ dp[i][j] = dp[i-1][j] + dp[i][j-1]
+ return dp[row-1][col-1]
+
+```
+
+犯了一个错,简直觉得不可思议。一开始初始化dp用的代码是
+
+```
+dp = [[0] * col] * row
+```
+
+问题在此:
+
+
+```
+>>> x = [[]] * 3
+>>> x[1].append(0)
+>>> x
+[[0], [0], [0]]
+```
+
+这样初始化是做了三个一样的object.
+
+The problem is that they're all the same exact list in memory. When you use the [x]*n syntax, what you get is a list of n many x objects, but they're all references to the same object. They're not distinct instances, rather, just n references to the same instance.
+
+参见stackoverflow :
diff --git a/docs/leetcode/python/064._minimum_path_sum.md b/docs/Leetcode_Solutions/Python/064._minimum_path_sum.md
similarity index 95%
rename from docs/leetcode/python/064._minimum_path_sum.md
rename to docs/Leetcode_Solutions/Python/064._minimum_path_sum.md
index 8e801f567..fe89255e5 100644
--- a/docs/leetcode/python/064._minimum_path_sum.md
+++ b/docs/Leetcode_Solutions/Python/064._minimum_path_sum.md
@@ -7,7 +7,7 @@
> 原题连接
* https://leetcode.com/problems/minimum-path-sum
-* https://leetcode-cn.com/problems/minimum-path-sum
+* https://leetcode-cn.com/problems/minimum-path-sum/description
> 内容描述
diff --git a/docs/leetcode/python/066._plus_one.md b/docs/Leetcode_Solutions/Python/066._plus_one.md
similarity index 100%
rename from docs/leetcode/python/066._plus_one.md
rename to docs/Leetcode_Solutions/Python/066._plus_one.md
diff --git a/docs/Leetcode_Solutions/Python/067._add_binary.md b/docs/Leetcode_Solutions/Python/067._add_binary.md
new file mode 100644
index 000000000..811c04d17
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/067._add_binary.md
@@ -0,0 +1,53 @@
+# 67. Add Binary
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/add-binary/description/
+
+> 内容描述
+
+```
+Given two binary strings, return their sum (also a binary string).
+
+The input strings are both non-empty and contains only characters 1 or 0.
+
+Example 1:
+
+Input: a = "11", b = "1"
+Output: "100"
+Example 2:
+
+Input: a = "1010", b = "1011"
+Output: "10101"
+```
+
+## 解题方案
+
+> 思路 1
+
+几种case:
+
+- a or b 为空,最简单
+- 唯一的问题是如果有进位的处理,进位的处理就是先让其中的一个数和```‘1’```做```addBinary```处理 ,然后再用```addBinary```
+
+```python
+class Solution(object):
+ def addBinary(self, a, b):
+ """
+ :type a: str
+ :type b: str
+ :rtype: str
+ """
+ if a == '' or b == '':
+ return a + b
+ if a[-1] == '0' and b[-1] == '0':
+ return self.addBinary(a[:-1], b[:-1]) + '0'
+ elif a[-1] == '1' and b[-1] == '1':
+ return self.addBinary(a[:-1], self.addBinary(b[:-1], '1')) + '0'
+ else:
+ return self.addBinary(a[:-1], b[:-1]) + '1'
+```
diff --git a/docs/Leetcode_Solutions/Python/069._sqrt(x).md b/docs/Leetcode_Solutions/Python/069._sqrt(x).md
new file mode 100644
index 000000000..f01be5105
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/069._sqrt(x).md
@@ -0,0 +1,126 @@
+# 69. Sqrt(x)
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/sqrtx/description/
+
+> 内容描述
+
+```
+Implement int sqrt(int x).
+
+Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
+
+Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.
+
+Example 1:
+
+Input: 4
+Output: 2
+Example 2:
+
+Input: 8
+Output: 2
+Explanation: The square root of 8 is 2.82842..., and since
+ the decimal part is truncated, 2 is returned.
+```
+
+## 解题方案
+
+> 思路 1
+
+一看,觉得很容易,一写,超时:
+
+```
+class Solution(object):
+ def mySqrt(self, x):
+ """
+ :type x: int
+ :rtype: int
+ """
+ i = 0
+ while i * i <= x :
+ if i * i == x:
+ return i
+ elif i * i < x and (i+1) * (i+1) > x:
+ return i
+ i += 1
+```
+
+> 思路 2
+
+看一眼tag, binary search,难道从x/2之类的开始搜起来?
+
+莫名其妙过了的代码:
+
+```python
+class Solution(object):
+ def mySqrt(self, x):
+ """
+ :type x: int
+ :rtype: int
+ """
+ if x == 0:
+ return 0
+ if x == 1:
+ return 1
+ l, r = 0, x - 1
+ while l <= r:
+ mid = l + ((r-l) >> 1)
+ if mid * mid <= x and (mid+1) * (mid+1) > x:
+ return mid
+ elif mid * mid > x:
+ r = mid - 1 # 这里也可以 r = mid
+ else:
+ l = mid + 1
+```
+> 思路 3
+
+跟思路 2 一样,就是return时机不一样
+
+```python
+class Solution(object):
+ def mySqrt(self, x):
+ """
+ :type x: int
+ :rtype: int
+ """
+ if x == 1:
+ return 1
+ if x == 0:
+ return 0
+ l, r = 0, x-1
+ while l <= r:
+ mid = l + ((r - l) >> 2)
+ if (mid * mid - x == 0):
+ return mid
+ elif (mid * mid - x > 0):
+ r = mid - 1
+ else:
+ l = mid + 1
+ return r
+```
+> 思路 4
+
+话说还想到求sqrt有个🐂的牛顿法?
+
+[牛顿法 wiki](https://zh.wikipedia.org/wiki/牛顿法)
+
+
+
+```python
+class Solution(object):
+ def mySqrt(self, x):
+ """
+ :type x: int
+ :rtype: int
+ """
+ res = 1.0
+ while abs(res * res - x) > 0.1:
+ res = (res + x / res) / 2
+ return int(res)
+```
diff --git a/docs/Leetcode_Solutions/Python/070._Climbing_Stairs.md b/docs/Leetcode_Solutions/Python/070._Climbing_Stairs.md
new file mode 100644
index 000000000..872a1dd77
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/070._Climbing_Stairs.md
@@ -0,0 +1,131 @@
+# 70. Climbing Stairs
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/climbing-stairs/description/
+
+> 内容描述
+
+```
+
+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?
+
+Note: Given n will be a positive integer.
+
+Example 1:
+
+Input: 2
+Output: 2
+Explanation: There are two ways to climb to the top.
+1. 1 step + 1 step
+2. 2 steps
+Example 2:
+
+Input: 3
+Output: 3
+Explanation: There are three ways to climb to the top.
+1. 1 step + 1 step + 1 step
+2. 1 step + 2 steps
+3. 2 steps + 1 step
+```
+
+## 解题方案
+
+> 思路 1
+
+Fibonacci 的DP版本
+
+对于DP的不同理解造成不同的写法
+Memoization will usually add on your time-complexity to your space-complexity (e.g. with tabulation you have more liberty to throw away calculations, like using tabulation with Fib lets you use O(1) space, but memoization with Fib uses O(N) stack space).
+详看
+
+[Dynamic programming and memoization: bottom-up vs top-down approaches](https://awjin.me/algos-js/dp/tab-memo.html)
+
+[Tabulation vs Memoizatation](http://www.geeksforgeeks.org/tabulation-vs-memoizatation/)
+- top-down(memorize)
+
+```
+def memorize_fib(n): # n为第几个Fibonacci数
+ memo = {1:1, 2:1}
+ if n in memo:
+ return memo[n]
+ else:
+ memo[n] = memorize_fib(n-1) + memorize_fib(n-2)
+ return memo[n]
+
+print(memorize_fib(4)) # 输出3
+```
+
+
+
+- bottom up(tabulation)
+
+```
+def tabulation_fib(n): # n为第几个Fibonacci数
+ fib = [1, 1, 2]
+ if n < 4:
+ return fib[n-1]
+ for k in range(3, n+1):
+ fib[2] = fib[0] + fib[1]
+ fib[0], fib[1] = fib[1], fib[2]
+ return fib[2]
+
+print(tabulation_fib(4)) # 输出3
+```
+
+
+这里memo用dict,用array也一样。当然用bottom up还有一点,可以只存每次最后两个数,可以save space.,这样就只用到constant space.
+
+AC 代码(这里采用bottom up思想)
+
+```python
+class Solution(object):
+ def climbStairs(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ fib = [1, 2, 3]
+ if n < 4:
+ return fib[n-1]
+ for k in range(3, n+1):
+ fib[2] = fib[0] + fib[1] # 永远只存3个元素,save space
+ fib[0], fib[1] = fib[1], fib[2]
+ return fib[2]
+```
+- Complexity Analysis
+
+ - Time complexity : O(n)
+
+ - Space complexity : O(1). Constant space is used.
+
+> 思路 2
+
+另外还有一个公式法:
+
+
+
+由于这里面相当于```standard Fibonacci```函数向前进了一步,排列为1,2,3,5而非原本的1,1,2,3,所以代码中使用```n+1```
+```python
+class Solution(object):
+ def climbStairs(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ import math
+ sqrt5 = math.sqrt(5)
+ fibn = pow((1 + sqrt5) / 2, n+1) - pow((1 - sqrt5) / 2, n+1)
+ return int(float(fibn/sqrt5))
+```
+- Complexity Analysis
+
+ - Time complexity : O(lg(n)). pow method takes log(n) time.
+
+ - Space complexity : O(1). Constant space is used.
diff --git a/docs/Leetcode_Solutions/Python/071._simplify_path.md b/docs/Leetcode_Solutions/Python/071._simplify_path.md
new file mode 100644
index 000000000..a1fdfaacf
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/071._simplify_path.md
@@ -0,0 +1,62 @@
+# 71. Simplify Path
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/simplify-path/description/
+
+> 内容描述
+
+```
+
+Given an absolute path for a file (Unix-style), simplify it.
+
+For example,
+path = "/home/", => "/home"
+path = "/a/./b/../../c/", => "/c"
+path = "/a/../../b/../c//.//", => "/c"
+path = "/a//b////c/d//././/..", => "/a/b/c"
+
+In a UNIX-style file system, a period ('.') refers to the current directory, so it can be ignored in a simplified path. Additionally, a double period ("..") moves up a directory, so it cancels out whatever the last directory was. For more information, look here: https://en.wikipedia.org/wiki/Path_(computing)#Unix_style
+
+Corner Cases:
+
+Did you consider the case where path = "/../"?
+In this case, you should return "/".
+Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/".
+In this case, you should ignore redundant slashes and return "/home/foo".
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+非常简单的模拟题,利用一个栈来储存当前的路径。用 "/" 将输入的全路径分割成多个部分,对于每一个部分循环处理:如果为空或者 "." 则忽略,如果是 ".." ,则出栈顶部元素(如果栈为空则忽略),其他情况直接压入栈即可。
+
+beats 100%
+
+```python
+class Solution(object):
+ def simplifyPath(self, path):
+ """
+ :type path: str
+ :rtype: str
+ """
+ stack = []
+ for part in path.split("/"):
+ if part and part != ".": # 如果为空或者 "." 则忽略
+ if part == "..":
+ if stack:
+ stack.pop()
+ else:
+ stack.append(part)
+ if not stack:
+ return "/"
+ else:
+ return "/" + "/".join(stack)
+```
diff --git a/docs/Leetcode_Solutions/Python/072._edit_distance.md b/docs/Leetcode_Solutions/Python/072._edit_distance.md
new file mode 100644
index 000000000..75291042c
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/072._edit_distance.md
@@ -0,0 +1,131 @@
+# 72. Edit Distance
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/edit-distance/description/
+
+> 内容描述
+
+```
+Given two words word1 and word2, find the minimum number of operations required to convert word1 to word2.
+
+You have the following 3 operations permitted on a word:
+
+Insert a character
+Delete a character
+Replace a character
+Example 1:
+
+Input: word1 = "horse", word2 = "ros"
+Output: 3
+Explanation:
+horse -> rorse (replace 'h' with 'r')
+rorse -> rose (remove 'r')
+rose -> ros (remove 'e')
+Example 2:
+
+Input: word1 = "intention", word2 = "execution"
+Output: 5
+Explanation:
+intention -> inention (remove 't')
+inention -> enention (replace 'i' with 'e')
+enention -> exention (replace 'n' with 'x')
+exention -> exection (replace 'n' with 'c')
+exection -> execution (insert 'u')
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(len(word1)*len(word2))******- 空间复杂度: O(len(word1)*len(word2))******
+
+可以做的操作:
+
+- insert
+- delete
+- replace
+
+动归典型,原来也是有wikipedia page的算法
+
+
+
+
+
+
+看wikipedia 这解释
+
+```
+ / max(i,j) if min(i,j) = 0
+
+ / dp[i-1][j] + 1 word1[i]不在word2[0...j]中,所以删除
+ dp[i][j] - min -- dp[i][j-1] + 1 insertion
+ \ dp[i-1][j-1] + 1/0 word[i]与word[j]是否相等
+```
+
+上面的就不用解释了,min分别对应:删除、插入、以及替代(1/0取决 word1[i] == word2[j] ),反正也是tabular类型,画表来解决问题。
+
+简单说,就是这样:
+
+1.delete:dp[i-1][j] + 1 —— 保留了从 word1[0:i-1] 转变到 word2[0:j] 的最优操作次数,因为我们的 word1 的 0~i-1 已经能够转变到 word2 了,
+所以我们就直接把 word1 中的最后一个字符删除掉就行了。所以就需要额外进行一个 删除 操作。
+
+2.insert:dp[i][j-1] + 1 —— 保留了从 word1[0:i] 转变到 word2[0:j-1] 的最优操作次数,因为我们的 word1 的 0~i 只能转变到 word2 的倒数第二位,所以我们就直接在 word1 的末尾添加一个与 word2 的最后一个字符相同的字符就可以了。所以就需要额外进行一个 插入 操作。
+
+3.replace:dp[i-1][j-1] + 1 —— 保留了从 word1[0:i-1] 转变到 word2[0:j-1] 的最优操作次数,因为我们的 word1 的 0~i-1 只能转变到 word2 的倒数第二位,而 word1 的最后一位与 word2 的最后一位是不同的,所以现在的情况只需要额外的一个 替换 操作即可。
+
+无论我们选取上面 3 中操作的哪种操作,我们选其中最小的值就可以了。
+
+参考链接:http://www.cnblogs.com/pandora/archive/2009/12/20/levenshtein_distance.html
+
+***要始终明确一点,```dp[i][j]```的含义是使得```word1的前i字符子串```与```word2的前j字符子串```相等所需要的操作数,这也是为什么我们需要在初始化```dp矩阵```时需要行列数均加上```1```***
+
+
+
+对应的例子表格图
+
+```
+ k i t t e n
+ 0 1 2 3 4 5 6
+s 1 1 2 3 4 5 6
+i 2 2 1 2 3 4 5
+t 3 3 2 1 2 3 4
+t 4 4 3 2 1 2 3
+i 5 5 4 3 2 2 3
+n 6 6 5 4 3 3 2
+g 7 7 6 5 4 4 3
+```
+
+
+AC代码
+
+```python
+class Solution(object):
+ def minDistance(self, word1, word2):
+ """
+ :type word1: str
+ :type word2: str
+ :rtype: int
+ """
+ if len(word1) == 0 or len(word2) == 0: # corner cases
+ return max(len(word1), len(word2))
+ # 这里第一行第一列初始值一定要为i+j,因为当另一个单词为空的时候很明显至少需要i或者j次edit
+ dp = [[i+j for j in range(len(word2)+1)] for i in range(len(word1)+1)]
+ for i in range(1, len(word1)+1):
+ for j in range(1, len(word2)+1):
+ tmp_dist = 0 if word1[i-1] == word2[j-1] else 1
+ dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1, dp[i-1][j-1]+tmp_dist)
+ return dp[-1][-1]
+```
+
+或者你愿意麻烦,可以这样初始化dp矩阵
+
+```
+dp = [[0 for j in range(len(word2)+1)] for i in range(len(word1)+1)]
+dp[0] = [i for i in range(len(word2)+1)]
+for i in range(len(word1)+1):
+ dp[i][0] = i
+```
diff --git a/docs/leetcode/python/073._Set_Matrix_Zeroes.md b/docs/Leetcode_Solutions/Python/073. Set Matrix Zeroes.md
similarity index 100%
rename from docs/leetcode/python/073._Set_Matrix_Zeroes.md
rename to docs/Leetcode_Solutions/Python/073. Set Matrix Zeroes.md
diff --git a/docs/leetcode/python/074._search_a_2d_matrix.md b/docs/Leetcode_Solutions/Python/074._search_a_2d_matrix.md
similarity index 100%
rename from docs/leetcode/python/074._search_a_2d_matrix.md
rename to docs/Leetcode_Solutions/Python/074._search_a_2d_matrix.md
diff --git a/docs/leetcode/python/075._sort_colors.md b/docs/Leetcode_Solutions/Python/075._sort_colors.md
similarity index 98%
rename from docs/leetcode/python/075._sort_colors.md
rename to docs/Leetcode_Solutions/Python/075._sort_colors.md
index 7605e298d..8e6a628c6 100644
--- a/docs/leetcode/python/075._sort_colors.md
+++ b/docs/Leetcode_Solutions/Python/075._sort_colors.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/sort-colors
+* https://leetcode.com/problems/sort-colors/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/076._Minimum_Window_Substring.md b/docs/Leetcode_Solutions/Python/076._Minimum_Window_Substring.md
new file mode 100644
index 000000000..a31e09202
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/076._Minimum_Window_Substring.md
@@ -0,0 +1,77 @@
+# 76. Minimum Window Substring
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-window-substring/description/
+
+> 内容描述
+
+```
+Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
+
+Example:
+
+Input: S = "ADOBECODEBANC", T = "ABC"
+Output: "BANC"
+Note:
+
+If there is no such window in S that covers all characters in T, return the empty string "".
+If there is such window, you are guaranteed that there will always be only one unique minimum window in S.
+```
+
+## 解题方案
+
+> 思路 1
+
+
+[模板大法好](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/Summarization/slide_windows_template.md),
+
+
+- 首先搞几个corner case
+- 开始步入正题,我们脑子里面必须要有一个window的概念,只要这个window的end小于len(s),就一直搞下去
+- 记录一下t中字符和其频率,然后随着end的变大不停更新这个maps,即出现一个字符,如果该字符在maps里面,我们就对应的自减一下这个字符在maps中的频率
+- 用一个counter记录这个maps里面频率不为0的字符个数,即key个数,当counter为0的时候我们就知道t中所以的字符都在我们的window里面了
+- 这个时候,我们就可以开始自增begin了,然后只要仍然可以保持counter为0(即所有字符都还在window里面),我们就一直移动begin以减小window的size
+- 当最后while end < len(s)循环出来的时候,我们判断一下我们的window的length是不是变化了(最开始设置了inf最大值),如果变化了说明我们找到了符合要求的window,否则没有
+
+
+
+```python
+class Solution(object):
+ def minWindow(self, s, t):
+ """
+ :type s: str
+ :type t: str
+ :rtype: str
+ """
+ if len(t) > len(s):
+ return ''
+ if s == '' or t == '':
+ return ''
+ maps = collections.Counter(t)
+ counter = len(maps.keys())
+ begin, end, head, length = 0, 0, 0, float('inf')
+ while end < len(s):
+ if s[end] in maps:
+ maps[s[end]] -= 1
+ if maps[s[end]] == 0:
+ counter -= 1
+ end += 1
+ while counter == 0:
+ if s[begin] in maps:
+ maps[s[begin]] += 1
+ if maps[s[begin]] > 0:
+ counter += 1
+ if end - begin < length:
+ length = end - begin
+ head = begin
+ begin += 1
+ if length == float('inf'):
+ return ''
+ return s[head:head+length]
+```
+
diff --git a/docs/leetcode/python/077._combinations.md b/docs/Leetcode_Solutions/Python/077._combinations.md
similarity index 100%
rename from docs/leetcode/python/077._combinations.md
rename to docs/Leetcode_Solutions/Python/077._combinations.md
diff --git a/docs/leetcode/python/078._Subsets.md b/docs/Leetcode_Solutions/Python/078._Subsets.md
similarity index 85%
rename from docs/leetcode/python/078._Subsets.md
rename to docs/Leetcode_Solutions/Python/078._Subsets.md
index 307e6a8dc..6fc756dbe 100644
--- a/docs/leetcode/python/078._Subsets.md
+++ b/docs/Leetcode_Solutions/Python/078._Subsets.md
@@ -6,7 +6,7 @@
> 原题连接
-* https://leetcode.com/problems/subsets
+* https://leetcode.com/problems/subsets/description/
> 内容描述
@@ -65,16 +65,15 @@ class Solution(object):
:type nums: List[int]
:rtype: List[List[int]]
"""
- nums.sort()
res = []
- def search(cur_lst, idx):
+ def search(tmp_res, idx):
if idx == len(nums):
- res.append(cur_lst)
- return
- search(cur_lst + [nums[idx]], idx + 1)
- search(cur_lst, idx + 1)
-
+ res.append(tmp_res)
+ else:
+ search(tmp_res+[nums[idx]], idx+1)
+ search(tmp_res, idx+1)
+
search([], 0)
return res
```
@@ -91,7 +90,6 @@ class Solution(object):
:type nums: List[int]
:rtype: List[List[int]]
"""
- nums.sort()
res = []
def dfs(depth, start, lst):
res.append(lst)
diff --git a/docs/Leetcode_Solutions/Python/079._word_search.md b/docs/Leetcode_Solutions/Python/079._word_search.md
new file mode 100644
index 000000000..1b88d3c7b
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/079._word_search.md
@@ -0,0 +1,77 @@
+# 79. Word Search
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/word-search/description/
+
+> 内容描述
+
+```
+Given a 2D board and a word, find if the word exists in the grid.
+
+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.
+
+Example:
+
+board =
+[
+ ['A','B','C','E'],
+ ['S','F','C','S'],
+ ['A','D','E','E']
+]
+
+Given word = "ABCCED", return true.
+Given word = "SEE", return true.
+Given word = "ABCB", return false.
+```
+
+## 解题方案
+
+> 思路 1
+
+其实这个题和number of islands类似,是backtracking基本功的考查,但是基本功非常有待提高|||
+
+比较核心的是dfs函数,然后这个函数有取巧的写法:如果outside of boundary就return False
+
+loop, 如果碰到跟word开头的字母一样,把这个扔进去loop,可以考查这个char在这个board的上下左右是否可以选择,补课使用则重置used, 然后return
+
+也还是之前摘录的,backtrack写法关键: 选择 (Options),限制 (Restraints),结束条件 (Termination)。
+
+
+```python
+class Solution(object):
+ def exist(self, board, word):
+ """
+ :type board: List[List[str]]
+ :type word: str
+ :rtype: bool
+ """
+ if not board:
+ return False
+
+ row = len(board)
+ col = len(board[0]) if row else 0
+
+ if row == 0:
+ return False
+ if row != 0 and col == 0:
+ return False
+ if not word or word == '':
+ return True
+
+ def dfs(i, j, idx):
+ if i < 0 or j < 0 or i > row-1 or j > col-1 or board[i][j] != word[idx]:
+ return False
+ if idx == len(word) - 1:
+ return True
+ board[i][j] = '*' # mark as visited
+ res = dfs(i+1, j, idx+1) or dfs(i, j+1, idx+1) or dfs(i-1, j, idx+1) or dfs(i, j-1, idx+1)
+ board[i][j] = word[idx] # backtrack
+ return res
+
+ return any(dfs(i, j, 0) for i in range(row) for j in range(col))
+```
diff --git a/docs/Leetcode_Solutions/Python/080._remove_duplicates_from_sorted_array_ii.md b/docs/Leetcode_Solutions/Python/080._remove_duplicates_from_sorted_array_ii.md
new file mode 100644
index 000000000..298b79def
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/080._remove_duplicates_from_sorted_array_ii.md
@@ -0,0 +1,89 @@
+# 80. Remove Duplicates from Sorted Array II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii
+
+> 内容描述
+
+```
+Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice and return the new length.
+
+Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
+
+Example 1:
+
+Given nums = [1,1,1,2,2,3],
+
+Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3 respectively.
+
+It doesn't matter what you leave beyond the returned length.
+
+Example 2:
+
+Given nums = [0,0,1,1,1,1,2,3,3],
+
+Your function should return length = 7, with the first seven elements of nums being modified to 0, 0, 1, 1, 2, 3 and 3 respectively.
+
+It doesn't matter what values are set beyond the returned length.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+通过Remove Duplicates from Sorted Array I的解法进行修改。如果从当前位置开始,连续三位值相等就pop掉当前值。
+
+beats 91.64%
+
+```python
+class Solution(object):
+ def removeDuplicates(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ if not nums:
+ return 0
+ if len(nums) <= 2:
+ return len(nums)
+ idx = 0
+ while idx < len(nums) - 2:
+ if nums[idx] == nums[idx+1] == nums[idx+2]:
+ nums.pop(idx)
+ else:
+ idx += 1
+ return len(nums)
+```
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+我想看程序更能解释这个算法,参考[智慧巅峰](https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/discuss/27976/3-6-easy-lines-C++-Java-Python-Ruby)
+
+```
+Just go through the numbers and include those in the result that haven't been included twice already.
+```
+
+beats 91.64%
+
+```python
+class Solution(object):
+ def removeDuplicates(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ idx = 0
+ for num in nums:
+ if idx < 2 or num > nums[idx-2]:
+ nums[idx] = num
+ idx += 1
+ return idx
+```
diff --git a/docs/Leetcode_Solutions/Python/082._remove_duplicates_from_sorted_list_ii.md b/docs/Leetcode_Solutions/Python/082._remove_duplicates_from_sorted_list_ii.md
new file mode 100644
index 000000000..8b1e91094
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/082._remove_duplicates_from_sorted_list_ii.md
@@ -0,0 +1,136 @@
+# 82. Remove Duplicates from Sorted List II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/description/
+
+> 内容描述
+
+```
+Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
+
+Example 1:
+
+Input: 1->2->3->3->4->4->5
+Output: 1->2->5
+Example 2:
+
+Input: 1->1->1->2->3
+Output: 2->3
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+先用83题的思想得到所有unique的list,期间遇到重复的存在字典里面一下
+
+然后遍历上面的unique的list,遇到在字典里面的node就跳过
+
+
+beats 72.95%
+
+```python
+class Solution(object):
+ def deleteDuplicates(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ head_cp = head
+ duplicate = {}
+ while head:
+ while head.next and head.next.val == head.val:
+ duplicate[head.val] = 1
+ head.next = head.next.next # skip duplicated node
+ head = head.next # not duplicate of current node, move to next node
+
+ dummy = prev = ListNode(None)
+ prev.next = head
+ while head_cp:
+ if head_cp.val not in duplicate:
+ prev.next = head_cp
+ prev = prev.next
+ head_cp = head_cp.next
+ prev.next = None # 一定要记得最后要加上这一步,因为最后的head_cp可能是一个重复数字
+ return dummy.next
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+更省时间的方法是用一个prev 和 cur 指针,这样loop一次即可解决问题。
+
+beats 100%
+
+```python
+class Solution(object):
+ def deleteDuplicates(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ dummy = cur = prev = ListNode(None)
+ while head:
+ while head and ((head.val == prev.val) or (head.next and head.val == head.next.val)):
+ prev = head
+ head = head.next
+ cur.next = head
+ cur = cur.next
+ prev = head
+ return dummy.next
+```
+
+但是这里的第二个prev = head有点难以理解
+
+我个人觉得更喜欢下面这个版本
+
+```python
+class Solution(object):
+ def deleteDuplicates(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ dummy = prev = cur = ListNode(None)
+ while head:
+ while head and ((head.val == prev.val) or (head.next and head.next.val == head.val)):
+ prev = head
+ head = head.next
+ cur.next = head
+ cur = cur.next
+ if head:
+ head = head.next
+
+ return dummy.next
+```
+
+
+
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+递归, beats 100%
+
+```python
+class Solution(object):
+ def deleteDuplicates(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ if not head:
+ return None
+ nxt, is_head_dup = head.next, False
+ while nxt and nxt.val == head.val:
+ nxt, is_head_dup = nxt.next, True
+ head.next = self.deleteDuplicates(nxt)
+ return head.next if is_head_dup else head
+```
diff --git a/docs/Leetcode_Solutions/Python/083._remove_duplicates_from_sorted_list.md b/docs/Leetcode_Solutions/Python/083._remove_duplicates_from_sorted_list.md
new file mode 100644
index 000000000..d7a521b39
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/083._remove_duplicates_from_sorted_list.md
@@ -0,0 +1,69 @@
+# 83. Remove Duplicates from Sorted List
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/remove-duplicates-from-sorted-list/description/
+
+> 内容描述
+
+```
+Given a sorted linked list, delete all duplicates such that each element appear only once.
+
+Example 1:
+
+Input: 1->1->2
+Output: 1->2
+Example 2:
+
+Input: 1->1->2->3->3
+Output: 1->2->3
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+先写了一个复杂一点的版本,beats 76.63%
+
+```python
+class Solution(object):
+ def deleteDuplicates(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ if not head:
+ return head
+ dummy = prev = ListNode(None)
+ while head:
+ if head.val == prev.val:
+ if not head.next:
+ prev.next = None
+ else:
+ prev.next = head
+ prev = prev.next
+ head = head.next
+
+ return dummy.next
+```
+更简单的dummy 大法,beats 100%
+
+```python
+class Solution(object):
+ def deleteDuplicates(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ dummy = head
+ while head:
+ while head.next and head.next.val == head.val:
+ head.next = head.next.next # skip duplicated node
+ head = head.next # not duplicate of current node, move to next node
+ return dummy
+```
diff --git a/docs/Leetcode_Solutions/Python/084._Largest_Rectangle_in_Histogram.md b/docs/Leetcode_Solutions/Python/084._Largest_Rectangle_in_Histogram.md
new file mode 100644
index 000000000..90e1b2e24
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/084._Largest_Rectangle_in_Histogram.md
@@ -0,0 +1,104 @@
+# 84. Largest Rectangle in Histogram
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/largest-rectangle-in-histogram/description/
+
+> 内容描述
+
+```
+Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.
+```
+
+
+Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].
+
+
+
+
+
+The largest rectangle is shown in the shaded area, which has area = 10 unit.
+
+
+```
+Example:
+
+Input: [2,1,5,6,2,3]
+Output: 10
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+参考大神[learnjava](https://leetcode.com/problems/largest-rectangle-in-histogram/discuss/158050/same-pattern-for-problem-84-496-503-and-739)的解法
+
+```
+All these problems share the same pattern: how to find the next greater/smaller element in an array.
+
+Problem 84:
+For bar i in the heights array, if we can find the first smaller bar with index l on the left
+and the first smaller bar with index r on the right, then the current max area with h(i)
+as the height is h(i)*(r-l-1). So we just need to compare all these current max areas.
+To find l for each bar, we can use one stack (see problem 496, 503 and 739);
+similarly we can use another stack for r.
+```
+
+beats 69.90%
+
+```python
+class Solution(object):
+ def largestRectangleArea(self, heights):
+ """
+ :type heights: List[int]
+ :rtype: int
+ """
+ left_stack, right_stack = [], []
+ left_indexes, right_indexes = [-1] * len(heights), [len(heights)] * len(heights)
+
+ for i in range(len(heights)):
+ while left_stack and heights[i] < heights[left_stack[-1]]:
+ right_indexes[left_stack.pop()] = i
+ left_stack.append(i)
+
+ for i in range(len(heights)-1, -1, -1):
+ while right_stack and heights[i] < heights[right_stack[-1]]:
+ left_indexes[right_stack.pop()] = i
+ right_stack.append(i)
+
+ res = 0
+ for i in range(len(heights)):
+ res = max(res, heights[i]*(right_indexes[i]-left_indexes[i]-1))
+ return res
+```
+
+> 思路 2
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+刚才是two-pass,现在优化成one-pass,beats 95%
+
+```python
+class Solution(object):
+ def largestRectangleArea(self, heights):
+ """
+ :type heights: List[int]
+ :rtype: int
+ """
+ heights.append(0)
+ area, stack = 0, [-1]
+
+ for idx, height in enumerate(heights):
+ while height < heights[stack[-1]]:
+ h = heights[stack.pop()]
+ w = idx - stack[-1] - 1
+ area = max(w*h, area)
+ stack.append(idx)
+
+ return area
+```
diff --git a/docs/Leetcode_Solutions/Python/085._Maximal_Rectangle.md b/docs/Leetcode_Solutions/Python/085._Maximal_Rectangle.md
new file mode 100644
index 000000000..681eccdb2
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/085._Maximal_Rectangle.md
@@ -0,0 +1,106 @@
+# 85. Maximal Rectangle
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/maximal-rectangle/description/
+
+> 内容描述
+
+```
+Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.
+
+Example:
+
+Input:
+[
+ ["1","0","1","0","0"],
+ ["1","0","1","1","1"],
+ ["1","1","1","1","1"],
+ ["1","0","0","1","0"]
+]
+Output: 6
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+参考大神[sikp](https://leetcode.com/problems/maximal-rectangle/discuss/122456/Easiest-solution-build-on-top-of-leetcode84)的解法
+
+首先我们可以看看 leetcode 第84题,然后你就会发现,这道题可以直接使用84题的解法来做。
+
+我们可以从matrix的第一行开始往下进行,然后每次都做出一个heights列表,找出当前的最大area,最终找到最后一行,可以得到最终的最大area。
+
+伪代码可以这样写:
+
+```
+class Solution(object):
+ def maximalRectangle(self, matrix):
+ """
+ :type matrix: List[List[str]]
+ :rtype: int
+ """
+ if not matrix or not matrix[0]:
+ return 0
+ # for each cell with value=1, we look upward (north), the number of continuous '1' is the height of cell
+ heights = [0] * len(matrix[0])
+ res, cur_max_area = -1
+ for i in range(len(matrix)):
+ for j in range(len(matrix[0])):
+ if matrix[i][j] == 0:
+ heights[j] = 0
+ else:
+ heights[j] += 1
+ cur_max_area = yourLeetCode84Funtion(heights)
+ res = max(cur_max_area, res)
+ return res
+```
+
+
+
+
+最终代码就是:
+
+```python
+class Solution(object):
+ def maximalRectangle(self, matrix):
+ """
+ :type matrix: List[List[str]]
+ :rtype: int
+ """
+ if not matrix or not matrix[0]:
+ return 0
+ heights = [0] * len(matrix[0])
+ area = 0
+ for row in matrix:
+ for col_num, item in enumerate(row):
+ heights[col_num] = heights[col_num] + 1 if item == '1' else 0
+ area = max(area, self.largestRectangleArea(heights))
+ return area
+
+
+ def largestRectangleArea(self, heights):
+ left_stack, right_stack = [], []
+ left_indexes, right_indexes = [-1] * len(heights), [len(heights)] * len(heights)
+
+ for i in range(len(heights)):
+ while left_stack and heights[i] < heights[left_stack[-1]]:
+ right_indexes[left_stack.pop()] = i
+ left_stack.append(i)
+
+ for i in range(len(heights)-1, -1, -1):
+ while right_stack and heights[i] < heights[right_stack[-1]]:
+ left_indexes[right_stack.pop()] = i
+ right_stack.append(i)
+
+ res = 0
+ for i in range(len(heights)):
+ area = heights[i] * (right_indexes[i] - left_indexes[i] - 1)
+ res = max(res, area)
+ return res
+```
diff --git a/docs/Leetcode_Solutions/Python/086._partition_list.md b/docs/Leetcode_Solutions/Python/086._partition_list.md
new file mode 100644
index 000000000..b4342686b
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/086._partition_list.md
@@ -0,0 +1,57 @@
+# 86. Partition List
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/partition-list/description/
+
+> 内容描述
+
+```
+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.
+
+Example:
+
+Input: head = 1->4->3->2->5->2, x = 3
+Output: 1->2->2->4->3->5
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+两个dummy,一个代表before,一个代表behind,最后连接起来就是结果,要注意behind的最后可能还连接着原来的点
+
+例如例子中的5,它在最开始后面还连接着1个2,所以要记得将dummy1_end.next置为None
+
+beats 99.39%
+
+```python
+class Solution(object):
+ def partition(self, head, x):
+ """
+ :type head: ListNode
+ :type x: int
+ :rtype: ListNode
+ """
+ dummy1_start = dummy1_end = ListNode(None) # before
+ dummy2_start = dummy2_end = ListNode(None) # behind
+ while head:
+ if head.val < x:
+ dummy1_end.next = head
+ dummy1_end = dummy1_end.next
+ else:
+ dummy2_end.next = head
+ dummy2_end = dummy2_end.next
+ head = head.next
+ # 从例子来看,因为dummy2_end最后指向5,它最开始还连着2呢,所以要置为空
+ dummy2_end.next = None
+ dummy1_end.next = dummy2_start.next
+ return dummy1_start.next
+```
diff --git a/docs/leetcode/python/088._merge_sorted_array.md b/docs/Leetcode_Solutions/Python/088._merge_sorted_array.md
similarity index 95%
rename from docs/leetcode/python/088._merge_sorted_array.md
rename to docs/Leetcode_Solutions/Python/088._merge_sorted_array.md
index 2117ae223..d24fb9b32 100644
--- a/docs/leetcode/python/088._merge_sorted_array.md
+++ b/docs/Leetcode_Solutions/Python/088._merge_sorted_array.md
@@ -6,7 +6,7 @@
> 原题连接
-* https://leetcode.com/problems/merge-sorted-array
+* https://leetcode.com/problems/merge-sorted-array/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/089._gray_code.md b/docs/Leetcode_Solutions/Python/089._gray_code.md
new file mode 100644
index 000000000..c889837a4
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/089._gray_code.md
@@ -0,0 +1,107 @@
+# 89. Gray Code
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/gray-code/description/
+
+> 内容描述
+
+```
+The gray code is a binary numeral system where two successive values differ in only one bit.
+
+Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.
+
+Example 1:
+
+Input: 2
+Output: [0,1,3,2]
+Explanation:
+00 - 0
+01 - 1
+11 - 3
+10 - 2
+
+For a given n, a gray code sequence may not be uniquely defined.
+For example, [0,2,3,1] is also a valid gray code sequence.
+
+00 - 0
+10 - 2
+11 - 3
+01 - 1
+Example 2:
+
+Input: 0
+Output: [0]
+Explanation: We define the gray code sequence to begin with 0.
+ A gray code sequence of n has size = 2n, which for n = 0 the size is 20 = 1.
+ Therefore, for n = 0 the gray code sequence is [0].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(2^N)******- 空间复杂度: O(2^N)******
+
+几分钟找到了规律,然后实现,AC了。
+
+规律就是n从1开始,每次的结果都是三部分的叠加,part1就是n-1返回的值f(n-1),part2就是f(n-1)的前半部分每一个元素加上```3*pow(2, n-2)```,
+part3就是f(n-1)的后半部分每一个元素加上```pow(2, n-2)```
+
+```
+ 3 1 6 6 2 2 12 12 12 12 4 4 4 4 (这一行就是要加上的数字)
+0 1 3 2 6 7 5 4 12 13 15 14 10 11 9 8
+```
+
+```python
+class Solution(object):
+ def grayCode(self, n):
+ """
+ :type n: int
+ :rtype: List[int]
+ """
+ if n == 0:
+ return [0]
+ if n == 1:
+ return [0, 1]
+ part1 = self.grayCode(n-1)
+ part2 = [i + 3 * pow(2, n-2) for i in part1[:len(part1)//2]]
+ part3 = [i + pow(2, n-2) for i in part1[len(part1)//2:]]
+ return part1 + part2 + part3
+```
+
+> 思路 2
+******- 时间复杂度: O(2^N)******- 空间复杂度: O(2^N)******
+
+AC了以后好自豪哦,看了下 discuss,然后居然有这个东西,我一口老血,我宛若一个智障
+
+```
+The main problem is we need to convert binary code B to Gray code G.
+For the i th bit of binary code:
+if i==0: G[i]=B[i]
+else: G[i] = B[i] XOR B[i-1]
+
+The above part can be simply expressed by G = B^(B>>1).
+```
+
+
+
+服气,这个待研究
+```
+class Solution(object):
+ def grayCode(self, n):
+ """
+ :type n: int
+ :rtype: List[int]
+ """
+ res = [(i>>1)^i for i in range(pow(2,n))]
+ return res
+```
+
+
+
+
+
diff --git a/docs/leetcode/python/090._subsets_ii.md b/docs/Leetcode_Solutions/Python/090._subsets_ii.md
similarity index 78%
rename from docs/leetcode/python/090._subsets_ii.md
rename to docs/Leetcode_Solutions/Python/090._subsets_ii.md
index 5d7285397..584fe278f 100644
--- a/docs/leetcode/python/090._subsets_ii.md
+++ b/docs/Leetcode_Solutions/Python/090._subsets_ii.md
@@ -6,7 +6,7 @@
> 原题连接
-* https://leetcode.com/problems/subsets-ii
+* https://leetcode.com/problems/subsets-ii/description/
> 内容描述
@@ -55,6 +55,8 @@ Output:
```
自己的解法,这里最关键的就是先对nums进行了排序,保证了我们插入相同的数字时都是相邻的
+
+
```python
class Solution(object):
def subsetsWithDup(self, nums):
@@ -64,16 +66,35 @@ class Solution(object):
"""
nums.sort()
res = [[]]
+
for i in range(len(nums)):
- if any(nums[i] in tmp for tmp in res):
- res.extend([tmp+[nums[i]] for tmp in res if tmp.count(nums[i]) == i - nums.index(nums[i])])
- else:
- res.extend([tmp+[nums[i]] for tmp in res])
+ res.extend([tmp+[nums[i]] for tmp in res if tmp.count(nums[i]) == i - nums.index(nums[i])])
return res
```
> 思路 2
+其实我们也可以不sort,如果出现了重复数字,我们就只需要将其加到拥有最多的那个数字的列表中即可
+比如对于[2,1,2],在第二个2出现的时候,我们只需要对[[], [2], [1], [1,2]]中的[1,2]和[2]进行加个2的操作即可
+
+其实换句话说就是之前出现了几次那个数字,现在只需要把这个数字加到拥有几个这个数字的列表中去,就像上面的[1,2]和[2]都出现了一次2,前面2也只出现了1次,所以对他们进行加个2操作就行了
+
+```python
+class Solution(object):
+ def subsetsWithDup(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: List[List[int]]
+ """
+ res = [[]]
+
+ for i in range(len(nums)):
+ res.extend([tmp+[nums[i]] for tmp in res if tmp.count(nums[i]) == nums[:i].count(nums[i])])
+ return res
+```
+
+> 思路 3
+
参考别人的
现在来观察规律,与之前有不同之处是我们需要一个位置来mark,因为不再需要往之前出现过的地方再加了,看这个:
@@ -99,7 +120,7 @@ class Solution(object):
return res
```
-> 思路 3
+> 思路 4
跟[leetcode第78题](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/078._Subsets.md)一样,DFS, 只不过需要在dfs函数里加一个剪枝的条件,排除掉同样的子集。
@@ -126,7 +147,7 @@ class Solution(object):
-> 思路 4
+> 思路 5
跟[leetcode第78题](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/078._Subsets.md)一样,backtrack
diff --git a/docs/leetcode/python/091._decode_ways.md b/docs/Leetcode_Solutions/Python/091._decode_ways.md
similarity index 100%
rename from docs/leetcode/python/091._decode_ways.md
rename to docs/Leetcode_Solutions/Python/091._decode_ways.md
diff --git a/docs/Leetcode_Solutions/Python/092._reverse_linked_list_ii.md b/docs/Leetcode_Solutions/Python/092._reverse_linked_list_ii.md
new file mode 100644
index 000000000..35ffebe8d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/092._reverse_linked_list_ii.md
@@ -0,0 +1,111 @@
+# 92. Reverse Linked List II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/reverse-linked-list-ii/description/
+
+> 内容描述
+
+```
+Reverse a linked list from position m to n. Do it in one-pass.
+
+Note: 1 ≤ m ≤ n ≤ length of list.
+
+Example:
+
+Input: 1->2->3->4->5->NULL, m = 2, n = 4
+Output: 1->4->3->2->5->NULL
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+难度:
+Medium
+
+
+跟 reverse linked list一样
+
+思路: 找到 第 m 个node,然后开始reverse到第n个node,然后再把它们和原本的list连接起来
+
+AC 代码
+
+```python
+class Solution(object):
+ def reverseBetween(self, head, m, n):
+ """
+ :type head: ListNode
+ :type m: int
+ :type n: int
+ :rtype: ListNode
+ """
+ if not head or m == n:
+ return head
+ node_m_before = dummy = ListNode(-1)
+ dummy.next = head
+
+ for i in range(m-1):
+ node_m_before = node_m_before.next
+
+ prev = None
+ cur = node_m_before.next
+ node_m = node_m_before.next
+
+ for i in range(n-m+1):
+ nxt = cur.next
+ cur.next = prev
+ prev = cur
+ cur = nxt
+
+ node_m_before.next = prev
+ node_m.next = cur
+
+ return dummy.next
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+看了一下别人的代码,又比我写的好嘛,因为是保证m和n有效,用的是for循环先找到 m node:
+
+详细见[realisking](https://leetcode.com/problems/reverse-linked-list-ii/discuss/30709/Talk-is-cheap-show-me-the-code-(and-DRAWING))
+```
+for _ in range(m-1):
+ ....
+
+for _ in range(n-m):
+ reverse 操作
+
+```
+```python
+class Solution(object):
+ def reverseBetween(self, head, m, n):
+ """
+ :type head: ListNode
+ :type m: int
+ :type n: int
+ :rtype: ListNode
+ """
+ if not head or m == n:
+ return head
+ p = dummy = ListNode(None)
+ dummy.next = head
+ for i in range(m-1):
+ p = p.next
+ tail = p.next
+
+ for i in range(n-m):
+ tmp = p.next
+ p.next = tail.next
+ tail.next = tail.next.next
+ p.next.next = tmp
+ return dummy.next
+```
+
diff --git a/docs/leetcode/python/093._restore_ip_addresses.md b/docs/Leetcode_Solutions/Python/093._restore_ip_addresses.md
similarity index 100%
rename from docs/leetcode/python/093._restore_ip_addresses.md
rename to docs/Leetcode_Solutions/Python/093._restore_ip_addresses.md
diff --git a/docs/leetcode/python/094._binary_tree_inorder_traversal.md b/docs/Leetcode_Solutions/Python/094._binary_tree_inorder_traversal.md
similarity index 96%
rename from docs/leetcode/python/094._binary_tree_inorder_traversal.md
rename to docs/Leetcode_Solutions/Python/094._binary_tree_inorder_traversal.md
index dc0f41f49..2b91f1ab8 100644
--- a/docs/leetcode/python/094._binary_tree_inorder_traversal.md
+++ b/docs/Leetcode_Solutions/Python/094._binary_tree_inorder_traversal.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/binary-tree-inorder-traversal
+* https://leetcode.com/problems/binary-tree-inorder-traversal/description/
> 内容描述
diff --git a/docs/leetcode/python/096._unique_binary_search_trees.md b/docs/Leetcode_Solutions/Python/096._unique_binary_search_trees.md
similarity index 95%
rename from docs/leetcode/python/096._unique_binary_search_trees.md
rename to docs/Leetcode_Solutions/Python/096._unique_binary_search_trees.md
index 6601516c5..cf9d8c9a7 100644
--- a/docs/leetcode/python/096._unique_binary_search_trees.md
+++ b/docs/Leetcode_Solutions/Python/096._unique_binary_search_trees.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/unique-binary-search-trees
+* https://leetcode.com/problems/unique-binary-search-trees/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/098._validate_binary_search_tree.md b/docs/Leetcode_Solutions/Python/098._validate_binary_search_tree.md
new file mode 100644
index 000000000..db5a92028
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/098._validate_binary_search_tree.md
@@ -0,0 +1,140 @@
+# 98. Validate Binary Search Tree
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/validate-binary-search-tree/description/
+
+> 内容描述
+
+```
+Given a binary tree, determine if it is a valid binary search tree (BST).
+
+Assume a BST is defined as follows:
+
+The left subtree of a node contains only nodes with keys less than the node's key.
+The right subtree of a node contains only nodes with keys greater than the node's key.
+Both the left and right subtrees must also be binary search trees.
+Example 1:
+
+Input:
+ 2
+ / \
+ 1 3
+Output: true
+Example 2:
+
+ 5
+ / \
+ 1 4
+ / \
+ 3 6
+Output: false
+Explanation: The input is: [5,1,4,null,null,3,6]. The root node's value
+ is 5 but its right child's value is 4.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+中序遍历一次,看看list是否严格满足递增
+
+```python
+ def isValidBST(self, root):
+ """
+ :type root: TreeNode
+ :rtype: bool
+ """
+ def inorder(root):
+ if not root:
+ return
+ inorder(root.left)
+ res.append(root)
+ inorder(root.right)
+
+ res = []
+ if not root:
+ return True
+ inorder(root)
+ for i in range(1, len(res)):
+ if res[i].val <= res[i-1].val:
+ return False
+ return True
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+以前做过这道题,valid binary tree,需要check两件事:
+
+
+```
+ 10
+ / \
+ 7 20
+ / \
+ 5 40
+```
+
+
+- node.left.val < node.val
+ - right subtree of left child, value < node.val
+- node.right.val > node.val
+ - left subtree of the right child, value > node.val
+
+
+wikipedia上有伪码:
+
+```
+truct TreeNode {
+ int key;
+ int value;
+ struct TreeNode *left;
+ struct TreeNode *right;
+};
+
+bool isBST(struct TreeNode *node, int minKey, int maxKey) {
+ if(node == NULL) return true;
+ if(node->key < minKey || node->key > maxKey) return false;
+
+ return isBST(node->left, minKey, node->key) && isBST(node->right, node->key, maxKey);
+}
+
+
+if(isBST(root, INT_MIN, INT_MAX)) {
+ puts("This is a BST.");
+} else {
+ puts("This is NOT a BST!");
+}
+```
+
+实际上就是每次往下看,node都确保被夹在一个范围。
+
+
+```python
+class Solution(object):
+ def isValidBST(self, root):
+ """
+ :type root: TreeNode
+ :rtype: bool
+ """
+ def valid(root, smallest, largest):
+ if not root:
+ return True
+ if smallest >= root.val or largest <= root.val:
+ return False
+ return valid(root.left, smallest, root.val) and valid(root.right, root.val, largest)
+ if not root:
+ return True
+ return valid(root, -sys.maxsize, sys.maxsize)
+```
+
+
+
diff --git a/docs/leetcode/python/100._same_tree.md b/docs/Leetcode_Solutions/Python/100._same_tree.md
similarity index 95%
rename from docs/leetcode/python/100._same_tree.md
rename to docs/Leetcode_Solutions/Python/100._same_tree.md
index f1e4a0b26..f12c86c3a 100644
--- a/docs/leetcode/python/100._same_tree.md
+++ b/docs/Leetcode_Solutions/Python/100._same_tree.md
@@ -1,49 +1,49 @@
-### 100. Same Tree
-
-题目:
-
-
-
-
-难度:
-
-Easy
-
-
-太简单了,递归一行!
-
-
-```python
-# Definition for a binary tree node.
-# class TreeNode(object):
-# def __init__(self, x):
-# self.val = x
-# self.left = None
-# self.right = None
-
-class Solution(object):
- def isSameTree(self, p, q):
- """
- :type p: TreeNode
- :type q: TreeNode
- :rtype: bool
- """
- return p.val == q.val and all(map(self.isSameTree, (p.left, p.right), (q.left, q.right))) if p and q else p is q
-```
-
-```python
-class Solution(object):
- def isSameTree(self, p, q):
- """
- :type p: TreeNode
- :type q: TreeNode
- :rtype: bool
- """
- if (not p and q) or (p and not q):
- return False
- if not p and not q:
- return True
- if p.val == q.val:
- return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
- return False
-```
+### 100. Same Tree
+
+题目:
+
+
+
+
+难度:
+
+Easy
+
+
+太简单了,递归一行!
+
+
+```python
+# Definition for a binary tree node.
+# class TreeNode(object):
+# def __init__(self, x):
+# self.val = x
+# self.left = None
+# self.right = None
+
+class Solution(object):
+ def isSameTree(self, p, q):
+ """
+ :type p: TreeNode
+ :type q: TreeNode
+ :rtype: bool
+ """
+ return p.val == q.val and all(map(self.isSameTree, (p.left, p.right), (q.left, q.right))) if p and q else p is q
+```
+
+```python
+class Solution(object):
+ def isSameTree(self, p, q):
+ """
+ :type p: TreeNode
+ :type q: TreeNode
+ :rtype: bool
+ """
+ if (not p and q) or (p and not q):
+ return False
+ if not p and not q:
+ return True
+ if p.val == q.val:
+ return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
+ return False
+```
diff --git a/docs/leetcode/python/101._symmetric_tree.md b/docs/Leetcode_Solutions/Python/101._symmetric_tree.md
similarity index 95%
rename from docs/leetcode/python/101._symmetric_tree.md
rename to docs/Leetcode_Solutions/Python/101._symmetric_tree.md
index ac5b08266..cb6f5219b 100644
--- a/docs/leetcode/python/101._symmetric_tree.md
+++ b/docs/Leetcode_Solutions/Python/101._symmetric_tree.md
@@ -1,45 +1,45 @@
-### 101. Symmetric Tree
-
-题目:
-
-
-
-
-难度:
-
-Easy
-
-
-两棵树symmetric, 有几种可能:
-
-- 均为none ,symmetric
-- 左孩子,右孩子都不存在,并且值相等, symmetric
-- 右子树 和 另一棵树的左子树相等,左子树 和另一颗树的右子树相等 🌲
-
-
-```python
-class Solution(object):
- def isSymmetric(self, root):
- """
- :type root: TreeNode
- :rtype: bool
- """
- if not root:
- return True
- return self.symmetric(root.left, root.right)
-
- def symmetric(self, l1, l2):
- if not l1 or not l2:
- if not l1 and not l2:
- return True
- else:
- return False
- if l1.val == l2.val:
- return self.symmetric(l1.left, l2.right) and self.symmetric(l1.right, l2.left)
- else:
- return False
-```
-
-
-
-
+### 101. Symmetric Tree
+
+题目:
+
+
+
+
+难度:
+
+Easy
+
+
+两棵树symmetric, 有几种可能:
+
+- 均为none ,symmetric
+- 左孩子,右孩子都不存在,并且值相等, symmetric
+- 右子树 和 另一棵树的左子树相等,左子树 和另一颗树的右子树相等 🌲
+
+
+```python
+class Solution(object):
+ def isSymmetric(self, root):
+ """
+ :type root: TreeNode
+ :rtype: bool
+ """
+ if not root:
+ return True
+ return self.symmetric(root.left, root.right)
+
+ def symmetric(self, l1, l2):
+ if not l1 or not l2:
+ if not l1 and not l2:
+ return True
+ else:
+ return False
+ if l1.val == l2.val:
+ return self.symmetric(l1.left, l2.right) and self.symmetric(l1.right, l2.left)
+ else:
+ return False
+```
+
+
+
+
diff --git a/docs/leetcode/python/102._binary_tree_level_order_traversal.md b/docs/Leetcode_Solutions/Python/102._binary_tree_level_order_traversal.md
similarity index 77%
rename from docs/leetcode/python/102._binary_tree_level_order_traversal.md
rename to docs/Leetcode_Solutions/Python/102._binary_tree_level_order_traversal.md
index d95eac61f..9c298ffda 100644
--- a/docs/leetcode/python/102._binary_tree_level_order_traversal.md
+++ b/docs/Leetcode_Solutions/Python/102._binary_tree_level_order_traversal.md
@@ -1,11 +1,11 @@
# 102. Binary Tree Level Order Traversal
-**难度: 中等**
+**难度: Medium**
## 刷题内容
> 原题连接
-* https://leetcode.com/problems/binary-tree-level-order-traversal
+* https://leetcode.com/problems/binary-tree-level-order-traversal/description/
> 内容描述
@@ -34,23 +34,24 @@ return its level order traversal as:
递归
```python
-class Solution(object):
+class Solution:
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
+ def dfs(node, level, res):
+ if not node:
+ return
+ if len(res) < level:
+ res.append([])
+ res[level-1].append(node.val)
+ dfs(node.left, level+1, res)
+ dfs(node.right, level+1, res)
+
res = []
- self.recurHelper(root, 0, res)
+ dfs(root, 1, res)
return res
-
- def recurHelper(self, root, level, res):
- if not root: return
- if len(res) < level + 1:
- res.append([])
- res[level].append(root.val)
- self.recurHelper(root.left, level+1, res)
- self.recurHelper(root.right, level+1, res)
```
> 思路 2
diff --git a/docs/leetcode/python/103._binary_tree_zigzag_level_order_traversal.md b/docs/Leetcode_Solutions/Python/103._binary_tree_zigzag_level_order_traversal.md
similarity index 95%
rename from docs/leetcode/python/103._binary_tree_zigzag_level_order_traversal.md
rename to docs/Leetcode_Solutions/Python/103._binary_tree_zigzag_level_order_traversal.md
index 0f5f55fd1..edc9b3986 100644
--- a/docs/leetcode/python/103._binary_tree_zigzag_level_order_traversal.md
+++ b/docs/Leetcode_Solutions/Python/103._binary_tree_zigzag_level_order_traversal.md
@@ -1,43 +1,43 @@
-### 103. Binary Tree Zigzag Level Order Traversal
-
-题目:
-
-
-
-
-难度:
-
-Medium
-
-
-
-```python
-class Solution(object):
- def zigzagLevelOrder(self, root):
- """
- :type root: TreeNode
- :rtype: List[List[int]]
- """
- if not root:
- return []
- res, cur_level, level_count = [], [root], 0
- while cur_level:
- next_level, tmp_res = [], []
- for node in cur_level:
- tmp_res.append(node.val)
- if node.left:
- next_level.append(node.left)
- if node.right:
- next_level.append(node.right)
- if level_count % 2 == 0:
- res.append(tmp_res)
- else:
- tmp_res.reverse()
- res.append(tmp_res)
- level_count += 1
- cur_level = next_level
-
- return res
-```
-
-
+### 103. Binary Tree Zigzag Level Order Traversal
+
+题目:
+
+
+
+
+难度:
+
+Medium
+
+
+
+```python
+class Solution(object):
+ def zigzagLevelOrder(self, root):
+ """
+ :type root: TreeNode
+ :rtype: List[List[int]]
+ """
+ if not root:
+ return []
+ res, cur_level, level_count = [], [root], 0
+ while cur_level:
+ next_level, tmp_res = [], []
+ for node in cur_level:
+ tmp_res.append(node.val)
+ if node.left:
+ next_level.append(node.left)
+ if node.right:
+ next_level.append(node.right)
+ if level_count % 2 == 0:
+ res.append(tmp_res)
+ else:
+ tmp_res.reverse()
+ res.append(tmp_res)
+ level_count += 1
+ cur_level = next_level
+
+ return res
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/104._maximum_depth_of_binary_tree.md b/docs/Leetcode_Solutions/Python/104._maximum_depth_of_binary_tree.md
new file mode 100644
index 000000000..f8f122bd1
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/104._maximum_depth_of_binary_tree.md
@@ -0,0 +1,49 @@
+# 104. Maximum Depth of Binary Tree
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/maximum-depth-of-binary-tree/description/
+
+> 内容描述
+
+```
+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.
+
+Note: A leaf is a node with no children.
+
+Example:
+
+Given binary tree [3,9,20,null,null,15,7],
+
+ 3
+ / \
+ 9 20
+ / \
+ 15 7
+return its depth = 3.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+简单题,但是这道题跟[leetcode111](https://github.com/apachecn/awesome-algorithm/blob/master/docs/Leetcode_Solutions/Python/111._minimum_depth_of_binary_tree.md)不一样,这道题没有特殊情况,所以一行就够了
+
+
+```python
+class Solution(object):
+ def maxDepth(self, root):
+ """
+ :type root: TreeNode
+ :rtype: int
+ """
+ return 1 + max(map(self.maxDepth, (root.left, root.right))) if root else 0
+```
diff --git a/docs/leetcode/python/105._construct_binary_tree_from_preorder_and_inorder_traversal.md b/docs/Leetcode_Solutions/Python/105._construct_binary_tree_from_preorder_and_inorder_traversal.md
similarity index 94%
rename from docs/leetcode/python/105._construct_binary_tree_from_preorder_and_inorder_traversal.md
rename to docs/Leetcode_Solutions/Python/105._construct_binary_tree_from_preorder_and_inorder_traversal.md
index 1fc2656c3..441679434 100644
--- a/docs/leetcode/python/105._construct_binary_tree_from_preorder_and_inorder_traversal.md
+++ b/docs/Leetcode_Solutions/Python/105._construct_binary_tree_from_preorder_and_inorder_traversal.md
@@ -6,8 +6,8 @@
> 原题连接
-* https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
-* https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal
+* https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/
+* https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/description/
> 内容描述
diff --git a/docs/leetcode/python/106._construct_binary_tree_from_inorder_and_postorder_traversal.md b/docs/Leetcode_Solutions/Python/106._construct_binary_tree_from_inorder_and_postorder_traversal.md
similarity index 100%
rename from docs/leetcode/python/106._construct_binary_tree_from_inorder_and_postorder_traversal.md
rename to docs/Leetcode_Solutions/Python/106._construct_binary_tree_from_inorder_and_postorder_traversal.md
diff --git a/docs/Leetcode_Solutions/Python/107._binary_tree_level_order_traversal_ii.md b/docs/Leetcode_Solutions/Python/107._binary_tree_level_order_traversal_ii.md
new file mode 100644
index 000000000..a3d59a027
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/107._binary_tree_level_order_traversal_ii.md
@@ -0,0 +1,61 @@
+# 107. Binary Tree Level Order Traversal II
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/binary-tree-level-order-traversal-ii/description/
+
+> 内容描述
+
+```
+Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).
+
+For example:
+Given binary tree [3,9,20,null,null,15,7],
+ 3
+ / \
+ 9 20
+ / \
+ 15 7
+return its bottom-up level order traversal as:
+[
+ [15,7],
+ [9,20],
+ [3]
+]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+用102 的算法作弊
+
+
+```python
+class Solution:
+ def levelOrderBottom(self, root):
+ """
+ :type root: TreeNode
+ :rtype: List[List[int]]
+ """
+ def dfs(node, level, res):
+ if not node:
+ return
+ if len(res) < level:
+ res.append([])
+ res[level-1].append(node.val)
+ dfs(node.left, level+1, res)
+ dfs(node.right, level+1, res)
+
+ res = []
+ dfs(root, 1, res)
+ return res[::-1]
+```
+
+
diff --git a/docs/leetcode/python/108._convert_sorted_array_to_binary_search_tree.md b/docs/Leetcode_Solutions/Python/108._convert_sorted_array_to_binary_search_tree.md
similarity index 100%
rename from docs/leetcode/python/108._convert_sorted_array_to_binary_search_tree.md
rename to docs/Leetcode_Solutions/Python/108._convert_sorted_array_to_binary_search_tree.md
diff --git a/docs/leetcode/python/109._convert_sorted_list_to_binary_search_tree.md b/docs/Leetcode_Solutions/Python/109._convert_sorted_list_to_binary_search_tree.md
similarity index 100%
rename from docs/leetcode/python/109._convert_sorted_list_to_binary_search_tree.md
rename to docs/Leetcode_Solutions/Python/109._convert_sorted_list_to_binary_search_tree.md
diff --git a/docs/leetcode/python/110._balanced_binary_tree.md b/docs/Leetcode_Solutions/Python/110._balanced_binary_tree.md
similarity index 89%
rename from docs/leetcode/python/110._balanced_binary_tree.md
rename to docs/Leetcode_Solutions/Python/110._balanced_binary_tree.md
index ac8f70104..5dc519d6a 100644
--- a/docs/leetcode/python/110._balanced_binary_tree.md
+++ b/docs/Leetcode_Solutions/Python/110._balanced_binary_tree.md
@@ -1,68 +1,68 @@
-# 110. Balanced Binary Tree
-**难度: 简单**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/balanced-binary-tree
-
-> 内容描述
-
-```
-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.
-
-Example 1:
-
-Given the following tree [3,9,20,null,null,15,7]:
-
- 3
- / \
- 9 20
- / \
- 15 7
-Return true.
-
-Example 2:
-
-Given the following tree [1,2,2,3,3,null,null,4,4]:
-
- 1
- / \
- 2 2
- / \
- 3 3
- / \
- 4 4
-Return false.
-```
-
-## 解题方案
-
-> 思路 1
-
-递归,判断左右子树最大高度差不超过1且左右子树均为平衡树
-
-```python
-class Solution(object):
- def isBalanced(self, root):
- """
- :type root: TreeNode
- :rtype: bool
- """
- def height(node):
- if not node:
- return 0
- return 1 + max(height(node.left), height(node.right))
- if not root:
- return True
- return abs(height(root.left) - height(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)
-```
-
-
-
-
+# 110. Balanced Binary Tree
+**难度: 简单**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/balanced-binary-tree/description/
+
+> 内容描述
+
+```
+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.
+
+Example 1:
+
+Given the following tree [3,9,20,null,null,15,7]:
+
+ 3
+ / \
+ 9 20
+ / \
+ 15 7
+Return true.
+
+Example 2:
+
+Given the following tree [1,2,2,3,3,null,null,4,4]:
+
+ 1
+ / \
+ 2 2
+ / \
+ 3 3
+ / \
+ 4 4
+Return false.
+```
+
+## 解题方案
+
+> 思路 1
+
+递归,判断左右子树最大高度差不超过1且左右子树均为平衡树
+
+```python
+class Solution(object):
+ def isBalanced(self, root):
+ """
+ :type root: TreeNode
+ :rtype: bool
+ """
+ def height(node):
+ if not node:
+ return 0
+ return 1 + max(height(node.left), height(node.right))
+ if not root:
+ return True
+ return abs(height(root.left) - height(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right)
+```
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/111._minimum_depth_of_binary_tree.md b/docs/Leetcode_Solutions/Python/111._minimum_depth_of_binary_tree.md
new file mode 100644
index 000000000..ad3270af1
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/111._minimum_depth_of_binary_tree.md
@@ -0,0 +1,115 @@
+# 111. Minimum Depth of Binary Tree
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-depth-of-binary-tree/description/
+
+> 内容描述
+
+```
+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.
+
+Note: A leaf is a node with no children.
+
+Example:
+
+Given binary tree [3,9,20,null,null,15,7],
+
+ 3
+ / \
+ 9 20
+ / \
+ 15 7
+return its minimum depth = 2.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+
+思路,看完题目我想当然的认为就是直接递归取最小的值,代码如下:
+```
+class Solution(object):
+ def minDepth(self, root):
+ """
+ :type root: TreeNode
+ :rtype: int
+ """
+ if not root:
+ return 0
+ return 1 + min(map(self.minDepth, (root.left, root.right)))
+```
+
+
+但是没过,有一种特殊情况就是
+
+注意```leaf node```: 反正就是没有```left```和```right```的
+
+比如下图
+
+
+```
+1
+ \
+ 2
+```
+
+```2```是一个孩子节点
+
+这种情况应该输出```2```而不是```1```
+
+
+
+唯一的特殊情况就是上面这种了,因为```root```下只有一个左节点或者是右节点,这样另外一边的空节点并不算是```leaf node```
+
+```leaf node: itself is not null but it has both children null```
+
+所以还是要养成多写edge case的好习惯,也许就帮你避免了general写法的特例,代码如下
+
+```python
+class Solution(object):
+ def minDepth(self, root):
+ """
+ :type root: TreeNode
+ :rtype: int
+ """
+ if not root:
+ return 0
+ elif root.left and root.right:
+ return 1 + min(self.minDepth(root.left), self.minDepth(root.right))
+ elif root.left:
+ return 1 + self.minDepth(root.left)
+ elif root.right:
+ return 1 + self.minDepth(root.right)
+ else:
+ return 1
+```
+
+
+
+
+> 思路 2
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+或许写的更巧妙一些
+
+```python
+class Solution(object):
+ def minDepth(self, root):
+ """
+ :type root: TreeNode
+ :rtype: int
+ """
+ if not root:
+ return 0
+ depth_under_root = map(self.minDepth, (root.left, root.right))
+ return 1 + (min(depth_under_root) or max(depth_under_root))
+```
diff --git a/docs/leetcode/python/112._path_sum.md b/docs/Leetcode_Solutions/Python/112._path_sum.md
similarity index 100%
rename from docs/leetcode/python/112._path_sum.md
rename to docs/Leetcode_Solutions/Python/112._path_sum.md
diff --git a/docs/leetcode/python/113._path_sum_ii.md b/docs/Leetcode_Solutions/Python/113._path_sum_ii.md
similarity index 100%
rename from docs/leetcode/python/113._path_sum_ii.md
rename to docs/Leetcode_Solutions/Python/113._path_sum_ii.md
diff --git a/docs/leetcode/python/114._flatten_binary_tree_to_linked_list.md b/docs/Leetcode_Solutions/Python/114._flatten_binary_tree_to_linked_list.md
similarity index 96%
rename from docs/leetcode/python/114._flatten_binary_tree_to_linked_list.md
rename to docs/Leetcode_Solutions/Python/114._flatten_binary_tree_to_linked_list.md
index 7997d090a..81ad647ca 100644
--- a/docs/leetcode/python/114._flatten_binary_tree_to_linked_list.md
+++ b/docs/Leetcode_Solutions/Python/114._flatten_binary_tree_to_linked_list.md
@@ -1,71 +1,71 @@
-### 114. Flatten Binary Tree to Linked List
-
-题目:
-
-
-
-难度:
-
-Medium
-
-这道题看了hint,说每个node的右节点都是相应先序遍历中它的下一个节点。
-所以我的思路是先把先序遍历的node顺序搞出来,然后对于这里面的每一个节点,只需要做两个操作:
-1. node.left = None
-2. node.right = 相应先序遍历中node的下一个节点
-
-```python
-class Solution(object):
- def flatten(self, root):
- """
- :type root: TreeNode
- :rtype: void Do not return anything, modify root in-place instead.
- """
- def preorder(root):
- res = []
- if not root:
- return res
- res.append(root)
- if root.left:
- res.extend(preorder(root.left))
- if root.right:
- res.extend(preorder(root.right))
- return res
- if not root:
- return
- node_order = preorder(root)
- for i in range(len(node_order)-1):
- node_order[i].left = None
- node_order[i].right = node_order[i+1]
- node_order[-1].left = None
- node_order[-1].right = None
-```
-beat 40.67%
-
-另外一种解法:
-1. copy the left and right subtree
-2. then cut root’s left subtree
-3. do DFS
-4. left and right has been flattened and connect them left and right back to the root
-
-```python
-class Solution(object):
- def flatten(self, root):
- """
- :type root: TreeNode
- :rtype: void Do not return anything, modify root in-place instead.
- """
- if not root:
- return
- left_node = root.left
- right_node = root.right
- root.left = None
- self.flatten(left_node)
- self.flatten(right_node)
- if left_node:
- root.right = left_node
- while left_node.right:
- left_node = left_node.right
- left_node.right = right_node
-```
-beat 32.18%
-
+### 114. Flatten Binary Tree to Linked List
+
+题目:
+
+
+
+难度:
+
+Medium
+
+这道题看了hint,说每个node的右节点都是相应先序遍历中它的下一个节点。
+所以我的思路是先把先序遍历的node顺序搞出来,然后对于这里面的每一个节点,只需要做两个操作:
+1. node.left = None
+2. node.right = 相应先序遍历中node的下一个节点
+
+```python
+class Solution(object):
+ def flatten(self, root):
+ """
+ :type root: TreeNode
+ :rtype: void Do not return anything, modify root in-place instead.
+ """
+ def preorder(root):
+ res = []
+ if not root:
+ return res
+ res.append(root)
+ if root.left:
+ res.extend(preorder(root.left))
+ if root.right:
+ res.extend(preorder(root.right))
+ return res
+ if not root:
+ return
+ node_order = preorder(root)
+ for i in range(len(node_order)-1):
+ node_order[i].left = None
+ node_order[i].right = node_order[i+1]
+ node_order[-1].left = None
+ node_order[-1].right = None
+```
+beat 40.67%
+
+另外一种解法:
+1. copy the left and right subtree
+2. then cut root’s left subtree
+3. do DFS
+4. left and right has been flattened and connect them left and right back to the root
+
+```python
+class Solution(object):
+ def flatten(self, root):
+ """
+ :type root: TreeNode
+ :rtype: void Do not return anything, modify root in-place instead.
+ """
+ if not root:
+ return
+ left_node = root.left
+ right_node = root.right
+ root.left = None
+ self.flatten(left_node)
+ self.flatten(right_node)
+ if left_node:
+ root.right = left_node
+ while left_node.right:
+ left_node = left_node.right
+ left_node.right = right_node
+```
+beat 32.18%
+
diff --git a/docs/leetcode/python/116._populating_next_right_pointers_in_each_node.md b/docs/Leetcode_Solutions/Python/116._populating_next_right_pointers_in_each_node.md
similarity index 98%
rename from docs/leetcode/python/116._populating_next_right_pointers_in_each_node.md
rename to docs/Leetcode_Solutions/Python/116._populating_next_right_pointers_in_each_node.md
index fec99e947..f0548445c 100644
--- a/docs/leetcode/python/116._populating_next_right_pointers_in_each_node.md
+++ b/docs/Leetcode_Solutions/Python/116._populating_next_right_pointers_in_each_node.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/populating-next-right-pointers-in-each-node
+* https://leetcode.com/problems/populating-next-right-pointers-in-each-node/description/
> 内容描述
diff --git a/docs/leetcode/python/117._Populating_Next_Right_Pointers_in_Each_Node_II.md b/docs/Leetcode_Solutions/Python/117._Populating_Next_Right_Pointers_in_Each_Node_II.md
similarity index 98%
rename from docs/leetcode/python/117._Populating_Next_Right_Pointers_in_Each_Node_II.md
rename to docs/Leetcode_Solutions/Python/117._Populating_Next_Right_Pointers_in_Each_Node_II.md
index f42e157ab..72b10dfb3 100644
--- a/docs/leetcode/python/117._Populating_Next_Right_Pointers_in_Each_Node_II.md
+++ b/docs/Leetcode_Solutions/Python/117._Populating_Next_Right_Pointers_in_Each_Node_II.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii
+* https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/description/
> 内容描述
diff --git a/docs/leetcode/python/118._pascal's_triangle.md b/docs/Leetcode_Solutions/Python/118._pascal's_triangle.md
similarity index 76%
rename from docs/leetcode/python/118._pascal's_triangle.md
rename to docs/Leetcode_Solutions/Python/118._pascal's_triangle.md
index 026ce65e4..33b152226 100644
--- a/docs/leetcode/python/118._pascal's_triangle.md
+++ b/docs/Leetcode_Solutions/Python/118._pascal's_triangle.md
@@ -1,73 +1,78 @@
-# 118. Pascal's Triangle
-**难度: 简单**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/pascals-triangle
-
-> 内容描述
-
-```
-Given a non-negative integer numRows, generate the first numRows of Pascal's triangle.
-```
-
-
-```
-In Pascal's triangle, each number is the sum of the two numbers directly above it.
-
-Example:
-
-Input: 5
-Output:
-[
- [1],
- [1,1],
- [1,2,1],
- [1,3,3,1],
- [1,4,6,4,1]
-]
-```
-
-## 解题方案
-
-> 思路 1
-
-
-高中数学知识,把行数理理清楚就ok
-
-
-```python
-class Solution(object):
- def generate(self, numRows):
- """
- :type numRows: int
- :rtype: List[List[int]]
- """
- if numRows == 0:
- return []
- res = [[1]]
- for i in range(1, numRows):
- tmp = [1]
- for j in range(1, i):
- tmp.append(res[-1][j-1]+res[-1][j])
- tmp.append(1)
- res.append(tmp)
- return res
-```
-或者可以写得更简单一些,这里谢谢荼靡大佬的想法,棒!
-
-```python
-class Solution(object):
- def generate(self, numRows):
- """
- :type numRows: int
- :rtype: List[List[int]]
- """
- res = [[1]]
- for i in range(1, numRows):
- res.append(map(lambda x,y:x+y, [0]+res[-1], res[-1]+[0]))
- return res[:numRows]
-```
-
+# 118. Pascal's Triangle
+**难度: 简单**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/pascals-triangle/description/
+
+> 内容描述
+
+```
+Given a non-negative integer numRows, generate the first numRows of Pascal's triangle.
+```
+
+
+```
+In Pascal's triangle, each number is the sum of the two numbers directly above it.
+
+Example:
+
+Input: 5
+Output:
+[
+ [1],
+ [1,1],
+ [1,2,1],
+ [1,3,3,1],
+ [1,4,6,4,1]
+]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+
+高中数学知识,把行数理理清楚就ok, beats 100%
+
+
+```python
+class Solution(object):
+ def generate(self, numRows):
+ """
+ :type numRows: int
+ :rtype: List[List[int]]
+ """
+ if numRows == 0:
+ return []
+ res = [[1]]
+ for i in range(1, numRows):
+ tmp = [1]
+ for j in range(1, i):
+ tmp.append(res[-1][j-1]+res[-1][j])
+ tmp.append(1)
+ res.append(tmp)
+ return res
+```
+
+> 思路 2
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+或者可以写得更简单一些,这里谢谢荼靡大佬的想法,棒!但是时间真的不好,才 beats 1.02%
+
+```python
+class Solution(object):
+ def generate(self, numRows):
+ """
+ :type numRows: int
+ :rtype: List[List[int]]
+ """
+ res = [[1]]
+ for i in range(1, numRows):
+ res.append(map(lambda x,y:x+y, [0]+res[-1], res[-1]+[0]))
+ return res[:numRows]
+```
+
diff --git a/docs/Leetcode_Solutions/Python/119. _Pascal's_Triangle_II.md b/docs/Leetcode_Solutions/Python/119. _Pascal's_Triangle_II.md
new file mode 100644
index 000000000..176476423
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/119. _Pascal's_Triangle_II.md
@@ -0,0 +1,58 @@
+# 119. Pascal's Triangle II
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/pascals-triangle-ii/description/
+
+> 内容描述
+
+```
+Given a non-negative index k where k ≤ 33, return the kth index row of the Pascal's triangle.
+
+Note that the row index starts from 0.
+```
+
+
+
+```
+In Pascal's triangle, each number is the sum of the two numbers directly above it.
+
+Example:
+
+Input: 3
+Output: [1,3,3,1]
+Follow up:
+
+Could you optimize your algorithm to use only O(k) extra space?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(k^2)******- 空间复杂度: O(k)******
+
+太简单了,注意一点算数就好, beats 99.89%
+
+
+```python
+class Solution(object):
+ def getRow(self, rowIndex):
+ """
+ :type rowIndex: int
+ :rtype: List[int]
+ """
+ if rowIndex == 0:
+ return [1]
+ res = [1]
+ for i in range(1, rowIndex+1):
+ tmp = [1]
+ for j in range(1, i):
+ tmp.append(res[j-1]+res[j])
+ tmp.append(1)
+ res = tmp
+ return res
+```
diff --git a/docs/leetcode/python/120._Triangle.md b/docs/Leetcode_Solutions/Python/120. Triangle.md
similarity index 100%
rename from docs/leetcode/python/120._Triangle.md
rename to docs/Leetcode_Solutions/Python/120. Triangle.md
diff --git a/docs/Leetcode_Solutions/Python/121._Best_Time_to_Buy_and_Sell_Stock.md b/docs/Leetcode_Solutions/Python/121._Best_Time_to_Buy_and_Sell_Stock.md
new file mode 100644
index 000000000..1d45796be
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/121._Best_Time_to_Buy_and_Sell_Stock.md
@@ -0,0 +1,112 @@
+# 121. Best Time to Buy and Sell Stock
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
+
+> 内容描述
+
+```
+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 (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.
+
+Note that you cannot sell a stock before you buy one.
+
+Example 1:
+
+Input: [7,1,5,3,6,4]
+Output: 5
+Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
+ Not 7-1 = 6, as selling price needs to be larger than buying price.
+Example 2:
+
+Input: [7,6,4,3,1]
+Output: 0
+Explanation: In this case, no transaction is done, i.e. max profit = 0.
+```
+
+## 解题方案
+
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+对于从第一天后的每一天i来说:
+- 如果我们在第i天卖出,则能赚的钱是在第i-1卖能赚到的钱+(第i天的股价 - 第i-1的股价)
+- 如果我们在第i天不卖出,则当前赚的钱为 0
+
+所以对于第一天后的第i天来说,他能赚到的最多的钱就是上面两种情况中的较大值
+
+
+All the straight forward solution should work, but if the interviewer twists the question slightly
+by giving the difference array of prices, Ex: for ```{1, 7, 4, 11}```, if he gives ```{0, 6, -3, 7}```,
+you might end up being confused.
+
+Here, the logic is to calculate the difference ```(maxCur += prices[i] - prices[i-1])```
+of the original array, and find a contiguous subarray giving maximum profit.
+If the difference falls below ```0```, reset it to zero.
+
+参考[Maximum subarray problem](https://en.wikipedia.org/wiki/Maximum_subarray_problem),
+[Kadane's Algorithm](https://discuss.leetcode.com/topic/19853/kadane-s-algorithm-since-no-one-has-mentioned-about-this-so-far-in-case-if-interviewer-twists-the-input)
+
+
+```
+Why maxCur = Math.max(0, maxCur += prices[i] - prices[i-1]); ?
+
+Well, we can assume opt(i) as the max Profit you will get if you sell the stock at day i;
+
+We now face two situations:
+
+We hold a stock at day i, which means opt(i) = opt(i - 1) - prices[i - 1] + prices[i] (max Profit you can get if you sell stock at day(i-1) - money you lose if you buy the stock at day (i-1) + money you gain if you sell the stock at day i.
+
+We do not hold a stock at day i, which means we cannot sell any stock at day i. In this case, money we can get at day i is 0;
+
+opt(i) is the best case of 1 and 2.
+
+So, opt(i) = Max{opt(i - 1) - prices[i - 1] + prices[i], 0}
+```
+
+
+```python
+class Solution(object):
+ def maxProfit(self, prices):
+ """
+ :type prices: List[int]
+ :rtype: int
+ """
+ if not prices or len(prices) == 0:
+ return 0
+ opt = [0] * len(prices)
+ for i in range(1, len(prices)):
+ opt[i] = max(opt[i-1]+prices[i]-prices[i-1], 0)
+ return max(opt)
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+```python
+class Solution(object):
+ def maxProfit(self, prices):
+ """
+ :type prices: List[int]
+ :rtype: int
+ """
+ if not prices or len(prices) == 0:
+ return 0
+ res, max_cur = 0, 0
+ for i in range(1, len(prices)):
+ max_cur = max(0, max_cur+prices[i]-prices[i-1])
+ res = max(res, max_cur)
+ return res
+```
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/122._Best_Time_to_Buy_and_Sell_Stock_II.md b/docs/Leetcode_Solutions/Python/122._Best_Time_to_Buy_and_Sell_Stock_II.md
new file mode 100644
index 000000000..24051f264
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/122._Best_Time_to_Buy_and_Sell_Stock_II.md
@@ -0,0 +1,58 @@
+# 122. Best Time to Buy and Sell Stock II
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/description/
+
+> 内容描述
+
+```
+
+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 as many transactions as you like (i.e., buy one and sell one share of the stock multiple times).
+
+Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
+
+Example 1:
+
+Input: [7,1,5,3,6,4]
+Output: 7
+Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
+ Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
+Example 2:
+
+Input: [1,2,3,4,5]
+Output: 4
+Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
+ Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
+ engaging multiple transactions at the same time. You must sell before buying again.
+Example 3:
+
+Input: [7,6,4,3,1]
+Output: 0
+Explanation: In this case, no transaction is done, i.e. max profit = 0.
+```
+
+## 解题方案
+
+> 思路 1
+
+因为不限制买卖次数,所以对于除了最后一天的每一天,我们只需要看看它是否比明天价格低即可,
+如果是的话那我们就今天买入明天卖出(注意:前后两天价格相等的话我们不做买卖操作,因为可能会减少后面可以赚钱的操作数),这样一直操作下去叠加即可
+
+```python
+class Solution(object):
+ def maxProfit(self, prices):
+ """
+ :type prices: List[int]
+ :rtype: int
+ """
+ if not prices or len(prices) == 0:
+ return 0
+ return sum([max(prices[i+1]-prices[i], 0) for i in range(len(prices)-1)])
+```
diff --git a/docs/Leetcode_Solutions/Python/123._Best_Time_to_Buy_and_Sell_Stock_III.md b/docs/Leetcode_Solutions/Python/123._Best_Time_to_Buy_and_Sell_Stock_III.md
new file mode 100644
index 000000000..dddee787c
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/123._Best_Time_to_Buy_and_Sell_Stock_III.md
@@ -0,0 +1,84 @@
+# 123. Best Time to Buy and Sell Stock III
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/
+
+> 内容描述
+
+```
+
+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 (i.e., you must sell the stock before you buy again).
+
+Example 1:
+
+Input: [3,3,5,0,0,3,1,4]
+Output: 6
+Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
+ Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.
+Example 2:
+
+Input: [1,2,3,4,5]
+Output: 4
+Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
+ Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
+ engaging multiple transactions at the same time. You must sell before buying again.
+Example 3:
+
+Input: [7,6,4,3,1]
+Output: 0
+Explanation: In this case, no transaction is done, i.e. max profit = 0.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(kN)******- 空间复杂度: O(k)******
+
+
+所有思路见[第188题](https://github.com/apachecn/awesome-algorithm/blob/master/docs/Leetcode_Solutions/Python/188._Best_Time_to_Buy_and_Sell_Stock_IV.md)
+
+
+这里直接用最优解了
+
+
+beats 57.37%
+
+```python
+class Solution(object):
+ def maxProfit(self, prices):
+ """
+ :type prices: List[int]
+ :rtype: int
+ """
+ def maxKProfit(K, prices):
+ if K >= len(prices) // 2:
+ return sum([max(prices[i+1]-prices[i], 0) for i in range(len(prices)-1)])
+ if not prices or len(prices) == 0:
+ return 0
+ dp, min_ = [0] * (K+1), [prices[0]] * (K+1)
+ for i in range(1, len(prices)):
+ for k in range(1, K+1):
+ min_[k] = min(min_[k], prices[i]-dp[k-1])
+ dp[k] = max(dp[k], prices[i]-min_[k])
+ return dp[-1]
+
+ return maxKProfit(2, prices)
+```
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/124._Binary_Tree_Maximum_Path_Sum.md b/docs/Leetcode_Solutions/Python/124._Binary_Tree_Maximum_Path_Sum.md
similarity index 100%
rename from docs/leetcode/python/124._Binary_Tree_Maximum_Path_Sum.md
rename to docs/Leetcode_Solutions/Python/124._Binary_Tree_Maximum_Path_Sum.md
diff --git a/docs/Leetcode_Solutions/Python/125._valid_palindrome.md b/docs/Leetcode_Solutions/Python/125._valid_palindrome.md
new file mode 100644
index 000000000..460a40df5
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/125._valid_palindrome.md
@@ -0,0 +1,100 @@
+# 125. Valid Palindrome
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/valid-palindrome/description/
+
+> 内容描述
+
+```
+Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.
+
+Note: For the purpose of this problem, we define empty string as valid palindrome.
+
+Example 1:
+
+Input: "A man, a plan, a canal: Panama"
+Output: true
+Example 2:
+
+Input: "race a car"
+Output: false
+```
+
+## 解题方案
+
+> 思路 1
+
+就是比较reversed string 和原本的是否相等.
+
+
+```python
+class Solution(object):
+ def isPalindrome(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ new = ''
+ s = s.lower()
+
+ for i in s:
+ if '0' <= i <= '9' or 'a' <= i <= 'z':
+ new += i
+ return new == new[::-1]
+```
+这样写更简单
+
+```python
+class Solution:
+ def isPalindrome(self, s):
+ s = ''.join(e for e in s if e.isalnum()).lower()
+ return s==s[::-1]
+```
+
+> 思路 2
+
+或者用正则,详见[re.sub()用法](http://blog.csdn.net/geekleee/article/details/75309433)
+瞬间```beats 97.71%```
+
+```python
+class Solution(object):
+ def isPalindrome(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ s = re.sub('[^0-9a-zA-Z]+', '', s ).lower()
+ return s == s[::-1]
+```
+
+> 思路 3
+
+
+双指针in-place
+
+时间复杂度还是O(n), 但是空间优化到了O(1)
+```python
+class Solution(object):
+ def isPalindrome(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ l, r = 0, len(s)-1
+ while l < r:
+ while l < r and not s[l].isalnum():
+ l += 1
+ while l < r and not s[r].isalnum():
+ r -= 1
+ if s[l].lower() != s[r].lower():
+ return False
+ l +=1
+ r -= 1
+ return True
+```
+
diff --git a/docs/leetcode/python/126._Word_Ladder_II.md b/docs/Leetcode_Solutions/Python/126. Word Ladder II.md
similarity index 100%
rename from docs/leetcode/python/126._Word_Ladder_II.md
rename to docs/Leetcode_Solutions/Python/126. Word Ladder II.md
diff --git a/docs/Leetcode_Solutions/Python/127._word_ladder.md b/docs/Leetcode_Solutions/Python/127._word_ladder.md
new file mode 100644
index 000000000..b852e9b11
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/127._word_ladder.md
@@ -0,0 +1,81 @@
+# 127. Word Ladder
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/word-ladder/description/
+
+> 内容描述
+
+```
+Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:
+
+Only one letter can be changed at a time.
+Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
+Note:
+
+Return 0 if there is no such transformation sequence.
+All words have the same length.
+All words contain only lowercase alphabetic characters.
+You may assume no duplicates in the word list.
+You may assume beginWord and endWord are non-empty and are not the same.
+Example 1:
+
+Input:
+beginWord = "hit",
+endWord = "cog",
+wordList = ["hot","dot","dog","lot","log","cog"]
+
+Output: 5
+
+Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
+return its length 5.
+Example 2:
+
+Input:
+beginWord = "hit"
+endWord = "cog"
+wordList = ["hot","dot","dog","lot","log"]
+
+Output: 0
+
+Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
+
+```
+
+## 解题方案
+
+> 思路 1
+
+tag可以算BFS,其实就是求shortest path的变体
+
+Reference from [kamyu104](https://github.com/kamyu104/LeetCode/blob/71e0ba555ee49befa01fcd9fc78c3528e2ab63a9/Python/word-ladder.py)
+
+```python
+class Solution(object):
+ def ladderLength(self, beginWord, endWord, wordList):
+ """
+ :type beginWord: str
+ :type endWord: str
+ :type wordList: List[str]
+ :rtype: int
+ """
+ distance, stack, visited, lookup = 0, [beginWord], set([beginWord]), set(wordList)
+ while stack:
+ next_stack = []
+ for word in stack:
+ if word == endWord:
+ return distance + 1
+ for i in range(len(word)):
+ for char in 'abcdefghijklmnopqrstuvwxyz':
+ trans_word = word[:i] + char + word[i+1:]
+ if trans_word not in visited and trans_word in lookup:
+ next_stack.append(trans_word)
+ visited.add(trans_word)
+ distance += 1
+ stack = next_stack
+ return 0
+```
diff --git a/docs/leetcode/python/128._Longest_Consecutive_Sequence.md b/docs/Leetcode_Solutions/Python/128._Longest_Consecutive_Sequence.md
similarity index 100%
rename from docs/leetcode/python/128._Longest_Consecutive_Sequence.md
rename to docs/Leetcode_Solutions/Python/128._Longest_Consecutive_Sequence.md
diff --git a/docs/leetcode/python/129._sum_root_to_leaf_numbers.md b/docs/Leetcode_Solutions/Python/129._sum_root_to_leaf_numbers.md
similarity index 100%
rename from docs/leetcode/python/129._sum_root_to_leaf_numbers.md
rename to docs/Leetcode_Solutions/Python/129._sum_root_to_leaf_numbers.md
diff --git a/docs/leetcode/python/130._surrounded_regions.md b/docs/Leetcode_Solutions/Python/130._surrounded_regions.md
similarity index 100%
rename from docs/leetcode/python/130._surrounded_regions.md
rename to docs/Leetcode_Solutions/Python/130._surrounded_regions.md
diff --git a/docs/leetcode/python/131._palindrome_partitioning.md b/docs/Leetcode_Solutions/Python/131._palindrome_partitioning.md
similarity index 100%
rename from docs/leetcode/python/131._palindrome_partitioning.md
rename to docs/Leetcode_Solutions/Python/131._palindrome_partitioning.md
diff --git a/docs/leetcode/python/133._clone_graph.md b/docs/Leetcode_Solutions/Python/133._clone_graph.md
similarity index 100%
rename from docs/leetcode/python/133._clone_graph.md
rename to docs/Leetcode_Solutions/Python/133._clone_graph.md
diff --git a/docs/Leetcode_Solutions/Python/134._Gas_Station.md b/docs/Leetcode_Solutions/Python/134._Gas_Station.md
new file mode 100644
index 000000000..dd8dafc25
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/134._Gas_Station.md
@@ -0,0 +1,170 @@
+# 134. Gas Station
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/gas-station/description/
+
+> 内容描述
+
+```
+There are N gas stations along a circular route, where the amount of gas at station i is gas[i].
+
+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.
+
+Return the starting gas station's index if you can travel around the circuit once in the clockwise direction, otherwise return -1.
+
+Note:
+
+If there exists a solution, it is guaranteed to be unique.
+Both input arrays are non-empty and have the same length.
+Each element in the input arrays is a non-negative integer.
+Example 1:
+
+Input:
+gas = [1,2,3,4,5]
+cost = [3,4,5,1,2]
+
+Output: 3
+
+Explanation:
+Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
+Travel to station 4. Your tank = 4 - 1 + 5 = 8
+Travel to station 0. Your tank = 8 - 2 + 1 = 7
+Travel to station 1. Your tank = 7 - 3 + 2 = 6
+Travel to station 2. Your tank = 6 - 4 + 3 = 5
+Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3.
+Therefore, return 3 as the starting index.
+Example 2:
+
+Input:
+gas = [2,3,4]
+cost = [3,4,3]
+
+Output: -1
+
+Explanation:
+You can't start at station 0 or 1, as there is not enough gas to travel to the next station.
+Let's start at station 2 and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
+Travel to station 0. Your tank = 4 - 3 + 2 = 3
+Travel to station 1. Your tank = 3 - 3 + 3 = 3
+You cannot travel back to station 2, as it requires 4 unit of gas but you only have 3.
+Therefore, you can't travel around the circuit once no matter where you start.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+
+开始想着有几个要点,
+
+1. 如果gas[i] < cost[i],那显然不行,返回-1
+2. 如果sum(gas) < sum(cost),显然也不行,返回-1
+
+根据要点1得到candidates,对里面的每一个元素进行判断,只要遇到行的立马返回对应idx
+
+但是最后一个case超时了
+
+
+```
+class Solution(object):
+ def canCompleteCircuit(self, gas, cost):
+ """
+ :type gas: List[int]
+ :type cost: List[int]
+ :rtype: int
+ """
+ n = len(gas)
+ if n == 1 and gas[0] >= cost[0]:
+ return 0
+ if sum(gas) < sum(cost):
+ return -1
+
+ def canTravel(idx):
+ tank = gas[idx]
+ tmp_idx1 = idx
+ tmp_idx2 = (idx + 1) % n
+ while tmp_idx2 != idx and tank - cost[tmp_idx1] >= 0:
+ tank = tank + gas[tmp_idx2] - cost[tmp_idx1]
+ tmp_idx1 = (tmp_idx1 + 1) % n
+ tmp_idx2 = (tmp_idx2 + 1) % n
+ if tank >= cost[tmp_idx1] and (tmp_idx1 + 1) % n == idx:
+ return True
+ return False
+
+ candidates = []
+ for i in range(n):
+ if gas[i] > cost[i]:
+ candidates.append(i)
+ for candidate in candidates:
+ if canTravel(candidate):
+ return candidate
+ return -1
+```
+
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+看完评论区,数学好是真的好啊,哈哈哈
+
+依然是两个要点:
+
+1. If car starts at A and can not reach B.
+Any station between A and B can not reach B.(B is the first station that A can not reach.)
+2. If the total number of gas is bigger than the total number of cost. There must be a solution.
+
+证明如下:
+```
+proof of property 1:
+
+Facts:
+
+1. A cannot reach B
+2. There are C1,C2, ..., Ck between A and B
+3. A can reach C1, C2, ..., Ck
+
+A ---> C1 ---> C2 ---> ... Ck ---> B
+
+Proof by contradiction:
+Assume: C1 can reach B
+A can reach C1 (by Fact3) & C1 can reach B => A can reach B (Contradict with Fact1 !)
+=> assumption is wrong, C1 cannot reach B
+Same proof could be applied to C2 ~ Ck
+=> any station between A and B that A can reach cannot reach B
+```
+
+```
+proof of property 2:
+
+If the gas is more than the cost in total, there must be some stations we have enough gas to go through them.
+Let's say they are green stations. So the other stations are red.
+The adjacent stations with same color can be joined together as one.
+Then there must be a red station that can be joined into a precedent green station unless there isn't any red station,
+because the total gas is more than the total cost.
+In other words, all of the stations will join into a green station at last.
+
+Approved
+```
+beats 100%
+
+```python
+class Solution(object):
+ def canCompleteCircuit(self, gas, cost):
+ """
+ :type gas: List[int]
+ :type cost: List[int]
+ :rtype: int
+ """
+ tank, start = 0, 0
+ for i in range(len(gas)):
+ tank += gas[i] - cost[i]
+ if tank < 0:
+ tank, start = 0, i + 1
+ return -1 if sum(gas) < sum(cost) else start
+```
diff --git a/docs/Leetcode_Solutions/Python/136._single_number.md b/docs/Leetcode_Solutions/Python/136._single_number.md
new file mode 100644
index 000000000..97778eaa8
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/136._single_number.md
@@ -0,0 +1,61 @@
+# 136. Single Number
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/single-number/description/
+
+> 内容描述
+
+```
+Given a non-empty 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?
+
+Example 1:
+
+Input: [2,2,1]
+Output: 1
+Example 2:
+
+Input: [4,1,2,1,2]
+Output: 4
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+位运算,终于要take it了
+
+非常常见的一道算法题,将所有数字进行异或操作即可。对于异或操作明确以下三点:
+
+- 一个整数与自己异或的结果是0
+- 一个整数与0异或的结果是自己
+- 异或操作满足交换律,即a^b=b^a
+
+Python的位操作:
+
+
+
+
+
+```python
+class Solution(object):
+ def singleNumber(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ res = nums[0]
+ for i in nums[1:]:
+ res ^= i
+ return res
+```
+
diff --git a/docs/Leetcode_Solutions/Python/137._Single_Number_II.md b/docs/Leetcode_Solutions/Python/137._Single_Number_II.md
new file mode 100644
index 000000000..9c26ff3a5
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/137._Single_Number_II.md
@@ -0,0 +1,85 @@
+# 137. Single Number II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/single-number-ii/description/
+
+> 内容描述
+
+```
+Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.
+
+Note:
+
+Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
+
+Example 1:
+
+Input: [2,2,3,2]
+Output: 3
+Example 2:
+
+Input: [0,1,0,1,0,1,99]
+Output: 99
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+一行,算出set和的三倍,然后减去总的sum,就是所求数字的2倍
+
+beats 100%
+```python
+class Solution(object):
+ def singleNumber(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ return int((3 * sum(set(nums)) - sum(nums)) // 2)
+```
+
+
+
+
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+参考文章:
+
+1. [[Leetcode]找到出现不同次数的数字(通用解法)](https://www.cnblogs.com/bjwu/p/9323808.html)
+2. [bron 【中文】简短又通俗的理解](https://leetcode.com/problems/single-number-ii/discuss/167343/topic)
+3. [leetcode-137-Single Number II-第二种解法](https://cloud.tencent.com/developer/article/1131945)
+
+```python
+class Solution(object):
+ def singleNumber(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ a = b = 0
+ for num in nums:
+ b = b ^ num & ~a
+ a = a ^ num & ~b
+ return a | b
+```
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/139._word_break.md b/docs/Leetcode_Solutions/Python/139._word_break.md
new file mode 100644
index 000000000..815737dec
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/139._word_break.md
@@ -0,0 +1,59 @@
+### 139. Word Break
+
+题目:
+
+
+
+难度:
+
+Medium
+
+
+
+```ok[i]``` tells whether ```s[:i]``` can be built.
+
+```python
+class Solution(object):
+ def wordBreak(self, s, wordDict):
+ """
+ :type s: str
+ :type wordDict: List[str]
+ :rtype: bool
+ """
+ ok = [True]
+ for i in range(1, len(s)+1):
+ ok += [any(ok[j] and s[j:i] in wordDict for j in range(i))]
+ return ok[-1]
+```
+
+但是往list里面加数据的方法有快有慢,下面是对比:
+```
+>>> from timeit import timeit
+>>> timeit('x.append(1)', 'x = []', number=10000000)
+1.9880003412529277
+>>> timeit('x += 1,', 'x = []', number=10000000)
+1.2676891852971721
+>>> timeit('x += [1]', 'x = []', number=10000000)
+3.361207239950204
+```
+因此我们可以将代码直接换成下面的格式
+```python
+ok += any(ok[j] and s[j:i] in wordDict for j in range(i)) # 会报错
+```
+但是这样会报错,TypeError: 'bool' object is not iterable,因此bool类型数据不能这样加,别的可以(list类型本身当然要注意哈)
+
+因此在这个例子中我们这样:
+```python
+class Solution(object):
+ def wordBreak(self, s, wordDict):
+ """
+ :type s: str
+ :type wordDict: List[str]
+ :rtype: bool
+ """
+ ok = [True]
+ for i in range(1, len(s)+1):
+ ok += any(ok[j] and s[j:i] in wordDict for j in range(i)),
+ return ok[-1]
+```
+代码里面的那个逗号构建了一个tuple,也会快一点
diff --git a/docs/leetcode/python/140._word_break_ii.md b/docs/Leetcode_Solutions/Python/140._word_break_ii.md
similarity index 100%
rename from docs/leetcode/python/140._word_break_ii.md
rename to docs/Leetcode_Solutions/Python/140._word_break_ii.md
diff --git a/docs/Leetcode_Solutions/Python/141._linked_list_cycle.md b/docs/Leetcode_Solutions/Python/141._linked_list_cycle.md
new file mode 100644
index 000000000..253257eef
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/141._linked_list_cycle.md
@@ -0,0 +1,75 @@
+# 141. Linked List Cycle
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/linked-list-cycle/description/
+
+> 内容描述
+
+```
+Given a linked list, determine if it has a cycle in it.
+
+Follow up:
+Can you solve it without using extra space?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+用个字典记录某个点是否被访问过,时间,空间复杂度都是O(n)
+
+beats 96.59%
+
+```python
+class Solution(object):
+ def hasCycle(self, head):
+ """
+ :type head: ListNode
+ :rtype: bool
+ """
+ if not head:
+ return False
+ lookup = {}
+ while head:
+ if head in lookup:
+ return True
+ lookup[head] = 1
+ head = head.next
+ return False
+```
+
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+快慢指针, beats 96.59%
+
+```python
+class Solution(object):
+ def hasCycle(self, head):
+ """
+ :type head: ListNode
+ :rtype: bool
+ """
+ slow = head
+ fast = head
+ while fast and fast.next:
+ slow = slow.next
+ fast = fast.next.next
+ if slow == fast:
+ return True
+ return False
+```
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/142_Linked_List_Cycle_II.md b/docs/Leetcode_Solutions/Python/142_Linked_List_Cycle_II.md
new file mode 100644
index 000000000..edf24e672
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/142_Linked_List_Cycle_II.md
@@ -0,0 +1,52 @@
+# 142. Linked List Cycle II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/linked-list-cycle-ii/description/
+
+> 内容描述
+
+```
+Given a linked list, return the node where the cycle begins. If there is no cycle, return null.
+
+Note: Do not modify the linked list.
+
+Follow up:
+Can you solve it without using extra space?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+直接快慢指针,跟141一样,。这里注意一下***while-else clause***的用法就行
+
+beats 99.81%
+
+```python
+class Solution(object):
+ def detectCycle(self, head):
+ """
+ :type head: ListNode
+ :rtype: bool
+ """
+ slow = fast = head
+ while fast and fast.next:
+ slow = slow.next
+ fast = fast.next.next
+ if slow == fast:
+ break
+ else:
+ return None
+ while head != slow:
+ slow = slow.next
+ head = head.next
+ return head
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/143._reorder_list.md b/docs/Leetcode_Solutions/Python/143._reorder_list.md
new file mode 100644
index 000000000..3bf56c53c
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/143._reorder_list.md
@@ -0,0 +1,133 @@
+# 143. Reorder List
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/reorder-list/description/
+
+> 内容描述
+
+```
+Given a singly linked list L: L0→L1→…→Ln-1→Ln,
+reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
+
+You may not modify the values in the list's nodes, only nodes itself may be changed.
+
+Example 1:
+
+Given 1->2->3->4, reorder it to 1->4->2->3.
+Example 2:
+
+Given 1->2->3->4->5, reorder it to 1->5->2->4->3.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+找到后半段反转后,再merge
+
+```python
+class Solution(object):
+ def reorderList(self, head):
+ """
+ :type head: ListNode
+ :rtype: void Do not return anything, modify head in-place instead.
+ """
+ if not head or not head.next or not head.next.next:
+ return
+
+ # calculate the length
+ n = 0
+ dummy1 = head
+ while dummy1:
+ n += 1
+ dummy1 = dummy1.next
+
+ # find the start point of the second half
+ m = n // 2 + 1
+ dummy2 = head
+ for i in range(m-1):
+ dummy2 = dummy2.next
+ dummy3 = dummy2.next
+ dummy2.next = None
+
+ # reverse second half
+ prev = None
+ while dummy3:
+ nxt = dummy3.next
+ dummy3.next = prev
+ prev = dummy3
+ dummy3= nxt
+
+ # merge two half
+ dummy4 = head
+ # print(head.next.next.val)
+ for i in range(n-m):
+ nxt_head = dummy4.next
+ nxt_prev = prev.next
+ dummy4.next = prev
+ prev.next = nxt_head
+ prev = nxt_prev
+ dummy4 = nxt_head
+```
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+取巧的办法是,用快慢指针找到后半段,这样不用计算链表长度
+
+找到中间节点,断开,把后半截linked list reverse,然后合并两段
+
+```python
+class Solution(object):
+ def reorderList(self, head):
+ """
+ :type head: ListNode
+ :rtype: void Do not return anything, modify head in-place instead.
+ """
+ if head == None or head.next == None or head.next.next == None:
+ return
+
+ slow = head
+ fast = head
+ prev = None
+
+ while fast and fast.next:
+ prev = slow
+ slow = slow.next
+ fast = fast.next.next
+ prev.next = None
+
+ slow = self.reverseList(slow)
+
+ cur = head
+ while cur.next:
+ nxt = cur.next
+ cur.next = slow
+ slow = slow.next
+ cur.next.next = nxt
+ cur = nxt
+ cur.next = slow
+
+ def reverseList(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ prev = None
+ cur = head
+ while cur:
+ nxt = cur.next
+ cur.next = prev
+ prev = cur
+ cur = nxt
+ return prev
+```
+
diff --git a/docs/leetcode/python/144._binary_tree_preorder_traversal.md b/docs/Leetcode_Solutions/Python/144._binary_tree_preorder_traversal.md
similarity index 96%
rename from docs/leetcode/python/144._binary_tree_preorder_traversal.md
rename to docs/Leetcode_Solutions/Python/144._binary_tree_preorder_traversal.md
index 8dd38e7fe..b81890681 100644
--- a/docs/leetcode/python/144._binary_tree_preorder_traversal.md
+++ b/docs/Leetcode_Solutions/Python/144._binary_tree_preorder_traversal.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/binary-tree-preorder-traversal
+* https://leetcode.com/problems/binary-tree-preorder-traversal/description/
> 内容描述
diff --git a/docs/leetcode/python/145._binary_tree_postorder_traversal.md b/docs/Leetcode_Solutions/Python/145._binary_tree_postorder_traversal.md
similarity index 96%
rename from docs/leetcode/python/145._binary_tree_postorder_traversal.md
rename to docs/Leetcode_Solutions/Python/145._binary_tree_postorder_traversal.md
index c62edbaf0..2729d4973 100644
--- a/docs/leetcode/python/145._binary_tree_postorder_traversal.md
+++ b/docs/Leetcode_Solutions/Python/145._binary_tree_postorder_traversal.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/binary-tree-postorder-traversal
+* https://leetcode.com/problems/binary-tree-postorder-traversal/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/146._LRU_Cache.md b/docs/Leetcode_Solutions/Python/146._LRU_Cache.md
new file mode 100644
index 000000000..2bdea0395
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/146._LRU_Cache.md
@@ -0,0 +1,158 @@
+# 146. LRU Cache
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/lru-cache/description/
+
+> 内容描述
+
+```
+Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and put.
+
+get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.
+put(key, value) - Set or insert the value if the key is not already present. When the cache reached its capacity, it should invalidate the least recently used item before inserting a new item.
+
+Follow up:
+Could you do both operations in O(1) time complexity?
+
+Example:
+
+LRUCache cache = new LRUCache( 2 /* capacity */ );
+
+cache.put(1, 1);
+cache.put(2, 2);
+cache.get(1); // returns 1
+cache.put(3, 3); // evicts key 2
+cache.get(2); // returns -1 (not found)
+cache.put(4, 4); // evicts key 1
+cache.get(1); // returns -1 (not found)
+cache.get(3); // returns 3
+cache.get(4); // returns 4
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(N)******
+
+
+LRU cache 相当于要维护一个跟时间顺序相关的数据结构
+
+那么能找到最早更新元素的数据结构有 queue,heap和LinkedList这几种
+
+1. 首先,我们需要能够快速的访问到指点的元素,这一点LinkedList要用O(n)遍历,但是我们可以通过一个字典来对应key和node的信息,这样就是O(1)了
+2. 其次,由于要随时插入和删除找到的node,双向链表 doubly LinkedList 显然更好一些
+
+然后我们可以开始想接下来的逻辑了
+
+1. LRU Cache里面维护一个cache字典对应key和node的信息,一个cap表示最大容量,一个双向链表,其中head.next是most recently的node,
+tail.prev是least recently的node(即容量满了被删除的那个node)
+2. 对于get方法
+ - 1. 如果key在cache字典中,说明node在链表中
+ - 根据key从cache字典中拿到对应的node,删除这个node,再重新插入这个node(插入逻辑包含了更新到最新的位置)
+ - 2. 如果不在直接返回 -1
+3. 对于put方法
+ - 1. 如果key在cache字典中,说明node在链表中
+ - 根据key从cache字典中拿到对应的node,删除这个node,再重新插入这个node(插入逻辑包含了更新到最新的位置)
+ - 2. 如果key不在cache字典中,说明是一个新的node
+ - 如果此时容量还没满的话:
+ - 生成新node,插入链表中,放入cache中
+ - 如果此时容量满了的话:
+ - 从链表中删除tail.prev,即least recently的node
+ - 从cache中删除这个node的信息
+ - 生成新node,插入链表中,放入cache中
+
+
+下面是AC代码,其中逻辑3中如果key不在cache字典中的代码可以优化,生成新node,插入链表中,放入cache中这一步是重复的
+
+beats 95.66%
+
+```python
+class Node(object):
+ def __init__(self, key, val):
+ self.key = key
+ self.val = val
+ self.next = None
+ self.prev = None
+
+
+class LRUCache(object):
+ def __init__(self, capacity):
+ """
+ :type capacity: int
+ """
+ self.cache = {}
+ self.cap = capacity
+ self.head = Node(None, None)
+ self.tail = Node(None, None)
+ self.head.next = self.tail
+ self.tail.prev = self.head
+
+
+ def remove(self, node):
+ n = node.next
+ p = node.prev
+ p.next = n
+ n.prev = p
+ node.next = None
+ node.prev = None
+
+
+ def insert(self, node):
+ n = self.head.next
+ self.head.next = node
+ node.next = n
+ n.prev = node
+ node.prev = self.head
+
+
+ def get(self, key):
+ """
+ :type key: int
+ :rtype: int
+ """
+ if key in self.cache:
+ node = self.cache[key]
+ self.remove(node)
+ self.insert(node)
+ return node.val
+ else:
+ return -1
+
+
+ def put(self, key, value):
+ """
+ :type key: int
+ :type value: int
+ :rtype: void
+ """
+ if key in self.cache:
+ node = self.cache[key]
+ node.val = value
+ self.remove(node)
+ self.insert(node)
+ else:
+ if len(self.cache) == self.cap:
+ delete_node = self.tail.prev
+ del self.cache[delete_node.key]
+ self.remove(delete_node)
+ node = Node(key, value)
+ self.insert(node)
+ self.cache[key] = node
+
+
+# Your LRUCache object will be instantiated and called as such:
+# obj = LRUCache(capacity)
+# param_1 = obj.get(key)
+# obj.put(key,value)
+```
+
+
+
+
+
+
diff --git a/docs/leetcode/python/147._insertion_sort_list.md b/docs/Leetcode_Solutions/Python/147._insertion_sort_list.md
similarity index 100%
rename from docs/leetcode/python/147._insertion_sort_list.md
rename to docs/Leetcode_Solutions/Python/147._insertion_sort_list.md
diff --git a/docs/leetcode/python/148._sort_list.md b/docs/Leetcode_Solutions/Python/148._sort_list.md
similarity index 100%
rename from docs/leetcode/python/148._sort_list.md
rename to docs/Leetcode_Solutions/Python/148._sort_list.md
diff --git a/docs/leetcode/python/150._evaluate_reverse_polish_notation.md b/docs/Leetcode_Solutions/Python/150._evaluate_reverse_polish_notation.md
similarity index 100%
rename from docs/leetcode/python/150._evaluate_reverse_polish_notation.md
rename to docs/Leetcode_Solutions/Python/150._evaluate_reverse_polish_notation.md
diff --git a/docs/leetcode/python/151._reverse_words_in_a_string.md b/docs/Leetcode_Solutions/Python/151._reverse_words_in_a_string.md
similarity index 100%
rename from docs/leetcode/python/151._reverse_words_in_a_string.md
rename to docs/Leetcode_Solutions/Python/151._reverse_words_in_a_string.md
diff --git a/docs/Leetcode_Solutions/Python/152._maximum_product_subarray.md b/docs/Leetcode_Solutions/Python/152._maximum_product_subarray.md
new file mode 100644
index 000000000..63d48ecda
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/152._maximum_product_subarray.md
@@ -0,0 +1,110 @@
+# 152. Maximum Product Subarray
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/maximum-product-subarray/description/
+
+> 内容描述
+
+```
+Given an integer array nums, find the contiguous subarray within an array (containing at least one number) which has the largest product.
+
+Example 1:
+
+Input: [2,3,-2,4]
+Output: 6
+Explanation: [2,3] has the largest product 6.
+Example 2:
+
+Input: [-2,0,-1]
+Output: 0
+Explanation: The result cannot be 2, because [-2,-1] is not a subarray.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+粗一看, 一股浓烈的DP气息飘来,想要套用53题的思路和方程。但是这个跟sum是不一样的,因为乘积可以正负正负的跳,这样的动归方程肯定是不对的
+
+dp[i] = max(dp[i-1] * a[i],a[i])
+
+举个例子 : [-2,3,-4]
+
+
+我猜想可不可以记录正的和负的,记录两个dp数组,因为刚才最小的可能突然就变成最大的了,比如刚才是```-7```,最小,现在```(-7)*(-3) = 21```可能就最大了
+
+最大值可能来源于最小值 -> 哲学般的句子
+
+beats 98.99%
+
+```python
+class Solution(object):
+ def maxProduct(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ maxdp = [nums[0]] * len(nums)
+ mindp = [nums[0]] * len(nums)
+
+ for i in range(1, len(nums)):
+ maxdp[i] = max(mindp[i-1]*nums[i], maxdp[i-1]*nums[i], nums[i])
+ mindp[i] = min(maxdp[i-1]*nums[i], mindp[i-1]*nums[i], nums[i])
+
+ return max(maxdp)
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+[寒神](https://leetcode.com/problems/maximum-product-subarray/discuss/183483/Easy-and-Concise-Python)的思路
+
+- Calculate prefix product in A.
+- Calculate suffix product in A.
+- Return the max.
+
+
+beats 99.93%
+
+```python
+class Solution(object):
+ def maxProduct(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ reverse = nums[::-1]
+ for i in range(1, len(nums)):
+ nums[i] *= nums[i-1] or 1
+ reverse[i] *= reverse[i-1] or 1
+ return max(nums + reverse)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/153._find_minimum_in_rotated_sorted_array.md b/docs/Leetcode_Solutions/Python/153._find_minimum_in_rotated_sorted_array.md
new file mode 100644
index 000000000..798beb50c
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/153._find_minimum_in_rotated_sorted_array.md
@@ -0,0 +1,103 @@
+# 153. Find Minimum in Rotated Sorted Array
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/description/
+
+> 内容描述
+
+```
+Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
+
+(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
+
+Find the minimum element.
+
+You may assume no duplicate exists in the array.
+
+Example 1:
+
+Input: [3,4,5,1,2]
+Output: 1
+Example 2:
+
+Input: [4,5,6,7,0,1,2]
+Output: 0
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(1)******
+
+python大法好,一行sb AC, beats 100%,可能测试用例大多数都是基本有序的吧
+
+```python
+class Solution(object):
+ def findMin(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ nums.sort()
+ return nums[0]
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+
+一遍遍历看有没有降序的时候,有立马返回那个值,到最后都没有就返回nums[0]
+
+30秒钟 Bug free,一遍AC, beats 100%
+
+```python
+class Solution(object):
+ def findMin(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ if len(nums) == 1:
+ return nums[0]
+ pivot = nums[0]
+ for i in range(1, len(nums)):
+ if nums[i] < pivot:
+ return nums[i]
+ pivot = nums[i]
+ return nums[0]
+```
+
+
+> 思路 3
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+
+二分法,思路看代码一目了然,[leetcode第33题](https://github.com/apachecn/awesome-algorithm/blob/master/docs/Leetcode_Solutions/Python/033._search_in_rotated_sorted_array.md)这道题很类似,我画了图的,可以看看
+
+beats 100%
+
+```python
+class Solution(object):
+ def findMin(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ l, r = 0, len(nums) - 1
+ while l <= r:
+ mid = l + ((r-l) >> 1)
+ if nums[mid] < nums[mid-1]:
+ return nums[mid]
+ elif nums[mid] < nums[l]:
+ r = mid - 1
+ elif nums[mid] > nums[r]:
+ l = mid + 1
+ else:
+ return nums[l]
+```
diff --git a/docs/Leetcode_Solutions/Python/154._Find_Minimum_in_Rotated_Sorted_Array_II.md b/docs/Leetcode_Solutions/Python/154._Find_Minimum_in_Rotated_Sorted_Array_II.md
new file mode 100644
index 000000000..234f1a035
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/154._Find_Minimum_in_Rotated_Sorted_Array_II.md
@@ -0,0 +1,146 @@
+# 154. Find Minimum in Rotated Sorted Array II
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/description/
+
+> 内容描述
+
+```
+Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
+
+(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
+
+Find the minimum element.
+
+The array may contain duplicates.
+
+Example 1:
+
+Input: [1,3,5]
+Output: 1
+Example 2:
+
+Input: [2,2,2,0,1]
+Output: 0
+Note:
+
+This is a follow up problem to Find Minimum in Rotated Sorted Array.
+Would allow duplicates affect the run-time complexity? How and why?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(1)******
+
+python大法好,一行sb AC, beats 100%,可能测试用例大多数都是基本有序的吧
+
+```python
+class Solution(object):
+ def findMin(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ nums.sort()
+ return nums[0]
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+跟第153题没啥区别,就先把重复元素去掉就行了
+
+2分钟 AC, beats 67.63%
+
+
+```python
+class Solution(object):
+ def findMin(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ lookup, new_nums = {}, []
+ for num in nums:
+ if num not in lookup:
+ lookup[num] = 1
+ new_nums.append(num)
+ if len(new_nums) == 1:
+ return new_nums[0]
+ pivot = new_nums[0]
+ for i in range(1, len(new_nums)):
+ if new_nums[i] < pivot:
+ return new_nums[i]
+ pivot = new_nums[i]
+ return new_nums[0]
+```
+
+> 思路 3
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+
+二分法,思路看代码一目了然,[leetcode第33题](https://github.com/apachecn/awesome-algorithm/blob/master/docs/Leetcode_Solutions/Python/033._search_in_rotated_sorted_array.md)这道题很类似,我画了图的,可以看看
+
+beats 100%
+
+```python
+class Solution(object):
+ def findMin(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ l, r = 0, len(nums) - 1
+ while l <= r:
+ mid = l + ((r-l) >> 1)
+ if nums[mid] < nums[mid-1]:
+ return nums[mid]
+ elif nums[mid] < nums[l]:
+ r = mid - 1
+ elif nums[mid] > nums[r]:
+ l = mid + 1
+ elif l != r and nums[l] == nums[r]:
+ l += 1
+ else:
+ return nums[l]
+```
+
+
+## Note
+
+```
+Would allow duplicates affect the run-time complexity? How and why?
+```
+
+回答:Duplicates will not affect run-time complexity, because we can also use binary search to handle duplicates, same time complexity
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/155._min_stack.md b/docs/Leetcode_Solutions/Python/155._min_stack.md
similarity index 100%
rename from docs/leetcode/python/155._min_stack.md
rename to docs/Leetcode_Solutions/Python/155._min_stack.md
diff --git a/docs/leetcode/python/157._Read_N_Characters_Given_Read4.md b/docs/Leetcode_Solutions/Python/157._Read_N_Characters_Given_Read4.md
similarity index 97%
rename from docs/leetcode/python/157._Read_N_Characters_Given_Read4.md
rename to docs/Leetcode_Solutions/Python/157._Read_N_Characters_Given_Read4.md
index e390ca0e3..447051ff7 100644
--- a/docs/leetcode/python/157._Read_N_Characters_Given_Read4.md
+++ b/docs/Leetcode_Solutions/Python/157._Read_N_Characters_Given_Read4.md
@@ -6,7 +6,7 @@
> 原题连接
-* https://leetcode.com/problems/read-n-characters-given-read4
+* https://leetcode.com/problems/read-n-characters-given-read4/description/
> 内容描述
diff --git a/docs/leetcode/python/158._Read_N_Characters_Given_Read4_II_-_Call_multiple_times.md b/docs/Leetcode_Solutions/Python/158._Read_N_Characters_Given_Read4_II_-_Call_multiple_times.md
similarity index 98%
rename from docs/leetcode/python/158._Read_N_Characters_Given_Read4_II_-_Call_multiple_times.md
rename to docs/Leetcode_Solutions/Python/158._Read_N_Characters_Given_Read4_II_-_Call_multiple_times.md
index a3826eafd..ec2c8cce8 100644
--- a/docs/leetcode/python/158._Read_N_Characters_Given_Read4_II_-_Call_multiple_times.md
+++ b/docs/Leetcode_Solutions/Python/158._Read_N_Characters_Given_Read4_II_-_Call_multiple_times.md
@@ -6,7 +6,7 @@
> 原题连接
-* https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times
+* https://leetcode.com/problems/read-n-characters-given-read4-ii-call-multiple-times/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/159._Longest_Substring_with_At_Most_Two_Distinct_Characters.md b/docs/Leetcode_Solutions/Python/159._Longest_Substring_with_At_Most_Two_Distinct_Characters.md
new file mode 100644
index 000000000..128abbe66
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/159._Longest_Substring_with_At_Most_Two_Distinct_Characters.md
@@ -0,0 +1,57 @@
+# 159. Longest Substring with At Most Two Distinct Characters
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/longest-substring-with-at-most-two-distinct-characters/description/
+
+> 内容描述
+
+```
+Given a string s , find the length of the longest substring t that contains at most 2 distinct characters.
+
+Example 1:
+
+Input: "eceba"
+Output: 3
+Explanation: t is "ece" which its length is 3.
+Example 2:
+
+Input: "ccaabbb"
+Output: 5
+Explanation: t is "aabbb" which its length is 5.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+```python
+class Solution(object):
+ def lengthOfLongestSubstringTwoDistinct(self, s):
+ """
+ :type s: str
+ :rtype: int
+ """
+ maps = {}
+ begin, end, counter, length = 0, 0, 0, 0
+ while end < len(s):
+ maps[s[end]] = maps.get(s[end], 0) + 1
+ if maps[s[end]] == 1:
+ counter += 1
+ end += 1 # end 永远指向下一个待处理的字符
+ while counter > 2:
+ maps[s[begin]] -= 1
+ if maps[s[begin]] == 0:
+ counter -= 1
+ begin += 1
+ length = max(length, end - begin) # 因此这里是```end - begin```而不是```end - begin + 1```
+ return length
+```
+
+
diff --git a/docs/leetcode/python/160._intersection_of_two_linked_lists.md b/docs/Leetcode_Solutions/Python/160._intersection_of_two_linked_lists.md
similarity index 100%
rename from docs/leetcode/python/160._intersection_of_two_linked_lists.md
rename to docs/Leetcode_Solutions/Python/160._intersection_of_two_linked_lists.md
diff --git a/docs/leetcode/python/162._find_peak_element.md b/docs/Leetcode_Solutions/Python/162._find_peak_element.md
similarity index 100%
rename from docs/leetcode/python/162._find_peak_element.md
rename to docs/Leetcode_Solutions/Python/162._find_peak_element.md
diff --git a/docs/leetcode/python/165._compare_version_numbers.md b/docs/Leetcode_Solutions/Python/165._compare_version_numbers.md
similarity index 100%
rename from docs/leetcode/python/165._compare_version_numbers.md
rename to docs/Leetcode_Solutions/Python/165._compare_version_numbers.md
diff --git a/docs/Leetcode_Solutions/Python/166._Fraction_to_Recurring_Decimal.md b/docs/Leetcode_Solutions/Python/166._Fraction_to_Recurring_Decimal.md
new file mode 100644
index 000000000..2045b3362
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/166._Fraction_to_Recurring_Decimal.md
@@ -0,0 +1,83 @@
+# 166. Fraction to Recurring Decimal
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/fraction-to-recurring-decimal/description/
+
+> 内容描述
+
+```
+Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.
+
+If the fractional part is repeating, enclose the repeating part in parentheses.
+
+Example 1:
+
+Input: numerator = 1, denominator = 2
+Output: "0.5"
+Example 2:
+
+Input: numerator = 2, denominator = 1
+Output: "2"
+Example 3:
+
+Input: numerator = 2, denominator = 3
+Output: "0.(6)"
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: hard to say****** - 空间复杂度: O(1)******
+
+
+- 先处理正负号
+- 再处理整数部分
+- 最后处理小数部分,利用字典来判断是否循环
+
+***note:对于小数处理部分,必须先进行将没有处理过的r加入到m中去***
+
+这是因为:
+```
+例如输入为4, 333
+如果我们将已经处理过的r加入到m中去的话,重复数字当次就被加入m中了,下一次循环判断的时候r肯定已经在里面了
+```
+
+
+```python
+class Solution(object):
+ def fractionToDecimal(self, numerator, denominator):
+ """
+ :type numerator: int
+ :type denominator: int
+ :rtype: str
+ """
+ if numerator == 0: # zero numerator
+ return '0'
+ res = ''
+ if numerator * denominator < 0: # determine the sign
+ res += '-'
+ numerator, denominator = abs(numerator), abs(denominator) # remove sign of operands
+ res += str(numerator / denominator) # append integer part
+ if numerator % denominator == 0: # in case no fractional part
+ return res
+ res += '.'
+ r = numerator % denominator
+ m = {}
+ while r: # simulate the division process
+ if r in m: # meet a known remainder
+ res = res[:m[r]] + '(' + res[m[r]:] + ')' # so we reach the end of the repeating part
+ break
+ m[r] = len(res) # if the remainder is first seen, remember next r/denominator index in res
+ r *= 10
+ res += str(r/denominator) # append the quotient digit
+ r %= denominator
+
+ return res
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/167._two_sum_ii_-_input_array_is_sorted.md b/docs/Leetcode_Solutions/Python/167._two_sum_ii_-_input_array_is_sorted.md
new file mode 100644
index 000000000..d4b46c407
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/167._two_sum_ii_-_input_array_is_sorted.md
@@ -0,0 +1,53 @@
+# 167. Two Sum II - Input array is sorted
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/description/
+
+> 内容描述
+
+```
+
+Given an array of integers that is already sorted in ascending order, 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.
+
+Note:
+
+Your returned answers (both index1 and index2) are not zero-based.
+You may assume that each input would have exactly one solution and you may not use the same element twice.
+Example:
+
+Input: numbers = [2,7,11,15], target = 9
+Output: [1,2]
+Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+二分法+双指针,beats 86.15%
+
+```python
+class Solution(object):
+ def twoSum(self, numbers, target):
+ """
+ :type numbers: List[int]
+ :type target: int
+ :rtype: List[int]
+ """
+ l, r = 0, len(numbers) - 1
+ while l < r:
+ if numbers[l] + numbers[r] == target:
+ return [l+1, r+1]
+ elif numbers[l] + numbers[r] < target:
+ l += 1
+ else:
+ r -= 1
+```
diff --git a/docs/leetcode/python/168._excel_sheet_column_title.md b/docs/Leetcode_Solutions/Python/168._excel_sheet_column_title.md
similarity index 97%
rename from docs/leetcode/python/168._excel_sheet_column_title.md
rename to docs/Leetcode_Solutions/Python/168._excel_sheet_column_title.md
index 1746fa858..547f083ee 100644
--- a/docs/leetcode/python/168._excel_sheet_column_title.md
+++ b/docs/Leetcode_Solutions/Python/168._excel_sheet_column_title.md
@@ -12,17 +12,17 @@ Easy
依旧26进制的反击,不过这个反击我做的没之前那个好,看了hint
```
-class Solution(object):
- def convertToTitle(self, n):
- """
- :type n: int
- :rtype: str
- """
- ans = ''
- while n :
- ans = chr(ord('A') + (n - 1) % 26) + ans
- n = (n - 1) // 26
- return ans
+class Solution(object):
+ def convertToTitle(self, n):
+ """
+ :type n: int
+ :rtype: str
+ """
+ ans = ''
+ while n :
+ ans = chr(ord('A') + (n - 1) % 26) + ans
+ n = (n - 1) // 26
+ return ans
```
diff --git a/docs/Leetcode_Solutions/Python/169._majority_element.md b/docs/Leetcode_Solutions/Python/169._majority_element.md
new file mode 100644
index 000000000..867e23f78
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/169._majority_element.md
@@ -0,0 +1,87 @@
+# 169. Majority Element
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/majority-element/description/
+
+> 内容描述
+
+```
+Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.
+
+You may assume that the array is non-empty and the majority element always exist in the array.
+
+Example 1:
+
+Input: [3,2,3]
+Output: 3
+Example 2:
+
+Input: [2,2,1,1,1,2,2]
+Output: 2
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+字典记录出现次数,取次数最多对应的key即可
+
+beats 70%
+
+```python
+class Solution(object):
+ def majorityElement(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ lookup = {}
+ for num in nums:
+ lookup[num] = lookup.get(num, 0) + 1
+ max_occur = max(lookup.values())
+ for key in lookup:
+ if lookup[key] == max_occur:
+ return key
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+
+这个问题有一个很出名的算法
+
+
+Boyer-Moore众数(majority number) 问题
+
+在数组中找到两个不相同的元素并删除它们,不断重复此过程,直到数组中元素都相同,那么剩下的元素就是主要元素。
+
+这个算法的妙处在于不直接删除数组中的元素,而是利用一个计数变量.
+
+beats 88.66%
+
+```python
+class Solution(object):
+ def majorityElement(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ count, candidate = 0, None
+
+ for num in nums:
+ if count == 0:
+ candidate = num
+ count = count + 1 if num == candidate else count - 1
+ return candidate
+```
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/170._Two_Sum_III_-_Data_structure_design.md b/docs/Leetcode_Solutions/Python/170._Two_Sum_III_-_Data_structure_design.md
new file mode 100644
index 000000000..fb54c93ab
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/170._Two_Sum_III_-_Data_structure_design.md
@@ -0,0 +1,78 @@
+# 170. Two Sum III - Data structure design
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/two-sum-iii-data-structure-design/description/
+
+> 内容描述
+
+```
+Design and implement a TwoSum class. It should support the following operations: add and find.
+
+add - Add the number to an internal data structure.
+find - Find if there exists any pair of numbers which sum is equal to the value.
+
+Example 1:
+
+add(1); add(3); add(5);
+find(4) -> true
+find(7) -> false
+Example 2:
+
+add(3); add(1); add(2);
+find(3) -> true
+find(6) -> false
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+沿用第一题 Two um 的思想,beats 85.71%
+```python
+class TwoSum(object):
+
+ def __init__(self):
+ """
+ Initialize your data structure here.
+ """
+ self.lookup = {}
+ self.lst = []
+
+ def add(self, number):
+ """
+ Add the number to an internal data structure..
+ :type number: int
+ :rtype: void
+ """
+ self.lst.append(number)
+ self.lookup[number] = self.lookup.get(number, 0) + 1
+
+
+ def find(self, value):
+ """
+ Find if there exists any pair of numbers which sum is equal to the value.
+ :type value: int
+ :rtype: bool
+ """
+ for num in self.lst:
+ if value - num in self.lookup:
+ if value == 2 * num and self.lookup[num] >= 2:
+ return True
+ elif value != 2 * num:
+ return True
+
+ return False
+
+
+
+# Your TwoSum object will be instantiated and called as such:
+# obj = TwoSum()
+# obj.add(number)
+# param_2 = obj.find(value)
+```
diff --git a/docs/leetcode/python/171._excel_sheet_column_number.md b/docs/Leetcode_Solutions/Python/171._excel_sheet_column_number.md
similarity index 97%
rename from docs/leetcode/python/171._excel_sheet_column_number.md
rename to docs/Leetcode_Solutions/Python/171._excel_sheet_column_number.md
index 0a92b3808..4521f737c 100644
--- a/docs/leetcode/python/171._excel_sheet_column_number.md
+++ b/docs/Leetcode_Solutions/Python/171._excel_sheet_column_number.md
@@ -13,22 +13,22 @@ Easy
26进制的反击
```
-class Solution(object):
- def titleToNumber(self, s):
- """
- :type s: str
- :rtype: int
- """
- maps = {}
- for i in range(65,91):
- maps[chr(i)] = i - 64
-
- lst = list(s)
- lst.reverse()
- num = 0
- for idx,item in enumerate(lst):
- num += maps[item] * (26 ** idx)
- return num
+class Solution(object):
+ def titleToNumber(self, s):
+ """
+ :type s: str
+ :rtype: int
+ """
+ maps = {}
+ for i in range(65,91):
+ maps[chr(i)] = i - 64
+
+ lst = list(s)
+ lst.reverse()
+ num = 0
+ for idx,item in enumerate(lst):
+ num += maps[item] * (26 ** idx)
+ return num
```
diff --git a/docs/Leetcode_Solutions/Python/172._Factorial_Trailing_Zeroes.md b/docs/Leetcode_Solutions/Python/172._Factorial_Trailing_Zeroes.md
new file mode 100644
index 000000000..c7e98eefa
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/172._Factorial_Trailing_Zeroes.md
@@ -0,0 +1,58 @@
+# 172. Factorial Trailing Zeroes
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/factorial-trailing-zeroes/description/
+
+> 内容描述
+
+```
+Given an integer n, return the number of trailing zeroes in n!.
+
+Example 1:
+
+Input: 3
+Output: 0
+Explanation: 3! = 6, no trailing zero.
+Example 2:
+
+Input: 5
+Output: 1
+Explanation: 5! = 120, one trailing zero.
+Note: Your solution should be in logarithmic time complexity.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+思路就是开始看我们有多少个5,多少个25,多少个125,这些数字成为base,直到这个base比我们的n大了,我们就不继续加了。那这是为什么呢?
+
+因为我们知道想让后面多个0,那一定要是偶数乘以5的形式,我们知道偶数一定是比5多的,所以完全够用,所以直接一直加就行了。
+
+
+开始我还想复杂了,每次算出最前的base_val,即1有0个0,5有1个0,25有6个0,我是通过算出所在区间然后再叠加,这样显然可以,
+但是不如上面的想法来得直接来得快。
+
+前后想了一个小时,真蠢啊!!!
+
+```python
+class Solution(object):
+ def trailingZeroes(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ base, res = 5, 0
+ while n >= base:
+ res += n // base
+ base *= 5
+ return res
+```
+
+
diff --git a/docs/leetcode/python/173._binary_search_tree_iterator.md b/docs/Leetcode_Solutions/Python/173._binary_search_tree_iterator.md
similarity index 100%
rename from docs/leetcode/python/173._binary_search_tree_iterator.md
rename to docs/Leetcode_Solutions/Python/173._binary_search_tree_iterator.md
diff --git a/docs/Leetcode_Solutions/Python/174._dungeon_game.md b/docs/Leetcode_Solutions/Python/174._dungeon_game.md
new file mode 100644
index 000000000..8e01a33f0
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/174._dungeon_game.md
@@ -0,0 +1,82 @@
+# 174. Dungeon Game
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/dungeon-game/
+
+
+## 解题方案
+
+> 思路 1 :* 时间复杂度: O(MN)* -*空间复杂度: O(MN)*
+
+一道比较简单的动态规划题。仔细观察题目可发现,如果我们用dp[x][y]表示xy点到终点所需的最低血量,则可得
+```
+dp[x][y] = max(1, - dungeon[x][y] + min(dp[x+1][y], dp[x][y+1]))
+```
+(即右边即下边格子所需的血量加上当前格子造成的影响,由于任何时刻血量都需要大于0,所以最小值为1)
+
+从终点开始反向填出所有格子的值,dp[0][0]记录的即为答案。
+
+
+beats 33.46%
+```python
+class Solution(object):
+ def calculateMinimumHP(self, dungeon):
+ """
+ :type dungeon: List[List[int]]
+ :rtype: int
+ """
+ m, n = len(dungeon), len(dungeon[0])
+ dp = [[0 for i in range(n)] for j in range(m)]
+
+ dp[m-1][n-1] = max(-dungeon[m-1][n-1] + 1, 1)
+
+ for i in reversed(range(m)):
+ for j in reversed(range(n)):
+ tmp = []
+ if i+1 思路 2 :* 时间复杂度: O(MN)* -*空间复杂度: O(N)*
+
+观察上一种思路的dp公式可发现,对于dp表中的任意一格,只依赖它右边以下一行相同位置的格子,所以可以压缩整个dp表到一维从而达成线性空间复杂度。
+
+
+beats 38.13%
+```python
+class Solution(object):
+ def calculateMinimumHP(self, dungeon):
+ """
+ :type dungeon: List[List[int]]
+ :rtype: int
+ """
+ m, n = len(dungeon), len(dungeon[0])
+ dp = [0 for i in range(n)]
+
+ dp[n-1] = max(-dungeon[m-1][n-1] + 1, 1)
+
+ for i in reversed(range(m)):
+ for j in reversed(range(n)):
+ tmp = []
+ if i+1难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/second-highest-salary/description/
+
+> 内容描述
+
+```
+Write a SQL query to get the second highest salary from the Employee table.
+
++----+--------+
+| Id | Salary |
++----+--------+
+| 1 | 100 |
+| 2 | 200 |
+| 3 | 300 |
++----+--------+
+For example, given the above Employee table, the query should return 200 as the second highest salary. If there is no second highest salary, then the query should return null.
+
++---------------------+
+| SecondHighestSalary |
++---------------------+
+| 200 |
++---------------------+
+```
+
+## 解题方案
+
+> 思路 1
+
+```sql
+select Salary SecondHighestSalary from Employee
+union
+select null
+order by SecondHighestSalary desc limit 1, 1
+```
+
+
+> 思路 2
+
+```sql
+select (
+ select distinct Salary from Employee order by Salary Desc limit 1, 1
+)as SecondHighestSalary
+```
diff --git a/docs/leetcode/python/179._Largest_Number.md b/docs/Leetcode_Solutions/Python/179._Largest_Number.md
similarity index 100%
rename from docs/leetcode/python/179._Largest_Number.md
rename to docs/Leetcode_Solutions/Python/179._Largest_Number.md
diff --git a/docs/leetcode/python/182._duplicate_emails.md b/docs/Leetcode_Solutions/Python/182._duplicate_emails.md
similarity index 92%
rename from docs/leetcode/python/182._duplicate_emails.md
rename to docs/Leetcode_Solutions/Python/182._duplicate_emails.md
index 1e77debe3..f000e80cd 100644
--- a/docs/leetcode/python/182._duplicate_emails.md
+++ b/docs/Leetcode_Solutions/Python/182._duplicate_emails.md
@@ -7,7 +7,7 @@
> 原题连接
* https://leetcode.com/problems/duplicate-emails
-* https://leetcode-cn.com/problems/duplicate-emails
+* https://leetcode-cn.com/problems/duplicate-emails/description
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/188._Best_Time_to_Buy_and_Sell_Stock_IV.md b/docs/Leetcode_Solutions/Python/188._Best_Time_to_Buy_and_Sell_Stock_IV.md
new file mode 100644
index 000000000..2c31d099e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/188._Best_Time_to_Buy_and_Sell_Stock_IV.md
@@ -0,0 +1,165 @@
+# 188. Best Time to Buy and Sell Stock IV
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/
+
+> 内容描述
+
+```
+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 (i.e., you must sell the stock before you buy again).
+
+Example 1:
+
+Input: [3,3,5,0,0,3,1,4]
+Output: 6
+Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
+ Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.
+Example 2:
+
+Input: [1,2,3,4,5]
+Output: 4
+Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
+ Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
+ engaging multiple transactions at the same time. You must sell before buying again.
+Example 3:
+
+Input: [7,6,4,3,1]
+Output: 0
+Explanation: In this case, no transaction is done, i.e. max profit = 0.
+```
+
+## 解题方案
+
+参考[meng789987](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/discuss/135704/detail-explanation-of-dp-solution/150296)
+
+> 思路 1
+******- 时间复杂度: O(k*N^2)******- 空间复杂度: O(k*N)******
+
+dp[k][i]代表在第i天完成第k次交易的最大profit
+
+因此状态方程为dp[k][i] = max(dp[k][i-1], prices[i]-prices[j]+dp[k-1][j-1]),其中0 < j <= i
+
+意思就是在第i天完成第k次交易的最大profit就是,在```第i-1天完成第k次交易的最大profit```与
+```在j-1天完成前k-1次交易的最大profit(然后在第j天最后一次买入股票,并在第i天卖出)```两者中的最大值
+
+另外这里还有一个trick就是当K >= len(prices)//2 的时候,实际上就跟无限次交易一样了
+
+但是这样还是超时了
+
+```
+class Solution(object):
+ def maxProfit(self, k, prices):
+ """
+ :type k: int
+ :type prices: List[int]
+ :rtype: int
+ """
+ K = k
+ if K >= len(prices) // 2:
+ return sum([max(prices[i+1]-prices[i], 0) for i in range(len(prices)-1)])
+ if not prices or len(prices) == 0:
+ return 0
+ dp = [[0] * len(prices) for i in range(K+1)]
+ for k in range(1, K+1):
+ for i in range(1, len(prices)):
+ min_ = prices[0]
+ for j in range(1, i+1):
+ min_ = min(min_, prices[j]-dp[k-1][j-1])
+ dp[k][i] = max(dp[k][i-1], prices[i]-min_)
+ return dp[-1][-1]
+```
+
+
+> 思路 2
+******- 时间复杂度: O(k*N)******- 空间复杂度: O(k*N)******
+
+
+我们可以通过多加一个min_列表来记录prices[i]-prices[j]+dp[k-1][j-1],这样不用每次都重新计算1 <= j <= i的循环
+
+beats 61.47%
+
+```python
+class Solution(object):
+ def maxProfit(self, k, prices):
+ """
+ :type k: int
+ :type prices: List[int]
+ :rtype: int
+ """
+ K = k
+ if K >= len(prices) // 2:
+ return sum([max(prices[i+1]-prices[i], 0) for i in range(len(prices)-1)])
+ if not prices or len(prices) == 0:
+ return 0
+ dp, min_ = [[0] * len(prices) for i in range(K+1)], [prices[0]] * (K+1)
+ for i in range(1, len(prices)):
+ for k in range(1, K+1):
+ min_[k] = min(min_[k], prices[i]-dp[k-1][i-1])
+ dp[k][i] = max(dp[k][i-1], prices[i]-min_[k])
+ return dp[-1][-1]
+```
+
+
+
+> 思路 3
+******- 时间复杂度: O(k*N)******- 空间复杂度: O(k)******
+
+
+想想看,其实空间还可以压缩,那就是跟刚才思路1到思路2的改进思想一样,我们把dp[k][i]也全部记录下来,其中0 <= i <= len(prices),
+
+意思就是说现在的dp[k]就等于原来的min([dp[k][i] for i in range(0, len(prices)])
+
+beats 90.54%
+
+```python
+class Solution(object):
+ def maxProfit(self, k, prices):
+ """
+ :type k: int
+ :type prices: List[int]
+ :rtype: int
+ """
+ K = k
+ if K >= len(prices) // 2:
+ return sum([max(prices[i+1]-prices[i], 0) for i in range(len(prices)-1)])
+ if not prices or len(prices) == 0:
+ return 0
+ dp, min_ = [0] * (K+1), [prices[0]] * (K+1)
+ for i in range(1, len(prices)):
+ for k in range(1, K+1):
+ min_[k] = min(min_[k], prices[i]-dp[k-1])
+ dp[k] = max(dp[k], prices[i]-min_[k])
+ return dp[-1]
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/189._rotate_array.md b/docs/Leetcode_Solutions/Python/189._rotate_array.md
similarity index 95%
rename from docs/leetcode/python/189._rotate_array.md
rename to docs/Leetcode_Solutions/Python/189._rotate_array.md
index ff9d5457f..b00de8752 100644
--- a/docs/leetcode/python/189._rotate_array.md
+++ b/docs/Leetcode_Solutions/Python/189._rotate_array.md
@@ -1,42 +1,42 @@
-###189. Rotate Array
-
-题目:
-
-
-
-难度 : Easy
-
-首先,要知道一点,```k```如果大于```nums```的长度了,那么其实进行 ```k % len(nums)``` 次就行了
-
-其次,要注意```k 为0```的情况
-
-```python
-class Solution(object):
- def rotate(self, nums, k):
- """
- :type nums: List[int]
- :type k: int
- :rtype: void Do not return anything, modify nums in-place instead.
- """
- k = k % len(nums)
- if k != 0:
- tmp = nums[-k:]
- for j in range(len(nums)-1, k-1, -1):
- nums[j] = nums[j-k]
- nums[:k] = tmp
-```
-
-
-还有作弊大法,贼🐂批
-
-```python
-class Solution(object):
- def rotate(self, nums, k):
- """
- :type nums: List[int]
- :type k: int
- :rtype: void Do not return anything, modify nums in-place instead.
- """
- k %= len(nums)
- nums[:] = nums[-k:] + nums[:-k]
-```
+###189. Rotate Array
+
+题目:
+
+
+
+难度 : Easy
+
+首先,要知道一点,```k```如果大于```nums```的长度了,那么其实进行 ```k % len(nums)``` 次就行了
+
+其次,要注意```k 为0```的情况
+
+```python
+class Solution(object):
+ def rotate(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: void Do not return anything, modify nums in-place instead.
+ """
+ k = k % len(nums)
+ if k != 0:
+ tmp = nums[-k:]
+ for j in range(len(nums)-1, k-1, -1):
+ nums[j] = nums[j-k]
+ nums[:k] = tmp
+```
+
+
+还有作弊大法,贼🐂批
+
+```python
+class Solution(object):
+ def rotate(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: void Do not return anything, modify nums in-place instead.
+ """
+ k %= len(nums)
+ nums[:] = nums[-k:] + nums[:-k]
+```
diff --git a/docs/Leetcode_Solutions/Python/191._number_of_1_bits.md b/docs/Leetcode_Solutions/Python/191._number_of_1_bits.md
new file mode 100644
index 000000000..21f9fe02c
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/191._number_of_1_bits.md
@@ -0,0 +1,92 @@
+# 191. Number of 1 Bits
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/number-of-1-bits/description/
+
+> 内容描述
+
+```
+Write a function that takes an unsigned integer and returns the number of '1' bits it has (also known as the Hamming weight).
+
+Example 1:
+
+Input: 11
+Output: 3
+Explanation: Integer 11 has binary representation 00000000000000000000000000001011
+Example 2:
+
+Input: 128
+Output: 1
+Explanation: Integer 128 has binary representation 00000000000000000000000010000000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+
+转成二进制,数1的个数
+
+```python
+class Solution(object):
+ def hammingWeight(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ return bin(n).count('1')
+```
+
+> 思路 2
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+有wikipedia的题目 [Hamming Weight]((https://zh.wikipedia.org/wiki/汉明重量))
+
+
+
+用wikipedia的解法:
+
+原理是在于每次使用x & x-1 总会把低位的数字给置0
+
+比如
+```
+3 = 011 2 = 010 3 & 2 = 010 cnt = 1
+2 = 010 1 = 001 2 & 1 = 000 cnt = 2
+```
+
+比如
+```
+9 = 1001 8 = 1000 9&8 = 1000 cnt = 1
+8 = 1000 7 = 0111 8&7 = 0000 cnt = 2
+```
+
+> 减1操作将最右边的符号从0变到1,从1变到0,与操作将会移除最右端的1。如果最初X有N个1,那么经过N次这样的迭代运算,X将减到0。下面的算法就是根据这个原理实现的。
+
+所以关键点是每次都会把最右边的1变成0.
+
+
+
+AC代码
+
+
+
+```python
+class Solution(object):
+ def hammingWeight(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ cnt = 0
+ while n != 0:
+ n &= n - 1
+ cnt += 1
+ return cnt == 1
+```
+
diff --git a/docs/Leetcode_Solutions/Python/198._house_robber.md b/docs/Leetcode_Solutions/Python/198._house_robber.md
new file mode 100644
index 000000000..950868ea6
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/198._house_robber.md
@@ -0,0 +1,81 @@
+# 198. House Robber
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/house-robber/description/
+
+> 内容描述
+
+```
+You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
+
+Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.
+
+Example 1:
+
+Input: [1,2,3,1]
+Output: 4
+Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
+ Total amount you can rob = 1 + 3 = 4.
+Example 2:
+
+Input: [2,7,9,3,1]
+Output: 12
+Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
+ Total amount you can rob = 2 + 9 + 1 = 12.
+```
+
+## 解题方案
+
+> 思路 1
+
+
+状态转移方程:
+
+dp[i] = max(dp[i-1], dp[i-2] + nums[i])
+
+
+AC 代码
+
+```python
+class Solution(object):
+ def rob(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ n = len(nums)
+ if n == 0 : return 0
+ elif n == 1 : return nums[0]
+ elif n == 2 : return max(nums[0], nums[1])
+ else:
+ dp = [0 for i in range(n)]
+ dp[0] = nums[0]
+ dp[1] = max(nums[0],nums[1])
+ for i in range(2,n):
+ dp[i] = max(dp[i-1], dp[i-2] + nums[i])
+ return dp[n-1]
+```
+
+> 思路 2
+
+迭代
+
+```python
+class Solution(object):
+ def rob(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ last, now = 0, 0
+ for num in nums:
+ last, now = now, max(last+num, now)
+ return now
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/199._binary_tree_right_side_view.md b/docs/Leetcode_Solutions/Python/199._binary_tree_right_side_view.md
new file mode 100644
index 000000000..b697d7eb7
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/199._binary_tree_right_side_view.md
@@ -0,0 +1,62 @@
+# 199. Binary Tree Right Side View
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/binary-tree-right-side-view/description/
+
+> 内容描述
+
+```
+
+Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.
+
+Example:
+
+Input: [1,2,3,null,5,null,4]
+Output: [1, 3, 4]
+Explanation:
+
+ 1 <---
+ / \
+2 3 <---
+ \ \
+ 5 4 <---
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+还是在玩第102题,level order traversal. beats 100%
+
+```python
+class Solution(object):
+ def rightSideView(self, root):
+ """
+ :type root: TreeNode
+ :rtype: List[int]
+ """
+ if not root:
+ return []
+
+ res = []
+ cur_level = [root]
+ while cur_level:
+ next_level, tmp_res = [], []
+ for node in cur_level:
+ tmp_res.append(node.val)
+ if node.left:
+ next_level.append(node.left)
+ if node.right:
+ next_level.append(node.right)
+ res.append(tmp_res[-1])
+ cur_level = next_level
+ return res
+```
+
diff --git a/docs/Leetcode_Solutions/Python/200._number_of_islands.md b/docs/Leetcode_Solutions/Python/200._number_of_islands.md
new file mode 100644
index 000000000..fe0420dbd
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/200._number_of_islands.md
@@ -0,0 +1,59 @@
+# 200. Number of Islands
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/number-of-islands/description/
+
+> 内容描述
+
+```
+Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
+
+Example 1:
+
+Input:
+11110
+11010
+11000
+00000
+
+Output: 1
+Example 2:
+
+Input:
+11000
+11000
+00100
+00011
+
+Output: 3
+```
+
+## 解题方案
+
+> 思路 1
+
+厉害的解法:Sink and count the islands.
+
+就是说从(0,0)这个点开始,只要一碰到1就将我们最终island数加1,并且同时将其周围临近的所有1全部都变成0,这样后面就不会重复计算了
+
+```python
+class Solution(object):
+ def numIslands(self, grid):
+ """
+ :type grid: List[List[str]]
+ :rtype: int
+ """
+ def sink(i, j):
+ if 0 <= i < len(grid) and 0 <= j < len(grid[0]) and grid[i][j] == '1':
+ grid[i][j] = '0'
+ map(sink, (i+1, i-1, i, i), (j, j, j+1, j-1))
+ return 1
+ return 0
+ return sum(sink(i, j) for i in range(len(grid)) for j in range(len(grid[0])))
+```
+
diff --git a/docs/Leetcode_Solutions/Python/201._Bitwise_AND_of_Numbers_Range.md b/docs/Leetcode_Solutions/Python/201._Bitwise_AND_of_Numbers_Range.md
new file mode 100644
index 000000000..a7c1d4bb7
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/201._Bitwise_AND_of_Numbers_Range.md
@@ -0,0 +1,93 @@
+# 201. Bitwise AND of Numbers Range
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/bitwise-and-of-numbers-range/description/
+
+> 内容描述
+
+```
+Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers in this range, inclusive.
+
+Example 1:
+
+Input: [5,7]
+Output: 4
+Example 2:
+
+Input: [0,1]
+Output: 0
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+我们知道你从m一直&到n,那么m和n二进制位后面不一样的地方肯定都会变成0
+```
+譬如n = 101111,m = 101011,当中经过101100。
+m & n抹除common prefix右边第一位上的1,中间经过那个数抹除所有更低位的1。
+```
+所以我们找到m和n的最长相同前缀,然后补齐二进制的32位(即往右边贴'0')
+
+自己写的一行版本!
+
+
+```python
+import os
+class Solution(object):
+ def rangeBitwiseAnd(self, m, n):
+ """
+ :type m: int
+ :type n: int
+ :rtype: int
+ """
+ return int(os.path.commonprefix([bin(m)[2:].zfill(32), bin(n)[2:].zfill(32)])[::-1].zfill(32)[::-1], 2)
+```
+
+
+> 思路 2
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+
+别人的一行版本!
+
+
+```python
+class Solution(object):
+ def rangeBitwiseAnd(self, m, n):
+ """
+ :type m: int
+ :type n: int
+ :rtype: int
+ """
+ return self.rangeBitwiseAnd(m, n & n-1) if m < n else n
+```
+
+
+> 思路
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+
+bit移位操作版本
+
+```python
+class Solution(object):
+ def rangeBitwiseAnd(self, m, n):
+ """
+ :type m: int
+ :type n: int
+ :rtype: int
+ """
+ diff = 0
+ while m != n:
+ m >>= 1
+ n >>= 1
+ diff += 1
+ return m << diff
+```
diff --git a/docs/leetcode/python/203._remove_linked_list_elements.md b/docs/Leetcode_Solutions/Python/203._remove_linked_list_elements.md
similarity index 96%
rename from docs/leetcode/python/203._remove_linked_list_elements.md
rename to docs/Leetcode_Solutions/Python/203._remove_linked_list_elements.md
index 7dcb32ee2..15aa10efa 100644
--- a/docs/leetcode/python/203._remove_linked_list_elements.md
+++ b/docs/Leetcode_Solutions/Python/203._remove_linked_list_elements.md
@@ -13,26 +13,26 @@ AC代码如下:
-```
-class Solution(object):
- def removeElements(self, head, val):
- """
- :type head: ListNode
- :type val: int
- :rtype: ListNode
- """
- dummy = ListNode(-1)
- dummy.next = head
-
- cur = dummy
-
- while cur.next:
- if cur.next.val == val:
- cur.next = cur.next.next
- else:
- cur = cur.next
-
- return dummy.next
+```
+class Solution(object):
+ def removeElements(self, head, val):
+ """
+ :type head: ListNode
+ :type val: int
+ :rtype: ListNode
+ """
+ dummy = ListNode(-1)
+ dummy.next = head
+
+ cur = dummy
+
+ while cur.next:
+ if cur.next.val == val:
+ cur.next = cur.next.next
+ else:
+ cur = cur.next
+
+ return dummy.next
```
\ No newline at end of file
diff --git a/docs/leetcode/python/204._count_primes.md b/docs/Leetcode_Solutions/Python/204._count_primes.md
similarity index 100%
rename from docs/leetcode/python/204._count_primes.md
rename to docs/Leetcode_Solutions/Python/204._count_primes.md
diff --git a/docs/leetcode/python/205._isomorphic_strings.md b/docs/Leetcode_Solutions/Python/205._isomorphic_strings.md
similarity index 97%
rename from docs/leetcode/python/205._isomorphic_strings.md
rename to docs/Leetcode_Solutions/Python/205._isomorphic_strings.md
index 9e4b6f178..47b0ab772 100644
--- a/docs/leetcode/python/205._isomorphic_strings.md
+++ b/docs/Leetcode_Solutions/Python/205._isomorphic_strings.md
@@ -10,29 +10,29 @@
AC之法,用dictionary,因为限制,所以确保s 和 t 是isomorphic 同时 t 和 s 是
-```
-class Solution(object):
- def isIsomorphic(self, s, t):
- """
- :type s: str
- :type t: str
- :rtype: bool
- """
+```
+class Solution(object):
+ def isIsomorphic(self, s, t):
+ """
+ :type s: str
+ :type t: str
+ :rtype: bool
+ """
return self.iso(s,t) and self.iso(t,s)
-
- def iso(self,s, t):
- """
- :type s: str
- :type t: str
- :rtype: bool
- """
- mapx = {}
- for i in range(len(s)):
- if s[i] not in mapx:
- mapx[s[i]] = t[i]
- elif s[i] in mapx:
- if t[i] != mapx[s[i]]:
- return False
+
+ def iso(self,s, t):
+ """
+ :type s: str
+ :type t: str
+ :rtype: bool
+ """
+ mapx = {}
+ for i in range(len(s)):
+ if s[i] not in mapx:
+ mapx[s[i]] = t[i]
+ elif s[i] in mapx:
+ if t[i] != mapx[s[i]]:
+ return False
return True
diff --git a/docs/Leetcode_Solutions/Python/206._reverse_linked_list.md b/docs/Leetcode_Solutions/Python/206._reverse_linked_list.md
new file mode 100644
index 000000000..5c05edc02
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/206._reverse_linked_list.md
@@ -0,0 +1,95 @@
+# 206. Reverse Linked List
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/reverse-linked-list/description/
+
+> 内容描述
+
+```
+Reverse a singly linked list.
+
+Example:
+
+Input: 1->2->3->4->5->NULL
+Output: 5->4->3->2->1->NULL
+Follow up:
+
+A linked list can be reversed either iteratively or recursively. Could you implement both?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+用三个指针,分别指向prev,cur 和 nxt,然后loop一圈还算比较简单.
+
+
+```python
+class Solution(object):
+ def reverseList(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ prev = None
+ cur = head
+ while cur:
+ nxt = cur.next
+ cur.next = prev
+ prev = cur
+ cur = nxt
+ return prev
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+其实不用cur也可以
+
+```python
+class Solution(object):
+ def reverseList(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ if not head:
+ return head
+ prev = None
+ while head.next:
+ nxt = head.next
+ head.next = prev
+ prev = head
+ head = nxt
+ head.next = prev
+ return head
+```
+
+递归版本,可以再消化一下.
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+```python
+class Solution(object):
+ def reverseList(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ def helper(head, new_head):
+ if head:
+ nxt = head.next
+ head.next = new_head
+ return helper(nxt, head)
+ else:
+ return new_head
+
+ return helper(head, None)
+```
diff --git a/docs/Leetcode_Solutions/Python/207._course_schedule.md b/docs/Leetcode_Solutions/Python/207._course_schedule.md
new file mode 100644
index 000000000..53cd22db9
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/207._course_schedule.md
@@ -0,0 +1,91 @@
+# 207. Course Schedule
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/course-schedule/description/
+
+> 内容描述
+
+```
+There are a total of n courses you have to take, labeled from 0 to n-1.
+
+Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
+
+Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
+
+Example 1:
+
+Input: 2, [[1,0]]
+Output: true
+Explanation: There are a total of 2 courses to take.
+ To take course 1 you should have finished course 0. So it is possible.
+Example 2:
+
+Input: 2, [[1,0],[0,1]]
+Output: false
+Explanation: There are a total of 2 courses to take.
+ To take course 1 you should have finished course 0, and to take course 0 you should
+ also have finished course 1. So it is impossible.
+Note:
+
+The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
+You may assume that there are no duplicate edges in the input prerequisites.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(V+E)******- 空间复杂度: O(N)******
+
+[Topological sorting](https://www.geeksforgeeks.org/topological-sorting/) for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that for every directed edge uv, vertex u comes before v in the ordering. Topological Sorting for a graph is not possible if the graph is not a DAG.
+
+pre-requisite问题,只需要判断最终的topological结果长度与courses数目是否相等即可
+
+DFS 和 BFS都可以用来拓扑排序。
+
+beats 95.38%
+```python
+class Solution(object):
+ def canFinish(self, numCourses, prerequisites):
+ """
+ :type numCourses: int
+ :type prerequisites: List[List[int]]
+ :rtype: bool
+ """
+ graph = collections.defaultdict(list)
+ indegrees = [0] * numCourses
+
+ for course, pre in prerequisites:
+ graph[pre].append(course)
+ indegrees[course] += 1
+
+ return self.topologicalSort(graph, indegrees) == numCourses
+
+
+ def topologicalSort(self, graph, indegrees):
+ count = 0
+ queue = []
+ for i in range(len(indegrees)):
+ if indegrees[i] == 0:
+ queue.append(i)
+ while queue:
+ course = queue.pop()
+ count += 1
+ for i in graph[course]:
+ indegrees[i] -= 1
+ if indegrees[i] == 0:
+ queue.append(i)
+ return count
+```
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/208._implement_trie_(prefix_tree).md b/docs/Leetcode_Solutions/Python/208._implement_trie_(prefix_tree).md
similarity index 95%
rename from docs/leetcode/python/208._implement_trie_(prefix_tree).md
rename to docs/Leetcode_Solutions/Python/208._implement_trie_(prefix_tree).md
index a828b2fd5..8ee06db58 100644
--- a/docs/leetcode/python/208._implement_trie_(prefix_tree).md
+++ b/docs/Leetcode_Solutions/Python/208._implement_trie_(prefix_tree).md
@@ -1,89 +1,89 @@
-### 208. Implement Trie (Prefix Tree)
-
-题目:
-
-
-
-
-难度:
-
-Medium
-
-这个Python实现也太精美了吧,谷歌复写之
-
-然后还unlock了一个solution,to read
-
-Trie整个都需要 to read,精美,可爱😊
-
-
-
-
-```python
-class TrieNode(object):
- def __init__(self):
- """
- Initialize your data structure here.
- """
- self.childs = dict()
- self.isWord = False
-
-
-
-class Trie(object):
-
- def __init__(self):
- self.root = TrieNode()
-
- def insert(self, word):
- """
- Inserts a word into the trie.
- :type word: str
- :rtype: void
- """
- node = self.root
- for letter in word:
- child = node.childs.get(letter)
- if child is None:
- child = TrieNode()
- node.childs[letter] = child
- node = child
- node.isWord = True
-
- def search(self, word):
- """
- Returns if the word is in the trie.
- :type word: str
- :rtype: bool
- """
- node = self.root
- for i in word:
- child = node.childs.get(i)
- if child is None:
- return False
- node = child
- return node.isWord
-
-
- def startsWith(self, prefix):
- """
- Returns if there is any word in the trie
- that starts with the given prefix.
- :type prefix: str
- :rtype: bool
- """
- node = self.root
- for letter in prefix:
- child = node.childs.get(letter)
- if child is None:
- return False
- node = child
- return True
-
-
-# Your Trie object will be instantiated and called as such:
-# trie = Trie()
-# trie.insert("somestring")
-# trie.search("key")
-
-```
-
+### 208. Implement Trie (Prefix Tree)
+
+题目:
+
+
+
+
+难度:
+
+Medium
+
+这个Python实现也太精美了吧,谷歌复写之
+
+然后还unlock了一个solution,to read
+
+Trie整个都需要 to read,精美,可爱😊
+
+
+
+
+```python
+class TrieNode(object):
+ def __init__(self):
+ """
+ Initialize your data structure here.
+ """
+ self.childs = dict()
+ self.isWord = False
+
+
+
+class Trie(object):
+
+ def __init__(self):
+ self.root = TrieNode()
+
+ def insert(self, word):
+ """
+ Inserts a word into the trie.
+ :type word: str
+ :rtype: void
+ """
+ node = self.root
+ for letter in word:
+ child = node.childs.get(letter)
+ if child is None:
+ child = TrieNode()
+ node.childs[letter] = child
+ node = child
+ node.isWord = True
+
+ def search(self, word):
+ """
+ Returns if the word is in the trie.
+ :type word: str
+ :rtype: bool
+ """
+ node = self.root
+ for i in word:
+ child = node.childs.get(i)
+ if child is None:
+ return False
+ node = child
+ return node.isWord
+
+
+ def startsWith(self, prefix):
+ """
+ Returns if there is any word in the trie
+ that starts with the given prefix.
+ :type prefix: str
+ :rtype: bool
+ """
+ node = self.root
+ for letter in prefix:
+ child = node.childs.get(letter)
+ if child is None:
+ return False
+ node = child
+ return True
+
+
+# Your Trie object will be instantiated and called as such:
+# trie = Trie()
+# trie.insert("somestring")
+# trie.search("key")
+
+```
+
diff --git a/docs/Leetcode_Solutions/Python/209._Minimum_Size_Subarray_Sum.md b/docs/Leetcode_Solutions/Python/209._Minimum_Size_Subarray_Sum.md
new file mode 100644
index 000000000..da9f704c0
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/209._Minimum_Size_Subarray_Sum.md
@@ -0,0 +1,80 @@
+# 209. Minimum Size Subarray Sum
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-size-subarray-sum/description/
+
+> 内容描述
+
+```
+Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.
+
+Example:
+
+Input: s = 7, nums = [2,3,1,2,4,3]
+Output: 2
+Explanation: the subarray [4,3] has the minimal length under the problem constraint.
+Follow up:
+If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+双指针走起,beats 98.40%
+
+```python
+class Solution(object):
+ def minSubArrayLen(self, s, nums):
+ """
+ :type s: int
+ :type nums: List[int]
+ :rtype: int
+ """
+ start, end, sums, res = 0, 0, 0, sys.maxsize
+ while end < len(nums):
+ sums += nums[end]
+ end += 1
+ while sums >= s:
+ sums -= nums[start]
+ start += 1
+ res = min(res, end-start+1)
+ return res if res != sys.maxsize else 0
+```
+
+
+## Follow up:
+
+If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+思路参考[Approach #3](https://leetcode.com/problems/minimum-size-subarray-sum/solution/)
+
+```python
+from bisect import bisect_left
+class Solution(object):
+ def minSubArrayLen(self, s, nums):
+ """
+ :type s: int
+ :type nums: List[int]
+ :rtype: int
+ """
+ res = sys.maxsize
+ sums = [0] * (len(nums)+1)
+ for i in range(1, len(nums)+1):
+ sums[i] = sums[i-1] + nums[i-1] # Sum of first i elements
+ for i in range(1, len(nums)+1):
+ to_find = s + sums[i-1] # minimum subarray starting from index i to have sum greater than s
+ idx = bisect_left(sums, to_find)
+ if idx != len(sums):
+ res = min(res, idx-i+1)
+ return res if res != sys.maxsize else 0
+```
diff --git a/docs/Leetcode_Solutions/Python/210._course_schedule_ii.md b/docs/Leetcode_Solutions/Python/210._course_schedule_ii.md
new file mode 100644
index 000000000..296ad9bdc
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/210._course_schedule_ii.md
@@ -0,0 +1,89 @@
+# 210. Course Schedule II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/course-schedule-ii/description/
+
+> 内容描述
+
+```
+There are a total of n courses you have to take, labeled from 0 to n-1.
+
+Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
+
+Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.
+
+There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.
+
+Example 1:
+
+Input: 2, [[1,0]]
+Output: [0,1]
+Explanation: There are a total of 2 courses to take. To take course 1 you should have finished
+ course 0. So the correct course order is [0,1] .
+Example 2:
+
+Input: 4, [[1,0],[2,0],[3,1],[3,2]]
+Output: [0,1,2,3] or [0,2,1,3]
+Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both
+ courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0.
+ So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3] .
+Note:
+
+The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
+You may assume that there are no duplicate edges in the input prerequisites.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(V+E)******- 空间复杂度: O(N)******
+
+
+course schedule II 在I的基础上改了3行代码过了
+
+论代码可重用性的重要程度,beats 97.77%
+
+```python
+class Solution(object):
+ def findOrder(self, numCourses, prerequisites):
+ """
+ :type numCourses: int
+ :type prerequisites: List[List[int]]
+ :rtype: List[int]
+ """
+ graph = collections.defaultdict(list)
+ indegrees = [0] * numCourses
+
+ for course, pre in prerequisites:
+ graph[pre].append(course)
+ indegrees[course] += 1
+
+ count, stack = self.topologicalSort(graph, indegrees)
+ return stack if count == numCourses else []
+
+
+ def topologicalSort(self, graph, indegrees):
+ count = 0
+ queue = []
+ stack = []
+ for i in range(len(indegrees)):
+ if indegrees[i] == 0:
+ queue.append(i)
+ while queue:
+ course = queue.pop()
+ stack.append(course)
+ count += 1
+ for i in graph[course]:
+ indegrees[i] -= 1
+ if indegrees[i] == 0:
+ queue.append(i)
+ return (count, stack)
+```
+
+
+
diff --git a/docs/leetcode/python/211._Add_and_Search_Word_-_Data_structure_design.md b/docs/Leetcode_Solutions/Python/211. Add and Search Word - Data structure design.md
similarity index 100%
rename from docs/leetcode/python/211._Add_and_Search_Word_-_Data_structure_design.md
rename to docs/Leetcode_Solutions/Python/211. Add and Search Word - Data structure design.md
diff --git a/docs/leetcode/python/213._house_robber_ii.md b/docs/Leetcode_Solutions/Python/213._house_robber_ii.md
similarity index 100%
rename from docs/leetcode/python/213._house_robber_ii.md
rename to docs/Leetcode_Solutions/Python/213._house_robber_ii.md
diff --git a/docs/Leetcode_Solutions/Python/215._Kth_Largest_Element_in_an_Array.md b/docs/Leetcode_Solutions/Python/215._Kth_Largest_Element_in_an_Array.md
new file mode 100644
index 000000000..2407389c9
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/215._Kth_Largest_Element_in_an_Array.md
@@ -0,0 +1,148 @@
+# 215. Kth Largest Element in an Array
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/kth-largest-element-in-an-array/description/
+
+> 内容描述
+
+```
+Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
+
+Example 1:
+
+Input: [3,2,1,5,6,4] and k = 2
+Output: 5
+Example 2:
+
+Input: [3,2,3,1,2,4,5,5,6] and k = 4
+Output: 4
+Note:
+You may assume k is always valid, 1 ≤ k ≤ array's length.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+先全部放到一个最大堆中去,然后返回第k个就行了
+
+因为python实现的heapq插入操作的时间复杂度是O(lgN),所以最终时间复杂度是O(NlgN)
+
+```
+1. bisect
+根据insort_left 的文档:
+
+Keep in mind that the O(log n) search is dominated by the slow O(n) insertion step.
+
+也就是说,单次 insort_left 的时间复杂度是 O(n),自然 sort1 的复杂度就变成了 O(n^2),它最慢是应当的。
+
+2. sort
+文档说是 O(n log n) 的复杂度。从 listsort 详细文档来看,开发人员着实没少下了工夫。
+
+3. heappush
+根据维基百科,插入操作的时间复杂度是 O(log n),所以总的时间复杂度仍然是 O(n log n)。不过有一点值得注意,插入操作的平均时间是 O(1),所以有可能会稍微快一点。
+
+Python vs. PyPy
+CPython 2.7
+
+sort1 : bisect 2.617674
+sort2 :lst.sort 0.295187
+sort3 : heapq 0.39279
+PyPy 2.4
+
+sort1 : bisect 1.31
+sort2 :lst.sort 0.043
+sort3 : heapq 0.029
+注,我把你的调用部分复制了一遍,执行了两次,结果为第二次的输出。
+
+可以看得出,O(n log n) 算法的耗时是在同一个数量级上的,但 CPython 中 sort 胜出,PyPy 中 heapq 胜出。
+```
+
+详细可见:
+1. [heapq数据结构](https://love.ranshy.com/heapq-%E5%A0%86%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/)
+2. [序列的sort方法 与 bisect.insort, heapq.heappush 效率比较](https://segmentfault.com/q/1010000000664272)
+
+
+```python
+class Solution(object):
+ def findKthLargest(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: int
+ """
+ from heapq import heappush, heappop
+ topk = []
+ heap = []
+ for i in range(len(nums)):
+ heappush(heap, -nums[i])
+ for i in range(k):
+ if i == k-1:
+ return -heappop(heap)
+ heappop(heap)
+```
+
+
+> 思路 2
+******- 时间复杂度: O(Nlgk)******- 空间复杂度: O(k)******
+
+前面的思路是全部放进去以后再pop k次
+
+现在打算只维护一个容量为k的最大堆,最终堆顶的值就是结果
+
+
+```python
+class Solution(object):
+ def findKthLargest(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: int
+ """
+ if not nums:
+ return 0
+ from heapq import *
+ heap = []
+ for i in range(len(nums)):
+ heappush(heap,nums[i])
+ if len(heap) > k:
+ heappop(heap)
+ return heap[0]
+```
+
+
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(n)******
+
+二分+quick sort的思想,随机取一个pivot,大于小于等于它的分别放起来,然后看看大于它的有没有k个,没有就可能在等于或者小于里面
+
+二分是O(lgN),但是找大于小于等于是O(N),所以最终时间复杂度是O(N)
+
+```python
+class Solution(object):
+ def findKthLargest(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: int
+ """
+ pivot = nums[0]
+ smaller = [num for num in nums if num < pivot]
+ equal = [num for num in nums if num == pivot]
+ greater = [num for num in nums if num > pivot]
+
+ if len(greater) >= k:
+ return self.findKthLargest(greater, k) #k may be there
+ elif len(equal) >= (k - len(greater)): # k may be in equal or smaller
+ return equal[0] # any number from equal
+ else:
+ return self.findKthLargest(smaller, k - len(greater) - len(equal))
+```
+
diff --git a/docs/leetcode/python/216._combination_sum_iii.md b/docs/Leetcode_Solutions/Python/216._combination_sum_iii.md
similarity index 100%
rename from docs/leetcode/python/216._combination_sum_iii.md
rename to docs/Leetcode_Solutions/Python/216._combination_sum_iii.md
diff --git a/docs/leetcode/python/217._contains_duplicate.md b/docs/Leetcode_Solutions/Python/217._contains_duplicate.md
similarity index 100%
rename from docs/leetcode/python/217._contains_duplicate.md
rename to docs/Leetcode_Solutions/Python/217._contains_duplicate.md
diff --git a/docs/Leetcode_Solutions/Python/218._The_Skyline_Problem.md b/docs/Leetcode_Solutions/Python/218._The_Skyline_Problem.md
new file mode 100644
index 000000000..4c198c4f8
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/218._The_Skyline_Problem.md
@@ -0,0 +1,117 @@
+# 218. The Skyline Problem
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/the-skyline-problem/description/
+
+> 内容描述
+
+```
+A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), write a program to output the skyline formed by these buildings collectively (Figure B).
+```
+
+
+

+

+
+
+```
+Buildings Skyline Contour
+The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0.
+
+For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] .
+
+The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline. A key point is the left endpoint of a horizontal line segment. Note that the last key point, where the rightmost building ends, is merely used to mark the termination of the skyline, and always has zero height. Also, the ground in between any two adjacent buildings should be considered part of the skyline contour.
+
+For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ].
+
+Notes:
+
+The number of buildings in any input list is guaranteed to be in the range [0, 10000].
+The input list is already sorted in ascending order by the left x position Li.
+The output list must be sorted by the x position.
+There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...[2 3], [4 5], [7 5], [11 5], [12 7]...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...[2 3], [4 5], [12 7], ...]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+观察发现,skyline的points的横坐标一定是某个building的左边界或者右边界。
+
+开始,假设只有2个建筑物,拿出第一个buiding B1,我们先把它的左上顶点加进我们的output结果skyline中,然后继续拿下一个building B2,我们现在需要将B2的左上顶点对应的x coordinate与B1的右上顶点所对应的x coordinate做比较:
+
+- 如果前者小且B2的高度大于B1的高度,则我们将B2的左上顶点也加入skyline中去。
+- 如果前者小且B2的高度小于等于B1的高度,则忽略B2的左上顶点
+
+接下来考虑更多建筑物的情况,从左到右扫描,当我们遇到第一个楼的左边界时,把它push到一个heap中。如果后面扫描的楼的高度比heap中最高的楼还高,那么它的左上顶点一定会被加入到skyline中。当我们遇到一个building的右边界时,我们需要将其从heap中pop掉,如果heap中max height有变化,则push到结果中。
+
+参考[Brian Gordon的blog](https://briangordon.github.io/2014/08/the-skyline-problem.html)
+ 和 [Stefan大神的题解](https://leetcode.com/problems/the-skyline-problem/discuss/61194)
+
+#### 程序代码解释
+
+- liveBuildings代表(左上顶点已经被加入output中但右上顶点还没有做判断的building)的右上顶点的集合,形式为[(height, x-coordinate)…..]
+- skyline是output
+- 程序里面的这句代码```while idx < n and buildings[idx][0] == start:```是为了防止有左右坐标完全相同但是height不同的building的存在,it's not useless!!!
+- python里面的heapq模块如果有不懂的同学可以看看这个文章:[heapq](http://blog.csdn.net/calling_wisdom/article/details/41676133)
+
+
+```python
+class Solution(object):
+ def getSkyline(self, buildings):
+ """
+ :type buildings: List[List[int]]
+ :rtype: List[List[int]]
+ """
+ idx, n = 0, len(buildings)
+ liveBuildings, skyline = [], []
+ while idx < n or len(liveBuildings) > 0: # 只要所有的点没处理完就一直循环
+ # 如果没有liveBuildings或者当前building的左边界小于等于前面高度最高且右边界最大的liveBuilding的右边界
+ if len(liveBuildings) == 0 or (idx < n and buildings[idx][0] <= -liveBuildings[0][1]):
+ start = buildings[idx][0] # 当前building的左边界
+ while idx < n and buildings[idx][0] == start: # 只要当前building的左边界不变,就一直往堆里放
+ heapq.heappush(liveBuildings, [-buildings[idx][2], -buildings[idx][1]])
+ idx += 1
+ else: # 如果有liveBuildings且当前building的左边界大于前面高度最高且右边界最大的liveBuilding的右边界
+ start = -liveBuildings[0][1] # 前面高度最高且右边界最大的liveBuilding的右边界
+ # 只要还有liveBuilding,pop掉所有右边界较小(高度必然比start对应liveBuilding小)的liveBuilding
+ while len(liveBuildings) > 0 and -liveBuildings[0][1] <= start:
+ heapq.heappop(liveBuildings)
+ height = len(liveBuildings) and -liveBuildings[0][0]
+ if len(skyline) == 0 or skyline[-1][1] != height:
+ skyline.append([start, height])
+ return skyline
+```
+
+> 思路 2
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+另外还有一个超级6的大神的代码,但是今天我要赶报告,就只先贴代码了
+
+```python
+class Solution(object):
+ def getSkyline(self, buildings):
+ """
+ :type buildings: List[List[int]]
+ :rtype: List[List[int]]
+ """
+ events = sorted([(L, -H, R) for L, R, H in buildings] + list(set((R, 0, None) for L, R, H in buildings)))
+ #events = sorted(event for L, R, H in buildings for event in ((L, -H, R), (R, 0, None)))
+ res, hp = [[0, 0]], [(0, float("inf"))]
+ for x, negH, R in events:
+ while x >= hp[0][1]:
+ heapq.heappop(hp)
+ if negH: heapq.heappush(hp, (negH, R))
+ if res[-1][1] + hp[0][0]:
+ res += [x, -hp[0][0]],
+ return res[1:]
+```
+
+
+
diff --git a/docs/leetcode/python/219._contains_duplicate_ii.md b/docs/Leetcode_Solutions/Python/219._contains_duplicate_ii.md
similarity index 96%
rename from docs/leetcode/python/219._contains_duplicate_ii.md
rename to docs/Leetcode_Solutions/Python/219._contains_duplicate_ii.md
index 7ffcf2427..050dd932e 100644
--- a/docs/leetcode/python/219._contains_duplicate_ii.md
+++ b/docs/Leetcode_Solutions/Python/219._contains_duplicate_ii.md
@@ -1,99 +1,99 @@
-# 219. Contains Duplicate II
-**难度: 简单**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/contains-duplicate-ii/
-
-> 内容描述
-
-```
-Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.
-
-Example 1:
-
-Input: nums = [1,2,3,1], k = 3
-Output: true
-Example 2:
-
-Input: nums = [1,0,1,1], k = 1
-Output: true
-Example 3:
-
-Input: nums = [1,2,3,1,2,3], k = 2
-Output: false
-```
-
-## 解题方案
-
-> 思路 1
-
-
-这道题虽然看似简单,但是我还是经历几次失败
-
-第一次我打算用最粗暴的方法来做,直接 Time Limit Exceeded,代码如下:
-```
-class Solution(object):
- def containsNearbyDuplicate(self, nums, k):
- """
- :type nums: List[int]
- :type k: int
- :rtype: bool
- """
- if k == 0:
- return False
- if k >= len(nums):
- return len(nums) != len(set(nums))
- for i in range(len(nums)-k):
- for j in range(1, k+1):
- if nums[i] == nums[i+j]:
- return True
- for i in range(len(nums)-k, len(nums)):
- for j in range(i+1, len(nums)):
- if nums[i] == nums[j]:
- return True
- return False
-```
-然后我打算用第 217 题的方法来一遍,还是报 Time Limit Exceeded 这个错,代码如下L:
-```
-class Solution(object):
- def containsNearbyDuplicate(self, nums, k):
- """
- :type nums: List[int]
- :type k: int
- :rtype: bool
- """
- if k == 0:
- return False
- if k >= len(nums):
- return len(nums) != len(set(nums))
- for i in range(len(nums)-k):
- if len(nums[i:i+k+1]) != len(set(nums[i:i+k+1])):
- return True
- return len(nums[-k:]) != len(set(nums[-k:]))
-```
-
-终于我想到了用字典来存,这个元素还没出现过,就以 的形式存进字典里,如果 num 再次出现了,计算相邻距离,小于等于 k 则 return true,否则更新字典中元素的位置,
-
-
-```python
-class Solution(object):
- def containsNearbyDuplicate(self, nums, k):
- """
- :type nums: List[int]
- :type k: int
- :rtype: bool
- """
- lookup = {}
- for i in range(len(nums)):
- if nums[i] not in lookup:
- lookup[nums[i]] = i
- else:
- if i - lookup[nums[i]] <= k:
- return True
- else:
- lookup[nums[i]] = i
- return False
-```
+# 219. Contains Duplicate II
+**难度: 简单**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/contains-duplicate-ii/
+
+> 内容描述
+
+```
+Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.
+
+Example 1:
+
+Input: nums = [1,2,3,1], k = 3
+Output: true
+Example 2:
+
+Input: nums = [1,0,1,1], k = 1
+Output: true
+Example 3:
+
+Input: nums = [1,2,3,1,2,3], k = 2
+Output: false
+```
+
+## 解题方案
+
+> 思路 1
+
+
+这道题虽然看似简单,但是我还是经历几次失败
+
+第一次我打算用最粗暴的方法来做,直接 Time Limit Exceeded,代码如下:
+```
+class Solution(object):
+ def containsNearbyDuplicate(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: bool
+ """
+ if k == 0:
+ return False
+ if k >= len(nums):
+ return len(nums) != len(set(nums))
+ for i in range(len(nums)-k):
+ for j in range(1, k+1):
+ if nums[i] == nums[i+j]:
+ return True
+ for i in range(len(nums)-k, len(nums)):
+ for j in range(i+1, len(nums)):
+ if nums[i] == nums[j]:
+ return True
+ return False
+```
+然后我打算用第 217 题的方法来一遍,还是报 Time Limit Exceeded 这个错,代码如下L:
+```
+class Solution(object):
+ def containsNearbyDuplicate(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: bool
+ """
+ if k == 0:
+ return False
+ if k >= len(nums):
+ return len(nums) != len(set(nums))
+ for i in range(len(nums)-k):
+ if len(nums[i:i+k+1]) != len(set(nums[i:i+k+1])):
+ return True
+ return len(nums[-k:]) != len(set(nums[-k:]))
+```
+
+终于我想到了用字典来存,这个元素还没出现过,就以 的形式存进字典里,如果 num 再次出现了,计算相邻距离,小于等于 k 则 return true,否则更新字典中元素的位置,
+
+
+```python
+class Solution(object):
+ def containsNearbyDuplicate(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: bool
+ """
+ lookup = {}
+ for i in range(len(nums)):
+ if nums[i] not in lookup:
+ lookup[nums[i]] = i
+ else:
+ if i - lookup[nums[i]] <= k:
+ return True
+ else:
+ lookup[nums[i]] = i
+ return False
+```
diff --git a/docs/leetcode/python/221._maximal_square.md b/docs/Leetcode_Solutions/Python/221._maximal_square.md
similarity index 100%
rename from docs/leetcode/python/221._maximal_square.md
rename to docs/Leetcode_Solutions/Python/221._maximal_square.md
diff --git a/docs/leetcode/python/222._count_complete_tree_nodes.md b/docs/Leetcode_Solutions/Python/222._count_complete_tree_nodes.md
similarity index 100%
rename from docs/leetcode/python/222._count_complete_tree_nodes.md
rename to docs/Leetcode_Solutions/Python/222._count_complete_tree_nodes.md
diff --git a/docs/leetcode/python/223._rectangle_area.md b/docs/Leetcode_Solutions/Python/223._rectangle_area.md
similarity index 89%
rename from docs/leetcode/python/223._rectangle_area.md
rename to docs/Leetcode_Solutions/Python/223._rectangle_area.md
index 1f5dd34c5..90a69fa37 100644
--- a/docs/leetcode/python/223._rectangle_area.md
+++ b/docs/Leetcode_Solutions/Python/223._rectangle_area.md
@@ -1,51 +1,51 @@
-# 223. Rectangle Area
-**难度: 中等**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/rectangle-area
-
-> 内容描述
-
-```
-Find the total area covered by two rectilinear rectangles in a 2D plane.
-
-Each rectangle is defined by its bottom left corner and top right corner as shown in the figure.
-
-Rectangle Area
-
-Example:
-
-Input: A = -3, B = 0, C = 3, D = 4, E = 0, F = -1, G = 9, H = 2
-Output: 45
-Note:
-
-Assume that the total area is never beyond the maximum possible value of int.
-```
-
-## 解题方案
-
-> 思路 1
-
-sb题没什么好说的
-
-```python
-class Solution(object):
- def computeArea(self, A, B, C, D, E, F, G, H):
- """
- :type A: int
- :type B: int
- :type C: int
- :type D: int
- :type E: int
- :type F: int
- :type G: int
- :type H: int
- :rtype: int
- """
- return (C - A) * (D - B) + (H - F) * (G - E) - max(min(C, G) - max(A, E), 0) * max(min(D, H) - max(B, F), 0)
-```
-
-
+# 223. Rectangle Area
+**难度: 中等**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/rectangle-area/description/
+
+> 内容描述
+
+```
+Find the total area covered by two rectilinear rectangles in a 2D plane.
+
+Each rectangle is defined by its bottom left corner and top right corner as shown in the figure.
+
+Rectangle Area
+
+Example:
+
+Input: A = -3, B = 0, C = 3, D = 4, E = 0, F = -1, G = 9, H = 2
+Output: 45
+Note:
+
+Assume that the total area is never beyond the maximum possible value of int.
+```
+
+## 解题方案
+
+> 思路 1
+
+sb题没什么好说的
+
+```python
+class Solution(object):
+ def computeArea(self, A, B, C, D, E, F, G, H):
+ """
+ :type A: int
+ :type B: int
+ :type C: int
+ :type D: int
+ :type E: int
+ :type F: int
+ :type G: int
+ :type H: int
+ :rtype: int
+ """
+ return (C - A) * (D - B) + (H - F) * (G - E) - max(min(C, G) - max(A, E), 0) * max(min(D, H) - max(B, F), 0)
+```
+
+
diff --git a/docs/leetcode/python/224._Basic_Calculator.md b/docs/Leetcode_Solutions/Python/224. Basic Calculator .md
similarity index 100%
rename from docs/leetcode/python/224._Basic_Calculator.md
rename to docs/Leetcode_Solutions/Python/224. Basic Calculator .md
diff --git a/docs/leetcode/python/225._implement_stack_using_queues.md b/docs/Leetcode_Solutions/Python/225._implement_stack_using_queues.md
similarity index 99%
rename from docs/leetcode/python/225._implement_stack_using_queues.md
rename to docs/Leetcode_Solutions/Python/225._implement_stack_using_queues.md
index 9f61d9722..10a1ac200 100644
--- a/docs/leetcode/python/225._implement_stack_using_queues.md
+++ b/docs/Leetcode_Solutions/Python/225._implement_stack_using_queues.md
@@ -13,7 +13,7 @@ Easy
又到了作弊神预言Python的强项
-```
+```
class Stack(object):
def __init__(self):
"""
diff --git a/docs/Leetcode_Solutions/Python/226._invert_binary_tree.md b/docs/Leetcode_Solutions/Python/226._invert_binary_tree.md
new file mode 100644
index 000000000..afcb20bea
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/226._invert_binary_tree.md
@@ -0,0 +1,60 @@
+# 226. Invert Binary Tree
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/invert-binary-tree/description/
+
+> 内容描述
+
+```
+Invert a binary tree.
+
+Example:
+
+Input:
+
+ 4
+ / \
+ 2 7
+ / \ / \
+1 3 6 9
+Output:
+
+ 4
+ / \
+ 7 2
+ / \ / \
+9 6 3 1
+Trivia:
+This problem was inspired by this original tweet by Max Howell:
+
+Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so f*** off.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+典型的递归题
+
+
+```python
+class Solution(object):
+ def invertTree(self, root):
+ """
+ :type root: TreeNode
+ :rtype: TreeNode
+ """
+ if not root:
+ return root
+ root.left, root.right = root.right, root.left
+ self.invertTree(root.left)
+ self.invertTree(root.right)
+ return root
+```
+
diff --git a/docs/leetcode/python/227._basic_calculator_ii.md b/docs/Leetcode_Solutions/Python/227._basic_calculator_ii.md
similarity index 100%
rename from docs/leetcode/python/227._basic_calculator_ii.md
rename to docs/Leetcode_Solutions/Python/227._basic_calculator_ii.md
diff --git a/docs/leetcode/python/228._summary_ranges.md b/docs/Leetcode_Solutions/Python/228._summary_ranges.md
similarity index 96%
rename from docs/leetcode/python/228._summary_ranges.md
rename to docs/Leetcode_Solutions/Python/228._summary_ranges.md
index 27486605e..ce9dce0f9 100644
--- a/docs/leetcode/python/228._summary_ranges.md
+++ b/docs/Leetcode_Solutions/Python/228._summary_ranges.md
@@ -1,58 +1,58 @@
-### 228. Summary Ranges
-
-题目:
-
-
-
-难度:
-
-Medium
-
-
-Just collect the ranges, then format and return them.
-
-```python
-class Solution(object):
- def summaryRanges(self, nums):
- """
- :type nums: List[int]
- :rtype: List[str]
- """
- ranges = []
- for i in nums:
- if not ranges or i > ranges[-1][-1] + 1:
- ranges += [],
- ranges[-1][1:] = i,
- return ['->'.join(map(str, r)) for r in ranges]
-```
-About the commas :-)
-
-```
-ranges += [],
-r[1:] = n,
-```
-Why the trailing commas? Because it turns the right hand side into a tuple and I get the same effects as these more common alternatives:
-```
-ranges += [[]]
-or
-ranges.append([])
-
-r[1:] = [n]
-```
-Without the comma, …
-
-- ranges += [] wouldn’t add [] itself but only its elements, i.e., nothing.
-- r[1:] = n wouldn’t work, because my n is not an iterable.
-
-Why do it this way instead of the more common alternatives I showed above? Because it’s shorter and faster (according to tests I did a while back).
-
-写到这里可能又有疑问了🤔️,为什么不可以直接写```ranges[-1][1] = i```呢,当然是会报```IndexError: list assignment index out of range```错误啦,那为什么```ranges[-1][1:] = i,```可以呢?
-
-简单来说
-
-L1=L 与 L1=L[:]
-- L1和L 都是对同一个对象的引用(所谓绑定的意思)。
-- L[:] 是生成了一个和L不同的新的对象,L1 变为了L[:] 这个对象的引用。
-
-
-参考[stefan](https://leetcode.com/problems/summary-ranges/discuss/63193)
+### 228. Summary Ranges
+
+题目:
+
+
+
+难度:
+
+Medium
+
+
+Just collect the ranges, then format and return them.
+
+```python
+class Solution(object):
+ def summaryRanges(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: List[str]
+ """
+ ranges = []
+ for i in nums:
+ if not ranges or i > ranges[-1][-1] + 1:
+ ranges += [],
+ ranges[-1][1:] = i,
+ return ['->'.join(map(str, r)) for r in ranges]
+```
+About the commas :-)
+
+```
+ranges += [],
+r[1:] = n,
+```
+Why the trailing commas? Because it turns the right hand side into a tuple and I get the same effects as these more common alternatives:
+```
+ranges += [[]]
+or
+ranges.append([])
+
+r[1:] = [n]
+```
+Without the comma, …
+
+- ranges += [] wouldn’t add [] itself but only its elements, i.e., nothing.
+- r[1:] = n wouldn’t work, because my n is not an iterable.
+
+Why do it this way instead of the more common alternatives I showed above? Because it’s shorter and faster (according to tests I did a while back).
+
+写到这里可能又有疑问了🤔️,为什么不可以直接写```ranges[-1][1] = i```呢,当然是会报```IndexError: list assignment index out of range```错误啦,那为什么```ranges[-1][1:] = i,```可以呢?
+
+简单来说
+
+L1=L 与 L1=L[:]
+- L1和L 都是对同一个对象的引用(所谓绑定的意思)。
+- L[:] 是生成了一个和L不同的新的对象,L1 变为了L[:] 这个对象的引用。
+
+
+参考[stefan](https://leetcode.com/problems/summary-ranges/discuss/63193)
diff --git a/docs/Leetcode_Solutions/Python/229._majority_element_ii.md b/docs/Leetcode_Solutions/Python/229._majority_element_ii.md
new file mode 100644
index 000000000..83c2ee387
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/229._majority_element_ii.md
@@ -0,0 +1,86 @@
+# 229. Majority Element II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/majority-element-ii/description/
+
+> 内容描述
+
+```
+
+Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times.
+
+Note: The algorithm should run in linear time and in O(1) space.
+
+Example 1:
+
+Input: [3,2,3]
+Output: [3]
+Example 2:
+
+Input: [1,1,1,3,3,2,2,2]
+Output: [1,2]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+参考[oterman](https://leetcode.com/problems/majority-element-ii/discuss/174987/topic)
+
+摩尔投票升级版,超过n/3的数最多只能有两个;
+
+- 先选出两个候选人A,B,遍历数组,如果投A(等于A),则A的票数加1;如果投B,B的票数加1;
+- 如果A,B都不投(即与A,B都不相等),那么检查此时是否AB中候选人的票数是否为0,如果为0,则成为新的候选人;
+- 如果A,B两个人的票数都不为0,那么A,B两个候选人的票数均减1;
+- 遍历结束后选出两个候选人,但是这两个候选人是否满足>n/3,还需要再遍历一遍数组,找出两个候选人的具体票数
+
+beats 96.93%
+```python
+class Solution(object):
+ def majorityElement(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: List[int]
+ """
+ if not nums or len(nums) == 0:
+ return []
+ count1, count2, candidate1, candidate2 = 0, 0, nums[0], nums[0]
+ for num in nums:
+ if num == candidate1: # 投A
+ count1 += 1
+ continue
+ if num == candidate2: # 投B
+ count2 += 1
+ continue
+ # 此时A,B都不投,检查是否有票数为0情况,如果为0,则更新候选人
+ if count1 == 0:
+ candidate1 = num
+ count1 += 1
+ continue
+ if count2 == 0:
+ candidate2 = num
+ count2 += 1
+ continue
+ # 此时两个候选人的票数都大于1,且当前A和B都不投,那么A,B对应的票数都要--;
+ count1 -= 1
+ count2 -= 1
+ # 上一轮遍历找出了两个候选人,但是这两个候选人是否均满足票数大于N/3仍然没法确定,需要重新遍历,确定票数
+ count1, count2 = 0, 0
+ for num in nums:
+ if num == candidate1:
+ count1 += 1
+ elif num == candidate2:
+ count2 += 1
+ res = []
+ if count1 > len(nums) / 3:
+ res.append(candidate1)
+ if count2 > len(nums) / 3:
+ res.append(candidate2)
+ return res
+```
diff --git a/docs/Leetcode_Solutions/Python/230._kth_smallest_element_in_a_bst.md b/docs/Leetcode_Solutions/Python/230._kth_smallest_element_in_a_bst.md
new file mode 100644
index 000000000..3a14adb30
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/230._kth_smallest_element_in_a_bst.md
@@ -0,0 +1,113 @@
+# 230. Kth Smallest Element in a BST
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/kth-smallest-element-in-a-bst/description/
+
+> 内容描述
+
+```
+Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.
+
+Note:
+You may assume k is always valid, 1 ≤ k ≤ BST's total elements.
+
+Example 1:
+
+Input: root = [3,1,4,null,2], k = 1
+ 3
+ / \
+ 1 4
+ \
+ 2
+Output: 1
+Example 2:
+
+Input: root = [5,3,6,2,4,null,null,1], k = 3
+ 5
+ / \
+ 3 6
+ / \
+ 2 4
+ /
+ 1
+Output: 3
+Follow up:
+What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+跟昨天做的一道题类似,一上来就走取巧之路。
+
+InOrder排序,输出,当然也完全可以用昨天的binary tree iterator,入stack,出stack,直到输出第k位
+
+
+```python
+class Solution(object):
+ def kthSmallest(self, root, k):
+ """
+ :type root: TreeNode
+ :type k: int
+ :rtype: int
+ """
+ self.root = root
+ self.lst = []
+ self.inOrder(root)
+ return self.lst[k-1]
+
+ def inOrder(self, root):
+ if root == None:
+ return
+ self.inOrder(root.left)
+ self.lst.append(root.val)
+ self.inOrder(root.right)
+```
+
+> 思路 2
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+现在看到kth 就条件反射的想用divide & conquer, 扫root的左子树看nodes量,如果nodes数量是k-1,那么root就刚好是第k个,如果大于k > 左子树数量,扫右子树,同时更新root为root.right。
+
+看到的言论:
+
+> If we can change the BST node structure, We can add a new Integer to mark the number of element in the left sub-tree.
+
+when the node is not null.
+
+- if k == node.leftNum + 1, return node
+- if k > node.leftNum + 1, make k -= node.leftNum + 1, and then node = node.right
+- otherwise, node = node.left
+
+
+```python
+class Solution:
+ def kthSmallest(self, root, k):
+ """
+ :type root: TreeNode
+ :type k: int
+ :rtype: int
+ """
+ def count(node):
+ if not node:
+ return 0
+ return count(node.left) + count(node.right) + 1
+
+ if not root:
+ return None
+ left = count(root.left)
+ if left == k - 1:
+ return root.val
+ elif left > k - 1:
+ return self.kthSmallest(root.left, k)
+ else:
+ return self.kthSmallest(root.right, k - left - 1)
+```
diff --git a/docs/Leetcode_Solutions/Python/231. _Power_of_Two.md b/docs/Leetcode_Solutions/Python/231. _Power_of_Two.md
new file mode 100644
index 000000000..98fa21b8d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/231. _Power_of_Two.md
@@ -0,0 +1,110 @@
+# 231. Power of Two
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/power-of-two/description/
+
+> 内容描述
+
+```
+Given an integer, write a function to determine if it is a power of two.
+
+Example 1:
+
+Input: 1
+Output: true
+Explanation: 20 = 1
+Example 2:
+
+Input: 16
+Output: true
+Explanation: 24 = 16
+Example 3:
+
+Input: 218
+Output: false
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+
+
+power of two 那是这个数字的 binary 表示一定只有一个1
+
+套用以前的代码[leetcode191](https://github.com/apachecn/awesome-algorithm/blob/master/docs/Leetcode_Solutions/Python/191._number_of_1_bits.md)
+
+这样会超时
+
+```
+class Solution(object):
+ def isPowerOfTwo(self, n): # 此法超时
+ """
+ :type n: int
+ :rtype: bool
+ """
+ cnt = 0
+ while n != 0:
+ n &= n - 1
+ cnt += 1
+ return cnt == 1
+```
+
+> 思路 2
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+跟power of three一样递归,可以AC
+
+
+
+```python
+class Solution(object):
+ def isPowerOfTwo(self, n):
+ """
+ :type n: int
+ :rtype: bool
+ """
+ if n <= 0:
+ return False
+ if n == 1:
+ return True
+ if n % 2 == 0:
+ return self.isPowerOfTwo(n/2)
+ return False
+```
+
+
+
+
+> 思路 3
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+
+也是有[算法的wikipedia page](https://en.wikipedia.org/wiki/Power_of_two#Fast_algorithm_to_check_if_a_positive_number_is_a_power_of_two)
+
+> The [binary representation](https://en.wikipedia.org/wiki/Binary_numeral_system) of integers makes it possible to apply a very fast test to determine whether a given [positive integer](https://en.wikipedia.org/wiki/Positive_integer) *x* is a power of two:
+>
+> positive *x* is a power of two ⇔ (*x* & (*x* − 1)) is equal to zero.
+
+
+
+注意特殊case 0的处理
+
+```python
+class Solution(object):
+ def isPowerOfTwo(self, n):
+ """
+ :type n: int
+ :rtype: bool
+ """
+ return n & (n-1) == 0 if n != 0 else False
+```
+
+
+
diff --git a/docs/leetcode/python/232._implement_queue_using_stacks.md b/docs/Leetcode_Solutions/Python/232._implement_queue_using_stacks.md
similarity index 100%
rename from docs/leetcode/python/232._implement_queue_using_stacks.md
rename to docs/Leetcode_Solutions/Python/232._implement_queue_using_stacks.md
diff --git a/docs/leetcode/python/234._palindrome_linked_list.md b/docs/Leetcode_Solutions/Python/234._palindrome_linked_list.md
similarity index 100%
rename from docs/leetcode/python/234._palindrome_linked_list.md
rename to docs/Leetcode_Solutions/Python/234._palindrome_linked_list.md
diff --git a/docs/Leetcode_Solutions/Python/235._lowest_common_ancestor_of_a_binary_search_tree.md b/docs/Leetcode_Solutions/Python/235._lowest_common_ancestor_of_a_binary_search_tree.md
new file mode 100644
index 000000000..4e6a02622
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/235._lowest_common_ancestor_of_a_binary_search_tree.md
@@ -0,0 +1,71 @@
+# 235. Lowest Common Ancestor of a Binary Search Tree
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description/
+
+> 内容描述
+
+```
+Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
+
+According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
+
+Given binary search tree: root = [6,2,8,0,4,7,9,null,null,3,5]
+
+ _______6______
+ / \
+ ___2__ ___8__
+ / \ / \
+ 0 _4 7 9
+ / \
+ 3 5
+Example 1:
+
+Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
+Output: 6
+Explanation: The LCA of nodes 2 and 8 is 6.
+Example 2:
+
+Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
+Output: 2
+Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself
+ according to the LCA definition.
+Note:
+
+All of the nodes' values will be unique.
+p and q are different and both values will exist in the BST.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+- 两个node,一个大于root,一个小于root,那么它们必定在root两边,共同的ancestor是root
+- 两个node,都比node小,到左边去寻找,那么先找到那个必定是common ancestor
+- 两个node,都比node大,类似....
+
+
+
+```python
+class Solution(object):
+ def lowestCommonAncestor(self, root, p, q):
+ """
+ :type root: TreeNode
+ :type p: TreeNode
+ :type q: TreeNode
+ :rtype: TreeNode
+ """
+ if not root:
+ return root
+ if root.val > p.val and root.val > q.val:
+ return self.lowestCommonAncestor(root.left, p, q)
+ if root.val < p.val and root.val < q.val:
+ return self.lowestCommonAncestor(root.right, p, q)
+ return root
+```
diff --git a/docs/Leetcode_Solutions/Python/236._lowest_common_ancestor_of_a_binary_tree.md b/docs/Leetcode_Solutions/Python/236._lowest_common_ancestor_of_a_binary_tree.md
new file mode 100644
index 000000000..244969559
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/236._lowest_common_ancestor_of_a_binary_tree.md
@@ -0,0 +1,108 @@
+# 236. Lowest Common Ancestor of a Binary Tree
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/
+
+> 内容描述
+
+```
+Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
+
+According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
+
+Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]
+
+ _______3______
+ / \
+ ___5__ ___1__
+ / \ / \
+ 6 _2 0 8
+ / \
+ 7 4
+Example 1:
+
+Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
+Output: 3
+Explanation: The LCA of of nodes 5 and 1 is 3.
+Example 2:
+
+Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
+Output: 5
+Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself
+ according to the LCA definition.
+Note:
+
+All of the nodes' values will be unique.
+p and q are different and both values will exist in the binary tree.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+1. Find path from root to n1 and store it in a vector or array.
+2. Find path from root to n2 and store it in another vector or array.
+3. Traverse both paths till the values in arrays are same. Return the common element just before the mismatch.
+
+时间复杂度worst case 是O(N),空间is the same
+```python
+class Solution(object):
+ def lowestCommonAncestor(self, root, p, q):
+ """
+ :type root: TreeNode
+ :type p: TreeNode
+ :type q: TreeNode
+ :rtype: TreeNode
+ """
+ def findPath(root, path, node):
+ if not root:
+ return False
+ path.append(root)
+ if root == node:
+ return True
+ if (root.left and findPath(root.left, path, node)) or (root.right and findPath(root.right, path, node)):
+ return True
+ path.pop()
+ return False
+ path_p, path_q = [], []
+ if not findPath(root, path_p, p) or not findPath(root, path_q, q):
+ return -1
+ i = 0
+ while i < len(path_p) and i < len(path_q):
+ if path_p[i] != path_q[i]:
+ break
+ i += 1
+ return path_p[i-1]
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+看代码才是最容易懂的,直接看吧
+
+```python
+class Solution(object):
+ pathp, pathq = [], []
+ def lowestCommonAncestor(self, root, p, q):
+ """
+ :type root: TreeNode
+ :type p: TreeNode
+ :type q: TreeNode
+ :rtype: TreeNode
+ """
+ if not root or root == p or root == q:
+ return root
+ left = self.lowestCommonAncestor(root.left, p, q)
+ right = self.lowestCommonAncestor(root.right, p, q)
+ if left and right:
+ return root
+ return left or right
+```
diff --git a/docs/leetcode/python/237._delete_node_in_a_linked_list.md b/docs/Leetcode_Solutions/Python/237._delete_node_in_a_linked_list.md
similarity index 96%
rename from docs/leetcode/python/237._delete_node_in_a_linked_list.md
rename to docs/Leetcode_Solutions/Python/237._delete_node_in_a_linked_list.md
index cd8be88c9..d401e090d 100644
--- a/docs/leetcode/python/237._delete_node_in_a_linked_list.md
+++ b/docs/Leetcode_Solutions/Python/237._delete_node_in_a_linked_list.md
@@ -1,52 +1,52 @@
-### 237. Delete Node in a Linked List
-
-题目:
-
-
-
-难度:
-Easy
-
-
-
-这道题,第一感觉,像删链表一样来删,把所有的node val前移一个,但是有个问题,为什么tail那个node还是存在?哼(ˉ(∞)ˉ)唧..
-
-已经被解答:
-
-
-
-
-
-另外一个O(1)的办法更好,把后一个node的val移到待删这个节点,并且把node.next = node.next.next
-
-题目说了不会删最后一个点,所以node.next.next一定存在,所以直接让node的val等于它next的val,然后让node的next指向它的next的next,举个例子:
- 1->2->3->4->5->None,要删除第四个节点,就让4变成5,然后让第四个节点指向第五个节点的next,
-这样原来的第四个节点就不存在了,虽然原来的第五个节点仍然存在且指向None,变成了1->2->3->5->None-<5
-
-
-
-```python
-O(1)时间
-class Solution(object):
- def deleteNode(self, node):
- """
- :type node: ListNode
- :rtype: void Do not return anything, modify node in-place instead.
- """
- node.val = node.next.val
- node.next = node.next.next
-```
-```python
-O(n)时间
-class Solution(object):
- def deleteNode(self, node):
- """
- :type node: ListNode
- :rtype: void Do not return anything, modify node in-place instead.
- """
- while node.next:
- node.val = node.next.val
- prev, node = node, node.next
- # clear reference to tail
- prev.next = None
-```
+### 237. Delete Node in a Linked List
+
+题目:
+
+
+
+难度:
+Easy
+
+
+
+这道题,第一感觉,像删链表一样来删,把所有的node val前移一个,但是有个问题,为什么tail那个node还是存在?哼(ˉ(∞)ˉ)唧..
+
+已经被解答:
+
+
+
+
+
+另外一个O(1)的办法更好,把后一个node的val移到待删这个节点,并且把node.next = node.next.next
+
+题目说了不会删最后一个点,所以node.next.next一定存在,所以直接让node的val等于它next的val,然后让node的next指向它的next的next,举个例子:
+ 1->2->3->4->5->None,要删除第四个节点,就让4变成5,然后让第四个节点指向第五个节点的next,
+这样原来的第四个节点就不存在了,虽然原来的第五个节点仍然存在且指向None,变成了1->2->3->5->None-<5
+
+
+
+```python
+O(1)时间
+class Solution(object):
+ def deleteNode(self, node):
+ """
+ :type node: ListNode
+ :rtype: void Do not return anything, modify node in-place instead.
+ """
+ node.val = node.next.val
+ node.next = node.next.next
+```
+```python
+O(n)时间
+class Solution(object):
+ def deleteNode(self, node):
+ """
+ :type node: ListNode
+ :rtype: void Do not return anything, modify node in-place instead.
+ """
+ while node.next:
+ node.val = node.next.val
+ prev, node = node, node.next
+ # clear reference to tail
+ prev.next = None
+```
diff --git a/docs/leetcode/python/238._product_of_array_except_self.md b/docs/Leetcode_Solutions/Python/238._product_of_array_except_self.md
similarity index 100%
rename from docs/leetcode/python/238._product_of_array_except_self.md
rename to docs/Leetcode_Solutions/Python/238._product_of_array_except_self.md
diff --git a/docs/Leetcode_Solutions/Python/239._Sliding_Window_Maximum.md b/docs/Leetcode_Solutions/Python/239._Sliding_Window_Maximum.md
new file mode 100644
index 000000000..a2e5c3a74
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/239._Sliding_Window_Maximum.md
@@ -0,0 +1,128 @@
+# 239. Sliding Window Maximum
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/sliding-window-maximum/description/
+
+> 内容描述
+
+```
+Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Return the max sliding window.
+
+Example:
+
+Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3
+Output: [3,3,5,5,6,7]
+Explanation:
+
+Window position Max
+--------------- -----
+[1 3 -1] -3 5 3 6 7 3
+ 1 [3 -1 -3] 5 3 6 7 3
+ 1 3 [-1 -3 5] 3 6 7 5
+ 1 3 -1 [-3 5 3] 6 7 5
+ 1 3 -1 -3 [5 3 6] 7 6
+ 1 3 -1 -3 5 [3 6 7] 7
+Note:
+You may assume k is always valid, 1 ≤ k ≤ input array's size for non-empty array.
+
+Follow up:
+Could you solve it in linear time?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N*k)******- 空间复杂度: O(1)******
+
+就暴力啊,beats 17.25%
+
+```python
+class Solution(object):
+ def maxSlidingWindow(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: List[int]
+ """
+ if not nums or len(nums) == 0:
+ return []
+ res = []
+ for i in range(len(nums)-k+1):
+ res.append(max(nums[i:i+k]))
+ return res
+```
+
+
+## Follow up:
+
+Could you solve it in linear time?
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+直接用deque, 照搬大神解法
+
+```
+# First traversing through K in the nums and only adding maximum value's index to the deque.
+# Note: We are olny storing the index and not the value.
+# Now, Comparing the new value in the nums with the last index value from deque,
+# and if new valus is less, we don't need it
+
+# Here we will have deque with index of maximum element for the first subsequence of length k.
+
+# Now we will traverse from k to the end of array and do 4 things
+# 1. Appending left most indexed value to the result
+# 2. Checking if left most is still in the range of k (so it only allows valid sub sequence)
+# 3. Checking if right most indexed element in deque is less than the new element found, if yes we will remove it
+# 4. Append i at the end of the deque (Not: 3rd and 4th steps are similar to previous for loop)
+```
+
+
+beats 92.08%
+
+```python
+from collections import deque
+class Solution(object):
+ def maxSlidingWindow(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: List[int]
+ """
+ if not nums or len(nums) == 0:
+ return []
+ if k == 0:
+ return nums
+ deq, res = deque(), []
+
+ for i in range(k):
+ while len(deq) != 0:
+ if nums[i] > nums[deq[-1]]:
+ deq.pop()
+ else:
+ break
+ deq.append(i)
+
+ for i in range(k, len(nums)):
+ res.append(nums[deq[0]])
+ if deq[0] < i - k + 1:
+ deq.popleft()
+
+
+ while len(deq) != 0:
+ if nums[i] > nums[deq[-1]]:
+ deq.pop()
+ else:
+ break
+ deq.append(i)
+
+ res.append(nums[deq[0]])
+ return res
+```
+
+
diff --git a/docs/leetcode/python/240._search_a_2d_matrix_ii.md b/docs/Leetcode_Solutions/Python/240._search_a_2d_matrix_ii.md
similarity index 100%
rename from docs/leetcode/python/240._search_a_2d_matrix_ii.md
rename to docs/Leetcode_Solutions/Python/240._search_a_2d_matrix_ii.md
diff --git a/docs/leetcode/python/242._valid_anagram.md b/docs/Leetcode_Solutions/Python/242._valid_anagram.md
similarity index 100%
rename from docs/leetcode/python/242._valid_anagram.md
rename to docs/Leetcode_Solutions/Python/242._valid_anagram.md
diff --git a/docs/leetcode/python/249._Group_Shifted_Strings.md b/docs/Leetcode_Solutions/Python/249._Group_Shifted_Strings.md
similarity index 95%
rename from docs/leetcode/python/249._Group_Shifted_Strings.md
rename to docs/Leetcode_Solutions/Python/249._Group_Shifted_Strings.md
index 2c31ed30c..1ad1c478d 100644
--- a/docs/leetcode/python/249._Group_Shifted_Strings.md
+++ b/docs/Leetcode_Solutions/Python/249._Group_Shifted_Strings.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/group-shifted-strings
+* https://leetcode.com/problems/group-shifted-strings/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/251._Flatten_2D_Vector.md b/docs/Leetcode_Solutions/Python/251._Flatten_2D_Vector.md
new file mode 100644
index 000000000..4032191c8
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/251._Flatten_2D_Vector.md
@@ -0,0 +1,71 @@
+# 251. Flatten 2D Vector
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/flatten-2d-vector/discuss/67653/My-Python-Solution
+
+> 内容描述
+
+```
+Implement an iterator to flatten a 2d vector.
+
+Example:
+
+Input: 2d vector =
+[
+ [1,2],
+ [3],
+ [4,5,6]
+]
+Output: [1,2,3,4,5,6]
+Explanation: By calling next repeatedly until hasNext returns false,
+ the order of elements returned by next should be: [1,2,3,4,5,6].
+```
+
+## 解题方案
+
+> 思路 1
+
+
+```python
+class Vector2D(object):
+
+ def __init__(self, vec2d):
+ """
+ Initialize your data structure here.
+ :type vec2d: List[List[int]]
+ """
+ self.row = 0
+ self.col = 0
+ self.vec = vec2d
+
+
+ def next(self):
+ """
+ :rtype: int
+ """
+ res = self.vec[self.row][self.col]
+ self.col += 1
+ return res
+
+
+ def hasNext(self):
+ """
+ :rtype: bool
+ """
+ while self.row < len(self.vec):
+ if self.col < len(self.vec[self.row]):
+ return True
+ self.col = 0
+ self.row += 1
+ return False
+
+
+# Your Vector2D object will be instantiated and called as such:
+# i, v = Vector2D(vec2d), []
+# while i.hasNext(): v.append(i.next())
+```
diff --git a/docs/Leetcode_Solutions/Python/252._Meeting_Rooms.md b/docs/Leetcode_Solutions/Python/252._Meeting_Rooms.md
new file mode 100644
index 000000000..7f434db8d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/252._Meeting_Rooms.md
@@ -0,0 +1,50 @@
+# 252. Meeting Rooms
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/meeting-rooms/description/
+
+> 内容描述
+
+```
+Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), determine if a person could attend all meetings.
+
+Example 1:
+
+Input: [[0,30],[5,10],[15,20]]
+Output: false
+Example 2:
+
+Input: [[7,10],[2,4]]
+Output: true
+```
+
+## 解题方案
+
+> 思路 1
+
+
+排个序然后看看后面meeting的start会不会比前面meeting的end小,如果有立刻就返回False,全都没有那就返回True
+
+
+
+
+```python
+class Solution(object):
+ def canAttendMeetings(self, intervals):
+ """
+ :type intervals: List[Interval]
+ :rtype: bool
+ """
+ if not intervals or len(intervals) < 2:
+ return True
+ intervals = sorted(intervals, key=lambda x:(x.start, x.end))
+ for i in range(1, len(intervals)):
+ if intervals[i].start < intervals[i-1].end:
+ return False
+ return True
+```
diff --git a/docs/Leetcode_Solutions/Python/253._Meeting_Rooms_II.md b/docs/Leetcode_Solutions/Python/253._Meeting_Rooms_II.md
new file mode 100644
index 000000000..890a2f6d2
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/253._Meeting_Rooms_II.md
@@ -0,0 +1,69 @@
+# 253. Meeting Rooms II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/meeting-rooms-ii/description/
+
+> 内容描述
+
+```
+Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si < ei), find the minimum number of conference rooms required.
+
+Example 1:
+
+Input: [[0, 30],[5, 10],[15, 20]]
+Output: 2
+Example 2:
+
+Input: [[7,10],[2,4]]
+Output: 1
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+想象一下,现实生活中,先开始的会议还没结束前我们就又要开始一个会议的话,此时我们需要一个新的会议室
+
+如果前面一堆先开始的会议都先于我们的新会议开始之前结束了,我们不需要新会议室
+
+换句话说,如果前面一堆新开始的会议中结束最早的那个会议如果在新开始的会议之前结束了的话,我们不需要会议室
+
+
+所以我们的思路是,先按照会议开始的时间排序,然后维护一个会议结束时间的最小堆,堆顶就是前面结束最早的那个会议的结束时间
+
+那么对于一个新的会议出现时:
+- 如果堆顶元素比新会议的开始时间更小的话,我们不需要新会议室。同时因为后面出现的新会议的开始时间更大了,
+所以目前最先结束的会议永远不可能比后面新出现的会议的开始时间更大,因此我们可以pop目前最先结束的会议,即pop堆顶元素,并且将新会议的结束时间放进堆中
+- 如果堆顶元素比新会议的开始时间更大的话,我们知道我们需要一个新的会议室,此时直接将新会议的结束时间放进堆中
+
+最终堆的size就是我们需要的会议室数量
+
+```python
+from heapq import heappush, heappop
+class Solution(object):
+ def minMeetingRooms(self, intervals):
+ """
+ :type intervals: List[Interval]
+ :rtype: int
+ """
+ if not intervals:
+ return 0
+
+ intervals.sort(key = lambda x:x.start)
+ end = []
+ for it in intervals:
+ # if the first finished meeting m1 ends before the next meeting
+ # we can directly pop m1, because there is no need to add a new room
+ if end and end[0] <= it.start:
+ heappop(end)
+ heappush(end, it.end)
+
+ return len(end)
+```
diff --git a/docs/Leetcode_Solutions/Python/254._Factor_Combinations.md b/docs/Leetcode_Solutions/Python/254._Factor_Combinations.md
new file mode 100644
index 000000000..c3e0ff5ae
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/254._Factor_Combinations.md
@@ -0,0 +1,144 @@
+# 254. Factor Combinations
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/factor-combinations/description/
+
+> 内容描述
+
+```
+Numbers can be regarded as product of its factors. For example,
+
+8 = 2 x 2 x 2;
+ = 2 x 4.
+Write a function that takes an integer n and return all possible combinations of its factors.
+
+Note:
+
+You may assume that n is always positive.
+Factors should be greater than 1 and less than n.
+Example 1:
+
+Input: 1
+Output: []
+Example 2:
+
+Input: 37
+Output:[]
+Example 3:
+
+Input: 12
+Output:
+[
+ [2, 6],
+ [2, 2, 3],
+ [3, 4]
+]
+Example 4:
+
+Input: 32
+Output:
+[
+ [2, 16],
+ [2, 2, 8],
+ [2, 2, 2, 4],
+ [2, 2, 2, 2, 2],
+ [2, 4, 4],
+ [4, 8]
+]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+就每次遍历到sqrt(n)就够了,再往后面过去其实重复了, beats 62.6%
+
+```python
+class Solution(object):
+ def getFactors(self, n):
+ """
+ :type n: int
+ :rtype: List[List[int]]
+ """
+ from math import sqrt
+ if n < 4:
+ return []
+ res = []
+ for i in range(2, int(sqrt(n))+1):
+ if n % i == 0 and i <= n / i:
+ res.append([i]+[n/i])
+ for j in self.getFactors(n/i):
+ if j and i <= j[0]:
+ res.append([i]+j)
+ return res
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+想着用一下memorization会更快一点,果然beats 100%
+
+```python
+class Solution(object):
+ cache = {}
+ def getFactors(self, n):
+ """
+ :type n: int
+ :rtype: List[List[int]]
+ """
+ from math import sqrt
+ if n < 4:
+ return []
+ if n in self.cache:
+ return self.cache[n]
+ else:
+ res = []
+ for i in range(2, int(sqrt(n))+1):
+ if n % i == 0 and i <= n / i:
+ res.append([i]+[n/i])
+ for j in self.getFactors(n/i):
+ if j and i <= j[0]:
+ res.append([i]+j)
+ self.cache[n] = res
+ return res
+```
+
+
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+换个思路,每次都先直接append一个最大到res中,然后递归部分只增加一个更大的factor,但其实这种也不是很快,只beats 62.61,跟思路1一样一样的。
+
+一直觉得这种类似递归的算法看code最能理解了,我就不多说了,打球去了!
+
+
+```python
+class Solution(object):
+ def getFactors(self, n):
+ """
+ :type n: int
+ :rtype: List[List[int]]
+ """
+ def helper(n, prev):
+ # for each recursive part, at least append a larger factor
+ start = 2 if not prev else prev[-1]
+ for i in range(start, int(pow(n, 0.5))+1):
+ if n % i == 0:
+ helper(n/i, prev+[i])
+ if prev: # drectly append the cur largest factor
+ self.res.append(prev+[n])
+
+ self.res = []
+ helper(n, [])
+ return self.res
+```
diff --git a/docs/leetcode/python/255._Verify_Preorder_Sequence_in_Binary_Search_Tree.md b/docs/Leetcode_Solutions/Python/255._Verify_Preorder_Sequence_in_Binary_Search_Tree.md
similarity index 100%
rename from docs/leetcode/python/255._Verify_Preorder_Sequence_in_Binary_Search_Tree.md
rename to docs/Leetcode_Solutions/Python/255._Verify_Preorder_Sequence_in_Binary_Search_Tree.md
diff --git a/docs/leetcode/python/256._Paint_House.md b/docs/Leetcode_Solutions/Python/256. Paint House.md
similarity index 100%
rename from docs/leetcode/python/256._Paint_House.md
rename to docs/Leetcode_Solutions/Python/256. Paint House.md
diff --git a/docs/leetcode/python/257._binary_tree_paths.md b/docs/Leetcode_Solutions/Python/257._binary_tree_paths.md
similarity index 90%
rename from docs/leetcode/python/257._binary_tree_paths.md
rename to docs/Leetcode_Solutions/Python/257._binary_tree_paths.md
index ff642ec54..c1191e275 100644
--- a/docs/leetcode/python/257._binary_tree_paths.md
+++ b/docs/Leetcode_Solutions/Python/257._binary_tree_paths.md
@@ -1,83 +1,83 @@
-# 257. Binary Tree Paths
-**难度: 简单**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/binary-tree-paths
-
-> 内容描述
-
-```
-Given a binary tree, return all root-to-leaf paths.
-
-Note: A leaf is a node with no children.
-
-Example:
-
-Input:
-
- 1
- / \
-2 3
- \
- 5
-
-Output: ["1->2->5", "1->3"]
-
-Explanation: All root-to-leaf paths are: 1->2->5, 1->3
-```
-
-## 解题方案
-
-> 思路 1
-
-递归+DFS
-
-```python
-class Solution(object):
- def binaryTreePaths(self, root):
- """
- :type root: TreeNode
- :rtype: List[str]
- """
- def helper(node, cur_path):
- if not node.left and not node.right: ## 到leaf了
- res.append(cur_path+[node.val])
- return
- if node.left:
- helper(node.left, cur_path+[node.val])
- if node.right:
- helper(node.right, cur_path+[node.val])
-
- res = []
- if not root:
- return res
- helper(root, [])
-
- return ['->'.join([str(val) for val in path]) for path in res]
-```
-注意一点,很多人可能看到这里有好几次cur_path+[node.val],觉得干嘛不直接写在最开头了,事实是这样做的话cur_path就已经变化了,因为要执行完if node.left才去执行if node.right,此时cur_path就不是原来的cur_path了。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+# 257. Binary Tree Paths
+**难度: 简单**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/binary-tree-paths/description/
+
+> 内容描述
+
+```
+Given a binary tree, return all root-to-leaf paths.
+
+Note: A leaf is a node with no children.
+
+Example:
+
+Input:
+
+ 1
+ / \
+2 3
+ \
+ 5
+
+Output: ["1->2->5", "1->3"]
+
+Explanation: All root-to-leaf paths are: 1->2->5, 1->3
+```
+
+## 解题方案
+
+> 思路 1
+
+递归+DFS
+
+```python
+class Solution(object):
+ def binaryTreePaths(self, root):
+ """
+ :type root: TreeNode
+ :rtype: List[str]
+ """
+ def helper(node, cur_path):
+ if not node.left and not node.right: ## 到leaf了
+ res.append(cur_path+[node.val])
+ return
+ if node.left:
+ helper(node.left, cur_path+[node.val])
+ if node.right:
+ helper(node.right, cur_path+[node.val])
+
+ res = []
+ if not root:
+ return res
+ helper(root, [])
+
+ return ['->'.join([str(val) for val in path]) for path in res]
+```
+注意一点,很多人可能看到这里有好几次cur_path+[node.val],觉得干嘛不直接写在最开头了,事实是这样做的话cur_path就已经变化了,因为要执行完if node.left才去执行if node.right,此时cur_path就不是原来的cur_path了。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/258._Add_Digits.md b/docs/Leetcode_Solutions/Python/258_ Add_Digits.md
similarity index 100%
rename from docs/leetcode/python/258._Add_Digits.md
rename to docs/Leetcode_Solutions/Python/258_ Add_Digits.md
diff --git a/docs/leetcode/python/261._Graph_Valid_Tree.md b/docs/Leetcode_Solutions/Python/261. Graph Valid Tree.md
similarity index 100%
rename from docs/leetcode/python/261._Graph_Valid_Tree.md
rename to docs/Leetcode_Solutions/Python/261. Graph Valid Tree.md
diff --git a/docs/Leetcode_Solutions/Python/263._ugly_number.md b/docs/Leetcode_Solutions/Python/263._ugly_number.md
new file mode 100644
index 000000000..9b0304aad
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/263._ugly_number.md
@@ -0,0 +1,68 @@
+# 263. Ugly Number
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/ugly-number/description/
+
+> 内容描述
+
+```
+Write a program to check whether a given number is an ugly number.
+
+Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.
+
+Example 1:
+
+Input: 6
+Output: true
+Explanation: 6 = 2 × 3
+Example 2:
+
+Input: 8
+Output: true
+Explanation: 8 = 2 × 2 × 2
+Example 3:
+
+Input: 14
+Output: false
+Explanation: 14 is not ugly since it includes another prime factor 7.
+Note:
+
+1 is typically treated as an ugly number.
+Input is within the 32-bit signed integer range: [−231, 231 − 1].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+因为其prime factors 只包括 2, 3, 5,所以比如如果能被 2 整除, n = n / 2, 直到不能被2整除,然后同样对3,5检验,如果最终结果为1,那么就是ugly number,否则不过关
+
+
+注意一下边界条件,当num为0的时候,return一下False
+
+```python
+class Solution(object):
+ def isUgly(self, num):
+ """
+ :type num: int
+ :rtype: bool
+ """
+ if num <= 0:
+ return False
+ if num <= 3:
+ return True
+ while num % 2 == 0:
+ num = num / 2
+ while num % 3 == 0:
+ num = num / 3
+ while num % 5 == 0:
+ num = num / 5
+ return True if num == 1 else False
+```
+
diff --git a/docs/Leetcode_Solutions/Python/264._ugly_number_ii.md b/docs/Leetcode_Solutions/Python/264._ugly_number_ii.md
new file mode 100644
index 000000000..c316bbc37
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/264._ugly_number_ii.md
@@ -0,0 +1,97 @@
+# 264. Ugly Number II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/ugly-number-ii/description/
+
+> 内容描述
+
+```
+Write a program to find the n-th ugly number.
+
+Ugly numbers are positive numbers whose prime factors only include 2, 3, 5.
+
+Example:
+
+Input: n = 10
+Output: 12
+Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.
+Note:
+
+1 is typically treated as an ugly number.
+n does not exceed 1690.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+因为deque的popleft是O(1)的,所以最终也可以做到O(N)时间
+
+beats 61.72%
+
+```python
+class Solution(object):
+ def nthUglyNumber(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ if n == 1:
+ return 1
+ q2, q3, q5 = collections.deque([2]), collections.deque([3]), collections.deque([5])
+ while n > 1:
+ x = min(q2[0],q3[0],q5[0])
+ if x == q2[0]:
+ x = q2.popleft()
+ q2.append(2*x)
+ q3.append(3*x)
+ q5.append(5*x)
+ elif x == q3[0]:
+ x = q3.popleft()
+ q3.append(3*x)
+ q5.append(5*x)
+ else:
+ x = q5.popleft()
+ q5.append(5*x)
+ n -= 1
+ return x
+```
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+更简单的版本,参考[alexef大神](https://leetcode.com/problems/ugly-number-ii/discuss/69384/My-expressive-Python-solution)
+
+beats 94.32%
+
+```python
+class Solution(object):
+ def nthUglyNumber(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ ugly = [1]
+ i2, i3, i5 = 0, 0, 0
+ for i in range(n-1):
+ u2, u3, u5 = 2 * ugly[i2], 3 * ugly[i3], 5 * ugly[i5]
+ umin = min(u2, u3, u5)
+ if umin == u2:
+ i2 += 1
+ if umin == u3:
+ i3 += 1
+ if umin == u5:
+ i5 += 1
+ ugly.append(umin)
+ return ugly[-1]
+```
+
diff --git a/docs/leetcode/python/265._Paint_House_II.md b/docs/Leetcode_Solutions/Python/265. Paint House II.md
similarity index 100%
rename from docs/leetcode/python/265._Paint_House_II.md
rename to docs/Leetcode_Solutions/Python/265. Paint House II.md
diff --git a/docs/leetcode/python/266._Palindrome_Permutation.md b/docs/Leetcode_Solutions/Python/266. Palindrome Permutation.md
similarity index 100%
rename from docs/leetcode/python/266._Palindrome_Permutation.md
rename to docs/Leetcode_Solutions/Python/266. Palindrome Permutation.md
diff --git a/docs/leetcode/python/267._Palindrome_Permutation_II.md b/docs/Leetcode_Solutions/Python/267. Palindrome Permutation II.md
similarity index 100%
rename from docs/leetcode/python/267._Palindrome_Permutation_II.md
rename to docs/Leetcode_Solutions/Python/267. Palindrome Permutation II.md
diff --git a/docs/Leetcode_Solutions/Python/268._missing_number.md b/docs/Leetcode_Solutions/Python/268._missing_number.md
new file mode 100644
index 000000000..22c0e0f89
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/268._missing_number.md
@@ -0,0 +1,103 @@
+# 268. Missing Number
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/missing-number/description/
+
+> 内容描述
+
+```
+Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.
+
+Example 1:
+
+Input: [3,0,1]
+Output: 2
+Example 2:
+
+Input: [9,6,4,2,3,5,7,0,1]
+Output: 8
+Note:
+Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+
+
+等差数列前n项和减去数组之和,一行瞬秒
+```(注意题目input从0开始取值)```
+
+
+```python
+class Solution(object):
+ def missingNumber(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ return len(nums) * (len(nums) + 1) / 2 - sum(nums)
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+位运算(异或运算)
+
+
+
+```python
+class Solution(object):
+ def missingNumber(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ res = n = len(nums)
+ for i in range(n):
+ res ^= i
+ res ^= nums[i]
+ return res
+```
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+让每一个元素都放在正确的index上面,感谢微信上大神 Jay kay的思路,这样写只要给出的nums是非负的就行,应用性更强,
+但是这个代码还是无法用于[leetcode 41题:First missing positive](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/041._First_Missing_Positive.md)
+
+最后元素不等于其index的就是返回值
+
+```python
+class Solution(object):
+ def missingNumber(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ if not nums or len(nums) == 0:
+ return 0
+ if len(nums) == 1:
+ return 1 if nums[0] == 0 else 0
+ for i in range(len(nums)):
+ tmp = nums[i]
+ while tmp < len(nums) and nums[tmp] != tmp:
+ nums[tmp], tmp = tmp, nums[tmp]
+ for i in range(len(nums)):
+ if nums[i] != i:
+ return i
+ return len(nums)
+```
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/269._Alien_Dictionary.md b/docs/Leetcode_Solutions/Python/269._Alien_Dictionary.md
new file mode 100644
index 000000000..a88f2f2ad
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/269._Alien_Dictionary.md
@@ -0,0 +1,135 @@
+# 269. Alien Dictionary
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/alien-dictionary/description/
+
+> 内容描述
+
+```
+There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.
+
+Example 1:
+
+Input:
+[
+ "wrt",
+ "wrf",
+ "er",
+ "ett",
+ "rftt"
+]
+
+Output: "wertf"
+Example 2:
+
+Input:
+[
+ "z",
+ "x"
+]
+
+Output: "zx"
+Example 3:
+
+Input:
+[
+ "z",
+ "x",
+ "z"
+]
+
+Output: ""
+
+Explanation: The order is invalid, so return "".
+Note:
+
+You may assume all letters are in lowercase.
+You may assume that if a is a prefix of b, then a must appear before b in the given dictionary.
+If the order is invalid, return an empty string.
+There may be multiple valid order of letters, return any one of them is fine.
+```
+
+## 解题方案
+
+> 思路 1
+
+参考大神[seanmsha](https://leetcode.com/problems/alien-dictionary/discuss/156130/Python-Solution-with-Detailed-Explanation-(91))的思路
+
+
+```
+We want to build a DAG graph so that we can get a possible order that doesn't have any invalid dependencies. First we initialize all of the words with degree 0 (which means that they're the first value in sorted order). We compare every letter by adjacent words (word i and word i+1) Once we find a different letter, we know that the letter in word i+1 is greater than word i so it comes later. We add a degree to the letter in i+1 and add an entry to the letter in word i's dictionary/hashmap signifying that theres an arrow from the letter in word i to the letter in word i+1. We break the loop on the adjacent words because we already found out the reason why word i is before word i+1 (we only get information about at most 1 letter per word). Once we have our degree counts, we traverse the graph (similar to a BFS) from the nodes with degree 0. When we visit a node, we append it to the result string. We subtract one from all of the words repeatedly until all of the words have had degree 0 and have been added to the result string.
+In summary:
+
+1. Initialize all letters in words with degree 0
+
+2. For each word i and word i+1 where i+1 原题连接
-* https://leetcode.com/problems/closest-binary-search-tree-value
+* https://leetcode.com/problems/closest-binary-search-tree-value/description/
> 内容描述
diff --git a/docs/leetcode/python/276._Paint_Fence.md b/docs/Leetcode_Solutions/Python/276. Paint Fence.md
similarity index 100%
rename from docs/leetcode/python/276._Paint_Fence.md
rename to docs/Leetcode_Solutions/Python/276. Paint Fence.md
diff --git a/docs/Leetcode_Solutions/Python/277. Find the Celebrity.md b/docs/Leetcode_Solutions/Python/277. Find the Celebrity.md
new file mode 100644
index 000000000..1eb3cf29b
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/277. Find the Celebrity.md
@@ -0,0 +1,76 @@
+# 277. Find the Celebrity
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-the-celebrity/description/
+
+> 内容描述
+
+```
+Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist one celebrity. The definition of a celebrity is that all the other n - 1 people know him/her but he/she does not know any of them.
+
+Now you want to find out who the celebrity is or verify that there is not one. The only thing you are allowed to do is to ask questions like: "Hi, A. Do you know B?" to get information of whether A knows B. You need to find out the celebrity (or verify there is not one) by asking as few questions as possible (in the asymptotic sense).
+
+You are given a helper function bool knows(a, b) which tells you whether A knows B. Implement a function int findCelebrity(n), your function should minimize the number of calls to knows.
+
+Note: There will be exactly one celebrity if he/she is in the party. Return the celebrity's label if there is a celebrity in the party. If there is no celebrity, return -1.
+```
+
+## 解题方案
+
+> 思路 1
+
+celebrity 是 每个人都知道他,而他不认识任何别的人。
+
+如果用图来看,那就每个别的人都有箭头指向c,而c没有任何出去的箭头。
+
+O(N^2)的代码还是还是很容易想到的
+
+但是我们可以有提升,那么就是可以check `knows(a,b)`,如果 a knows b,那么可以排除a是celebrity,否则可以排除b是celebrity.
+
+最后还要确认一遍是否这个是真的celebrity
+
+
+
+总的思路就是说先假设0就是celebrity,然后我们依次遍历下去,第一个不认识cele的人new成为新的cele,因为new不认识原来的cele,并且我们知道如果有的cele的话,那么有且只能有一个cele,所以既然new不认识cele,那cele肯定不是真正的cele,所以目前先假设new是新的cele,继续判断下去。最后我们需要遍历再判断一遍,如果任意cele认识某人或者某人不认识cele的情况出现,就说明没有cele了。
+
+
+AC代码
+
+时间复杂度: O(n)
+空间复杂度: O(1)
+
+```python
+# The knows API is already defined for you.
+# @param a, person a
+# @param b, person b
+# @return a boolean, whether a knows b
+# def knows(a, b):
+
+class Solution(object):
+ def findCelebrity(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ if n == 0:
+ return -1
+ cele = 0
+ for i in range(1, n):
+ if not knows(i, cele):
+ cele = i
+ for i in range(n):
+ if cele != i:
+ if not knows(i, cele) or knows(cele, i):
+ return -1
+ return cele
+```
+
+
+
+
+
diff --git a/docs/leetcode/python/278._First_Bad_Version.md b/docs/Leetcode_Solutions/Python/278._First_Bad _Version.md
similarity index 100%
rename from docs/leetcode/python/278._First_Bad_Version.md
rename to docs/Leetcode_Solutions/Python/278._First_Bad _Version.md
diff --git a/docs/Leetcode_Solutions/Python/279._perfect_squares.md b/docs/Leetcode_Solutions/Python/279._perfect_squares.md
new file mode 100644
index 000000000..f4d8bd50f
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/279._perfect_squares.md
@@ -0,0 +1,116 @@
+
+### 279. Perfect Squares
+
+
+题目:
+
+
+
+难度:
+
+Medium
+
+### 思路一:
+DP, 状态转移方程:
+
+```dp[i] = min(dp[i], dp[i - j * j] + 1)```
+
+
+
+
+```python
+class Solution(object):
+ def numSquares(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ dp = [0] * (n+1)
+ for i in range(n+1):
+ dp[i] = i
+ j = 1
+ while j * j <= i:
+ dp[i] = min(dp[i], dp[i-j*j] + 1)
+ j += 1
+ return dp[-1]
+```
+但是这个方法贼慢,beats 12%, 有时候提交甚至会超时,有时候又不会。。。。因此想别的办法
+
+### 思路二:
+
+Static DP, beats 90.39%
+
+```python
+class Solution(object):
+ dp = [0]
+ def numSquares(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ while len(self.dp) <= n:
+ m = len(self.dp)
+ inf = float('inf')
+ i = 1
+ while i * i <= m:
+ inf = min(inf, self.dp[m-i*i] + 1)
+ i += 1
+ self.dp.append(inf)
+ return self.dp[n]
+```
+
+进一步简化可以写成:
+```python
+class Solution(object):
+ dp = [0]
+ def numSquares(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ while len(self.dp) <= n:
+ self.dp += min(self.dp[-j*j] + 1 for j in range(1, int(len(self.dp)**0.5+1))),
+ return self.dp[n]
+```
+这里有个问题现在还没搞明白,以后再好好想一下,写成```return self.dp[-1]```提交就失败,
+```
+Submission Result: Wrong Answer
+Input: 1024
+Output: 4
+Expected: 1
+```
+
+### 思路三:
+
+还是慢,有个数学方法, runtime beats 98.48%
+```python
+import math
+class Solution(object):
+ def numSquares(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ def isSquare(num):
+ tmp = int(math.sqrt(num))
+ return tmp * tmp == num
+ while n & 3 == 0: # n % 4 == 0
+ n >>= 2
+ if n & 7 == 7: # n % 8 == 7
+ return 4
+ if isSquare(n):
+ return 1
+ sqrt_n = int(math.sqrt(n))
+ for i in range(1, sqrt_n + 1):
+ if isSquare(n-i*i):
+ return 2
+ return 3
+```
+in order to understand, I suggest u read:
+
+here is the [Lagrange's Four Square theorem](https://en.wikipedia.org/wiki/Lagrange%27s_four-square_theorem
+) - Limit the result to <= 4:
+
+And this [article](http://www.alpertron.com.ar/4SQUARES.HTM), in which you can also find the way to present a number as a sum of four squares:
+
+
diff --git a/docs/Leetcode_Solutions/Python/280._Wiggle_Sort.md b/docs/Leetcode_Solutions/Python/280._Wiggle_Sort.md
new file mode 100644
index 000000000..13a97f476
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/280._Wiggle_Sort.md
@@ -0,0 +1,88 @@
+# 280. Wiggle Sort
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/wiggle-sort/description/
+
+> 内容描述
+
+```
+Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] <= nums[3]....
+
+Example:
+
+Input: nums = [3,5,2,1,6,4]
+Output: One possible answer is [3,5,1,6,2,4]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+
+
+想的是比如bubble sort或者任何简单的比较sort,只是放数字的时候是按这样的大小顺序放:
+
+1, n, 2, n-1,3, n-2….
+
+或者每个pass其实做两个sort,找出最大的和最小的。然后分别放在头尾。
+
+
+
+这样的写法TLE:
+
+```
+class Solution(object):
+ def wiggleSort(self, nums): # 此法超时
+ """
+ :type nums: List[int]
+ :rtype: void Do not return anything, modify nums in-place instead.
+ """
+ n = len(nums)
+ for i in range(n):
+ # small bubble sort
+ if i % 2 == 0:
+ for j in range(n - 1, i - 1, -1):
+ if nums[j] > nums[j - 1]:
+ nums[j], nums[j - 1] = nums[j - 1], nums[j]
+ else:
+ for j in range(n - 1, i - 1, -1):
+ if nums[j] < nums[j - 1]:
+ nums[j], nums[j - 1] = nums[j - 1], nums[j]
+```
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+但是貌似想复杂了,其实对于这个简单化,要求只有一个:
+
+1. 如果i是奇数,nums[i] >= nums[i - 1]
+2. 如果i是偶数,nums[i] <= nums[i - 1]
+
+所以我们只要遍历一遍数组,把不符合的情况交换一下就行了。具体来说,如果nums[i] > nums[i - 1], 则交换以后肯定有nums[i] <= nums[i - 1]。
+
+
+
+AC 代码
+
+```python
+class Solution(object):
+ def wiggleSort(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: void Do not return anything, modify nums in-place instead.
+ """
+ for i in range(1, len(nums)):
+ if (i & 1 == 0 and nums[i] > nums[i-1]) or (i & 1 != 0 and nums[i] < nums[i-1]):
+ nums[i], nums[i-1] = nums[i-1], nums[i]
+```
+
+
+
diff --git a/docs/leetcode/python/283._move_zeroes.md b/docs/Leetcode_Solutions/Python/283._move_zeroes.md
similarity index 78%
rename from docs/leetcode/python/283._move_zeroes.md
rename to docs/Leetcode_Solutions/Python/283._move_zeroes.md
index a5e887c05..26d868112 100644
--- a/docs/leetcode/python/283._move_zeroes.md
+++ b/docs/Leetcode_Solutions/Python/283._move_zeroes.md
@@ -1,19 +1,35 @@
-### 283. Move Zeroes
+# 283. Move Zeroes
+**难度: Easy**
-题目:
-
+## 刷题内容
+> 原题连接
-难度:
-Easy
+* https://leetcode.com/problems/move-zeroes/description/
+> 内容描述
-思路:
+```
+Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.
-### 思路一:暴力
+Example:
-```python
+Input: [0,1,0,3,12]
+Output: [1,3,12,0,0]
+Note:
+
+You must do this in-place without making a copy of the array.
+Minimize the total number of operations.
+```
+
+## 解题方案
+
+> 思路 1
+
+这个思路不符合题目意思,题目要求in-place
+
+```
class Solution(object):
def moveZeroes(self, nums):
"""
@@ -26,13 +42,10 @@ class Solution(object):
i += 1
nums.extend([0]*i)
```
-
-### 思路二:
+> 思路 2
一旦遇到不是0的就把它往前移动,移动非0完成,剩下的全部填0,看例子
-
-
```
0 1 0 3 12
@@ -50,6 +63,13 @@ class Solution(object):
```
1 3 0 3 12
```
+然后变成
+```
+1 3 12 3 12
+ ^ ^
+ cur idx
+```
+
这样知道变换完成,简直逆天啊,因为cur 总是小于idx,所以总可以保持这样的稳定性
@@ -71,11 +91,10 @@ class Solution(object):
while cur < len(nums):
nums[cur] = 0
cur += 1
-
```
-### 思路三:
+> 思路 3
传统的双指针,参考这里
@@ -106,9 +125,11 @@ class Solution(object):
相反,我觉得这样双指针反而没有上面的代码容易理解
-### 思路四:
+> 思路 4
一个比较巧妙的方法:
+
+这个思路符合题目意思in-place,但是时间复杂度是O(nlgn)
```python
class Solution(object):
def moveZeroes(self, nums):
diff --git a/docs/leetcode/python/285._inorder_successor_in_bst.md b/docs/Leetcode_Solutions/Python/285._inorder_successor_in_bst.md
similarity index 97%
rename from docs/leetcode/python/285._inorder_successor_in_bst.md
rename to docs/Leetcode_Solutions/Python/285._inorder_successor_in_bst.md
index b3a941587..aafca56c7 100644
--- a/docs/leetcode/python/285._inorder_successor_in_bst.md
+++ b/docs/Leetcode_Solutions/Python/285._inorder_successor_in_bst.md
@@ -6,7 +6,7 @@
> 原题连接
-* https://leetcode.com/problems/inorder-successor-in-bst
+* https://leetcode.com/problems/inorder-successor-in-bst/description/
> 内容描述
diff --git a/docs/leetcode/python/286._Walls_and_Gates.md b/docs/Leetcode_Solutions/Python/286. Walls and Gates.md
similarity index 100%
rename from docs/leetcode/python/286._Walls_and_Gates.md
rename to docs/Leetcode_Solutions/Python/286. Walls and Gates.md
diff --git a/docs/Leetcode_Solutions/Python/287._Find_the_Duplicate_Number.md b/docs/Leetcode_Solutions/Python/287._Find_the_Duplicate_Number.md
new file mode 100644
index 000000000..9b8d8b014
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/287._Find_the_Duplicate_Number.md
@@ -0,0 +1,161 @@
+# 287. Find the Duplicate Number
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-the-duplicate-number/description/
+
+> 内容描述
+
+```
+
+Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
+
+Example 1:
+
+Input: [1,3,4,2,2]
+Output: 2
+Example 2:
+
+Input: [3,1,3,4,2]
+Output: 3
+Note:
+
+You must not modify the array (assume the array is read only).
+You must use only constant, O(1) extra space.
+Your runtime complexity should be less than O(n2).
+There is only one duplicate number in the array, but it could be repeated more than once.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(1)******
+
+参考[小瑶大神](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/287._Find_the_Duplicate_Number.ipynb
+)的思路
+
+二分枚举答案范围,使用鸽笼原理进行检验
+
+根据鸽笼原理,给定 n+1 个范围为 [1, n]的整数,其中一定存在数字出现至少两次。
+假设枚举的数字为 n / 2 :
+遍历数组,若数组中不大于 n / 2 的数字个数超过 n / 2 ,则可以确定 [1, n/2] 范围内一定有解,否则可以确定解落在 (n/2, n]范围内。
+也可以这样分析一下:
+
+
+如果n 是5,那么就会有1 2 3 4 5 一共5个数字的可能,而array size 是6,那么其中一个数字肯定会至少出现两次。
+
+如果没有重复的数字,小于等于1的数字 出现的次数 等于 1;
+
+小于等于2的数字 出现的次数 等于 2;
+
+... 同理3;4;5。
+
+如果有重复的数字,如果重复的是1,那么 小于等于1的数字 出现的次数 肯定大于1;
+
+基于这个理论,我们可以在1 2 3 4 5 选出一个 mid, 遍历array来count 小于等于mid 的数字个数 小于等于 它自己mid 还是 大于 mid?
+
+如果count 小于等于mid, 说明 1 到 mid 这些数字 没有重复项, 重复项在 右半边 mid 到n, 所以缩小到右半边继续搜索;
+
+如果count 大于mid, 说明 1 到 mid 这些数字中 有重复项,缩小到 左半边继续搜索。
+
+```python
+class Solution(object):
+ def findDuplicate(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ l, r = 0, len(nums) - 1
+ while l <= r:
+ mid = l +((r-l) >> 2)
+ count = sum(num <= mid for num in nums)
+ if count > mid:
+ r = mid - 1
+ else:
+ l = mid + 1
+ return l
+```
+
+> 思路 2
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(1)******
+
+参考[haitao7](https://leetcode.com/haitao7/)大神的思路
+
+我们可以用bit的思路来做,basic idea就是,重复出现的那个数字会使得我们在某一位上出现1的次数是异常的
+
+比如说[1,3,4,2,2]跟[1, 2, 3, 4]对比:
+
+- [1, 3, 4, 2, 2] == [001, 011, 100, 010, 010]
+- [1, 2, 3, 4] == [001, 010, 011, 100]
+
+从最小位开始看起,[1, 3, 4, 2, 2]有2个数,1和3,在最小位上是1,[1, 2, 3, 4]也一样。
+
+但是在从右往左数第二位,[1, 3, 4, 2, 2]就有3个数[3, 2, 2] == [011, 010, 010],在那个bit上是1;而[1, 2, 3, 4]只有[2, 3]两个。
+
+每当发现一个数位上,nums里在那个数位上为1的元素个数,超过了1到n在那个数位上为1的元素个数,我们就可以确定,重复的那个数,在那个数位上肯定是1。如果数位上的1个数相等,则本来那个重复的数字该数位上也是0,不管重复的那个数重复出现多少次,只要多了该数位就是1,没多该数位就是0。
+
+
+这个算法还是有点慢,可能大家用的都是接下来的这个思路,只beats 了 2%
+
+```python
+class Solution(object):
+ def findDuplicate(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ import math
+
+ bits_count = int(math.log(len(nums), 2)) # this is the bits we have
+ base, duplicate = 1, 0
+ for i in range(bits_count+1): # O(logn) for loop
+ normal, real = 0, 0
+ for j in range(len(nums)): # O(n) for loop
+ normal += (j >> i) & 1
+ real += (nums[j] >> i) & 1
+ if real > normal:
+ duplicate += base
+ base <<= 1
+ return duplicate
+```
+
+
+
+
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+快慢指针,先快慢轮询一遍,再慢慢轮询一遍,就找到了,beats 99.7%
+```python
+class Solution(object):
+ def findDuplicate(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ # The "tortoise and hare" step. We start at the end of the array and try
+ # to find an intersection point in the cycle.
+ slow, fast = 0, 0
+ # Keep advancing 'slow' by one step and 'fast' by two steps until they
+ # meet inside the loop.
+ while True:
+ slow = nums[slow]
+ fast = nums[nums[fast]]
+ if slow == fast:
+ break
+ # Start up another pointer from the end of the array and march it forward
+ # until it hits the pointer inside the array.
+ finder = 0
+ while True:
+ slow = nums[slow]
+ finder = nums[finder]
+ # If the two hit, the intersection index is the duplicate element.
+ if slow == finder:
+ return slow
+```
diff --git a/docs/leetcode/python/289._game_of_life.md b/docs/Leetcode_Solutions/Python/289._game_of_life.md
similarity index 100%
rename from docs/leetcode/python/289._game_of_life.md
rename to docs/Leetcode_Solutions/Python/289._game_of_life.md
diff --git a/docs/leetcode/python/290._word_pattern.md b/docs/Leetcode_Solutions/Python/290._word_pattern.md
similarity index 100%
rename from docs/leetcode/python/290._word_pattern.md
rename to docs/Leetcode_Solutions/Python/290._word_pattern.md
diff --git a/docs/leetcode/python/292._nim_game.md b/docs/Leetcode_Solutions/Python/292._nim_game.md
similarity index 100%
rename from docs/leetcode/python/292._nim_game.md
rename to docs/Leetcode_Solutions/Python/292._nim_game.md
diff --git a/docs/leetcode/python/293._Flip_Game.md b/docs/Leetcode_Solutions/Python/293._Flip_Game.md
similarity index 100%
rename from docs/leetcode/python/293._Flip_Game.md
rename to docs/Leetcode_Solutions/Python/293._Flip_Game.md
diff --git a/docs/Leetcode_Solutions/Python/295._Find_Median_from_Data_Stream.md b/docs/Leetcode_Solutions/Python/295._Find_Median_from_Data_Stream.md
new file mode 100644
index 000000000..8b0d94386
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/295._Find_Median_from_Data_Stream.md
@@ -0,0 +1,126 @@
+# 295. Find Median from Data Stream
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-median-from-data-stream/description/
+
+> 内容描述
+
+```
+Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.
+
+For example,
+[2,3,4], the median is 3
+
+[2,3], the median is (2 + 3) / 2 = 2.5
+
+Design a data structure that supports the following two operations:
+
+void addNum(int num) - Add a integer number from the data stream to the data structure.
+double findMedian() - Return the median of all elements so far.
+
+
+Example:
+
+addNum(1)
+addNum(2)
+findMedian() -> 1.5
+addNum(3)
+findMedian() -> 2
+
+
+Follow up:
+
+If all integer numbers from the stream are between 0 and 100, how would you optimize it?
+If 99% of all integer numbers from the stream are between 0 and 100, how would you optimize it?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+二分插入,插入后要挪元素位置,总时间为O(N)
+
+beats 93.41%
+
+```python
+class MedianFinder:
+
+ def __init__(self):
+ """
+ initialize your data structure here.
+ """
+ self.lst = []
+
+
+ def addNum(self, num):
+ """
+ :type num: int
+ :rtype: void
+ """
+ bisect.insort(self.lst, num)
+
+
+ def findMedian(self):
+ """
+ :rtype: float
+ """
+ return (self.lst[len(self.lst) / 2] + self.lst[~(len(self.lst) / 2)]) / 2.0
+```
+
+
+
+> 思路 2
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(N)******
+
+
+
+两个堆,一个放更大的那一半数字,一个放更小的那一半数字
+
+- Time complexity: O(3 * log(n)) + O(1) ≈ O(log(n))
+
+ - At worst, there are two heap insertions and one heap deletions from the top.
+ Each of these takes about O(log(n)) time.
+ - Finding the mean takes constant O(1) time since the tops of heaps are directly accessible.
+- Space complexity: O(n) linear space to hold input in containers.
+
+beats 99.86%
+
+```python
+from heapq import *
+class MedianFinder:
+
+ def __init__(self):
+ """
+ initialize your data structure here.
+ """
+ self.min_half = []
+ self.max_half = [] # 可能会多一个数字
+
+
+ def addNum(self, num):
+ """
+ :type num: int
+ :rtype: void
+ """
+ num = float(num)
+ if len(self.min_half) == len(self.max_half):
+ heappush(self.max_half, -heappushpop(self.min_half, -num))
+ else:
+ heappush(self.min_half, -heappushpop(self.max_half, num))
+
+
+ def findMedian(self):
+ """
+ :rtype: float
+ """
+ if len(self.min_half) == len(self.max_half):
+ return (-self.min_half[0] + self.max_half[0] ) / 2
+ else:
+ return self.max_half[0]
+```
diff --git a/docs/leetcode/python/296._Best_Meeting_Point.md b/docs/Leetcode_Solutions/Python/296. Best Meeting Point.md
similarity index 100%
rename from docs/leetcode/python/296._Best_Meeting_Point.md
rename to docs/Leetcode_Solutions/Python/296. Best Meeting Point.md
diff --git a/docs/leetcode/python/298._Binary_Tree_Longest_Consecutive_Sequence.md b/docs/Leetcode_Solutions/Python/298. Binary Tree Longest Consecutive Sequence.md
similarity index 100%
rename from docs/leetcode/python/298._Binary_Tree_Longest_Consecutive_Sequence.md
rename to docs/Leetcode_Solutions/Python/298. Binary Tree Longest Consecutive Sequence.md
diff --git a/docs/leetcode/python/299._bulls_and_cows.md b/docs/Leetcode_Solutions/Python/299._bulls_and_cows.md
similarity index 98%
rename from docs/leetcode/python/299._bulls_and_cows.md
rename to docs/Leetcode_Solutions/Python/299._bulls_and_cows.md
index 1d6818460..8b6cbe468 100644
--- a/docs/leetcode/python/299._bulls_and_cows.md
+++ b/docs/Leetcode_Solutions/Python/299._bulls_and_cows.md
@@ -13,38 +13,38 @@ Easy
我花了很久时间来AC,因为想了边界条件
-```
-class Solution(object):
- def getHint(self, secret, guess):
- """
- :type secret: str
- :type guess: str
- :rtype: str
- """
- maps = {}
- for i in range(len(secret)):
- if secret[i] not in maps:
- maps[secret[i]] = [i]
- else:
- maps[secret[i]].append(i)
- mapg = {}
- for i in range(len(guess)):
- if guess[i] not in mapg:
- mapg[guess[i]] = [i]
- else:
- mapg[guess[i]].append(i)
-
- print maps, mapg
-
- a,b = 0,0
- for key in maps.keys():
- if key in mapg.keys():
- common = list(set(mapg[key]) & set(maps[key]))
- #check for bull
- a += len(common)
- mapg[key] = [item for item in mapg[key] if item not in common]
- maps[key] = [item for item in maps[key] if item not in common]
- b += min(len(maps[key]), len(mapg[key]))
+```
+class Solution(object):
+ def getHint(self, secret, guess):
+ """
+ :type secret: str
+ :type guess: str
+ :rtype: str
+ """
+ maps = {}
+ for i in range(len(secret)):
+ if secret[i] not in maps:
+ maps[secret[i]] = [i]
+ else:
+ maps[secret[i]].append(i)
+ mapg = {}
+ for i in range(len(guess)):
+ if guess[i] not in mapg:
+ mapg[guess[i]] = [i]
+ else:
+ mapg[guess[i]].append(i)
+
+ print maps, mapg
+
+ a,b = 0,0
+ for key in maps.keys():
+ if key in mapg.keys():
+ common = list(set(mapg[key]) & set(maps[key]))
+ #check for bull
+ a += len(common)
+ mapg[key] = [item for item in mapg[key] if item not in common]
+ maps[key] = [item for item in maps[key] if item not in common]
+ b += min(len(maps[key]), len(mapg[key]))
return str(a) + 'A' + str(b) + 'B'
```
diff --git a/docs/Leetcode_Solutions/Python/300._longest_increasing_subsequence.md b/docs/Leetcode_Solutions/Python/300._longest_increasing_subsequence.md
new file mode 100644
index 000000000..556041d7a
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/300._longest_increasing_subsequence.md
@@ -0,0 +1,138 @@
+# 300. Longest Increasing Subsequence
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/longest-increasing-subsequence/description/
+
+> 内容描述
+
+```
+Given an unsorted array of integers, find the length of longest increasing subsequence.
+
+Example:
+
+Input: [10,9,2,5,3,7,101,18]
+Output: 4
+Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
+Note:
+
+There may be more than one LIS combination, it is only necessary for you to return the length.
+Your algorithm should run in O(n2) complexity.
+Follow up: Could you improve it to O(n log n) time complexity?
+```
+
+## 解题方案
+
+> 思路 1
+
+典型DP
+
+递推关系式:
+
+对于以num[i]结束的longest increasing subsequence的长度
+
+dp[i] = dp[j] + 1 if num[i] > num[j] else dp[i], which 0 <= j < i
+
+loop一圈,求出最长的
+
+AC 代码, 时间复杂度为O(n^2)
+
+```python
+class Solution(object):
+ def lengthOfLIS(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ if not nums or len(nums) == 0:
+ return 0
+ dp = [1] * len(nums)
+ for i in range(len(nums)):
+ for j in range(i):
+ if nums[i] > nums[j]:
+ dp[i] = max(dp[j]+1, dp[i])
+ return max(dp)
+```
+
+
+## Follow up
+
+Could you improve it to O(n log n) time complexity?
+
+> 思路 1
+
+参考这篇🐂p的[博客](https://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/):
+
+自己写二分
+
+```python
+class Solution(object):
+ def lengthOfLIS(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ def binarySearch(nums, l, r, target):
+ while l <= r:
+ mid = l + ((r-l) >> 1)
+ if nums[mid] < target:
+ l = mid + 1
+ else:
+ r = mid - 1
+ return l
+
+ if not nums or len(nums) == 0:
+ return 0
+
+ tails = [0 for i in range(len(nums)+1)]
+ tails[0] = nums[0]
+ # always points empty slot
+ length = 1
+ for i in range(1, len(nums)):
+ if (nums[i] < tails[0]):
+ # new smallest value
+ tails[0] = nums[i]
+ elif (nums[i] > tails[length-1]):
+ # A[i] wants to extend
+ # largest subsequence
+ tails[length] = nums[i]
+ length+=1
+ else:
+ # A[i] wants to be current
+ # end candidate of an existing
+ # subsequence. It will replace
+ # ceil value in tailTable
+ tails[binarySearch(tails, 0, length-1, nums[i])] = nums[i]
+
+ return length
+```
+
+
+> 思路 2
+
+调用自带的二分,并且不维护整个tails,只是慢慢往上面append元素,这样二分查找时不需要手动输入left和right
+
+```python
+class Solution(object):
+ def lengthOfLIS(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ if not nums or len(nums) == 0:
+ return 0
+
+ lis = [nums[0]]
+ for i in range(1, len(nums)):
+ if nums[i] > lis[-1]:
+ lis.append(nums[i])
+ else:
+ # 要用bisect_left,因为如果插入到右边就相当于多append了一个,而不再是replace了
+ lis[bisect.bisect_left(lis, nums[i])] = nums[i]
+
+ return len(lis)
+```
diff --git a/docs/leetcode/python/303._range_sum_query_-_immutable.md b/docs/Leetcode_Solutions/Python/303._range_sum_query_-_immutable.md
similarity index 100%
rename from docs/leetcode/python/303._range_sum_query_-_immutable.md
rename to docs/Leetcode_Solutions/Python/303._range_sum_query_-_immutable.md
diff --git a/docs/Leetcode_Solutions/Python/305._Number_of_Islands_II.md b/docs/Leetcode_Solutions/Python/305._Number_of_Islands_II.md
new file mode 100644
index 000000000..d4e1c25a6
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/305._Number_of_Islands_II.md
@@ -0,0 +1,95 @@
+# 305. Number of Islands II
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/number-of-islands-ii/description/
+
+> 内容描述
+
+```
+A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand operation which turns the water at position (row, col) into a land. Given a list of positions to operate, count the number of islands after each addLand operation. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
+
+Example:
+
+Input: m = 3, n = 3, positions = [[0,0], [0,1], [1,2], [2,1]]
+Output: [1,1,2,3]
+Explanation:
+
+Initially, the 2d grid grid is filled with water. (Assume 0 represents water and 1 represents land).
+
+0 0 0
+0 0 0
+0 0 0
+Operation #1: addLand(0, 0) turns the water at grid[0][0] into a land.
+
+1 0 0
+0 0 0 Number of islands = 1
+0 0 0
+Operation #2: addLand(0, 1) turns the water at grid[0][1] into a land.
+
+1 1 0
+0 0 0 Number of islands = 1
+0 0 0
+Operation #3: addLand(1, 2) turns the water at grid[1][2] into a land.
+
+1 1 0
+0 0 1 Number of islands = 2
+0 0 0
+Operation #4: addLand(2, 1) turns the water at grid[2][1] into a land.
+
+1 1 0
+0 0 1 Number of islands = 3
+0 1 0
+Follow up:
+
+Can you do it in time complexity O(k log mn), where k is the length of the positions?
+```
+
+## 解题方案
+
+> 思路 1
+
+对于positions中的每一个点,我们把他认为是一个单独的岛屿的root,然后我们看看他周围有没有value为1的点(即陆地),如果有,那么那一块陆地的root也是当前点
+
+然后每次结束一个点,我们就可以算一下当前一共有几个岛屿,即有几个不同的root,在代码中为```island_groups```的长度
+
+这个解法也称为并查集算法,可以去看看[union-find](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/Summarization/union_find.md)
+
+
+```python
+class Solution(object):
+ def numIslands2(self, m, n, positions):
+ """
+ :type m: int
+ :type n: int
+ :type positions: List[List[int]]
+ :rtype: List[int]
+ """
+ # find the root of a point
+ def find(x, uf):
+ while x != uf[x]:
+ uf[x] = uf[uf[x]]
+ x = uf[x]
+ return uf[x]
+
+ island_groups, res, uf, idx = set(), [], {}, 1
+ for i, j in positions:
+ uf[(i, j)] = uf[idx] = idx
+ for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):
+ # when neighbor == 1, we make cur_point as the root
+ if (x, y) in uf:
+ root = find(uf[(x, y)], uf)
+ island_groups.discard(root)
+ uf[root] = idx
+ island_groups.add(idx)
+ idx += 1
+ res.append(len(island_groups))
+ return res
+```
+
+
+```因为并查集的查找时间复杂度是O(lgN),由于这里N就是m*n,所以我们总的时间复杂度就是O(k*lgmn)```
diff --git a/docs/Leetcode_Solutions/Python/309._Best_Time_to_Buy_and_Sell_Stock_with_Cooldown.md b/docs/Leetcode_Solutions/Python/309._Best_Time_to_Buy_and_Sell_Stock_with_Cooldown.md
new file mode 100644
index 000000000..1e561171d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/309._Best_Time_to_Buy_and_Sell_Stock_with_Cooldown.md
@@ -0,0 +1,101 @@
+# 309. Best Time to Buy and Sell Stock with Cooldown
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/description/
+
+> 内容描述
+
+```
+
+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 as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions:
+
+You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
+After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)
+Example:
+
+Input: [1,2,3,0,2]
+Output: 3
+Explanation: transactions = [buy, sell, cooldown, buy, sell]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+对于今天过后,有以下三种状态
+
+1. 没有股票 notown
+ - 要么是昨天我就没有股票,然后今天我啥也没做
+ - 要么是昨天cooldown,今天我啥也没做
+2. 有股票 own
+ - 要么是昨天就有股票了,今天没卖
+ - 要么是昨天没有股票,今天买了股票
+ - 要注意,昨天如果是cooldown,今天无论如何都不可能有股票
+3. cool
+ - 我昨天有股票,今天卖了
+
+
+最后一天我的状态肯定是notown 或者 cool
+
+beats 97.77%
+
+```python
+class Solution(object):
+ def maxProfit(self, prices):
+ """
+ :type prices: List[int]
+ :rtype: int
+ """
+ notown = 0
+ own = cool = -sys.maxsize
+ for p in prices:
+ notown, own, cool = max(notown, cool), max(own, notown - p), own + p
+ return max(notown, cool)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/311._Sparse_Matrix_Multiplication.md b/docs/Leetcode_Solutions/Python/311._Sparse_Matrix_Multiplication.md
new file mode 100644
index 000000000..e8f33c212
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/311._Sparse_Matrix_Multiplication.md
@@ -0,0 +1,78 @@
+# 311. Sparse Matrix Multiplication
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/sparse-matrix-multiplication/description/
+
+> 内容描述
+
+```
+Given two sparse matrices A and B, return the result of AB.
+
+You may assume that A's column number is equal to B's row number.
+
+Example:
+
+Input:
+
+A = [
+ [ 1, 0, 0],
+ [-1, 0, 3]
+]
+
+B = [
+ [ 7, 0, 0 ],
+ [ 0, 0, 0 ],
+ [ 0, 0, 1 ]
+]
+
+Output:
+
+ | 1 0 0 | | 7 0 0 | | 7 0 0 |
+AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 |
+ | 0 0 1 |
+```
+
+## 解题方案
+
+> 思路 1
+
+
+
+直接搞一个完全的稀疏矩阵然后一个一个地去看,这样万一内存不够怎么办,所以我们基于A建一个非0的新list,然后对应的求出结果,这样操作数会少一些,
+并且对内存的要求也没有那么高,借用一句话```I think, in perspective of Big4, they would have a HUGE sparse dataset.
+And would like to process them in a machine.
+So memory does not fit without the Table representation of sparse matrix.
+And this is efficient since can be loaded into a one machine```
+
+```python
+class Solution(object):
+ def multiply(self, A, B):
+ """
+ :type A: List[List[int]]
+ :type B: List[List[int]]
+ :rtype: List[List[int]]
+ """
+ m, n, nB = len(A), len(A[0]), len(B[0])
+ res = [[0] * nB for i in range(m)]
+
+ idxA = []
+ for i in range(len(A)):
+ tmp = []
+ for j in range(len(A[0])):
+ if A[i][j] != 0:
+ tmp.append(j)
+ idxA.append(tmp)
+ print(idxA)
+
+ for i in range(len(idxA)):
+ for j in idxA[i]:
+ for k in range(nB):
+ res[i][k] += A[i][j] * B[j][k]
+
+ return res
+```
diff --git a/docs/Leetcode_Solutions/Python/313._Super_Ugly_Number.md b/docs/Leetcode_Solutions/Python/313._Super_Ugly_Number.md
new file mode 100644
index 000000000..d8795813e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/313._Super_Ugly_Number.md
@@ -0,0 +1,61 @@
+# 313. Super Ugly Number
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/super-ugly-number/description/
+
+> 内容描述
+
+```
+Write a program to find the nth super ugly number.
+
+Super ugly numbers are positive numbers whose all prime factors are in the given prime list primes of size k.
+
+Example:
+
+Input: n = 12, primes = [2,7,13,19]
+Output: 32
+Explanation: [1,2,4,7,8,13,14,16,19,26,28,32] is the sequence of the first 12
+ super ugly numbers given primes = [2,7,13,19] of size 4.
+Note:
+
+1 is a super ugly number for any given primes.
+The given numbers in primes are in ascending order.
+0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000.
+The nth super ugly number is guaranteed to fit in a 32-bit signed integer.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(n * len(primes))******- 空间复杂度: O(N)******
+
+
+直接用[lc第264题 ugly number II](https://github.com/apachecn/awesome-algorithm/blob/master/docs/Leetcode_Solutions/Python/264._ugly_number_ii.md)的代码改改就可以
+
+
+思路一摸一样,beats 57.47%
+
+```python
+class Solution(object):
+ def nthSuperUglyNumber(self, n, primes):
+ """
+ :type n: int
+ :type primes: List[int]
+ :rtype: int
+ """
+ ugly = [1]
+ pointers = [0] * len(primes)
+ for i in range(n-1):
+ next_uglys = [primes[i] * ugly[pointers[i]] for i in range(len(primes))]
+ umin = min(next_uglys)
+ pointer_idxs = [i for i in range(len(next_uglys)) if next_uglys[i] == umin] # 哪些指针目前最小
+ for pointer_idx in pointer_idxs: # 目前指向值最小的指针都需要右移一位
+ pointers[pointer_idx] += 1
+ ugly.append(umin)
+ return ugly[-1]
+```
diff --git a/docs/leetcode/python/316._Remove_Duplicate_Letters.md b/docs/Leetcode_Solutions/Python/316._Remove_Duplicate_Letters.md
similarity index 100%
rename from docs/leetcode/python/316._Remove_Duplicate_Letters.md
rename to docs/Leetcode_Solutions/Python/316._Remove_Duplicate_Letters.md
diff --git a/docs/Leetcode_Solutions/Python/319._Bulb_Switcher.md b/docs/Leetcode_Solutions/Python/319._Bulb_Switcher.md
new file mode 100644
index 000000000..c764bbd30
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/319._Bulb_Switcher.md
@@ -0,0 +1,96 @@
+# 319. Bulb Switcher
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/bulb-switcher/description/
+
+> 内容描述
+
+```
+There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it's off or turning off if it's on). For the i-th round, you toggle every i bulb. For the n-th round, you only toggle the last bulb. Find how many bulbs are on after n rounds.
+
+Example:
+
+Input: 3
+Output: 1
+Explanation:
+At first, the three bulbs are [off, off, off].
+After first round, the three bulbs are [on, on, on].
+After second round, the three bulbs are [on, off, on].
+After third round, the three bulbs are [on, off, off].
+
+So you should return 1, because there is only one bulb is on.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+bulb代表第一轮结束后的所有灯亮灭的情况,从第二轮开始
+- 如果是最后一轮,则bulb的最后一个灯要switch
+- 对于其他轮,相应的第i-1+C(i)个灯要siwitch,且C为常数,i-1+C(i)必须<=n-1
+
+但是发现这样提交会超时
+Last executed input:
+999999
+
+
+```
+class Solution(object):
+ def bulbSwitch(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ bulb = [1] * n
+ for i in range(2,n+1):
+ for x in range(i-1, n, i):
+ bulb[x] = 1 if bulb[x] == 0 else 0
+ return bulb.count(1)
+```
+
+> 思路 2
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+原来,这是一道智商碾压题:
+
+> A bulb ends up on iff it is switched an odd number of times.
+Bulb i is switched in round d iff d divides i.
+So bulb i ends up on iff it has an odd number of >divisors.
+Divisors come in pairs, like i=12 has divisors 1 and 12, 2 and 6, and 3 and 4.
+Except if i is a >square, like 36 has divisors 1 and 36, 2 and 18, 3 and 12, 4 and 9,
+and double divisor 6. So bulb >i ends up on iff and only if i is a square. So just count the square numbers.
+
+大概解释一下,当一个灯泡被执行偶数次switch操作时它是灭着的,当被执行奇数次switch操作时它是亮着的,那么这题就是要找出哪些编号的灯泡会被执行奇数次操作。
+
+现在假如我们执行第i次操作,即从编号i开始对编号每次+i进行switch操作,对于这些灯来说,
+如果其编号j(j=1,2,3,⋯,n)能够整除i,则编号j的灯需要执行switch操作。
+具备这样性质的i是成对出现的,比如:
+- 12 = 1 * 12,
+- 12 = 2 * 6
+- 12 = 3 * 4
+
+所以编号为12的灯,在第1次,第12次;第2次,第6次;第3次,第4次一定会被执行Switch操作,这样的话,编号为12的灯执行偶数次switch,肯定为灭。
+这样推出,完全平方数一定是亮着的,因为它有两个相同的因子,总因子数为奇数,如36 = 6 * 6,所以本题的关键在于找完全平方数的个数。
+
+为什么时间复杂度是O(1)呢,因为追溯到最底层,求开方就是O(1)的,详细见
+1. [求平方根sqrt()函数的底层算法效率问题](http://www.nowamagic.net/algorithm/algorithm_EfficacyOfFunctionSqrt.php)
+2. [Time complexity of Math.Sqrt()?](https://stackoverflow.com/questions/34580158/time-complexity-of-math-sqrt)
+
+```python
+class Solution(object):
+ def bulbSwitch(self, n):
+ """
+ type n: int
+ rtype: int
+ """
+ # The number of full/perfect squares.
+ return int(math.sqrt(n))
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/322._Coin_Change.md b/docs/Leetcode_Solutions/Python/322._Coin_Change.md
new file mode 100644
index 000000000..426320a38
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/322._Coin_Change.md
@@ -0,0 +1,56 @@
+# 322. Coin Change
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/coin-change/description/
+
+> 内容描述
+
+```
+You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.
+
+Example 1:
+
+Input: coins = [1, 2, 5], amount = 11
+Output: 3
+Explanation: 11 = 5 + 5 + 1
+Example 2:
+
+Input: coins = [2], amount = 3
+Output: -1
+Note:
+You may assume that you have an infinite number of each kind of coin.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N*amount)******- 空间复杂度: O(amount)******
+
+DP入门
+
+递推方程式: dp[i] = min(dp[i], dp[i-coins[j]]+1), coins[j] 是硬币的面额
+
+
+
+```python
+class Solution(object):
+ def coinChange(self, coins, amount):
+ """
+ :type coins: List[int]
+ :type amount: int
+ :rtype: int
+ """
+ dp = [amount+1] * (amount+1)
+ dp[0] = 0
+ for i in range(1, amount+1):
+ for coin in coins:
+ if coin <= i:
+ dp[i] = min(dp[i], dp[i-coin]+1)
+ return -1 if dp[-1] == amount + 1 else dp[-1]
+```
+
diff --git a/docs/leetcode/python/323._number_of_connected_components_in_an_undirected_graph.md b/docs/Leetcode_Solutions/Python/323._number_of_connected_components_in_an_undirected_graph.md
similarity index 97%
rename from docs/leetcode/python/323._number_of_connected_components_in_an_undirected_graph.md
rename to docs/Leetcode_Solutions/Python/323._number_of_connected_components_in_an_undirected_graph.md
index 9527b47df..c7d282ae4 100644
--- a/docs/leetcode/python/323._number_of_connected_components_in_an_undirected_graph.md
+++ b/docs/Leetcode_Solutions/Python/323._number_of_connected_components_in_an_undirected_graph.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph
+* https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/description/
> 内容描述
diff --git a/docs/leetcode/python/324._Wiggle_Sort_II.md b/docs/Leetcode_Solutions/Python/324._Wiggle_Sort_II.md
similarity index 100%
rename from docs/leetcode/python/324._Wiggle_Sort_II.md
rename to docs/Leetcode_Solutions/Python/324._Wiggle_Sort_II.md
diff --git a/docs/Leetcode_Solutions/Python/325._Maximum_Size_Subarray_Sum_Equals_k.md b/docs/Leetcode_Solutions/Python/325._Maximum_Size_Subarray_Sum_Equals_k.md
new file mode 100644
index 000000000..0d9cc56dd
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/325._Maximum_Size_Subarray_Sum_Equals_k.md
@@ -0,0 +1,60 @@
+# 325. Maximum Size Subarray Sum Equals k
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/maximum-size-subarray-sum-equals-k/description/
+
+> 内容描述
+
+```
+Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't one, return 0 instead.
+
+Note:
+The sum of the entire nums array is guaranteed to fit within the 32-bit signed integer range.
+
+Example 1:
+
+Input: nums = [1, -1, 5, -2, 3], k = 3
+Output: 4
+Explanation: The subarray [1, -1, 5, -2] sums to 3 and is the longest.
+Example 2:
+
+Input: nums = [-2, -1, 2, 1], k = 1
+Output: 2
+Explanation: The subarray [-1, 2] sums to 1 and is the longest.
+Follow Up:
+Can you do it in O(n) time?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+前缀和+字典的方法
+
+```python
+class Solution(object):
+ def maxSubArrayLen(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: int
+ """
+ res, sums = 0, 0 # res and the accumulative value of nums
+ lookup = {0: -1} # key is accumlative sum, value is index
+ for i, num in enumerate(nums):
+ sums += num
+ if sums - k in lookup:
+ res = max(res, i-lookup[sums-k]) # when key = 0, we should just use i+1
+ if sums not in lookup:
+ lookup[sums] = i
+ return res
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/326._power_of_three.md b/docs/Leetcode_Solutions/Python/326._power_of_three.md
new file mode 100644
index 000000000..185cbcaa4
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/326._power_of_three.md
@@ -0,0 +1,78 @@
+# 326. Power of Three
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/power-of-three/description/
+
+> 内容描述
+
+```
+Given an integer, write a function to determine if it is a power of three.
+
+Example 1:
+
+Input: 27
+Output: true
+Example 2:
+
+Input: 0
+Output: false
+Example 3:
+
+Input: 9
+Output: true
+Example 4:
+
+Input: 45
+Output: false
+Follow up:
+Could you do it without using any loop / recursion?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+
+直接就上的递归
+
+```python
+class Solution(object):
+ def isPowerOfThree(self,n):
+ """
+ :type n: int
+ :rtype: bool
+ """
+ if n <= 0:
+ return False
+ if n == 1:
+ return True
+ if n % 3 == 0:
+ return self.isPowerOfThree(n/3)
+ return False
+```
+
+## Follow up: Could you do it without using any loop / recursion?
+
+看到了取巧的办法,因为是Given an integer,是有范围的(<2147483648),存在能输入的最大的3的幂次,即 3^19=1162261467。
+
+只用检查是否能被这个数整除
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+```python
+class Solution(object):
+ def isPowerOfThree(self, n):
+ """
+ :type n: int
+ :rtype: bool
+ """
+ return n > 0 and pow(3, 19) % n == 0
+```
+
diff --git a/docs/leetcode/python/328._odd_even_linked_list.md b/docs/Leetcode_Solutions/Python/328._odd_even_linked_list.md
similarity index 99%
rename from docs/leetcode/python/328._odd_even_linked_list.md
rename to docs/Leetcode_Solutions/Python/328._odd_even_linked_list.md
index 893314630..b628ab241 100644
--- a/docs/leetcode/python/328._odd_even_linked_list.md
+++ b/docs/Leetcode_Solutions/Python/328._odd_even_linked_list.md
@@ -52,26 +52,26 @@ class Solution(object):
看别人的优雅代码
-```
-class Solution(object):
- def oddEvenList(self, head):
- """
- :type head: ListNode
- :rtype: ListNode
- """
- if head == None:
- return head
-
- # odd used to keep track of the tail of odd nodes
- odd = oddHead = head
- # record how many swaps happend
- even = evenHead = head.next
- while even and even.next:
- odd.next = even.next
- odd = odd.next
- even.next = odd.next
- even = even.next
- odd.next = evenHead
+```
+class Solution(object):
+ def oddEvenList(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ if head == None:
+ return head
+
+ # odd used to keep track of the tail of odd nodes
+ odd = oddHead = head
+ # record how many swaps happend
+ even = evenHead = head.next
+ while even and even.next:
+ odd.next = even.next
+ odd = odd.next
+ even.next = odd.next
+ even = even.next
+ odd.next = evenHead
return head
```
diff --git a/docs/leetcode/python/334._increasing_triplet_subsequence.md b/docs/Leetcode_Solutions/Python/334._increasing_triplet_subsequence.md
similarity index 100%
rename from docs/leetcode/python/334._increasing_triplet_subsequence.md
rename to docs/Leetcode_Solutions/Python/334._increasing_triplet_subsequence.md
diff --git a/docs/Leetcode_Solutions/Python/336._Palindrome_Pairs.md b/docs/Leetcode_Solutions/Python/336._Palindrome_Pairs.md
new file mode 100644
index 000000000..cd16b3c99
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/336._Palindrome_Pairs.md
@@ -0,0 +1,119 @@
+# 336. Palindrome Pairs
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/palindrome-pairs/description/
+
+> 内容描述
+
+```
+
+Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.
+
+Example 1:
+
+Input: ["abcd","dcba","lls","s","sssll"]
+Output: [[0,1],[1,0],[3,2],[2,4]]
+Explanation: The palindromes are ["dcbaabcd","abcddcba","slls","llssssll"]
+Example 2:
+
+Input: ["bat","tab","cat"]
+Output: [[0,1],[1,0]]
+Explanation: The palindromes are ["battab","tabbat"]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+对于每一个word,我们只需要算出它的所有prefix和suffix,
+
+```
+比如‘abc’:
+它的所有prefix为'', 'a', 'ab', 'abc'
+它的所有suffix为'', 'c', 'cb', 'cba'
+```
+
+现在有两种情况:
+
+1. 如果前缀pref是回文且后缀suff的reverse也在words里面,那么suff[::-1]+(pref+suff)肯定是回文, 注意其中suff[::-1]不能等于word本身
+2. 如果后缀suff是回文且前缀pref的reverse也在words里面,那么(pref+suff)+pref[::-1]肯定是回文, 注意其中pref[::-1]不能等于word本身
+
+***但是!!!我们不要忘记直接这样算会有duplicates,例如:***
+```
+输入为["abcd","dcba"]
+
+直接按照上面的算法我们会返回[[0,1], [1,0], [0,1], [1,0]]
+
+但实际上应该返回[[0,1], [1,0]]
+
+那么究竟为什么会有重复呢?
+因为前面验证第一种情况prefix的时候计算了'abcd'+(''+'dcba')和'dcba'+(''+'abcd')的情况
+后面验证第二种情况suffix的时候我们又计算了('abcd'+'')+'dcba'和(‘dcba'+'')+'abcd'的情况
+
+这就导致了重复,所以在计算第二种情况的时候我们要排除suffix就是word本身的情况
+```
+
+
+
+```python
+class Solution(object):
+ def palindromePairs(self, words):
+ """
+ :type words: List[str]
+ :rtype: List[List[int]]
+ """
+ lookup = {
+ word: i for i, word in enumerate(words)
+ }
+ res = []
+ for i, word in enumerate(words):
+ for j in range(len(word)+1):
+ pref, suff = word[:j], word[j:]
+ # 如果前缀pref是回文且后缀suff的reverse也在words里面,那么suff[::-1]+(pref+suff)肯定是回文
+ if pref == pref[::-1] and suff[::-1] in lookup and suff[::-1] != word:
+ res.append([lookup[suff[::-1]], i])
+ # 如果后缀suff是回文且前缀pref的reverse也在words里面,那么(pref+suff)+pref[::-1]肯定是回文
+ if suff == suff[::-1] and pref[::-1] in lookup and pref[::-1] != word:
+ # 这是为了保证没有重复,例如:
+ # 如果前面算了'abcd'+(''+'dcba')和'dcba'+(''+'abcd')的情况
+ # 后面不能再算一遍('abcd'+'')+'dcba'和(‘dcba'+'')+'abcd'了
+ if j != len(word):
+ res.append([i, lookup[pref[::-1]]])
+ return res
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/337._house_robber_iii.md b/docs/Leetcode_Solutions/Python/337._house_robber_iii.md
similarity index 100%
rename from docs/leetcode/python/337._house_robber_iii.md
rename to docs/Leetcode_Solutions/Python/337._house_robber_iii.md
diff --git a/docs/Leetcode_Solutions/Python/338._Counting_Bits.md b/docs/Leetcode_Solutions/Python/338._Counting_Bits.md
new file mode 100644
index 000000000..e96e70c79
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/338._Counting_Bits.md
@@ -0,0 +1,132 @@
+# 338. Counting Bits
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/counting-bits/description/
+
+> 内容描述
+
+```
+Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array.
+
+Example 1:
+
+Input: 2
+Output: [0,1,1]
+Example 2:
+
+Input: 5
+Output: [0,1,1,2,1,2]
+Follow up:
+
+It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a single pass?
+Space complexity should be O(n).
+Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N*k) k is number of bits in num******- 空间复杂度: O(N)******
+
+
+
+**O(n\*sizeof(integer))** 算法,其实就是把count of 1 bit拿来用:
+
+```python
+class Solution(object):
+ def countBits(self, num):
+ """
+ :type num: int
+ :rtype: List[int]
+ """
+ def hammingWeight(n):
+ cnt = 0
+ while n != 0:
+ n &= n -1
+ cnt += 1
+ return cnt
+
+ res = []
+ for i in range(num+1):
+ res.append(hammingWeight(i))
+ return res
+
+```
+
+
+## Follow up:
+
+```It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a single pass?
+Space complexity should be O(n).
+Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language.
+```
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+DP 算法
+
+DP 的思路其实不难,就是“把每天当成是末日来相待”,并且这一天发生的事能记下来就记下来。
+转换到实际问题上,就是把每一步都当时是最后一步来操作,然后沿途记下一些以后需要的数据即可。
+
+本题是求二进制数中`1`的个数,首先,创建一个数组`dp`,数组的索引`i`就是数字`i`,索引`i`对应的值就是数字`i`二进制数的`1`的个数。
+
+我们知道,任何一个十进制数字`num`都可以转换成二进制,并且,转换后的二进制长度是`x = floor(log(num, 2)) + 1`位,这`x`位数字除了第一位是`1`之外,其他位都是`0`或`1`。
+
+所以,可以把`num`拆成两个数的和,其中第一个数是`p = 2**(x-1)`,第二个数就是`num - p`。如果`num == p`, 因为`p = 2**(x-1)`中数字`1`的个数是`1`,那么此时`num`的二进制数中的`1`的个数就是`1`,即`dp[num] = 1`,否则,`dp[num] = dp[p] + dp[num-p]`(`num-p`一定小于`p`)。
+
+总结一下,关键点在于`c = a + b`,如何找到合适的`a`、`b`.
+
+
+
+首先只有一轮循环,在每一轮循环里面有log函数,但是基本上可以忽略不计,所以总时间复杂度为O(N),空间也为O(N)
+
+```python
+class Solution(object):
+ def countBits(self, num):
+ """
+ :type num: int
+ :rtype: List[int]
+ """
+ from math import floor, log
+ dp = [0] * (num+1)
+ for i in range(1, num+1):
+ x = floor(log(i, 2)) + 1
+ p = int(pow(2, x-1))
+ if p == i:
+ dp[i] = 1
+ else:
+ dp[i] = dp[p] + dp[i-p]
+ return dp
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+dp的另外一种方法,状态方程为 ```P(x) = P(x&(x-1)) + 1```
+
+beats 95.17%
+
+```python
+class Solution(object):
+ def countBits(self, num):
+ """
+ :type num: int
+ :rtype: List[int]
+ """
+ dp = [0] * (num+1)
+ for i in range(1, num+1):
+ dp[i] = dp[i&(i-1)] + 1
+ return dp
+```
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/339._Nested_List_Weight_Sum.md b/docs/Leetcode_Solutions/Python/339._Nested_List_Weight_Sum.md
new file mode 100644
index 000000000..d854b8b8e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/339._Nested_List_Weight_Sum.md
@@ -0,0 +1,57 @@
+# 339. Nested List Weight Sum
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/nested-list-weight-sum/description/
+
+> 内容描述
+
+```
+Given a nested list of integers, return the sum of all integers in the list weighted by their depth.
+
+Each element is either an integer, or a list -- whose elements may also be integers or other lists.
+
+Example 1:
+
+Input: [[1,1],2,[1,1]]
+Output: 10
+Explanation: Four 1's at depth 2, one 2 at depth 1.
+Example 2:
+
+Input: [1,[4,[6]]]
+Output: 27
+Explanation: One 1 at depth 1, one 4 at depth 2, and one 6 at depth 3; 1 + 4*2 + 6*3 = 27.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+很简单的递归
+
+假设nestedList铺平开来,里面一共有N个NestedInteger的话,时间复杂度就是O(N)
+
+beats 99.77%
+
+```python
+class Solution:
+ def depthSum(self, nestedList):
+ """
+ :type nestedList: List[NestedInteger]
+ :rtype: int
+ """
+ def helper(nestedList, depth):
+ res = 0
+ for nested in nestedList:
+ if nested.isInteger():
+ res += depth * nested.getInteger()
+ else:
+ res += helper(nested.getList(), depth+1)
+ return res
+ return helper(nestedList, 1)
+```
diff --git a/docs/Leetcode_Solutions/Python/340._Longest_Substring_with_At_Most_K_Distinct_Characters.md b/docs/Leetcode_Solutions/Python/340._Longest_Substring_with_At_Most_K_Distinct_Characters.md
new file mode 100644
index 000000000..832857c02
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/340._Longest_Substring_with_At_Most_K_Distinct_Characters.md
@@ -0,0 +1,59 @@
+# 340. Longest Substring with At Most K Distinct Characters
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/longest-substring-with-at-most-k-distinct-characters/description/
+
+> 内容描述
+
+```
+
+Given a string, find the length of the longest substring T that contains at most k distinct characters.
+
+Example 1:
+
+Input: s = "eceba", k = 2
+Output: 3
+Explanation: T is "ece" which its length is 3.
+Example 2:
+
+Input: s = "aa", k = 1
+Output: 2
+Explanation: T is "aa" which its length is 2.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+思路见第159题
+
+```python
+class Solution(object):
+ def lengthOfLongestSubstringKDistinct(self, s, k):
+ """
+ :type s: str
+ :type k: int
+ :rtype: int
+ """
+ maps = {}
+ begin, end, counter, length = 0, 0, 0, 0
+ while end < len(s):
+ maps[s[end]] = maps.get(s[end], 0) + 1
+ if maps[s[end]] == 1:
+ counter += 1
+ end += 1 # end 永远指向下一个待处理的字符
+ while counter > k:
+ maps[s[begin]] -= 1
+ if maps[s[begin]] == 0:
+ counter -= 1
+ begin += 1
+ length = max(length, end - begin) # 因此这里是```end - begin```而不是```end - begin + 1```
+ return length
+```
diff --git a/docs/Leetcode_Solutions/Python/341._Flatten_Nested_List_Iterator.md b/docs/Leetcode_Solutions/Python/341._Flatten_Nested_List_Iterator.md
new file mode 100644
index 000000000..4ac6ac6c7
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/341._Flatten_Nested_List_Iterator.md
@@ -0,0 +1,115 @@
+# 341. Flatten Nested List Iterator
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/flatten-nested-list-iterator/description/
+
+> 内容描述
+
+```
+Given a nested list of integers, implement an iterator to flatten it.
+
+Each element is either an integer, or a list -- whose elements may also be integers or other lists.
+
+Example 1:
+
+Input: [[1,1],2,[1,1]]
+Output: [1,1,2,1,1]
+Explanation: By calling next repeatedly until hasNext returns false,
+ the order of elements returned by next should be: [1,1,2,1,1].
+Example 2:
+
+Input: [1,[4,[6]]]
+Output: [1,4,6]
+Explanation: By calling next repeatedly until hasNext returns false,
+ the order of elements returned by next should be: [1,4,6].
+```
+
+## 解题方案
+
+> 思路 1
+
+这个思路就是先把nestedList里面所有的Integer全部拿出来放到一个stack里面,next()就是简单的拿出下一个,hasNext()就是简单的看看还有没有下一个,但是这样会有一个不好的地方就是如果在现实中,我们的nestedList很大很大,然后我们可能只调用一次next(),那岂不是很亏吗。后面的解法会解决这个问题
+
+
+```python
+class NestedIterator(object):
+
+ def __init__(self, nestedList):
+ """
+ Initialize your data structure here.
+ :type nestedList: List[NestedInteger]
+ """
+ def dfs(nestedList):
+ for item in nestedList:
+ if item.isInteger():
+ self.stack.append(item.getInteger())
+ else:
+ dfs(item.getList())
+ self.stack = []
+ dfs(nestedList)
+
+
+ def next(self):
+ """
+ :rtype: int
+ """
+ if self.hasNext():
+ return self.stack.pop(0)
+
+
+ def hasNext(self):
+ """
+ :rtype: bool
+ """
+ return self.stack != []
+```
+
+> 思路 2
+
+参考大神[StefanPochmann](https://leetcode.com/problems/flatten-nested-list-iterator/discuss/80146/Real-iterator-in-Python-Java-C++)
+其实还是有一个stack,但是每次只把当前非空的nestedList加进来,然后递归嵌套调用的思想,取出最后一个。
+
+
+```python
+class NestedIterator(object):
+
+ def __init__(self, nestedList):
+ """
+ Initialize your data structure here.
+ :type nestedList: List[NestedInteger]
+ """
+ self.stack = [[nestedList, 0]]
+
+
+ def next(self):
+ """
+ :rtype: int
+ """
+ cur_nestedList, i = self.stack[-1]
+ self.stack[-1][1] += 1
+ return cur_nestedList[i]
+
+
+ def hasNext(self):
+ """
+ :rtype: bool
+ """
+ s = self.stack
+ while s:
+ cur_nestedList, i = s[-1]
+ if i == len(cur_nestedList):
+ s.pop()
+ else:
+ x = cur_nestedList[i]
+ if x.isInteger(): # x is a Integer
+ return True
+ else: # x is still a nestedList
+ s[-1][1] += 1
+ s.append([x.getList(), 0])
+ return False
+```
diff --git a/docs/Leetcode_Solutions/Python/342._Power_of_Four.md b/docs/Leetcode_Solutions/Python/342._Power_of_Four.md
new file mode 100644
index 000000000..6ff31db01
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/342._Power_of_Four.md
@@ -0,0 +1,97 @@
+# 342. Power of Four
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/power-of-four/description/
+
+> 内容描述
+
+```
+Given an integer (signed 32 bits), write a function to check whether it is a power of 4.
+
+Example 1:
+
+Input: 16
+Output: true
+Example 2:
+
+Input: 5
+Output: false
+Follow up: Could you solve it without loops/recursion?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+继续照抄power of three
+
+```python
+class Solution(object):
+ def isPowerOfFour(self, num):
+ """
+ :type num: int
+ :rtype: bool
+ """
+ if num <= 0 :
+ return False
+ if num == 1:
+ return True
+ if num % 4 == 0:
+ return self.isPowerOfFour(num/4)
+ return False
+```
+
+
+
+## Follow up: Could you solve it without loops/recursion?
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+
+```python
+class Solution(object):
+ def isPowerOfFour(self, num):
+ """
+ :type num: int
+ :rtype: bool
+ """
+ return num > 0 and num & (num-1) == 0 and len(bin(num)[3:]) % 2 == 0
+```
+
+> 思路 2
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+
+
+```python
+class Solution(object):
+ def isPowerOfFour(self, num):
+ """
+ :type num: int
+ :rtype: bool
+ """
+ return num > 0 and num & (num-1) == 0 and bin(num)[3:].count('0') & 1 == 0
+```
+
+> 思路 3
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+
+
+```python
+class Solution(object):
+ def isPowerOfFour(self, num):
+ """
+ :type num: int
+ :rtype: bool
+ """
+ return bool(re.match(r'^0b1(00)*$', bin(num)))
+```
+
diff --git a/docs/leetcode/python/344._reverse_string.md b/docs/Leetcode_Solutions/Python/344._reverse_string.md
similarity index 94%
rename from docs/leetcode/python/344._reverse_string.md
rename to docs/Leetcode_Solutions/Python/344._reverse_string.md
index 2346c22e6..0e4c0f4fb 100644
--- a/docs/leetcode/python/344._reverse_string.md
+++ b/docs/Leetcode_Solutions/Python/344._reverse_string.md
@@ -1,47 +1,47 @@
-### 344. Reverse String
-
-
-
-题目:
-
-
-
-难度:
-Easy
-
-思路:
-
-不要脸的python AC code:
-
-
-```python
-class Solution(object):
- def reverseString(self, s):
- """
- :type s: str
- :rtype: str
- """
- return s[::-1]
-```
-
-因为python不支持item assignment
-
-所以如果非要用two pointer来做的话,那么会是这样
-
-```python
-class Solution(object):
- def reverseString(self, s):
- """
- :type s: str
- :rtype: str
- """
- lst = list(s)
- n = len(lst)
- start, end = 0, n - 1
-
- while start < end:
- lst[end], lst[start] = lst[start],lst[end]
- start += 1
- end -= 1
- return ''.join(lst)
-```
+### 344. Reverse String
+
+
+
+题目:
+
+
+
+难度:
+Easy
+
+思路:
+
+不要脸的python AC code:
+
+
+```python
+class Solution(object):
+ def reverseString(self, s):
+ """
+ :type s: str
+ :rtype: str
+ """
+ return s[::-1]
+```
+
+因为python不支持item assignment
+
+所以如果非要用two pointer来做的话,那么会是这样
+
+```python
+class Solution(object):
+ def reverseString(self, s):
+ """
+ :type s: str
+ :rtype: str
+ """
+ lst = list(s)
+ n = len(lst)
+ start, end = 0, n - 1
+
+ while start < end:
+ lst[end], lst[start] = lst[start],lst[end]
+ start += 1
+ end -= 1
+ return ''.join(lst)
+```
diff --git a/docs/leetcode/python/345._Reverse_Vowels_of_a_String.md b/docs/Leetcode_Solutions/Python/345._Reverse_Vowels_of_a_String.md
similarity index 100%
rename from docs/leetcode/python/345._Reverse_Vowels_of_a_String.md
rename to docs/Leetcode_Solutions/Python/345._Reverse_Vowels_of_a_String.md
diff --git a/docs/Leetcode_Solutions/Python/347._Top_K_Frequent_Elements.md b/docs/Leetcode_Solutions/Python/347._Top_K_Frequent_Elements.md
new file mode 100644
index 000000000..db073ec64
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/347._Top_K_Frequent_Elements.md
@@ -0,0 +1,92 @@
+# 347. Top K Frequent Elements
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/top-k-frequent-elements/description/
+
+> 内容描述
+
+```
+Given a non-empty array of integers, return the k most frequent elements.
+
+Example 1:
+
+Input: nums = [1,1,1,2,2,3], k = 2
+Output: [1,2]
+Example 2:
+
+Input: nums = [1], k = 1
+Output: [1]
+Note:
+
+You may assume k is always valid, 1 ≤ k ≤ number of unique elements.
+Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
+```
+
+## 解题方案
+
+> 思路 1
+
+思路就是我们先把对应的数字和其出现频次放到一个map里面,然后对这个maps里面的value()集合做一个for loop,这样我们就可以得到一个list,
+list里面的每一个元素代表的就是count为该对应index的key(即数字)的集合
+
+例如:
+```
+k = 2
+nums = [1,1,1,2,2,3,4,4]时,
+
+我们的maps就是{1: 3, 2: 2, 3: 1},
+然后我们新建一个buckets,
+- count为3的数字有1,我们就令bucktes[3] = [1],
+- count为2的数字有2和4,我们就令buckets[2] = [2,4]
+- count为1的数字有3,我们就令buckets[1] = [3]
+
+
+最后我们从bucktes的最后一个元素开始遍历,如果该元素不为初始化的'*'的话,我们就把当前元素(type list)的元素全部extend到res中去,最后返回res
+```
+
+
+时间复杂度为O(n)
+
+```python
+class Solution(object):
+ def topKFrequent(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: List[int]
+ """
+ res, maps, buckets = [], collections.Counter(nums), ['*'] * (len(nums)+1)
+
+ for key in maps.keys():
+ count = maps.get(key)
+ if buckets[count] == '*':
+ buckets[count] = []
+ buckets[count].append(key)
+ i = len(nums)
+ while len(res) < k and i >= 0:
+ if buckets[i] != '*':
+ res.extend(buckets[i])
+ i -= 1
+ return res
+```
+
+> 思路 2
+
+如果题目没有要求时间复杂度必须要优于o(nlgn)的话,下面这个解法真的🐂p
+
+
+```python
+class Solution(object):
+ def topKFrequent(self, nums, K):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: List[int]
+ """
+ return [k for k,v in sorted(collections.Counter(nums).items(), key=lambda (k,v): -v)][:K]
+```
diff --git a/docs/leetcode/python/349._intersection_of_two_arrays.md b/docs/Leetcode_Solutions/Python/349._intersection_of_two_arrays.md
similarity index 94%
rename from docs/leetcode/python/349._intersection_of_two_arrays.md
rename to docs/Leetcode_Solutions/Python/349._intersection_of_two_arrays.md
index eb4052736..2f79b8dd9 100644
--- a/docs/leetcode/python/349._intersection_of_two_arrays.md
+++ b/docs/Leetcode_Solutions/Python/349._intersection_of_two_arrays.md
@@ -1,25 +1,25 @@
-### 349. Intersection of Two Arrays
-
-题目:
-
-
-
-难度:
-
-Easy
-
-
-
-Python一句话作弊
-
-```python
-class Solution(object):
- def intersection(self, nums1, nums2):
- """
- :type nums1: List[int]
- :type nums2: List[int]
- :rtype: List[int]
- """
- return list(set(nums1).intersection(nums2))
-```
-
+### 349. Intersection of Two Arrays
+
+题目:
+
+
+
+难度:
+
+Easy
+
+
+
+Python一句话作弊
+
+```python
+class Solution(object):
+ def intersection(self, nums1, nums2):
+ """
+ :type nums1: List[int]
+ :type nums2: List[int]
+ :rtype: List[int]
+ """
+ return list(set(nums1).intersection(nums2))
+```
+
diff --git a/docs/leetcode/python/350._intersection_of_two_arrays_ii.md b/docs/Leetcode_Solutions/Python/350._intersection_of_two_arrays_ii.md
similarity index 94%
rename from docs/leetcode/python/350._intersection_of_two_arrays_ii.md
rename to docs/Leetcode_Solutions/Python/350._intersection_of_two_arrays_ii.md
index b386d9179..d2a444772 100644
--- a/docs/leetcode/python/350._intersection_of_two_arrays_ii.md
+++ b/docs/Leetcode_Solutions/Python/350._intersection_of_two_arrays_ii.md
@@ -1,65 +1,65 @@
-### 350. Intersection of Two Arrays II
-
-题目:
-
-
-
-
-难度:
-
-Easy
-
-
-sort之后用了双指针来走和看
-
-
-```python
-class Solution(object):
- def intersect(self, nums1, nums2):
- """
- :type nums1: List[int]
- :type nums2: List[int]
- :rtype: List[int]
- """
- nums1.sort()
- nums2.sort()
-
- l1 = len(nums1)
- l2 = len(nums2)
-
- p1 = 0
- p2 = 0
-
- res = []
-
- while p1 < l1 and p2 < l2:
- if nums1[p1] < nums2[p2]:
- p1 += 1
- elif nums1[p1] > nums2[p2]:
- p2 += 1
- else:
- res.append(nums1[p1])
- p1 += 1
- p2 += 1
- return res
-```
-
-两行版本
-```python
-class Solution(object):
- def intersect(self, nums1, nums2):
- """
- :type nums1: List[int]
- :type nums2: List[int]
- :rtype: List[int]
- """
- a, b = map(collections.Counter, (nums1, nums2))
- return list((a & b).elements())
-```
-
-
-
-
-
-
-
+### 350. Intersection of Two Arrays II
+
+题目:
+
+
+
+
+难度:
+
+Easy
+
+
+sort之后用了双指针来走和看
+
+
+```python
+class Solution(object):
+ def intersect(self, nums1, nums2):
+ """
+ :type nums1: List[int]
+ :type nums2: List[int]
+ :rtype: List[int]
+ """
+ nums1.sort()
+ nums2.sort()
+
+ l1 = len(nums1)
+ l2 = len(nums2)
+
+ p1 = 0
+ p2 = 0
+
+ res = []
+
+ while p1 < l1 and p2 < l2:
+ if nums1[p1] < nums2[p2]:
+ p1 += 1
+ elif nums1[p1] > nums2[p2]:
+ p2 += 1
+ else:
+ res.append(nums1[p1])
+ p1 += 1
+ p2 += 1
+ return res
+```
+
+两行版本
+```python
+class Solution(object):
+ def intersect(self, nums1, nums2):
+ """
+ :type nums1: List[int]
+ :type nums2: List[int]
+ :rtype: List[int]
+ """
+ a, b = map(collections.Counter, (nums1, nums2))
+ return list((a & b).elements())
+```
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/353._Design_Snake_Game.md b/docs/Leetcode_Solutions/Python/353. Design Snake Game.md
similarity index 100%
rename from docs/leetcode/python/353._Design_Snake_Game.md
rename to docs/Leetcode_Solutions/Python/353. Design Snake Game.md
diff --git a/docs/leetcode/python/361._Bomb_Enemy.md b/docs/Leetcode_Solutions/Python/361._Bomb_Enemy.md
similarity index 100%
rename from docs/leetcode/python/361._Bomb_Enemy.md
rename to docs/Leetcode_Solutions/Python/361._Bomb_Enemy.md
diff --git a/docs/Leetcode_Solutions/Python/364. Nested List Weight Sum II.md b/docs/Leetcode_Solutions/Python/364. Nested List Weight Sum II.md
new file mode 100644
index 000000000..2bcb6476d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/364. Nested List Weight Sum II.md
@@ -0,0 +1,63 @@
+# 364. Nested List Weight Sum II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/nested-list-weight-sum-ii/description/
+
+> 内容描述
+
+```
+Given a nested list of integers, return the sum of all integers in the list weighted by their depth.
+
+Each element is either an integer, or a list -- whose elements may also be integers or other lists.
+
+Different from the previous question where weight is increasing from root to leaf, now the weight is defined from bottom up. i.e., the leaf level integers have weight 1, and the root level integers have the largest weight.
+
+Example 1:
+
+Input: [[1,1],2,[1,1]]
+Output: 8
+Explanation: Four 1's at depth 1, one 2 at depth 2.
+Example 2:
+
+Input: [1,[4,[6]]]
+Output: 17
+Explanation: One 1 at depth 3, one 4 at depth 2, and one 6 at depth 1; 1*3 + 4*2 + 6*1 = 17.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+很简单,原来基础上稍微改改就行了
+
+假设nestedList铺平开来,里面一共有N个NestedInteger的话,时间复杂度就是O(N), 空间也是O(N)
+
+beats 99.64%
+
+```python
+class Solution:
+ def depthSumInverse(self, nestedList):
+ """
+ :type nestedList: List[NestedInteger]
+ :rtype: int
+ """
+ def helper(nestedList, depth):
+ for nested in nestedList:
+ if nested.isInteger():
+ lookup[depth].append(nested.getInteger())
+ else:
+ helper(nested.getList(), depth+1)
+
+ lookup = collections.defaultdict(list)
+ helper(nestedList, 1)
+ max_depth = max(lookup.keys()) if lookup.keys() else 0
+ return sum([(max_depth + 1 - depth) * value for depth, values in lookup.items() for value in values])
+```
diff --git a/docs/leetcode/python/366._Find_Leaves_of_Binary_Tree.md b/docs/Leetcode_Solutions/Python/366. Find Leaves of Binary Tree.md
similarity index 100%
rename from docs/leetcode/python/366._Find_Leaves_of_Binary_Tree.md
rename to docs/Leetcode_Solutions/Python/366. Find Leaves of Binary Tree.md
diff --git a/docs/leetcode/python/367._valid_perfect_square.md b/docs/Leetcode_Solutions/Python/367._valid_perfect_square.md
similarity index 98%
rename from docs/leetcode/python/367._valid_perfect_square.md
rename to docs/Leetcode_Solutions/Python/367._valid_perfect_square.md
index c51099284..7bb7285d4 100644
--- a/docs/leetcode/python/367._valid_perfect_square.md
+++ b/docs/Leetcode_Solutions/Python/367._valid_perfect_square.md
@@ -14,19 +14,19 @@ Medium
```
-class Solution(object):
- def isPerfectSquare(self, num):
- """
- :type num: int
- :rtype: bool
- """
- if num == 1 or num == 4 : return True
- for i in xrange(num//2):
- if i*i == num:
- return True
- elif i*i > num:
- return False
- return False
+class Solution(object):
+ def isPerfectSquare(self, num):
+ """
+ :type num: int
+ :rtype: bool
+ """
+ if num == 1 or num == 4 : return True
+ for i in xrange(num//2):
+ if i*i == num:
+ return True
+ elif i*i > num:
+ return False
+ return False
```
diff --git a/docs/leetcode/python/369._Plus_One_Linked_List.md b/docs/Leetcode_Solutions/Python/369.Plus One Linked List.md
similarity index 100%
rename from docs/leetcode/python/369._Plus_One_Linked_List.md
rename to docs/Leetcode_Solutions/Python/369.Plus One Linked List.md
diff --git a/docs/leetcode/python/371._sum_of_two_integers.md b/docs/Leetcode_Solutions/Python/371._sum_of_two_integers.md
similarity index 99%
rename from docs/leetcode/python/371._sum_of_two_integers.md
rename to docs/Leetcode_Solutions/Python/371._sum_of_two_integers.md
index f7e949deb..675aa9724 100644
--- a/docs/leetcode/python/371._sum_of_two_integers.md
+++ b/docs/Leetcode_Solutions/Python/371._sum_of_two_integers.md
@@ -44,16 +44,16 @@ x y output
python没有左移,用c++来看
```
-class Solution {
-public:
- int getSum(int a, int b) {
- while (b != 0 ){
- int c = a & b;
- a = a ^ b;
- b = c << 1;
- }
- return a;
- }
+class Solution {
+public:
+ int getSum(int a, int b) {
+ while (b != 0 ){
+ int c = a & b;
+ a = a ^ b;
+ b = c << 1;
+ }
+ return a;
+ }
};
```
diff --git a/docs/Leetcode_Solutions/Python/372._Super_Pow.md b/docs/Leetcode_Solutions/Python/372._Super_Pow.md
new file mode 100644
index 000000000..0502c7542
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/372._Super_Pow.md
@@ -0,0 +1,92 @@
+# 372. Super Pow
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/super-pow/description/
+
+> 内容描述
+
+```
+Your task is to calculate ab mod 1337 where a is a positive integer and b is an extremely large positive integer given in the form of an array.
+
+Example 1:
+
+Input: a = 2, b = [3]
+Output: 8
+Example 2:
+
+Input: a = 2, b = [1,0]
+Output: 1024
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(lgB)******- 空间复杂度: O(1)******
+
+递归
+
+beats 22.60%
+
+```python
+class Solution(object):
+ def superPow(self, a, b):
+ """
+ :type a: int
+ :type b: List[int]
+ :rtype: int
+ """
+ def helper(a, b):
+ if b == 1:
+ return a
+ if b & 1 == 0:
+ tmp = helper(a, b // 2)
+ return (tmp * tmp) % 1337
+ else:
+ tmp = helper(a, b // 2)
+ return (tmp * tmp * a) % 1337
+
+ if a == 0: return 0
+ if a == 1: return 1
+ b = int(''.join(map(str,b)))
+ a %= 1337
+ return helper(a, b)
+```
+
+
+> 思路 2
+******- 时间复杂度: O(len(b))******- 空间复杂度: O(1)******
+
+数学方法,具体证明见[ShuangQuanLi](https://leetcode.com/problems/super-pow/discuss/84466/Math-solusion-based-on-Euler's-theorem-power-called-only-ONCE-C++Java1-line-Python)
+
+***这里 pow(x, y[, z]), 函数是计算x的y次方,如果z在存在,则再对结果进行取模,其结果等效于pow(x,y) %z***
+
+beats 100%
+
+```python
+class Solution(object):
+ def superPow(self, a, b):
+ """
+ :type a: int
+ :type b: List[int]
+ :rtype: int
+ """
+ return 0 if a % 1337 == 0 else pow(a, reduce(lambda x, y: (x * 10 + y) % 1140, b) + 1140, 1337)
+```
+
+自己重写了一下
+
+```python
+class Solution(object):
+ def superPow(self, a, b):
+ """
+ :type a: int
+ :type b: List[int]
+ :rtype: int
+ """
+ return 0 if a % 1337 == 0 else pow(a, int(''.join(map(str,b))) % 1140 + 1140) % 1337
+```
diff --git a/docs/leetcode/python/374._Guess_Number_Higher_or_Lower.md b/docs/Leetcode_Solutions/Python/374._Guess_Number_Higher_or_Lower.md
similarity index 100%
rename from docs/leetcode/python/374._Guess_Number_Higher_or_Lower.md
rename to docs/Leetcode_Solutions/Python/374._Guess_Number_Higher_or_Lower.md
diff --git a/docs/Leetcode_Solutions/Python/376._Wiggle_Subsequence.md b/docs/Leetcode_Solutions/Python/376._Wiggle_Subsequence.md
new file mode 100644
index 000000000..bea7283c4
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/376._Wiggle_Subsequence.md
@@ -0,0 +1,67 @@
+# 376. Wiggle Subsequence
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/wiggle-subsequence/description/
+
+> 内容描述
+
+```
+A sequence of numbers is called a wiggle sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a wiggle sequence.
+
+For example, [1,7,4,9,2,5] is a wiggle sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, [1,4,7,2,5] and [1,7,4,5,5] are not wiggle sequences, the first because its first two differences are positive and the second because its last difference is zero.
+
+Given a sequence of integers, return the length of the longest subsequence that is a wiggle sequence. A subsequence is obtained by deleting some number of elements (eventually, also zero) from the original sequence, leaving the remaining elements in their original order.
+
+Example 1:
+
+Input: [1,7,4,9,2,5]
+Output: 6
+Explanation: The entire sequence is a wiggle sequence.
+Example 2:
+
+Input: [1,17,5,10,13,15,10,5,16,8]
+Output: 7
+Explanation: There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8].
+Example 3:
+
+Input: [1,2,3,4,5,6,7,8,9]
+Output: 2
+Follow up:
+Can you do it in O(n) time?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+
+很简单的思想,从index为1的num开始看
+- 如果比之前一个数字大的话,那么此时就可以看作之前最后一下是negative的序列的后续num
+- 如果比之前一个数字小的话,那么此时就可以看作之前最后一下是positive的序列的后续num
+- 如果与之前一个数字相等的话,那么当前这个数字可以直接删除不要
+
+
+```python
+class Solution(object):
+ def wiggleMaxLength(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ if not nums or len(nums) == 0:
+ return 0
+ positive, negative = 1, 1
+ for i in range(1, len(nums)):
+ if nums[i] > nums[i-1]:
+ positive = negative + 1
+ elif nums[i] < nums[i-1]:
+ negative = positive + 1
+ return max(positive, negative)
+```
diff --git a/docs/leetcode/python/377._combination_sum_iv.md b/docs/Leetcode_Solutions/Python/377._combination_sum_iv.md
similarity index 100%
rename from docs/leetcode/python/377._combination_sum_iv.md
rename to docs/Leetcode_Solutions/Python/377._combination_sum_iv.md
diff --git a/docs/leetcode/python/378._kth_smallest_element_in_a_sorted_matrix.md b/docs/Leetcode_Solutions/Python/378._kth_smallest_element_in_a_sorted_matrix.md
similarity index 100%
rename from docs/leetcode/python/378._kth_smallest_element_in_a_sorted_matrix.md
rename to docs/Leetcode_Solutions/Python/378._kth_smallest_element_in_a_sorted_matrix.md
diff --git a/docs/Leetcode_Solutions/Python/380._Insert_Delete_GetRandom_O(1).md b/docs/Leetcode_Solutions/Python/380._Insert_Delete_GetRandom_O(1).md
new file mode 100644
index 000000000..0c573bcde
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/380._Insert_Delete_GetRandom_O(1).md
@@ -0,0 +1,140 @@
+# 380. Insert Delete GetRandom O(1)
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/insert-delete-getrandom-o1/description/
+
+> 内容描述
+
+```
+Design a data structure that supports all following operations in average O(1) time.
+
+insert(val): Inserts an item val to the set if not already present.
+remove(val): Removes an item val from the set if present.
+getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.
+Example:
+
+// Init an empty set.
+RandomizedSet randomSet = new RandomizedSet();
+
+// Inserts 1 to the set. Returns true as 1 was inserted successfully.
+randomSet.insert(1);
+
+// Returns false as 2 does not exist in the set.
+randomSet.remove(2);
+
+// Inserts 2 to the set, returns true. Set now contains [1,2].
+randomSet.insert(2);
+
+// getRandom should return either 1 or 2 randomly.
+randomSet.getRandom();
+
+// Removes 1 from the set, returns true. Set now contains [2].
+randomSet.remove(1);
+
+// 2 was already in the set, so return false.
+randomSet.insert(2);
+
+// Since 2 is the only number in the set, getRandom always return 2.
+randomSet.getRandom();
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(N)******
+
+
+
+因为对于插入,删除还有同可能性返回数都要O(1),我们知道以下几种典型的数据结构
+```
+dictionary
+list
+set
+LinkedList
+```
+想要删除确定数字必须要知道数字的index,所以list肯定需要,然后怎么通过O(1)时间得到要删除元素的index呢?
+
+mock的时候我没有想出来,墨汁大佬给了hint才想出来的
+
+然后我就想到用字典,key,value分别是element和其index
+
+然后想要O(1)时间同可能性返回数都要,必须要知道总共有多少个数字,那么就要维护一个self.length才行
+
+
+
+beats 98.71%
+
+
+```python
+import random
+class RandomizedSet(object):
+
+ def __init__(self):
+ """
+ Initialize your data structure here.
+ """
+ self.cache = {}
+ self.lst = []
+
+
+ def insert(self, val):
+ """
+ Inserts a value to the set. Returns true if the set did not already contain the specified element.
+ :type val: int
+ :rtype: bool
+ """
+ if val not in self.cache:
+ self.lst.append(val)
+ self.cache[val] = len(self.lst) - 1
+ return True
+ return False
+
+
+ def remove(self, val):
+ """
+ Removes a value from the set. Returns true if the set contained the specified element.
+ :type val: int
+ :rtype: bool
+ """
+ # if the elment is in our RandomizedSet
+ if val in self.cache:
+ # get the index of element in our self.lst
+ idx = self.cache[val]
+ # use the index to update our self.lst
+ self.lst[idx] = self.lst[-1] # swap the value in index and self.length-1
+ # this should be done before pop() operation
+ # because we may only have one element is self.lst
+ self.cache[self.lst[idx]] = idx
+ self.lst.pop()
+ del self.cache[val]
+ return True
+ return False
+
+
+ def getRandom(self):
+ """
+ Get a random element from the set.
+ :rtype: int
+ """
+ # 这种是常规方法
+ # idx = random.randint(0, self.length-1)
+ # return self.lst[idx]
+ # 神奇函数
+ return random.choice(self.lst)
+
+
+
+# Your RandomizedSet object will be instantiated and called as such:
+# obj = RandomizedSet()
+# param_1 = obj.insert(val)
+# param_2 = obj.remove(val)
+# param_3 = obj.getRandom()
+```
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/381._Insert_Delete_GetRandom_O(1)_-_Duplicates_allowed.md b/docs/Leetcode_Solutions/Python/381._Insert_Delete_GetRandom_O(1)_-_Duplicates_allowed.md
new file mode 100644
index 000000000..f7209bd2b
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/381._Insert_Delete_GetRandom_O(1)_-_Duplicates_allowed.md
@@ -0,0 +1,113 @@
+# 381. Insert Delete GetRandom O(1) - Duplicates allowed
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/insert-delete-getrandom-o1-duplicates-allowed/description/
+
+> 内容描述
+
+```
+Design a data structure that supports all following operations in average O(1) time.
+
+Note: Duplicate elements are allowed.
+insert(val): Inserts an item val to the collection.
+remove(val): Removes an item val from the collection if present.
+getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.
+Example:
+
+// Init an empty collection.
+RandomizedCollection collection = new RandomizedCollection();
+
+// Inserts 1 to the collection. Returns true as the collection did not contain 1.
+collection.insert(1);
+
+// Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1].
+collection.insert(1);
+
+// Inserts 2 to the collection, returns true. Collection now contains [1,1,2].
+collection.insert(2);
+
+// getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3.
+collection.getRandom();
+
+// Removes 1 from the collection, returns true. Collection now contains [1,2].
+collection.remove(1);
+
+// getRandom should return 1 and 2 both equally likely.
+collection.getRandom();
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+
+要注意len(self.lst)是O(1)的
+
+beats 96.28%
+
+
+
+```python
+class RandomizedCollection(object):
+
+ def __init__(self):
+ """
+ Initialize your data structure here.
+ """
+ self.cache = collections.defaultdict(set)
+ self.lst = []
+
+
+ def insert(self, val):
+ """
+ Inserts a value to the collection. Returns true if the collection did not already contain the specified element.
+ :type val: int
+ :rtype: bool
+ """
+ self.lst.append(val)
+ self.cache[val].add(len(self.lst)-1)
+ return len(self.cache[val]) == 1
+
+
+ def remove(self, val):
+ """
+ Removes a value from the collection. Returns true if the collection contained the specified element.
+ :type val: int
+ :rtype: bool
+ """
+ if self.cache[val]:
+ idx = self.cache[val].pop()
+ self.lst[idx] = self.lst[-1]
+ # order of two lines below can not be changed
+ # we have to consider there is a condition, self.lst only have one val
+ # and val is at the end of our self.lst
+ self.cache[self.lst[-1]].add(idx)
+ self.cache[self.lst[-1]].discard(len(self.lst) - 1)
+ self.lst.pop()
+ return True
+ return False
+
+
+ def getRandom(self):
+ """
+ Get a random element from the collection.
+ :rtype: int
+ """
+ return random.choice(self.lst)
+
+
+
+# Your RandomizedCollection object will be instantiated and called as such:
+# obj = RandomizedCollection()
+# param_1 = obj.insert(val)
+# param_2 = obj.remove(val)
+# param_3 = obj.getRandom()
+```
diff --git a/docs/leetcode/python/382._linked_list_random_node.md b/docs/Leetcode_Solutions/Python/382._linked_list_random_node.md
similarity index 100%
rename from docs/leetcode/python/382._linked_list_random_node.md
rename to docs/Leetcode_Solutions/Python/382._linked_list_random_node.md
diff --git a/docs/leetcode/python/383._ransom_note.md b/docs/Leetcode_Solutions/Python/383._ransom_note.md
similarity index 95%
rename from docs/leetcode/python/383._ransom_note.md
rename to docs/Leetcode_Solutions/Python/383._ransom_note.md
index 82fc223d6..6a6ee16e7 100644
--- a/docs/leetcode/python/383._ransom_note.md
+++ b/docs/Leetcode_Solutions/Python/383._ransom_note.md
@@ -1,53 +1,53 @@
-### 383. Ransom Note
-
-题目:
-
-
-
-难度 : Easy
-
-
-
-略微想了一下,用了一个dictionary来存magazine里面的单字出现的个数,然后来对应check是否可以用来组成ransomNote
-
-
-```python
-class Solution(object):
- def canConstruct(self, ransomNote, magazine):
- """
- :type ransomNote: str
- :type magazine: str
- :rtype: bool
- """
- maps = {}
- for i in magazine:
- if i in maps:
- maps[i] += 1
- else:
- maps[i] = 1
- for i in ransomNote:
- if i not in maps:
- return False
- else:
- maps[i] -= 1
- if maps[i] < 0:
- return False
- return True
-```
-解法2:
-
-```python
-class Solution(object):
- def canConstruct(self, ransomNote, magazine):
- """
- :type ransomNote: str
- :type magazine: str
- :rtype: bool
- """
- magCounter = collections.Counter(magazine)
- ranCounter = collections.Counter(ransomNote)
- for k in ranCounter:
- if ranCounter.get(k) > magCounter.get(k):
- return False
- return True
-```
+### 383. Ransom Note
+
+题目:
+
+
+
+难度 : Easy
+
+
+
+略微想了一下,用了一个dictionary来存magazine里面的单字出现的个数,然后来对应check是否可以用来组成ransomNote
+
+
+```python
+class Solution(object):
+ def canConstruct(self, ransomNote, magazine):
+ """
+ :type ransomNote: str
+ :type magazine: str
+ :rtype: bool
+ """
+ maps = {}
+ for i in magazine:
+ if i in maps:
+ maps[i] += 1
+ else:
+ maps[i] = 1
+ for i in ransomNote:
+ if i not in maps:
+ return False
+ else:
+ maps[i] -= 1
+ if maps[i] < 0:
+ return False
+ return True
+```
+解法2:
+
+```python
+class Solution(object):
+ def canConstruct(self, ransomNote, magazine):
+ """
+ :type ransomNote: str
+ :type magazine: str
+ :rtype: bool
+ """
+ magCounter = collections.Counter(magazine)
+ ranCounter = collections.Counter(ransomNote)
+ for k in ranCounter:
+ if ranCounter.get(k) > magCounter.get(k):
+ return False
+ return True
+```
diff --git a/docs/leetcode/python/384._Shuffle_an_Array.md b/docs/Leetcode_Solutions/Python/384. Shuffle an Array.md
similarity index 100%
rename from docs/leetcode/python/384._Shuffle_an_Array.md
rename to docs/Leetcode_Solutions/Python/384. Shuffle an Array.md
diff --git a/docs/Leetcode_Solutions/Python/386._Lexicographical_Numbers.md b/docs/Leetcode_Solutions/Python/386._Lexicographical_Numbers.md
new file mode 100644
index 000000000..4782bacfa
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/386._Lexicographical_Numbers.md
@@ -0,0 +1,86 @@
+# 386. Lexicographical Numbers
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/lexicographical-numbers/description/
+
+> 内容描述
+
+```
+
+Given an integer n, return 1 - n in lexicographical order.
+
+For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9].
+
+Please optimize your algorithm to use less time and space. The input size may be as large as 5,000,000.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+那当然是直接转换成string比较排序啊,多么暴力,简单明了, ```beats 66.87%```
+
+
+```python
+class Solution(object):
+ def lexicalOrder(self, n):
+ """
+ :type n: int
+ :rtype: List[int]
+ """
+ return sorted(range(1, n+1), key=lambda x: str(x))
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+其实我们每次只要知道下一个数是啥就行了
+例如对于67这个数,
+- 它的下一个数要么是670(如果670 <= n )的话
+- 要么是68(如果68 <= n )的话, 同时还要注意,如果我们例子中n换成200的话,如果当前数字为199,那其实它的下一个数字应该是2而不是200,
+所以这里我们要多加一个判断```(cur + 1) % 10 != 0```, 然后对于尾数是9的数字我们要一直除以10让它尾数不是9之后再加1,即```199 --> 2```的过程
+- 要么是7(当然7肯定小于n了,因为67都出现了)
+
+
+这个方法```beats 94.94%```
+
+```python
+class Solution(object):
+ def lexicalOrder(self, n):
+ """
+ :type n: int
+ :rtype: List[int]
+ """
+ res = []
+ cur = 1
+ for i in range(n):
+ res.append(cur)
+ if (cur * 10 <= n):
+ cur *= 10
+ elif cur + 1 <= n and (cur + 1) % 10 != 0:
+ cur += 1
+ else:
+ while (cur/10) % 10 == 9:
+ cur /= 10
+ cur = cur / 10 + 1
+ return res
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/387._first_unique_character_in_a_string.md b/docs/Leetcode_Solutions/Python/387._first_unique_character_in_a_string.md
new file mode 100644
index 000000000..d7e888853
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/387._first_unique_character_in_a_string.md
@@ -0,0 +1,75 @@
+# 387. First Unique Character in a String
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/first-unique-character-in-a-string/description/
+
+> 内容描述
+
+```
+Given a string, find the first non-repeating character in it and return it's index. If it doesn't exist, return -1.
+
+Examples:
+
+s = "leetcode"
+return 0.
+
+s = "loveleetcode",
+return 2.
+Note: You may assume the string contain only lowercase letters.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+Python作弊法
+
+用Python的Counter模块
+
+可以参考
+
+
+
+
+```python
+class Solution(object):
+ def firstUniqChar(self, s):
+ """
+ :type s: str
+ :rtype: int
+ """
+ d = collections.Counter(s)
+ for i, c in enumerate(s):
+ if d[c] == 1:
+ return i
+ return -1
+```
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+利用问题的特性,因为只有可能是小写字母,所以可以用一个长度为26的array, 先数一遍char的数量,然后enumerate从左往右又来
+
+```python
+class Solution(object):
+ def firstUniqChar(self, s):
+ """
+ :type s: str
+ :rtype: int
+ """
+ cnt = [0 for i in range(26)]
+ for c in s:
+ cnt[ord(c) - ord('a')] += 1
+
+ for idx, c in enumerate(s):
+ if cnt[ord(c) - ord('a')] == 1:
+ return idx
+ return -1
+```
diff --git a/docs/Leetcode_Solutions/Python/388._Longest_Absolute_File_Path.md b/docs/Leetcode_Solutions/Python/388._Longest_Absolute_File_Path.md
new file mode 100644
index 000000000..9e1d12614
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/388._Longest_Absolute_File_Path.md
@@ -0,0 +1,132 @@
+# 388. Longest Absolute File Path
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/longest-absolute-file-path/description/
+
+> 内容描述
+
+```
+Suppose we abstract our file system by a string in the following manner:
+
+The string "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" represents:
+
+dir
+ subdir1
+ subdir2
+ file.ext
+The directory dir contains an empty sub-directory subdir1 and a sub-directory subdir2 containing a file file.ext.
+
+The string "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext" represents:
+
+dir
+ subdir1
+ file1.ext
+ subsubdir1
+ subdir2
+ subsubdir2
+ file2.ext
+The directory dir contains two sub-directories subdir1 and subdir2. subdir1 contains a file file1.ext and an empty second-level sub-directory subsubdir1. subdir2 contains a second-level sub-directory subsubdir2 containing a file file2.ext.
+
+We are interested in finding the longest (number of characters) absolute path to a file within our file system. For example, in the second example above, the longest absolute path is "dir/subdir2/subsubdir2/file2.ext", and its length is 32 (not including the double quotes).
+
+Given a string representing the file system in the above format, return the length of the longest absolute path to file in the abstracted file system. If there is no file in the system, return 0.
+
+Note:
+The name of a file contains at least a . and an extension.
+The name of a directory or sub-directory will not contain a ..
+Time complexity required: O(n) where n is the size of the input string.
+
+Notice that a/aa/aaa/file1.txt is not the longest file path, if there is another path aaaaaaaaaaaaaaaaaaaaa/sth.png.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+我们首先观察到每个```文件夹```或者是```文件```前面都会有一个```'\n'```, 还有对应其层数个数的```'\t'```.
+- 所以首先根据```'\n'```分行,然后算出该```文件/文件夹```的层数```depth```
+- 如果是```文件```,我们需要更新```maxlen```
+- 如果是```文件夹```,我们需要更新该```depth```下的```pathlen```
+
+### 程序变量解释
+
+- ```maxlen``` 代表目前最大子串的长度
+- ```pathlen``` 每一个```depth```下对应的```path```长度
+
+#### 特别需要注意的是,```'\t'```的长度是1
+有的人仍然会有疑问,每次碰到文件夹都直接更新```pathlen```会不会导致本来长的反而变得短了,但是我们可以看到字符串的排版格式,每层```path```都是严格有自己的分级的,
+因此不会出现这样的问题。
+例如:
+- The string ```"dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext"``` represents:
+```
+dir
+ subdir1
+ file1.ext
+ subsubdir1
+ subdir2
+ subsubdir2
+ file2.ext
+```
+其最大长度是```32```, ```"dir/subdir2/subsubdir2/file2.ext"```
+
+- 如果变成```"dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir20\n\t\tsubsubdir2\n\t\t\tfile2.ext"```,
+
+```
+dir
+ subdir1
+ file1.ext
+ subsubdir1
+ subdir20
+ subsubdir2
+ file2.ext
+```
+
+最大长度就是```33```,
+```"dir/subdir2/subsubdir20/file2.ext"```
+
+
+- 如果变成
+```"dir\n\tsubdir1000000000000\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext"```
+
+```
+dir
+ subdir10000000000000
+ file1.ext
+ subsubdir1
+ subdir20
+ subsubdir2
+ file2.ext
+```
+
+最大长度就是```34```,```"dir/subdir10000000000000/file1.ext"```
+
+beats 99.66%
+
+```python
+class Solution(object):
+ def lengthLongestPath(self, input):
+ """
+ :type input: str
+ :rtype: int
+ """
+ lap = 0
+ depth_len = {0: 0}
+ for line in input.splitlines():
+ name = line.lstrip('\t')
+ # 前面有几个'\t', depth就是几, 因为'\t'的长度为1
+ depth = len(line) - len(name)
+ if '.' in name:
+ lap = max(lap, depth_len[depth]+len(name))
+ else:
+ # 加1是为了加上一个path分隔符'/'的长度
+ depth_len[depth+1] = depth_len[depth] + 1 + len(name)
+ return lap
+```
+
+
diff --git a/docs/leetcode/python/389._find_the_difference.md b/docs/Leetcode_Solutions/Python/389._find_the_difference.md
similarity index 100%
rename from docs/leetcode/python/389._find_the_difference.md
rename to docs/Leetcode_Solutions/Python/389._find_the_difference.md
diff --git a/docs/Leetcode_Solutions/Python/392._is_subsequence.md b/docs/Leetcode_Solutions/Python/392._is_subsequence.md
new file mode 100644
index 000000000..84297dd49
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/392._is_subsequence.md
@@ -0,0 +1,185 @@
+# 392. Is Subsequence
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/is-subsequence/description/
+
+> 内容描述
+
+```
+
+Given a string s and a string t, check if s is subsequence of t.
+
+You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) string, and s is a short string (<=100).
+
+A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ace" is a subsequence of "abcde" while "aec" is not).
+
+Example 1:
+s = "abc", t = "ahbgdc"
+
+Return true.
+
+Example 2:
+s = "axc", t = "ahbgdc"
+
+Return false.
+
+Follow up:
+If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(len(s)+len(t))******- 空间复杂度: O(1)******
+
+
+最naive的思路是递归,原来可以beats 53.74%
+
+
+但是今天上来发现多了case,超时过不了了
+
+时间复杂度为O(len(s)+len(t))
+
+
+
+
+```
+class Solution(object):
+ def isSubsequence(self, s, t):
+ """
+ :type s: str
+ :type t: str
+ :rtype: bool
+ """
+ if s == '':
+ return True
+ for i in range(len(t)):
+ if t[i] == s[0]:
+ return self.isSubsequence(s[1:],t[i+1:])
+
+ return False
+```
+
+> 思路 2
+******- 时间复杂度: O(max(len(s), len(t)))******- 空间复杂度: O(1)******
+
+因为递归操作以及对字符串的操作太过于昂贵,所以用index来处理,节省了时间和空间
+
+时间复杂度是O(max(len(s), len(t)))
+
+beats 40%
+
+
+```python
+class Solution(object):
+ def isSubsequence(self, s, t):
+ """
+ :type s: str
+ :type t: str
+ :rtype: bool
+ """
+ if s == '':
+ return True
+ ps, pt = 0, 0
+ while ps < len(s) and pt < len(t):
+ if s[ps] == t[pt]:
+ ps += 1
+ pt += 1
+ return ps >= len(s)
+```
+> 思路 3
+******- 时间复杂度: O(len(t))******- 空间复杂度: O(1)******
+
+
+想到说对于每一个s中的字符,看看在不在,找到了就记录一下t的当前位置idx,下次从t的idx+1后面开始找
+
+
+```python
+class Solution(object):
+ def isSubsequence(self, s, t):
+ """
+ :type s: str
+ :type t: str
+ :rtype: bool
+ """
+ idx = 0
+ for c in s:
+ idx = t.find(c, idx)
+ if idx == -1:
+ return False
+ idx += 1
+ return True
+```
+
+## follow up question
+```
+If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code?
+```
+
+> 思路 1
+******- 时间复杂度: O(lt+k*ms*O(lg(lt)))******- 空间复杂度: O(lt)******
+
+我们可以先把t里面的所有字符和其出现的idx的list分别作为key和value放进一个字典里面
+
+然后对于s中的每个字符,我们要做两步判断:
+1. 如果这个字符不在字典里面,直接返回False
+2. 如果这个字符在字典里面,那我们就看看我们在这个字符在t里面出现的idx的list里面是不是有比上一个字符的idx更大的idx,
+
+例如对于输入
+```
+"abc"
+"ahbgdc"
+```
+
+```
+首先初始化idx为-1
+lookup = {'a': [0], 'c': [5], 'b': [2], 'd': [4], 'g': [3], 'h': [1]}
+我们先找字符a,发现a在lookup里面的list为[0],并且里面存在比idx -1更大的元素,所以我们找到了字符a,更新 idx为1,意味着下一个字符要从t的idx 1开始找
+开始找字符b,发现b在lookup里面的list为[2],并且里面存在比idx 1更大的元素,所以我们找到了字符b,更新idx 为3,意味着下一个字符要从t的idx 3开始找
+开始找字符c,发现c在lookup里面的list为[5],并且里面存在比idx 3更大的元素,所以我们找到了字符c,更新idx 为6,意味着下一个字符要从t的idx 6开始找
+
+但是此时所有字符都已经找到,直接返回True
+```
+
+假设t的长度为lt,s的长度为ls,一共有k个s(假设最长的一个s长度为ms)
+
+我们只需要最开始对整个t做一个遍历,时间复杂度为O(lt),同时用了一个字典,空间复杂度为O(lt),
+
+然后对于每一个s的每一个字符,我们都只需要进行一个二分查找,时间复杂度为O(lg(lt)),因为最坏有可能t只有一个字符,它在字典里面对应的list的长度就是lt
+
+因此最终的时间复杂度为O(lt+k*ms*O(lg(lt))),时间复杂度为O(lt)
+
+
+```python
+class Solution(object):
+ def isSubsequence(self, s, t):
+ """
+ :type s: str
+ :type t: str
+ :rtype: bool
+ """
+ lookup = {}
+ for i in range(len(t)):
+ if t[i] in lookup:
+ lookup[t[i]].append(i)
+ else:
+ lookup[t[i]] = [i]
+ idx = -1
+ for c in s:
+ if c not in lookup:
+ return False
+ else:
+ c_idx = bisect.bisect_left(lookup[c], idx)
+ if c_idx == len(lookup[c]): # this means we don't find next char of s in t
+ return False
+ idx = lookup[c][c_idx] + 1 # we have to find next char from the prev char's index + 1
+ return True
+```
+
+
+
+
diff --git a/docs/leetcode/python/394._decode_string.md b/docs/Leetcode_Solutions/Python/394._decode_string.md
similarity index 100%
rename from docs/leetcode/python/394._decode_string.md
rename to docs/Leetcode_Solutions/Python/394._decode_string.md
diff --git a/docs/Leetcode_Solutions/Python/400._Nth_Digit.md b/docs/Leetcode_Solutions/Python/400._Nth_Digit.md
new file mode 100644
index 000000000..5dd5f3ccb
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/400._Nth_Digit.md
@@ -0,0 +1,113 @@
+# 400. Nth Digit
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/nth-digit/description/
+
+> 内容描述
+
+```
+Find the nth digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...
+
+Note:
+n is positive and will fit within the range of a 32-bit signed integer (n < 231).
+
+Example 1:
+
+Input:
+3
+
+Output:
+3
+Example 2:
+
+Input:
+11
+
+Output:
+0
+
+Explanation:
+The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which is part of the number 10.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(lgn)******- 空间复杂度: O(1)******
+
+
+
+这道简单题我服, tag是math,找规律
+
+```
+1- 9 : 9 → 只占1位 9
+10 - 99: 90 → 两位 90 * 2
+100 - 999: 900 → 三位 900 * 3
+1000 - 9999: 9000 → 四位 9000 * 4
+```
+参考微信大佬[caitao7](https://leetcode.com/haitao7/)的代码,加了注释,修改了变量名
+
+```python
+class Solution(object):
+ def findNthDigit(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ digits_count = 1 # 当前区间数字的位数
+ while n >= 9 * 10 ** (digits_count-1) * digits_count:
+ n -= 9 * 10 ** (digits_count-1) * digits_count
+ digits_count += 1
+ target_num = 10 ** (digits_count-1) - 1 + n // digits_count # 我们要从这个数字上面取digit
+ target_digit = n % digits_count # 我们要从这个数字上面取第几位digit
+ if target_digit == 0: # 取第0位digit其实就是说这个数字的个数位刚好到达我们的第n位digit
+ return target_num % 10
+ return ((target_num+1) / 10 ** (digits_count-target_digit)) % 10
+```
+
+
+> 思路 2
+******- 时间复杂度: O(lgn)******- 空间复杂度: O(1)******
+
+改进[agave](https://leetcode.com/problems/nth-digit/discuss/88417/4-liner-in-Python-and-complexity-analysis)大神的解法
+
+So we can "fast-skip" those numbers until we find the size of the number that will hold our digit.
+At the end of the loop, we will have:
+
+- start: first number of size size (will be power of 10)
+- n: will be the number of digits that we need to count after start
+
+How do we get the number that will hold the digit? It will be start + (n - 1) // size (we use n - 1 because we need zero-based index). Once we have that number, we can get the ```[(n - 1) % size]-th``` digit of that number, and that will be our result.
+
+```python
+class Solution(object):
+ def findNthDigit(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ start, size, step = 1, 1, 9
+ while n > size * step:
+ n -= size * step
+ start, size, step = start * 10, size + 1, step * 10
+ num = start + (n - 1) // size # 所要取的数字,(n - 1) % size为取该数字的第几位
+ mod = 0
+ for i in range(size - (n - 1) % size):
+ mod = num % 10
+ num /= 10
+ return mod
+```
+
+The while loop takes O(log(n)) time because a number n will have at most O(log(n)) digits. Then the return statement takes O(log(n)) time to convert the number to string. So total time complexity is O(log(n)), with O(1) extra space for the string.
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/401._binary_watch.md b/docs/Leetcode_Solutions/Python/401._binary_watch.md
similarity index 100%
rename from docs/leetcode/python/401._binary_watch.md
rename to docs/Leetcode_Solutions/Python/401._binary_watch.md
diff --git a/docs/Leetcode_Solutions/Python/402._Remove_K_Digits.md b/docs/Leetcode_Solutions/Python/402._Remove_K_Digits.md
new file mode 100644
index 000000000..bed940c96
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/402._Remove_K_Digits.md
@@ -0,0 +1,98 @@
+# 402. Remove K Digits
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/remove-k-digits/description/
+
+> 内容描述
+
+```
+Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.
+
+Note:
+The length of num is less than 10002 and will be ≥ k.
+The given num does not contain any leading zero.
+Example 1:
+
+Input: num = "1432219", k = 3
+Output: "1219"
+Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.
+Example 2:
+
+Input: num = "10200", k = 1
+Output: "200"
+Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.
+Example 3:
+
+Input: num = "10", k = 2
+Output: "0"
+Explanation: Remove all the digits from the number and it is left with nothing which is 0.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+我们知道如果数字相等话,这个数字越靠左它代表的实际数值就越大,所以我们应该优先删除它
+
+```
+Just a few of my intuition to make myself more comfortable about why using greedy.
+In fact, any time you see "smallest","as... as possible",
+you should try greedy first and that might be a really nice solution.
+By meaning greedy, we mean to start from most significant digit (left most digit).
+If you can replace that digit (k>0) with a smaller number (by removing that digit), you remove it.
+The following digit takes the place and the number becomes smaller.
+And as you are operating from most significant digit, the resulting number is guaranteed to be the smallest.
+```
+
+```python
+class Solution(object):
+ def removeKdigits(self, num, k):
+ """
+ :type num: str
+ :type k: int
+ :rtype: str
+ """
+ if k == 0:
+ return num
+
+ stack = []
+ for c in num:
+ while k and stack and c < stack[-1]:
+ stack.pop()
+ k -= 1
+ stack.append(c)
+ while k:
+ stack.pop()
+ k -= 1
+ res = ''.join(stack).lstrip('0')
+ return res if res else '0'
+```
+
+写的更精简就是:
+
+```python
+class Solution(object):
+ def removeKdigits(self, num, k):
+ """
+ :type num: str
+ :type k: int
+ :rtype: str
+ """
+ if k == 0:
+ return num
+
+ stack = []
+ for c in num:
+ while k and stack and c < stack[-1]:
+ stack.pop()
+ k -= 1
+ stack.append(c)
+ res = ''.join(stack[:len(stack)-k]).lstrip('0')
+ return res if res else '0'
+```
diff --git a/docs/Leetcode_Solutions/Python/403._Frog_Jump.md b/docs/Leetcode_Solutions/Python/403._Frog_Jump.md
new file mode 100644
index 000000000..9ba1e48af
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/403._Frog_Jump.md
@@ -0,0 +1,161 @@
+# 403. Frog Jump
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/frog-jump/description/
+
+> 内容描述
+
+```
+A frog is crossing a river. The river is divided into x units and at each unit there may or may not exist a stone. The frog can jump on a stone, but it must not jump into the water.
+
+Given a list of stones' positions (in units) in sorted ascending order, determine if the frog is able to cross the river by landing on the last stone. Initially, the frog is on the first stone and assume the first jump must be 1 unit.
+
+If the frog's last jump was k units, then its next jump must be either k - 1, k, or k + 1 units. Note that the frog can only jump in the forward direction.
+
+Note:
+
+The number of stones is ≥ 2 and is < 1,100.
+Each stone's position will be a non-negative integer < 231.
+The first stone's position is always 0.
+Example 1:
+
+[0,1,3,5,6,8,12,17]
+
+There are a total of 8 stones.
+The first stone at the 0th unit, second stone at the 1st unit,
+third stone at the 3rd unit, and so on...
+The last stone at the 17th unit.
+
+Return true. The frog can jump to the last stone by jumping
+1 unit to the 2nd stone, then 2 units to the 3rd stone, then
+2 units to the 4th stone, then 3 units to the 6th stone,
+4 units to the 7th stone, and 5 units to the 8th stone.
+Example 2:
+
+[0,1,2,3,4,8,9,11]
+
+Return false. There is no way to jump to the last stone as
+the gap between the 5th and 6th stone is too large.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^3)******- 空间复杂度: O(N^2)******
+
+这个题目肯定要用dp来做的
+
+然后我开始找了一个方法,就是让dp[x][y]代表我们可以到达stone x,我们是否可以到达z
+
+所以初始值就是dp[0][1] = 1
+
+如果```dp[x][y] == 1```的话,并且对于一个```z```大于```y```,如果```abs((stones[z] - stones[y]) - (stones[y) - stones[x)) <= 1```,
+那么```dp[y][z] = 1```
+
+但是超时了
+
+```python
+class Solution(object):
+ def canCross(self, stones):
+ """
+ :type stones: List[int]
+ :rtype: bool
+ """
+ if stones[1] != 1:
+ return False
+
+ dp = [[0] * len(stones) for i in range(len(stones))]
+ dp[0][1] = 1
+ for y in range(1, len(stones)):
+ for x in range(y):
+ for z in range(y+1, len(stones)):
+ if not dp[x][y]:
+ continue
+ else:
+ if abs((stones[z]-stones[y])-(stones[y]-stones[x])) <= 1:
+ if z == len(stones)-1:
+ return True
+ dp[y][z] = 1
+ for i in range(len(dp)):
+ if dp[i][-1]:
+ return True
+ return False
+```
+
+
+
+
+
+> 思路 2
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N^2)******
+
+于是想到了另外一种dp,用一个字典,存的key和value分别是stone 的位置和从该位置能跳的步数的set
+
+初始值位置0的value只有1,那么初始位置1的value有(0,1,2)
+
+最后我们看看,如果有哪个位置和其value中的任意一个步数的和可以凑齐最后一个位置,那么最后一个位置可达
+
+但是这样不是很好判断,其实如果最后一个位置对应的value set非空的话也说明最后一个位置可达,因为不可达我们一定对其无操作,其value set必为空
+
+beats 66.77%
+```python
+class Solution(object):
+ def canCross(self, stones):
+ """
+ :type stones: List[int]
+ :rtype: bool
+ """
+ lookup = {}
+ for i in range(len(stones)):
+ lookup[stones[i]] = set()
+ lookup[0].add(1)
+
+ for i in range(len(stones)):
+ for step in lookup[stones[i]]:
+ if step > 0 and stones[i] + step in lookup:
+ # lookup[stones[i]+step] = lookup[stones[i]+step].union(set([step-1,step,step+1]))
+ lookup[stones[i]+step].update([step-1,step,step+1])
+ return len(lookup[stones[-1]]) > 0
+```
+
+或者将value看作可以到达该key的步数,beats 47.71%
+
+```python
+class Solution(object):
+ def canCross(self, stones):
+ """
+ :type stones: List[int]
+ :rtype: bool
+ """
+ lookup = {}
+ for i in range(len(stones)):
+ lookup[stones[i]] = set()
+ lookup[0].add(0)
+
+ for i in range(len(stones)):
+ for k in lookup[stones[i]]:
+ for step in (k-1,k,k+1):
+ if step > 0 and stones[i] + step in lookup:
+ lookup[stones[i]+step].add(step)
+ return len(lookup[stones[-1]]) > 0
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/404._sum_of_left_leaves.md b/docs/Leetcode_Solutions/Python/404._sum_of_left_leaves.md
similarity index 100%
rename from docs/leetcode/python/404._sum_of_left_leaves.md
rename to docs/Leetcode_Solutions/Python/404._sum_of_left_leaves.md
diff --git a/docs/leetcode/python/405._Convert_a_Number_to_Hexadecimal.md b/docs/Leetcode_Solutions/Python/405. Convert a Number to Hexadecimal.md
similarity index 100%
rename from docs/leetcode/python/405._Convert_a_Number_to_Hexadecimal.md
rename to docs/Leetcode_Solutions/Python/405. Convert a Number to Hexadecimal.md
diff --git a/docs/Leetcode_Solutions/Python/406._Queue_Reconstruction_by_Height.md b/docs/Leetcode_Solutions/Python/406._Queue_Reconstruction_by_Height.md
new file mode 100644
index 000000000..c6cbff2ff
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/406._Queue_Reconstruction_by_Height.md
@@ -0,0 +1,69 @@
+# 406. Queue Reconstruction by Height
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/queue-reconstruction-by-height/description/
+
+> 内容描述
+
+```
+
+Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue.
+
+Note:
+The number of people is less than 1,100.
+
+
+Example
+
+Input:
+[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
+
+Output:
+[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(1)******
+
+People are only counting (in their k-value) taller or equal-height others standing in front of them.
+So a smallest person is completely irrelevant for all taller ones. And of all smallest people,
+the one standing most in the back is even completely irrelevant for everybody else. Nobody is counting that person.
+So we can first arrange everybody else, ignoring that one person. And then just insert that person appropriately.
+Now note that while this person is irrelevant for everybody else, everybody else is relevant for this person -
+this person counts exactly everybody in front of them. So their count-value tells you exactly the index they must be standing.
+
+So you can first solve the sub-problem with all but that one person and then just insert that person appropriately.
+And you can solve that sub-problem the same way, first solving the sub-sub-problem with all
+but the last-smallest person of the subproblem. And so on. The base case is when you have the sub-…-sub-problem of zero people.
+You’re then inserting the people in the reverse order, i.e., that overall last-smallest person in the very end
+and thus the first-tallest person in the very beginning. That’s what the above solution does,
+Sorting the people from the first-tallest to the last-smallest, and inserting them one by one as appropriate.
+
+参考[stefan](https://leetcode.com/problems/queue-reconstruction-by-height/discuss/89359)
+
+不算返回结果res的话,空间复杂度为O(1)
+
+beats 99.12%
+
+```python
+class Solution(object):
+ def reconstructQueue(self, people):
+ """
+ :type people: List[List[int]]
+ :rtype: List[List[int]]
+ """
+ people.sort(key = lambda x: (-x[0], x[1]))
+ res = []
+ for p in people:
+ res.insert(p[1], p)
+ return res
+```
+
+
diff --git a/docs/leetcode/python/412._fizz_buzz.md b/docs/Leetcode_Solutions/Python/412._fizz_buzz.md
similarity index 100%
rename from docs/leetcode/python/412._fizz_buzz.md
rename to docs/Leetcode_Solutions/Python/412._fizz_buzz.md
diff --git a/docs/leetcode/python/413._Arithmetic_Slices.md b/docs/Leetcode_Solutions/Python/413. Arithmetic Slices.md
similarity index 100%
rename from docs/leetcode/python/413._Arithmetic_Slices.md
rename to docs/Leetcode_Solutions/Python/413. Arithmetic Slices.md
diff --git a/docs/leetcode/python/414._third_maximum_number.md b/docs/Leetcode_Solutions/Python/414._third_maximum_number.md
similarity index 100%
rename from docs/leetcode/python/414._third_maximum_number.md
rename to docs/Leetcode_Solutions/Python/414._third_maximum_number.md
diff --git a/docs/leetcode/python/415._add_strings.md b/docs/Leetcode_Solutions/Python/415._add_strings.md
similarity index 94%
rename from docs/leetcode/python/415._add_strings.md
rename to docs/Leetcode_Solutions/Python/415._add_strings.md
index 4c7be7b0a..95663f8e2 100644
--- a/docs/leetcode/python/415._add_strings.md
+++ b/docs/Leetcode_Solutions/Python/415._add_strings.md
@@ -6,7 +6,7 @@
> 原题连接
-* https://leetcode.com/problems/add-strings
+* https://leetcode.com/problems/add-strings/description/
> 内容描述
diff --git a/docs/leetcode/python/416._Partition_Equal_Subset_Sum.md b/docs/Leetcode_Solutions/Python/416._Partition_Equal_Subset_Sum.md
similarity index 95%
rename from docs/leetcode/python/416._Partition_Equal_Subset_Sum.md
rename to docs/Leetcode_Solutions/Python/416._Partition_Equal_Subset_Sum.md
index 045089748..1dd92f5fa 100644
--- a/docs/leetcode/python/416._Partition_Equal_Subset_Sum.md
+++ b/docs/Leetcode_Solutions/Python/416._Partition_Equal_Subset_Sum.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/partition-equal-subset-sum
+* https://leetcode.com/problems/partition-equal-subset-sum/description/
> 内容描述
diff --git a/docs/leetcode/python/421._Maximum_XOR_of_Two_Numbers_in_an_Array.md b/docs/Leetcode_Solutions/Python/421._Maximum_XOR_of_Two_Numbers_in_an_Array.md
similarity index 100%
rename from docs/leetcode/python/421._Maximum_XOR_of_Two_Numbers_in_an_Array.md
rename to docs/Leetcode_Solutions/Python/421._Maximum_XOR_of_Two_Numbers_in_an_Array.md
diff --git a/docs/leetcode/python/422._Valid_Word_Square.md b/docs/Leetcode_Solutions/Python/422. Valid Word Square.md
similarity index 100%
rename from docs/leetcode/python/422._Valid_Word_Square.md
rename to docs/Leetcode_Solutions/Python/422. Valid Word Square.md
diff --git a/docs/Leetcode_Solutions/Python/424._Longest_Repeating_Character_Replacement.md b/docs/Leetcode_Solutions/Python/424._Longest_Repeating_Character_Replacement.md
new file mode 100644
index 000000000..5bebbafea
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/424._Longest_Repeating_Character_Replacement.md
@@ -0,0 +1,159 @@
+# 424. Longest Repeating Character Replacement
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/longest-repeating-character-replacement/description/
+
+> 内容描述
+
+```
+Given a string that consists of only uppercase English letters, you can replace any letter in the string with another letter at most k times. Find the length of a longest substring containing all repeating letters you can get after performing the above operations.
+
+Note:
+Both the string's length and k will not exceed 104.
+
+Example 1:
+
+Input:
+s = "ABAB", k = 2
+
+Output:
+4
+
+Explanation:
+Replace the two 'A's with two 'B's or vice versa.
+Example 2:
+
+Input:
+s = "AABABBA", k = 1
+
+Output:
+4
+
+Explanation:
+Replace the one 'A' in the middle with 'B' and form "AABBBBA".
+The substring "BBBB" has the longest repeating letters, which is 4.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+假设我们用来替换别的字符的那个字符是c,那么题目可以转变成这样一个问题,在一个window里面,最多有k个不为c的字符,这样才是满足条件的
+
+那么这样的字符c有哪些呢?毫无疑问是set(s)里面的这些字符。
+
+然后我们维护一个window,不断计算不为c的字符的个数counter,如果counter大于n了说明我们怎么替换也不行了,我们就要将start往前挪一格,否则一直挪end。
+每次挪完end之后都要记得更新这一轮的最大长度
+
+每个字符c循环后都要更新最终res。
+
+代码如下:只beats 15%
+
+
+```python
+class Solution(object):
+ def characterReplacement(self, s, k):
+ """
+ :type s: str
+ :type k: int
+ :rtype: int
+ """
+ res = 0
+ for c in set(s):
+ start, end, counter, length = 0, 0, 0, 0
+ while end < len(s):
+ if s[end] != c:
+ counter += 1
+ end += 1 # end 永远指向下一个待处理的字符
+ while counter > k:
+ if s[start] != c:
+ counter -= 1
+ start += 1
+ length = max(length, end - start) # 因此这里是```end - start```而不是```end - start + 1```
+ res = max(res, length)
+ return res
+```
+
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+
+我们不按照可能的字符来遍历了,我们每次维护一个当前的最大字符频率,如果```end - start + 1 - max_freq > k```我们就知道此时怎么替换都不行了
+
+这个时候我们就要将start往前挪一格,对应的东西全都更新一下
+
+
+
+beats 93.46%
+
+
+
+
+```python
+class Solution(object):
+ def characterReplacement(self, s, k):
+ """
+ :type s: str
+ :type k: int
+ :rtype: int
+ """
+ lookup = {}
+ start, end, max_freq, res = 0, 0, 0, 0
+ while end < len(s):
+ lookup[s[end]] = lookup.get(s[end], 0) + 1
+ max_freq = max(max_freq, lookup[s[end]])
+ if end - start + 1 - max_freq > k: # 这里为什么用if不用while呢?见下方解析
+ lookup[s[start]] -= 1
+ start += 1
+ end += 1
+ res = max(res, end - start)
+ return res
+```
+
+上面用if不用while是因为在接下来的变化当中,我们start肯定是要前进一位的,end和max_freq此时没有变化,那么也就是说
+```end - start + 1 - max_freq > k```在经过一次if后就一定不会再满足了,所以这个地方不用while直接用if即可。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/434._number_of_segments_in_a_string.md b/docs/Leetcode_Solutions/Python/434._number_of_segments_in_a_string.md
similarity index 94%
rename from docs/leetcode/python/434._number_of_segments_in_a_string.md
rename to docs/Leetcode_Solutions/Python/434._number_of_segments_in_a_string.md
index a1aa617b2..424472a5a 100644
--- a/docs/leetcode/python/434._number_of_segments_in_a_string.md
+++ b/docs/Leetcode_Solutions/Python/434._number_of_segments_in_a_string.md
@@ -1,27 +1,27 @@
-### 434. Number of Segments in a String
-
-题目:
-
-
-
-难度:
-
-Easy
-
-
-作弊神器Python
-
-
-```python
-class Solution(object):
- def countSegments(self, s):
- """
- :type s: str
- :rtype: int
- """
- return len(s.split())
-```
-
-不过对于比如C++这种语言来说,应该是O(N),扫一圈应该也能得到正确答案
-
-总之拿Python做string的题目就是作弊啊
+### 434. Number of Segments in a String
+
+题目:
+
+
+
+难度:
+
+Easy
+
+
+作弊神器Python
+
+
+```python
+class Solution(object):
+ def countSegments(self, s):
+ """
+ :type s: str
+ :rtype: int
+ """
+ return len(s.split())
+```
+
+不过对于比如C++这种语言来说,应该是O(N),扫一圈应该也能得到正确答案
+
+总之拿Python做string的题目就是作弊啊
diff --git a/docs/leetcode/python/435._Non-overlapping_Intervals.md b/docs/Leetcode_Solutions/Python/435._Non-overlapping_Intervals.md
similarity index 97%
rename from docs/leetcode/python/435._Non-overlapping_Intervals.md
rename to docs/Leetcode_Solutions/Python/435._Non-overlapping_Intervals.md
index 581fb1982..b9f6f1dfd 100644
--- a/docs/leetcode/python/435._Non-overlapping_Intervals.md
+++ b/docs/Leetcode_Solutions/Python/435._Non-overlapping_Intervals.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/non-overlapping-intervals
+* https://leetcode.com/problems/non-overlapping-intervals/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/436._Find_Right_Interval.md b/docs/Leetcode_Solutions/Python/436._Find_Right_Interval.md
new file mode 100644
index 000000000..044cb3156
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/436._Find_Right_Interval.md
@@ -0,0 +1,153 @@
+# 436. Find Right Interval
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-right-interval/description/
+
+> 内容描述
+
+```
+Given a set of intervals, for each of the interval i, check if there exists an interval j whose start point is bigger than or equal to the end point of the interval i, which can be called that j is on the "right" of i.
+
+For any interval i, you need to store the minimum interval j's index, which means that the interval j has the minimum start point to build the "right" relationship for interval i. If the interval j doesn't exist, store -1 for the interval i. Finally, you need output the stored value of each interval as an array.
+
+Note:
+You may assume the interval's end point is always bigger than its start point.
+You may assume none of these intervals have the same start point.
+Example 1:
+Input: [ [1,2] ]
+
+Output: [-1]
+
+Explanation: There is only one interval in the collection, so it outputs -1.
+Example 2:
+Input: [ [3,4], [2,3], [1,2] ]
+
+Output: [-1, 0, 1]
+
+Explanation: There is no satisfied "right" interval for [3,4].
+For [2,3], the interval [3,4] has minimum-"right" start point;
+For [1,2], the interval [2,3] has minimum-"right" start point.
+Example 3:
+Input: [ [1,4], [2,3], [3,4] ]
+
+Output: [-1, 2, -1]
+
+Explanation: There is no satisfied "right" interval for [1,4] and [3,4].
+For [2,3], the interval [3,4] has minimum-"right" start point.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+
+打算先按照start,end排个序,然后只要往后面找就行,虽然是O(N^2),但是稍微小了点,但没想到结果超时。
+
+```
+class Solution(object):
+ def findRightInterval(self, intervals):
+ """
+ :type intervals: List[Interval]
+ :rtype: List[int]
+ """
+ res = [-1] * len(intervals)
+ new_intervals = sorted(intervals, key = lambda x: (x.start, x.end))
+ lookup = {}
+ for idx, interval in enumerate(intervals):
+ lookup[(interval.start, interval.end)] = idx
+
+ for i in range(len(new_intervals)):
+ for j in range(i+1, len(new_intervals)):
+ if new_intervals[j].start >= new_intervals[i].end:
+ look_interval = (new_intervals[i].start, new_intervals[i].end)
+ look_idx = lookup[look_interval]
+ next_interval = (new_intervals[j].start, new_intervals[j].end)
+ next_idx = lookup[next_interval]
+ res[look_idx] = next_idx
+ break
+ return res
+```
+
+> 思路 2
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+后面我想到既然所有的start都不一样,我不如搞一个list存排过序的start,然后这样就可以用二分查找来找到第一个大于某end的idx了,
+同样的用一个字典来存start和idx的信息。
+
+这个二分的思想就是找到第一个大于target的index,思路跟[leetcode第35题](https://github.com/apachecn/awesome-leetcode/blob/master/docs/Leetcode_Solutions/035._search_insert_position.md)一样
+
+```python
+class Solution(object):
+ def findRightInterval(self, intervals):
+ """
+ :type intervals: List[Interval]
+ :rtype: List[int]
+ """
+ res = [-1] * len(intervals)
+ starts = sorted([i.start for i in intervals])
+ lookup = {}
+ for idx, interval in enumerate(intervals):
+ lookup[interval.start] = idx
+ for i in range(len(intervals)):
+ if starts[-1] < intervals[i].end:
+ continue
+ else:
+ l, r = 0, len(starts) - 1
+ target = intervals[i].end
+ # print(i, l, r, target)
+ while l <= r:
+ mid = l + ((r-l) >> 1)
+ if starts[mid] < target:
+ l = mid + 1
+ else:
+ r = mid - 1
+ res[i] = lookup[starts[l]]
+ return res
+```
+
+
+
+
+
+
+## Follow up
+
+
+就是题目变成
+```
+Given a set of intervals, for each of the interval i,
+check if there exists an interval j whose start point is bigger than or equal to the start point of the interval i,
+which can be called that j is on the "right" of i.
+```
+
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+
+```python
+class Solution(object):
+ def findRightInterval(self, intervals):
+ """
+ :type intervals: List[Interval]
+ :rtype: List[int]
+ """
+ res = [-1] * len(intervals)
+ new_intervals = sorted(intervals, key = lambda x: (x.start, x.end))
+ lookup = {}
+ for idx, interval in enumerate(intervals):
+ lookup[(interval.start, interval.end)] = idx
+ for i in range(len(new_intervals)-1):
+ look_interval = (new_intervals[i].start, new_intervals[i].end)
+ look_idx = lookup[look_interval]
+ next_interval = (new_intervals[i+1].start, new_intervals[i+1].end)
+ next_idx = lookup[next_interval]
+ res[look_idx] = next_idx
+ return res
+```
diff --git a/docs/leetcode/python/437._path_sum_iii.md b/docs/Leetcode_Solutions/Python/437._path_sum_iii.md
similarity index 100%
rename from docs/leetcode/python/437._path_sum_iii.md
rename to docs/Leetcode_Solutions/Python/437._path_sum_iii.md
diff --git a/docs/Leetcode_Solutions/Python/438._Find_All_Anagrams_in_a_String.md b/docs/Leetcode_Solutions/Python/438._Find_All_Anagrams_in_a_String.md
new file mode 100644
index 000000000..af71cc8de
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/438._Find_All_Anagrams_in_a_String.md
@@ -0,0 +1,107 @@
+# 438. Find All Anagrams in a String
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-all-anagrams-in-a-string/description/
+
+> 内容描述
+
+```
+Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.
+
+Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.
+
+The order of output does not matter.
+
+Example 1:
+
+Input:
+s: "cbaebabacd" p: "abc"
+
+Output:
+[0, 6]
+
+Explanation:
+The substring with start index = 0 is "cba", which is an anagram of "abc".
+The substring with start index = 6 is "bac", which is an anagram of "abc".
+Example 2:
+
+Input:
+s: "abab" p: "ab"
+
+Output:
+[0, 1, 2]
+
+Explanation:
+The substring with start index = 0 is "ab", which is an anagram of "ab".
+The substring with start index = 1 is "ba", which is an anagram of "ab".
+The substring with start index = 2 is "ab", which is an anagram of "ab".
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(m*n)******- 空间复杂度: O(1)******
+
+刚开始打算直接遍历整个s,时间复杂度为O(m*n),m和n分别为字符串p和s的长度,但是超时了
+
+
+
+```
+class Solution(object):
+ def findAnagrams(self, s, p):
+ """
+ :type s: str
+ :type p: str
+ :rtype: List[int]
+ """
+ l, res = len(p), []
+ maps = collections.Counter(p)
+ for i in range(len(s)):
+ if collections.Counter(s[i:i+l]) == maps:
+ res.append(i)
+ return res
+```
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+于是用双指针,start 和 end 都从0开始往后遍历, beats 88.88%
+
+```python
+class Solution(object):
+ def findAnagrams(self, s, p):
+ """
+ :type s: str
+ :type p: str
+ :rtype: List[int]
+ """
+ res, start, end = [], 0, 0
+ # maps = collections.Counter(p) # 这个贼慢
+ maps = {}
+ for c in p:
+ maps[c] = maps.get(c, 0) + 1
+ counter = len(maps)
+ while end < len(s):
+ if s[end] in maps:
+ maps[s[end]] -= 1
+ if maps[s[end]] == 0:
+ counter -= 1
+ end += 1
+ while counter == 0:
+ if end-start == len(p):
+ res.append(start)
+ if s[start] in maps:
+ maps[s[start]] += 1
+ if maps[s[start]] == 1:
+ counter += 1
+ start += 1
+ return res
+```
+
+
+
diff --git a/docs/leetcode/python/439._Ternary_Expression_Parser.md b/docs/Leetcode_Solutions/Python/439. Ternary Expression Parser.md
similarity index 100%
rename from docs/leetcode/python/439._Ternary_Expression_Parser.md
rename to docs/Leetcode_Solutions/Python/439. Ternary Expression Parser.md
diff --git a/docs/leetcode/python/441._arranging_coins.md b/docs/Leetcode_Solutions/Python/441._arranging_coins.md
similarity index 100%
rename from docs/leetcode/python/441._arranging_coins.md
rename to docs/Leetcode_Solutions/Python/441._arranging_coins.md
diff --git a/docs/Leetcode_Solutions/Python/442._Find_All_Duplicates_in_an_Array.md b/docs/Leetcode_Solutions/Python/442._Find_All_Duplicates_in_an_Array.md
new file mode 100644
index 000000000..c89c19a27
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/442._Find_All_Duplicates_in_an_Array.md
@@ -0,0 +1,89 @@
+# 442. Find All Duplicates in an Array
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-all-duplicates-in-an-array/description/
+
+> 内容描述
+
+```
+Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
+
+Find all the elements that appear twice in this array.
+
+Could you do it without extra space and in O(n) runtime?
+
+Example:
+Input:
+[4,3,2,7,8,2,3,1]
+
+Output:
+[2,3]
+```
+
+## 解题方案
+
+> 思路 1
+
+直接用个字典存一下key和出现次数,然后loop一遍
+
+- 时间复杂度O(n)
+- 空间复杂度O(n)
+
+```python
+class Solution(object):
+ def findDuplicates(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: List[int]
+ """
+ res, lookup = [], {}
+ for num in nums:
+ lookup[num] = lookup.get(num, 0) + 1
+ for key in lookup.keys():
+ if lookup[key] == 2:
+ res.append(key)
+ return res
+```
+
+
+> 思路 2
+
+把每个数字都放到正确的位置上去,a[0] = 1, a[1] = 2, a[2] = 3 ... etc. (1<=a[i]<=n).
+
+参考[ZhassanB](https://leetcode.com/problems/find-all-duplicates-in-an-array/discuss/92411/Java-O(1)-space-O(n)-time-solution-with-swapping)
+
+- 时间复杂度O(n)
+- 空间复杂度O(1)
+```python
+class Solution(object):
+ def findDuplicates(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: List[int]
+ """
+ if not nums or len(nums) == 0:
+ return []
+ res = []
+ i, n = 0, len(nums)
+ while i < n: # traverse the array till the end
+ if nums[i] == i+1: # if number stays at it's supposed position, just continue
+ i += 1
+ continue
+ cur = nums[i]
+ if cur == -1: # if the duplicate number in that position is already found continue
+ i += 1
+ continue
+ if nums[cur-1] == cur: # if current num is equals to the number at supposed position,
+ res.append(cur) # then it is duplicate.
+ nums[i] = -1 # mark this position, in order to denote that duplicate has found
+ i += 1
+ continue
+ # if current number's supposed position is occupied by another number swap and consider that number
+ nums[i], nums[cur-1] = nums[cur-1], nums[i]
+ return res
+```
diff --git a/docs/leetcode/python/448._Find_All_Numbers_Disappeared_in_an_Array.md b/docs/Leetcode_Solutions/Python/448._Find_All_Numbers_Disappeared_in_an_Array.md
similarity index 100%
rename from docs/leetcode/python/448._Find_All_Numbers_Disappeared_in_an_Array.md
rename to docs/Leetcode_Solutions/Python/448._Find_All_Numbers_Disappeared_in_an_Array.md
diff --git a/docs/leetcode/python/450._Delete_Node_in_a_BST.md b/docs/Leetcode_Solutions/Python/450. Delete Node in a BST.md
similarity index 100%
rename from docs/leetcode/python/450._Delete_Node_in_a_BST.md
rename to docs/Leetcode_Solutions/Python/450. Delete Node in a BST.md
diff --git a/docs/Leetcode_Solutions/Python/452._minimum_number_of_arrows_to_burst_balloons.md b/docs/Leetcode_Solutions/Python/452._minimum_number_of_arrows_to_burst_balloons.md
new file mode 100644
index 000000000..48e806d3d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/452._minimum_number_of_arrows_to_burst_balloons.md
@@ -0,0 +1,59 @@
+# 452. Minimum Number of Arrows to Burst Balloons
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/
+
+> 内容描述
+
+```
+There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided input is the start and end coordinates of the horizontal diameter. Since it's horizontal, y-coordinates don't matter and hence the x-coordinates of start and end of the diameter suffice. Start is always smaller than end. There will be at most 10^4 balloons.
+
+An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with x_start and x_end bursts by an arrow shot at x if x_start ≤ x ≤ x_end. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons.
+
+Example:
+
+Input:
+[[10,16], [2,8], [1,6], [7,12]]
+
+Output:
+2
+
+Explanation:
+One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x = 11 (bursting the other two balloons).
+
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N*log(N))******- 空间复杂度: O(N)******
+
+
+仔细观察可发现,一定存在一个发射点都在气球结束点的最优解。所以此题贪心可解,我们只要将气球结束点从小到大排列,对于每个气球,我们考虑这个气球能否被之前的发射点覆盖,如果不能我们就将当前气球的结束点当做新的发射点(发射点总数+1)。
+
+beats 86.77%
+
+```python
+class Solution(object):
+ def findMinArrowShots(self, points):
+ """
+ :type points: List[List[int]]
+ :rtype: int
+ """
+ if not points or len(points) == 0:
+ return 0
+
+ points.sort(key = lambda x: x[1])
+ end = points[0][1]
+ res = 1
+ for i, point in enumerate(points):
+ if point[0] > end:
+ res += 1
+ end = point[1]
+ return res
+```
diff --git a/docs/Leetcode_Solutions/Python/453._Minimum_Moves_to_Equal_Array_Elements.md b/docs/Leetcode_Solutions/Python/453._Minimum_Moves_to_Equal_Array_Elements.md
new file mode 100644
index 000000000..ac0df589e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/453._Minimum_Moves_to_Equal_Array_Elements.md
@@ -0,0 +1,94 @@
+# 453. Minimum Moves to Equal Array Elements
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-moves-to-equal-array-elements/description/
+
+> 内容描述
+
+```
+Given a non-empty integer array of size n, find the minimum number of moves required to make all array elements equal, where a move is incrementing n - 1 elements by 1.
+
+Example:
+
+Input:
+[1,2,3]
+
+Output:
+3
+
+Explanation:
+Only three moves are needed (remember each move increments two elements):
+
+[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2*lgN)******- 空间复杂度: O(1)******
+
+naive TLE 代码:
+
+每次都是给并不是最大的元素加1直到全部相等。
+
+```
+class Solution(object):
+ def minMoves(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ res = 0
+ while(not all(x == nums[0] for x in nums)):
+ nums.sort()
+ for i in range(len(nums) - 1):
+ nums[i] += 1
+ res += 1
+
+ return res
+```
+
+
+
+给的测试例子是 `[1,2147483647]`能不TLE么?tag 是Math,所以要用观察到的结果来做吧?
+
+所以就是每个和最小值来比,看到底要增加多少,这是观察,但不是证明
+
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+
+类证明:
+
+
+
+其实给n-1个数字加1,效果等同于给那个未被选中的数字减1,比如数组[1,2,3], 给除去最大值的其他数字加1,变为[2,3,3],我们全体减1,并不影响数字间相对差异,变为[1,2,2],这个结果其实就是原始数组的最大值3自减1,那么问题也可能转化为,将所有数字都减小到最小值,这样难度就大大降低了,我们只要先找到最小值,然后累加每个数跟最小值之间的差值即可
+
+beats 73.62%
+
+AC代码
+
+```python
+class Solution(object):
+ def minMoves(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ res = 0
+ minVal = min(nums)
+ for num in nums:
+ res += num - minVal
+ return res
+```
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/457._Circular_Array_Loop.md b/docs/Leetcode_Solutions/Python/457._Circular_Array_Loop.md
new file mode 100644
index 000000000..22ef6f435
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/457._Circular_Array_Loop.md
@@ -0,0 +1,104 @@
+# 457. Circular Array Loop
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/circular-array-loop/description/
+
+> 内容描述
+
+```
+
+You are given an array of positive and negative integers. If a number n at an index is positive, then move forward n steps. Conversely, if it's negative (-n), move backward n steps. Assume the first element of the array is forward next to the last element, and the last element is backward next to the first element. Determine if there is a loop in this array. A loop starts and ends at a particular index with more than 1 element along the loop. The loop must be "forward" or "backward'.
+
+Example 1: Given the array [2, -1, 1, 2, 2], there is a loop, from index 0 -> 2 -> 3 -> 0.
+
+Example 2: Given the array [-1, 2], there is no loop.
+
+Note: The given array is guaranteed to contain no element "0".
+
+Can you do it in O(n) time complexity and O(1) space complexity?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+快慢指针,然后要注意的是如果loop只有一个元素不算loop,每次找完一圈后发现没有找到的话要将这一路上经过的点全都设为0防止下次重复查找了
+
+
+```python
+class Solution(object):
+ def circularArrayLoop(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: bool
+ """
+ def get_next_idx(i):
+ n = len(nums)
+ return (i + nums[i] + n) % n
+
+ for i, val in enumerate(nums):
+ if val == 0:
+ continue
+
+ slow = i
+ fast = get_next_idx(i)
+ # make sure always forward or always backward
+ while nums[fast] * val > 0 and nums[get_next_idx(fast)] * val > 0:
+ if slow == fast:
+ # exclude for loop with only one element
+ if slow == get_next_idx(slow):
+ break
+ return True
+
+ slow = get_next_idx(slow)
+ fast = get_next_idx(get_next_idx(fast))
+
+ slow = i
+ # set all the element along the path to 0, avoiding repeated lookup
+ while nums[slow] * val > 0:
+ nxt = get_next_idx(slow)
+ nums[slow] = 0
+ slow = nxt
+
+ return False
+```
+
+或者最后的循环也可以改一下
+
+```python
+class Solution(object):
+ def circularArrayLoop(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: bool
+ """
+ def get_nxt_idx(i):
+ n = len(nums)
+ return (i+nums[i]+n) % n
+
+ for i, val in enumerate(nums):
+ slow = i
+ fast = get_nxt_idx(i)
+
+ while nums[fast] * val > 0 and nums[get_nxt_idx(fast)] * val > 0:
+ if slow == fast:
+ if slow == get_nxt_idx(slow):
+ break
+ return True
+
+ slow = get_nxt_idx(slow)
+ fast = get_nxt_idx(get_nxt_idx(fast))
+
+ fast = get_nxt_idx(i)
+ while nums[fast] * val > 0:
+ nxt = get_nxt_idx(get_nxt_idx(fast))
+ nums[fast] = 0
+ fast = nxt
+ return False
+```
diff --git a/docs/leetcode/python/459._Repeated_Substring_Pattern.md b/docs/Leetcode_Solutions/Python/459._Repeated_Substring_Pattern.md
similarity index 100%
rename from docs/leetcode/python/459._Repeated_Substring_Pattern.md
rename to docs/Leetcode_Solutions/Python/459._Repeated_Substring_Pattern.md
diff --git a/docs/Leetcode_Solutions/Python/461._Hamming Distance.md b/docs/Leetcode_Solutions/Python/461._Hamming Distance.md
new file mode 100644
index 000000000..32b2b3dd6
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/461._Hamming Distance.md
@@ -0,0 +1,102 @@
+# 461. Hamming Distance
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/hamming-distance/description/
+
+> 内容描述
+
+```
+The Hamming distance between two integers is the number of positions at which the corresponding bits are different.
+
+Given two integers x and y, calculate the Hamming distance.
+
+Note:
+0 ≤ x, y < 231.
+
+Example:
+
+Input: x = 1, y = 4
+
+Output: 2
+
+Explanation:
+1 (0 0 0 1)
+4 (0 1 0 0)
+ ↑ ↑
+
+The above arrows point to positions where the corresponding bits are different.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+
+有wikipedia的page:
+
+https://en.wikipedia.org/wiki/Hamming_distance
+
+
+
+其实思路还是比较简单的
+
+
+
+先用异或,再求hamming weight
+
+> For binary strings *a* and *b* the Hamming distance is equal to the number of ones ([Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight)) in *a* [XOR](https://en.wikipedia.org/wiki/Exclusive_or) *b*.
+>
+>
+
+beats 100%
+
+一行无敌
+```python
+class Solution(object):
+ def hammingDistance(self, x, y):
+ """
+ :type x: int
+ :type y: int
+ :rtype: int
+ """
+ return bin(x^y).count('1')
+```
+
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+不用count,用位运算更快,虽然在这里全部都是beats 100%
+
+AC代码
+
+```python
+class Solution(object):
+ def hammingDistance(self, x, y):
+ """
+ :type x: int
+ :type y: int
+ :rtype: int
+ """
+ dist = 0
+ val = x ^ y
+
+ while val:
+ dist += 1
+ val &= val - 1
+
+ return dist
+```
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/463._Island_Perimeter.md b/docs/Leetcode_Solutions/Python/463._Island_Perimeter.md
new file mode 100644
index 000000000..2897ca68e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/463._Island_Perimeter.md
@@ -0,0 +1,53 @@
+# 463. Island Perimeter
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/island-perimeter/description/
+
+> 内容描述
+
+```
+You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn't have "lakes" (water inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island.
+
+Example:
+
+[[0,1,0,0],
+ [1,1,1,0],
+ [0,1,0,0],
+ [1,1,0,0]]
+
+Answer: 16
+Explanation: The perimeter is the 16 yellow stripes in the image below:
+```
+
+## 解题方案
+
+> 思路 1
+
+
+```python
+class Solution(object):
+ def islandPerimeter(self, grid):
+ """
+ :type grid: List[List[int]]
+ :rtype: int
+ """
+ h = len(grid)
+ w = len(grid[0]) if h else 0
+ res = 0
+ # 每一个陆地单元格的周长为4,当两单元格上下或者左右相邻时,令周长减2
+ for i in range(h):
+ for j in range(w):
+ if grid[i][j] == 1:
+ res += 4
+ # 因为x+1还在后面,所以不需要考虑,即只需要考虑左边和上边,因为循环已经出现过该点了
+ if i > 0 and grid[i-1][j]:
+ res -= 2
+ if j > 0 and grid[i][j-1]:
+ res -= 2
+ return res
+```
diff --git a/docs/leetcode/python/467._Unique_Substrings_in_Wraparound_String.md b/docs/Leetcode_Solutions/Python/467._Unique_Substrings_in_Wraparound_String.md
similarity index 100%
rename from docs/leetcode/python/467._Unique_Substrings_in_Wraparound_String.md
rename to docs/Leetcode_Solutions/Python/467._Unique_Substrings_in_Wraparound_String.md
diff --git a/docs/leetcode/python/469._Convex_Polygon.md b/docs/Leetcode_Solutions/Python/469. Convex Polygon.md
similarity index 100%
rename from docs/leetcode/python/469._Convex_Polygon.md
rename to docs/Leetcode_Solutions/Python/469. Convex Polygon.md
diff --git a/docs/leetcode/python/476._Number_Complement.md b/docs/Leetcode_Solutions/Python/476._Number_Complement.md
similarity index 100%
rename from docs/leetcode/python/476._Number_Complement.md
rename to docs/Leetcode_Solutions/Python/476._Number_Complement.md
diff --git a/docs/leetcode/python/477._Total_Hamming_Distance.md b/docs/Leetcode_Solutions/Python/477._Total_Hamming_Distance.md
similarity index 100%
rename from docs/leetcode/python/477._Total_Hamming_Distance.md
rename to docs/Leetcode_Solutions/Python/477._Total_Hamming_Distance.md
diff --git a/docs/Leetcode_Solutions/Python/485._Max_Consecutive_Ones.md b/docs/Leetcode_Solutions/Python/485._Max_Consecutive_Ones.md
new file mode 100644
index 000000000..8a50f655e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/485._Max_Consecutive_Ones.md
@@ -0,0 +1,62 @@
+# 485. Max Consecutive Ones
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/max-consecutive-ones/description/
+
+> 内容描述
+
+```
+Given a binary array, find the maximum number of consecutive 1s in this array.
+
+Example 1:
+Input: [1,1,0,1,1,1]
+Output: 3
+Explanation: The first two digits or the last three digits are consecutive 1s.
+ The maximum number of consecutive 1s is 3.
+Note:
+
+The input array will only contain 0 and 1.
+The length of input array is a positive integer and will not exceed 10,000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+一行无敌
+```python
+class Solution(object):
+ def findMaxConsecutiveOnes(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ return len(max(''.join(map(str, nums)).split('0')))
+```
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+```python
+class Solution(object):
+ def findMaxConsecutiveOnes(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ res, count = [], 0
+ for x in nums:
+ count = 0 if x == 0 else count + 1
+ res.append(count)
+ return max(res)
+```
+
+
diff --git a/docs/leetcode/python/494._Target_Sum.md b/docs/Leetcode_Solutions/Python/494._Target_Sum.md
similarity index 98%
rename from docs/leetcode/python/494._Target_Sum.md
rename to docs/Leetcode_Solutions/Python/494._Target_Sum.md
index e9ef2f4ce..e9f1a9598 100644
--- a/docs/leetcode/python/494._Target_Sum.md
+++ b/docs/Leetcode_Solutions/Python/494._Target_Sum.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/target-sum
+* https://leetcode.com/problems/target-sum/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/496._Next_Greater_Element_I.md b/docs/Leetcode_Solutions/Python/496._Next_Greater_Element_I.md
new file mode 100644
index 000000000..74a6d8d79
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/496._Next_Greater_Element_I.md
@@ -0,0 +1,113 @@
+# 496. Next Greater Element I
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/next-greater-element-i/description/
+
+> 内容描述
+
+```
+You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of nums2. Find all the next greater numbers for nums1's elements in the corresponding places of nums2.
+
+The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number.
+
+Example 1:
+Input: nums1 = [4,1,2], nums2 = [1,3,4,2].
+Output: [-1,3,-1]
+Explanation:
+ For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1.
+ For number 1 in the first array, the next greater number for it in the second array is 3.
+ For number 2 in the first array, there is no next greater number for it in the second array, so output -1.
+Example 2:
+Input: nums1 = [2,4], nums2 = [1,2,3,4].
+Output: [3,-1]
+Explanation:
+ For number 2 in the first array, the next greater number for it in the second array is 3.
+ For number 4 in the first array, there is no next greater number for it in the second array, so output -1.
+Note:
+All elements in nums1 and nums2 are unique.
+The length of both nums1 and nums2 would not exceed 1000.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(len(findNums) * len(nums))******- 空间复杂度: O(len(nums))******
+
+
+
+用一个字典把nums里面的数字和其idx分别作为key和value存下来,然后对于findNums里面的每一个数字,我们只需要看看其在字典中的value,
+然后从nums的idx = value+1开始往后找,如果找到了更大的数字就append,没找到出来之后根据flag定位知道要append一个-1
+
+beats 57.92%
+
+```python
+class Solution(object):
+ def nextGreaterElement(self, findNums, nums):
+ """
+ :type findNums: List[int]
+ :type nums: List[int]
+ :rtype: List[int]
+ """
+ lookup = {}
+ for i in range(len(nums)):
+ lookup[nums[i]] = i
+
+ res = []
+ for num in findNums:
+ idx = lookup[num]
+ flag = False
+ for i in range(idx+1, len(nums)):
+ if nums[i] > num:
+ res.append(nums[i])
+ flag = True
+ break
+ if not flag:
+ res.append(-1)
+ return res
+```
+
+
+> 思路 2
+******- 时间复杂度: O(len(nums))******- 空间复杂度: O(len(nums))******
+
+遍历nums,用栈来存nums里面的数字
+
+- while 碰到比栈顶元素更大的元素,我们知道栈顶元素的next greater num就是当前nums[i],pop栈顶,别忘了push nums[i]
+- 如果当前栈顶元素比nums[i]更大,只需要push当前nums[i]
+
+beats 100%
+
+```python
+class Solution(object):
+ def nextGreaterElement(self, findNums, nums):
+ """
+ :type findNums: List[int]
+ :type nums: List[int]
+ :rtype: List[int]
+ """
+ if not nums:
+ return [] # because findNums is subset of nums
+ stack = [nums[0]]
+ lookup = {}
+ for i in range(1, len(nums)):
+ # meet larger(than the last number in stack) number
+ # pop(all the smaller numbers than the current number)
+ # and set their next greater num to nums[i]
+ while stack and stack[-1] < nums[i]:
+ lookup[stack[-1]] = nums[i]
+ stack = stack[:-1]
+ stack.append(nums[i]) # don't forget to push nums[i]
+ # all the nums left in stack has no greater num behind it
+ for num in stack:
+ lookup[num] = -1
+ res =[]
+ for num in findNums:
+ res.append(lookup[num])
+
+ return res
+```
diff --git a/docs/Leetcode_Solutions/Python/507._Perfect_Number.md b/docs/Leetcode_Solutions/Python/507._Perfect_Number.md
new file mode 100644
index 000000000..6fe9436fd
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/507._Perfect_Number.md
@@ -0,0 +1,51 @@
+# 507. Perfect Number
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/perfect-number/description/
+
+> 内容描述
+
+```
+We define the Perfect Number is a positive integer that is equal to the sum of all its positive divisors except itself.
+
+Now, given an integer n, write a function that returns true when it is a perfect number and false when it is not.
+Example:
+Input: 28
+Output: True
+Explanation: 28 = 1 + 2 + 4 + 7 + 14
+Note: The input number n will not exceed 100,000,000. (1e8)
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(1)******
+
+用了一个比较巧妙的方法,首先排除一些 corner case,num 小于等于1的时候直接返回 False
+
+然后后面开始这个方法,就是我们其实不需要对所有小于 num 的数字做遍历,只需要从 2 遍历到 int(sqrt(num)) 即可,
+然后每次可以整除的时候都加上当前数字 i 和 num//i,然后初始化的时候让 sums = 1 ,这样最后就是不包含自己的所有因子的和,最后 return sum == num
+
+
+beats 95.73%
+```python
+from math import sqrt
+class Solution(object):
+ def checkPerfectNumber(self, num):
+ """
+ :type num: int
+ :rtype: bool
+ """
+ if num <= 1:
+ return False
+ sums = 1
+ for i in range(2, int(sqrt(num))+1):
+ if num % i == 0:
+ sums += i + num // i
+ return sums == num
+```
diff --git a/docs/leetcode/python/536._Construct_Binary_Tree_from_String.md b/docs/Leetcode_Solutions/Python/536._Construct_Binary_Tree_from_String.md
similarity index 99%
rename from docs/leetcode/python/536._Construct_Binary_Tree_from_String.md
rename to docs/Leetcode_Solutions/Python/536._Construct_Binary_Tree_from_String.md
index d28194fab..3f000278e 100644
--- a/docs/leetcode/python/536._Construct_Binary_Tree_from_String.md
+++ b/docs/Leetcode_Solutions/Python/536._Construct_Binary_Tree_from_String.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/construct-binary-tree-from-string
+* https://leetcode.com/problems/construct-binary-tree-from-string/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/539._Minimum_Time_Difference.md b/docs/Leetcode_Solutions/Python/539._Minimum_Time_Difference.md
new file mode 100644
index 000000000..e268fb8dd
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/539._Minimum_Time_Difference.md
@@ -0,0 +1,39 @@
+# 539. Minimum Time Difference
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-time-difference/description/
+
+> 内容描述
+
+```
+Given a list of 24-hour clock time points in "Hour:Minutes" format, find the minimum minutes difference between any two time points in the list.
+Example 1:
+Input: ["23:59","00:00"]
+Output: 1
+Note:
+The number of time points in the given list is at least 2 and won't exceed 20000.
+The input time is legal and ranges from 00:00 to 23:59.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+先全部转换成分钟数,再排序,然后取最小差值,唯一要注意首尾两者差值可能还最小,例如["23:59","00:00"]
+
+```python
+class Solution(object):
+ def findMinDifference(self, timePoints):
+ """
+ :type timePoints: List[str]
+ :rtype: int
+ """
+ tp = sorted(60*int(pt[:2])+int(pt[3:]) for pt in timePoints)
+ return min(min(b - a for (a, b) in zip(tp, tp[1:])), (24*60)+tp[0]-tp[-1])
+```
diff --git a/docs/Leetcode_Solutions/Python/547._Friend_Circles.md b/docs/Leetcode_Solutions/Python/547._Friend_Circles.md
new file mode 100644
index 000000000..31369032e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/547._Friend_Circles.md
@@ -0,0 +1,102 @@
+# 547. Friend Circles
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/friend-circles/description/
+
+> 内容描述
+
+```
+There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.
+
+Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.
+
+Example 1:
+Input:
+[[1,1,0],
+ [1,1,0],
+ [0,0,1]]
+Output: 2
+Explanation:The 0th and 1st students are direct friends, so they are in a friend circle.
+The 2nd student himself is in a friend circle. So return 2.
+Example 2:
+Input:
+[[1,1,0],
+ [1,1,1],
+ [0,1,1]]
+Output: 1
+Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends,
+so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.
+Note:
+N is in range [1,200].
+M[i][i] = 1 for all students.
+If M[i][j] = 1, then M[j][i] = 1.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^3)******- 空间复杂度: O(N)******
+
+发现一件事,只要是关于这种circle类的题目,
+- 第一印象如果是关于链表的那么就想到快慢指针
+- 第二印象如果是关于图的立马想到union-find
+
+思路就没什么好说的,把这道题看成求图中有多少个联通分量就可以了。
+
+时间复杂度是因为两个for loop,并且调用connected方法会调用find方法,find方法最差到O(n),所以最终是O(N^3)
+
+空间自然就是O(N)
+
+
+```python
+class UnionFind(object):
+ uf = [] # access to component id (site indexed)
+ count = 0 # number of components
+
+ def uf(self, n): # 初始化uf数组和组数目
+ self.count = n
+ self.uf = [i for i in range(n)]
+
+ def find(self, x): # 判断节点所属于的组
+ while x != self.uf[x]:
+ self.uf[x] = self.uf[self.uf[x]]
+ x = self.uf[x]
+ return self.uf[x]
+
+ def union(self, x, y): # 连接两个节点
+ x_root = self.find(x)
+ y_root = self.find(y)
+ self.uf[x_root] = y_root
+ self.count -= 1
+
+ def connected(self, x, y): # 判断两个节点是否联通
+ return self.find(x) == self.find(y)
+
+ def count(self): # 返回所有组的数目
+ return self.count
+
+
+class Solution(object):
+ def findCircleNum(self, grid):
+ """
+ :type M: List[List[int]]
+ :rtype: int
+ """
+ s = UnionFind()
+ s.uf(len(grid))
+ for i in range(len(grid)):
+ for j in range(len(grid[i])):
+ # 如果i等于j说明是自己,没必要判断
+ # 只有当该位置为1即互为朋友的时候才需要看是否联通
+ # 不联通才union,联通也union一来浪费时间二来可能会无故减小count
+ if j != i and grid[i][j] == 1 and not s.connected(j, i):
+ s.union(j, i)
+ return s.count
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/560._Subarray_Sum_Equals_K.md b/docs/Leetcode_Solutions/Python/560._Subarray_Sum_Equals_K.md
new file mode 100644
index 000000000..6821d7b3b
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/560._Subarray_Sum_Equals_K.md
@@ -0,0 +1,56 @@
+# 560. Subarray Sum Equals K
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/subarray-sum-equals-k/description/
+
+> 内容描述
+
+```
+Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.
+
+Example 1:
+Input:nums = [1,1,1], k = 2
+Output: 2
+Note:
+The length of the array is in range [1, 20,000].
+The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].
+```
+
+## 解题方案
+
+> 思路 1
+
+
+跟two sum一样的题目
+
+就不停维护一个当前和的变量,然后每次都check一下```当前和 - k```是否在字典里面,如果存在我们就知道了之前有一坨字符串和的值为```当前和 - k```,然后
+当前和的值就是当前和,所以最近接触的一坨字符串其和必为k
+
+例如在[1,2,3,4]里面找7,之前存过1+2在字典里面,然后循环到4的时候当前和为10,就看看3在不在字典里面,一看果然有,那么最近一坨的 3+4 = 7,找到了
+
+但是这里要注意光找到没用,我们要知道存在多少个,所以字典里面的value对应的就是当前和出现的次数
+
+AC 代码:
+
+```python
+class Solution(object):
+ def subarraySum(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: int
+ """
+ # 这是为了保证如果当前和的值就等于k的话,我们其实也相当于找到一次
+ lookup = {0:1}
+ res = cur_sum = 0
+ for num in nums:
+ cur_sum += num
+ res += lookup.get(cur_sum-k, 0)
+ lookup[cur_sum] = lookup.get(cur_sum, 0) + 1
+ return res
+```
diff --git a/docs/Leetcode_Solutions/Python/563._Binary_Tree_Tilt.md b/docs/Leetcode_Solutions/Python/563._Binary_Tree_Tilt.md
new file mode 100644
index 000000000..f46db9f76
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/563._Binary_Tree_Tilt.md
@@ -0,0 +1,85 @@
+# 563. Binary Tree Tilt
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/binary-tree-tilt/description/
+
+> 内容描述
+
+```
+
+Given a binary tree, return the tilt of the whole tree.
+
+The tilt of a tree node is defined as the absolute difference between the sum of all left subtree node values and the sum of all right subtree node values. Null node has tilt 0.
+
+The tilt of the whole tree is defined as the sum of all nodes' tilt.
+
+Example:
+Input:
+ 1
+ / \
+ 2 3
+Output: 1
+Explanation:
+Tilt of node 2 : 0
+Tilt of node 3 : 0
+Tilt of node 1 : |2-3| = 1
+Tilt of binary tree : 0 + 0 + 1 = 1
+Note:
+
+The sum of node values in any subtree won't exceed the range of 32-bit integer.
+All the tilt values won't exceed the range of 32-bit integer.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+
+写一个sums函数,input为node,返回这个node本身的value和它所有孩子的value之和,该node的tilt就是左孩子sums和右孩子sums的差值的绝对值
+
+然后对于root和其所有子孙,只需要把他们的tilt全部加起来就是结果
+
+beats 98.70%
+
+```python
+class Solution(object):
+ def findTilt(self, root):
+ """
+ :type root: TreeNode
+ :rtype: int
+ """
+ self.res = 0
+ def sums(node):
+ if not node:
+ return 0
+ left_sum = sums(node.left)
+ right_sum = sums(node.right)
+ self.res += abs(left_sum-right_sum)
+ return left_sum + right_sum + node.val
+
+ sums(root)
+ return self.res
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/564._Find_the_Closest_Palindrome.md b/docs/Leetcode_Solutions/Python/564._Find_the_Closest_Palindrome.md
new file mode 100644
index 000000000..8d4312ddd
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/564._Find_the_Closest_Palindrome.md
@@ -0,0 +1,118 @@
+# 564. Find the Closest Palindrome
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-the-closest-palindrome/description/
+
+> 内容描述
+
+```
+Given an integer n, find the closest integer (not including itself), which is a palindrome.
+
+The 'closest' is defined as absolute difference minimized between two integers.
+
+Example 1:
+Input: "123"
+Output: "121"
+Note:
+The input n is a positive integer represented by string, whose length will not exceed 18.
+If there is a tie, return the smaller one as answer.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+前前后后搞了2天,感谢今天下午女朋友和我一起讨论,最终搞出来了。
+
+- 总共三种情况,算出后面的,前面的,还有当前的前半部分直接反转黏贴到后半部分。总结一下就是说[前半部分+1,前半部分-1,前半部分自身] + 前面得出结果的反转就是我们可能的结果之一。
+- 另外两种情况就是进位和减位,格式为1000..0001, 999...999
+
+5个部分看看哪个更近,唯一需要注意的是输入为10和11的时候handle不了,要在最前面手动处理一下。
+
+beats 100%,功夫不负有心人!
+
+```
+class Solution(object):
+ def nearestPalindromic(self, n):
+ """
+ :type n: str
+ :rtype: str
+ """
+ tmp = str(n)
+ if 9 < int(n) < 12:
+ return '9'
+ r_half_len = len(tmp) // 2
+ if len(tmp) & 1 == 0: # 长度为偶数
+ num_digits = len(str(int(tmp[:len(tmp)/2])))
+ half = tmp[:len(tmp)/2]
+ else: # 长度为奇数
+ num_digits = len(str(int(tmp[:(len(tmp)+1)/2])))
+ half = tmp[:(len(tmp)+1)/2]
+
+ if len(str(int(half)+1)) > num_digits: # 进位了
+ behind = '1' + '0' * (len(tmp)-1) + '1'
+ else:
+ behind = str(int(half) + 1)+ str(int(half) + 1)[:r_half_len][::-1]
+ if len(str(int(half)-1)) < num_digits: # 减位了
+ before = '9' * (len(tmp)-1)
+ else:
+ before = str(int(half) - 1)+ str(int(half) - 1)[:r_half_len][::-1]
+ # 当前的前半部分直接反转,如1002,变成了1001
+ cur = str(int(half))+ str(int(half))[:r_half_len][::-1]
+ if cur == tmp[::-1]:
+ return behind if abs(int(tmp)-int(behind)) < abs(int(tmp)-int(before)) else before
+ abss = map(lambda x: abs(int(x)-int(tmp)), [before, cur, behind])
+ selects = [before, cur, behind]
+ return selects[abss.index(min(abss))]
+```
+
+后面我觉得完全可以重构一下代码,behind和before不用非得算出来,我只要把所有的可能性全都放到一个list里面去,最后来判断就行了
+
+```python
+class Solution(object):
+ def nearestPalindromic(self, n):
+ """
+ :type n: str
+ :rtype: str
+ """
+ prefix = int(n[:(len(n)+1)//2])
+
+ candidates = set(['1' + '0' * (len(n)-1) + '1', '9' * (len(n)-1)]) # 进位减位可能性
+
+ for i in map(str, [prefix-1, prefix, prefix+1]): # 前半部分+1,-1,+0可能性
+ candidates.add(i + [i, i[:-1]][len(n) & 1][::-1])
+
+ candidates.discard(n) # 除去自身可能就是Palindrome的可能性
+ candidates.discard('') # 输入n为个位数的话,我们还会加入空字符串,必须要去掉
+
+ return min(candidates, key = lambda x: (abs(int(x) - int(n)), int(x)))
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/581._Shortest_Unsorted_Continuous_Subarray.md b/docs/Leetcode_Solutions/Python/581._Shortest_Unsorted_Continuous_Subarray.md
new file mode 100644
index 000000000..e53153d72
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/581._Shortest_Unsorted_Continuous_Subarray.md
@@ -0,0 +1,176 @@
+# 581. Shortest Unsorted Continuous Subarray
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/two-sum
+* https://leetcode-cn.com/problems/two-sum/description
+
+> 内容描述
+
+```
+给定 nums = [2, 7, 11, 15], target = 9
+
+因为 nums[0] + nums[1] = 2 + 7 = 9
+所以返回 [0, 1]
+```
+
+## 解题方案
+
+> 思路 1
+ ******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+直接sort,然后找出sort前与sort后不同的数组长度
+
+
+```python
+class Solution(object):
+ def findUnsortedSubarray(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ start, end = 0, 0
+ sorted_nums = sorted(nums)
+
+ for i in range(len(nums)):
+ if nums[i] != sorted_nums[i]:
+ start = i
+ break
+ for i in range(len(nums)-1, -1, -1):
+ if nums[i] != sorted_nums[i]:
+ end = i
+ break
+
+ return end - start + 1 if start != end else 0
+```
+
+> 思路 2
+ ******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+要满足三个性质:
+
+1. nums[0, i - 1] and nums[j + 1, n - 1] are both sorted.
+2. nums[i] != nums_sorted[i] and nums[j] != nums_sorted[j].
+3. nums[i - 1] <= min and max <= nums[j + 1], where min and max are the minimum and maximum values of subarray nums[i, j].
+
+所以我们需要做的就是 find the two longest sorted subarrays starting at index 0 and ending at index n - 1
+
+- 从左到右找到第一个不满足nums[l] <= nums[l+1]的index l
+- 然后从右到左找到第一个不满足nums[r] >= nums[r-1]的 index r
+- 然后开始保证第三条性质,只要min(nums[l:r+1]) < nums[l],l就自减1;只要max(nums[l:r+1]) > nums[r], r就自增1;
+- 这两个index中间这一坨就是需要我们sort的最短subarray
+
+参考[fun4LeetCode](https://leetcode.com/problems/shortest-unsorted-continuous-subarray/discuss/103066/Ideas-behind-the-O(n)-two-pass-and-one-pass-solutions)
+
+two-pass,Finding the longest subarrays and the maximum and minimum values of the middle subarray takes one-pass.
+Ensuring the third property requires a second pass.
+
+```python
+class Solution(object):
+ def findUnsortedSubarray(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ l, r = 0, len(nums) - 1
+ while l < r and nums[l] <= nums[l+1]:
+ l += 1
+ if l >= r:
+ return 0
+ while nums[r] >= nums[r-1]:
+ r -= 1
+ max_num, min_num = -sys.maxsize, sys.maxsize
+
+ for k in range(l, r+1):
+ max_num = max(max_num, nums[k])
+ min_num = min(min_num, nums[k])
+
+ while l >= 0 and min_num < nums[l]:
+ l -= 1
+ while r < len(nums) and nums[r] < max_num:
+ r += 1
+
+ return r - l - 1
+```
+
+> 思路 3
+ ******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+这个方法我最推荐了,他其实和思路2一样,但是不用考虑那么多
+
+1. 从左到右找到最后一个不符合递增规律的index end
+2. 从右到左找到最后一个不符合递增规律的index start
+3. 直接返回max(end-start+1, 0), 因为end可能比start小,比如对于输入[1,2,3,3,3],end等于0,start等于4
+
+```python
+class Solution(object):
+ def findUnsortedSubarray(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ m = nums[0]
+ end = 0
+ for i in range(1, len(nums)):
+ if nums[i] >= m:
+ m = nums[i]
+ else:
+ end = i
+
+ m = nums[-1]
+ start = len(nums)-1
+ for i in range(len(nums)-1, -1, -1):
+ if nums[i] <= m:
+ m = nums[i]
+ else:
+ start = i
+
+ if start == end:
+ return 0
+
+ return max(end-start+1, 0)
+```
+
+
+
+
+> 思路 4
+ ******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+ one-pass
+
+ 这一次我们只需要找到
+
+- i is the smallest index such that nums[i] != min[i:]
+- j is the largest index such that nums[j] != max[:j+1]
+
+
+```python
+class Solution(object):
+ def findUnsortedSubarray(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ i, j = 0, -1
+ l, r = 0, len(nums) - 1
+ max_num, min_num = -sys.maxsize, sys.maxsize
+ while r >= 0:
+ min_num = min(min_num, nums[r])
+ # i is the smallest index such that nums[i] != min[i:]
+ if nums[r] != min_num:
+ i = r
+ max_num = max(max_num, nums[l])
+ # j is the largest index such that nums[j] != max[:j+1]
+ if nums[l] != max_num:
+ j = l
+ l += 1
+ r -= 1
+
+ return j-i+1
+```
+
diff --git a/docs/Leetcode_Solutions/Python/587._Erect_the_Fence .md b/docs/Leetcode_Solutions/Python/587._Erect_the_Fence .md
new file mode 100644
index 000000000..f61d75b3c
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/587._Erect_the_Fence .md
@@ -0,0 +1,133 @@
+
+
+### 587. Erect the Fence
+
+
+题目:
+
+
+
+难度:
+
+Hard
+
+
+
+思路
+
+题目要求用一个围栏把所有的点(🌲)围起来,然后求处于围栏上点(🌲)的集合。
+
+我们可以发现,从最左边的那个点一直往右走,只要一直都是走的逆时针方向,那么我们一定可以找到这条围栏。那么接下来就考虑最简单的情况,
+
+- 只有两个点```p```和```q```,我们从```p```走到```q```,当```p```到原点这条直线的斜率小于```q```到原点这条直线的斜率时,```p->q```就是沿逆时针方向走的;
+- 接下来考虑3个点:```p,q,r```,以```p```为参照点(即前面的原点),那么从```q```走到```r```的时候,只要```q```到```q```这条直线的斜率小于```r```到```p```这条直线的斜率,```q->r```就是沿逆时针方向走的。
+
+因此,我们只要构建一个```orientation```函数,就可以判断出目前我们的围栏是不是沿着逆时针在走下去了。
+
+我们用一个```stack```来存放目前认为在围栏上的点的集合,然后把所有的点按照指定规则排好序:```先按照点的x坐标升序排列,如果x相等则按照点的y坐标升序排列```。这样我们依次取点,只要```stack```里面的点大于等于```2```个我们就要无限进行判断是否走的是逆时针,如果不是就把```stack```里面最后那个点```pop```出去(可能一直```pop```到只剩一个点),否则就把目前的这个点加入到```stack```中去,因为目前它还是在逆时针方向上的。
+
+从左往右走完一遍```points```之后,我们围栏的下部分```lower hull```就构建好了,此时我们还要构建围栏的```upper hull```,因此我们将```points```逆序一下,从右往左再来一次遍历,仍然看是否走的是逆时针。但是这次遍历我们需要进行一个判断,就是之前放进```stack```的点,此时我们还是会经过它,如果它已经在```stack```里面了,我们就不需要再加进去了,同时这样也避免了我们把最左边的点重复加进去。
+
+
+
+```python
+python
+# import functools
+class Solution:
+ def outerTrees(self, points):
+ """
+ :type points: List[Point]
+ :rtype: List[Point]
+ """
+ def orientation(p, q, r):
+ return (q.y - p.y)*(r.x - p.x) - (r.y - p.y)*(q.x - p.x)
+ # def myComparator(p,q):
+ # return p.x - q.x if p.x != q.x else p.y - q.y
+ stack= []
+ # points.sort(key = functools.cmp_to_key(myComparator))
+ points.sort(key = lambda p: (p.x, p.y))
+ for i in range(len(points)):
+ while (len(stack) >= 2 and orientation(stack[-2],stack[-1],points[i]) > 0):
+ stack.pop()
+ stack.append(points[i])
+ points.reverse();
+ for i in range(len(points)):
+ while (len(stack) >= 2 and orientation(stack[-2],stack[-1],points[i]) > 0):
+ stack.pop()
+ if points[i] not in stack:
+ stack.append(points[i])
+ return stack
+```
+简化python版本
+```python
+class Solution(object):
+ def outerTrees(self, points):
+ """
+ :type points: List[Point]
+ :rtype: List[Point]
+ """
+ def orientation(p, q, r):
+ return (q.y - p.y) * (r.x - q.x) - \
+ (q.x - p.x) * (r.y - q.y)
+
+ hull = []
+ points.sort(key=lambda p: (p.x, p.y))
+
+ for i in itertools.chain(xrange(len(points)), \
+ reversed(xrange(len(points)))):
+ while len(hull) >= 2 and \
+ orientation(hull[-2], hull[-1], points[i]) > 0:
+ hull.pop()
+ hull.append(points[i])
+
+ return list(set(hull))
+```
+
+下面是小傅大神的代码,本来想叫‘’傅神‘’的,结果这名字🤦♂️(手动捂脸)[小傅每日一题587](https://www.bilibili.com/video/av15446980/)
+
+另外其中的```stack.pop()```这行代码注释掉也是可以的
+
+```java
+java
+class Solution {
+ public List outerTrees(Point[] points) {
+ List res = new ArrayList();
+ Arrays.sort(points, new Comparator(){
+ @Override
+ public int compare(Point p, Point q){
+ return p.x == q.x ? p.y - q.y : p.x - q.x;
+ }
+ });
+ Stack stack = new Stack<>();
+ for (int i = 0; i < points.length; i++){
+ while(stack.size() >= 2 && orientation(stack.get(stack.size() - 2), stack.peek(), points[i]) > 0){
+ stack.pop();
+ }
+ stack.push(points[i]);
+ }
+ //stack.pop();
+ for (int i = points.length - 1; i >= 0; i--){
+ while(stack.size() >= 2 && orientation(stack.get(stack.size() - 2), stack.peek(), points[i]) > 0){
+ stack.pop();
+ }
+ stack.push(points[i]);
+ }
+ res.addAll(new HashSet<>(stack));
+ return res;
+ }
+
+ public int orientation(Point p, Point q, Point r){
+ return (q.y - p.y)*(r.x - p.x) - (r.y - p.y)*(q.x - p.x);
+ }
+}
+```
+
+
+
+
+
+Author: Keqi Huang
+
+If you like it, please spread your support
+
+
diff --git a/docs/Leetcode_Solutions/Python/592._Fraction_Addition_and_Subtraction.md b/docs/Leetcode_Solutions/Python/592._Fraction_Addition_and_Subtraction.md
new file mode 100644
index 000000000..cef93a65d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/592._Fraction_Addition_and_Subtraction.md
@@ -0,0 +1,115 @@
+# 592. Fraction Addition and Subtraction
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/fraction-addition-and-subtraction/description/
+
+> 内容描述
+
+```
+Given a string representing an expression of fraction addition and subtraction, you need to return the calculation result in string format. The final result should be irreducible fraction. If your final result is an integer, say 2, you need to change it to the format of fraction that has denominator 1. So in this case, 2 should be converted to 2/1.
+
+Example 1:
+Input:"-1/2+1/2"
+Output: "0/1"
+Example 2:
+Input:"-1/2+1/2+1/3"
+Output: "1/3"
+Example 3:
+Input:"1/3-1/2"
+Output: "-1/6"
+Example 4:
+Input:"5/3+1/3"
+Output: "2/1"
+Note:
+The input string only contains '0' to '9', '/', '+' and '-'. So does the output.
+Each fraction (input and output) has format ±numerator/denominator. If the first input fraction or the output is positive, then '+' will be omitted.
+The input only contains valid irreducible fractions, where the numerator and denominator of each fraction will always be in the range [1,10]. If the denominator is 1, it means this fraction is actually an integer in a fraction format defined above.
+The number of given fractions will be in the range [1,10].
+The numerator and denominator of the final result are guaranteed to be valid and in the range of 32-bit int.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+这个思路真的没啥好说的,就是最小公倍数和最大公约数稍微注意下怎么写就行,然后剩下的就是搬砖活了, 20分钟 bug free,一遍AC,莫名小自豪。。。。
+
+```python
+class Solution(object):
+ def fractionAddition(self, expression):
+ """
+ :type expression: str
+ :rtype: str
+ """
+ def gcd(a, b):
+ if a == 0:
+ return b
+ return gcd(b % a, a)
+
+ def gcm(num1, num2):
+ return num1 * num2 // gcd(num1, num2)
+
+ def is_sign(expression, index): # 判断符号'-'是否是描述负数的符号
+ if expression[i] == '-':
+ if i - 1 < 0 or expression[i - 1] in oprs:
+ return True
+ return False
+
+ oprs = '+-'
+ units = [] # 保存包含操作符和操作数的列表
+ start = 0 # 标记数字起点
+ for i in range(len(expression)):
+ if expression[i] in oprs:
+ if not is_sign(expression, i):
+ units.append(expression[start:i])
+ units.append(expression[i])
+ start = i + 1
+ units.append(expression[start:])
+ while len(units) > 1:
+ left, right = 0, 0
+ gcmm = gcm(int(units[0].split('/')[1]), int(units[2].split('/')[1]))
+ if units[0].split('/')[0][0] == '-':
+ left = int(units[0].split('/')[0].lstrip('-')) * gcmm // int(units[0].split('/')[1]) * (-1)
+ else:
+ left = int(units[0].split('/')[0].lstrip('-')) * gcmm // int(units[0].split('/')[1])
+ right = int(units[2].split('/')[0]) * gcmm // int(units[2].split('/')[1])
+ if units[1] == '+':
+ units = [str(left + right) + '/' + str(gcmm)] + units[3:]
+ else:
+ units = [str(left - right) + '/' + str(gcmm)] + units[3:]
+ if units[0].split('/')[0].lstrip('-') == '0':
+ res = units[0].split('/')[0] + '/1'
+ else:
+ gcdd = gcd(int(units[0].split('/')[0].lstrip('-')), int(units[0].split('/')[1]))
+ # print('gcdd',gcdd)
+ if units[0].split('/')[0][0] == '-':
+ res = '-' + str(int(units[0].split('/')[0].lstrip('-'))//gcdd) + '/' + str(int(units[0].split('/')[1])//gcdd)
+ else:
+ res = str(int(units[0].split('/')[0].lstrip('-'))//gcdd) + '/' + str(int(units[0].split('/')[1])//gcdd)
+
+ return res
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+我怕不是个智障吧,还小自豪,。。。。看了discuss里面[lee215](https://leetcode.com/problems/fraction-addition-and-subtraction/discuss/103387/Python-easy-understood-2-line-solution)大神的答案,我tm。。。。
+```python
+class Solution(object):
+ def fractionAddition(self, expression):
+ """
+ :type expression: str
+ :rtype: str
+ """
+ from fractions import Fraction
+ res = sum(map(Fraction, expression.replace('+', ' +').replace('-', ' -').split()))
+ return str(res.numerator) + '/' + str(res.denominator)
+```
diff --git a/docs/Leetcode_Solutions/Python/593._Valid_Square.md b/docs/Leetcode_Solutions/Python/593._Valid_Square.md
new file mode 100644
index 000000000..fb61b27fe
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/593._Valid_Square.md
@@ -0,0 +1,201 @@
+# 593. Valid Square
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/valid-square/description/
+
+> 内容描述
+
+```
+
+Given the coordinates of four points in 2D space, return whether the four points could construct a square.
+
+The coordinate (x,y) of a point is represented by an integer array with two integers.
+
+Example:
+Input: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1]
+Output: True
+Note:
+
+All the input integers are in the range [-10000, 10000].
+A valid square has four equal sides with positive length and four equal angles (90-degree angles).
+Input points have no order.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+只要满足3个条件就行,
+
+1. 每个点都不相等,处理掉比如4个点都是(0, 0)啥的case
+2. 4条边相等
+3. 其中2条边夹角为90度
+
+
+或者,
+
+1. 每个点都不相等,处理掉比如4个点都是(0, 0)啥的case
+2. 有其中一组相邻边相等
+3. 有一对对角均为90度
+
+
+第一种方式代码如下:
+
+
+```python
+class Solution(object):
+ def validSquare(self, p1, p2, p3, p4):
+ """
+ :type p1: List[int]
+ :type p2: List[int]
+ :type p3: List[int]
+ :type p4: List[int]
+ :rtype: bool
+ """
+ # corner cases
+ points = [p1, p2, p3, p4]
+ for i in range(len(points)):
+ for j in range(i + 1, len(points)):
+ if points[i][0] == points[j][0] and points[i][1] == points[j][1]:
+ return False
+
+ points = sorted(points, key=lambda p: (p[0], p[1])) # []
+
+ import math
+
+ # for this part , we calculate the four sides
+ tmp = pow(points[-1][0] - points[1][0], 2) + pow(points[-1][1] - points[1][1], 2)
+ len_bottom = math.sqrt((tmp))
+
+ tmp = pow(points[-2][0] - points[0][0], 2) + pow(points[-2][1] - points[0][1], 2)
+ len_top = math.sqrt((tmp))
+
+ tmp = pow(points[1][0] - points[0][0], 2) + pow(points[1][1] - points[0][1], 2)
+ len_left = math.sqrt((tmp))
+
+ tmp = pow(points[-1][0] - points[-2][0], 2) + pow(points[-1][1] - points[-2][1], 2)
+ len_right = math.sqrt((tmp))
+
+ # now this is our angle part
+ vector_bottom = [points[-1][0] - points[1][0], points[-1][1] - points[1][1]]
+ vector_left = [points[1][0] - points[0][0], points[1][1] - points[0][1]]
+
+ dikall = vector_bottom[0] * vector_left[0] + vector_bottom[1] * vector_left[1]
+
+ if len_bottom == len_top == len_left == len_right and dikall == 0:
+ return True
+ return False
+```
+
+第二种代码如下:
+
+```python
+class Solution(object):
+ def validSquare(self, p1, p2, p3, p4):
+ """
+ :type p1: List[int]
+ :type p2: List[int]
+ :type p3: List[int]
+ :type p4: List[int]
+ :rtype: bool
+ """
+ # corner cases
+ points = [p1, p2, p3, p4]
+ for i in range(len(points)):
+ for j in range(i + 1, len(points)):
+ if points[i][0] == points[j][0] and points[i][1] == points[j][1]:
+ return False
+
+ points = sorted(points, key=lambda p: (p[0], p[1])) # []
+
+ import math
+
+ # for this part , we calculate the four sides
+ tmp = pow(points[-1][0] - points[1][0], 2) + pow(points[-1][1] - points[1][1], 2)
+ len_bottom = math.sqrt((tmp))
+
+ tmp = pow(points[1][0] - points[0][0], 2) + pow(points[1][1] - points[0][1], 2)
+ len_left = math.sqrt((tmp))
+
+ # now this is our angle part
+ vector_bottom = [points[-1][0] - points[1][0], points[-1][1] - points[1][1]]
+ vector_left = [points[1][0] - points[0][0], points[1][1] - points[0][1]]
+
+ vector_top = [points[2][0] - points[0][0], points[2][1] - points[0][1]]
+ vector_right = [points[2][0] - points[-1][0], points[2][1] - points[-1][1]]
+
+ vec_product1 = vector_bottom[0] * vector_left[0] + vector_bottom[1] * vector_left[1]
+ vec_product2 = vector_top[0] * vector_right[0] + vector_top[1] * vector_right[1]
+
+ if len_bottom == len_left and vec_product1 == vec_product2 == 0:
+ return True
+ return False
+```
+
+> 思路 2
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+这个思路是根据后面Follow up大佬告诉我的,根据三个点就可以算出正方形的第四个点了,然后我们需要考虑的就是下面的几个case
+
+1. 如果4个点中有两个点相等,那么肯定不行
+2. 如果是菱形,肯定不行,即夹角不为90度
+3. 如果相邻边长度不相等,那肯定不行
+
+满足以上3个条件,就返回True,否则返回False
+
+
+```python
+class Solution(object):
+ def validSquare(self, p1, p2, p3, p4):
+ """
+ :type p1: List[int]
+ :type p2: List[int]
+ :type p3: List[int]
+ :type p4: List[int]
+ :rtype: bool
+ """
+ points = [p1, p2, p3, p4]
+ points = sorted(points, key=lambda p: (p[0], p[1]))
+
+ for i in range(len(points)): # for same point case
+ for j in range(i + 1, len(points)):
+ if points[i][0] == points[j][0] and points[i][1] == points[j][1]:
+ return False
+
+ x4, y4 = points[2][0] + points[1][0] - points[0][0], points[1][1] - points[0][1] + points[2][1]
+
+ if x4 == points[-1][0] and y4 == points[-1][1]: # for point4 not exist case
+
+ distance_bottom = pow((x4-points[1][0]), 2) + pow((y4-points[1][1]), 2)
+ distance_left = pow((points[0][1]-points[1][1]), 2) + pow((points[0][0]-points[1][0]), 2)
+
+ if distance_bottom == distance_left: # for diamond case
+
+ vec_product = (x4-points[1][0]) * (points[0][0]-points[1][0]) + (y4-points[1][1]) * (points[0][1]-points[1][1])
+
+ if vec_product == 0: # for angle != 90 degree case
+ return True
+ return False
+```
+
+## Follow up
+
+如果给一个列表的点,返回一共能组成多少个正方形。input里面可能有重复的点
+
+
+开始我很sb的想着4 个 for loop取得4个点,然后用上面的函数判断是否可以组成正方形,最后叠加结果并且返回
+
+这里感谢微信墨汁大佬的指导,
+
+- 首先将input去重
+- 然后可以先将所有点放到一个字典里面去
+- 然后我们用2个for loop去确定好2个点,根据正方形的性质我们就可以自己算出正方形的另外两个点了
+- 随后我们判断这两个点是否在我们的字典里面
+
+这样我们最终的时间复杂度是O(N^2),空间复杂度是O(N),完美!!
diff --git a/docs/Leetcode_Solutions/Python/595._Big_Countries.md b/docs/Leetcode_Solutions/Python/595._Big_Countries.md
new file mode 100644
index 000000000..cf8cace79
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/595._Big_Countries.md
@@ -0,0 +1,45 @@
+# 595. Big Countries
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/big-countries/description/
+
+> 内容描述
+
+```
+There is a table World
+
++-----------------+------------+------------+--------------+---------------+
+| name | continent | area | population | gdp |
++-----------------+------------+------------+--------------+---------------+
+| Afghanistan | Asia | 652230 | 25500100 | 20343000 |
+| Albania | Europe | 28748 | 2831741 | 12960000 |
+| Algeria | Africa | 2381741 | 37100000 | 188681000 |
+| Andorra | Europe | 468 | 78115 | 3712000 |
+| Angola | Africa | 1246700 | 20609294 | 100990000 |
++-----------------+------------+------------+--------------+---------------+
+A country is big if it has an area of bigger than 3 million square km or a population of more than 25 million.
+
+Write a SQL solution to output big countries' name, population and area.
+
+For example, according to the above table, we should output:
+
++--------------+-------------+--------------+
+| name | population | area |
++--------------+-------------+--------------+
+| Afghanistan | 25500100 | 652230 |
+| Algeria | 37100000 | 2381741 |
++--------------+-------------+--------------+
+```
+
+## 解题方案
+
+> 思路 1
+
+```sql
+select name, population, area from World where area > 3000000 or population > 25000000;
+```
diff --git a/docs/leetcode/python/599._Minimum_Index_Sum_of_Two_Lists.md b/docs/Leetcode_Solutions/Python/599._Minimum_Index_Sum_of_Two_Lists.md
similarity index 94%
rename from docs/leetcode/python/599._Minimum_Index_Sum_of_Two_Lists.md
rename to docs/Leetcode_Solutions/Python/599._Minimum_Index_Sum_of_Two_Lists.md
index 819bcff9d..1682fab62 100644
--- a/docs/leetcode/python/599._Minimum_Index_Sum_of_Two_Lists.md
+++ b/docs/Leetcode_Solutions/Python/599._Minimum_Index_Sum_of_Two_Lists.md
@@ -55,4 +55,4 @@ Author: Keqi Huang
If you like it, please spread your support
-
+
diff --git a/docs/leetcode/python/606._Construct_String_from_Binary_Tree.md b/docs/Leetcode_Solutions/Python/606._Construct_String_from_Binary_Tree.md
similarity index 99%
rename from docs/leetcode/python/606._Construct_String_from_Binary_Tree.md
rename to docs/Leetcode_Solutions/Python/606._Construct_String_from_Binary_Tree.md
index cc67ceac0..df0b8af42 100644
--- a/docs/leetcode/python/606._Construct_String_from_Binary_Tree.md
+++ b/docs/Leetcode_Solutions/Python/606._Construct_String_from_Binary_Tree.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/construct-string-from-binary-tree
+* https://leetcode.com/problems/construct-string-from-binary-tree/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/611._Valid_Triangle_Number.md b/docs/Leetcode_Solutions/Python/611._Valid_Triangle_Number.md
new file mode 100644
index 000000000..fe89e524d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/611._Valid_Triangle_Number.md
@@ -0,0 +1,99 @@
+# 611. Valid Triangle Number
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/valid-triangle-number/description/
+
+> 内容描述
+
+```
+Given an array consists of non-negative integers, your task is to count the number of triplets chosen from the array that can make triangles if we take them as side lengths of a triangle.
+Example 1:
+Input: [2,2,3,4]
+Output: 3
+Explanation:
+Valid combinations are:
+2,3,4 (using the first 2)
+2,3,4 (using the second 2)
+2,2,3
+Note:
+The length of the given array won't exceed 1000.
+The integers in the given array are in the range of [0, 1000].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(1)******
+
+明确一点,三角形三边为a, b, c,那么何时满足可以组成一个三角形呢?
+要同时满足以下3点:
+1. a + b > c
+2. a + c > b
+3. b + c > a
+
+首先对数组逆向排序,固定第一个数字,我们发现```nums[i] >= nums[j] >= nums[k]```,
+所以我们现在只需要保证```nums[j] + nums[k] > nums[i]```即可,
+因为```nums[i] + nums[j] > nums[k]```和```nums[i] + nums[k] > nums[j]```是肯定的
+
+后面开始二分,分两种情况:
+- 如果```nums[j] + nums[k] > nums[i]```,那么我们只需要将```j += 1```使得比较式前面变小继续判断,
+并且```res += k - j```,因为组合```i, j, [j+1...k]```都可以满足比较式,我们需要全部加起来,后面不会再次判断了
+- 如果```nums[j] + nums[k] <= nums[i]```,那么我们只需要将```k -= 1```使得比较式前面变大继续判断是否满足比较式
+
+
+```python
+class Solution(object):
+ def triangleNumber(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ nums.sort()
+ nums = nums[::-1]
+ res = 0
+ for i in range(len(nums)-2):
+ j, k = i + 1, len(nums) - 1
+ while j < k:
+ if nums[k] + nums[j] > nums[i]:
+ res += k - j
+ j += 1
+ else:
+ k -= 1
+ return res
+```
+这里真的我遇到了两次坑,首先如果我们排序用的是正向排序的话,那么我们需要做的是固定最后一个数,否则会出现(假如固定第一个数):
+- 等式满足,我们将```j -= 1```,那么就有可能漏掉了一种情况,就是原本组合```i, j, [j+1...k-1]```可以满足,但是我们这里没有加上
+- 等式满足,我们将```k += 1```,那么就有可能漏掉了一种情况,就是原本组合```i, [j+1...k-1], k```可以满足,但是我们这里没有加上
+
+所以二分法真的没有那么简单,我们需要充分根据实际场景去改变我们的固定位置和前后更新方向
+
+这里也给出正向排序的代码:
+
+
+```python
+class Solution(object):
+ def triangleNumber(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ nums.sort()
+ res = 0
+ for k in range(len(nums)-1, 1, -1):
+ i, j = 0, k - 1
+ while i < j:
+ if nums[i] + nums[j] > nums[k]:
+ res += j - i
+ j -= 1
+ else:
+ i += 1
+ return res
+```
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/613._Shortest_Distance_in_a_Line.md b/docs/Leetcode_Solutions/Python/613._Shortest_Distance_in_a_Line.md
new file mode 100644
index 000000000..de97e3de3
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/613._Shortest_Distance_in_a_Line.md
@@ -0,0 +1,41 @@
+# 613. Shortest Distance in a Line
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/shortest-distance-in-a-line/description/
+
+> 内容描述
+
+```
+Table point holds the x coordinate of some points on x-axis in a plane, which are all integers.
+Write a query to find the shortest distance between two points in these points.
+| x |
+|-----|
+| -1 |
+| 0 |
+| 2 |
+The shortest distance is '1' obviously, which is from point '-1' to '0'. So the output is as below:
+| shortest|
+|---------|
+| 1 |
+Note: Every point is unique, which means there is no duplicates in table point.
+Follow-up: What if all these points have an id and are arranged from the left most to the right most of x axis?
+```
+
+## 解题方案
+
+> 思路 1
+
+```sql
+select min(abs(p1.x-p2.x)) as shortest from point p1, point p2 where p1.x != p2.x;
+```
+
+> 思路 2
+
+```sql
+select min(p2.x-p1.x) shortest from point p1 inner join point p2 where p2.x > p1.x;
+```
diff --git a/docs/Leetcode_Solutions/Python/621._Task_Scheduler.md b/docs/Leetcode_Solutions/Python/621._Task_Scheduler.md
new file mode 100644
index 000000000..411c9d83e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/621._Task_Scheduler.md
@@ -0,0 +1,138 @@
+# 621. Task Scheduler
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/task-scheduler/description/
+
+> 内容描述
+
+```
+Given a char array representing tasks CPU need to do. It contains capital letters A to Z where different letters represent different tasks.Tasks could be done without original order. Each task could be done in one interval. For each interval, CPU could finish one task or just be idle.
+
+However, there is a non-negative cooling interval n that means between two same tasks, there must be at least n intervals that CPU are doing different tasks or just be idle.
+
+You need to return the least number of intervals the CPU will take to finish all the given tasks.
+
+Example 1:
+Input: tasks = ["A","A","A","B","B","B"], n = 2
+Output: 8
+Explanation: A -> B -> idle -> A -> B -> idle -> A -> B.
+Note:
+The number of tasks is in the range [1, 10000].
+The integer n is in the range [0, 100].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+思路参考见[jinzhou](https://leetcode.com/problems/task-scheduler/discuss/104500/Java-O(n)-time-O(1)-space-1-pass-no-sorting-solution-with-detailed-explanation)
+
+我们只需要算我们需要多少idle,最终的结果就是len(tasks)+idles
+
+例如```3 A, 2 B, 1 C```, 我们从频率最大的A开始排列,那么一定可以排成这个样子:```A??A??A```,其中```?````代表的是还没有排列的任务,
+然后此时A已经排完了,我们继续从当前最大的B开始排,就是```AB?AB?A```,把C也放进去,就是```ABCAB?A```,最终我们就只需要一个idle,因此最终结果就是```
+len(tasks)+idles = 6+1 = 7```
+
+
+如果我们有多个频率最多的task的时候,例如,```3 A, 3 B, 2 C, 1 D```,那么我们其实可以将AB同时看成一个task,然后问题就一样了,
+
+
+对于```A ? ? ? A ? ? ? A```
+
+```?```所在区域就是我们的```emptySlots```
+
+- partCount = count(A) - 1
+- emptySlots = partCount * (n - (count of tasks with most frequency - 1))
+- availableTasks = tasks.length - count(A) * count of tasks with most frenquency
+- idles = max(0, emptySlots - availableTasks)
+- result = tasks.length + idles
+
+直接按照这种格式写,
+beats 73.65
+
+```python
+class Solution(object):
+ def leastInterval(self, tasks, n):
+ """
+ :type tasks: List[str]
+ :type n: int
+ :rtype: int
+ """
+ d = collections.Counter(tasks)
+ part_count = max(d.values()) - 1
+ empty_slots = part_count * (n-(len([i for i in d.values() if i == max(d.values())])-1))
+ available_tasks = len(tasks) - len([i for i in d.values() if i == max(d.values())]) * max(d.values())
+ idles = max(0, empty_slots - available_tasks)
+ return len(tasks) + idles
+```
+
+完全可以写的更简单一点, beats 84.90%
+
+```python
+class Solution(object):
+ def leastInterval(self, tasks, n):
+ """
+ :type tasks: List[str]
+ :type n: int
+ :rtype: int
+ """
+ lookup = {}
+ for task in tasks:
+ lookup[task] = lookup.get(task, 0) + 1
+ max_freq = max(lookup.values())
+ res = (max_freq-1) * (n+1)
+ for freq in lookup.values():
+ if freq == max_freq:
+ res += 1
+ return max(len(tasks), res)
+```
+
+写成两行版本吧
+
+```python
+class Solution(object):
+ def leastInterval(self, tasks, n):
+ """
+ :type tasks: List[str]
+ :type n: int
+ :rtype: int
+ """
+ d = collections.Counter(tasks).values()
+ return max((max(d)-1)*(n+1) + d.count(max(d)), len(tasks))
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/630._Course_Schedule_III.md b/docs/Leetcode_Solutions/Python/630._Course_Schedule_III.md
new file mode 100644
index 000000000..4ecdb8879
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/630._Course_Schedule_III.md
@@ -0,0 +1,94 @@
+# 630. Course Schedule III
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/course-schedule-iii/description/
+
+> 内容描述
+
+```
+
+There are n different online courses numbered from 1 to n. Each course has some duration(course length) t and closed on dth day. A course should be taken continuously for t days and must be finished before or on the dth day. You will start at the 1st day.
+
+Given n online courses represented by pairs (t,d), your task is to find the maximal number of courses that can be taken.
+
+Example:
+Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]]
+Output: 3
+Explanation:
+There're totally 4 courses, but you can take 3 courses at most:
+First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day.
+Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day.
+Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day.
+The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date.
+Note:
+The integer 1 <= d, t, n <= 10,000.
+You can't take two courses simultaneously.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+
+跟我一开始的思路很接近,但是我的代码没有这个精简
+
+See []().
+
+```
+Sort all the courses by their ending time. When considering the first K courses, they all end before end.
+A necessary and sufficient condition for our schedule to be valid, is that (for all K),
+the courses we choose to take within the first K of them, have total duration less than end.
+
+For each K, we will greedily remove the largest-length course until the total duration start is <= end.
+To select these largest-length courses, we will use a max heap. start will maintain the loop invariant that
+it is the sum of the lengths of the courses we have currently taken.
+
+Clearly, this greedy choice makes the number of courses used maximal for each K.
+When considering potential future K, there's never a case
+where we preferred having a longer course to a shorter one, so indeed our greedy choice dominates all other candidates.
+```
+
+beats 73.33%
+
+```python
+class Solution(object):
+ def scheduleCourse(self, courses):
+ """
+ :type courses: List[List[int]]
+ :rtype: int
+ """
+ start, taken = 0, []
+ for duration, end in sorted(courses, key = lambda x: x[1]):
+ start += duration
+ heapq.heappush(taken, -duration)
+ while start > end:
+ start -= -heapq.heappop(taken)
+ return len(taken)
+```
+
+优化了一波代码之后 beats 100%
+
+```python
+class Solution(object):
+ def scheduleCourse(self, courses):
+ """
+ :type courses: List[List[int]]
+ :rtype: int
+ """
+ courses, start, taken = sorted(courses, key = lambda x: x[1]), 0, []
+ for course in courses:
+ if start + course[0] <= course[1]:
+ start += course[0]
+ heapq.heappush(taken, -course[0])
+ elif len(taken) > 0 and -taken[0] > course[0]:
+ pop_duration = -heapq.heappop(taken)
+ start = start - pop_duration + course[0]
+ heapq.heappush(taken, -course[0])
+ return len(taken)
+```
diff --git a/docs/leetcode/python/646._Maximum_Length_of_Pair_Chain.md b/docs/Leetcode_Solutions/Python/646._Maximum_Length_of_Pair_Chain.md
similarity index 97%
rename from docs/leetcode/python/646._Maximum_Length_of_Pair_Chain.md
rename to docs/Leetcode_Solutions/Python/646._Maximum_Length_of_Pair_Chain.md
index 8cc8e6260..a294701e3 100644
--- a/docs/leetcode/python/646._Maximum_Length_of_Pair_Chain.md
+++ b/docs/Leetcode_Solutions/Python/646._Maximum_Length_of_Pair_Chain.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/maximum-length-of-pair-chain
+* https://leetcode.com/problems/maximum-length-of-pair-chain/description/
> 内容描述
diff --git a/docs/leetcode/python/647._Palindromic_Substrings.md b/docs/Leetcode_Solutions/Python/647._Palindromic_Substrings.md
similarity index 79%
rename from docs/leetcode/python/647._Palindromic_Substrings.md
rename to docs/Leetcode_Solutions/Python/647._Palindromic_Substrings.md
index 22791ab64..450acba5d 100644
--- a/docs/leetcode/python/647._Palindromic_Substrings.md
+++ b/docs/Leetcode_Solutions/Python/647._Palindromic_Substrings.md
@@ -1,12 +1,37 @@
-### 647. Palindromic Substrings
+# 647. Palindromic Substrings
-题目:
-
+**难度: Medium**
+## 刷题内容
-难度:
+> 原题连接
-Medium
+* https://leetcode.com/problems/palindromic-substrings/description/
+
+> 内容描述
+
+```
+
+Given a string, your task is to count how many palindromic substrings in this string.
+
+The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.
+
+Example 1:
+Input: "abc"
+Output: 3
+Explanation: Three palindromic strings: "a", "b", "c".
+Example 2:
+Input: "aaa"
+Output: 6
+Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".
+Note:
+The input string length won't exceed 1000.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
思路
@@ -21,17 +46,17 @@ Manacher算法增加两个辅助变量id和mx,其中id表示最大回文子串
下面,令j = 2*id - i,也就是说j是i关于id的对称点。
- 当 mx - i > P[j] 的时候,以S[j]为中心的回文子串包含在以S[id]为中心的回文子串中,由于i和j对称,以S[i]为中心的回文子串必然包含在以S[id]为中心的回文子串中,所以必有P[i] = P[j];
-
+
- 当 P[j] >= mx - i 的时候,以S[j]为中心的回文子串不一定完全包含于以S[id]为中心的回文子串中,但是基于对称性可知,下图中两个绿框所包围的部分是相同的,也就是说以S[i]为中心的回文子串,其向右至少会扩张到mx的位置,也就是说 P[i] >= mx - i。至于mx之后的部分是否对称,再具体匹配。
-
+
所以P[i] >= Min(P[2 * id - i], mx - i),因为以j为中心的绘回文子串的左边界可能会比mx关于id的对称点要大,此时只能证明P[i]=P[2 * id - i]
- 此外,对于 mx <= i 的情况,因为无法对 P[i]做更多的假设,只能让P[i] = 1,然后再去匹配。
此题还可以借鉴我leetcode第5题的解析,
[thining-in-lc-5](https://github.com/Lisanaaa/thinking_in_lc/blob/master/005._longest_palindromic_substring.md)
这道题的基本思想是将以每一个字符为中心的回文子串个数相加,还是用一个小例子来解释
-
+
其实,以‘#’为中心的回文子串就代表这个子串的长度是偶数,类似于'abba'这种
但是其实这个字符本身也是一个回文子串,所以叠加的形式是count += (P[i]+1)/2,为什么呢,以下是解释:
- 对于每一个以字符‘#’为中心的回文子串,其P值绝对是偶数,所以```(P[i]+1)/2 = P[i]/2```,并不影响
@@ -70,6 +95,10 @@ class Solution(object):
count += (P[i]+1)/2
return count
```
+
+> 思路 2
+
+
python无敌啊!!!有没有天理啊,手动滑稽😏😏😏😏!一行解法:
```python
class Solution(object):
diff --git a/docs/Leetcode_Solutions/Python/653._Two_Sum_IV_-_Input_is_a_BST.md b/docs/Leetcode_Solutions/Python/653._Two_Sum_IV_-_Input_is_a_BST.md
new file mode 100644
index 000000000..1bc1d69ac
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/653._Two_Sum_IV_-_Input_is_a_BST.md
@@ -0,0 +1,87 @@
+# 653. Two Sum IV - Input is a BST
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/two-sum-iv-input-is-a-bst/description/
+
+> 内容描述
+
+```
+Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target.
+
+Example 1:
+Input:
+ 5
+ / \
+ 3 6
+ / \ \
+2 4 7
+
+Target = 9
+
+Output: True
+Example 2:
+Input:
+ 5
+ / \
+ 3 6
+ / \ \
+2 4 7
+
+Target = 28
+
+Output: False
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+inorder遍历是O(N),后面的二分是O(lgN),总的时间复杂度为O(N)
+
+beats 75.90%
+
+```python
+class Solution(object):
+ def findTarget(self, root, k):
+ """
+ :type root: TreeNode
+ :type k: int
+ :rtype: bool
+ """
+ def inorder(root):
+ if not root:
+ return
+ inorder(root.left)
+ nums.append(root.val)
+ inorder(root.right)
+
+ nums = []
+ inorder(root)
+ l, r = 0, len(nums) - 1
+ while l < r:
+ if nums[l] + nums[r] == k:
+ return True
+ elif nums[l] + nums[r] < k:
+ l += 1
+ else:
+ r -= 1
+ return False
+```
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/657._Judge_Route_Circle.md b/docs/Leetcode_Solutions/Python/657._Judge_Route_Circle.md
similarity index 100%
rename from docs/leetcode/python/657._Judge_Route_Circle.md
rename to docs/Leetcode_Solutions/Python/657._Judge_Route_Circle.md
diff --git a/docs/Leetcode_Solutions/Python/665._Non-decreasing_Array.md b/docs/Leetcode_Solutions/Python/665._Non-decreasing_Array.md
new file mode 100644
index 000000000..bd5deb204
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/665._Non-decreasing_Array.md
@@ -0,0 +1,69 @@
+# 665. Non-decreasing Array
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/non-decreasing-array/description/
+
+> 内容描述
+
+```
+Given an array with n integers, your task is to check if it could become non-decreasing by modifying at most 1 element.
+
+We define an array is non-decreasing if array[i] <= array[i + 1] holds for every i (1 <= i < n).
+
+Example 1:
+Input: [4,2,3]
+Output: True
+Explanation: You could modify the first 4 to 1 to get a non-decreasing array.
+Example 2:
+Input: [4,2,1]
+Output: False
+Explanation: You can't get a non-decreasing array by modify at most one element.
+Note: The n belongs to [1, 10,000].
+```
+
+## 解题方案
+
+> 思路 1
+
+从index=1的元素依次检查,只要不符合规则则让count+1,如果count>1则肯定不符合返回False
+但是我们在发现nums[i]小于nums[i-1]的时候,我们就必须要对原数组作出改变了,来让它的后面index部分尽可能满足条件
+下面就是两种情况:
+- 2,4,2,6
+
+如果是这种情况,当index=2时,不满足条件,但是i=0的元素是小于i=2处元素的,我们需要改变的是i-1处的元素,也就是将4改变成i=2处元素即2,最终变成2,2,2,6
+
+- 3,4,2,6
+
+这种情况如果我们将4变成2那么仍然是不满足条件的,此时我们需要将2变成4,即将i处元素变为i-1处元素
+
+在每一次不符合条件的时候我们都检查一下count,如果count大于1的话我们就返回False,否则最终就返回True
+
+```python
+class Solution(object):
+ def checkPossibility(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: bool
+ """
+ if not nums or len(nums) <= 1:
+ return True
+ count = 0
+ for i in range(1, len(nums)):
+ if nums[i] < nums[i-1]:
+ count += 1
+ if count > 1:
+ return False
+ if i-2 < 0 or nums[i-2] <= nums[i]:
+ nums[i-1] = nums[i]
+ else:
+ nums[i] = nums[i-1]
+ return True
+```
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/672._Bulb_Switcher_II.md b/docs/Leetcode_Solutions/Python/672._Bulb_Switcher_II.md
new file mode 100644
index 000000000..3cad5b3ce
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/672._Bulb_Switcher_II.md
@@ -0,0 +1,105 @@
+# 672. Bulb Switcher II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/bulb-switcher-ii/description/
+
+> 内容描述
+
+```
+There is a room with n lights which are turned on initially and 4 buttons on the wall. After performing exactly m unknown operations towards buttons, you need to return how many different kinds of status of the n lights could be.
+
+Suppose n lights are labeled as number [1, 2, 3 ..., n], function of these 4 buttons are given below:
+
+Flip all the lights.
+Flip lights with even numbers.
+Flip lights with odd numbers.
+Flip lights with (3k + 1) numbers, k = 0, 1, 2, ...
+Example 1:
+Input: n = 1, m = 1.
+Output: 2
+Explanation: Status can be: [on], [off]
+Example 2:
+Input: n = 2, m = 1.
+Output: 3
+Explanation: Status can be: [on, off], [off, on], [off, off]
+Example 3:
+Input: n = 3, m = 1.
+Output: 4
+Explanation: Status can be: [off, on, off], [on, off, on], [off, off, off], [off, on, on].
+Note: n and m both fit in range [0, 1000].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+这道题又是一个数学题。找规律呀找规律。
+我们只需要考虑当 n<=2 and m < 3 的特殊情形。因为当 n >2 and m >=3, 结果肯定是 8.
+The four buttons:
+
+- Flip all the lights.
+- Flip lights with even numbers.
+- Flip lights with odd numbers.
+- Flip lights with (3k + 1) numbers, k = 0, 1, 2, ...
+
+如果我们使用了 button 1 和 2, 其效果等同于使用 button 3 。
+类似的..
+
+- 1 + 2 --> 3
+- 1 + 3 --> 2
+- 2 + 3 --> 1
+
+所以,只有 8 种情形。
+
+***灯全亮, 操作1, 操作2, 操作3, 操作4, 操作1+4, 操作2+4, 操作3+4***
+
+并且当 n>2 and m>=3 时,我们就能够获得所有的情形。
+
+| m\n | 0 | 1 | 2 | 3 | 4 |
+ --- |----|--- |----|---|---|
+| 0 | 1 | 1 | 1 | 1 | 1 |
+| 1 | 1 | 2 | 3 | 4 | 4 |
+| 2 | 1 | 2 | 4 | 7 | 7 |
+| 3 | 1 | 2 | 3 | 8 | 8 |
+
+```python
+class Solution(object):
+ def flipLights(self, n, m):
+ """
+ :type n: int
+ :type m: int
+ :rtype: int
+ """
+ if m * n == 0: return 1
+ if n == 1: return 2
+ if n == 2: return 4 - (m % 2)
+ if m == 1: return 4
+ if m == 2: return 7
+ return 8
+```
+
+> 思路 2
+
+
+还有两位大佬的两行解法:
+
+```python
+class Solution(object):
+ def flipLights(self, n, m):
+ m, n = min(3, m), min(3, n)
+ return 1 if n * m == 0 else self.flipLights(n - 1, m) + self.flipLights( n - 1, m - 1)
+```
+```python
+class Solution(object):
+ def flipLights(self, n, m):
+ n = min(n, 3)
+ return min(1<难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/valid-parenthesis-string/description/
+
+> 内容描述
+
+```
+
+Given a string containing only three types of characters: '(', ')' and '*', write a function to check whether this string is valid. We define the validity of a string by these rules:
+
+Any left parenthesis '(' must have a corresponding right parenthesis ')'.
+Any right parenthesis ')' must have a corresponding left parenthesis '('.
+Left parenthesis '(' must go before the corresponding right parenthesis ')'.
+'*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string.
+An empty string is also valid.
+Example 1:
+Input: "()"
+Output: True
+Example 2:
+Input: "(*)"
+Output: True
+Example 3:
+Input: "(*))"
+Output: True
+Note:
+The string size will be in the range [1, 100].
+```
+
+## 解题方案
+
+
+> 思路 1
+******- 时间复杂度: O(N^3)******- 空间复杂度: O(N^2)******
+
+```
+Let dp[i][j] be true if and only if the interval s[i], s[i+1], ..., s[j] can be made valid. Then dp[i][j] is true only if:
+
+s[i] is '*', and the interval s[i+1], s[i+2], ..., s[j] can be made valid;
+
+or, s[i] can be made to be '(', and there is some k in [i+1, j] such that s[k] can be made to be ')', plus the two intervals cut by s[k] (s[i+1: k] and s[k+1: j+1]) can be made valid;
+```
+因为文章要从垃圾算法写到好的算法,这不是我的第一解法
+
+但是是真的垃圾,才beats 2.75%
+```python
+class Solution(object):
+ def checkValidString(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ if not s or len(s) == 0:
+ return True
+
+ LEFTY, RIGHTY = '(*', ')*'
+
+ n = len(s)
+ dp = [[0] * n for _ in s]
+ for i in range(n):
+ if s[i] == '*':
+ dp[i][i] = 1
+ if i < n-1 and s[i] in LEFTY and s[i+1] in RIGHTY:
+ dp[i][i+1] = 1
+ for j in range(n):
+ for i in range(j-2, -1, -1):
+ if s[i] == '*' and dp[i+1][j]:
+ dp[i][j] = 1
+ elif s[i] in LEFTY:
+ for k in range(i+1, j+1):
+ if s[k] in RIGHTY and \
+ (k == i+1 or dp[i+1][k-1]) and \
+ (k == j or dp[k+1][j]):
+ dp[i][j] = 1
+
+ return True if dp[0][-1] else False
+```
+
+或者后面的循环按照子串的长度size来遍历,
+
+```python
+class Solution(object):
+ def checkValidString(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ if not s or len(s) == 0:
+ return True
+
+ LEFTY, RIGHTY = '(*', ')*'
+
+ n = len(s)
+ dp = [[False] * n for _ in s]
+ for i in range(n):
+ if s[i] == '*':
+ dp[i][i] = True
+ if i < n-1 and s[i] in LEFTY and s[i+1] in RIGHTY:
+ dp[i][i+1] = True
+
+ for size in range(2, n):
+ for i in range(n - size):
+ if s[i] == '*' and dp[i+1][i+size]:
+ dp[i][i+size] = True
+ elif s[i] in LEFTY:
+ for k in range(i+1, i+size+1):
+ if (s[k] in RIGHTY and \
+ (k == i+1 or dp[i+1][k-1]) and \
+ (k == i+size or dp[k+1][i+size])):
+ dp[i][i+size] = True
+
+ return dp[0][-1]
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+这是我的最初方法
+
+- Keep track of indices for unmatched '(' and available '*'.
+- After the loop we can check whether the index of any remaining '*' can match the unmatched '('.
+- If the index of star is greater than the index of '(' then they can match.
+
+beats 100%
+
+
+```python
+class Solution(object):
+ def checkValidString(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ if not s or len(s) == 0:
+ return True
+
+ stack, star = [], []
+ for i in range(len(s)):
+ if s[i] == '(':
+ stack.append(i)
+ elif s[i] == ')':
+ if stack:
+ stack.pop()
+ elif star:
+ star.pop()
+ else:
+ return False
+ else:
+ star.append(i)
+
+ while stack and star:
+ # 从后面开始比较,如果最后出现的'('的index比最后出现的'*'更大,那其实这个匹配不了,比如'*('
+ if stack[-1] > star[-1]:
+ return False
+ else:
+ stack.pop()
+ star.pop()
+
+ return not stack
+```
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+看到别人的解法,真的🐂p,贪心算法
+
+```
+We know that at each point in the string, '( 'count should never be bigger than ')' count, and in the end the difference of two counts should be 0.
+So we have two boundaries: lowerBond and higherBound, which respectively represents the minimun possible difference and maximum possbile difference, as long as
+
+higherBound is never below 0.
+in the end 0 is between lowerBond and higherBound
+in the string, when lowerbound is < 0, we make it back to 0.
+We know that the string is valid.
+```
+
+beats 100%
+
+```python
+class Solution(object):
+ def checkValidString(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ lower_bound = higher_bound = 0
+ for c in s:
+ lower_bound += 1 if c == '(' else -1
+ higher_bound += 1 if c != ')' else -1
+ if higher_bound < 0:
+ return False
+ lower_bound = max(lower_bound, 0)
+
+ return lower_bound == 0
+```
+
diff --git a/docs/Leetcode_Solutions/Python/680._Valid_Palindrome_II.md b/docs/Leetcode_Solutions/Python/680._Valid_Palindrome_II.md
new file mode 100644
index 000000000..b33597376
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/680._Valid_Palindrome_II.md
@@ -0,0 +1,111 @@
+# 680. Valid Palindrome II
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/valid-palindrome-ii/description/
+
+> 内容描述
+
+```
+
+Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome.
+
+Example 1:
+Input: "aba"
+Output: True
+Example 2:
+Input: "abca"
+Output: True
+Explanation: You could delete the character 'c'.
+Note:
+The string will only contain lowercase characters a-z. The maximum length of the string is 50000.
+```
+
+## 解题方案
+
+> 思路 1
+
+想直接来个 for loop,看看对应除去该index元素之后的字符串是否为 palindrome 即可
+
+但是直接 Time Limit Exceeded
+
+```python
+class Solution(object):
+ def validPalindrome(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ for i in range(len(s)):
+ if s[:i] + s[i+1:] == s[i+1:][::-1] + s[:i][::-1]:
+ return True
+ return False
+```
+
+
+> 思路 2
+
+我们先定义一个reverse变量作为字符串s的翻转版本,例如
+
+```
+s = 'abbbbbca'
+reverse = 'acbbbbba'
+```
+
+然后我们从第一个字符开始比较,直到两边的字符不相等的时候,比如上面的例子我们就是index为1的时候不相等,所以i = 1,此时我们就会面临两个选择:
+
+1. 我们可以舍弃s中index为i的这个元素看看是否可以使其成为palindrome,即让s变成'abbbbca',然后我们可以通过s[i+1:n-i] == reverse[i:n-i-1]来判断
+2. 我们可以舍弃reverse中index为i的这个元素(即s中index为n-1-i的这个元素),即让s变成'abbbbba',我们可以通过s[i:n-1-i] == reverse[i+1:n-i]来判断
+
+```python
+class Solution(object):
+ def validPalindrome(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ n = len(s)
+ if n < 3:
+ return True
+
+ reverse = s[::-1]
+ i = 0
+ while i < len(s) and s[i] == reverse[i]:
+ i += 1
+ return s[i:n-1-i] == reverse[i+1:n-i] or s[i+1:n-i] == reverse[i:n-i-1]
+```
+
+
+
+> 思路 3
+
+或者我们不搞reverse,直接在s上面原地判断即可
+
+
+```python
+class Solution(object):
+ def validPalindrome(self, s):
+ """
+ :type s: str
+ :rtype: bool
+ """
+ n = len(s)
+ if n < 3:
+ return True
+
+ l, r = 0, n - 1
+ while l < r and s[l] == s[r]:
+ l += 1
+ r -= 1
+ if l >= r:
+ return True
+ else:
+ return s[l+1:r+1] == s[l+1:r+1][::-1] or s[l:r] == s[l:r][::-1]
+```
+
+
+
diff --git a/docs/leetcode/python/681._Next_Closest_Time.md b/docs/Leetcode_Solutions/Python/681._Next_Closest_Time.md
similarity index 100%
rename from docs/leetcode/python/681._Next_Closest_Time.md
rename to docs/Leetcode_Solutions/Python/681._Next_Closest_Time.md
diff --git a/docs/leetcode/python/682._Baseball_Game.md b/docs/Leetcode_Solutions/Python/682._Baseball_Game.md
similarity index 100%
rename from docs/leetcode/python/682._Baseball_Game.md
rename to docs/Leetcode_Solutions/Python/682._Baseball_Game.md
diff --git a/docs/leetcode/python/685._Redundant_Connection_II.md b/docs/Leetcode_Solutions/Python/685._Redundant_Connection_II.md
similarity index 100%
rename from docs/leetcode/python/685._Redundant_Connection_II.md
rename to docs/Leetcode_Solutions/Python/685._Redundant_Connection_II.md
diff --git a/docs/leetcode/python/687._Longest_Univalue_Path.md b/docs/Leetcode_Solutions/Python/687._Longest_Univalue_Path.md
similarity index 100%
rename from docs/leetcode/python/687._Longest_Univalue_Path.md
rename to docs/Leetcode_Solutions/Python/687._Longest_Univalue_Path.md
diff --git a/docs/leetcode/python/693._Binary_Number_with_Alternating_Bits.md b/docs/Leetcode_Solutions/Python/693._Binary_Number_with_Alternating_Bits.md
similarity index 97%
rename from docs/leetcode/python/693._Binary_Number_with_Alternating_Bits.md
rename to docs/Leetcode_Solutions/Python/693._Binary_Number_with_Alternating_Bits.md
index 0fdbac4b1..f95ae536e 100644
--- a/docs/leetcode/python/693._Binary_Number_with_Alternating_Bits.md
+++ b/docs/Leetcode_Solutions/Python/693._Binary_Number_with_Alternating_Bits.md
@@ -6,8 +6,8 @@
> 原题连接
-* https://leetcode.com/problems/binary-number-with-alternating-bits
-* https://leetcode-cn.com/problems/binary-number-with-alternating-bits
+* https://leetcode.com/problems/binary-number-with-alternating-bits/description/
+* https://leetcode-cn.com/problems/binary-number-with-alternating-bits/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/695._Max_Area_of_Island.md b/docs/Leetcode_Solutions/Python/695._Max_Area_of_Island.md
new file mode 100644
index 000000000..f25827006
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/695._Max_Area_of_Island.md
@@ -0,0 +1,164 @@
+# 695. Max Area of Island
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/max-area-of-island/description/
+
+> 内容描述
+
+```
+Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water.
+
+Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area is 0.)
+
+Example 1:
+[[0,0,1,0,0,0,0,1,0,0,0,0,0],
+ [0,0,0,0,0,0,0,1,1,1,0,0,0],
+ [0,1,1,0,1,0,0,0,0,0,0,0,0],
+ [0,1,0,0,1,1,0,0,1,0,1,0,0],
+ [0,1,0,0,1,1,0,0,1,1,1,0,0],
+ [0,0,0,0,0,0,0,0,0,0,1,0,0],
+ [0,0,0,0,0,0,0,1,1,1,0,0,0],
+ [0,0,0,0,0,0,0,1,1,0,0,0,0]]
+Given the above grid, return 6. Note the answer is not 11, because the island must be connected 4-directionally.
+Example 2:
+[[0,0,0,0,0,0,0,0]]
+Given the above grid, return 0.
+Note: The length of each dimension in the given grid does not exceed 50.
+```
+
+## 解题方案
+
+> 思路 1
+
+
+对于每一个点我们不停的dfs,然后每次碰到一个点是1我们就将当前area加1,然后把这个点变成0,每一次都更新我们的res,最终返回res
+
+```python
+class Solution(object):
+ def maxAreaOfIsland(self, grid):
+ """
+ :type grid: List[List[int]]
+ :rtype: int
+ """
+ if not grid or len(grid) == 0:
+ return 0
+ m = len(grid)
+ n = len(grid[0]) if m else 0
+
+ def dfs(i, j, area):
+ if i < 0 or i >= m or j < 0 or j >= n or grid[i][j] != 1:
+ return area
+ else:
+ grid[i][j] = 0
+ area += 1
+ for x, y in ([(i, j+1), (i, j-1), (i+1, j), (i-1, j)]):
+ area = dfs(x, y, area)
+ return area
+
+ res = 0
+ for i in range(len(grid)):
+ for j in range(len(grid[0])):
+ area = dfs(i, j, 0)
+ res = max(res, area)
+ return res
+```
+
+
+
+## Follow up:
+
+If we still want the max area of the island, but if one land is surrrounded all by land,
+then it should not be part of our area, how can we solve it?
+
+
+
+
+比如:
+```
+1 0 0 1 1 1
+1 0 0 1 1 1
+0 0 0 0 1 1
+```
+
+这个我们要返回的是7而不是8,因为坐标为(1,4)的点被陆地包围,所以我们不算他的面积
+
+大概思路就是并查集,然后各大岛屿的坐标集合遍历一遍看看有没有没有点完全被包围,有的话就面积减1,然后最后算出来,
+参考[leetcode 200](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/200._number_of_islands.md)
+和 [leetcode 305](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/305._Number_of_Islands_II.md)
+
+```python
+def find(x, uf):
+ while x != uf[x]:
+ uf[x] = uf[uf[x]]
+ x = uf[x]
+ return uf[x]
+
+class Solution(object):
+ uf, idx = {}, 1
+ def numIslands(self, grid):
+ """
+ :type grid: List[List[str]]
+ :rtype: int
+ """
+ m = len(grid)
+ n = len(grid[0])
+
+
+
+ def sink(i, j):
+ if 0 <= i < len(grid) and 0 <= j < len(grid[0]) and grid[i][j] == '1':
+ self.uf[(i,j)] = self.uf[self.idx] = self.idx
+ grid[i][j] = '0'
+ for x, y in [(i, j+1), (i, j-1), (i+1, j), (i-1, j)]:
+ if (x,y) in self.uf:
+ root = find(self.uf[(x,y)], self.uf)
+ self.uf[root] = self.idx
+ self.idx += 1
+ map(sink, (i+1, i-1, i, i), (j, j, j+1, j-1))
+
+ for i in range(len(grid)):
+ for j in range(len(grid[0])):
+ sink(i, j)
+ return self.uf
+
+grid = [["1","1","1","1","0"],["1","1","1","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]]
+grid1 = [["1","1","1","1","0"],["1","1","1","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]]
+# print(Solution().numIslands(grid))
+
+uf = Solution().numIslands(grid)
+print(uf)
+
+islands = {}
+for key in uf.keys():
+ if type(key).__name__ != 'int':
+ if find(key, uf) not in islands:
+ islands[find(key, uf)] = [key]
+ else:
+ islands[find(key, uf)].append(key)
+print(islands)
+
+print(grid)
+max_aera = -float('inf')
+for key in islands.keys():
+ aera = len(islands[key])
+ for i, j in islands[key]:
+ tmp = 0
+ for x, y in [(i, j + 1), (i, j - 1), (i + 1, j), (i - 1, j)]:
+ if 0 <= x < len(grid1) and 0 <= y < len(grid1[0]) and grid1[x][y] == '1':
+ tmp += 1
+ if tmp == 4:
+ aera -= 1
+ max_aera = max(max_aera, aera)
+print(max_aera)
+```
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/698._Partition_to_K_Equal_Sum_Subsets.md b/docs/Leetcode_Solutions/Python/698._Partition_to_K_Equal_Sum_Subsets.md
new file mode 100644
index 000000000..ebf2f58f6
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/698._Partition_to_K_Equal_Sum_Subsets.md
@@ -0,0 +1,61 @@
+# 698. Partition to K Equal Sum Subsets
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/
+
+> 内容描述
+
+```
+Given an array of integers nums and a positive integer k, find whether it's possible to divide this array into k non-empty subsets whose sums are all equal.
+
+Example 1:
+Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
+Output: True
+Explanation: It's possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums.
+Note:
+
+1 <= k <= len(nums) <= 16.
+0 < nums[i] < 10000.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N!)******- 空间复杂度: O(N)******
+
+
+
+将问题一步一步缩小到找一个subset的sum为target的问题,即剩下的整个数组的sum是否为target
+```python
+class Solution(object):
+ def canPartitionKSubsets(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: bool
+ """
+ def dfs(nums, target, num, k):
+ if k == 0:
+ return True
+ for i in range(len(nums)):
+ new_nums = nums[:i] + nums[i+1:]
+ if num + nums[i] == target:
+ if dfs(new_nums, target, 0, k-1):
+ return True
+ elif num + nums[i] < target:
+ if dfs(new_nums, target, num+nums[i], k):
+ return True
+ elif num == 0: # 有一个数比target还大,直接返回False
+ return False
+ return False
+ if sum(nums) % k != 0:
+ return False
+ target = sum(nums) / k
+ nums.sort(reverse = True) # 逆序排序,先从大的开始判断,速度会更快
+ return dfs(nums, target, 0, k)
+```
diff --git a/docs/leetcode/python/701._Insert_into_a_Binary_Search_Tree.md b/docs/Leetcode_Solutions/Python/701._Insert_into_a_Binary_Search_Tree.md
similarity index 100%
rename from docs/leetcode/python/701._Insert_into_a_Binary_Search_Tree.md
rename to docs/Leetcode_Solutions/Python/701._Insert_into_a_Binary_Search_Tree.md
diff --git a/docs/leetcode/python/707._Design_Linked_List.md b/docs/Leetcode_Solutions/Python/707._Design_Linked_List.md
similarity index 98%
rename from docs/leetcode/python/707._Design_Linked_List.md
rename to docs/Leetcode_Solutions/Python/707._Design_Linked_List.md
index 6b84db798..7623a50ac 100644
--- a/docs/leetcode/python/707._Design_Linked_List.md
+++ b/docs/Leetcode_Solutions/Python/707._Design_Linked_List.md
@@ -6,7 +6,7 @@
> 原题连接
-* https://leetcode.com/problems/design-linked-list
+* https://leetcode.com/problems/design-linked-list/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/713._Subarray_Product_Less_Than_K.md b/docs/Leetcode_Solutions/Python/713._Subarray_Product_Less_Than_K.md
new file mode 100644
index 000000000..1e01bb7f8
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/713._Subarray_Product_Less_Than_K.md
@@ -0,0 +1,97 @@
+# 713. Subarray Product Less Than K
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/subarray-product-less-than-k/description/
+
+> 内容描述
+
+```
+Your are given an array of positive integers nums.
+
+Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less than k.
+
+Example 1:
+Input: nums = [10, 5, 2, 6], k = 100
+Output: 8
+Explanation: The 8 subarrays that have product less than 100 are: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6].
+Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k.
+Note:
+
+0 < nums.length <= 50000.
+0 < nums[i] < 1000.
+0 <= k < 10^6.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+跟第560题思路一样,维护一个当前积的常量,每次只要看之前有多少个积大于 cur_product/nums[i]的,如果有就说明最近出现的这个subarray product可以小于k
+
+但是超时了
+
+```
+class Solution(object):
+ def numSubarrayProductLessThanK(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: int
+ """
+ if k == 0:
+ n = nums.count(0)
+ return n*(n+1)/2
+ # 这是为了保证如果当前product的值就等于k的话,我们其实也相当于找到一次
+ lookup = {1:1}
+ res = 0
+ cur_product = 1
+ for num in nums:
+ cur_product *= num
+ res += sum(lookup[key] for key in lookup.keys() if key > cur_product/k)
+ # for key in lookup.keys():
+ # if key > cur_product / k:
+ # res += lookup.get(key)
+ lookup[cur_product] = lookup.get(cur_product, 0) + 1
+ return res
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+参考[gabbu](https://leetcode.com/problems/subarray-product-less-than-k/discuss/108846/Python-solution-with-detailed-explanation)
+```
+Initialize start and end to index 0. Initialize prod to 1. Iterate end from 0 to len(nums)-1.
+Now if prod * nums[end] is less than k, then all subarray between start and end contribute to the solution.
+Since we are moving from left to right, we would have already counted all valid subarrays from start to end-1.
+How many new subarrays with nums[end]? Answer: end-start. What will be the updated prod? Answer: prod * nums[end].
+
+```
+
+双指针走起,beats 74.86%
+
+```python
+class Solution(object):
+ def numSubarrayProductLessThanK(self, nums, k):
+ """
+ :type nums: List[int]
+ :type k: int
+ :rtype: int
+ """
+ if k <= 1:
+ return 0
+ start, end, prod, res = 0, 0, 1, 0
+ while end < len(nums):
+ prod *= nums[end]
+ end += 1
+ while prod >= k:
+ prod /= nums[start]
+ start += 1
+ res += end - start
+ return res
+```
diff --git a/docs/Leetcode_Solutions/Python/714._Best_Time_to_Buy_and_Sell_Stock_with_Transaction_Fee.md b/docs/Leetcode_Solutions/Python/714._Best_Time_to_Buy_and_Sell_Stock_with_Transaction_Fee.md
new file mode 100644
index 000000000..e6f720783
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/714._Best_Time_to_Buy_and_Sell_Stock_with_Transaction_Fee.md
@@ -0,0 +1,108 @@
+# 714. Best Time to Buy and Sell Stock with Transaction Fee
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/description/
+
+> 内容描述
+
+```
+Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; and a non-negative integer fee representing a transaction fee.
+
+You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.)
+
+Return the maximum profit you can make.
+
+Example 1:
+Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
+Output: 8
+Explanation: The maximum profit can be achieved by:
+Buying at prices[0] = 1
+Selling at prices[3] = 8
+Buying at prices[4] = 4
+Selling at prices[5] = 9
+The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
+Note:
+
+0 < prices.length <= 50000.
+0 < prices[i] < 50000.
+0 <= fee < 50000.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+直接看的solution
+
+
+1. 如果今天过后我手上有股票:
+ - 要么是我昨天有股票今天没卖
+ - 要么是我昨天没有股票,但是今天买了
+ - own = max(own, notown - prices[i])
+2. 如果今天过后我手上没有股票:
+ - 要么是我昨天就没有股票今天也没有买
+ - 要么是我昨天手上有股票,但是今天卖了
+ - notown = max(notown, own + prices[i] - fee)
+
+
+beats 70.38%
+
+```python
+class Solution(object):
+ def maxProfit(self, prices, fee):
+ """
+ :type prices: List[int]
+ :type fee: int
+ :rtype: int
+ """
+ notown, own = 0, -prices[0] # 第一天就有股票说明我第一天买了股票,因此profit为 -prices[0]
+ for i in range(1, len(prices)):
+ notown = max(notown, own + prices[i] - fee)
+ own = max(own, notown - prices[i])
+ return notown
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/724._Find_Pivot_Index.md b/docs/Leetcode_Solutions/Python/724._Find_Pivot_Index.md
new file mode 100644
index 000000000..04ab325d9
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/724._Find_Pivot_Index.md
@@ -0,0 +1,112 @@
+# 724. Find Pivot Index
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-pivot-index/description/
+
+> 内容描述
+
+```
+Given an array of integers nums, write a method that returns the "pivot" index of this array.
+
+We define the pivot index as the index where the sum of the numbers to the left of the index is equal to the sum of the numbers to the right of the index.
+
+If no such index exists, we should return -1. If there are multiple pivot indexes, you should return the left-most pivot index.
+
+Example 1:
+Input:
+nums = [1, 7, 3, 6, 5, 6]
+Output: 3
+Explanation:
+The sum of the numbers to the left of index 3 (nums[3] = 6) is equal to the sum of numbers to the right of index 3.
+Also, 3 is the first index where this occurs.
+Example 2:
+Input:
+nums = [1, 2, 3]
+Output: -1
+Explanation:
+There is no index that satisfies the conditions in the problem statement.
+Note:
+
+The length of nums will be in the range [0, 10000].
+Each element nums[i] will be an integer in the range [-1000, 1000].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+前缀和数组+后缀和数组,实现时间复杂度O(n)和空间复杂度O(n),3分钟 bug free
+
+
+
+```python
+class Solution(object):
+ def pivotIndex(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ if not nums or len(nums) == 0:
+ return -1
+
+ prefix_sums = [nums[0]] * len(nums)
+ for i in range(1, len(nums)):
+ prefix_sums[i] = nums[i] + prefix_sums[i-1]
+
+ suffix_sums = [nums[-1]] * len(nums)
+ for i in range(len(nums)-2, -1, -1):
+ suffix_sums[i] = nums[i] + suffix_sums[i+1]
+
+ sums = sum(nums)
+ if sum(nums[1:]) == 0:
+ return 0
+ for i in range(1, len(nums)):
+ if prefix_sums[i] == suffix_sums[i]:
+ return i
+ return -1
+```
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+后面发现其实空间只要O(1)就可以了,就是用left_sum, right_sum分别代表左右两边的和,初始化为0和sum(nums)
+
+```python
+class Solution(object):
+ def pivotIndex(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ left_sum, right_sum = 0, sum(nums)
+ for idx, num in enumerate(nums):
+ right_sum -= num
+ if left_sum == right_sum:
+ return idx
+ left_sum += num
+ return -1
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/733._Flood_Fill.md b/docs/Leetcode_Solutions/Python/733._Flood_Fill.md
new file mode 100644
index 000000000..d1c54dceb
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/733._Flood_Fill.md
@@ -0,0 +1,80 @@
+# 733. Flood Fill
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/flood-fill/description/
+
+> 内容描述
+
+```
+An image is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535).
+
+Given a coordinate (sr, sc) representing the starting pixel (row and column) of the flood fill, and a pixel value newColor, "flood fill" the image.
+
+To perform a "flood fill", consider the starting pixel, plus any pixels connected 4-directionally to the starting pixel of the same color as the starting pixel, plus any pixels connected 4-directionally to those pixels (also with the same color as the starting pixel), and so on. Replace the color of all of the aforementioned pixels with the newColor.
+
+At the end, return the modified image.
+
+Example 1:
+Input:
+image = [[1,1,1],[1,1,0],[1,0,1]]
+sr = 1, sc = 1, newColor = 2
+Output: [[2,2,2],[2,2,0],[2,0,1]]
+Explanation:
+From the center of the image (with position (sr, sc) = (1, 1)), all pixels connected
+by a path of the same color as the starting pixel are colored with the new color.
+Note the bottom corner is not colored 2, because it is not 4-directionally connected
+to the starting pixel.
+Note:
+
+The length of image and image[0] will be in the range [1, 50].
+The given starting pixel will satisfy 0 <= sr < image.length and 0 <= sc < image[0].length.
+The value of each color in image[i][j] and newColor will be an integer in [0, 65535].
+
+```
+
+## 解题方案
+
+> 思路 1
+
+
+dfs, 多加了一层判断,只有周围color一样才放进stack里面
+
+```python
+class Solution(object):
+ def floodFill(self, image, sr, sc, newColor):
+ """
+ :type image: List[List[int]]
+ :type sr: int
+ :type sc: int
+ :type newColor: int
+ :rtype: List[List[int]]
+ """
+ row = len(image)
+ col = len(image[0]) if row else 0
+ directions = [[1,0], [-1,0], [0,1], [0,-1]]
+
+ def dfs(image, sr, sc, color):
+ stack, visited = [[sr, sc]], []
+ flood = []
+ while stack:
+ vertex = stack.pop()
+ if vertex not in visited:
+ flood.append(vertex)
+ visited.append(vertex)
+ x, y = vertex[0], vertex[1]
+ for dire in directions:
+ if 0 <= x+dire[0] < row and 0 <= y+dire[1] < col:
+ if [x+dire[0], y+dire[1]] not in visited:
+ if image[x+dire[0]][y+dire[1]] == color:
+ stack.append([x+dire[0], y+dire[1]])
+ return flood
+
+ for i in dfs(image, sr, sc, image[sr][sc]):
+ image[i[0]][i[1]] = newColor
+ return image
+```
diff --git a/docs/Leetcode_Solutions/Python/739._Daily_Temperatures.md b/docs/Leetcode_Solutions/Python/739._Daily_Temperatures.md
new file mode 100644
index 000000000..dd6d69d0e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/739._Daily_Temperatures.md
@@ -0,0 +1,87 @@
+# 739. Daily Temperatures
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/daily-temperatures/description/
+
+> 内容描述
+
+```
+Given a list of daily temperatures, produce a list that, for each day in the input, tells you how many days you would have to wait until a warmer temperature. If there is no future day for which this is possible, put 0 instead.
+
+For example, given the list temperatures = [73, 74, 75, 71, 69, 72, 76, 73], your output should be [1, 1, 4, 2, 1, 1, 0, 0].
+
+Note: The length of temperatures will be in the range [1, 30000]. Each temperature will be an integer in the range [30, 100].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N*W)******- 空间复杂度: O(N+W)******
+
+Next Array 方法
+
+温度只有[30,100],搞一个102长度的list记一下
+
+```python
+class Solution(object):
+ def dailyTemperatures(self, temperatures):
+ """
+ :type temperatures: List[int]
+ :rtype: List[int]
+ """
+ nxt = [float('inf')] * 102
+ res = [0] * len(temperatures)
+ for i, temperature in enumerate(temperatures[::-1]):
+ # Use 102 so min(nxt[t]) has a default value
+ i = len(temperatures) - 1 - i
+ warmer_index = min(nxt[t] for t in range(temperature+1, 102)) # 最近的一个warmer天的idx
+ if warmer_index < float('inf'):
+ res[i] = warmer_index - i # 第一个warmer天的idx与当前idx的差即为等几天
+ nxt[temperature] = i
+ return res
+```
+
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(W)******
+
+
+
+
+单调栈, 牢记找小于大于问题
+
+beats 87.24%
+
+
+```python
+class Solution(object):
+ def dailyTemperatures(self, temperatures):
+ """
+ :type temperatures: List[int]
+ :rtype: List[int]
+ """
+ res = [0] * len(temperatures)
+ stack = [] # indexes from hottest to coldest
+ for i in range(len(temperatures) - 1, -1, -1):
+ while stack and temperatures[i] >= temperatures[stack[-1]]:
+ stack.pop()
+ if stack:
+ res[i] = stack[-1] - i # 第一个warmer天的idx与当前idx的差即为等几天
+ stack.append(i)
+ return res
+```
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/740._delete_and_earn.md b/docs/Leetcode_Solutions/Python/740._delete_and_earn.md
new file mode 100644
index 000000000..7d50fc5a8
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/740._delete_and_earn.md
@@ -0,0 +1,85 @@
+# 740. Delete and Earn
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/delete-and-earn/description/
+
+> 内容描述
+
+```
+Given an array nums of integers, you can perform operations on the array.
+
+In each operation, you pick any nums[i] and delete it to earn nums[i] points. After, you must delete every element equal to nums[i] - 1 or nums[i] + 1.
+
+You start with 0 points. Return the maximum number of points you can earn by applying such operations.
+
+Example 1:
+Input: nums = [3, 4, 2]
+Output: 6
+Explanation:
+Delete 4 to earn 4 points, consequently 3 is also deleted.
+Then, delete 2 to earn 2 points. 6 total points are earned.
+Example 2:
+Input: nums = [2, 2, 3, 3, 3, 4]
+Output: 9
+Explanation:
+Delete 3 to earn 3 points, deleting both 2's and the 4.
+Then, delete 3 again to earn 3 points, and 3 again to earn 3 points.
+9 total points are earned.
+Note:
+
+The length of nums is at most 20000.
+Each element nums[i] is an integer in the range [1, 10000].
+```
+
+## 解题方案
+
+> 思路 1
+
+典型dp,dp[i]代表的是数字i,然后我们将其变化为删除数字i我们可以得到的最大分数(已经处理过所有比i小的数字了)。
+
+推导公式为dp[i] = max(dp[i]+dp[i-2], dp[i-1]),
+
+- 即要么删除dp[i]得到所有数字i的和
+- 要么删除dp[i-1]不要dp[i]的分数
+
+又因为Each element nums[i] is an integer in the range [1, 10000],所以dp长度初始化为10001
+
+```python
+class Solution(object):
+ def deleteAndEarn(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ dp = [0] * 10001
+ for num in nums:
+ # now dp[num] = sum of the num in nums
+ dp[num] += num
+ for i in range(2, 10001):
+ dp[i] = max(dp[i]+dp[i-2], dp[i-1])
+ return dp[-1]
+```
+
+
+> 思路 2
+
+迭代
+
+```python
+class Solution(object):
+ def deleteAndEarn(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: int
+ """
+ last, now = 0, 0
+ for value in range(10001):
+ last, now = now, max(last + value * nums.count(value), now)
+ return now
+```
+
diff --git a/docs/leetcode/python/760._Find_Anagram_Mappings.md b/docs/Leetcode_Solutions/Python/760._Find_Anagram_Mappings.md
similarity index 100%
rename from docs/leetcode/python/760._Find_Anagram_Mappings.md
rename to docs/Leetcode_Solutions/Python/760._Find_Anagram_Mappings.md
diff --git a/docs/Leetcode_Solutions/Python/763._Partition_Labels.md b/docs/Leetcode_Solutions/Python/763._Partition_Labels.md
new file mode 100644
index 000000000..f69a604cf
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/763._Partition_Labels.md
@@ -0,0 +1,76 @@
+# 763. Partition Labels
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/partition-labels/description/
+
+> 内容描述
+
+```
+
+A string S of lowercase letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts.
+
+Example 1:
+Input: S = "ababcbacadefegdehijhklij"
+Output: [9,7,8]
+Explanation:
+The partition is "ababcbaca", "defegde", "hijhklij".
+This is a partition so that each letter appears in at most one part.
+A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits S into less parts.
+Note:
+
+S will have length in range [1, 500].
+S will consist of lowercase letters ('a' to 'z') only.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+从第一个字母开始,只要我们包含了这个字母,那么它在S中出现的最后一次我们也要包含进去,当前出现过的所有的字母,我们每次都要更新最后出现的那一次,
+并且要一直遍历到其最后一次,这样我们可以维护一个当前至少需要遍历到的end,然后只要出现一个新的字母,
+就更新一个这个end(取新字母最后出现idx和end之间的大者),最后,当我们遍历到一个idx的时候,如果这个idx与我们的end相等,
+说明截止当前所有出现的字母都在我们的[start, end]字串当中了,直接append它的长度到res中,一直遍历到最后,返回res
+
+beats 98.39%
+
+```python
+class Solution(object):
+ def partitionLabels(self, S):
+ """
+ :type S: str
+ :rtype: List[int]
+ """
+ if not S or len(S) == 0:
+ return True
+ lookup = {}
+ for i, c in enumerate(S):
+ lookup[c] = i
+ start, end, res = 0, 0, []
+ for i, c in enumerate(S):
+ end = max(end, lookup[c])
+ if i == end:
+ res.append(end-start+1)
+ start = i + 1
+ return res
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/766._Toeplitz_Matrix.md b/docs/Leetcode_Solutions/Python/766._Toeplitz_Matrix.md
new file mode 100644
index 000000000..809616445
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/766._Toeplitz_Matrix.md
@@ -0,0 +1,220 @@
+# 766. Toeplitz Matrix
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/toeplitz-matrix/description/
+
+> 内容描述
+
+```
+A matrix is Toeplitz if every diagonal from top-left to bottom-right has the same element.
+
+Now given an M x N matrix, return True if and only if the matrix is Toeplitz.
+
+
+Example 1:
+
+Input:
+matrix = [
+ [1,2,3,4],
+ [5,1,2,3],
+ [9,5,1,2]
+]
+Output: True
+Explanation:
+In the above grid, the diagonals are:
+"[9]", "[5, 5]", "[1, 1, 1]", "[2, 2, 2]", "[3, 3]", "[4]".
+In each diagonal all elements are the same, so the answer is True.
+Example 2:
+
+Input:
+matrix = [
+ [1,2],
+ [2,2]
+]
+Output: False
+Explanation:
+The diagonal "[1, 2]" has different elements.
+
+Note:
+
+matrix will be a 2D array of integers.
+matrix will have a number of rows and columns in range [1, 20].
+matrix[i][j] will be integers in range [0, 99].
+
+Follow up:
+
+What if the matrix is stored on disk, and the memory is limited such that you can only load at most one row of the matrix into the memory at once?
+What if the matrix is so large that you can only load up a partial row into the memory at once?
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+遍历每个元素,如果它与其右下角元素不相等,那么返回False
+
+beats 100%
+
+```python
+class Solution(object):
+ def isToeplitzMatrix(self, matrix):
+ """
+ :type matrix: List[List[int]]
+ :rtype: bool
+ """
+ if not matrix or len(matrix) == 0:
+ return True
+ row = len(matrix)
+ col = len(matrix[0]) if row else 0
+
+ for i in range(row):
+ for j in range(col):
+ if i + 1 <= row - 1 and j + 1 <= col - 1 and matrix[i][j] != matrix[i+1][j+1]:
+ return False
+ return True
+```
+
+1行版本
+
+```python
+class Solution(object):
+ def isToeplitzMatrix(self, matrix):
+ """
+ :type matrix: List[List[int]]
+ :rtype: bool
+ """
+ return all(r == 0 or c == 0 or matrix[r-1][c-1] == val for r, row in enumerate(matrix) for c, val in enumerate(row))
+```
+
+
+## Follow up 1:
+
+```
+What if the matrix is stored on disk, and the memory is limited such that you can only load at most one row of the matrix into the memory at once?
+```
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+一行一行取呗,简单
+
+```python
+class Solution(object):
+ def isToeplitzMatrix(self, matrix):
+ """
+ :type matrix: List[List[int]]
+ :rtype: bool
+ """
+ if len(matrix) <= 1 or len(matrix[0]) <= 1:
+ return True
+
+ row, col, queue = len(matrix), len(matrix[0]), []
+
+ for i in range(col):
+ queue.append(matrix[0][i])
+
+ for i in range(1, row):
+ queue.pop()
+ for j in range(1, col):
+ if matrix[i][j] == queue[j-1]:
+ continue
+ else:
+ return False
+ queue.insert(0, matrix[i][0])
+
+ return True
+```
+
+
+## Follow up 2:
+
+```
+What if the matrix is so large that you can only load up a partial row into the memory at once?
+```
+
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+
+每次只取一行的一部分, 参考[leavedelta](https://leetcode.com/problems/toeplitz-matrix/discuss/147808/Java-Answers-to-the-follow-ups-(load-partial-rowcolumn-one-time)-the-3rd-one-beats-98)的解法
+
+```python
+class Solution(object):
+ def isToeplitzMatrix(self, matrix):
+ """
+ :type matrix: List[List[int]]
+ :rtype: bool
+ """
+ row = len(matrix)
+ col = len(matrix[0]) if row else 0
+ step = 3 # This step indicates the maximum length of 'piece' which can be loaded at one time.
+ size, idx = 1, col - 1
+
+ while idx >= 0:
+ size = min(idx+1, step)
+ memory = [0] *size
+ for i in range(size):
+ memory[size-1-i] = matrix[0][idx-i] # set memory
+ for j in range(1, min(row, col)): # check the related pieces of rows
+ right_bound = min(idx+j, col-1)
+ left_bound = max(idx-step+1+j, j)
+ m, n = 0, left_bound
+ while m < size and n <= right_bound:
+ if matrix[j][n] != memory[m]:
+ print(1)
+ return False
+ m += 1
+ n += 1
+ idx -= step
+
+ idx = 0
+ while idx < row: # for the purpose of completeness, the criteria should include two sides of the matrix
+ size = min(row-1-idx, step)
+ memory = [0] *size
+ for i in range(size):
+ memory[size-1-i] = matrix[row-idx-1-i][0] # set memory
+ for j in range(1, min(row, col)): # check the related pieces of rows
+ upper_bound = max(row-idx-step+j, j+1)
+ lower_bound = min(row-idx-1+j, row-1)
+ m, n = 0, upper_bound
+ while m < size and n <= lower_bound:
+ if matrix[n][j] != memory[m]:
+ print(2)
+ return False
+ m += 1
+ n += 1
+ idx += step
+
+ return True
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/767._Reorganize_String.md b/docs/Leetcode_Solutions/Python/767._Reorganize_String.md
new file mode 100644
index 000000000..90929c768
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/767._Reorganize_String.md
@@ -0,0 +1,96 @@
+# 767. Reorganize String
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/reorganize-string/description/
+
+> 内容描述
+
+```
+Given a string S, check if the letters can be rearranged so that two characters that are adjacent to each other are not the same.
+
+If possible, output any possible result. If not possible, return the empty string.
+
+Example 1:
+
+Input: S = "aab"
+Output: "aba"
+Example 2:
+
+Input: S = "aaab"
+Output: ""
+Note:
+
+S will consist of lowercase letters and have length in range [1, 500].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+
+先按照出现频率排序,然后频率越大的字母越往后面放,加入某个字母出现频率大于len(S)+1,一定不能满足条件,直接返回''
+
+最后采用插空法,先把前半段固定,后半段插空即可
+
+beats 100%
+
+```python
+class Solution(object):
+ def reorganizeString(self, S):
+ """
+ :type S: str
+ :rtype: str
+ """
+ lookup = {}
+ reorg_S, res = [], [0] * len(S)
+ for c in S:
+ lookup[c] = lookup.get(c, 0) + 1
+ if lookup[c] > (len(S) + 1) / 2:
+ return ''
+ chars = sorted([key for key in lookup.keys()], key = lambda x: lookup[x])
+ for key in chars:
+ reorg_S.extend([key] * lookup[key])
+ res[::2], res[1::2] = reorg_S[len(S)/2:], reorg_S[:len(S)/2]
+ return ''.join(res)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/leetcode/python/774._Minimize_Max_Distance_to_Gas_Station.md b/docs/Leetcode_Solutions/Python/774._Minimize_Max_Distance_to_Gas_Station.md
similarity index 99%
rename from docs/leetcode/python/774._Minimize_Max_Distance_to_Gas_Station.md
rename to docs/Leetcode_Solutions/Python/774._Minimize_Max_Distance_to_Gas_Station.md
index 6dc7c9af6..e9c4c06b6 100644
--- a/docs/leetcode/python/774._Minimize_Max_Distance_to_Gas_Station.md
+++ b/docs/Leetcode_Solutions/Python/774._Minimize_Max_Distance_to_Gas_Station.md
@@ -5,7 +5,7 @@
> 原题连接
-* https://leetcode.com/problems/minimize-max-distance-to-gas-station
+* https://leetcode.com/problems/minimize-max-distance-to-gas-station/description/
> 内容描述
diff --git a/docs/Leetcode_Solutions/Python/777. Swap_Adjacent_in_LR_String.md b/docs/Leetcode_Solutions/Python/777. Swap_Adjacent_in_LR_String.md
new file mode 100644
index 000000000..af0a30019
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/777. Swap_Adjacent_in_LR_String.md
@@ -0,0 +1,133 @@
+# 777. Swap Adjacent in LR String 在LR字符串中交换相邻字符
+
+**难度: 中等**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/swap-adjacent-in-lr-string/description/
+* https://leetcode-cn.com/problems/swap-adjacent-in-lr-string/description/
+
+> 内容描述
+
+```
+
+在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。
+
+示例 :
+
+输入: start = "RXXLRXRXL", end = "XRLXXRRLX"
+输出: True
+解释:
+我们可以通过以下几步将start转换成end:
+RXXLRXRXL ->
+XRXLRXRXL ->
+XRLXRXRXL ->
+XRLXXRRXL ->
+XRLXXRRLX
+注意:
+
+1 <= len(start) = len(end) <= 10000。
+start和end中的字符串仅限于'L', 'R'和'X'。
+```
+
+## 解题方案
+
+> 思路 1
+
+这道题就是一道坑比题,为什么我这么说,题目都说了是 **Adjacent**,然后XL换成LX的情况居然包括"XXXXXLXXXX"到"LXXXXXXXXX",
+你说这是 **Adjacent**吗,XL不相邻也可以换,我去nm的,不好意思爆粗口了。
+
+先说一下XL必须相邻的解法吧,不能白费我功夫啊。
+
+动态规划:dp[i]代表以```index i```结尾的字串是否能够被替换成功,首先dp[0]必须等于False吧,所以我们初始化全部设为False,然后把dp[1]也先判断好
+
+那么很显然,对于dp[i]有下面的情况:
+1. dp[i-1] == True
+- 如果start[i] == end[i],那么dp[i] = True
+- 如果start[i] != end[i],那么这里我们不做操作,因为初始化就是False
+
+2. dp[i-1] == False
+- 如果start[i] == end[i],那么dp[i] = False
+- 如果start[i] != end[i],那么只有当最后两个字符可以转换且dp[i-2] == True的情况下dp[i]才为True
+
+最后返回dp[-1]
+
+
+```
+class Solution(object):
+ def canTransform(self, start, end):
+ """
+ :type start: str
+ :type end: str
+ :rtype: bool
+ """
+ if not start or len(start) == 0:
+ return True
+ if len(start) == 1:
+ return False
+
+ dp = [False for i in range(len(start))]
+ if start[:2] == 'XL' and end[:2] == 'LX' or start[:2] == 'RX' and end[:2] == 'XR' or start[:2] == end[:2]:
+ dp[1] = True
+ for i in range(2, len(dp)):
+ if dp[i-1]:
+ if start[i] == end[i]:
+ dp[i] = True
+ else:
+ if start[i] == 'L' and start[i-1] == 'X' and end[i] == 'X' and end[i-1] == 'L' and dp[i-2]:
+ dp[i] = True
+ if start[i] == 'X' and start[i-1] == 'R' and end[i] == 'R' and end[i-1] == 'X' and dp[i-2]:
+ dp[i] = True
+ return dp[-1]
+```
+接下来说一下XL可以不相邻的情况吧。
+用```rx``` 和 ```xl```来存储出现了可以替换的可能性,即当start出现X或者R的时候,如果后面又开始出现结尾情况了,
+我们就要pop一下对应的```rx``` 和 ```xl```中的一个
+
+```python
+class Solution(object):
+ def canTransform(self, start, end):
+ """
+ :type start: str
+ :type end: str
+ :rtype: bool
+ """
+ if not start or len(start) == 0 or start == end:
+ return True
+ if len(start) == 1:
+ return False
+
+ xl, rx = [], []
+ for i in range(len(start)):
+ if start[i] == end[i]:
+ continue
+ elif start[i] == 'X' and end[i] == 'L':
+ xl.append('L')
+ elif start[i] == 'L' and end[i] == 'X':
+ if not xl:
+ return False
+ xl.pop()
+ elif start[i] == 'R' and end[i] == 'X':
+ rx.append('R')
+ elif start[i] == 'X' and end[i] == 'R':
+ if not rx:
+ return False
+ rx.pop()
+ else:
+ return False
+ return not rx and not xl
+```
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/785._Is_Graph_Bipartite?.md b/docs/Leetcode_Solutions/Python/785._Is_Graph_Bipartite?.md
new file mode 100644
index 000000000..de272829e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/785._Is_Graph_Bipartite?.md
@@ -0,0 +1,85 @@
+# 785. Is Graph Bipartite?
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/is-graph-bipartite/description/
+
+> 内容描述
+
+```
+
+Given an undirected graph, return true if and only if it is bipartite.
+
+Recall that a graph is bipartite if we can split it's set of nodes into two independent subsets A and B such that every edge in the graph has one node in A and another node in B.
+
+The graph is given in the following form: graph[i] is a list of indexes j for which the edge between nodes i and j exists. Each node is an integer between 0 and graph.length - 1. There are no self edges or parallel edges: graph[i] does not contain i, and it doesn't contain any element twice.
+
+Example 1:
+Input: [[1,3], [0,2], [1,3], [0,2]]
+Output: true
+Explanation:
+The graph looks like this:
+0----1
+| |
+| |
+3----2
+We can divide the vertices into two groups: {0, 2} and {1, 3}.
+Example 2:
+Input: [[1,2,3], [0,2], [0,1,3], [0,2]]
+Output: false
+Explanation:
+The graph looks like this:
+0----1
+| \ |
+| \ |
+3----2
+We cannot find a way to divide the set of nodes into two independent subsets.
+
+
+Note:
+
+graph will have length in range [1, 100].
+graph[i] will contain integers in range [0, graph.length - 1].
+graph[i] will not contain i or duplicate values.
+The graph is undirected: if any element j is in graph[i], then i will be in graph[j].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(V+E)******- 空间复杂度: O(V)******
+
+对于二分图中任意一点来说,它的neighbor都必定在另外一个集合,否则就不是二分图
+
+BFS的思想
+
+beats 100%
+
+```python
+class Solution:
+ def isBipartite(self, graph):
+ """
+ :type graph: List[List[int]]
+ :rtype: bool
+ """
+ visited = set()
+ for i in range(len(graph)):
+ if i in visited or not graph[i]:
+ continue
+ cur_level = set([i])
+ while cur_level:
+ nxt_level = set()
+ for j in cur_level:
+ visited.add(j)
+ for n in graph[j]:
+ if n in cur_level:
+ return False
+ if n not in visited:
+ nxt_level.add(n)
+ cur_level = nxt_level
+ return True
+```
diff --git a/docs/Leetcode_Solutions/Python/792._Number_of_Matching_Subsequences.md b/docs/Leetcode_Solutions/Python/792._Number_of_Matching_Subsequences.md
new file mode 100644
index 000000000..334ddf5af
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/792._Number_of_Matching_Subsequences.md
@@ -0,0 +1,206 @@
+# 792. Number of Matching Subsequences
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/number-of-matching-subsequences/description/
+
+> 内容描述
+
+```
+Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S.
+
+Example :
+Input:
+S = "abcde"
+words = ["a", "bb", "acd", "ace"]
+Output: 3
+Explanation: There are three words in words that are a subsequence of S: "a", "acd", "ace".
+Note:
+
+All words in words and S will only consists of lowercase letters.
+The length of S will be in the range of [1, 50000].
+The length of words will be in the range of [1, 5000].
+The length of words[i] will be in the range of [1, 50].
+```
+
+## 解题方案
+
+假设words里面最长的word长度为m,words的长度为n,S的长度为s
+
+> 思路 1
+******- 时间复杂度: O(m*n*s)******- 空间复杂度: O(1)******
+
+暴力,超时
+```
+class Solution(object):
+ def numMatchingSubseq(self, S, words):
+ """
+ :type S: str
+ :type words: List[str]
+ :rtype: int
+ """
+ def match(word, S):
+ i, j = 0, 0
+ while i < len(word) and j < len(S):
+ if word[i] == S[j]:
+ i += 1
+ j += 1
+ else:
+ j += 1
+ return i == len(word)
+
+ res = 0
+ for word in words:
+ if match(word, S):
+ res += 1
+ return res
+```
+
+我觉得是不是多加一个判断,如果一个字符在S里面没有立马返回False这样会快一点,但是还是超时
+
+```
+class Solution(object):
+ def numMatchingSubseq(self, S, words):
+ """
+ :type S: str
+ :type words: List[str]
+ :rtype: int
+ """
+ def match(word, S):
+ i = 0
+ while S and i < len(word):
+ idx = S.find(word[i])
+ if idx == -1:
+ return False
+ S = S[idx+1:]
+ i += 1
+ return i == len(word)
+
+ res = 0
+ for word in words:
+ if match(word, S):
+ res += 1
+ return res
+```
+
+
+于是又觉得用自带的iter函数会不会快一点,结果还是超时
+
+
+```
+class Solution(object):
+ def numMatchingSubseq(self, S, words):
+ """
+ :type S: str
+ :type words: List[str]
+ :rtype: int
+ """
+ def match(word, S):
+ it = iter(S)
+ if all(c in it for c in word):
+ return True
+ return False
+
+ res = 0
+ for word in words:
+ if match(word, S):
+ res += 1
+ return res
+```
+
+
+> 思路 2
+******- 时间复杂度: O(m*n*s)******- 空间复杂度: O(N)******
+
+终于,我想到了用memorization,AC了,beats 70.4%
+
+```python
+class Solution(object):
+ def numMatchingSubseq(self, S, words):
+ """
+ :type S: str
+ :type words: List[str]
+ :rtype: int
+ """
+ def match(word, S):
+ it = iter(S)
+ if all(c in it for c in word):
+ return True
+ return False
+
+ res = 0
+ matched, unmatched = set(), set()
+ for word in words:
+ if word in matched:
+ res += 1
+ continue
+ elif word in unmatched:
+ continue
+ else:
+ if match(word, S):
+ res += 1
+ matched.add(word)
+ else:
+ unmatched.add(word)
+ return res
+```
+
+
+然后换了之前我觉得写的最好最快的match函数,beats 100%
+
+```python
+class Solution(object):
+ def numMatchingSubseq(self, S, words):
+ """
+ :type S: str
+ :type words: List[str]
+ :rtype: int
+ """
+ def match(sub, s):
+ idx = 0
+ for c in sub:
+ idx = s.find(c, idx) + 1
+ if idx == 0:
+ return False
+ return True
+
+ res = 0
+ matched, unmatched = set(), set()
+ for word in words:
+ if word in matched:
+ res += 1
+ continue
+ elif word in unmatched:
+ continue
+ else:
+ if match(word, S):
+ res += 1
+ matched.add(word)
+ else:
+ unmatched.add(word)
+ return res
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/796._Rotate_String.md b/docs/Leetcode_Solutions/Python/796._Rotate_String.md
new file mode 100644
index 000000000..1e08139be
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/796._Rotate_String.md
@@ -0,0 +1,46 @@
+# 796. Rotate String
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/rotate-string/description/
+
+> 内容描述
+
+```
+We are given two strings, A and B.
+
+A shift on A consists of taking string A and moving the leftmost character to the rightmost position. For example, if A = 'abcde', then it will be 'bcdea' after one shift on A. Return True if and only if A can become B after some number of shifts on A.
+
+Example 1:
+Input: A = 'abcde', B = 'cdeab'
+Output: true
+
+Example 2:
+Input: A = 'abcde', B = 'abced'
+Output: false
+Note:
+
+A and B will have length at most 100.
+```
+
+## 解题方案
+
+> 思路 1
+
+
+一行就够了,太简单了
+
+```python
+class Solution(object):
+ def rotateString(self, A, B):
+ """
+ :type A: str
+ :type B: str
+ :rtype: bool
+ """
+ return len(A) == len(B) and B in A * 2
+```
diff --git a/docs/Leetcode_Solutions/Python/800._Similar_RGB_Color.md b/docs/Leetcode_Solutions/Python/800._Similar_RGB_Color.md
new file mode 100644
index 000000000..f56c14544
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/800._Similar_RGB_Color.md
@@ -0,0 +1,109 @@
+# 800. Similar RGB Color
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/similar-rgb-color/description/
+
+> 内容描述
+
+```
+
+In the following, every capital letter represents some hexadecimal digit from 0 to f.
+
+The red-green-blue color "#AABBCC" can be written as "#ABC" in shorthand. For example, "#15c" is shorthand for the color "#1155cc".
+
+Now, say the similarity between two colors "#ABCDEF" and "#UVWXYZ" is -(AB - UV)^2 - (CD - WX)^2 - (EF - YZ)^2.
+
+Given the color "#ABCDEF", return a 7 character color that is most similar to #ABCDEF, and has a shorthand (that is, it can be represented as some "#XYZ"
+
+Example 1:
+Input: color = "#09f166"
+Output: "#11ee66"
+Explanation:
+The similarity is -(0x09 - 0x11)^2 -(0xf1 - 0xee)^2 - (0x66 - 0x66)^2 = -64 -9 -0 = -73.
+This is the highest among any shorthand color.
+Note:
+
+color is a string of length 7.
+color is a valid RGB color: for i > 0, color[i] is a hexadecimal digit from 0 to f
+Any answer which has the same (highest) similarity as the best answer will be accepted.
+All inputs and outputs should use lowercase letters, and the output is 7 characters.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+
+暴力,我也是醉了,一道easy题居然被我写超时了。。。。。
+
+
+
+```
+class Solution(object):
+ def similarRGB(self, color):
+ """
+ :type color: str
+ :rtype: str
+ """
+ def getSimilarity(color1, color2):
+ res = 0
+ for i in range(1, 6, 2):
+ res -= pow(int(color1[i:i+2], 16)-int(color2[i:i+2], 16), 2)
+ return res
+ res, max_num = '', -sys.maxsize
+ for i in range(16):
+ for j in range(16):
+ for k in range(16):
+ new_color = '#' + ''.join(map(lambda x: hex(x)[2:] * 2, [i, j, k]))
+ if getSimilarity(color, new_color) > max_num:
+ max_num = getSimilarity(color, new_color)
+ res = new_color
+ return res
+```
+
+
+> 思路 2
+******- 时间复杂度: O(1)******- 空间复杂度: O(1)******
+
+瞬间觉得是不是要位运算,发现不用位运算也可以
+
+分成R,G,B三部分,每部分都取最小肯定最小
+
+beats 79.55%
+
+```python
+class Solution(object):
+ def similarRGB(self, color):
+ """
+ :type color: str
+ :rtype: str
+ """
+ def getClosest(s):
+ return min(['00', '11', '22', '33', '44', '55', '66', '77', '88', '99', 'aa', 'bb', 'cc', 'dd', 'ee', 'ff'],
+ key=lambda x: abs(int(s, 16) - int(x, 16)))
+
+ res = [getClosest(color[i:i+2]) for i in range(1, len(color), 2)]
+ return '#' + ''.join(res)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/801._Minimum_Swaps_To_Make_Sequences_Increasing.md b/docs/Leetcode_Solutions/Python/801._Minimum_Swaps_To_Make_Sequences_Increasing.md
new file mode 100644
index 000000000..df94d1a4d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/801._Minimum_Swaps_To_Make_Sequences_Increasing.md
@@ -0,0 +1,67 @@
+# 801. Minimum Swaps To Make Sequences Increasing
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-swaps-to-make-sequences-increasing/description/
+
+> 内容描述
+
+```
+
+We have two integer sequences A and B of the same non-zero length.
+
+We are allowed to swap elements A[i] and B[i]. Note that both elements are in the same index position in their respective sequences.
+
+At the end of some number of swaps, A and B are both strictly increasing. (A sequence is strictly increasing if and only if A[0] < A[1] < A[2] < ... < A[A.length - 1].)
+
+Given A and B, return the minimum number of swaps to make both sequences strictly increasing. It is guaranteed that the given input always makes it possible.
+
+Example:
+Input: A = [1,3,5,4], B = [1,2,3,7]
+Output: 1
+Explanation:
+Swap A[3] and B[3]. Then the sequences are:
+A = [1, 3, 5, 7] and B = [1, 2, 3, 4]
+which are both strictly increasing.
+Note:
+
+A, B are arrays with the same length, and that length will be in the range [1, 1000].
+A[i], B[i] are integer values in the range [0, 2000].
+```
+
+## 解题方案
+
+> 思路 1
+
+
+参考大神[Luckypants](https://leetcode.com/problems/minimum-swaps-to-make-sequences-increasing/discuss/119830/Python-14-line-O(1)-space-O(n)-time-DP-solution)的思路
+
+
+- dp[i][0] means the least swaps used to make A[:i+1] and B[:i+1] sorted having no swap at i-th position.
+- dp[i][1] means the least swaps used to make A[:i+1] and B[:i+1] sorted having swap at i-th position.
+
+```python
+class Solution(object):
+ def minSwap(self, A, B):
+ """
+ :type A: List[int]
+ :type B: List[int]
+ :rtype: int
+ """
+ n = len(A)
+ pre = [0, 1]
+ for i in range(1, n):
+ cur = [sys.maxsize, sys.maxsize]
+ if A[i]>A[i-1] and B[i]>B[i-1]:
+ cur[0] = min(cur[0], pre[0])
+ cur[1] = min(cur[1], pre[1]+1)
+ if A[i]>B[i-1] and B[i]>A[i-1]:
+ cur[0] = min(cur[0], pre[1])
+ cur[1] = min(cur[1], pre[0]+1)
+ pre = cur
+ return min(pre)
+```
diff --git a/docs/Leetcode_Solutions/Python/815._Bus_Routes.md b/docs/Leetcode_Solutions/Python/815._Bus_Routes.md
new file mode 100644
index 000000000..dc741cf66
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/815._Bus_Routes.md
@@ -0,0 +1,77 @@
+# 815. Bus Routes
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/bus-routes/description/
+
+> 内容描述
+
+```
+
+We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. For example if routes[0] = [1, 5, 7], this means that the first bus (0-th indexed) travels in the sequence 1->5->7->1->5->7->1->... forever.
+
+We start at bus stop S (initially not on a bus), and we want to go to bus stop T. Travelling by buses only, what is the least number of buses we must take to reach our destination? Return -1 if it is not possible.
+
+Example:
+Input:
+routes = [[1, 2, 7], [3, 6, 7]]
+S = 1
+T = 6
+Output: 2
+Explanation:
+The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6.
+Note:
+
+1 <= routes.length <= 500.
+1 <= routes[i].length <= 500.
+0 <= routes[i][j] < 10 ^ 6.
+````
+
+## 解题方案
+
+
+
+其实还有第三种解法,就是看stop能到哪些stop,但是也是TLE
+> 思路 1
+******- 时间复杂度: O(VE)******- 空间复杂度: O(VE)******
+
+这里用了截图中的第一种思路
+
+看作是一个图的话,V是bus,E是bus所在的routes,那么时间和空间复杂度都是O(VE)
+
+beats 90.45%
+
+```python
+class Solution(object):
+ def numBusesToDestination(self, routes, S, T):
+ """
+ :type routes: List[List[int]]
+ :type S: int
+ :type T: int
+ :rtype: int
+ """
+ bus_in_routes, cur_buses, step, visited = collections.defaultdict(set), [S], 0, set()
+ for i, route in enumerate(routes):
+ for bus in route:
+ bus_in_routes[bus].add(i) # this bus is in route i
+ while cur_buses:
+ new_buses = []
+ for bus in cur_buses:
+ if bus == T:
+ return step
+
+ for route_idx in bus_in_routes[bus]:
+ if route_idx not in visited:
+ visited.add(route_idx)
+ for new_bus in routes[route_idx]:
+ if new_bus != bus:
+ new_buses.append(new_bus)
+ routes[route_idx] = [] # this line is optional, more efficient if added
+ cur_buses = new_buses
+ step += 1
+ return -1
+```
diff --git a/docs/Leetcode_Solutions/Python/819._Most_Common_Word.md b/docs/Leetcode_Solutions/Python/819._Most_Common_Word.md
new file mode 100644
index 000000000..ab1895bf3
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/819._Most_Common_Word.md
@@ -0,0 +1,93 @@
+# 819. Most Common Word
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/most-common-word/description/
+
+> 内容描述
+
+```
+Given a paragraph and a list of banned words, return the most frequent word that is not in the list of banned words. It is guaranteed there is at least one word that isn't banned, and that the answer is unique.
+
+Words in the list of banned words are given in lowercase, and free of punctuation. Words in the paragraph are not case sensitive. The answer is in lowercase.
+
+Example:
+Input:
+paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."
+banned = ["hit"]
+Output: "ball"
+Explanation:
+"hit" occurs 3 times, but it is a banned word.
+"ball" occurs twice (and no other word does), so it is the most frequent non-banned word in the paragraph.
+Note that words in the paragraph are not case sensitive,
+that punctuation is ignored (even if adjacent to words, such as "ball,"),
+and that "hit" isn't the answer even though it occurs more because it is banned.
+
+
+Note:
+
+1 <= paragraph.length <= 1000.
+1 <= banned.length <= 100.
+1 <= banned[i].length <= 10.
+The answer is unique, and written in lowercase (even if its occurrences in paragraph may have uppercase symbols, and even if it is a proper noun.)
+paragraph only consists of letters, spaces, or the punctuation symbols !?',;.
+Different words in paragraph are always separated by a space.
+There are no hyphens or hyphenated words.
+Words only consist of letters, never apostrophes or other punctuation symbols.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(P)******
+
+
+
+
+最需要注意的一个点就是,当input为下面的情况的时候,我们其实要将逗号也给分割开来
+
+```
+Input:
+"a, a, a, a, b,b,b,c, c"
+["a"]
+
+Expected:
+"b"
+```
+
+```b,b,b,c```其实是```b b b c```
+
+
+思路就是先按照空格split,然后每个word再按照逗号split,最后strip掉每个word中所有的``` !?';.```等字符,还要注意全部换成小写
+
+最后要注意就是我们以逗号split的时候可能会带入空word,后面要进行一下判断
+
+因为paragraph中的每一个字符我们都要处理一次,时间复杂度就是O(N)
+
+假设paragraph中有P个word,空间复杂度为O(P)
+
+```python
+class Solution(object):
+ def mostCommonWord(self, paragraph, banned):
+ """
+ :type paragraph: str
+ :type banned: List[str]
+ :rtype: str
+ """
+ banned = set(banned)
+ words = [w.strip("!?';.") for word in paragraph.lower().split(' ') for w in word.split(',')]
+
+ lookup = {}
+ for word in words:
+ if word and word not in banned: # 需要保证word不为空
+ lookup[word] = lookup.get(word, 0) + 1
+
+ max_freq = max(lookup.values())
+ for key in lookup:
+ if lookup[key] == max_freq:
+ return key
+```
diff --git a/docs/Leetcode_Solutions/Python/824._Goat_Latin.md b/docs/Leetcode_Solutions/Python/824._Goat_Latin.md
new file mode 100644
index 000000000..6d1ca175e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/824._Goat_Latin.md
@@ -0,0 +1,72 @@
+# 824. Goat Latin
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/goat-latin/description/
+
+> 内容描述
+
+```
+A sentence S is given, composed of words separated by spaces. Each word consists of lowercase and uppercase letters only.
+
+We would like to convert the sentence to "Goat Latin" (a made-up language similar to Pig Latin.)
+
+The rules of Goat Latin are as follows:
+
+If a word begins with a vowel (a, e, i, o, or u), append "ma" to the end of the word.
+For example, the word 'apple' becomes 'applema'.
+
+If a word begins with a consonant (i.e. not a vowel), remove the first letter and append it to the end, then add "ma".
+For example, the word "goat" becomes "oatgma".
+
+Add one letter 'a' to the end of each word per its word index in the sentence, starting with 1.
+For example, the first word gets "a" added to the end, the second word gets "aa" added to the end and so on.
+Return the final sentence representing the conversion from S to Goat Latin.
+
+
+
+Example 1:
+
+Input: "I speak Goat Latin"
+Output: "Imaa peaksmaaa oatGmaaaa atinLmaaaaa"
+Example 2:
+
+Input: "The quick brown fox jumped over the lazy dog"
+Output: "heTmaa uickqmaaa rownbmaaaa oxfmaaaaa umpedjmaaaaaa overmaaaaaaa hetmaaaaaaaa azylmaaaaaaaaa ogdmaaaaaaaaaa"
+
+
+Notes:
+
+S contains only uppercase, lowercase and spaces. Exactly one space between each word.
+1 <= S.length <= 150.
+```
+
+## 解题方案
+
+> 思路 1
+
+
+sb题没什么好说的
+
+```python
+class Solution(object):
+ def toGoatLatin(self, S):
+ """
+ :type S: str
+ :rtype: str
+ """
+ res = ''
+ for index, word in enumerate(S.split()):
+ if(word[0] in 'aeiouAEIOU'):
+ word = word + 'ma'
+ else:
+ tmp = word[0]
+ word = word[1:] + tmp + 'ma'
+ word = word + 'a' * (index + 1)
+ res = res + ' ' + word
+ return res[1:]
+```
diff --git a/docs/Leetcode_Solutions/Python/844._Backspace_String_Compare.md b/docs/Leetcode_Solutions/Python/844._Backspace_String_Compare.md
new file mode 100644
index 000000000..d62ebc325
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/844._Backspace_String_Compare.md
@@ -0,0 +1,171 @@
+# 844. Backspace String Compare
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/backspace-string-compare/description/
+
+> 内容描述
+
+```
+Given two strings S and T, return if they are equal when both are typed into empty text editors. # means a backspace character.
+
+Example 1:
+
+Input: S = "ab#c", T = "ad#c"
+Output: true
+Explanation: Both S and T become "ac".
+Example 2:
+
+Input: S = "ab##", T = "c#d#"
+Output: true
+Explanation: Both S and T become "".
+Example 3:
+
+Input: S = "a##c", T = "#a#c"
+Output: true
+Explanation: Both S and T become "c".
+Example 4:
+
+Input: S = "a#c", T = "b"
+Output: false
+Explanation: S becomes "c" while T becomes "b".
+Note:
+
+1 <= S.length <= 200
+1 <= T.length <= 200
+S and T only contain lowercase letters and '#' characters.
+Follow up:
+
+Can you solve it in O(N) time and O(1) space?
+```
+
+## 解题方案
+
+> 思路 1
+
+就看一下两个字符串变化完之后是不是相等就行了,
+
+- 时间复杂度:O(n)
+- 空间复杂度:O(n)
+
+
+```python
+class Solution(object):
+ def backspaceCompare(self, S, T):
+ """
+ :type S: str
+ :type T: str
+ :rtype: bool
+ """
+ def afterChange(s):
+ res = ''
+ for i in s:
+ if i == '#':
+ res = '' if len(res) == 0 else res[:-1]
+ else:
+ res += i
+ return res
+ return afterChange(S) == afterChange(T)
+```
+
+> 思路 2
+
+deque
+
+- 时间复杂度:O(n)
+- 空间复杂度:O(n)
+
+```python
+class Solution:
+ def backspaceCompare(self, S, T):
+ """
+ :type S: str
+ :type T: str
+ :rtype: bool
+ """
+ q1 = collections.deque()
+ q2 = collections.deque()
+ for i in S:
+ if i != "#":
+ q1.append(i)
+ elif q1:
+ q1.pop()
+ else:
+ continue
+ for i in T:
+ if i != "#":
+ q2.append(i)
+ elif q2:
+ q2.pop()
+ else:
+ continue
+
+ return q1==q2
+```
+## Follow up
+
+Can you solve it in O(N) time and O(1) space?
+
+> 思路 2
+
+
+参考[angelina_not_jolie](https://leetcode.com/problems/backspace-string-compare/discuss/165435/Python-O(1)-space-solution-for-the-follow-up-beats-100-using-two-pointers)
+```
+The idea is we first need to find the first char in each string that was not deleted and compare equality.
+Corner case is that the number of '#' is larger than the number of chars in front, e.g. "ab#######c" ---> "c"
+So in my codes, the outter loop condition is as long as we haven't gone through both strings, we need to keep going. e.g. "ab#########c" vs. "a#c"
+The inner loops are to find the next char after deleting.
+
+There are only two cases we need to return False:
+1. Both pointers are at a char and these two chars are different.
+One pointer is pointing to a char but the other string has been deleted till index 0. i.e.
+2. compare a char to an empty string
+
+```
+- 时间复杂度:O(n)
+- 空间复杂度:O(1)
+
+```python
+class Solution(object):
+ def backspaceCompare(self, S, T):
+ """
+ :type S: str
+ :type T: str
+ :rtype: bool
+ """
+ i, poundS = len(S) - 1, 0; j, poundT = len(T) - 1, 0
+ while i >= 0 or j >= 0:
+ while i >= 0:
+ if S[i] == "#":
+ poundS += 1
+ elif poundS:
+ poundS -= 1
+ else: #found the first undeleted char
+ break
+ i -= 1
+
+ while j >= 0:
+ if T[j] == '#':
+ poundT += 1
+ elif poundT:
+ poundT -= 1
+ else:
+ break
+ j -= 1
+
+ #either both side are chars then we need to compare
+ if i >= 0 and j >= 0 and S[i] != T[j]:
+ return False
+ #compare a char with empty(have more # than actually char, we delete everything before #)
+ if (i >= 0) != (j >=0):
+ return False
+
+ i -= 1
+ j -= 1
+
+ return i == j
+```
diff --git a/docs/Leetcode_Solutions/Python/865._Smallest_Subtree_with_all_the_Deepest_Nodes.md b/docs/Leetcode_Solutions/Python/865._Smallest_Subtree_with_all_the_Deepest_Nodes.md
new file mode 100644
index 000000000..2c7b53625
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/865._Smallest_Subtree_with_all_the_Deepest_Nodes.md
@@ -0,0 +1,331 @@
+# 865. Smallest Subtree with all the Deepest Nodes
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/description/
+
+> 内容描述
+
+```
+Given a binary tree rooted at root, the depth of each node is the shortest distance to the root.
+
+A node is deepest if it has the largest depth possible among any node in the entire tree.
+
+The subtree of a node is that node, plus the set of all descendants of that node.
+
+Return the node with the largest depth such that it contains all the deepest nodes in its subtree.
+
+
+
+Example 1:
+
+Input: [3,5,1,6,2,0,8,null,null,7,4]
+Output: [2,7,4]
+Explanation:
+```
+
+
+
+```
+We return the node with value 2, colored in yellow in the diagram.
+The nodes colored in blue are the deepest nodes of the tree.
+The input "[3, 5, 1, 6, 2, 0, 8, null, null, 7, 4]" is a serialization of the given tree.
+The output "[2, 7, 4]" is a serialization of the subtree rooted at the node with value 2.
+Both the input and output have TreeNode type.
+
+Note:
+
+The number of nodes in the tree will be between 1 and 500.
+The values of each node are unique.
+```
+
+## 解题方案
+
+> 思路 1
+
+直接参考的[leetcode solution](https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/solution/)
+- 首先将所有的node与其对应的depth记录下来
+- 然后,从root开始往下走,如果一个node的depth是最大的depth的话,就直接返回这个node,递归进行
+- 如果这个node的depth不是最大的depth,但是它的左孩子和右孩子的depth都最大的话也是直接返回这个node,递归进行
+
+```python
+class Solution(object):
+ def subtreeWithAllDeepest(self, root):
+ """
+ :type root: TreeNode
+ :rtype: TreeNode
+ """
+ depth = {
+ None: -1
+ }
+ def dfs(node, parent = None):
+ if node:
+ depth[node] = depth[parent] + 1
+ dfs(node.left, node)
+ dfs(node.right, node)
+
+ dfs(root)
+ max_depth = max(depth.values())
+
+ def decide(node):
+ if not node or depth[node] == max_depth:
+ return node
+ l, r = decide(node.left), decide(node.right)
+ return node if l and r else l or r
+ return decide(root)
+```
+
+> 思路 2
+
+The Result (on some subtree) returned by our (depth-first search) recursion will have two parts:
+- Result.node: the largest depth node that is equal to or an ancestor of all the deepest nodes of this subtree.
+- Result.depth: the number of nodes in the path from the root of this subtree, to the deepest node in this subtree.
+
+We can calculate these answers disjointly for dfs(node):
+
+To calculate the Result.node of our answer:
+
+- If one childResult has deeper nodes, then childResult.node will be the answer.
+
+- If they both have the same depth nodes, then node will be the answer.
+
+- The Result.depth of our answer is always 1 more than the largest childResult.depth we have.
+
+```python
+class Solution(object):
+ def subtreeWithAllDeepest(self, root):
+ """
+ :type root: TreeNode
+ :rtype: TreeNode
+ """
+ Result = collections.namedtuple('Result', ('node', 'depth'))
+ def dfs(node):
+ if not node:
+ return Result(None, 0)
+ l, r = dfs(node.left), dfs(node.right)
+ if l.depth > r.depth:
+ return Result(l.node, l.depth+1)
+ elif l.depth < r.depth:
+ return Result(r.node, r.depth+1)
+ else:
+ return Result(node, l.depth+1)
+ return dfs(root).node
+```
+
+> 思路 3
+
+自己的解法:
+
+```python
+class Solution(object):
+ def subtreeWithAllDeepest(self, root):
+ """
+ :type root: TreeNode
+ :rtype: TreeNode
+ """
+ def depth(node):
+ return 0 if not node else max(depth(node.left), depth(node.right)) + 1
+
+ tmp = depth(root.left) - depth(root.right)
+ if tmp == 0:
+ return root
+ elif tmp > 0:
+ return self.subtreeWithAllDeepest(root.left)
+ else:
+ return self.subtreeWithAllDeepest(root.right)
+```
+
+
+
+## Follow up
+
+如果每一个树节点可以拥有超过2个孩子怎么办:
+
+> 思路 1
+
+自己的解法,
+- 只要这个节点的孩子中有两个及以上的depth相等就直接返回这个node本身
+- 如果只有一个孩子的depth最大就返回那个孩子
+
+```python
+class TreeNode(object):
+ def __init__(self, x):
+ self.val = x
+ self.children = []
+
+
+class Solution(object):
+ def subtreeWithAllDeepestForMoreChildren(self, root):
+ """
+ :type root: TreeNode
+ :rtype: TreeNode
+ """
+ # calculate a node's depth
+ def depth(node):
+ if not node:
+ return 0
+ tmp = [depth(child) for child in node.children]
+ if not tmp or len(tmp) == 0:
+ return 1
+ return max(tmp) + 1
+
+ if not root:
+ return None
+ tmp = [depth(child) for child in root.children]
+ if not tmp or len(tmp) == 0:
+ return root
+ # if 2 or more children have same depth, then return the node itself
+ if tmp.count(max(tmp)) > 1:
+ return root
+ # else recalculate the child who has largest depth
+ else:
+ return self.subtreeWithAllDeepestForMoreChildren(root.children[tmp.index(max(tmp))])
+```
+
+搞一下测试用例
+
+```python
+import unittest
+
+
+class TestSolution(unittest.TestCase):
+ def test_1(self):
+ root = TreeNode(0)
+
+ for i in range(1, 4):
+ root.children.append(TreeNode(i))
+
+ for i in range(4, 10):
+ root.children[1].children.append(TreeNode(i))
+ self.assertTrue(Solution().subtreeWithAllDeepestForMoreChildren(root).val == 2)
+
+ def test_2(self):
+ root = TreeNode(0)
+ self.assertTrue(Solution().subtreeWithAllDeepestForMoreChildren(root).val == 0)
+
+ def test_3(self):
+ root = TreeNode(0)
+
+ for i in range(1, 4):
+ root.children.append(TreeNode(i))
+
+ for i in range(4, 10):
+ root.children[1].children.append(TreeNode(i))
+
+ for i in range(10, 12):
+ root.children[2].children.append(TreeNode(i))
+ self.assertTrue(Solution().subtreeWithAllDeepestForMoreChildren(root).val == 0)
+
+ def test_4(self):
+ root = TreeNode(0)
+
+ for i in range(1, 3):
+ root.children.append(TreeNode(i))
+
+ for i in range(3, 5):
+ root.children[0].children.append(TreeNode(i))
+
+ for i in range(5, 7):
+ root.children[1].children.append(TreeNode(i))
+
+ for i in range(7, 9):
+ root.children[0].children[1].children.append(TreeNode(i))
+ self.assertTrue(Solution().subtreeWithAllDeepestForMoreChildren(root).val == 4)
+
+ def test_5(self):
+ root = TreeNode(0)
+
+ for i in range(1, 5):
+ root.children.append(TreeNode(i))
+ root.children[1].children.append(TreeNode(5))
+ root.children[2].children.append(TreeNode(6))
+ root.children[3].children.append(TreeNode(7))
+ self.assertTrue(Solution().subtreeWithAllDeepestForMoreChildren(root).val == 0)
+
+
+if __name__ == "__main__":
+ unittest.main()
+
+
+
+.....
+----------------------------------------------------------------------
+Ran 5 tests in 0.000s
+
+OK
+```
+
+
+> 思路 2
+
+
+
+```python
+import collections
+import sys
+
+
+class TreeNode(object):
+ def __init__(self, x):
+ self.val = x
+ self.children = []
+
+
+# Find the tree with largest depth among all nodes
+class Solution(object):
+ def subtreeWithAllDeepestForMoreChildren(self, root):
+ """
+ :type root: TreeNode
+ :rtype: TreeNode
+ """
+ if not root:
+ return None
+ Result = collections.namedtuple("Result", ("node", "depth"))
+
+ # return the Result of the subtree at this node
+ def dfs(node):
+ if not node:
+ return Result(None, 0)
+ if len(node.children) == 0:
+ return Result(node, 1)
+ largest_depth = 0
+ res = Result(None, 0)
+ for child in node.children:
+ cur = dfs(child) # cur is a Result type: store ('node','depth')
+ if cur.depth > abs(largest_depth):
+ largest_depth = cur.depth
+ res = cur
+ elif cur.depth == largest_depth:
+ # negative number means largestDepth occurs more than once
+ largest_depth = -largest_depth
+ if largest_depth > 0:
+ return Result(res.node, largest_depth + 1)
+ return Result(node, -largest_depth + 1)
+
+ return dfs(root).node
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/871._Minimum_Number_of_Refueling_Stops.md b/docs/Leetcode_Solutions/Python/871._Minimum_Number_of_Refueling_Stops.md
new file mode 100644
index 000000000..fe14c4cab
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/871._Minimum_Number_of_Refueling_Stops.md
@@ -0,0 +1,131 @@
+# 871. Minimum Number of Refueling Stops
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-number-of-refueling-stops/description/
+
+> 内容描述
+
+```
+A car travels from a starting position to a destination which is target miles east of the starting position.
+
+Along the way, there are gas stations. Each station[i] represents a gas station that is station[i][0] miles east of the starting position, and has station[i][1] liters of gas.
+
+The car starts with an infinite tank of gas, which initially has startFuel liters of fuel in it. It uses 1 liter of gas per 1 mile that it drives.
+
+When the car reaches a gas station, it may stop and refuel, transferring all the gas from the station into the car.
+
+What is the least number of refueling stops the car must make in order to reach its destination? If it cannot reach the destination, return -1.
+
+Note that if the car reaches a gas station with 0 fuel left, the car can still refuel there. If the car reaches the destination with 0 fuel left, it is still considered to have arrived.
+
+
+
+Example 1:
+
+Input: target = 1, startFuel = 1, stations = []
+Output: 0
+Explanation: We can reach the target without refueling.
+Example 2:
+
+Input: target = 100, startFuel = 1, stations = [[10,100]]
+Output: -1
+Explanation: We can't reach the target (or even the first gas station).
+Example 3:
+
+Input: target = 100, startFuel = 10, stations = [[10,60],[20,30],[30,30],[60,40]]
+Output: 2
+Explanation:
+We start with 10 liters of fuel.
+We drive to position 10, expending 10 liters of fuel. We refuel from 0 liters to 60 liters of gas.
+Then, we drive from position 10 to position 60 (expending 50 liters of fuel),
+and refuel from 10 liters to 50 liters of gas. We then drive to and reach the target.
+We made 2 refueling stops along the way, so we return 2.
+
+
+Note:
+
+1 <= target, startFuel, stations[i][1] <= 10^9
+0 <= stations.length <= 500
+0 < stations[0][0] < stations[1][0] < ... < stations[stations.length-1][0] < target
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+
+看到这道题就想到了前几天做的gas station
+
+这种题我有一种感觉了,就是先将station排序然后遍历一遍,每碰到一个station都会有两种或者三种情况,最终遍历完还要check一些东西结束
+
+
+所以这道题目首先station是已经有序的,并且```0 < stations[0][0] < stations[1][0] < ... < stations[stations.length-1][0] < target```
+
+
+我们定义一个起点名为start_point,当前的燃料cur_fuel,然后最重要的就是贪心思想维护一个station含油量的最大堆,
+每次油不够我们自然而然取堆顶元素补充燃料
+
+对于每一个station:
+
+ 1. 如果当前位置加上当前燃料能够到达当前station,那么:
+ - 燃料更新,减去 station[0] - start_point
+ - 位置更新为 station[0]
+ 2. 如果当前位置加上当前燃料不能到达当前station,那么:
+ - 只要我们不能到达,就一直从堆里去燃料,直到能到达或者堆空了,如果while循环出来发现还是不能达到(即因为堆空退出的循环),立刻返回 -1
+ 3. 一定要记得将当前station的燃料加到堆里面去,以便后面不够的时候取用
+
+现在,我们走完了所有station,但是最后一个station的位置也是小于target的,我们还要看是否能走到target
+
+所以我们首先将当前燃油全部耗尽,如果还是不够就看看堆里面还能不能补充,如果while循环出来发现还是不能达到(即因为堆空退出的循环),立刻返回 -1;
+如果最终达到了target,那么我们返回总的station个数与堆内元素的差值(即我们已经加了油的station个数)。
+
+beats 99.07%
+
+```python
+class Solution(object):
+ def minRefuelStops(self, target, startFuel, stations):
+ """
+ :type target: int
+ :type startFuel: int
+ :type stations: List[List[int]]
+ :rtype: int
+ """
+ from heapq import heappush, heappop
+ not_fueled, start_point, cur_fuel = [], 0, startFuel
+ for station in stations:
+ if start_point + cur_fuel >= station[0]:
+ cur_fuel -= station[0] - start_point
+ start_point = station[0]
+ else:
+ while not_fueled and start_point + cur_fuel < station[0]:
+ cur_fuel += -heappop(not_fueled)
+ if start_point + cur_fuel < station[0]:
+ return -1
+ heappush(not_fueled, -station[1])
+ start_point += cur_fuel
+ while not_fueled and start_point < target:
+ start_point += -heappop(not_fueled)
+ if start_point < target:
+ return -1
+ return len(stations) - len(not_fueled)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/872._Leaf-Similar_Trees.md b/docs/Leetcode_Solutions/Python/872._Leaf-Similar_Trees.md
new file mode 100644
index 000000000..6a676dca3
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/872._Leaf-Similar_Trees.md
@@ -0,0 +1,60 @@
+# 872. Leaf-Similar Trees
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/leaf-similar-trees/description/
+
+> 内容描述
+
+```
+
+Consider all the leaves of a binary tree. From left to right order, the values of those leaves form a leaf value sequence.
+
+
+
+For example, in the given tree above, the leaf value sequence is (6, 7, 4, 9, 8).
+
+Two binary trees are considered leaf-similar if their leaf value sequence is the same.
+
+Return true if and only if the two given trees with head nodes root1 and root2 are leaf-similar.
+
+
+
+Note:
+
+Both of the given trees will have between 1 and 100 nodes.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+先递归找到两颗树的叶子结点集合,再比较是否相等。beats 100%
+
+```python
+class Solution(object):
+ def leafSimilar(self, root1, root2):
+ """
+ :type root1: TreeNode
+ :type root2: TreeNode
+ :rtype: bool
+ """
+ def findleaf(root):
+ if not root:
+ return []
+ if not root.left and not root.right:
+ return [root.val]
+ return findleaf(root.left) + findleaf(root.right)
+
+ return findleaf(root1) == findleaf(root2)
+```
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/873._Length_of_Longest_Fibonacci_Subsequence.md b/docs/Leetcode_Solutions/Python/873._Length_of_Longest_Fibonacci_Subsequence.md
new file mode 100644
index 000000000..ea6f71248
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/873._Length_of_Longest_Fibonacci_Subsequence.md
@@ -0,0 +1,108 @@
+# 873. Length of Longest Fibonacci Subsequence
+
+**难度: Meidum**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/description/
+
+> 内容描述
+
+```
+A sequence X_1, X_2, ..., X_n is fibonacci-like if:
+
+n >= 3
+X_i + X_{i+1} = X_{i+2} for all i + 2 <= n
+Given a strictly increasing array A of positive integers forming a sequence, find the length of the longest fibonacci-like subsequence of A. If one does not exist, return 0.
+
+(Recall that a subsequence is derived from another sequence A by deleting any number of elements (including none) from A, without changing the order of the remaining elements. For example, [3, 5, 8] is a subsequence of [3, 4, 5, 6, 7, 8].)
+
+
+
+Example 1:
+
+Input: [1,2,3,4,5,6,7,8]
+Output: 5
+Explanation:
+The longest subsequence that is fibonacci-like: [1,2,3,5,8].
+Example 2:
+
+Input: [1,3,7,11,12,14,18]
+Output: 3
+Explanation:
+The longest subsequence that is fibonacci-like:
+[1,11,12], [3,11,14] or [7,11,18].
+
+
+Note:
+
+3 <= A.length <= 1000
+1 <= A[0] < A[1] < ... < A[A.length - 1] <= 10^9
+(The time limit has been reduced by 50% for submissions in Java, C, and C++.)
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2*LgN)******- 空间复杂度: O(N)******
+
+思路见[lee215](https://leetcode.com/problems/length-of-longest-fibonacci-subsequence/discuss/152343/C++JavaPython-Check-Pair)
+```
+Save array A to a hash set s.
+Start from base (A[i], A[j]) as the first two element in the sequence,
+we try to find the Fibonacci like subsequence as long as possible,
+
+Initial (a, b) = (A[i], A[j])
+While the set s contains a + b, we update (a, b) = (b, a + b).
+In the end we update the longest length we find.
+
+Time Complexity:
+O(N^2logM), where M is the max(A).
+```
+
+```python
+class Solution(object):
+ def lenLongestFibSubseq(self, A):
+ """
+ :type A: List[int]
+ :rtype: int
+ """
+ s, res = set(A), 0
+ for i in range(len(A)):
+ for j in range(i+1, len(A)):
+ a, b, l = A[i], A[j], 2
+ while a + b in s:
+ a, b, l = b, a + b, l + 1
+ res = max(res, l)
+ return res if res > 2 else 0
+```
+
+
+
+> 思路 2
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+```
+dp[a, b] represents the length of fibo sequence ends up with (a, b)
+Then we have dp[a, b] = dp[b - a, a] or 2
+The complexity reduce to O(N^2).
+```
+
+```python
+class Solution(object):
+ def lenLongestFibSubseq(self, A):
+ """
+ :type A: List[int]
+ :rtype: int
+ """
+ dp = {}
+ s, res = set(A), 0
+ for i in range(len(A)):
+ for j in range(i):
+ if A[i] - A[j] < A[j] and A[i] - A[j] in s:
+ dp[(A[j], A[i])] = dp.get((A[i]-A[j], A[j]), 2) + 1
+ res = max(res, dp[(A[j], A[i])])
+ return res if res > 2 else 0
+```
diff --git a/docs/Leetcode_Solutions/Python/878._Nth_Magical_Number.md b/docs/Leetcode_Solutions/Python/878._Nth_Magical_Number.md
new file mode 100644
index 000000000..4e9d8f319
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/878._Nth_Magical_Number.md
@@ -0,0 +1,140 @@
+# 878. Nth Magical Number
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/nth-magical-number/description/
+
+> 内容描述
+
+```
+A positive integer is magical if it is divisible by either A or B.
+
+Return the N-th magical number. Since the answer may be very large, return it modulo 10^9 + 7.
+
+
+
+Example 1:
+
+Input: N = 1, A = 2, B = 3
+Output: 2
+Example 2:
+
+Input: N = 4, A = 2, B = 3
+Output: 6
+Example 3:
+
+Input: N = 5, A = 2, B = 4
+Output: 10
+Example 4:
+
+Input: N = 3, A = 6, B = 4
+Output: 8
+
+
+Note:
+
+1 <= N <= 10^9
+2 <= A <= 40000
+2 <= B <= 40000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(A+B)******- 空间复杂度: O(1)******
+
+数学题直接看的[solution](https://leetcode.com/problems/nth-magical-number/solution/):
+
+* 从数据范围看来,N高达10^9,直接遍历不现实
+* 注意到魔法数是有循环的,我们令P=A和B的最小公倍数,那么在每P个数中,魔法数的数量和位置都是相同的,因此我们只需要计算[1,p]中间的魔法数
+* [1,p]的魔法数数量是 P/A+P/B-1,注意到,P是A和B的最小公倍数,因此[1,p]中,既能被A整除,也能被B整除,只有一个数,就是P
+* 现在问题变成,在[1,p]中,求第n个魔法数
+
+注意到,我们在[1,p]中任取一个数x(x 思路 2
+******- 时间复杂度: O(log(N*max(A,B)))******- 空间复杂度: O(1)******
+
+
+从另外一个角度来看,如果我们知道了一个数字x,那么我们可以轻易算出有多少个magic number 是小于等于x的,
+即```x // A + x // B - x // L```, 其中```L = lcm(A, B)```, 我们可以通过二分法算出一个最小的数字num,小于等于num的magic number 数量刚好是N,
+然后这个num就是我们要求的 Nth Magical Number
+
+时间复杂度为O(log(N∗max(A,B))), beats 100%
+
+```python
+class Solution(object):
+ def nthMagicalNumber(self, N, A, B):
+ """
+ :type N: int
+ :type A: int
+ :type B: int
+ :rtype: int
+ """
+ def gcd(a, b):
+ if b == 0:
+ return a
+ return gcd(b, a % b)
+
+ def lcm(a, b):
+ return a * b // gcd(a, b)
+
+ MOD = 10**9 + 7
+ L = lcm(A, B)
+
+ def magic_below_x(x):
+ # How many magical numbers are <= x?
+ return x // A + x // B - x // L
+
+ l, r = 0, N * max(A,B)
+ while l <= r:
+ mid = l + ((r-l) >> 1)
+ if magic_below_x(mid) < N:
+ l = mid + 1
+ else:
+ r = mid - 1
+
+ return l % MOD
+```
+
diff --git a/docs/Leetcode_Solutions/Python/890._Find_and_Replace_Pattern.md b/docs/Leetcode_Solutions/Python/890._Find_and_Replace_Pattern.md
new file mode 100644
index 000000000..edefe3380
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/890._Find_and_Replace_Pattern.md
@@ -0,0 +1,83 @@
+# 890. Find and Replace Pattern
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/find-and-replace-pattern/description/
+
+> 内容描述
+
+```
+You have a list of words and a pattern, and you want to know which words in words matches the pattern.
+
+A word matches the pattern if there exists a permutation of letters p so that after replacing every letter x in the pattern with p(x), we get the desired word.
+
+(Recall that a permutation of letters is a bijection from letters to letters: every letter maps to another letter, and no two letters map to the same letter.)
+
+Return a list of the words in words that match the given pattern.
+
+You may return the answer in any order.
+
+
+
+Example 1:
+
+Input: words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"
+Output: ["mee","aqq"]
+Explanation: "mee" matches the pattern because there is a permutation {a -> m, b -> e, ...}.
+"ccc" does not match the pattern because {a -> c, b -> c, ...} is not a permutation,
+since a and b map to the same letter.
+
+
+Note:
+
+1 <= words.length <= 50
+1 <= pattern.length = words[i].length <= 20
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N*k)******- 空间复杂度: O(k)****** 这里k为最长的那个字符串的长度
+
+1. 定义一个convert函数
+ - 首先对于传进来的word做一个for loop
+ - 只要字符没有出现过就用一个全新的num来对应它
+ - 否则就用之前存在dict里面的它所对应num来对应它
+2. 比较每个word convert之后是否于pattern convert之后相等,相等就加入最终结果
+3. 返回最终结果
+
+
+```python
+class Solution(object):
+ def findAndReplacePattern(self, words, pattern):
+ """
+ :type words: List[str]
+ :type pattern: str
+ :rtype: List[str]
+ """
+ def convert(word):
+ lookup = {}
+ num = 0
+ word_convert = ''
+ for i in word:
+ if i not in lookup: # 第一次出现这个字符
+ num += 1 # 用一个全新的num来对应它
+ word_convert += str(num)
+ lookup[i] = num # 存进dict供给后面用
+ else:
+ word_convert += str(lookup[i]) # 之前出现过了这个字符那么就加上它之前对应的数字
+ return word_convert
+ pattern_convert = convert(pattern)
+ res = []
+ for word in words:
+ if convert(word) == pattern_convert:
+ res.append(word)
+ return res
+```
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/891._Sum_of_Subsequence_Widths.md b/docs/Leetcode_Solutions/Python/891._Sum_of_Subsequence_Widths.md
new file mode 100644
index 000000000..1f5297320
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/891._Sum_of_Subsequence_Widths.md
@@ -0,0 +1,104 @@
+# 891. Sum of Subsequence Widths
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/sum-of-subsequence-widths/description/
+
+> 内容描述
+
+```
+
+Given an array of integers A, consider all non-empty subsequences of A.
+
+For any sequence S, let the width of S be the difference between the maximum and minimum element of S.
+
+Return the sum of the widths of all subsequences of A.
+
+As the answer may be very large, return the answer modulo 10^9 + 7.
+
+
+
+Example 1:
+
+Input: [2,1,3]
+Output: 6
+Explanation:
+Subsequences are [1], [2], [3], [2,1], [2,3], [1,3], [2,1,3].
+The corresponding widths are 0, 0, 0, 1, 1, 2, 2.
+The sum of these widths is 6.
+
+
+Note:
+
+1 <= A.length <= 20000
+1 <= A[i] <= 20000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
+
+
+设n为A数组的长度
+
+先给A排序,其中以A[0]为最小值的子序列的个数为2^(n-1),以A[0]为最大值的子序列的个数为2^(0),以此类推。
+
+开始写的代码如下:
+
+```
+class Solution(object):
+ def sumSubseqWidths(self, A):
+ """
+ :type A: List[int]
+ :rtype: int
+ """
+ A.sort()
+ res, n = 0, len(A)
+ for i in range(len(A)):
+ res -= A[i] * pow(2, n-1-i)
+ res += A[i] * pow(2, i)
+ res %= pow(10, 9) + 7
+ return res
+```
+
+
+但是一直超时,于是我觉得是因为pow()函数太费时间了,所以用空间换时间,先把所有2的0到(n-1)次方全部存起来,然后后面直接取就行了,果然AC
+
+beats 84.15%
+```python
+class Solution(object):
+ def sumSubseqWidths(self, A):
+ """
+ :type A: List[int]
+ :rtype: int
+ """
+ MOD = 10**9 + 7
+ res, n = 0, len(A)
+ A.sort()
+
+ pow2 = [1]
+ for i in xrange(1, n):
+ pow2.append(pow2[-1] * 2 % MOD)
+
+ for i, x in enumerate(A):
+ res -= x * pow2[n-1-i] % MOD
+ res += x * pow2[i] % MOD
+ return res % MOD
+```
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/896._monotonic_array.md b/docs/Leetcode_Solutions/Python/896._monotonic_array.md
new file mode 100644
index 000000000..4095fc7b6
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/896._monotonic_array.md
@@ -0,0 +1,74 @@
+# 896. Monotonic Array
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/monotonic-array
+
+> 内容描述
+
+```
+An array is monotonic if it is either monotone increasing or monotone decreasing.
+
+An array A is monotone increasing if for all i <= j, A[i] <= A[j]. An array A is monotone decreasing if for all i <= j, A[i] >= A[j].
+
+Return true if and only if the given array A is monotonic.
+
+Example 1:
+
+Input: [1,2,2,3]
+Output: true
+
+Example 2:
+
+Input: [6,5,4,4]
+Output: true
+
+Exmaple 3:
+
+Input: [1,3,2]
+Output: false
+
+Example 4:
+
+Input: [1,2,4,5]
+Output: true
+
+Example 5:
+
+Input: [1,1,1]
+Output: true
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+遍历list, 如果不满足条件, flag设为False, 返回两者之一。
+
+beats 54.15%
+
+```python
+class Solution(object):
+ def isMonotonic(self, A):
+ """
+ :type A: List[int]
+ :rtype: bool
+ """
+ if not A or len(A) <= 1:
+ return True
+
+ increasing = decreasing = True
+
+ for i in range(len(A) - 1):
+ if A[i] > A[i+1]:
+ increasing = False
+ if A[i] < A[i+1]:
+ decreasing = False
+
+ return increasing or decreasing
+```
diff --git a/docs/Leetcode_Solutions/Python/900._RLE_Iterator.md b/docs/Leetcode_Solutions/Python/900._RLE_Iterator.md
new file mode 100644
index 000000000..3cc60284d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/900._RLE_Iterator.md
@@ -0,0 +1,173 @@
+# 900. RLE Iterator
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/rle-iterator/description/
+
+> 内容描述
+
+```
+
+Write an iterator that iterates through a run-length encoded sequence.
+
+The iterator is initialized by RLEIterator(int[] A), where A is a run-length encoding of some sequence. More specifically, for all even i, A[i] tells us the number of times that the non-negative integer value A[i+1] is repeated in the sequence.
+
+The iterator supports one function: next(int n), which exhausts the next n elements (n >= 1) and returns the last element exhausted in this way. If there is no element left to exhaust, next returns -1 instead.
+
+For example, we start with A = [3,8,0,9,2,5], which is a run-length encoding of the sequence [8,8,8,5,5]. This is because the sequence can be read as "three eights, zero nines, two fives".
+
+
+
+Example 1:
+
+Input: ["RLEIterator","next","next","next","next"], [[[3,8,0,9,2,5]],[2],[1],[1],[2]]
+Output: [null,8,8,5,-1]
+Explanation:
+RLEIterator is initialized with RLEIterator([3,8,0,9,2,5]).
+This maps to the sequence [8,8,8,5,5].
+RLEIterator.next is then called 4 times:
+
+.next(2) exhausts 2 terms of the sequence, returning 8. The remaining sequence is now [8, 5, 5].
+
+.next(1) exhausts 1 term of the sequence, returning 8. The remaining sequence is now [5, 5].
+
+.next(1) exhausts 1 term of the sequence, returning 5. The remaining sequence is now [5].
+
+.next(2) exhausts 2 terms, returning -1. This is because the first term exhausted was 5,
+but the second term did not exist. Since the last term exhausted does not exist, we return -1.
+
+Note:
+
+0 <= A.length <= 1000
+A.length is an even integer.
+0 <= A[i] <= 10^9
+There are at most 1000 calls to RLEIterator.next(int n) per test case.
+Each call to RLEIterator.next(int n) will have 1 <= n <= 10^9.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(len(A))******
+
+
+
+周赛的时候做的这道题,刚开始很sb,抱着试试的想法直接全部装起来然后一个个返回,果然太 naive
+
+
+```
+class RLEIterator(object):
+
+ def __init__(self, A):
+ """
+ :type A: List[int]
+ """
+ self.lst = A
+ self.tmp = []
+ for i in range(0, len(self.lst), 2):
+ self.tmp.extend([self.lst[i+1]]*self.lst[i])
+
+
+
+ def next(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ if len(self.tmp) < n:
+ return -1
+ else:
+ for i in range(n):
+ if i == n-1:
+ return self.tmp.pop(0)
+ self.tmp.pop(0)
+```
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(len(A))******
+
+
+然后写了半天,每次只取一个的逻辑,还是超时了。真的蠢。。。。
+
+```
+class RLEIterator(object):
+
+ def __init__(self, A):
+ """
+ :type A: List[int]
+ """
+ self.lst = A
+ self.tmp = []
+ self.cnt, self.num = 0, 0
+
+
+
+
+ def next(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ if self.tmp:
+ if n == 1:
+ return self.tmp.pop(0)
+ else:
+ self.tmp.pop(0)
+ return self.next(n-1)
+ else:
+ if self.cnt > 0:
+ self.tmp.append(self.num)
+ self.cnt -= 1
+ return self.next(n)
+ else:
+ if self.lst:
+ self.cnt, self.num = self.lst.pop(0), self.lst.pop(0)
+ return self.next(n)
+ else:
+ return -1
+```
+
+> 思路 3
+******- 时间复杂度: O(N)******- 空间复杂度: O(len(A))******
+
+
+利用python built-in数据结构deque的性质,直接AC, beats 100%
+
+```python
+class RLEIterator(object):
+
+ def __init__(self, A):
+ """
+ :type A: List[int]
+ """
+ self._deque = collections.deque(A)
+
+
+ def next(self, n):
+ """
+ :type n: int
+ :rtype: int
+ """
+ while self._deque and n:
+ count = self._deque.popleft()
+ val = self._deque[0]
+ if count >= n:
+ self._deque.appendleft(count-n)
+ return val
+ else:
+ n -= count
+ self._deque.popleft()
+ return -1
+
+
+
+
+# Your RLEIterator object will be instantiated and called as such:
+# obj = RLEIterator(A)
+# param_1 = obj.next(n)
+```
diff --git a/docs/Leetcode_Solutions/Python/901._Online_Stock_Span.md b/docs/Leetcode_Solutions/Python/901._Online_Stock_Span.md
new file mode 100644
index 000000000..e93f1ef5d
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/901._Online_Stock_Span.md
@@ -0,0 +1,76 @@
+# 901. Online Stock Span
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/online-stock-span/description/
+
+> 内容描述
+
+```
+Write a class StockSpanner which collects daily price quotes for some stock, and returns the span of that stock's price for the current day.
+
+The span of the stock's price today is defined as the maximum number of consecutive days (starting from today and going backwards) for which the price of the stock was less than or equal to today's price.
+
+For example, if the price of a stock over the next 7 days were [100, 80, 60, 70, 60, 75, 85], then the stock spans would be [1, 1, 1, 2, 1, 4, 6].
+
+
+
+Example 1:
+
+Input: ["StockSpanner","next","next","next","next","next","next","next"], [[],[100],[80],[60],[70],[60],[75],[85]]
+Output: [null,1,1,1,2,1,4,6]
+Explanation:
+First, S = StockSpanner() is initialized. Then:
+S.next(100) is called and returns 1,
+S.next(80) is called and returns 1,
+S.next(60) is called and returns 1,
+S.next(70) is called and returns 2,
+S.next(60) is called and returns 1,
+S.next(75) is called and returns 4,
+S.next(85) is called and returns 6.
+
+Note that (for example) S.next(75) returned 4, because the last 4 prices
+(including today's price of 75) were less than or equal to today's price.
+
+
+Note:
+
+Calls to StockSpanner.next(int price) will have 1 <= price <= 10^5.
+There will be at most 10000 calls to StockSpanner.next per test case.
+There will be at most 150000 calls to StockSpanner.next across all test cases.
+The total time limit for this problem has been reduced by 75% for C++, and 50% for all other languages.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+
+
+while pop + push new 思想
+
+```python
+class StockSpanner(object):
+
+ def __init__(self):
+ self.stack = []
+
+ def next(self, price):
+ """
+ :type price: int
+ :rtype: int
+ """
+ cnt = 1
+ while self.stack and self.stack[-1][0] <= price:
+ cnt += self.stack.pop()[1]
+ self.stack.append([price, cnt])
+ return cnt
+```
+
diff --git a/docs/Leetcode_Solutions/Python/902._Numbers_At_Most_N_Given_Digit_Set.md b/docs/Leetcode_Solutions/Python/902._Numbers_At_Most_N_Given_Digit_Set.md
new file mode 100644
index 000000000..c14134124
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/902._Numbers_At_Most_N_Given_Digit_Set.md
@@ -0,0 +1,88 @@
+# 902. Numbers At Most N Given Digit Set
+
+**难度: hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/numbers-at-most-n-given-digit-set/description/
+
+> 内容描述
+
+```
+We have a sorted set of digits D, a non-empty subset of {'1','2','3','4','5','6','7','8','9'}. (Note that '0' is not included.)
+
+Now, we write numbers using these digits, using each digit as many times as we want. For example, if D = {'1','3','5'}, we may write numbers such as '13', '551', '1351315'.
+
+Return the number of positive integers that can be written (using the digits of D) that are less than or equal to N.
+
+
+
+Example 1:
+
+Input: D = ["1","3","5","7"], N = 100
+Output: 20
+Explanation:
+The 20 numbers that can be written are:
+1, 3, 5, 7, 11, 13, 15, 17, 31, 33, 35, 37, 51, 53, 55, 57, 71, 73, 75, 77.
+Example 2:
+
+Input: D = ["1","4","9"], N = 1000000000
+Output: 29523
+Explanation:
+We can write 3 one digit numbers, 9 two digit numbers, 27 three digit numbers,
+81 four digit numbers, 243 five digit numbers, 729 six digit numbers,
+2187 seven digit numbers, 6561 eight digit numbers, and 19683 nine digit numbers.
+In total, this is 29523 integers that can be written using the digits of D.
+
+
+Note:
+
+D is a subset of digits '1'-'9' in sorted order.
+1 <= N <= 10^9
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(lgN)******- 空间复杂度: O(N)******
+
+
+这里时间复杂度为 O(lgN) 是因为我们把N看作是input里面N的大小
+
+并且pow(x, y)的时间复杂度为:
+
+1. For y < 2^63, there's a loop of size ceil(log_2(y)),
+2. but for larger y, the result is calculated using Exp(y * Log(x)).
+
+
+参见[lee215](https://leetcode.com/problems/numbers-at-most-n-given-digit-set/discuss/168279/Python-O(logN))
+```
+- N has n digits, so all numbers less than n digits are valid, which are: sum(len(D) ** i for i in range(1, n))
+- The loop is to deal with all numbers with n digits, considering from N[0], N[1] back to N[n-1].
+For example, N[0] is valid only for c in D if c <= N[0].
+If c < N[0], then N[1], ..., N[n-1] can take any number in D but if c == N[0], then we need consider N[1],
+and the iteration repeats. That's why if N[i] not in D, then we don't need to repeat the loop anymore.
+- Finally i==n is addressed at the end when there exists all c in D that matches N
+```
+
+```python
+class Solution(object):
+ def atMostNGivenDigitSet(self, D, N):
+ """
+ :type D: List[str]
+ :type N: int
+ :rtype: int
+ """
+ N = str(N)
+ n = len(N)
+ res = sum(pow(len(D), i) for i in range(1, n)) # 考虑少于n位的答案
+ i = 0
+ while i < n: # 开始考虑刚好为n位的答案
+ res += sum(c < N[i] for c in D) * pow(len(D), n-i-1) # 每次只考虑比N当前位置的数字小的数字
+ if N[i] not in D: # 如果N当前位置的数字都不在D里面了,我们考虑不了下一个位置
+ break
+ i += 1
+ return res + (i==n) # 如果N判断到最后一个位置的数字了,这个数字都还在D里面,我们就知道有一个刚好等于N的组合
+```
diff --git a/docs/Leetcode_Solutions/Python/904._Fruit_Into_Baskets.md b/docs/Leetcode_Solutions/Python/904._Fruit_Into_Baskets.md
new file mode 100644
index 000000000..7adabebb5
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/904._Fruit_Into_Baskets.md
@@ -0,0 +1,89 @@
+# 904. Fruit Into Baskets
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/contest/weekly-contest-102/problems/fruit-into-baskets/
+
+> 内容描述
+
+```
+In a row of trees, the i-th tree produces fruit with type tree[i].
+
+You start at any tree of your choice, then repeatedly perform the following steps:
+
+Add one piece of fruit from this tree to your baskets. If you cannot, stop.
+Move to the next tree to the right of the current tree. If there is no tree to the right, stop.
+Note that you do not have any choice after the initial choice of starting tree: you must perform step 1, then step 2, then back to step 1, then step 2, and so on until you stop.
+
+You have two baskets, and each basket can carry any quantity of fruit, but you want each basket to only carry one type of fruit each.
+
+What is the total amount of fruit you can collect with this procedure?
+
+
+
+Example 1:
+
+Input: [1,2,1]
+Output: 3
+Explanation: We can collect [1,2,1].
+Example 2:
+
+Input: [0,1,2,2]
+Output: 3
+Explanation: We can collect [1,2,2].
+If we started at the first tree, we would only collect [0, 1].
+Example 3:
+
+Input: [1,2,3,2,2]
+Output: 4
+Explanation: We can collect [2,3,2,2].
+If we started at the first tree, we would only collect [1, 2].
+Example 4:
+
+Input: [3,3,3,1,2,1,1,2,3,3,4]
+Output: 5
+Explanation: We can collect [1,2,1,1,2].
+If we started at the first tree or the eighth tree, we would only collect 4 fruits.
+
+
+Note:
+
+1 <= tree.length <= 40000
+0 <= tree[i] < tree.length
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+和第159一样的思路,时间复杂度最差为O(N),因为有可能整个列表只有两种不同的数字
+
+```python
+class Solution(object):
+ def totalFruit(self, A):
+ """
+ :type tree: List[int]
+ :rtype: int
+ """
+ maps = {}
+ begin, end, counter, res = 0, 0, 0, 0
+ while end < len(A):
+ maps[A[end]] = maps.get(A[end], 0) + 1
+ if maps[A[end]] == 1:
+ counter += 1
+ end += 1 # end points to the next fruit
+ while counter > 2:
+ maps[A[begin]] -= 1
+ if maps[A[begin]] == 0:
+ counter -= 1
+ begin += 1
+ res = max(res, end - begin)
+ return res
+```
diff --git a/docs/Leetcode_Solutions/Python/905._Sort_Array_By_Parity.md b/docs/Leetcode_Solutions/Python/905._Sort_Array_By_Parity.md
new file mode 100644
index 000000000..53439ccda
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/905._Sort_Array_By_Parity.md
@@ -0,0 +1,72 @@
+# 905. Sort Array By Parity
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/sort-array-by-parity/description/
+
+> 内容描述
+
+```
+Given an array A of non-negative integers, return an array consisting of all the even elements of A, followed by all the odd elements of A.
+
+You may return any answer array that satisfies this condition.
+
+
+
+Example 1:
+
+Input: [3,1,2,4]
+Output: [2,4,3,1]
+The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted.
+
+
+Note:
+
+1 <= A.length <= 5000
+0 <= A[i] <= 5000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+贼暴力思路
+
+```python
+class Solution(object):
+ def sortArrayByParity(self, A):
+ """
+ :type A: List[int]
+ :rtype: List[int]
+ """
+ return [i for i in A if i & 1 == 0] + [i for i in A if i & 1 == 1]
+```
+
+
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+优化空间,in-place AC!
+
+```python
+class Solution(object):
+ def sortArrayByParity(self, A):
+ """
+ :type A: List[int]
+ :rtype: List[int]
+ """
+ idx = 0 # idx 指向的永远是奇数的 candidate
+ for i in range(len(A)):
+ if A[i] & 1 == 0:
+ A[i], A[idx] = A[idx], A[i]
+ idx += 1
+ return A
+```
diff --git a/docs/Leetcode_Solutions/Python/907._Sum_of_Subarray_Minimums.md b/docs/Leetcode_Solutions/Python/907._Sum_of_Subarray_Minimums.md
new file mode 100644
index 000000000..190ec1a83
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/907._Sum_of_Subarray_Minimums.md
@@ -0,0 +1,163 @@
+# 907. Sum of Subarray Minimums
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/sum-of-subarray-minimums/description/
+
+> 内容描述
+
+```
+
+Given an array of integers A, find the sum of min(B), where B ranges over every (contiguous) subarray of A.
+
+Since the answer may be large, return the answer modulo 10^9 + 7.
+
+
+
+Example 1:
+
+Input: [3,1,2,4]
+Output: 17
+Explanation: Subarrays are [3], [1], [2], [4], [3,1], [1,2], [2,4], [3,1,2], [1,2,4], [3,1,2,4].
+Minimums are 3, 1, 2, 4, 1, 1, 2, 1, 1, 1. Sum is 17.
+
+
+Note:
+
+1 <= A.length <= 30000
+1 <= A[i] <= 30000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+对于A中的每一个元素,我们只需要计算出以它为最小值且以它为结束的子串的个数left[i],然后再计算出以它为最小值且以它为开始的子串的个数right[i],
+注意这其中不允许有重复(即一个优先原则,例如1,2,3,1,其中先出现的那个1才是最小值,这样可以避免我们重复计算子串)
+
+```
+然后假设我们的A为[3,2,1,2,3]
+
+那么对于中间的1来说,它的left[i]为3,right[i]也为3
+那么它一共涉及到多少个字串呢,我们枚举一下
+
+3,2,1
+2,1
+1
+3,2,1,2
+2,1,2
+1,2
+3,2,1,2,3
+2,1,2,3
+1,2,3
+
+
+一共涉及到9个,也就是说以A{i]为最小值的子串总数其实等于left[i] 和right[i]的乘积,这个也可以自己想出来,枚举只是为了看的更清晰
+```
+
+所以现在我们的目标变成了求以A中每一个元素为最小值的子串个数的list,命名为sub_counts
+
+例如还是上面的例子,我们的sub_counts = [1*1, 2*1, 3*3, 1*2, 1*1], 这里的对称性不是普遍的,因为我们的输入是对称的。
+
+所以我们的结果就是A中的每一个元素与其sub_count乘积的总和,即3*(1*1) + 2*(2*1) + 1*(3*3) + 2*(1*2) + 3*(1*1) = 23
+
+
+整个思路都是参考[寒神](https://leetcode.com/problems/sum-of-subarray-minimums/discuss/170750/C++JavaPython-Stack-Solution?page=2)的
+
+AC 代码如下:
+beats 53.98%
+
+
+```python
+class Solution(object):
+ def sumSubarrayMins(self, A):
+ """
+ :type A: List[int]
+ :rtype: int
+ """
+ stack_left, stack_right = [], []
+ # 分别代表左边和右边所涉及的子串个数的list
+ sub_left, sub_right = [0] * len(A), [0] * len(A)
+ for i in range(len(A)):
+ count = 1 # 初始都是1,因为自己本身算一个
+ while stack_left and stack_left[-1][0] > A[i]:
+ count += stack_left.pop()[1]
+ sub_left[i] = count # 其左边涉及子串个数为count
+ # stack—_left里面存的是A[i]这个元素前面有多少个严格比它小的数字
+ stack_left.append((A[i], count))
+ for i in range(len(A))[::-1]:
+ count = 1
+ while stack_right and stack_right[-1][0] >= A[i]:
+ count += stack_right.pop()[1]
+ sub_right[i] = count # 其右边涉及子串个数为count
+ # stack—_right里面存的是A[i]这个元素前面有多少个大于等于它的数字
+ stack_right.append((A[i], count))
+
+ return sum(a * l * r for a, l, r in zip(A, sub_left, sub_right)) % (10**9 + 7)
+```
+
+时间复杂度为O(N),因为对于A中的每一个元素我们都值进行了恰好两次push stack操作和最多2次pop stack的操作,因此是O(N)
+
+空间显然为O(N)
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+看了下,别人说这两个stack可以one pass,一个stack就够了, beats 100%
+
+
+不得不说,其中```left = stack[-1] if stack else -1```这句代码真的精妙绝伦,至少我想不到
+代码如下:
+
+
+```python
+class Solution(object):
+ def sumSubarrayMins(self, A):
+ """
+ :type A: List[int]
+ :rtype: int
+ """
+ count, stack = 0, []
+ for i in range(len(A)):
+ while stack and A[stack[-1]] >= A[i]:
+ pos = stack.pop()
+ # 下面这句代码是整个代码中最精妙的一句了
+ left = stack[-1] if stack else -1
+ # 这里一次就把涉及A[i]的子串的和全部加上次
+ count += (i - pos) * (pos - left) * A[pos]
+ stack.append(i)
+
+ while stack:
+ pos = stack.pop()
+ left = stack[-1] if stack else -1
+ count += (pos - left) * (len(A) - pos) * A[pos]
+ return count % (10**9 + 7)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/908._Smallest_Range.md b/docs/Leetcode_Solutions/Python/908._Smallest_Range.md
new file mode 100644
index 000000000..de79b5db6
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/908._Smallest_Range.md
@@ -0,0 +1,79 @@
+# 908. Smallest Range
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/smallest-range-i/description/
+
+> 内容描述
+
+```
+Given an array A of integers, for each integer A[i] we may choose any x with -K <= x <= K, and add x to A[i].
+
+After this process, we have some array B.
+
+Return the smallest possible difference between the maximum value of B and the minimum value of B.
+
+
+
+Example 1:
+
+Input: A = [1], K = 0
+Output: 0
+Explanation: B = [1]
+Example 2:
+
+Input: A = [0,10], K = 2
+Output: 6
+Explanation: B = [2,8]
+Example 3:
+
+Input: A = [1,3,6], K = 3
+Output: 0
+Explanation: B = [3,3,3] or B = [4,4,4]
+
+
+Note:
+
+1 <= A.length <= 10000
+0 <= A[i] <= 10000
+0 <= K <= 10000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+比赛起晚了,9点25惊醒,看到题目后 3 分钟多一点 bug free 一遍 AC
+
+这个题目这么简单就没必要说什么了
+
+
+```python
+class Solution(object):
+ def smallestRangeI(self, A, K):
+ """
+ :type A: List[int]
+ :type K: int
+ :rtype: int
+ """
+ max_num = max(A)
+ min_num = min(A)
+ if max_num - min_num > 2 * abs(K):
+ return max_num - min_num - 2 * abs(K)
+ elif max_num - min_num <= 2 * abs(K):
+ return 0
+```
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/910._Smallest_Range_II.md b/docs/Leetcode_Solutions/Python/910._Smallest_Range_II.md
new file mode 100644
index 000000000..eb6f06c3e
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/910._Smallest_Range_II.md
@@ -0,0 +1,83 @@
+# 910. Smallest Range II
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/smallest-range-ii/description/
+
+> 内容描述
+
+```
+Given an array A of integers, for each integer A[i] we need to choose either x = -K or x = K, and add x to A[i] (only once).
+
+After this process, we have some array B.
+
+Return the smallest possible difference between the maximum value of B and the minimum value of B.
+
+
+
+Example 1:
+
+Input: A = [1], K = 0
+Output: 0
+Explanation: B = [1]
+Example 2:
+
+Input: A = [0,10], K = 2
+Output: 6
+Explanation: B = [2,8]
+Example 3:
+
+Input: A = [1,3,6], K = 3
+Output: 3
+Explanation: B = [4,6,3]
+
+
+Note:
+
+1 <= A.length <= 10000
+0 <= A[i] <= 10000
+0 <= K <= 10000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+今天比赛睡晚了,总共只有35分钟,所以没什么时间,没有想出来,事后证明自己已经非常接近了
+
+这道题的AC率12%左右,其实有点难想出来的
+
+开始我想的是先算出max_num和min_num,再算出它们两的平均值avg_num,然后对于A中的所有数字,如果大于avg_num就减去K,如果小于等于avg_num就加上K。
+但是这样是不对的,毕竟这种东西跟我们的K也是有关的
+
+最后想到我们先把A排序,然后A前面一部分比较小的数字全部加上K,后面那部分比较大的数字全部减去K,这样找到一个临界值,使得我们最终的极值最小
+
+所以我们对排序后的A做一个遍历,然后每一轮的最大值会在```A[i]+K```和```A[-1]-K```之间取,最小值只会在```A[i+1]-K```和```A[0]+K```中取
+
+```python
+class Solution(object):
+ def smallestRangeII(self, A, K):
+ """
+ :type A: List[int]
+ :type K: int
+ :rtype: int
+ """
+ if not A or len(A) <= 1:
+ return 0
+ if len(A) == 2:
+ return min(A[-1]-A[0], abs(A[-1]-A[0]-2*K))
+
+ K = abs(K)
+ A.sort()
+ res = sys.maxsize
+ for i in range(len(A)-1):
+ tmp = max(A[i]+K, A[-1]-K) - min(A[i+1]-K, A[0]+K)
+ res = min(res, tmp)
+ return min(res, A[-1]-A[0])
+```
diff --git a/docs/Leetcode_Solutions/Python/914._X_of_a_Kind_in_a_Deck_of_Cards.md b/docs/Leetcode_Solutions/Python/914._X_of_a_Kind_in_a_Deck_of_Cards.md
new file mode 100644
index 000000000..966a8a797
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/914._X_of_a_Kind_in_a_Deck_of_Cards.md
@@ -0,0 +1,88 @@
+# 914. X of a Kind in a Deck of Cards
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/contest/weekly-contest-104/problems/x-of-a-kind-in-a-deck-of-cards/
+
+> 内容描述
+
+```
+In a deck of cards, each card has an integer written on it.
+
+Return true if and only if you can choose X >= 2 such that it is possible to split the entire deck into 1 or more groups of cards, where:
+
+Each group has exactly X cards.
+All the cards in each group have the same integer.
+
+
+Example 1:
+
+Input: [1,2,3,4,4,3,2,1]
+Output: true
+Explanation: Possible partition [1,1],[2,2],[3,3],[4,4]
+Example 2:
+
+Input: [1,1,1,2,2,2,3,3]
+Output: false
+Explanation: No possible partition.
+Example 3:
+
+Input: [1]
+Output: false
+Explanation: No possible partition.
+Example 4:
+
+Input: [1,1]
+Output: true
+Explanation: Possible partition [1,1]
+Example 5:
+
+Input: [1,1,2,2,2,2]
+Output: true
+Explanation: Possible partition [1,1],[2,2],[2,2]
+
+Note:
+
+1 <= deck.length <= 10000
+0 <= deck[i] < 10000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+按照纸牌种类算一下每种纸牌的数量,然后有几下几个要点
+
+1. 如果最少的纸牌数小于2,肯定返回False
+2. 求出最小的纸牌数之后,如果任意一个纸牌数与它的最大公约数小于2,也直接返回False
+
+
+因为数字都小于10000,所以求最大公约数的时间复杂度可以看成O(1),因此最后的时间复杂度为O(N)
+
+```python
+class Solution(object):
+ def hasGroupsSizeX(self, deck):
+ """
+ :type deck: List[int]
+ :rtype: bool
+ """
+ lookup = collections.Counter(deck)
+ min_num = min(lookup.values())
+ if min_num < 2:
+ return False
+ def gcd(a, b):
+ if a % b == 0:
+ return b
+ return gcd(b, a%b)
+ for value in lookup.values():
+ if gcd(value, min_num) < 2:
+ return False
+ return True
+```
diff --git a/docs/Leetcode_Solutions/Python/915._Partition_Array_into_Disjoint_Intervals.md b/docs/Leetcode_Solutions/Python/915._Partition_Array_into_Disjoint_Intervals.md
new file mode 100644
index 000000000..70b8ab72f
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/915._Partition_Array_into_Disjoint_Intervals.md
@@ -0,0 +1,88 @@
+# 915. Partition Array into Disjoint Intervals
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/contest/weekly-contest-104/problems/partition-array-into-disjoint-intervals/
+
+> 内容描述
+
+```
+Given an array A, partition it into two (contiguous) subarrays left and right so that:
+
+Every element in left is less than or equal to every element in right.
+left and right are non-empty.
+left has the smallest possible size.
+Return the length of left after such a partitioning. It is guaranteed that such a partitioning exists.
+
+
+
+Example 1:
+
+Input: [5,0,3,8,6]
+Output: 3
+Explanation: left = [5,0,3], right = [8,6]
+Example 2:
+
+Input: [1,1,1,0,6,12]
+Output: 4
+Explanation: left = [1,1,1,0], right = [6,12]
+
+
+Note:
+
+2 <= A.length <= 30000
+0 <= A[i] <= 10^6
+It is guaranteed there is at least one way to partition A as described.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+
+用前缀最大数组与后缀最大数组做,满足要求的临界点是前半部分的最大值刚好由大于变成了小于等于后半部分的最小值
+
+```python
+class Solution(object):
+ def partitionDisjoint(self, A):
+ """
+ :type A: List[int]
+ :rtype: int
+ """
+ if not A or len(A) == 0:
+ return 0
+
+ max_num, min_num = A[0], A[-1]
+ max_prefix, min_suffix = [max_num], [min_num]
+ for i in range(1, len(A)):
+ max_num = max(A[i], max_num)
+ max_prefix.append(max_num)
+ for i in range(len(A)-2, -1, -1):
+ min_num = min(A[i], min_num)
+ min_suffix.insert(0, min_num)
+ idx = 0
+ while max_prefix[idx] > min_suffix[idx+1]:
+ idx += 1
+ return idx + 1
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/916._Word_Subsets.md b/docs/Leetcode_Solutions/Python/916._Word_Subsets.md
new file mode 100644
index 000000000..29c7afd41
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/916._Word_Subsets.md
@@ -0,0 +1,117 @@
+# 916. Word Subsets
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/contest/weekly-contest-104/problems/word-subsets/
+
+> 内容描述
+
+```
+We are given two arrays A and B of words. Each word is a string of lowercase letters.
+
+Now, say that word b is a subset of word a if every letter in b occurs in a, including multiplicity. For example, "wrr" is a subset of "warrior", but is not a subset of "world".
+
+Now say a word a from A is universal if for every b in B, b is a subset of a.
+
+Return a list of all universal words in A. You can return the words in any order.
+
+
+
+Example 1:
+
+Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["e","o"]
+Output: ["facebook","google","leetcode"]
+Example 2:
+
+Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["l","e"]
+Output: ["apple","google","leetcode"]
+Example 3:
+
+Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["e","oo"]
+Output: ["facebook","google"]
+Example 4:
+
+Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["lo","eo"]
+Output: ["google","leetcode"]
+Example 5:
+
+Input: A = ["amazon","apple","facebook","google","leetcode"], B = ["ec","oc","ceo"]
+Output: ["facebook","leetcode"]
+
+
+Note:
+
+1 <= A.length, B.length <= 10000
+1 <= A[i].length, B[i].length <= 10
+A[i] and B[i] consist only of lowercase letters.
+All words in A[i] are unique: there isn't i != j with A[i] == A[j].
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(max(ma*la, mb*lb))******- 空间复杂度: O(1)******
+
+
+假设A的长度为na,其中最长的一个单词长度为la
+B的长度为nb,其中最长的一个单词长度为lb
+
+那么时间复杂度为O(max(ma*la, mb*lb)),由于字符总共就26个,所以空间复杂度可以看作O(1)
+
+
+先求出B中所有字符在所有单词中出现的最大次数,用lookup记录,然后如果A中的某一个单词满足lookup里面所有的key都有,且对应数量都大于等于lookup中的,
+那么该单词满足条件,append到最终结果中
+
+```python
+class Solution(object):
+ def wordSubsets(self, A, B):
+ """
+ :type A: List[str]
+ :type B: List[str]
+ :rtype: List[str]
+ """
+ if not B or len(B) == 0:
+ return A
+ lookup = collections.Counter(B[0])
+ for word in B[1:]:
+ tmp = collections.Counter(word)
+ for key in tmp.keys():
+ if key not in lookup:
+ lookup[key] = tmp[key]
+ else:
+ lookup[key] = max(lookup[key], tmp[key])
+ def uni(tmp_a, tmp_b):
+ if len(tmp_a.keys()) < len(tmp_b.keys()):
+ return False
+ for key in tmp_b.keys():
+ if key not in tmp_a:
+ return False
+ else:
+ if tmp_a[key] < tmp_b[key]:
+ return False
+ return True
+ res = []
+ for word in A:
+ if uni(collections.Counter(word), lookup):
+ res.append(word)
+ return res
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/917._Reverse_Only_Letters.md b/docs/Leetcode_Solutions/Python/917._Reverse_Only_Letters.md
new file mode 100644
index 000000000..31dc49d8b
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/917._Reverse_Only_Letters.md
@@ -0,0 +1,71 @@
+# 917. Reverse Only Letters
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/contest/weekly-contest-105/problems/reverse-only-letters/
+
+> 内容描述
+
+```
+Given a string S, return the "reversed" string where all characters that are not a letter stay in the same place, and all letters reverse their positions.
+
+
+
+Example 1:
+
+Input: "ab-cd"
+Output: "dc-ba"
+Example 2:
+
+Input: "a-bC-dEf-ghIj"
+Output: "j-Ih-gfE-dCba"
+Example 3:
+
+Input: "Test1ng-Leet=code-Q!"
+Output: "Qedo1ct-eeLg=ntse-T!"
+
+
+Note:
+
+S.length <= 100
+33 <= S[i].ASCIIcode <= 122
+S doesn't contain \ or "
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+sb题没什么好说的
+
+
+```python
+class Solution(object):
+ def reverseOnlyLetters(self, S):
+ """
+ :type S: str
+ :rtype: str
+ """
+ if not S or len(S) == 0:
+ return ''
+ tmp = []
+ res = []
+ for c in S:
+ if 'a' <= c <= 'z' or 'A' <= c <= 'Z':
+ tmp.append(c)
+ res.append(c)
+ tmp = tmp[::-1]
+ idx = 0
+ for i, c in enumerate(res):
+ if 'a' <= c <= 'z' or 'A' <= c <= 'Z':
+ res[i] = tmp[idx]
+ idx += 1
+ return ''.join(res)
+```
+
+
diff --git a/docs/Leetcode_Solutions/Python/918._Maximum_Sum_Circular_Subarray.md b/docs/Leetcode_Solutions/Python/918._Maximum_Sum_Circular_Subarray.md
new file mode 100644
index 000000000..c7cf49603
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/918._Maximum_Sum_Circular_Subarray.md
@@ -0,0 +1,113 @@
+# 918. Maximum Sum Circular Subarray
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/maximum-sum-circular-subarray/description/
+
+> 内容描述
+
+```
+Given a circular array C of integers represented by A, find the maximum possible sum of a non-empty subarray of C.
+
+Here, a circular array means the end of the array connects to the beginning of the array. (Formally, C[i] = A[i] when 0 <= i < A.length, and C[i+A.length] = C[i] when i >= 0.)
+
+Also, a subarray may only include each element of the fixed buffer A at most once. (Formally, for a subarray C[i], C[i+1], ..., C[j], there does not exist i <= k1, k2 <= j with k1 % A.length = k2 % A.length.)
+
+
+
+Example 1:
+
+Input: [1,-2,3,-2]
+Output: 3
+Explanation: Subarray [3] has maximum sum 3
+Example 2:
+
+Input: [5,-3,5]
+Output: 10
+Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10
+Example 3:
+
+Input: [3,-1,2,-1]
+Output: 4
+Explanation: Subarray [2,-1,3] has maximum sum 2 + (-1) + 3 = 4
+Example 4:
+
+Input: [3,-2,2,-3]
+Output: 3
+Explanation: Subarray [3] and [3,-2,2] both have maximum sum 3
+Example 5:
+
+Input: [-2,-3,-1]
+Output: -1
+Explanation: Subarray [-1] has maximum sum -1
+
+
+Note:
+
+-30000 <= A[i] <= 30000
+1 <= A.length <= 30000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+
+
+
+
+直接用53题的最优思想做,然后参考了[寒神的牛p思想](https://leetcode.com/problems/maximum-sum-circular-subarray/discuss/178422/C++JavaPython-One-Pass)
+
+```
+The max subarray circular sum equals to
+max(the max subarray sum, the total sum - the min subarray sum)
+
+One corner case: If all number are negative, return the maximum one, (which equals to the max subarray sum)
+```
+
+```python
+class Solution(object):
+ def maxSubarraySumCircular(self, A):
+ """
+ :type A: List[int]
+ :rtype: int
+ """
+ nums = A
+ flag = all(num < 0 for num in nums)
+ max_sum, max_end, min_sum, min_end = nums[0], nums[0], nums[0], nums[0]
+ for i in range(1, len(nums)):
+ max_end = max(nums[i], max_end+nums[i])
+ max_sum = max(max_sum, max_end)
+ min_end = min(nums[i], min_end+nums[i])
+ min_sum = min(min_sum, min_end)
+ return max(max_sum, sum(nums) - min_sum) if not flag else max(nums)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/919._Complete_Binary_Tree_Inserter.md b/docs/Leetcode_Solutions/Python/919._Complete_Binary_Tree_Inserter.md
new file mode 100644
index 000000000..78ec77e5c
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/919._Complete_Binary_Tree_Inserter.md
@@ -0,0 +1,104 @@
+# 919. Complete Binary Tree Inserter
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/complete-binary-tree-inserter/description/
+
+> 内容描述
+
+```
+A complete binary tree is a binary tree in which every level, except possibly the last, is completely filled, and all nodes are as far left as possible.
+
+Write a data structure CBTInserter that is initialized with a complete binary tree and supports the following operations:
+
+CBTInserter(TreeNode root) initializes the data structure on a given tree with head node root;
+CBTInserter.insert(int v) will insert a TreeNode into the tree with value node.val = v so that the tree remains complete, and returns the value of the parent of the inserted TreeNode;
+CBTInserter.get_root() will return the head node of the tree.
+
+
+Example 1:
+
+Input: inputs = ["CBTInserter","insert","get_root"], inputs = [[[1]],[2],[]]
+Output: [null,1,[1,2]]
+Example 2:
+
+Input: inputs = ["CBTInserter","insert","insert","get_root"], inputs = [[[1,2,3,4,5,6]],[7],[8],[]]
+Output: [null,3,4,[1,2,3,4,5,6,7,8]]
+
+
+Note:
+
+The initial given tree is complete and contains between 1 and 1000 nodes.
+CBTInserter.insert is called at most 10000 times per test case.
+Every value of a given or inserted node is between 0 and 5000.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(1)******- 空间复杂度: O(N)******
+
+
+
+
+- init的时候来个层序遍历搞起来,两个列表一个按照次序放node,一个按照次序放对应的value
+- 每次插入的时候先得到父亲的index,然后如果插入后总node数为偶数就说明是右孩子,反之则是左孩子
+- get_root则简单了,直接返回self.lst[0]
+
+```python
+class CBTInserter(object):
+
+ def __init__(self, root):
+ """
+ :type root: TreeNode
+ """
+ self.lst = []
+ self.values = []
+ def levelTraversal(root):
+ cur_level = [root]
+ while cur_level:
+ next_level = []
+ for node in cur_level:
+ if node.left:
+ next_level.append(node.left)
+ if node.right:
+ next_level.append(node.right)
+ self.lst.append(node)
+ self.values.append(node.val)
+ cur_level = next_level
+ levelTraversal(root)
+
+
+
+ def insert(self, v):
+ """
+ :type v: int
+ :rtype: int
+ """
+ self.values.append(v)
+ self.lst.append(TreeNode(v))
+ idx = len(self.lst) - 1
+ if idx & 1:
+ self.lst[(idx-1)//2].left = self.lst[-1]
+ else:
+ self.lst[(idx-1)//2].right = self.lst[-1]
+ return self.values[(idx-1)//2] if idx > 0 else self.values[0]
+
+
+ def get_root(self):
+ """
+ :rtype: TreeNode
+ """
+ return self.lst[0]
+
+
+
+# Your CBTInserter object will be instantiated and called as such:
+# obj = CBTInserter(root)
+# param_1 = obj.insert(v)
+# param_2 = obj.get_root()
+```
diff --git a/docs/Leetcode_Solutions/Python/920._Number_of_Music_Playlists.md b/docs/Leetcode_Solutions/Python/920._Number_of_Music_Playlists.md
new file mode 100644
index 000000000..c403c33c2
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/920._Number_of_Music_Playlists.md
@@ -0,0 +1,108 @@
+# 920. Number of Music Playlists
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/number-of-music-playlists/description/
+
+> 内容描述
+
+```
+Your music player contains N different songs and she wants to listen to L (not necessarily different) songs during your trip. You create a playlist so that:
+
+Every song is played at least once
+A song can only be played again only if K other songs have been played
+Return the number of possible playlists. As the answer can be very large, return it modulo 10^9 + 7.
+
+
+
+Example 1:
+
+Input: N = 3, L = 3, K = 1
+Output: 6
+Explanation: There are 6 possible playlists. [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1].
+Example 2:
+
+Input: N = 2, L = 3, K = 0
+Output: 6
+Explanation: There are 6 possible playlists. [1, 1, 2], [1, 2, 1], [2, 1, 1], [2, 2, 1], [2, 1, 2], [1, 2, 2]
+Example 3:
+
+Input: N = 2, L = 3, K = 1
+Output: 2
+Explanation: There are 2 possible playlists. [1, 2, 1], [2, 1, 2]
+
+
+Note:
+
+0 <= K < N <= L <= 100
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N*L)******- 空间复杂度: O(N*L)******
+
+
+
+DP
+
+- dp[i][j]代表用j首不同的歌曲来组成播放列表的前i首歌的可能性,初始化dp[0][0] = 1,其他元素全为0,确定返回dp[L][N]
+- 第一种可能性,第i首歌与前i-1首歌均不重复,先用j-1首不同的歌组成播放列表的前i-1首歌,然后挑选一首与那j-1首歌都不同的歌来作为播放列表的第i首歌
+ - 这种情况毫无疑问不需要担心第i首歌与它前面的K首歌出现重复
+ - 状态转移方程为dp[i][j] += dp[i-1][j-1] * (N-j+1) % M
+- 第二种可能性,第i首歌与前i-1首歌有重复,先用j首不同的歌组成播放列表的前i-1首歌,然后挑选一首与那j-1首歌重复的歌来作为播放列表的第i首歌
+ - 我们需要保证第i首歌与它的前K首歌不出现重复
+ - 如果所有不重复的歌都不大于K(即j <= K),那第i首歌与它前面的K首歌必然出现重复,因此没有这种排列
+ - 如果j>K,状态转移方程为dp[i][j] += dp[i-1][j] * (j-K) % M,
+ 我们需要保证第i首歌与它前面的K首歌都不相同,所以第i首歌只能从j-K首歌里面选取
+
+- 最后返回dp[L][N],即用N首不同的歌来组成播放列表的前L首歌
+
+
+
+```python
+class Solution(object):
+ def numMusicPlaylists(self, N, L, K):
+ """
+ :type N: int
+ :type L: int
+ :type K: int
+ :rtype: int
+ """
+ M = 10**9+7
+ dp = [[0] * (N+1) for i in range(L+1)] # dp[i][j]代表用j首不同的歌曲来组成播放列表的前i首歌的可能性
+ dp[0][0] = 1 # 初始化为1种
+ for i in range(1, L+1):
+ for j in range(1, N+1):
+ dp[i][j] += dp[i-1][j-1] * (N-j+1) % M # 第一种可能性
+ if j > K:
+ dp[i][j] += dp[i-1][j] * (j-K) % M # 第二种可能性
+ return dp[L][N] % M
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/921._Minimum_Add_to_Make_Parentheses_Valid.md b/docs/Leetcode_Solutions/Python/921._Minimum_Add_to_Make_Parentheses_Valid.md
new file mode 100644
index 000000000..737ca447c
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/921._Minimum_Add_to_Make_Parentheses_Valid.md
@@ -0,0 +1,111 @@
+# 921. Minimum Add to Make Parentheses Valid
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/description/
+
+> 内容描述
+
+```
+Given a string S of '(' and ')' parentheses, we add the minimum number of parentheses ( '(' or ')', and in any positions ) so that the resulting parentheses string is valid.
+
+Formally, a parentheses string is valid if and only if:
+
+It is the empty string, or
+It can be written as AB (A concatenated with B), where A and B are valid strings, or
+It can be written as (A), where A is a valid string.
+Given a parentheses string, return the minimum number of parentheses we must add to make the resulting string valid.
+
+
+
+Example 1:
+
+Input: "())"
+Output: 1
+Example 2:
+
+Input: "((("
+Output: 3
+Example 3:
+
+Input: "()"
+Output: 0
+Example 4:
+
+Input: "()))(("
+Output: 4
+
+
+Note:
+
+S.length <= 1000
+S only consists of '(' and ')' characters.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+
+乍一看还以为绝世难题呢,结果太 easy 了
+
+
+```python
+class Solution(object):
+ def minAddToMakeValid(self, S):
+ """
+ :type S: str
+ :rtype: int
+ """
+ if not S or len(S) == 0:
+ return 0
+ left, right, res = 0, 0, 0
+ for i in S:
+ if i == '(':
+ left += 1
+ else:
+ if left == 0:
+ res += 1
+ else:
+ left -= 1
+ return res + left
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/922._Sort_Array_By_Parity_II.md b/docs/Leetcode_Solutions/Python/922._Sort_Array_By_Parity_II.md
new file mode 100644
index 000000000..408a63e08
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/922._Sort_Array_By_Parity_II.md
@@ -0,0 +1,64 @@
+# 922. Sort Array By Parity II
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/sort-array-by-parity-ii/description/
+
+> 内容描述
+
+```
+Given an array A of non-negative integers, half of the integers in A are odd, and half of the integers are even.
+
+Sort the array so that whenever A[i] is odd, i is odd; and whenever A[i] is even, i is even.
+
+You may return any answer array that satisfies this condition.
+
+
+
+Example 1:
+
+Input: [4,2,5,7]
+Output: [4,5,2,7]
+Explanation: [4,7,2,5], [2,5,4,7], [2,7,4,5] would also have been accepted.
+
+
+Note:
+
+2 <= A.length <= 20000
+A.length % 2 == 0
+0 <= A[i] <= 1000
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+
+太简单了,2分钟bug free
+
+```python
+class Solution(object):
+ def sortArrayByParityII(self, A):
+ """
+ :type A: List[int]
+ :rtype: List[int]
+ """
+ if not A or len(A) == 0:
+ return []
+ odds = [i for i in A if i & 1]
+ evens = [i for i in A if not i & 1]
+ res = [0] * len(A)
+ for i in range(len(A)):
+ if i & 1:
+ res[i] = odds.pop(0)
+ else:
+ res[i] = evens.pop(0)
+ return res
+```
diff --git a/docs/Leetcode_Solutions/Python/923._3Sum_With_Multiplicity.md b/docs/Leetcode_Solutions/Python/923._3Sum_With_Multiplicity.md
new file mode 100644
index 000000000..127726b46
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/923._3Sum_With_Multiplicity.md
@@ -0,0 +1,183 @@
+# 923. 3Sum With Multiplicity
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/3sum-with-multiplicity/description/
+
+> 内容描述
+
+```
+Given an integer array A, and an integer target, return the number of tuples i, j, k such that i < j < k and A[i] + A[j] + A[k] == target.
+
+As the answer can be very large, return it modulo 10^9 + 7.
+
+
+
+Example 1:
+
+Input: A = [1,1,2,2,3,3,4,4,5,5], target = 8
+Output: 20
+Explanation:
+Enumerating by the values (A[i], A[j], A[k]):
+(1, 2, 5) occurs 8 times;
+(1, 3, 4) occurs 8 times;
+(2, 2, 4) occurs 2 times;
+(2, 3, 3) occurs 2 times.
+Example 2:
+
+Input: A = [1,1,2,2,2,2], target = 5
+Output: 12
+Explanation:
+A[i] = 1, A[j] = A[k] = 2 occurs 12 times:
+We choose one 1 from [1,1] in 2 ways,
+and two 2s from [2,2,2,2] in 6 ways.
+
+
+Note:
+
+3 <= A.length <= 3000
+0 <= A[i] <= 100
+0 <= target <= 300
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******
+
+
+
+直接 3sum 走起,so easy,7分钟 bug free
+
+```python
+class Solution(object):
+ def threeSumMulti(self, A, target):
+ """
+ :type A: List[int]
+ :type target: int
+ :rtype: int
+ """
+ def threeSum(nums, target):
+ n, res = len(nums), []
+ nums.sort()
+ for i in range(n):
+ if i > 0 and nums[i] == nums[i-1]: # 因为i=0这个元素会直接往下执行
+ continue
+ l, r = i+1, n-1
+ while l < r:
+ tmp = nums[i] + nums[l] + nums[r]
+ if tmp == target:
+ res.append([nums[i], nums[l], nums[r]])
+ l += 1
+ r -= 1
+ while l < r and nums[l] == nums[l-1]:
+ l += 1
+ while l < r and nums[r] == nums[r+1]:
+ r -= 1
+ elif tmp > target:
+ r -= 1
+ else:
+ l += 1
+ return res
+ # 这个函数是为了算每一种排列的情况实际上有多少种,例如(2, 2, 4) occurs 2 times;
+ def cal(i, j, k, d):
+ if i == j == k:
+ return d[i] * (d[i]-1) * (d[i]-2) // 6
+ if i == j:
+ return d[k] * d[i] * (d[i]-1) // 2
+ if i == k:
+ return d[j] * d[i] * (d[i]-1) // 2
+ if j == k:
+ return d[i] * d[j] * (d[j]-1) // 2
+ return d[i] * d[j] * d[k]
+
+ if not A or len(A) == 0:
+ return 0
+ d = collections.Counter(A)
+ res, M = 0, 10**9 + 7
+ keys = [i for i in d.keys()]
+ for permu in threeSum(A, target):
+ res += cal(permu[0], permu[1], permu[2], d)
+ res %= M
+ return res % M
+```
+
+
+
+
+
+> 思路 2
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+改进一下空间,顺便缩短代码
+
+
+```python
+class Solution(object):
+ def threeSumMulti(self, A, target):
+ """
+ :type A: List[int]
+ :type target: int
+ :rtype: int
+ """
+ if not A or len(A) == 0:
+ return 0
+ res, n, M = 0, len(A), 10**9 + 7
+ A.sort() # 先排序利于后面的相等情况处理
+
+ for i in range(n):
+ l, r = i+1, n-1
+ while l < r:
+ if A[i] + A[l] + A[r] == target:
+ if A[l] != A[r]:
+ left, right = 1, 1
+
+ while l + 1 < r and A[l] == A[l+1]:
+ left, l = left + 1, l + 1
+ while r - 1 > l and A[r] == A[r-1]:
+ right, r = right + 1, r - 1
+
+ res += left * right
+ res %= M
+ l, r = l + 1, r - 1
+ else:
+ res += (r-l+1) * (r-l) // 2 # 例如[2,4,4]的取法
+ res %= M
+ break
+ elif A[i] + A[l] + A[r] > target:
+ r -= 1
+ else:
+ l += 1
+
+ return res % M
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/924._Minimize_Malware_Spread.md b/docs/Leetcode_Solutions/Python/924._Minimize_Malware_Spread.md
new file mode 100644
index 000000000..05929092c
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/924._Minimize_Malware_Spread.md
@@ -0,0 +1,129 @@
+# 924. Minimize Malware Spread
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimize-malware-spread/description/
+
+> 内容描述
+
+```
+In a network of nodes, each node i is directly connected to another node j if and only if graph[i][j] = 1.
+
+Some nodes initial are initially infected by malware. Whenever two nodes are directly connected and at least one of those two nodes is infected by malware, both nodes will be infected by malware. This spread of malware will continue until no more nodes can be infected in this manner.
+
+Suppose M(initial) is the final number of nodes infected with malware in the entire network, after the spread of malware stops.
+
+We will remove one node from the initial list. Return the node that if removed, would minimize M(initial). If multiple nodes could be removed to minimize M(initial), return such a node with the smallest index.
+
+Note that if a node was removed from the initial list of infected nodes, it may still be infected later as a result of the malware spread.
+
+
+
+Example 1:
+
+Input: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1]
+Output: 0
+Example 2:
+
+Input: graph = [[1,0,0],[0,1,0],[0,0,1]], initial = [0,2]
+Output: 0
+Example 3:
+
+Input: graph = [[1,1,1],[1,1,1],[1,1,1]], initial = [1,2]
+Output: 1
+
+
+Note:
+
+1 < graph.length = graph[0].length <= 300
+0 <= graph[i][j] == graph[j][i] <= 1
+graph[i][i] = 1
+1 <= initial.length < graph.length
+0 <= initial[i] < graph.length
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(len(graph)^2)******- 空间复杂度: O(len(graph))******
+
+
+
+
+
+比赛中sb了,一直用dfs超时,最后想到直接用并查集就行了,拍断大腿,本来稳稳前50的(自己欺骗自己😂😂😂)
+
+思路就是看看initial里面哪个index最小的点所在的联通分量size最大
+
+其中要注意每个initial中元素ini所在的联通分量我们还要去除它里面含有的本身就在initial中的其他元素,因为对于这些元素,事实上即使我们删除了ini,也minimize不了它们。所以要算一下每个initial里面的元素所在的联通分量里面包含的其他的initial元素的个数,代码中用dup表示
+
+graph长度为N,
+
+find()时间复杂度为O(N), union为O(1),所以最终时间复杂度为O(len(graph)^2)
+
+空间为O(N)
+
+```python
+class Solution(object):
+ def minMalwareSpread(self, graph, initial):
+ """
+ :type graph: List[List[int]]
+ :type initial: List[int]
+ :rtype: int
+ """
+ def find(x):
+ while x != uf[x]:
+ uf[x] = uf[uf[x]]
+ x = uf[x]
+ return uf[x]
+
+ def union(x, y):
+ x_root = find(x)
+ y_root = find(y)
+ uf[x_root] = y_root
+
+ uf = [i for i in range(len(graph))]
+ for i in range(len(graph)):
+ for j in range(i+1, len(graph)):
+ if graph[i][j]:
+ union(i, j)
+
+ lookup, dup = {}, {}
+ for i in range(len(graph)):
+ root = find(i)
+ lookup[root] = lookup.get(root, 0) + 1
+ if i in initial: # 这里是算一下每个initial里面的元素所在的联通分量里面包含的其他的initial元素的个数
+ dup[root] = dup.get(root, -1) + 1 # 这里默认值是-1就代表不把自己包含进去了,算的是所有其他initial元素的个数
+
+ component_sizes_of_initial = [lookup[find(ini)]-dup[find(ini)] for ini in initial]
+ max_component_size = max(component_sizes_of_initial)
+
+ res = []
+ for i in range(len(initial)):
+ if component_sizes_of_initial[i] == max_component_size:
+ res.append(initial[i])
+ return min(res)
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/925._Long_Pressed_Name.md b/docs/Leetcode_Solutions/Python/925._Long_Pressed_Name.md
new file mode 100644
index 000000000..dd430823a
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/925._Long_Pressed_Name.md
@@ -0,0 +1,110 @@
+# 925. Long Pressed Name
+
+**难度: Easy**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/long-pressed-name/description/
+
+> 内容描述
+
+```
+Your friend is typing his name into a keyboard. Sometimes, when typing a character c, the key might get long pressed, and the character will be typed 1 or more times.
+
+You examine the typed characters of the keyboard. Return True if it is possible that it was your friends name, with some characters (possibly none) being long pressed.
+
+
+
+Example 1:
+
+Input: name = "alex", typed = "aaleex"
+Output: true
+Explanation: 'a' and 'e' in 'alex' were long pressed.
+Example 2:
+
+Input: name = "saeed", typed = "ssaaedd"
+Output: false
+Explanation: 'e' must have been pressed twice, but it wasn't in the typed output.
+Example 3:
+
+Input: name = "leelee", typed = "lleeelee"
+Output: true
+Example 4:
+
+Input: name = "laiden", typed = "laiden"
+Output: true
+Explanation: It's not necessary to long press any character.
+
+
+Note:
+
+name.length <= 1000
+typed.length <= 1000
+The characters of name and typed are lowercase letters.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(max(len(name),len(typed)))******- 空间复杂度: O(1)******
+
+
+两个字符串从index为0开始比较
+
+- 如果该字符相同就同时往后挪, i += 1, j += 1
+- 如果该字符不相同,那么
+ - 如果typed的字符和name的前一个字符相等,那么j += 1
+ - 如果typed的字符和name的前一个字符不相等,肯定不行,直接返回False
+- while循环完了,如果 i < len(name),那么说明name没有被比较晚,肯定不行,直接返回False
+- 如果typed还没有完,即j < len(typed),那么如果typed剩下的所有字符不是都与name的最后一个字符相等的话,就说明不行,直接返回False,否则返回True
+
+
+```python
+class Solution(object):
+ def isLongPressedName(self, name, typed):
+ """
+ :type name: str
+ :type typed: str
+ :rtype: bool
+ """
+ i, j = 0, 0
+ prev = None
+
+ while i < len(name) and j < len(typed):
+ if name[i] == typed[j]:
+ prev = name[i]
+ i += 1
+ j += 1
+ else:
+ if typed[j] == prev:
+ j += 1
+ else:
+ return False
+ if i < len(name):
+ return False
+
+ while j < len(typed):
+ if typed[j] != prev:
+ return False
+ else:
+ j += 1
+
+ return True
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/926._Flip_String_to_Monotone_Increasing.md b/docs/Leetcode_Solutions/Python/926._Flip_String_to_Monotone_Increasing.md
new file mode 100644
index 000000000..025c86816
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/926._Flip_String_to_Monotone_Increasing.md
@@ -0,0 +1,151 @@
+# 926. Flip String to Monotone Increasing
+
+**难度: Medium**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/flip-string-to-monotone-increasing/description/
+
+> 内容描述
+
+```
+A string of '0's and '1's is monotone increasing if it consists of some number of '0's (possibly 0), followed by some number of '1's (also possibly 0.)
+
+We are given a string S of '0's and '1's, and we may flip any '0' to a '1' or a '1' to a '0'.
+
+Return the minimum number of flips to make S monotone increasing.
+
+
+
+Example 1:
+
+Input: "00110"
+Output: 1
+Explanation: We flip the last digit to get 00111.
+Example 2:
+
+Input: "010110"
+Output: 2
+Explanation: We flip to get 011111, or alternatively 000111.
+Example 3:
+
+Input: "00011000"
+Output: 2
+Explanation: We flip to get 00000000.
+
+
+Note:
+
+1 <= S.length <= 20000
+S only consists of '0' and '1' characters.
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
+
+
+
+
+
+
+
+我们就这样想吧,要想最后满足要求,我们的字符串S肯定是'000000001111111'的形式,可以全为0还可以全为1
+
+因此我们每种情况都考虑一下,取其中改变次数最小的那个次数,
+
+即让前i个字符都变成0,后面len(S)-i个字符都变成1所需要的次数
+
+
+
+```python
+class Solution(object):
+ def minFlipsMonoIncr(self, S):
+ """
+ :type S: str
+ :rtype: int
+ """
+ if not S or len(S) <= 1:
+ return 0
+ count_0, count_1 = [0] * (len(S)+1), [0] * (len(S)+1)
+ for i, v in enumerate(S):
+ if v == '0':
+ count_0[i+1] = count_0[i] + 1
+ count_1[i+1] = count_1[i]
+ else:
+ count_0[i+1] = count_0[i]
+ count_1[i+1] = count_1[i] + 1
+ res = sys.maxsize
+ for i in range(len(S)+1): # 代表S前面i个字符全都是'0'
+ res = min(res, count_1[i] + count_0[-1] - count_0[i])
+ return res
+```
+
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+跟刚才的思想一样,我们只要把左边的1全部变成0, 右边的0全部变成1,然后取最小的那次就行了
+
+
+```python
+class Solution(object):
+ def minFlipsMonoIncr(self, S):
+ """
+ :type S: str
+ :rtype: int
+ """
+ r0, r1, l0, l1 = 0, 0, 0, 0
+ for i, c in enumerate(S):
+ if c == '0':
+ r0 += 1 # 从idx为0开始,右边有多少个0
+ else:
+ r1 += 1 # 从idx为0开始,右边有多少个1
+ res = r0
+ for i, c in enumerate(S):
+ if c == '0':
+ r0 -= 1
+ l0 += 1
+ else:
+ r1 -= 1
+ l1 += 1
+ res = min(l1 + r0, res) # 此时我们要将左边的1全部变成0,右边的0全部变成1
+ return res
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/927._Three_Equal_Parts.md b/docs/Leetcode_Solutions/Python/927._Three_Equal_Parts.md
new file mode 100644
index 000000000..3c5e65d52
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/927._Three_Equal_Parts.md
@@ -0,0 +1,247 @@
+# 927. Three Equal Parts
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/three-equal-parts/description/
+
+> 内容描述
+
+```
+Given an array A of 0s and 1s, divide the array into 3 non-empty parts such that all of these parts represent the same binary value.
+
+If it is possible, return any [i, j] with i+1 < j, such that:
+
+A[0], A[1], ..., A[i] is the first part;
+A[i+1], A[i+2], ..., A[j-1] is the second part, and
+A[j], A[j+1], ..., A[A.length - 1] is the third part.
+All three parts have equal binary value.
+If it is not possible, return [-1, -1].
+
+Note that the entire part is used when considering what binary value it represents. For example, [1,1,0] represents 6 in decimal, not 3. Also, leading zeros are allowed, so [0,1,1] and [1,1] represent the same value.
+
+
+
+Example 1:
+
+Input: [1,0,1,0,1]
+Output: [0,3]
+Example 2:
+
+Input: [1,1,0,1,1]
+Output: [-1,-1]
+
+
+Note:
+
+3 <= A.length <= 30000
+A[i] == 0 or A[i] == 1
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******
+
+
+
+什么都不说了,我是个智障,不允许任何反驳,上来就无脑写了一个暴力,我就是头铁,我,就是铁头娃!!!
+
+```
+class Solution(object):
+ def threeEqualParts(self, A):
+ """
+ :type A: List[int]
+ :rtype: List[int]
+ """
+ if len(A) < 3:
+ return [-1, -1]
+ for i in range(len(A)-2):
+ for j in range(i+2, len(A)):
+ tmpi, tmpj, tmpk = i, j-1, len(A)-1
+ while tmpi >= 0 and tmpj >= i+1 and tmpk >= j:
+ if A[tmpi] == A[tmpj] == A[tmpk]:
+ tmpi -= 1
+ tmpj -= 1
+ tmpk -= 1
+ else:
+ break
+ if not (tmpi == -1 or tmpj == i or tmpk == j-1):
+ continue
+ while tmpi >= 0:
+ if A[tmpi] == 0:
+ tmpi -= 1
+ else:
+ break
+ if tmpi != -1:
+ continue
+ while tmpj >= i+1:
+ if A[tmpj] == 0:
+ tmpj -= 1
+ else:
+ break
+ if tmpj != i:
+ continue
+ while tmpk >= j:
+ if A[tmpk] == 0:
+ tmpk -= 1
+ else:
+ break
+ if tmpk != j-1:
+ continue
+
+ return [i, j]
+ return [-1,-1]
+```
+
+
+
+> 思路 2
+******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
+
+
+
+三个部分相等,那么三个部分1的数量肯定要相等,立马变成O(1)
+
+但是这里要注意三个比较重要的点
+
+1. 如果A的长度小于3,直接返回[-1,-1]
+2. 如果A中全是0,直接返回[0,2]
+3. 如果A的末尾有很多连续的0的时候,我们要注意在part1和part2后面也要加上那么多个0, 例如:输入为[1,0,0,0,1,0,0,0,1,0,0]
+应该分为的三个部分分别是```part1 = [1,0,0], part2 = [0,1,0,0], part3 = [0,1,0,0]```,
+而不是```part1 = [1], part2 = [0,0,0,1], part3 = [0,0,0,1,0,0]```。因为A末尾有2个连续的0,所以每个part后面都要有2个连续的0
+
+```python
+class Solution(object):
+ def threeEqualParts(self, A):
+ """
+ :type A: List[int]
+ :rtype: List[int]
+ """
+ if len(A) < 3:
+ return [-1, -1]
+
+ count_one = 0
+ for i in A:
+ if i == 1:
+ count_one += 1
+
+ if count_one == 0:
+ return [0, 2]
+
+ if count_one % 3 != 0:
+ return [-1, -1]
+
+ idx, count_end_zero = len(A) - 1, 0
+ while A[idx] == 0:
+ count_end_zero += 1
+ idx -= 1
+
+ part1_end, part2_end, count = 0, 0
+ for idx, num in enumerate(A):
+ if num == 1:
+ count += 1
+ if count == count_one / 3:
+ part1_end = idx
+ elif count == 2 * count_one / 3:
+ part2_end = idx
+ break
+
+ i, j = part1_end+count_end_zero, part2_end+count_end_zero+1
+ tmpi, tmpj, tmpk = i, j-1, len(A)-1
+
+ while tmpi >= 0 and tmpj >= i+1 and tmpk >= j:
+ if A[tmpi] == A[tmpj] == A[tmpk]:
+ tmpi -= 1
+ tmpj -= 1
+ tmpk -= 1
+ else:
+ break
+ if not (tmpi == -1 or tmpj == i or tmpk == j-1):
+ return [-1,-1]
+ while tmpi >= 0:
+ if A[tmpi] == 0:
+ tmpi -= 1
+ else:
+ break
+ if tmpi != -1:
+ return [-1,-1]
+ while tmpj >= i+1:
+ if A[tmpj] == 0:
+ tmpj -= 1
+ else:
+ break
+ if tmpj != i:
+ return [-1,-1]
+ while tmpk >= j:
+ if A[tmpk] == 0:
+ tmpk -= 1
+ else:
+ break
+ if tmpk != j-1:
+ return [-1,-1]
+
+ return [i, j]
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/928._Minimize_Malware_Spread_II.md b/docs/Leetcode_Solutions/Python/928._Minimize_Malware_Spread_II.md
new file mode 100644
index 000000000..14410d7b3
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/928._Minimize_Malware_Spread_II.md
@@ -0,0 +1,158 @@
+# 928. Minimize Malware Spread II
+
+**难度: Hard**
+
+## 刷题内容
+
+> 原题连接
+
+* https://leetcode.com/problems/minimize-malware-spread-ii/description/
+
+> 内容描述
+
+```
+(This problem is the same as Minimize Malware Spread, with the differences bolded.)
+
+In a network of nodes, each node i is directly connected to another node j if and only if graph[i][j] = 1.
+
+Some nodes initial are initially infected by malware. Whenever two nodes are directly connected and at least one of those two nodes is infected by malware, both nodes will be infected by malware. This spread of malware will continue until no more nodes can be infected in this manner.
+
+Suppose M(initial) is the final number of nodes infected with malware in the entire network, after the spread of malware stops.
+
+We will remove one node from the initial list, completely removing it and any connections from this node to any other node. Return the node that if removed, would minimize M(initial). If multiple nodes could be removed to minimize M(initial), return such a node with the smallest index.
+
+
+
+Example 1:
+
+Input: graph = [[1,1,0],[1,1,0],[0,0,1]], initial = [0,1]
+Output: 0
+Example 2:
+
+Input: graph = [[1,1,0],[1,1,1],[0,1,1]], initial = [0,1]
+Output: 1
+Example 3:
+
+Input: graph = [[1,1,0,0],[1,1,1,0],[0,1,1,1],[0,0,1,1]], initial = [0,1]
+Output: 1
+
+
+Note:
+
+1 < graph.length = graph[0].length <= 300
+0 <= graph[i][j] == graph[j][i] <= 1
+graph[i][i] = 1
+1 <= initial.length < graph.length
+0 <= initial[i] < graph.length
+```
+
+## 解题方案
+
+> 思路 1
+******- 时间复杂度: O(len(graph)^2 * len(initial))******- 空间复杂度: O(len(graph))******
+
+
+
+这道题跟第924题的区别在于924题目中的这句话:
+
+```
+Note that if a node was removed from the initial list of infected nodes,
+it may still be infected later as a result of the malware spread.
+```
+
+以及928题目里面的这句话:
+
+```
+We will remove one node from the initial list, completely removing it and any connections from this node to any other node.
+```
+
+
+因此如果928里面一个initial的node被删除掉之后,那么通过这个node去感染别的node也不可以了,相当于直接隔离了这个点。
+
+因此我们就模拟这个过程,对initial做一个遍历,每次隔离掉一个点,然后看隔离掉哪个点所导致最终的infects最少,就返回哪个点
+
+
+
+```python
+class Solution(object):
+ def minMalwareSpread(self, graph, initial):
+ """
+ :type graph: List[List[int]]
+ :type initial: List[int]
+ :rtype: int
+ """
+ def find(x):
+ while x != uf[x]:
+ uf[x] = uf[uf[x]]
+ x = uf[x]
+ return uf[x]
+
+ def union(x, y):
+ x_root = find(x)
+ y_root = find(y)
+ uf[x_root] = y_root
+ size[y_root] += size[x_root]
+
+ def connected(x, y):
+ return find(x) == find(y)
+
+ def helper(graph, initial, node):
+ for i in range(len(graph)):
+ for j in range(i+1, len(graph)):
+ if graph[i][j] and i != node and j != node:
+ if not connected(i, j): # 没联通才联通,避免重复更新size列表
+ union(i, j)
+ seen = [False] * len(graph)
+ infects = 0
+ for ini in initial:
+ if ini == -1: # 代表这个点被隔离了
+ continue
+ root = find(ini)
+ if seen[root]: # 避免重复计算感染数量
+ continue
+ seen[root] = True
+ infects += size[root] # 只要有initial里面元素在该联通分量里面,这整个联通分量都会被感染
+ return infects
+
+
+ initial.sort() # 这样最后会返回最小的index
+ res, min_ = initial[0], sys.maxsize
+ uf = [i for i in range(len(graph))] # 定义我们的uf与size列表
+ size = [1] * len(graph)
+ for idx, node in enumerate(initial):
+ initial[idx] = -1 # 隔离这个点
+ infects = helper(graph, initial, node)
+ uf = [i for i in range(len(graph))] # 需要reset我们的uf与size列表
+ size = [1] * len(graph)
+ if infects < min_:
+ min_ = infects
+ res = node
+ initial[idx] = node # 恢复这个点
+ return res
+```
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/README.md b/docs/Leetcode_Solutions/Python/README.md
new file mode 100644
index 000000000..fb996b73a
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/README.md
@@ -0,0 +1 @@
+# Leetcode solutions and summary!
diff --git a/docs/Leetcode_Solutions/Python/Summary/Binary Search.md b/docs/Leetcode_Solutions/Python/Summary/Binary Search.md
new file mode 100644
index 000000000..7c9449c09
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/Summary/Binary Search.md
@@ -0,0 +1,131 @@
+### Binary Search
+
+
+```python
+def binarySearch(nums, target):
+ l, r = 0, len(nums) -1
+ while l <= r:
+ mid = l + ((r-l) >> 1)
+ if nums[mid] > target:
+ r = mid - 1
+ elif nums[mid] < target:
+ l = mid + 1
+ else:
+ return mid
+ return -1
+```
+
+
+wisdompeak大佬说,
+
+标准模板就两套:
+```
+while (left 1) {
+ int mid = (left + right) / 2;
+ if (A[mid] == k) {
+ return mid;
+ } else if (A[mid] < k) {
+ left = mid;
+ } else {
+ right = mid;
+ }
+ }
+ return -1;
+}
+```
+
+- 满足judge(x)=true的最大值
+
+```c++
+bool judge(int x) {}
+int bsearch(int min, int max) {
+ int left = min, right = max;
+ //这里为什么要right++呢,因为我们求的是上界,二分区间中,left要满足f(x),并且尽可能大
+ //需要要保证left在[min, max]遍历到
+ //终止条件是right - left > 1,所以right需要+1确保left能取到min
+ right++;
+ while (right - left > 1) {
+ int mid = (left + right) / 2;
+ if (judge(mid)) {
+ left = mid;
+ } else {
+ right = mid;
+ }
+ }
+ return left;
+}
+```
+
+- 满足judge(x)=true的最小值
+
+```c++
+bool judge(int x) {}
+int bsearch(int min, int max) {
+ int left = min, right = max;
+ //这里为什么要left--呢,因为我们求的是下界,二分区间中,right要满足f(x),并且尽可能小
+ //需要要保证right在[min, max]遍历到
+ //终止条件是right - left > 1,所以left需要-1确保right能取到max
+ left--;
+ while (right - left > 1) {
+ int mid = (left + right) / 2;
+ if (judge(mid)) {
+ right = mid;
+ } else {
+ left = mid;
+ }
+ }
+ return right;
+}
+```
+
+- 浮点数,求f(x)在[min,max]的零点
+
+```c++
+const double EPS = 1e-8;
+double cal(double x) {} //假定是单调增
+//这里需要保证区间有零点
+double bsearch(double min, double max) {
+ double left = min, right = max;
+ while (right - left > EPS) {
+ double mid = (left + right) / 2;
+ if (A[mid] == 0) {
+ return mid;
+ } else if (cal(mid) < 0) {
+ left = mid;
+ } else {
+ right = mid;
+ }
+ }
+ return (left + right) / 2;
+}
+```
\ No newline at end of file
diff --git "a/docs/Leetcode_Solutions/Python/Summary/DFS\345\222\214BFS.md" "b/docs/Leetcode_Solutions/Python/Summary/DFS\345\222\214BFS.md"
new file mode 100644
index 000000000..6054330dd
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/DFS\345\222\214BFS.md"
@@ -0,0 +1,145 @@
+# Graph Search,DFS, BFS
+
+
+
+## DFS/BFS
+
+可以让stack/queue记录更多一些的东西,因为反正stack/queue更像通用结构
+
+```
+ A
+ / \
+ C B
+ \ / \
+ \ D E
+ \ /
+ F
+
+
+graph = {'A': set(['B', 'C']),
+ 'B': set(['A', 'D', 'E']),
+ 'C': set(['A', 'F']),
+ 'D': set(['B']),
+ 'E': set(['B', 'F']),
+ 'F': set(['C', 'E'])}
+```
+### DFS
+
+迭代版本
+```python
+def dfs(graph, start): # iterative
+ visited, stack = [], [start]
+ while stack:
+ vertex = stack.pop()
+ if vertex not in visited:
+ visited.append(vertex)
+ stack.extend(graph[vertex] - set(visited))
+ return visited
+print(dfs(graph, 'A')) # ['A', 'C', 'F', 'E', 'B', 'D'] 这只是其中一种答案
+```
+
+递归版本
+```python
+def dfs(graph, start, visited=None): # recursive
+ if visited is None:
+ visited = []
+ print('visiting', start)
+ visited.append(start)
+ for next in graph[start]:
+ if next not in visited:
+ dfs(graph, next, visited)
+ return visited
+print(dfs(graph, 'A')) # ['A', 'C', 'F', 'E', 'B', 'D'] 这只是其中一种答案
+```
+
+
+迭代打印出从出发点到终点的路径
+```python
+def dfs_paths(graph, start, goal): # iterative
+ stack = [(start, [start])]
+ while stack:
+ (vertex, path) = stack.pop()
+ for next in graph[vertex] - set(path):
+ if next == goal:
+ yield path + [next]
+ else:
+ stack.append((next, path + [next]))
+print(list(dfs_paths(graph, 'A', 'F'))) # [['A', 'C', 'F'], ['A', 'B', 'E', 'F']]
+```
+
+递归打印出从出发点到终点的路径
+```python
+def dfs_paths(graph, start, goal, path=None): # recursive
+ if path is None:
+ path = [start]
+ if start == goal:
+ yield path
+ for next in graph[start] - set(path):
+ yield from dfs_paths(graph, next, goal, path + [next])
+print(list(dfs_paths(graph, 'C', 'F'))) # [['C', 'A', 'B', 'E', 'F'], ['C', 'F']]
+```
+
+### BFS
+
+迭代版本,和DFS唯一的区别就是pop(0)而不是pop()
+```python
+def bfs(graph, start): # iterative
+ visited, queue = [], [start]
+ while queue:
+ vertex = queue.pop(0)
+ if vertex not in visited:
+ visited.append(vertex)
+ queue.extend(graph[vertex] - set(visited))
+ return visited
+print(bfs(graph, 'A')) # ['A', 'C', 'B', 'F', 'D', 'E']
+```
+
+
+返回两点之间的所有路径,第一个一定是最短的
+```python
+def bfs_paths(graph, start, goal):
+ queue = [(start, [start])]
+ while queue:
+ (vertex, path) = queue.pop(0)
+ for next in graph[vertex] - set(path):
+ if next == goal:
+ yield path + [next]
+ else:
+ queue.append((next, path + [next]))
+print(list(bfs_paths(graph, 'A', 'F'))) # [['A', 'C', 'F'], ['A', 'B', 'E', 'F']]
+```
+
+知道了这个特性,最短路径就很好搞了
+```python
+def bfs_paths(graph, start, goal):
+ queue = [(start, [start])]
+ while queue:
+ (vertex, path) = queue.pop(0)
+ for next in graph[vertex] - set(path):
+ if next == goal:
+ yield path + [next]
+ else:
+ queue.append((next, path + [next]))
+def shortest_path(graph, start, goal):
+ try:
+ return next(bfs_paths(graph, start, goal))
+ except StopIteration:
+ return None
+print(shortest_path(graph, 'A', 'F')) # ['A', 'C', 'F']
+```
+
+#### Improvement/Follow up
+
+1. 一旦BFS/DFS与更具体的,更有特性的data structure结合起来,比如binary search tree,那么BFS/DFS会针对这个tree traversal显得更有特性。
+2. it's worth mentioning that there is an optimized queue object in the collections module called [deque](https://docs.python.org/2/library/collections.html#collections.deque)) for which removing items from the beginning ( or popleft ) takes constant time as opposed to O(n) time for lists.
+
+
+
+### Resources
+
+1. [Depth-and Breadth-First Search](https://jeremykun.com/2013/01/22/depth-and-breadth-first-search/)
+2. [Edd Mann](http://eddmann.com/posts/depth-first-search-and-breadth-first-search-in-python/)
+3. [graph - Depth-first search in Python](https://codereview.stackexchange.com/questions/78577/depth-first-search-in-python)
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/Summary/Data Structure and Algorthim Review.md b/docs/Leetcode_Solutions/Python/Summary/Data Structure and Algorthim Review.md
new file mode 100644
index 000000000..61c9c7d68
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/Summary/Data Structure and Algorthim Review.md
@@ -0,0 +1,101 @@
+
+
+### Data Structure and Algorthim Review
+
+
+
+- [x] Binary Search Tree
+
+ - [x] 插入
+
+ • 如果树为空,创建一个叶子节点,令该节点的key = k;
+ • 如果k小于根节点的key,将它插入到左子树中;
+ • 如果k大于根节点的key,将它插入到右子树中。
+
+ - [x] 遍历
+
+ • 前序: 根,左,右
+
+ • 中序:左,根,右 **有序**
+
+ • 后序:左,右,根
+
+ - [x] 搜索
+
+ - look up : 是否存在
+
+ • 如果树为空,搜索失败;
+ • 如果根节点的key等于待搜索的值,搜索成功,返回根节点作为结果;
+ • 如果待搜索的值小于根节点的key,继续在左子树中递归搜索;
+ • 否则,待搜索的值大于根节点的key,继续在右子树中递归搜索。
+
+ - 最大元素和最小元素
+
+ • 最右和最左
+
+ - 前驱(Successor)和后继(predecessor)
+
+ 给定元素x,它的后继元素y是满足y > x的最小值
+
+ • 如果x所在的节点有一个非空的右子树,则右子树中的最小值就是答案
+
+ • 否则我们需要向上回溯,找到最近的一个祖先,使得该祖先的左侧孩子,也为x的祖 先。
+
+
+ - [x] 删除
+
+ • 如果x没有子节点,或者只有一个孩子,直接将x“切下”;
+
+ • 否则,x有两个孩子,我们用其右子树中的最小值替换掉x,然后将右子树中的这一最小值“切掉”。
+
+
+
+
+
+
+- [x] 递归
+ - [x] 入门
+
+ - 回文
+ - 阶乘 factorial, 慕指数
+ - 分形
+ - Tower of Hanoi
+
+ - [x] 排列 Permutation
+
+ - [x] 子集 Subsets
+
+ - [ ] backtracking
+
+
+- [x] dynamic programming
+
+ - coin change
+
+ - longest common subsequence
+
+ - edit distance
+
+
+
+
+
+
+-[ ] majority element
+
+
+
+- [ ] 随机
+ - 水塘抽样
+ - 洗牌
+
+
+-[ ] 荷兰旗问题
+
+
+-[ ] quick select
+
+
+-[ ] median of two sorted array
+-[ ] regular expression
+
diff --git a/docs/Leetcode_Solutions/Python/Summary/Dynamic Programming.md b/docs/Leetcode_Solutions/Python/Summary/Dynamic Programming.md
new file mode 100644
index 000000000..102d032c3
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/Summary/Dynamic Programming.md
@@ -0,0 +1,48 @@
+### Dynamic Programming
+
+
+
+- Fibonacci Numbers
+- Shortest Path (no cycles)
+
+
+
+
+
+
+
+- subproblems
+
+- guessing
+
+- relate subproblems
+
+- recurse & memoize (bulid DP table)
+
+- solve original problem
+
+
+
+
+
+
+
+
+
+
+
+
+感觉DP有几类:
+
+- 容易写出递推公式的
+
+- 画表更容易理解的
+
+
+
+* DP ≈ “controlled brute force”
+
+* DP ≈ recursion + re-use
+
+
+
diff --git "a/docs/Leetcode_Solutions/Python/Summary/Introduction to String Searching Algorithms \342\200\223 topcoder.pdf" "b/docs/Leetcode_Solutions/Python/Summary/Introduction to String Searching Algorithms \342\200\223 topcoder.pdf"
new file mode 100644
index 000000000..110950bf9
Binary files /dev/null and "b/docs/Leetcode_Solutions/Python/Summary/Introduction to String Searching Algorithms \342\200\223 topcoder.pdf" differ
diff --git "a/docs/Leetcode_Solutions/Python/Summary/Java\345\220\204\347\247\215\347\261\273\345\236\213\347\232\204\350\275\254\346\215\242.md" "b/docs/Leetcode_Solutions/Python/Summary/Java\345\220\204\347\247\215\347\261\273\345\236\213\347\232\204\350\275\254\346\215\242.md"
new file mode 100644
index 000000000..c1d3e5522
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/Java\345\220\204\347\247\215\347\261\273\345\236\213\347\232\204\350\275\254\346\215\242.md"
@@ -0,0 +1,239 @@
+之前在写java程序的时候,经常会遇到很多的需要需要转换基础数据类型的情况,然后我就一直去记录这些情况,今天做了一下总结,当然转换的方法肯定不止我写的这些,有的我可能只会写其中的一种,以后再遇到其他的情况的话,我会慢慢来补充,希望这篇文章会对大家能有所帮助。
+
+------
+
+# String的转换
+
+首先介绍一下String类型的转换,一般遇到的情况可能会有以下几种:Strng转int,String转long,String转byte数组,String转float,下面主要介绍这四种情况。
+
+## String转int
+
+把String类型转换为int类型,常用的有以下三种方法:
+
+```
+public class StringToInt {
+ public static void main(String[] args) {
+ String number = "123456";
+ int num1 = Integer.parseInt(number);//使用Integer的parseInt方法
+ int num2 = new Integer(number);//强制转换
+ int num3 = Integer.valueOf(number).intValue();//先转Integer类型,再调用intValue()转为int
+ }
+}
+```
+
+## String转long
+
+把String类型转换为long类型的方法跟上面的方法类似。
+
+```
+public class StringToLong {
+ public static void main(String[] args) {
+ String number = "1234567890";
+ long num1 = Long.parseLong(number);//调用Long类型的parseLong方法
+ long num2 = new Long(number);//强制转换
+ long num3 = Long.valueOf(number).longValue();//先转换Long类型,再使用longValue方法转为long
+ }
+}
+```
+
+## String转float
+
+把String类型转换为float类型的方法也跟上面的类似。
+
+```
+public class StringToFloat {
+ public static void main(String[] args) {
+ String number = "1234.202";
+ float num1 = Float.parseFloat(number);//调用Float的parseFloat方法
+ float num2 = new Float(number);//强制转换
+ float num3 = Float.valueOf(number).floatValue();//先转为Float类型再使用floatValue转为float
+ }
+}
+```
+
+## String转byte[]
+
+String类型转byte数组方法一般使用String类自带的`getBytes()`方法。
+
+```
+public class StringToByte {
+ public static void main(String[] args) {
+ byte[] num = new byte[200];
+ String number = "1234567890";
+ num = number.getBytes();
+ }
+}
+```
+
+这里补充一个path类型转换为String类型的方法:
+
+```
+String fileName=path.getFileName().toString();
+```
+
+------
+
+# long类型转换
+
+long类型的转换,这一部分用的情况也很多,下面介绍几种常见的情况。
+
+## long转String
+
+long类型转String类型,这里主要介绍三种方法:
+
+```
+public class LongToString {
+ public static void main(String[] args) {
+ long number = 1234567890l;
+ String num1 = Long.toString(number);//Long的tostring方法
+ String num2 = String.valueOf(number);//使用String的valueOf方法
+ String num3 = "" + number;//这个应该属于强制转换吧
+ }
+}
+```
+
+## long转int
+
+long类型转换为int类型,这里也主要介绍三种方法:
+
+```
+public class LongToInt {
+ public static void main(String[] args) {
+ long number = 121121121l;
+ int num1 = (int) number;// 强制类型转换
+ int num2 = new Long(number).intValue();// 调用intValue方法
+ int num3 = Integer.parseInt(String.valueOf(number));// 先把long转换位字符串String,然后转换为Integer
+ }
+}
+```
+
+## long与byte数组的相互转换
+
+一直都感觉byte数组转换比较繁琐,这里也不再叙述,我就给出一篇别人的博客让大家作为参考吧,这里面byte数组与多种数据类型的转换——[ java Byte和各数据类型(short,int,long,float,double)之间的转换](http://blog.csdn.net/cshichao/article/details/9813973)
+
+------
+
+# int类型的转换
+
+int类型的转换也是我们经常使用的情况,下面也主要介绍几种常见的情况。
+
+## int转String
+
+int类型转换为String类型与long转String的类似,一般也有以下三种方法。
+
+```
+public class IntToString {
+ public static void main(String[] args) {
+ int number = 121121;
+ String num1 = Integer.toString(number);//使用Integer的toString方法
+ String num2 = String.valueOf(number);//使用String的valueOf方法
+ String num3 = "" + number;//也是强制转换吧
+ }
+}
+```
+
+## int与Byte的相互转换
+
+关于int类型与byte[]数组的转换,一般情况下,我们使用条件都是在这里转换过来,在另外一个地方就要转换回来,这里介绍两种int与byte数组互相转换的方式。
+
+```
+//int类型转换为byte[]数组
+public static byte[] intToByteArray(int i) {
+ byte[] result = new byte[4];
+ // 由高位到低位
+ result[0] = (byte) ((i >> 24) & 0xFF);
+ result[1] = (byte) ((i >> 16) & 0xFF);
+ result[2] = (byte) ((i >> 8) & 0xFF);
+ result[3] = (byte) (i & 0xFF);
+ return result;
+}
+
+//byte数组转换为int类型
+public static int byteArrayToInt(byte[] bytes) {
+ int value = 0;
+ // 由高位到低位
+ for (int i = 0; i < 4; i++) {
+ int shift = (4 - 1 - i) * 8;
+ value += (bytes[i] & 0x000000FF) << shift;// 往高位游
+ }
+ return value;
+}
+```
+
+还有一种为:
+
+```
+//int类型转换为byte[]数组
+public static byte[] intToByteArray(int x) {
+ byte[] bb = new byte[4];
+ bb[3] = (byte) (x >> 24);
+ bb[2] = (byte) (x >> 16);
+ bb[1] = (byte) (x >> 8);
+ bb[0] = (byte) (x >> 0);
+ return bb;
+}
+
+//byte数组转换为int类型
+public static int byteArrayToInt(byte[] bb) {
+ return (int) ((((bb[3] & 0xff) << 24) | ((bb[2] & 0xff) << 16) | ((bb[1] & 0xff) << 8) | ((bb[0] & 0xff) << 0)));
+}
+```
+
+## int转long
+
+int类型转换为long类型的情况并不是大多,这里主要接收几种转换方法:
+
+```
+public class IntToLong {
+ public static void main(String[] args) {
+ int number = 123111;
+ long num1 = (long) number;//强制
+ long num2 = Long.parseLong(new Integer(number).toString());//先转String再进行转换
+ long num3 = Long.valueOf(number);
+ }
+}
+```
+
+## int转Interger
+
+int类型转换为Interger类型的情况,我是基本上每怎么遇到过,在这里也上网查询一些资料找到了两种方法。
+
+```
+public class IntToInterge {
+ public static void main(String[] args) {
+ int number = 123456;
+ Integer num1 = Integer.valueOf(number);
+ Integer num2 = new Integer(number);
+ }
+}
+```
+
+------
+
+# byte数组的转换
+
+关于byte数组的转换,上面有几个都是它们只见相互转换的,所以这里就不再介绍那么多,只介绍一个byte数组转换String类型的方法,其他的类型可以通过String类型再进行转换。
+
+byte数组转String类型的方法经常用的可能就是下面这种方法。
+
+```
+public class ByteToString {
+ public static void main(String[] args) {
+ byte[] number = "121121".getBytes();
+ String num1 = new String(number);
+ }
+}
+```
+
+------
+
+最后简单补充以下Java基本数据类型的一些知识:
+
+| 类型 | 字节数 | 类名称 | 范围 |
+| ------ | ---- | -------- | ---------------------------------------- |
+| int | 4字节 | Interger | -2147483648 ~ 2147483647 |
+| short | 2字节 | Short | -32768 ~ 32767 |
+| long | 8字节 | Long | -9223372036854775808 ~ 9223372036854775807 |
+| byte | 1字节 | Byte | -128 ~ 127 |
+| float | 4字节 | Float | |
+| double | 8字节 | Double | |
\ No newline at end of file
diff --git "a/docs/Leetcode_Solutions/Python/Summary/LinkedList\346\212\200\345\267\247.md" "b/docs/Leetcode_Solutions/Python/Summary/LinkedList\346\212\200\345\267\247.md"
new file mode 100644
index 000000000..677a083a2
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/LinkedList\346\212\200\345\267\247.md"
@@ -0,0 +1,118 @@
+# LinkedList
+
+结点定义如下:
+
+ class ListNode(object):
+ def __init__(self, x):
+ self.val = x
+ self.next = None
+
+
+可以使用的技巧包括:
+
+
+## Dummy head
+
+有的时候因为边界条件,需要判定是否是list的head,因为处理起来会有些不同,而创造一个dummy head则可以极大的解决一些问题。
+
+```
+ dummy = ListNode(-1)
+ dummy.next = head
+```
+
+## 双指针
+
+- 19. Remove Nth Node From End of List
+
+两个指针p,q, q先走n步,然后p和q一起走,直到q走到结点,删除p.next解决。
+
+理解: 先走了n步,q始终在p前方n个,这样q走到末尾,p的下一个则是距离尾端n个的,画个图还是容易理解。
+
+
+- 160. Intersection of Two Linked Lists
+
+如果两个linkedlist有intersection的话,可以看到,其实如果一开始我们就走到b2的话,那么我们就可以两个pointer一个一个的对比,到哪一个地址一样,接下来就是intersection部分。
+
+就一开始把长的那条list走掉多余部分。
+还有这里保证了是无环的状况
+
+
+
+```
+A: a1 → a2
+ ↘
+ c1 → c2 → c3
+ ↗
+B: b1 → b2 → b3
+```
+
+
+## 快慢指针
+
+- 141. Linked List Cycle
+
+用两个指针,一个每次走两步,一个每次走一步,如果慢的最终和快的相遇,那么说明有环,否则没有环,直观的理解是如果两个跑的速度不一的人进操场跑步,那么最终慢的会追上快的.
+
+
+
+## Reverse Linked List
+
+- 206. Reverse Linked List
+
+loop版本用prev, cur ,nxt 三个指针过一遍,recursion版本如下,可以再消化消化
+
+```
+class Solution(object):
+ def reverseList(self, head):
+ """
+ :type head: ListNode
+ :rtype: ListNode
+ """
+ return self.doReverse(head, None)
+
+
+ def doReverse(self, head, newHead):
+ if head == None:
+ return newHead
+ nxt = head.next
+ head.next = newHead
+ return self.doReverse(nxt, head)
+```
+
+
+## 寻找LinkedList中间项
+
+依旧使用双指针,快慢指针:快指针每次走两步,慢指针每次走一步,快指针如果到头了,那么慢指针也会在中间了,这个中间可以考量,如果是奇数的话必然是中间。
+
+如果是偶数则是偏前面的中间一项
+
+```
+1 -> 2 -> 3 -> 4: 2
+1 -> 2 -> 3 -> 4 -> 5 -> 6 : 3
+1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 : 4
+
+```
+
+算法:
+
+```
+
+def findMid(head):
+ if head == None or head.next == None:
+ return head
+
+ slow = head
+ fast = head
+
+ while fast.next and fast.next.next:
+ slow = slow.next
+ fast = fast.next.next
+
+ return slow
+```
+
+
+
+
+
+
diff --git a/docs/Leetcode_Solutions/Python/Summary/Maximal Square.pdf b/docs/Leetcode_Solutions/Python/Summary/Maximal Square.pdf
new file mode 100644
index 000000000..235cd3b86
Binary files /dev/null and b/docs/Leetcode_Solutions/Python/Summary/Maximal Square.pdf differ
diff --git "a/docs/Leetcode_Solutions/Python/Summary/Python\345\210\267\351\242\230\346\212\200\345\267\247\347\254\224\350\256\260.md" "b/docs/Leetcode_Solutions/Python/Summary/Python\345\210\267\351\242\230\346\212\200\345\267\247\347\254\224\350\256\260.md"
new file mode 100644
index 000000000..8e110020c
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/Python\345\210\267\351\242\230\346\212\200\345\267\247\347\254\224\350\256\260.md"
@@ -0,0 +1,242 @@
+
+### python有无数奇技淫巧和许多人不知道的秘密,这里用简洁的语言一条条表述出来,不断更新, 大家一起贡献!
+```python
+# 1. python 排序
+# 用lst.sort() 而不是nlst = sorted(lst), 区别在于lst.sort()是 in-place sort,改变lst, sorted会创建新list,成本比较高。
+```
+```python
+# 2. xrange和range的区别
+# range会产生list存在memory中,xrange更像是生成器,generate on demand所以有的时候xrange会更快
+```
+```python
+# 3. python处理矩阵
+row = len(matrix)
+col = len(matrix[0]) if row else 0
+# 这样写通用的原因是, 当matrix = [], row = 0, col = 0
+```
+```python
+# 4. python列表生成式
+lst = [0 for i in range(3)] # lst = [0,0,0]
+lst = [[0 for i in range(3)] for j in range(2)] # lst = [[0, 0, 0], [0, 0, 0]]
+# 下面这种写法危险:
+# lst1 = [ 0, 0, 0 ]
+# lst2 = [lst1] * 2 # lst2 = [ [0,0,0] , [0,0,0] ]
+# lst2[0][0] = 1 # lst2 = [ [1,0,0], [1,0,0]]
+# 因为lst1是object,改一个相当于全改, 这样写会踩坑
+```
+```python
+# 5. D.get(key, default)
+# 如果这个key 没有在dict里面,给它一个默认值:
+D = {}
+if 1 in D:
+ val = D[1]
+else :
+ val = 0
+# 等同于这样写:
+val = D.get(1, 0)
+```
+```python
+# 6. 字典赋值
+if key in D:
+ D[key].append(1)
+else :
+ D[key] = []
+```
+```python
+# 7. 字符串反转和列表反转
+# python字符串没有reverse函数,只能str[::-1]
+string[::-1]
+# python的list可以直接reverse(),因此也可以借用这个特性
+"".join([string].reverse())
+
+测试了一下3种列表反转的速度
+tmp = [i for i in range(100000)]
+
+import datetime
+starttime = datetime.datetime.now()
+
+for i in range(100000):
+ tmp = tmp[::-1]
+endtime = datetime.datetime.now()
+print((endtime - starttime))
+
+starttime = datetime.datetime.now()
+for i in range(100000):
+ tmp = list(reversed(tmp))
+endtime = datetime.datetime.now()
+print((endtime - starttime))
+
+starttime = datetime.datetime.now()
+for i in range(100000):
+ tmp.reverse()
+endtime = datetime.datetime.now()
+print((endtime - starttime))
+
+
+
+
+输出:
+0:00:33.486971
+0:01:43.027222
+0:00:03.958400
+
+说明in-place反转最快,但是这样改变了原list,因此在不能改动原list的情况下,我们用分片会更好
+```
+```python
+# 8. 快速统计
+import collections
+lst = [1, 1, 1, 2, 3, 4, 5, 5]
+collections.Counter(lst) # Counter({1: 3, 5: 2, 2: 1, 3: 1, 4: 1})
+```
+```python
+# 9. python自带小顶堆heapq
+# Python有built-in heap, 默认min heap.
+heapq.heappush(heap, item) # 把item添加到heap中(heap是一个列表)
+
+heapq.heappop(heap) # 把堆顶元素弹出,返回的就是堆顶
+
+heapq.heappushpop(heap, item) # 先把item加入到堆中,然后再pop,比heappush()再heappop()要快得多
+
+heapq.heapreplace(heap, item) # 先pop,然后再把item加入到堆中,比heappop()再heappush()要快得多
+
+heapq.heapify(x) # 将列表x进行堆调整,默认的是小顶堆
+
+heapq.merge(*iterables) # 将多个列表合并,并进行堆调整,返回的是合并后的列表的迭代器
+
+heapq.nlargest(n, iterable, key=None) # 返回最大的n个元素(Top-K问题)
+
+heapq.nsmallest(n, iterable, key=None) # 返回最小的n个元素(Top-K问题)
+
+# 如何来用它实现max heap呢,看到过一个有意思的方法是把key取负,比如把100变成-100,5变成-5
+
+import heapq
+mylist = [1, 2, 3, 4, 5, 10, 9, 8, 7, 6]
+largest = heapq.nlargest(3, mylist) # [10, 9, 8]
+smallest = heapq.nsmallest(3, mylist) # [1, 2, 3]
+```
+```python
+# 10. 双端队列deque [http://stackoverflow.com/questions/4098179/anyone-know-this-python-data-structure]
+# 可以很简单的.popleft(), .popright(), .appendleft(), .appendright(),最关键的是时间是O(1), 而用list来模拟队列是O(n)的时间复杂度
+# 还有很好用的rotate函数,
+# 一个简单的跑马灯程序
+import sys
+import time
+from collections import deque
+
+fancy_loading = deque('>--------------------')
+
+while True:
+ print('\r%s' % ''.join(fancy_loading))
+ fancy_loading.rotate(1)
+ sys.stdout.flush()
+ time.sleep(0.08)
+```
+```python
+# 11. 用yield 不用return,可以返回一个generator
+```
+```python
+# 12. 符号~的巧妙应用
+for i in range(n):
+ # 这里的```[~i]``` 意思就是 ```[n-1-i]```
+ a[~i] = 1
+```
+```python
+# 13. 位运算判断奇偶数
+一般判断奇偶数是用 num % 2 == 0 来判断,如果为true则为偶数,为false则为奇数。
+偶数在二进制里面,最后一位为0,奇数则为1。所以可以通过与1做位与运算判断奇偶数。
+if (num & 1) == 0:
+ print('偶数')
+else:
+ print('奇数')
+如果结果为true则为偶数,为false则为奇数。效率比取余运算高的多。
+
+反正注意不要使用
+if num % 2 == 1
+来判断是否是奇数,因为如果是负奇数就不满足了
+
+最起码也要用if num % 2 != 0
+```
+
+
+```python
+# 14. pow(x, y)的时间复杂度为:
+
+For y < 2^63, there's a loop of size ceil(log_2(y)),
+but for larger y, the result is calculated using Exp(y * Log(x)).
+
+sqrt()函数平常认为是O(lgn)的
+但是追溯到最底层,sqrt()就是O(1)的,详细见
+```
+1. [求平方根sqrt()函数的底层算法效率问题](http://www.nowamagic.net/algorithm/algorithm_EfficacyOfFunctionSqrt.php)
+2. [Time complexity of Math.Sqrt()?](https://stackoverflow.com/questions/34580158/time-complexity-of-math-sqrt)
+
+
+```python
+# 15. python deque用法
+
+Operations on deque :
+
+1. append() :- This function is used to insert the value in its argument to the right end of deque.
+2. appendleft() :- This function is used to insert the value in its argument to the left end of deque.
+3. pop() :- This function is used to delete an argument from the right end of deque.
+4. popleft() :- This function is used to delete an argument from the left end of deque.
+5. index(ele, beg, end) :- This function returns the first index of the value mentioned in arguments, starting searching from beg till end index.
+6. insert(i, a) :- This function inserts the value mentioned in arguments(a) at index(i) specified in arguments.
+7. remove() :- This function removes the first occurrence of value mentioned in arguments.
+8. count() :- This function counts the number of occurrences of value mentioned in arguments.
+9. extend(iterable) :- This function is used to add multiple values at the right end of deque. The argument passed is an iterable.
+10. extendleft(iterable) :- This function is used to add multiple values at the left end of deque. The argument passed is an iterable. Order is reversed as a result of left appends.
+11. reverse() :- This function is used to reverse order of deque elements.
+12. rotate() :- This function rotates the deque by the number specified in arguments. If the number specified is negative, rotation occurs to left. Else rotation is to right.
+```
+[Deque in Python](https://www.geeksforgeeks.org/deque-in-python/)
+
+
+```python
+# 16. getRandom: Returns a random element from current set of elements. Each element must have the same probability of being returned.
+
+# 这种是常规方法
+idx = random.randint(0, self.length-1)
+return self.lst[idx]
+# 神奇函数
+return random.choice(self.lst)
+```
+
+
+
+```python
+# 17. while-else clause
+
+python支持while-else 语句
+```
+详细请看[leetcode 142题](https://github.com/apachecn/awesome-algorithm/blob/master/docs/Leetcode_Solutions/Python/142_Linked_List_Cycle_II.md),这里我用到了这个语句,贼爽!
+
+
+```python
+# 18. 两层嵌套for循环的效率比较
+
+正常情况下,次数多的循环放在内层,会减少cache更新数据的次数,当离开内层循环的时候会恢复外层的计数器,外层循环次数越少,恢复计数器的次数越少,效率较高,由此看来情况二更加高效。
+
+从cpu指令执行机制上来分析,因为基本所有cpu都有分支指令预测,所以如果有10次循环,只有第一次和最后一次可能预测失败。如果外层循环为A次,则预测失败的次数为2*A+2,所以外层循环次数少的情况效率更高,和上面分析一致。
+
+情况总有峰回路转的时候,考虑下面两个情况
+---------------------
+
+a = [[0] * 100000 for i in range(100000)]
+for i in range(100000):
+ for i in range(10):
+ a[i][j] = 0
+
+for i in range(10):
+ for i in range(100000):
+ a[j][i] = 0
+
+
+事实证明第一种情况更快。
+因为cpu从内存中获取到数据存放到cache的时候,是一块一块获取的,如果cache的利用率高,那么效率肯定更高。因为第一个代码对数组a的访问是顺序的,所以换页次数更少,时间开销更小。
+
+由此看来,对两种情况的分析并不是绝对的,效率应该由三种分析共同决定。
+---------------------
+
+```
+
diff --git a/docs/Leetcode_Solutions/Python/Summary/Range Sum Query 2D - Immutable.pdf b/docs/Leetcode_Solutions/Python/Summary/Range Sum Query 2D - Immutable.pdf
new file mode 100644
index 000000000..09410e209
Binary files /dev/null and b/docs/Leetcode_Solutions/Python/Summary/Range Sum Query 2D - Immutable.pdf differ
diff --git a/docs/Leetcode_Solutions/Python/Summary/Recusrion & BackTracking.md b/docs/Leetcode_Solutions/Python/Summary/Recusrion & BackTracking.md
new file mode 100644
index 000000000..16e0f9279
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/Summary/Recusrion & BackTracking.md
@@ -0,0 +1,237 @@
+#Recusrion & BackTracking
+
+##Recusrion
+
+### DrawFractal
+
+```
+void DrawFractal(double x, double y, double w, double h)
+{
+ DrawTriangel(x, y, w, h);
+ if(w < .2 || h < .2) return ;
+ double halfH = h/2;
+ double halfw = w/2;
+ DrawFractal(x, y, halfW, halfH);
+ DrawFractal(x + halfW/2, y + halfH, halfW, halfH);
+ DrawFractal(x + halfW, y, halfW, halfH);
+}
+```
+
+
+Sierpinski triangle更伪码的写法:
+
+```
+void DrawFractal (x, y, w, h){
+ if (too small) return ;
+ DrawTriangle(x, y, w, h);
+ DrawFractal(.left);
+ DrawFractal(.top);
+ DrawFractal(.right);
+}
+```
+
+实际上老师故意调了里面几句代码的顺序,让来看到虽然结果相同,但是画的过程是不一样的。
+
+然后老师还在黑板上画了过程树,分枝是怎样的,实际上当学到DFS的preOrder, inOrder 和 postOrder的时候会更印象深刻。
+
+一个分支走完之后再回去走另一些。
+
+
+### DrawMondrian
+
+
+
+```
+void DrawMondrian(double x, double y, double w, double h){
+
+ if(w < 1 || h < 1) return ;// base case
+
+ FillRectangle(x,y,w,h,RandomColor()); // fill background
+
+ switch(RandomInteger(0, 2)){
+ case 0: // do nothing
+ break;
+ case 1: // bisect vertically
+ double midX = RandomReal(0,w);
+ DrawBlackLine( x + midX, y, h);
+ DrawMondrian(x, y, midX, h);
+ DrawMondrian(x + midx, y, w- midX, h);
+ break;
+ case 2: // bisect horizontally
+ double midY = RandomReal(0,h);
+ DrawBlackLine( x, y+ midY, h);
+ DrawMondrian(x, y, w, midY);
+ DrawMondrian(x, y+midY,w, midY);
+ break;
+ }
+}
+```
+
+
+### The tower of Hanoi
+
+
+```
+void MoveTower(int n, char src, char dst, char tmp){
+ if (n > 0){
+ MoveTower(n - 1, src, tmp, dst );
+ MoveSingleDisk(src, dst);
+ MoveTower(n -1, tmp, dst, src);
+ }
+}
+
+```
+
+
+### Permutation
+
+老师说permutation 和 subset 是 mother problems of all recursion.
+
+
+given a string, print out its all permutations
+
+思路如下:
+
+- 使用了的string sofar,以及还未使用的string rest
+- 一开始rest就是给的string本身,然后sofar是空
+- 每次挑一个rest里面的char,然后递归的再把rest剩下的拿来permutation,这样每次都会有一个char从rest shuffle到sofar
+- n 次之后 rest为空,制造了一个permutation
+
+
+```
+void RecPermute(string sofar, string rest){
+ if(rest = ""){
+ cout << soFar << endl;
+ } else {
+ for(int i = 0 ; i < rest.length(); i++){
+ string next = soFar + rest[i];
+ string remaining = rest.substr(0,i) + rest.substr(i+1);
+ RecPermute(next, remaining);
+ }
+ }
+}
+
+
+// "wrapper" function
+void ListPermutations(string s)
+{
+ RecPermute("",s);
+}
+```
+
+
+老师的黑板图真的是击中要害。
+
+因为老师强调的是,也要用mind来trace它是如何操作的。
+
+
+
+### Subsets
+
+
+```
+void RecSubsets(string soFar, string rest)
+{
+ if(rest = "")
+ cout << soFar << endl;
+ else {
+ // add to subset, remove from rest, recur
+ RecSubsets(soFar + rest[0],rest.substr(1));
+ //don't add to substr, remove from rest, recur
+ RecSubsets(soFar, rest.substr(1));
+ }
+}
+
+
+void ListSubsets(string str)
+{
+ RecSubsets("",str);
+}
+
+```
+
+代码非常容易理解
+
+
+比较一下:两个都是有关选择,permutation是每次选哪一个char,而subsets是选择这个char 是否in.
+
+两个recursion tree都是有branching 和 depth的, depth都是n,每次选一个,知道n个选完.
+
+branching是how many recusive calls 每次made,subset每次都是两个,in/out,而permutation则是n,n-1.......grows very quickly.
+
+因为permutation是n!,subsets是2^n,跟树对应。这些都是比较intractable的问题,并不是因为recursion,而是问题本身的复杂度。
+
+
+这两个问题都是exhaustive的,然而,我们会更多碰到一些问题,有着
+
+similar exhaustive structure,但是遇到'satisfactory' outcome就会stop的 -> 也就是backtracking了.
+
+##BackTracking
+
+
+
+### pseudocode
+
+把问题转成decision problem,然后开始make choice.
+
+```
+bool Solve(configuration conf)
+{
+ if (no more choices) // BASE CASE
+ return (conf is goal state);
+
+ for (all available choices){
+ try one choice c;
+ // sove from here, it works out. you're done.
+ if (Solve(conf with choice c made)) return true;
+ unmake choice c;
+ }
+ return false; //tried all choices, no soln found
+}
+```
+
+
+###IsAnagram
+
+
+```
+bool IsAnagram(string soFar, string rest, Lexicon & lex)
+{
+ if(rest == ""){
+ if(lex.contains(soFar)){
+ cout << soFar << endl;
+ return true;
+ }
+ } else {
+ for(int i = 0; i < rest.length() ; i++ ){
+ string next = soFar + rest[i];
+ string remaining = rest.substr(0,i) + rest.substr(i+1);
+ if(IsAnagram(next, remaining, lex)) return true;
+ }
+ }
+ return false;
+}
+```
+
+
+### 8 Queens
+
+
+```
+
+bool Solve(Grid &board, int col)
+{
+ if(col > = board.numCols()) return true;
+
+ for(int rowToTry = 0; rowToTry < board.numRows(); rowToTry++){
+ if (IsSafe(board,rowToTry, col)){
+ PlaceQueen(board,rowToTry,col);
+ if (Solve(board,col+1)) return true;
+ RemoveQueen(board,rowToTry, col);
+ }
+ }
+ return false;
+}
+
+```
+
diff --git a/docs/Leetcode_Solutions/Python/Summary/SegmentTree.md b/docs/Leetcode_Solutions/Python/Summary/SegmentTree.md
new file mode 100644
index 000000000..e03cd68bb
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/Summary/SegmentTree.md
@@ -0,0 +1,101 @@
+Let us consider the following problem to understand Segment Trees.
+
+We have an array arr[0 . . . n-1]. We should be able to
+1. Find the sum of elements from index l to r where 0 <= l <= r <= n-1
+2. Change value of a specified element of the array to a new value x. We need to do arr[i] = x where 0 <= i <= n-1.
+
+A simple solution is to run a loop from l to r and calculate sum of elements in given range. To update a value, simply do arr[i] = x.
+The first operation takes O(n) time and second operation takes O(1) time.
+
+Another solution is to create another array and store sum from start to i at the ith index in this array.
+Sum of a given range can now be calculated in O(1) time, but update operation takes O(n) time now.
+This works well if the number of query operations are large and very few updates.
+
+What if the number of query and updates are equal?
+Can we perform both the operations in O(log n) time once given the array?
+We can use a Segment Tree to do both operations in O(Logn) time.
+
+Representation of Segment trees
+1. Leaf Nodes are the elements of the input array.
+2. Each internal node represents some merging of the leaf nodes.
+The merging may be different for different problems. For this problem, merging is sum of leaves under a node.
+
+详细见[Segment Tree | Set 1 (Sum of given range)](https://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/)
+
+
+下面是我的python实现,可以作为模版
+
+```python
+from math import *
+
+
+class SegmentTree(object):
+ def __init__(self, nums):
+ self.nums = nums
+ self.range_len = len(nums)
+ power = ceil(log(self.range_len, 2))
+ self.st = [0] * (2 ** (power + 1))
+ self.constrcut(nums, 0, self.range_len - 1, 0)
+
+ # A utility function to get the middle index from corner indexes.
+ def getMid(self, start, end):
+ return start + (end - start) // 2
+
+ # A recursive function that constructs Segment Tree for array[start..end].
+ # cur is the index of current node in segment tree self.st
+ # Time Complexity for tree construction is O(n).
+ # There are total 2n-1 nodes, and value of every node is calculated only once in tree construction.
+ def constrcut(self, nums, start, end, cur): # O(N)
+ if start == end:
+ self.st[cur] = nums[start]
+ return nums[start]
+ mid = self.getMid(start, end)
+ self.st[cur] = self.constrcut(nums, start, mid, 2 * cur + 1) + \
+ self.constrcut(nums, mid + 1, end, 2 * cur + 2)
+ return self.st[cur]
+
+ def getSumHelper(self, start, end, query_start, query_end, cur):
+ if query_start <= start and query_end >= end:
+ return self.st[cur]
+ if end < query_start or start > query_end:
+ return 0
+ mid = self.getMid(start, end)
+ return self.getSumHelper(start, mid, query_start, query_end, 2 * cur + 1) + \
+ self.getSumHelper(mid + 1, end, query_start, query_end, 2 * cur + 2)
+
+ # Time complexity to query is O(Logn).
+ # To query a sum, we process at most four nodes at every level and number of levels is O(Logn).
+ def getSum(self, query_start, query_end):
+ if query_start < 0 or query_end > self.range_len - 1 or query_start > query_end:
+ print('Invalid Input')
+ return -1
+ return self.getSumHelper(0, self.range_len - 1, query_start, query_end, 0)
+
+ # idx --> index of the element to be updated. This index is in input nums.
+ def updateValueHelper(self, start, end, idx, diff, cur):
+ if idx < start or idx > end:
+ return
+ self.st[cur] += diff
+ if end != start:
+ mid = self.getMid(start, end)
+ self.updateValueHelper(start, mid, idx, diff, 2 * cur + 1)
+ self.updateValueHelper(mid + 1, end, idx, diff, 2 * cur + 2)
+
+ # The time complexity of update is also O(Logn).
+ # To update a leaf value, we process one node at every level and number of levels is O(Logn).
+ def updateValue(self, idx, new_val): # O(lgN)
+ if idx < 0 or idx > self.range_len - 1:
+ print('Invalid Input')
+ return
+ diff = new_val - self.nums[idx]
+ self.nums[idx] = new_val
+ self.updateValueHelper(0, self.range_len - 1, idx, diff, 0)
+
+
+nums = [1, 3, 5, 7, 9, 11]
+s = SegmentTree(nums)
+print("Sum of values in given range = ", s.getSum(1, 3))
+s.updateValue(1, 9)
+print("Updated sum of values in given range = ", s.getSum(1, 3))
+
+```
diff --git "a/docs/Leetcode_Solutions/Python/Summary/backtracking\346\200\235\350\267\257.md" "b/docs/Leetcode_Solutions/Python/Summary/backtracking\346\200\235\350\267\257.md"
new file mode 100644
index 000000000..dbb7e8cf1
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/backtracking\346\200\235\350\267\257.md"
@@ -0,0 +1,295 @@
+## backtracking 全集
+
+### 回溯是啥
+用爬山来比喻回溯,好比从山脚下找一条爬上山顶的路,起初有好几条道可走,当选择一条道走到某处时,又有几条岔道可供选择,只能选择其中一条道往前走,若能这样子顺利爬上山顶则罢了,否则走到一条绝路上时,只好返回到最近的一个路口,重新选择另一条没走过的道往前走。如果该路口的所有路都走不通,只得从该路口继续回返。照此规则走下去,要么找到一条到达山顶的路,要么最终试过所有可能的道,无法到达山顶。
+回溯是一种穷举,但与brute force有一些区别,回溯带了两点脑子的,并不多,brute force一点也没带。
+第一点脑子是回溯知道回头;相反如果是brute force,发现走不通立刻跳下山摔死,换第二条命从头换一条路走。
+第二点脑子是回溯知道剪枝;如果有一条岔路上放了一坨屎,那这条路我们不走,就可以少走很多不必要走的路。
+
+还有一些爱混淆的概念:递归,回溯,DFS。
+回溯是一种找路方法,搜索的时候走不通就回头换路接着走,直到走通了或者发现此山根本不通。
+DFS是一种开路策略,就是一条道先走到头,再往回走一步换一条路走到头,这也是回溯用到的策略。在树和图上回溯时人们叫它DFS。
+递归是一种行为,回溯和递归如出一辙,都是一言不合就回到来时的路,所以一般回溯用递归实现;当然也可以不用,用栈。
+以下以回溯统称,因为这个词听上去很文雅。
+
+### 识别回溯
+判断回溯很简单,拿到一个问题,你感觉如果不穷举一下就没法知道答案,那就可以开始回溯了。
+一般回溯的问题有三种:
+
+1. Find a path to success 有没有解
+2. Find all paths to success 求所有解
+ - 2.1 求所有解的个数,
+ - 2.2 求所有解的具体信息
+3. Find the best path to success 求最优解
+
+理解回溯:给一堆选择, 必须从里面选一个. 选完之后我又有了新的一组选择. ```This procedure is repeated over and over until you reach a final state. If you made a good sequence of choices, your final state is a goal state; if you didn't, it isn't.```
+
+回溯可以抽象为一棵树,我们的目标可以是找这个树有没有good leaf,也可以是问有多少个good leaf,也可以是找这些good leaf都在哪,也可以问哪个good leaf最好,分别对应上面所说回溯的问题分类。
+good leaf都在leaf上。good leaf是我们的goal state,leaf node是final state,是解空间的边界。
+
+对于第一类问题(问有没有解),基本都是长着个样子的,理解了它,其他类别迎刃而解:
+```java
+boolean solve(Node n) {
+ if n is a leaf node {
+ if the leaf is a goal node, return true
+ else return false
+ } else {
+ for each child c of n {
+ if solve(c) succeeds, return true
+ }
+ return false
+ }
+}
+```
+请读以下这段话以加深理解:
+```Notice that the algorithm is expressed as a boolean function. This is essential to understanding the algorithm. If solve(n) is true, that means node n is part of a solution--that is, node n is one of the nodes on a path from the root to some goal node. We say that n is solvable. If solve(n) is false, then there is no path that includes n to any goal node.```
+
+还不懂的话请通读全文吧:[Backtracking - David Matuszek](https://www.cis.upenn.edu/~matuszek/cit594-2012/Pages/backtracking.html)
+
+关于回溯的三种问题,模板略有不同,
+第一种,返回值是true/false。
+第二种,求个数,设全局counter,返回值是void;求所有解信息,设result,返回值void。
+第三种,设个全局变量best,返回值是void。
+
+第一种:
+```java
+boolean solve(Node n) {
+ if n is a leaf node {
+ if the leaf is a goal node, return true
+ else return false
+ } else {
+ for each child c of n {
+ if solve(c) succeeds, return true
+ }
+ return false
+ }
+}
+```
+第二种:
+```java
+void solve(Node n) {
+ if n is a leaf node {
+ if the leaf is a goal node, count++, return;
+ else return
+ } else {
+ for each child c of n {
+ solve(c)
+ }
+ }
+}
+```
+第三种:
+```java
+void solve(Node n) {
+ if n is a leaf node {
+ if the leaf is a goal node, update best result, return;
+ else return
+ } else {
+ for each child c of n {
+ solve(c)
+ }
+ }
+}
+```
+题目
+
+八皇后 N-Queens
+
+问题
+
+1. 给个n,问有没有解;
+2. 给个n,有几种解;(Leetcode N-Queens II)
+3. 给个n,给出所有解;(Leetcode N-Queens I)
+
+解答
+
+1.有没有解
+
+怎么做:一行一行的放queen,每行尝试n个可能,有一个可达,返回true;都不可达,返回false.
+
+边界条件leaf:放完第n行 或者 该放第n+1行(出界,返回)
+
+目标条件goal:n行放满且isValid,即目标一定在leaf上
+
+helper函数:
+boolean solve(int i, int[][] matrix)
+在进来的一瞬间,满足property:第i行还没有被放置,前i-1行放置完毕且valid
+solve要在给定的matrix上试图给第i行每个位置放queen。
+```java
+public static boolean solve1(int i, List matrix, int n) {
+ if (i == n) {
+ if (isValid(matrix))
+ return true;
+ return false;
+ } else {
+ for (int j = 0; j < n; j++) {
+ matrix.add(j);
+ if (isValid(matrix)) { //剪枝
+ if (solve1(i + 1, matrix, n))
+ return true;
+ }
+ matrix.remove(matrix.size() - 1);
+ }
+ return false;
+ }
+}
+```
+2.求解的个数
+
+怎么做:一行一行的放queen,每行尝试n个可能。这回因为要找所有,返回值就没有了意义,用void即可。在搜索时,如果有一个可达,仍要继续尝试;每个子选项都试完了,返回.
+
+边界条件leaf:放完第n行 或者 该放第n+1行(出界,返回)
+
+目标条件goal:n行放满且isValid,即目标一定在leaf上
+
+helper函数:
+void solve(int i, int[][] matrix)
+在进来的一瞬间,满足property:第i行还没有被放置,前i-1行放置完毕且valid
+solve要在给定的matrix上试图给第i行每个位置放queen。
+这里为了记录解的个数,设置一个全局变量(static)int是比较efficient的做法。
+```java
+public static void solve2(int i, List matrix, int n) {
+ if (i == n) {
+ if (isValid(matrix))
+ count++;
+ return;
+ } else {
+ for (int j = 0; j < n; j++) {
+ matrix.add(j);
+ if (isValid(matrix)) { //剪枝
+ solve2(i + 1, matrix, n);
+ }
+ matrix.remove(matrix.size() - 1);
+ }
+ }
+}
+```
+3.求所有解的具体信息
+
+怎么做:一行一行的放queen,每行尝试n个可能。返回值同样用void即可。在搜索时,如果有一个可达,仍要继续尝试;每个子选项都试完了,返回.
+
+边界条件leaf:放完第n行 或者 该放第n+1行(出界,返回)
+
+目标条件goal:n行放满且isValid,即目标一定在leaf上
+
+helper函数:
+void solve(int i, int[][] matrix)
+在进来的一瞬间,满足property:第i行还没有被放置,前i-1行放置完毕且valid
+solve要在给定的matrix上试图给第i行每个位置放queen。
+这里为了记录解的具体情况,设置一个全局变量(static)集合是比较efficient的做法。
+当然也可以把结果集合作为参数传来传去。
+```java
+public static void solve3(int i, List matrix, int n) {
+ if (i == n) {
+ if (isValid(matrix))
+ result.add(new ArrayList(matrix));
+ return;
+ } else {
+ for (int j = 0; j < n; j++) {
+ matrix.add(j);
+ if (isValid(matrix)) { //剪枝
+ solve3(i + 1, matrix, n);
+ }
+ matrix.remove(matrix.size() - 1);
+ }
+ }
+}
+```
+优化
+
+上面的例子用了省空间的方法。
+由于每行只能放一个,一共n行的话,用一个大小为n的数组,数组的第i个元素表示第i行放在了第几列上。
+
+Utility(给一个list判断他的最后一行是否和前面冲突):
+```java
+public static boolean isValid(List list){
+ int row = list.size() - 1;
+ int col = list.get(row);
+ for (int i = 0; i <= row - 1; i++) {
+ int row1 = i;
+ int col1 = list.get(i);
+ if (col == col1)
+ return false;
+ if (row1 - row == col1 - col)
+ return false;
+ if (row1 - row == col - col1)
+ return false;
+ }
+ return true;
+
+}
+```
+
+参考[Backtracking回溯法(又称DFS,递归)全解](https://segmentfault.com/a/1190000006121957)
+以及 [Python Patterns - Implementing Graphs](https://www.python.org/doc/essays/graphs/)
+
+
+
+## 以Generate Parentheses为例,backtrack的题到底该怎么去思考?
+
+
+所谓Backtracking都是这样的思路:在当前局面下,你有若干种选择。那么尝试每一种选择。如果已经发现某种选择肯定不行(因为违反了某些限定条件),就返回;如果某种选择试到最后发现是正确解,就将其加入解集
+
+所以你思考递归题时,只要明确三点就行:选择 (Options),限制 (Restraints),结束条件 (Termination)。即“ORT原则”(这个是我自己编的)
+
+
+
+
+对于这道题,在任何时刻,你都有两种选择:
+1. 加左括号。
+2. 加右括号。
+
+同时有以下限制:
+1. 如果左括号已经用完了,则不能再加左括号了。
+2. 如果已经出现的右括号和左括号一样多,则不能再加右括号了。因为那样的话新加入的右括号一定无法匹配。
+
+结束条件是:
+左右括号都已经用完。
+
+结束后的正确性:
+左右括号用完以后,一定是正确解。因为1. 左右括号一样多,2. 每个右括号都一定有与之配对的左括号。因此一旦结束就可以加入解集(有时也可能出现结束以后不一定是正确解的情况,这时要多一步判断)。
+
+递归函数传入参数:
+限制和结束条件中有“用完”和“一样多”字样,因此你需要知道左右括号的数目。
+当然你还需要知道当前局面sublist和解集res。
+
+因此,把上面的思路拼起来就是代码:
+
+ if (左右括号都已用完) {
+ 加入解集,返回
+ }
+ //否则开始试各种选择
+ if (还有左括号可以用) {
+ 加一个左括号,继续递归
+ }
+ if (右括号小于左括号) {
+ 加一个右括号,继续递归
+ }
+
+
+
+你帖的那段代码逻辑中加了一条限制:“3. 是否还有右括号剩余。如有才加右括号”。这是合理的。不过对于这道题,如果满足限制1、2时,3一定自动满足,所以可以不判断3。
+
+这题其实是最好的backtracking初学练习之一,因为ORT三者都非常简单明显。你不妨按上述思路再梳理一遍,还有问题的话再说。
+
+
+
+以上文字来自 1point3arces的牛人解答
+
+
+
+Backtracking 伪码
+
+
+```
+Pick a starting point.
+while(Problem is not solved)
+ For each path from the starting point.
+ check if selected path is safe, if yes select it
+ and make recursive call to rest of the problem
+ If recursive calls returns true, then return true.
+ else undo the current move and return false.
+ End For
+ If none of the move works out, return false, NO SOLUTON.
+
+```
diff --git "a/docs/Leetcode_Solutions/Python/Summary/delete_node_in_a_linked_list\351\227\256\351\242\230.md" "b/docs/Leetcode_Solutions/Python/Summary/delete_node_in_a_linked_list\351\227\256\351\242\230.md"
new file mode 100644
index 000000000..e148bb218
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/delete_node_in_a_linked_list\351\227\256\351\242\230.md"
@@ -0,0 +1,69 @@
+##Delete Node in a Linked List问题
+
+
+This is a LeetCode question, I knew its solution, but wondering about why my code not work.
+
+
+>Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.
+
+>Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function
+
+
+At first glance, my intution is delete like an array:
+
+shift all the node values one front, then delete the tail, here's my implementation and test case:
+
+
+
+ class ListNode(object):
+ def __init__(self, x):
+ self.val = x
+ self.next = None
+
+ node1 = ListNode(1)
+ node2 = ListNode(2)
+ node3 = ListNode(3)
+ node4 = ListNode(4)
+ node5 = ListNode(5)
+
+ node1.next = node2
+ node2.next = node3
+ node3.next = node4
+ node4.next = node5
+
+
+
+ def deleteNode(node):
+ """
+ :type node: ListNode
+ :rtype: void Do not return anything, modify node in-place instead.
+ """
+ while node.next:
+ node.val = node.next.val
+ node = node.next
+ node = None
+
+
+ deleteNode(node4)
+
+But After deletion, it has two 5 value nodes, the tail was still kept, can anyone please explain to me what's wrong here?
+
+ deleteNode(node4)
+
+ node1.val
+ Out[162]: 1
+
+ node1.next.val
+ Out[163]: 2
+
+ node1.next.next.val
+ Out[164]: 3
+
+ node1.next.next.next.val
+ Out[165]: 5
+
+ node1.next.next.next.next.val
+ Out[166]: 5
+
+
+Really appreciate any help.
\ No newline at end of file
diff --git a/docs/Leetcode_Solutions/Python/Summary/deque.md b/docs/Leetcode_Solutions/Python/Summary/deque.md
new file mode 100644
index 000000000..593119508
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/Summary/deque.md
@@ -0,0 +1,65 @@
+
+
+
+
+看一下deque + rotate:
+
+
+```python
+import collections
+a = collections.deque()
+a.append(2)
+a.append(5)
+a.append(7)
+a.append(9) #a deque([2, 5, 7, 9])
+
+import bisect
+idx = bisect.bisect_left(a,3) #1
+a.rotate(-idx) #deque([5, 7, 9, 2])
+
+a.appendleft(3) #deque([3, 5, 7, 9, 2])
+
+a.rotate(idx) # deque([2, 3, 5, 7, 9])
+```
+
+这个rotate -是往左边rotate,看官网的介绍.
+
+>Rotate the deque n steps to the right. If n is negative, rotate to the left. Rotating one step to the right is equivalent to: d.appendleft(d.pop()).
+
+所以这样造成可以🐂的数据结构
+
+用这个微调之后的fasttable来解决问题
+
+
+```python
+import collections
+import bisect
+
+class FastTable:
+
+ def __init__(self):
+ self.__deque = collections.deque()
+
+ def __len__(self):
+ return len(self.__deque)
+
+ def head(self):
+ return self.__deque.popleft()
+
+ def tail(self):
+ return self.__deque.pop()
+
+ def peek(self):
+ return self.__deque[-1]
+
+ def insert(self, obj):
+ if obj in self.__deque:
+ return
+ index = bisect.bisect_left(self.__deque, obj)
+ self.__deque.rotate(-index)
+ self.__deque.appendleft(obj)
+ self.__deque.rotate(index)
+```
+
+
+可以用来实现动态插入元素,只是记录一下,我个人觉得这个还没直接insert(idx, num)快呢
diff --git a/docs/Leetcode_Solutions/Python/Summary/python_base.md b/docs/Leetcode_Solutions/Python/Summary/python_base.md
new file mode 100644
index 000000000..718e2edbb
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/Summary/python_base.md
@@ -0,0 +1,1338 @@
+```python
+# _*_ coding: utf-8 _*_
+
+"""类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算----类型和运算"""
+
+#-- 寻求帮助:
+ dir(obj) # 简单的列出对象obj所包含的方法名称,返回一个字符串列表
+ help(obj.func) # 查询obj.func的具体介绍和用法
+
+#-- 测试类型的三种方法,推荐第三种
+ if type(L) == type([]):
+ print("L is list")
+ if type(L) == list:
+ print("L is list")
+ if isinstance(L, list):
+ print("L is list")
+
+#-- Python数据类型:哈希类型、不可哈希类型
+ # 哈希类型,即在原地不能改变的变量类型,不可变类型。可利用hash函数查看其hash值,也可以作为字典的key
+ "数字类型:int, float, decimal.Decimal, fractions.Fraction, complex"
+ "字符串类型:str, bytes"
+ "元组:tuple"
+ "冻结集合:frozenset"
+ "布尔类型:True, False"
+ "None"
+ # 不可hash类型:原地可变类型:list、dict和set。它们不可以作为字典的key。
+
+#-- 数字常量
+ 1234, -1234, 0, 999999999 # 整数
+ 1.23, 1., 3.14e-10, 4E210, 4.0e+210 # 浮点数
+ 0o177, 0x9ff, 0X9FF, 0b101010 # 八进制、十六进制、二进制数字
+ 3+4j, 3.0+4.0j, 3J # 复数常量,也可以用complex(real, image)来创建
+ hex(I), oct(I), bin(I) # 将十进制数转化为十六进制、八进制、二进制表示的“字符串”
+ int(string, base) # 将字符串转化为整数,base为进制数
+ # 2.x中,有两种整数类型:一般整数(32位)和长整数(无穷精度)。可以用l或L结尾,迫使一般整数成为长整数
+ float('inf'), float('-inf'), float('nan') # 无穷大, 无穷小, 非数
+
+#-- 数字的表达式操作符
+ yield x # 生成器函数发送协议
+ lambda args: expression # 生成匿名函数
+ x if y else z # 三元选择表达式
+ x and y, x or y, not x # 逻辑与、逻辑或、逻辑非
+ x in y, x not in y # 成员对象测试
+ x is y, x is not y # 对象实体测试
+ xy, x>=y, x==y, x!=y # 大小比较,集合子集或超集值相等性操作符
+ 1 < a < 3 # Python中允许连续比较
+ x|y, x&y, x^y # 位或、位与、位异或
+ x<>y # 位操作:x左移、右移y位
+ +, -, *, /, //, %, ** # 真除法、floor除法:返回不大于真除法结果的整数值、取余、幂运算
+ -x, +x, ~x # 一元减法、识别、按位求补(取反)
+ x[i], x[i:j:k] # 索引、分片、调用
+ int(3.14), float(3) # 强制类型转换
+
+#-- 整数可以利用bit_length函数测试所占的位数
+ a = 1; a.bit_length() # 1
+ a = 1024; a.bit_length() # 11
+
+#-- repr和str显示格式的区别
+ """
+ repr格式:默认的交互模式回显,产生的结果看起来它们就像是代码。
+ str格式:打印语句,转化成一种对用户更加友好的格式。
+ """
+
+#-- 数字相关的模块
+ # math模块
+ # Decimal模块:小数模块
+ import decimal
+ from decimal import Decimal
+ Decimal("0.01") + Decimal("0.02") # 返回Decimal("0.03")
+ decimal.getcontext().prec = 4 # 设置全局精度为4 即小数点后边4位
+ # Fraction模块:分数模块
+ from fractions import Fraction
+ x = Fraction(4, 6) # 分数类型 4/6
+ x = Fraction("0.25") # 分数类型 1/4 接收字符串类型的参数
+
+#-- 集合set
+ """
+ set是一个无序不重复元素集, 基本功能包括关系测试和消除重复元素。
+ set支持union(联合), intersection(交), difference(差)和symmetric difference(对称差集)等数学运算。
+ set支持x in set, len(set), for x in set。
+ set不记录元素位置或者插入点, 因此不支持indexing, slicing, 或其它类序列的操作
+ """
+ s = set([3,5,9,10]) # 创建一个数值集合,返回{3, 5, 9, 10}
+ t = set("Hello") # 创建一个唯一字符的集合返回{}
+ a = t | s; t.union(s) # t 和 s的并集
+ b = t & s; t.intersection(s) # t 和 s的交集
+ c = t – s; t.difference(s) # 求差集(项在t中, 但不在s中)
+ d = t ^ s; t.symmetric_difference(s) # 对称差集(项在t或s中, 但不会同时出现在二者中)
+ t.add('x'); t.remove('H') # 增加/删除一个item
+ s.update([10,37,42]) # 利用[......]更新s集合
+ x in s, x not in s # 集合中是否存在某个值
+ s.issubset(t); s <= t # 测试是否 s 中的每一个元素都在 t 中
+ s.issuperset(t); s >= t # 测试是否 t 中的每一个元素都在 s 中
+ s.copy();
+ s.discard(x); # 删除s中x
+ s.clear() # 清空s
+ {x**2 for x in [1, 2, 3, 4]} # 集合解析,结果:{16, 1, 4, 9}
+ {x for x in 'spam'} # 集合解析,结果:{'a', 'p', 's', 'm'}
+
+#-- 集合frozenset,不可变对象
+ """
+ set是可变对象,即不存在hash值,不能作为字典的键值。同样的还有list等(tuple是可以作为字典key的)
+ frozenset是不可变对象,即存在hash值,可作为字典的键值
+ frozenset对象没有add、remove等方法,但有union/intersection/difference等方法
+ """
+ a = set([1, 2, 3])
+ b = set()
+ b.add(a) # error: set是不可哈希类型
+ b.add(frozenset(a)) # ok,将set变为frozenset,可哈希
+
+#-- 布尔类型bool
+ type(True) # 返回
+ isinstance(False, int) # bool类型属于整型,所以返回True
+ True == 1; True is 1 # 输出(True, False)
+
+#-- 动态类型简介
+ """
+ 变量名通过引用,指向对象。
+ Python中的“类型”属于对象,而不是变量,每个对象都包含有头部信息,比如"类型标示符" "引用计数器"等
+ """
+ #共享引用及在原处修改:对于可变对象,要注意尽量不要共享引用!
+ #共享引用和相等测试:
+ L = [1], M = [1], L is M # 返回False
+ L = M = [1, 2, 3], L is M # 返回True,共享引用
+ #增强赋值和共享引用:普通+号会生成新的对象,而增强赋值+=会在原处修改
+ L = M = [1, 2]
+ L = L + [3, 4] # L = [1, 2, 3, 4], M = [1, 2]
+ L += [3, 4] # L = [1, 2, 3, 4], M = [1, 2, 3, 4]
+
+#-- 常见字符串常量和表达式
+ S = '' # 空字符串
+ S = "spam’s" # 双引号和单引号相同
+ S = "s\np\ta\x00m" # 转义字符
+ S = """spam""" # 三重引号字符串,一般用于函数说明
+ S = r'\temp' # Raw字符串,不会进行转义,抑制转义
+ S = b'Spam' # Python3中的字节字符串
+ S = u'spam' # Python2.6中的Unicode字符串
+ s1+s2, s1*3, s[i], s[i:j], len(s) # 字符串操作
+ 'a %s parrot' % 'kind' # 字符串格式化表达式
+ 'a {1} {0} parrot'.format('kind', 'red')# 字符串格式化方法
+ for x in s: print(x) # 字符串迭代,成员关系
+ [x*2 for x in s] # 字符串列表解析
+ ','.join(['a', 'b', 'c']) # 字符串输出,结果:a,b,c
+
+#-- 内置str处理函数:
+ str1 = "stringobject"
+ str1.upper(); str1.lower(); str1.swapcase(); str1.capitalize(); str1.title() # 全部大写,全部小写、大小写转换,首字母大写,每个单词的首字母都大写
+ str1.ljust(width) # 获取固定长度,左对齐,右边不够用空格补齐
+ str1.rjust(width) # 获取固定长度,右对齐,左边不够用空格补齐
+ str1.center(width) # 获取固定长度,中间对齐,两边不够用空格补齐
+ str1.zfill(width) # 获取固定长度,右对齐,左边不足用0补齐
+ str1.find('t',start,end) # 查找字符串,可以指定起始及结束位置搜索
+ str1.rfind('t') # 从右边开始查找字符串
+ str1.count('t') # 查找字符串出现的次数
+ #上面所有方法都可用index代替,不同的是使用index查找不到会抛异常,而find返回-1
+ str1.replace('old','new') # 替换函数,替换old为new,参数中可以指定maxReplaceTimes,即替换指定次数的old为new
+ str1.strip(); # 默认删除空白符
+ str1.strip('d'); # 删除str1字符串中开头、结尾处,位于 d 删除序列的字符
+ str1.lstrip();
+ str1.lstrip('d'); # 删除str1字符串中开头处,位于 d 删除序列的字符
+ str1.rstrip();
+ str1.rstrip('d') # 删除str1字符串中结尾处,位于 d 删除序列的字符
+ str1.startswith('start') # 是否以start开头
+ str1.endswith('end') # 是否以end结尾
+ str1.isalnum(); str1.isalpha(); str1.isdigit(); str1.islower(); str1.isupper() # 判断字符串是否全为字符、数字、小写、大写
+
+#-- 三重引号编写多行字符串块,并且在代码折行处嵌入换行字符\n
+ mantra = """hello world
+ hello python
+ hello my friend"""
+ # mantra为"""hello world \n hello python \n hello my friend"""
+
+#-- 索引和分片:
+ S[0], S[len(S)–1], S[-1] # 索引
+ S[1:3], S[1:], S[:-1], S[1:10:2] # 分片,第三个参数指定步长,如`S[1:10:2]`是从1位到10位没隔2位获取一个字符。
+
+#-- 字符串转换工具:
+ int('42'), str(42) # 返回(42, '42')
+ float('4.13'), str(4.13) # 返回(4.13, '4.13')
+ ord('s'), chr(115) # 返回(115, 's')
+ int('1001', 2) # 将字符串作为二进制数字,转化为数字,返回9
+ bin(13), oct(13), hex(13) # 将整数转化为二进制/八进制/十六进制字符串,返回('0b1101', '015', '0xd')
+
+#-- 另类字符串连接
+ name = "wang" "hong" # 单行,name = "wanghong"
+ name = "wang" \
+ "hong" # 多行,name = "wanghong"
+
+#-- Python中的字符串格式化实现1--字符串格式化表达式
+ """
+ 基于C语言的'print'模型,并且在大多数的现有的语言中使用。
+ 通用结构:%[(name)][flag][width].[precision]typecode
+ """
+ "this is %d %s bird" % (1, 'dead') # 一般的格式化表达式
+ "%s---%s---%s" % (42, 3.14, [1, 2, 3]) # 字符串输出:'42---3.14---[1, 2, 3]'
+ "%d...%6d...%-6d...%06d" % (1234, 1234, 1234, 1234) # 对齐方式及填充:"1234... 1234...1234 ...001234"
+ x = 1.23456789
+ "%e | %f | %g" % (x, x, x) # 对齐方式:"1.234568e+00 | 1.234568 | 1.23457"
+ "%6.2f*%-6.2f*%06.2f*%+6.2f" % (x, x, x, x) # 对齐方式:' 1.23*1.23 *001.23* +1.23'
+ "%(name1)d---%(name2)s" % {"name1":23, "name2":"value2"} # 基于字典的格式化表达式
+ "%(name)s is %(age)d" % vars() # vars()函数调用返回一个字典,包含了所有本函数调用时存在的变量
+
+#-- Python中的字符串格式化实现2--字符串格式化调用方法
+ # 普通调用
+ "{0}, {1} and {2}".format('spam', 'ham', 'eggs') # 基于位置的调用
+ "{motto} and {pork}".format(motto = 'spam', pork = 'ham') # 基于Key的调用
+ "{motto} and {0}".format('ham', motto = 'spam') # 混合调用
+ # 添加键 属性 偏移量 (import sys)
+ "my {1[spam]} runs {0.platform}".format(sys, {'spam':'laptop'}) # 基于位置的键和属性
+ "{config[spam]} {sys.platform}".format(sys = sys, config = {'spam':'laptop'}) # 基于Key的键和属性
+ "first = {0[0]}, second = {0[1]}".format(['A', 'B', 'C']) # 基于位置的偏移量
+ # 具体格式化
+ "{0:e}, {1:.3e}, {2:g}".format(3.14159, 3.14159, 3.14159) # 输出'3.141590e+00, 3.142e+00, 3.14159'
+ "{fieldname:format_spec}".format(......)
+ # 说明:
+ """
+ fieldname是指定参数的一个数字或关键字, 后边可跟可选的".name"或"[index]"成分引用
+ format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
+ fill ::= #填充字符
+ align ::= "<" | ">" | "=" | "^" #对齐方式
+ sign ::= "+" | "-" | " " #符号说明
+ width ::= integer #字符串宽度
+ precision ::= integer #浮点数精度
+ type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
+ """
+ # 例子:
+ '={0:10} = {1:10}'.format('spam', 123.456) # 输出'=spam = 123.456'
+ '={0:>10}='.format('test') # 输出'= test='
+ '={0:<10}='.format('test') # 输出'=test ='
+ '={0:^10}='.format('test') # 输出'= test ='
+ '{0:X}, {1:o}, {2:b}'.format(255, 255, 255) # 输出'FF, 377, 11111111'
+ 'My name is {0:{1}}.'.format('Fred', 8) # 输出'My name is Fred .' 动态指定参数
+
+#-- 常用列表常量和操作
+ L = [[1, 2], 'string', {}] # 嵌套列表
+ L = list('spam') # 列表初始化
+ L = list(range(0, 4)) # 列表初始化
+ list(map(ord, 'spam')) # 列表解析
+ len(L) # 求列表长度
+ L.count(value) # 求列表中某个值的个数
+ L.append(obj) # 向列表的尾部添加数据,比如append(2),添加元素2
+ L.insert(index, obj) # 向列表的指定index位置添加数据,index及其之后的数据后移
+ L.extend(interable) # 通过添加iterable中的元素来扩展列表,比如extend([2]),添加元素2,注意和append的区别
+ L.index(value, [start, [stop]]) # 返回列表中值value的第一个索引
+ L.pop([index]) # 删除并返回index处的元素,默认为删除并返回最后一个元素
+ L.remove(value) # 删除列表中的value值,只删除第一次出现的value的值
+ L.reverse() # 反转列表
+ L.sort(cmp=None, key=None, reverse=False) # 排序列表
+ a = [1, 2, 3], b = a[10:] # 注意,这里不会引发IndexError异常,只会返回一个空的列表[]
+ a = [], a += [1] # 这里实在原有列表的基础上进行操作,即列表的id没有改变
+ a = [], a = a + [1] # 这里最后的a要构建一个新的列表,即a的id发生了变化
+
+#-- 用切片来删除序列的某一段
+ a = [1, 2, 3, 4, 5, 6, 7]
+ a[1:4] = [] # a = [1, 5, 6, 7]
+ a = [0, 1, 2, 3, 4, 5, 6, 7]
+ del a[::2] # 去除偶数项(偶数索引的),a = [1, 3, 5, 7]
+
+#-- 常用字典常量和操作
+ D = {}
+ D = {'spam':2, 'tol':{'ham':1}} # 嵌套字典
+ D = dict.fromkeys(['s', 'd'], 8) # {'s': 8, 'd': 8}
+ D = dict(name = 'tom', age = 12) # {'age': 12, 'name': 'tom'}
+ D = dict([('name', 'tom'), ('age', 12)]) # {'age': 12, 'name': 'tom'}
+ D = dict(zip(['name', 'age'], ['tom', 12])) # {'age': 12, 'name': 'tom'}
+ D.keys(); D.values(); D.items() # 字典键、值以及键值对
+ D.get(key, default) # get函数
+ D.update(D_other) # 合并字典,如果存在相同的键值,D_other的数据会覆盖掉D的数据
+ D.pop(key, [D]) # 删除字典中键值为key的项,返回键值为key的值,如果不存在,返回默认值D,否则异常
+ D.popitem() # pop字典中随机的一项(一个键值对)
+ D.setdefault(k[, d]) # 设置D中某一项的默认值。如果k存在,则返回D[k],否则设置D[k]=d,同时返回D[k]。
+ del D # 删除字典
+ del D['key'] # 删除字典的某一项
+ if key in D: if key not in D: # 测试字典键是否存在
+ # 字典注意事项:(1)对新索引赋值会添加一项(2)字典键不一定非得是字符串,也可以为任何的不可变对象
+ # 不可变对象:调用对象自身的任意方法,也不会改变该对象自身的内容,这些方法会创建新的对象并返回。
+ # 字符串、整数、tuple都是不可变对象,dict、set、list都是可变对象
+ D[(1,2,3)] = 2 # tuple作为字典的key
+
+#-- 字典解析
+ D = {k:8 for k in ['s', 'd']} # {'s': 8, 'd': 8}
+ D = {k:v for (k, v) in zip(['name', 'age'], ['tom', 12])} # {'age': 12, 'name': tom}
+
+#-- 字典的特殊方法__missing__:当查找找不到key时,会执行该方法
+ class Dict(dict):
+ def __missing__(self, key):
+ self[key] = []
+ return self[key]
+ dct = dict()
+ dct["foo"].append(1) # 这有点类似于collections.defalutdict
+ dct["foo"] # [1]
+
+#-- 元组和列表的唯一区别在于元组是不可变对象,列表是可变对象
+ a = [1, 2, 3] # a[1] = 0, OK
+ a = (1, 2, 3) # a[1] = 0, Error
+ a = ([1, 2]) # a[0][1] = 0, OK
+ a = [(1, 2)] # a[0][1] = 0, Error
+
+#-- 元组的特殊语法: 逗号和圆括号
+ D = (12) # 此时D为一个整数 即D = 12
+ D = (12, ) # 此时D为一个元组 即D = (12, )
+
+#-- 文件基本操作
+ output = open(r'C:\spam', 'w') # 打开输出文件,用于写
+ input = open('data', 'r') # 打开输入文件,用于读。打开的方式可以为'w', 'r', 'a', 'wb', 'rb', 'ab'等
+ fp.read([size]) # size为读取的长度,以byte为单位
+ fp.readline([size]) # 读一行,如果定义了size,有可能返回的只是一行的一部分
+ fp.readlines([size]) # 把文件每一行作为一个list的一个成员,并返回这个list。其实它的内部是通过循环调用readline()来实现的。如果提供size参数,size是表示读取内容的总长。
+ fp.readable() # 是否可读
+ fp.write(str) # 把str写到文件中,write()并不会在str后加上一个换行符
+ fp.writelines(seq) # 把seq的内容全部写到文件中(多行一次性写入)
+ fp.writeable() # 是否可写
+ fp.close() # 关闭文件。
+ fp.flush() # 把缓冲区的内容写入硬盘
+ fp.fileno() # 返回一个长整型的”文件标签“
+ fp.isatty() # 文件是否是一个终端设备文件(unix系统中的)
+ fp.tell() # 返回文件操作标记的当前位置,以文件的开头为原点
+ fp.next() # 返回下一行,并将文件操作标记位移到下一行。把一个file用于for … in file这样的语句时,就是调用next()函数来实现遍历的。
+ fp.seek(offset[,whence]) # 将文件打开操作标记移到offset的位置。whence为0表示从头开始计算,1表示以当前位置为原点计算。2表示以文件末尾为原点进行计算。
+ fp.seekable() # 是否可以seek
+ fp.truncate([size]) # 把文件裁成规定的大小,默认的是裁到当前文件操作标记的位置。
+ for line in open('data'):
+ print(line) # 使用for语句,比较适用于打开比较大的文件
+ with open('data') as file:
+ print(file.readline()) # 使用with语句,可以保证文件关闭
+ with open('data') as file:
+ lines = file.readlines() # 一次读入文件所有行,并关闭文件
+ open('f.txt', encoding = 'latin-1') # Python3.x Unicode文本文件
+ open('f.bin', 'rb') # Python3.x 二进制bytes文件
+ # 文件对象还有相应的属性:buffer closed encoding errors line_buffering name newlines等
+
+#-- 其他
+ # Python中的真假值含义:1. 数字如果非零,则为真,0为假。 2. 其他对象如果非空,则为真
+ # 通常意义下的类型分类:1. 数字、序列、映射。 2. 可变类型和不可变类型
+
+
+"""语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句----语法和语句"""
+
+#-- 赋值语句的形式
+ spam = 'spam' # 基本形式
+ spam, ham = 'spam', 'ham' # 元组赋值形式
+ [spam, ham] = ['s', 'h'] # 列表赋值形式
+ a, b, c, d = 'abcd' # 序列赋值形式
+ a, *b, c = 'spam' # 序列解包形式(Python3.x中才有)
+ spam = ham = 'no' # 多目标赋值运算,涉及到共享引用
+ spam += 42 # 增强赋值,涉及到共享引用
+
+#-- 序列赋值 序列解包
+ [a, b, c] = (1, 2, 3) # a = 1, b = 2, c = 3
+ a, b, c, d = "spam" # a = 's', b = 'p', c = 'a', d = 'm'
+ a, b, c = range(3) # a = 0, b = 1, c = 2
+ a, *b = [1, 2, 3, 4] # a = 1, b = [2, 3, 4]
+ *a, b = [1, 2, 3, 4] # a = [1, 2, 3], b = 4
+ a, *b, c = [1, 2, 3, 4] # a = 1, b = [2, 3], c = 4
+ # 带有*时 会优先匹配*之外的变量 如
+ a, *b, c = [1, 2] # a = 1, c = 2, b = []
+
+#-- print函数原型
+ print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
+ # 流的重定向
+ print('hello world') # 等于sys.stdout.write('hello world')
+ temp = sys.stdout # 原有流的保存
+ sys.stdout = open('log.log', 'a') # 流的重定向
+ print('hello world') # 写入到文件log.log
+ sys.stdout.close()
+ sys.stdout = temp # 原有流的复原
+
+#-- Python中and或or总是返回对象(左边的对象或右边的对象) 且具有短路求值的特性
+ 1 or 2 or 3 # 返回 1
+ 1 and 2 and 3 # 返回 3
+
+#-- if/else三元表达符(if语句在行内)
+ A = 1 if X else 2
+ A = 1 if X else (2 if Y else 3)
+ # 也可以使用and-or语句(一条语句实现多个if-else)
+ a = 6
+ result = (a > 20 and "big than 20" or a > 10 and "big than 10" or a > 5 and "big than 5") # 返回"big than 5"
+
+#-- Python的while语句或者for语句可以带else语句 当然也可以带continue/break/pass语句
+ while a > 1:
+ anything
+ else:
+ anything
+ # else语句会在循环结束后执行,除非在循环中执行了break,同样的还有for语句
+ for i in range(5):
+ anything
+ else:
+ anything
+
+#-- for循环的元组赋值
+ for (a, b) in [(1, 2), (3, 4)]: # 最简单的赋值
+ for ((a, b), c) in [((1, 2), 3), ((4, 5), 6)]: # 自动解包赋值
+ for ((a, b), c) in [((1, 2), 3), ("XY", 6)]: # 自动解包 a = X, b = Y, c = 6
+ for (a, *b) in [(1, 2, 3), (4, 5, 6)]: # 自动解包赋值
+
+#-- 列表解析语法
+ M = [[1,2,3], [4,5,6], [7,8,9]]
+ res = [sum(row) for row in M] # G = [6, 15, 24] 一般的列表解析 生成一个列表
+ res = [c * 2 for c in 'spam'] # ['ss', 'pp', 'aa', 'mm']
+ res = [a * b for a in [1, 2] for b in [4, 5]] # 多解析过程 返回[4, 5, 8, 10]
+ res = [a for a in [1, 2, 3] if a < 2] # 带判断条件的解析过程
+ res = [a if a > 0 else 0 for a in [-1, 0, 1]] # 带判断条件的高级解析过程
+ # 两个列表同时解析:使用zip函数
+ for teama, teamb in zip(["Packers", "49ers"], ["Ravens", "Patriots"]):
+ print(teama + " vs. " + teamb)
+ # 带索引的列表解析:使用enumerate函数
+ for index, team in enumerate(["Packers", "49ers", "Ravens", "Patriots"]):
+ print(index, team) # 输出0, Packers \n 1, 49ers \n ......
+
+#-- 生成器表达式
+ G = (sum(row) for row in M) # 使用小括号可以创建所需结果的生成器generator object
+ next(G), next(G), next(G) # 输出(6, 15, 24)
+ G = {sum(row) for row in M} # G = {6, 15, 24} 解析语法还可以生成集合和字典
+ G = {i:sum(M[i]) for i in range(3)} # G = {0: 6, 1: 15, 2: 24}
+
+#-- 文档字符串:出现在Module的开端以及其中函数或类的开端 使用三重引号字符串
+ """
+ module document
+ """
+ def func():
+ """
+ function document
+ """
+ print()
+ class Employee(object):
+ """
+ class document
+ """
+ print()
+ print(func.__doc__) # 输出函数文档字符串
+ print(Employee.__doc__) # 输出类的文档字符串
+
+#-- 命名惯例:
+ """
+ 以单一下划线开头的变量名(_X)不会被from module import*等语句导入
+ 前后有两个下划线的变量名(__X__)是系统定义的变量名,对解释器有特殊意义
+ 以两个下划线开头但不以下划线结尾的变量名(__X)是类的本地(私有)变量
+ """
+
+#-- 列表解析 in成员关系测试 map sorted zip enumerate内置函数等都使用了迭代协议
+ 'first line' in open('test.txt') # in测试 返回True或False
+ list(map(str.upper, open('t'))) # map内置函数
+ sorted(iter([2, 5, 8, 3, 1])) # sorted内置函数
+ list(zip([1, 2], [3, 4])) # zip内置函数 [(1, 3), (2, 4)]
+
+#-- del语句: 手动删除某个变量
+ del X
+
+#-- 获取列表的子表的方法:
+ x = [1,2,3,4,5,6]
+ x[:3] # 前3个[1,2,3]
+ x[1:5] # 中间4个[2,3,4,5]
+ x[-3:] # 最后3个[4,5,6]
+ x[::2] # 奇数项[1,3,5]
+ x[1::2] # 偶数项[2,4,6]
+
+#-- 手动迭代:iter和next
+ L = [1, 2]
+ I = iter(L) # I为L的迭代器
+ I.next() # 返回1
+ I.next() # 返回2
+ I.next() # Error:StopIteration
+
+#-- Python中的可迭代对象
+ """
+ 1.range迭代器
+ 2.map、zip和filter迭代器
+ 3.字典视图迭代器:D.keys()), D.items()等
+ 4.文件类型
+ """
+
+
+"""函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则----函数语法规则"""
+
+#-- 函数相关的语句和表达式
+ myfunc('spam') # 函数调用
+ def myfunc(): # 函数定义
+ return None # 函数返回值
+ global a # 全局变量
+ nonlocal x # 在函数或其他作用域中使用外层(非全局)变量
+ yield x # 生成器函数返回
+ lambda # 匿名函数
+
+#-- Python函数变量名解析:LEGB原则,即:
+ """
+ local(functin) --> encloseing function locals --> global(module) --> build-in(python)
+ 说明:以下边的函数maker为例 则相对于action而言 X为Local N为Encloseing
+ """
+
+#-- 嵌套函数举例:工厂函数
+ def maker(N):
+ def action(X):
+ return X ** N
+ return action
+ f = maker(2) # pass 2 to N
+ f(3) # 9, pass 3 to X
+
+#-- 嵌套函数举例:lambda实例
+ def maker(N):
+ action = (lambda X: X**N)
+ return action
+ f = maker(2) # pass 2 to N
+ f(3) # 9, pass 3 to X
+
+#-- nonlocal和global语句的区别
+ # nonlocal应用于一个嵌套的函数的作用域中的一个名称 例如:
+ start = 100
+ def tester(start):
+ def nested(label):
+ nonlocal start # 指定start为tester函数内的local变量 而不是global变量start
+ print(label, start)
+ start += 3
+ return nested
+ # global为全局的变量 即def之外的变量
+ def tester(start):
+ def nested(label):
+ global start # 指定start为global变量start
+ print(label, start)
+ start += 3
+ return nested
+
+#-- 函数参数,不可变参数通过“值”传递,可变参数通过“引用”传递
+ def f(a, b, c): print(a, b, c)
+ f(1, 2, 3) # 参数位置匹配
+ f(1, c = 3, b = 2) # 参数关键字匹配
+ def f(a, b=1, c=2): print(a, b, c)
+ f(1) # 默认参数匹配
+ f(1, 2) # 默认参数匹配
+ f(a = 1, c = 3) # 关键字参数和默认参数的混合
+ # Keyword-Only参数:出现在*args之后 必须用关键字进行匹配
+ def keyOnly(a, *b, c): print('') # c就为keyword-only匹配 必须使用关键字c = value匹配
+ def keyOnly(a, *, b, c): ...... # b c为keyword-only匹配 必须使用关键字匹配
+ def keyOnly(a, *, b = 1): ...... # b有默认值 或者省略 或者使用关键字参数b = value
+
+#-- 可变参数匹配: * 和 **
+ def f(*args): print(args) # 在元组中收集不匹配的位置参数
+ f(1, 2, 3) # 输出(1, 2, 3)
+ def f(**args): print(args) # 在字典中收集不匹配的关键字参数
+ f(a = 1, b = 2) # 输出{'a':1, 'b':2}
+ def f(a, *b, **c): print(a, b, c) # 两者混合使用
+ f(1, 2, 3, x=4, y=5) # 输出1, (2, 3), {'x':4, 'y':5}
+
+#-- 函数调用时的参数解包: * 和 ** 分别解包元组和字典
+ func(1, *(2, 3)) <==> func(1, 2, 3)
+ func(1, **{'c':3, 'b':2}) <==> func(1, b = 2, c = 3)
+ func(1, *(2, 3), **{'c':3, 'b':2}) <==> func(1, 2, 3, b = 2, c = 3)
+
+#-- 函数属性:(自己定义的)函数可以添加属性
+ def func():.....
+ func.count = 1 # 自定义函数添加属性
+ print.count = 1 # Error 内置函数不可以添加属性
+
+#-- 函数注解: 编写在def头部行 主要用于说明参数范围、参数类型、返回值类型等
+ def func(a:'spam', b:(1, 10), c:float) -> int :
+ print(a, b, c)
+ func.__annotations__ # {'c':, 'b':(1, 10), 'a':'spam', 'return':}
+ # 编写注解的同时 还是可以使用函数默认值 并且注解的位置位于=号的前边
+ def func(a:'spam'='a', b:(1, 10)=2, c:float=3) -> int :
+ print(a, b, c)
+
+#-- 匿名函数:lambda
+ f = lambda x, y, z : x + y + z # 普通匿名函数,使用方法f(1, 2, 3)
+ f = lambda x = 1, y = 1: x + y # 带默认参数的lambda函数
+ def action(x): # 嵌套lambda函数
+ return (lambda y : x + y)
+ f = lambda: a if xxx() else b # 无参数的lambda函数,使用方法f()
+
+#-- lambda函数与map filter reduce函数的结合
+ list(map((lambda x: x + 1), [1, 2, 3])) # [2, 3, 4]
+ list(filter((lambda x: x > 0), range(-4, 5))) # [1, 2, 3, 4]
+ functools.reduce((lambda x, y: x + y), [1, 2, 3]) # 6
+ functools.reduce((lambda x, y: x * y), [2, 3, 4]) # 24
+
+#-- 生成器函数:yield VS return
+ def gensquare(N):
+ for i in range(N):
+ yield i** 2 # 状态挂起 可以恢复到此时的状态
+ for i in gensquare(5): # 使用方法
+ print(i, end = ' ') # [0, 1, 4, 9, 16]
+ x = gensquare(2) # x是一个生成对象
+ next(x) # 等同于x.__next__() 返回0
+ next(x) # 等同于x.__next__() 返回1
+ next(x) # 等同于x.__next__() 抛出异常StopIteration
+
+#-- 生成器表达式:小括号进行列表解析
+ G = (x ** 2 for x in range(3)) # 使用小括号可以创建所需结果的生成器generator object
+ next(G), next(G), next(G) # 和上述中的生成器函数的返回值一致
+ #(1)生成器(生成器函数/生成器表达式)是单个迭代对象
+ G = (x ** 2 for x in range(4))
+ I1 = iter(G) # 这里实际上iter(G) = G
+ next(I1) # 输出0
+ next(G) # 输出1
+ next(I1) # 输出4
+ #(2)生成器不保留迭代后的结果
+ gen = (i for i in range(4))
+ 2 in gen # 返回True
+ 3 in gen # 返回True
+ 1 in gen # 返回False,其实检测2的时候,1已经就不在生成器中了,即1已经被迭代过了,同理2、3也不在了
+
+#-- 本地变量是静态检测的
+ X = 22 # 全局变量X的声明和定义
+ def test():
+ print(X) # 如果没有下一语句 则该句合法 打印全局变量X
+ X = 88 # 这一语句使得上一语句非法 因为它使得X变成了本地变量 上一句变成了打印一个未定义的本地变量(局部变量)
+ if False: # 即使这样的语句 也会把print语句视为非法语句 因为:
+ X = 88 # Python会无视if语句而仍然声明了局部变量X
+ def test(): # 改进
+ global X # 声明变量X为全局变量
+ print(X) # 打印全局变量X
+ X = 88 # 改变全局变量X
+
+#-- 函数的默认值是在函数定义的时候实例化的 而不是在调用的时候 例子:
+ def foo(numbers=[]): # 这里的[]是可变的
+ numbers.append(9)
+ print(numbers)
+ foo() # first time, like before, [9]
+ foo() # second time, not like before, [9, 9]
+ foo() # third time, not like before too, [9, 9, 9]
+ # 改进:
+ def foo(numbers=None):
+ if numbers is None: numbers = []
+ numbers.append(9)
+ print(numbers)
+ # 另外一个例子 参数的默认值为不可变的:
+ def foo(count=0): # 这里的0是数字, 是不可变的
+ count += 1
+ print(count)
+ foo() # 输出1
+ foo() # 还是输出1
+ foo(3) # 输出4
+ foo() # 还是输出1
+
+
+"""函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子----函数例子"""
+
+ """数学运算类"""
+ abs(x) # 求绝对值,参数可以是整型,也可以是复数,若参数是复数,则返回复数的模
+ complex([real[, imag]]) # 创建一个复数
+ divmod(a, b) # 分别取商和余数,注意:整型、浮点型都可以
+ float([x]) # 将一个字符串或数转换为浮点数。如果无参数将返回0.0
+ int([x[, base]]) # 将一个字符串或浮点数转换为int类型,base表示进制
+ long([x[, base]]) # 将一个字符串或浮点数转换为long类型
+ pow(x, y) # 返回x的y次幂
+ range([start], stop[, step]) # 产生一个序列,默认从0开始
+ round(x[, n]) # 四舍五入
+ sum(iterable[, start]) # 对集合求和
+ oct(x) # 将一个数字转化为8进制字符串
+ hex(x) # 将一个数字转换为16进制字符串
+ chr(i) # 返回给定int类型对应的ASCII字符
+ unichr(i) # 返回给定int类型的unicode
+ ord(c) # 返回ASCII字符对应的整数
+ bin(x) # 将整数x转换为二进制字符串
+ bool([x]) # 将x转换为Boolean类型
+
+ """集合类操作"""
+ basestring() # str和unicode的超类,不能直接调用,可以用作isinstance判断
+ format(value [, format_spec]) # 格式化输出字符串,格式化的参数顺序从0开始,如“I am {0},I like {1}”
+ enumerate(sequence[, start=0]) # 返回一个可枚举的对象,注意它有第二个参数
+ iter(obj[, sentinel]) # 生成一个对象的迭代器,第二个参数表示分隔符
+ max(iterable[, args...][key]) # 返回集合中的最大值
+ min(iterable[, args...][key]) # 返回集合中的最小值
+ dict([arg]) # 创建数据字典
+ list([iterable]) # 将一个集合类转换为另外一个集合类
+ set() # set对象实例化
+ frozenset([iterable]) # 产生一个不可变的set
+ tuple([iterable]) # 生成一个tuple类型
+ str([object]) # 转换为string类型
+ sorted(iterable[, cmp[, key[, reverse]]]) # 集合排序
+ L = [('b',2),('a',1),('c',3),('d',4)]
+ sorted(L, key=lambda x: x[1]), reverse=True) # 使用Key参数和reverse参数
+ sorted(L, key=lambda x: (x[0], x[1])) # 使用key参数进行多条件排序,即如果x[0]相同,则比较x[1]
+
+ """逻辑判断"""
+ all(iterable) # 集合中的元素都为真的时候为真,特别的,若为空串返回为True
+ any(iterable) # 集合中的元素有一个为真的时候为真,特别的,若为空串返回为False
+ cmp(x, y) # 如果x < y ,返回负数;x == y, 返回0;x > y,返回正数
+
+ """IO操作"""
+ file(filename [, mode [, bufsize]]) # file类型的构造函数。
+ input([prompt]) # 获取用户输入,推荐使用raw_input,因为该函数将不会捕获用户的错误输入,意思是自行判断类型
+ # 在 Built-in Functions 里有一句话是这样写的:Consider using the raw_input() function for general input from users.
+ raw_input([prompt]) # 设置输入,输入都是作为字符串处理
+ open(name[, mode[, buffering]]) # 打开文件,与file有什么不同?推荐使用open
+
+ """其他"""
+ callable(object) # 检查对象object是否可调用
+ classmethod(func) # 用来说明这个func是个类方法
+ staticmethod(func) # 用来说明这个func为静态方法
+ dir([object]) # 不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。
+ help(obj) # 返回obj的帮助信息
+ eval(expression) # 计算表达式expression的值,并返回
+ exec(str) # 将str作为Python语句执行
+ execfile(filename) # 用法类似exec(),不同的是execfile的参数filename为文件名,而exec的参数为字符串。
+ filter(function, iterable) # 构造一个序列,等价于[item for item in iterable if function(item)],function返回值为True或False的函数
+ list(filter(bool, range(-3, 4)))# 返回[-3, -2, -1, 1, 2, 3], 没有0
+ hasattr(object, name) # 判断对象object是否包含名为name的特性
+ getattr(object, name [, defalut]) # 获取一个类的属性
+ setattr(object, name, value) # 设置属性值
+ delattr(object, name) # 删除object对象名为name的属性
+ globals() # 返回一个描述当前全局符号表的字典
+ hash(object) # 如果对象object为哈希表类型,返回对象object的哈希值
+ id(object) # 返回对象的唯一标识,一串数字
+ isinstance(object, classinfo) # 判断object是否是class的实例
+ isinstance(1, int) # 判断是不是int类型
+ isinstance(1, (int, float)) # isinstance的第二个参数接受一个元组类型
+ issubclass(class, classinfo) # 判断class是否为classinfo的子类
+ locals() # 返回当前的变量列表
+ map(function, iterable, ...) # 遍历每个元素,执行function操作
+ list(map(abs, range(-3, 4))) # 返回[3, 2, 1, 0, 1, 2, 3]
+ next(iterator[, default]) # 类似于iterator.next()
+ property([fget[, fset[, fdel[, doc]]]]) # 属性访问的包装类,设置后可以通过c.x=value等来访问setter和getter
+ reduce(function, iterable[, initializer]) # 合并操作,从第一个开始是前两个参数,然后是前两个的结果与第三个合并进行处理,以此类推
+ def add(x,y):return x + y
+ reduce(add, range(1, 11)) # 返回55 (注:1+2+3+4+5+6+7+8+9+10 = 55)
+ reduce(add, range(1, 11), 20) # 返回75
+ reload(module) # 重新加载模块
+ repr(object) # 将一个对象变幻为可打印的格式
+ slice(start, stop[, step]) # 产生分片对象
+ type(object) # 返回该object的类型
+ vars([object]) # 返回对象的变量名、变量值的字典
+ a = Class(); # Class为一个空类
+ a.name = 'qi', a.age = 9
+ vars(a) # {'name':'qi', 'age':9}
+ zip([iterable, ...]) # 返回对应数组
+ list(zip([1, 2, 3], [4, 5, 6])) # [(1, 4), (2, 5), (3, 6)]
+ a = [1, 2, 3], b = ["a", "b", "c"]
+ z = zip(a, b) # 压缩:[(1, "a"), (2, "b"), (3, "c")]
+ zip(*z) # 解压缩:[(1, 2, 3), ("a", "b", "c")]
+ unicode(string, encoding, errors) # 将字符串string转化为unicode形式,string为encoded string。
+
+
+"""模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle----模块Moudle"""
+
+#-- Python模块搜索路径:
+ """
+ (1)程序的主目录 (2)PYTHONPATH目录 (3)标准链接库目录 (4)任何.pth文件的内容
+ """
+
+#-- 查看全部的模块搜索路径
+ import sys
+ sys.path
+ sys.argv # 获得脚本的参数
+ sys.builtin_module_names # 查找内建模块
+ sys.platform # 返回当前平台 出现如: "win32" "linux" "darwin"等
+ sys.modules # 查找已导入的模块
+ sys.modules.keys()
+ sys.stdout # stdout 和 stderr 都是类文件对象,但是它们都是只写的。它们都没有 read 方法,只有 write 方法
+ sys.stdout.write("hello")
+ sys.stderr
+ sys.stdin
+
+#-- 模块的使用代码
+ import module1, module2 # 导入module1 使用module1.printer()
+ from module1 import printer # 导入module1中的printer变量 使用printer()
+ from module1 import * # 导入module1中的全部变量 使用不必添加module1前缀
+
+#-- 重载模块reload: 这是一个内置函数 而不是一条语句
+ from imp import reload
+ reload(module)
+
+#-- 模块的包导入:使用点号(.)而不是路径(dir1\dir2)进行导入
+ import dir1.dir2.mod # d导入包(目录)dir1中的包dir2中的mod模块 此时dir1必须在Python可搜索路径中
+ from dir1.dir2.mod import * # from语法的包导入
+
+#-- __init__.py包文件:每个导入的包中都应该包含这么一个文件
+ """
+ 该文件可以为空
+ 首次进行包导入时 该文件会自动执行
+ 高级功能:在该文件中使用__all__列表来定义包(目录)以from*的形式导入时 需要导入什么
+ """
+
+#-- 包相对导入:使用点号(.) 只能使用from语句
+ from . import spam # 导入当前目录下的spam模块(Python2: 当前目录下的模块, 直接导入即可)
+ from .spam import name # 导入当前目录下的spam模块的name属性(Python2: 当前目录下的模块, 直接导入即可,不用加.)
+ from .. import spam # 导入当前目录的父目录下的spam模块
+
+#-- 包相对导入与普通导入的区别
+ from string import * # 这里导入的string模块为sys.path路径上的 而不是本目录下的string模块(如果存在也不是)
+ from .string import * # 这里导入的string模块为本目录下的(不存在则导入失败) 而不是sys.path路径上的
+
+#-- 模块数据隐藏:最小化from*的破坏
+ _X # 变量名前加下划线可以防止from*导入时该变量名被复制出去
+ __all__ = ['x', 'x1', 'x2'] # 使用__all__列表指定from*时复制出去的变量名(变量名在列表中为字符串形式)
+
+#-- 可以使用__name__进行模块的单元测试:当模块为顶层执行文件时值为'__main__' 当模块被导入时为模块名
+ if __name__ == '__main__':
+ doSomething
+ # 模块属性中还有其他属性,例如:
+ __doc__ # 模块的说明文档
+ __file__ # 模块文件的文件名,包括全路径
+ __name__ # 主文件或者被导入文件
+ __package__ # 模块所在的包
+
+#-- import语句from语句的as扩展
+ import modulename as name
+ from modulename import attrname as name
+
+#-- 得到模块属性的几种方法 假设为了得到name属性的值
+ M.name
+ M.__dict__['name']
+ sys.modules['M'].name
+ getattr(M, 'name')
+
+
+"""类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象----类与面向对象"""
+
+#-- 最普通的类
+ class C1(C2, C3):
+ spam = 42 # 数据属性
+ def __init__(self, name): # 函数属性:构造函数
+ self.name = name
+ def __del__(self): # 函数属性:析构函数
+ print("goodbey ", self.name)
+ I1 = C1('bob')
+
+#-- Python的类没有基于参数的函数重载
+ class FirstClass(object):
+ def test(self, string):
+ print(string)
+ def test(self): # 此时类中只有一个test函数 即后者test(self) 它覆盖掉前者带参数的test函数
+ print("hello world")
+
+#-- 子类扩展超类: 尽量调用超类的方法
+ class Manager(Person):
+ def giveRaise(self, percent, bonus = .10):
+ self.pay = int(self.pay*(1 + percent + bonus)) # 不好的方式 复制粘贴超类代码
+ Person.giveRaise(self, percent + bonus) # 好的方式 尽量调用超类方法
+
+#-- 类内省工具
+ bob = Person('bob')
+ bob.__class__ #
+ bob.__class__.__name__ # 'Person'
+ bob.__dict__ # {'pay':0, 'name':'bob', 'job':'Manager'}
+
+#-- 返回1中 数据属性spam是属于类 而不是对象
+ I1 = C1('bob'); I2 = C2('tom') # 此时I1和I2的spam都为42 但是都是返回的C1的spam属性
+ C1.spam = 24 # 此时I1和I2的spam都为24
+ I1.spam = 3 # 此时I1新增自有属性spam 值为3 I2和C1的spam还都为24
+
+#-- 类方法调用的两种方式
+ instance.method(arg...)
+ class.method(instance, arg...)
+
+#-- 抽象超类的实现方法
+ # (1)某个函数中调用未定义的函数 子类中定义该函数
+ def delegate(self):
+ self.action() # 本类中不定义action函数 所以使用delegate函数时就会出错
+ # (2)定义action函数 但是返回异常
+ def action(self):
+ raise NotImplementedError("action must be defined")
+ # (3)上述的两种方法还都可以定义实例对象 实际上可以利用@装饰器语法生成不能定义的抽象超类
+ from abc import ABCMeta, abstractmethod
+ class Super(metaclass = ABCMeta):
+ @abstractmethod
+ def action(self): pass
+ x = Super() # 返回 TypeError: Can't instantiate abstract class Super with abstract methods action
+
+#-- # OOP和继承: "is-a"的关系
+ class A(B):
+ pass
+ a = A()
+ isinstance(a, B) # 返回True, A是B的子类 a也是B的一种
+ # OOP和组合: "has-a"的关系
+ pass
+ # OOP和委托: "包装"对象 在Python中委托通常是以"__getattr__"钩子方法实现的, 这个方法会拦截对不存在属性的读取
+ # 包装类(或者称为代理类)可以使用__getattr__把任意读取转发给被包装的对象
+ class wrapper(object):
+ def __init__(self, object):
+ self.wrapped = object
+ def __getattr(self, attrname):
+ print('Trace: ', attrname)
+ return getattr(self.wrapped, attrname)
+ # 注:这里使用getattr(X, N)内置函数以变量名字符串N从包装对象X中取出属性 类似于X.__dict__[N]
+ x = wrapper([1, 2, 3])
+ x.append(4) # 返回 "Trace: append" [1, 2, 3, 4]
+ x = wrapper({'a':1, 'b':2})
+ list(x.keys()) # 返回 "Trace: keys" ['a', 'b']
+
+#-- 类的伪私有属性:使用__attr
+ class C1(object):
+ def __init__(self, name):
+ self.__name = name # 此时类的__name属性为伪私有属性 原理 它会自动变成self._C1__name = name
+ def __str__(self):
+ return 'self.name = %s' % self.__name
+ I = C1('tom')
+ print(I) # 返回 self.name = tom
+ I.__name = 'jeey' # 这里无法访问 __name为伪私有属性
+ I._C1__name = 'jeey' # 这里可以修改成功 self.name = jeey
+
+#-- 类方法是对象:无绑定类方法对象 / 绑定实例方法对象
+ class Spam(object):
+ def doit(self, message):
+ print(message)
+ def selfless(message)
+ print(message)
+ obj = Spam()
+ x = obj.doit # 类的绑定方法对象 实例 + 函数
+ x('hello world')
+ x = Spam.doit # 类的无绑定方法对象 类名 + 函数
+ x(obj, 'hello world')
+ x = Spam.selfless # 类的无绑定方法函数 在3.0之前无效
+ x('hello world')
+
+#-- 获取对象信息: 属性和方法
+ a = MyObject()
+ dir(a) # 使用dir函数
+ hasattr(a, 'x') # 测试是否有x属性或方法 即a.x是否已经存在
+ setattr(a, 'y', 19) # 设置属性或方法 等同于a.y = 19
+ getattr(a, 'z', 0) # 获取属性或方法 如果属性不存在 则返回默认值0
+ #这里有个小技巧,setattr可以设置一个不能访问到的属性,即只能用getattr获取
+ setattr(a, "can't touch", 100) # 这里的属性名带有空格,不能直接访问
+ getattr(a, "can't touch", 0) # 但是可以用getattr获取
+
+#-- 为类动态绑定属性或方法: MethodType方法
+ # 一般创建了一个class的实例后, 可以给该实例绑定任何属性和方法, 这就是动态语言的灵活性
+ class Student(object):
+ pass
+ s = Student()
+ s.name = 'Michael' # 动态给实例绑定一个属性
+ def set_age(self, age): # 定义一个函数作为实例方法
+ self.age = age
+ from types import MethodType
+ s.set_age = MethodType(set_age, s) # 给实例绑定一个方法 类的其他实例不受此影响
+ s.set_age(25) # 调用实例方法
+ Student.set_age = MethodType(set_age, Student) # 为类绑定一个方法 类的所有实例都拥有该方法
+
+
+"""类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题----类的高级话题"""
+
+#-- 多重继承: "混合类", 搜索方式"从下到上 从左到右 广度优先"
+ class A(B, C):
+ pass
+
+#-- 类的继承和子类的初始化
+ # 1.子类定义了__init__方法时,若未显示调用基类__init__方法,python不会帮你调用。
+ # 2.子类未定义__init__方法时,python会自动帮你调用首个基类的__init__方法,注意是首个。
+ # 3.子类显示调用基类的初始化函数:
+ class FooParent(object):
+ def __init__(self, a):
+ self.parent = 'I\'m the Parent.'
+ print('Parent:a=' + str(a))
+ def bar(self, message):
+ print(message + ' from Parent')
+ class FooChild(FooParent):
+ def __init__(self, a):
+ FooParent.__init__(self, a)
+ print('Child:a=' + str(a))
+ def bar(self, message):
+ FooParent.bar(self, message)
+ print(message + ' from Child')
+ fooChild = FooChild(10)
+ fooChild.bar('HelloWorld')
+
+#-- #实例方法 / 静态方法 / 类方法
+ class Methods(object):
+ def imeth(self, x): print(self, x) # 实例方法:传入的是实例和数据,操作的是实例的属性
+ def smeth(x): print(x) # 静态方法:只传入数据 不传入实例,操作的是类的属性而不是实例的属性
+ def cmeth(cls, x): print(cls, x) # 类方法:传入的是类对象和数据
+ smeth = staticmethod(smeth) # 调用内置函数,也可以使用@staticmethod
+ cmeth = classmethod(cmeth) # 调用内置函数,也可以使用@classmethod
+ obj = Methods()
+ obj.imeth(1) # 实例方法调用 <__main__.Methods object...> 1
+ Methods.imeth(obj, 2) # <__main__.Methods object...> 2
+ Methods.smeth(3) # 静态方法调用 3
+ obj.smeth(4) # 这里可以使用实例进行调用
+ Methods.cmeth(5) # 类方法调用 5
+ obj.cmeth(6) # 6
+
+#-- 函数装饰器:是它后边的函数的运行时的声明 由@符号以及后边紧跟的"元函数"(metafunction)组成
+ @staticmethod
+ def smeth(x): print(x)
+ # 等同于:
+ def smeth(x): print(x)
+ smeth = staticmethod(smeth)
+ # 同理
+ @classmethod
+ def cmeth(cls, x): print(x)
+ # 等同于
+ def cmeth(cls, x): print(x)
+ cmeth = classmethod(cmeth)
+
+#-- 类修饰器:是它后边的类的运行时的声明 由@符号以及后边紧跟的"元函数"(metafunction)组成
+ def decorator(aClass):.....
+ @decorator
+ class C(object):....
+ # 等同于:
+ class C(object):....
+ C = decorator(C)
+
+#-- 限制class属性: __slots__属性
+ class Student(object):
+ __slots__ = ('name', 'age') # 限制Student及其实例只能拥有name和age属性
+ # __slots__属性只对当前类起作用, 对其子类不起作用
+ # __slots__属性能够节省内存
+ # __slots__属性可以为列表list,或者元组tuple
+
+#-- 类属性高级话题: @property
+ # 假设定义了一个类:C,该类必须继承自object类,有一私有变量_x
+ class C(object):
+ def __init__(self):
+ self.__x = None
+ # 第一种使用属性的方法
+ def getx(self):
+ return self.__x
+ def setx(self, value):
+ self.__x = value
+ def delx(self):
+ del self.__x
+ x = property(getx, setx, delx, '')
+ # property函数原型为property(fget=None,fset=None,fdel=None,doc=None)
+ # 使用
+ c = C()
+ c.x = 100 # 自动调用setx方法
+ y = c.x # 自动调用getx方法
+ del c.x # 自动调用delx方法
+ # 第二种方法使用属性的方法
+ @property
+ def x(self):
+ return self.__x
+ @x.setter
+ def x(self, value):
+ self.__x = value
+ @x.deleter
+ def x(self):
+ del self.__x
+ # 使用
+ c = C()
+ c.x = 100 # 自动调用setter方法
+ y = c.x # 自动调用x方法
+ del c.x # 自动调用deleter方法
+
+#-- 定制类: 重写类的方法
+ # (1)__str__方法、__repr__方法: 定制类的输出字符串
+ # (2)__iter__方法、next方法: 定制类的可迭代性
+ class Fib(object):
+ def __init__(self):
+ self.a, self.b = 0, 1 # 初始化两个计数器a,b
+ def __iter__(self):
+ return self # 实例本身就是迭代对象,故返回自己
+ def next(self):
+ self.a, self.b = self.b, self.a + self.b
+ if self.a > 100000: # 退出循环的条件
+ raise StopIteration()
+ return self.a # 返回下一个值
+ for n in Fib():
+ print(n) # 使用
+ # (3)__getitem__方法、__setitem__方法: 定制类的下标操作[] 或者切片操作slice
+ class Indexer(object):
+ def __init__(self):
+ self.data = {}
+ def __getitem__(self, n): # 定义getitem方法
+ print('getitem:', n)
+ return self.data[n]
+ def __setitem__(self, key, value): # 定义setitem方法
+ print('setitem:key = {0}, value = {1}'.format(key, value))
+ self.data[key] = value
+ test = Indexer()
+ test[0] = 1; test[3] = '3' # 调用setitem方法
+ print(test[0]) # 调用getitem方法
+ # (4)__getattr__方法: 定制类的属性操作
+ class Student(object):
+ def __getattr__(self, attr): # 定义当获取类的属性时的返回值
+ if attr=='age':
+ return 25 # 当获取age属性时返回25
+ raise AttributeError('object has no attribute: %s' % attr)
+ # 注意: 只有当属性不存在时 才会调用该方法 且该方法默认返回None 需要在函数最后引发异常
+ s = Student()
+ s.age # s中age属性不存在 故调用__getattr__方法 返回25
+ # (5)__call__方法: 定制类的'可调用'性
+ class Student(object):
+ def __call__(self): # 也可以带参数
+ print('Calling......')
+ s = Student()
+ s() # s变成了可调用的 也可以带参数
+ callable(s) # 测试s的可调用性 返回True
+ # (6)__len__方法:求类的长度
+ def __len__(self):
+ return len(self.data)
+
+#-- 动态创建类type()
+ # 一般创建类 需要在代码中提前定义
+ class Hello(object):
+ def hello(self, name='world'):
+ print('Hello, %s.' % name)
+ h = Hello()
+ h.hello() # Hello, world
+ type(Hello) # Hello是一个type类型 返回
+ type(h) # h是一个Hello类型 返回
+ # 动态类型语言中 类可以动态创建 type函数可用于创建新类型
+ def fn(self, name='world'): # 先定义函数
+ print('Hello, %s.' % name)
+ Hello = type('Hello', (object,), dict(hello=fn)) # 创建Hello类 type原型: type(name, bases, dict)
+ h = Hello() # 此时的h和上边的h一致
+
+
+"""异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关----异常相关"""
+
+#-- #捕获异常:
+ try:
+ except: # 捕获所有的异常 等同于except Exception:
+ except name: # 捕获指定的异常
+ except name, value: # 捕获指定的异常和额外的数据(实例)
+ except (name1, name2):
+ except (name1, name2), value:
+ except name4 as X:
+ else: # 如果没有发生异常
+ finally: # 总会执行的部分
+ # 引发异常: raise子句(raise IndexError)
+ raise # raise instance of a class, raise IndexError()
+ raise # make and raise instance of a class, raise IndexError
+ raise # reraise the most recent exception
+
+#-- Python3.x中的异常链: raise exception from otherException
+ except Exception as X:
+ raise IndexError('Bad') from X
+
+#-- assert子句: assert ,
+ assert x < 0, 'x must be negative'
+
+#-- with/as环境管理器:作为常见的try/finally用法模式的替代方案
+ with expression [as variable], expression [as variable]:
+ # 例子:
+ with open('test.txt') as myfile:
+ for line in myfile: print(line)
+ # 等同于:
+ myfile = open('test.txt')
+ try:
+ for line in myfile: print(line)
+ finally:
+ myfile.close()
+
+#-- 用户自定义异常: class Bad(Exception):.....
+ """
+ Exception超类 / except基类即可捕获到其所有子类
+ Exception超类有默认的打印消息和状态 当然也可以定制打印显示:
+ """
+ class MyBad(Exception):
+ def __str__(self):
+ return '定制的打印消息'
+ try:
+ MyBad()
+ except MyBad as x:
+ print(x)
+
+#-- 用户定制异常数据
+ class FormatError(Exception):
+ def __init__(self, line ,file):
+ self.line = line
+ self.file = file
+ try:
+ raise FormatError(42, 'test.py')
+ except FormatError as X:
+ print('Error at ', X.file, X.line)
+ # 用户定制异常行为(方法):以记录日志为例
+ class FormatError(Exception):
+ logfile = 'formaterror.txt'
+ def __init__(self, line ,file):
+ self.line = line
+ self.file = file
+ def logger(self):
+ open(self.logfile, 'a').write('Error at ', self.file, self.line)
+ try:
+ raise FormatError(42, 'test.py')
+ except FormatError as X:
+ X.logger()
+
+#-- 关于sys.exc_info:允许一个异常处理器获取对最近引发的异常的访问
+ try:
+ ......
+ except:
+ # 此时sys.exc_info()返回一个元组(type, value, traceback)
+ # type:正在处理的异常的异常类型
+ # value:引发的异常的实例
+ # traceback:堆栈信息
+
+#-- 异常层次
+ BaseException
+ +-- SystemExit
+ +-- KeyboardInterrupt
+ +-- GeneratorExit
+ +-- Exception
+ +-- StopIteration
+ +-- ArithmeticError
+ +-- AssertionError
+ +-- AttributeError
+ +-- BufferError
+ +-- EOFError
+ +-- ImportError
+ +-- LookupError
+ +-- MemoryError
+ +-- NameError
+ +-- OSError
+ +-- ReferenceError
+ +-- RuntimeError
+ +-- SyntaxError
+ +-- SystemError
+ +-- TypeError
+ +-- ValueError
+ +-- Warning
+
+
+"""Unicode和字节字符串---Unicode和字节字符串----Unicode和字节字符串----Unicode和字节字符串----Unicode和字节字符串----Unicode和字节字符串----Unicode和字节字符串"""
+
+#-- Python的字符串类型
+ """Python2.x"""
+ # 1.str表示8位文本和二进制数据
+ # 2.unicode表示宽字符Unicode文本
+ """Python3.x"""
+ # 1.str表示Unicode文本(8位或者更宽)
+ # 2.bytes表示不可变的二进制数据
+ # 3.bytearray是一种可变的bytes类型
+
+#-- 字符编码方法
+ """ASCII""" # 一个字节,只包含英文字符,0到127,共128个字符,利用函数可以进行字符和数字的相互转换
+ ord('a') # 字符a的ASCII码为97,所以这里返回97
+ chr(97) # 和上边的过程相反,返回字符'a'
+ """Latin-1""" # 一个字节,包含特殊字符,0到255,共256个字符,相当于对ASCII码的扩展
+ chr(196) # 返回一个特殊字符:Ä
+ """Unicode""" # 宽字符,一个字符包含多个字节,一般用于亚洲的字符集,比如中文有好几万字
+ """UTF-8""" # 可变字节数,小于128的字符表示为单个字节,128到0X7FF之间的代码转换为两个字节,0X7FF以上的代码转换为3或4个字节
+ # 注意:可以看出来,ASCII码是Latin-1和UTF-8的一个子集
+ # 注意:utf-8是unicode的一种实现方式,unicode、gbk、gb2312是编码字符集
+
+#-- 查看Python中的字符串编码名称,查看系统的编码
+ import encodings
+ help(encoding)
+ import sys
+ sys.platform # 'win64'
+ sys.getdefaultencoding() # 'utf-8'
+ sys.getdefaultencoding() # 返回当前系统平台的编码类型
+ sys.getsizeof(object) # 返回object占有的bytes的大小
+
+#-- 源文件字符集编码声明: 添加注释来指定想要的编码形式 从而改变默认值 注释必须出现在脚本的第一行或者第二行
+ """说明:其实这里只会检查#和coding:utf-8,其余的字符都是为了美观加上的"""
+ # _*_ coding: utf-8 _*_
+ # coding = utf-8
+
+#-- #编码: 字符串 --> 原始字节 #解码: 原始字节 --> 字符串
+
+#-- Python3.x中的字符串应用
+ s = '...' # 构建一个str对象,不可变对象
+ b = b'...' # 构建一个bytes对象,不可变对象
+ s[0], b[0] # 返回('.', 113)
+ s[1:], b[1:] # 返回('..', b'..')
+ B = B"""
+ xxxx
+ yyyy
+ """
+ # B = b'\nxxxx\nyyyy\n'
+ # 编码,将str字符串转化为其raw bytes形式:
+ str.encode(encoding = 'utf-8', errors = 'strict')
+ bytes(str, encoding)
+ # 编码例子:
+ S = 'egg'
+ S.encode() # b'egg'
+ bytes(S, encoding = 'ascii') # b'egg'
+ # 解码,将raw bytes字符串转化为str形式:
+ bytes.decode(encoding = 'utf-8', errors = 'strict')
+ str(bytes_or_buffer[, encoding[, errors]])
+ # 解码例子:
+ B = b'spam'
+ B.decode() # 'spam'
+ str(B) # "b'spam'",不带编码的str调用,结果为打印该bytes对象
+ str(B, encoding = 'ascii')# 'spam',带编码的str调用,结果为转化该bytes对象
+
+#-- Python2.x的编码问题
+ u = u'汉'
+ print repr(u) # u'\xba\xba'
+ s = u.encode('UTF-8')
+ print repr(s) # '\xc2\xba\xc2\xba'
+ u2 = s.decode('UTF-8')
+ print repr(u2) # u'\xba\xba'
+ # 对unicode进行解码是错误的
+ s2 = u.decode('UTF-8') # UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
+ # 同样,对str进行编码也是错误的
+ u2 = s.encode('UTF-8') # UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128)
+
+#-- bytes对象
+ B = b'abc'
+ B = bytes('abc', 'ascii')
+ B = bytes([97, 98, 99])
+ B = 'abc'.encode()
+ # bytes对象的方法调用基本和str类型一致 但:B[0]返回的是ASCII码值97, 而不是b'a'
+
+#-- #文本文件: 根据Unicode编码来解释文件内容,要么是平台的默认编码,要么是指定的编码类型
+ # 二进制文件:表示字节值的整数的一个序列 open('bin.txt', 'rb')
+
+#-- Unicode文件
+ s = 'A\xc4B\xe8C' # s = 'A?BèC' len(s) = 5
+ #手动编码
+ l = s.encode('latin-1') # l = b'A\xc4B\xe8C' len(l) = 5
+ u = s.encode('utf-8') # u = b'A\xc3\x84B\xc3\xa8C' len(u) = 7
+ #文件输出编码
+ open('latindata', 'w', encoding = 'latin-1').write(s)
+ l = open('latindata', 'rb').read() # l = b'A\xc4B\xe8C' len(l) = 5
+ open('uft8data', 'w', encoding = 'utf-8').write(s)
+ u = open('uft8data', 'rb').read() # u = b'A\xc3\x84B\xc3\xa8C' len(u) = 7
+ #文件输入编码
+ s = open('latindata', 'r', encoding = 'latin-1').read() # s = 'A?BèC' len(s) = 5
+ s = open('latindata', 'rb').read().decode('latin-1') # s = 'A?BèC' len(s) = 5
+ s = open('utf8data', 'r', encoding = 'utf-8').read() # s = 'A?BèC' len(s) = 5
+ s = open('utf8data', 'rb').read().decode('utf-8') # s = 'A?BèC' len(s) = 5
+
+
+"""其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他----其他"""
+
+#-- Python实现任意深度的赋值 例如a[0] = 'value1'; a[1][2] = 'value2'; a[3][4][5] = 'value3'
+ class MyDict(dict):
+ def __setitem__(self, key, value): # 该函数不做任何改动 这里只是为了输出
+ print('setitem:', key, value, self)
+ super().__setitem__(key, value)
+ def __getitem__(self, item): # 主要技巧在该函数
+ print('getitem:', item, self) # 输出信息
+ # 基本思路: a[1][2]赋值时 需要先取出a[1] 然后给a[1]的[2]赋值
+ if item not in self: # 如果a[1]不存在 则需要新建一个dict 并使得a[1] = dict
+ temp = MyDict() # 新建的dict: temp
+ super().__setitem__(item, temp) # 赋值a[1] = temp
+ return temp # 返回temp 使得temp[2] = value有效
+ return super().__getitem__(item) # 如果a[1]存在 则直接返回a[1]
+ # 例子:
+ test = MyDict()
+ test[0] = 'test'
+ print(test[0])
+ test[1][2] = 'test1'
+ print(test[1][2])
+ test[1][3] = 'test2'
+ print(test[1][3])
+
+#-- Python中的多维数组
+ lists = [0] * 3 # 扩展list,结果为[0, 0, 0]
+ lists = [[]] * 3 # 多维数组,结果为[[], [], []],但有问题,往下看
+ lists[0].append(3) # 期望看到的结果[[3], [], []],实际结果[[3], [3], [3]],原因:list*n操作,是浅拷贝,如何避免?往下看
+ lists = [[] for i in range(3)] # 多维数组,结果为[[], [], []]
+ lists[0].append(3) # 结果为[[3], [], []]
+ lists[1].append(6) # 结果为[[3], [6], []]
+ lists[2].append(9) # 结果为[[3], [6], [9]]
+ lists = [[[] for j in range(4)] for i in range(3)] # 3行4列,且每一个元素为[]
+```
diff --git "a/docs/Leetcode_Solutions/Python/Summary/python\347\232\204\345\220\204\347\247\215pass.md" "b/docs/Leetcode_Solutions/Python/Summary/python\347\232\204\345\220\204\347\247\215pass.md"
new file mode 100644
index 000000000..c1ac085a8
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/python\347\232\204\345\220\204\347\247\215pass.md"
@@ -0,0 +1,123 @@
+#Python的各种Pass
+
+感觉最近对于pass by reference 和 pass by value又有了一点/一些认识
+
+
+1. python不允许程序员选择采用传值还是传引用。Python参数传递采用的肯定是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于通过“传值'来传递对象。
+2. 当人们复制列表或字典时,就复制了对象列表的引用同,如果改变引用的值,则修改了原始的参数。
+3. 为了简化内存管理,Python通过引用计数机制实现自动垃圾回收功能,Python中的每个对象都有一个引用计数,用来计数该对象在不同场所分别被引用了多少次。每当引用一次Python对象,相应的引用计数就增1,每当消毁一次Python对象,则相应的引用就减1,只有当引用计数为零时,才真正从内存中删除Python对象。
+
+
+##### Linked List的例子
+
+
+
+```
+class ListNode(object):
+ def __init__(self, x):
+ self.val = x
+ self.next = None
+
+node1 = ListNode(1)
+node2 = ListNode(2)
+node3 = ListNode(3)
+node4 = ListNode(4)
+node5 = ListNode(5)
+
+node1.next = node2
+node2.next = node3
+node3.next = node4
+node4.next = node5
+
+```
+
+
+
+来改变head
+
+```
+def testWithPointers1(head):
+ head.next = None
+```
+
+
+
+运行 testWithPointers1(node1)
+
+然后node1.next 为None了
+
+// 可以理解,因为传进去的是head这个可变对象。
+
+
+
+```
+def testWithPointers2(head):
+ cur = head
+ cur.next = None
+```
+
+
+
+运行 testWithPointers2(node1)
+// node1.next 同样为None了
+
+Python的object,list都是pass by reference,所以是改变的
+
+看另外一个例子:
+
+```
+def printLinkedList(head):
+ while head:
+ print(head)
+ head = head.next
+```
+
+
+输出
+
+```
+ printLinkedList(head)
+
+<__main__.ListNode object at 0x1044c0e10>
+
+1
+
+<__main__.ListNode object at 0x1044c0fd0>
+
+2
+
+<__main__.ListNode object at 0x1044c0c88>
+
+3
+
+<__main__.ListNode object at 0x1044c0be0>
+
+4
+
+<__main__.ListNode object at 0x1044c0780>
+
+5
+
+head
+
+Out[39]: <__main__.ListNode at 0x1044c0e10>
+
+```
+
+其实这里的head为什么没有改变有点疑惑
+
+
+
+##### String看一下
+
+
+ a = "abc"
+
+ def changeA(s):
+ s = ""
+ changeA(a)
+
+
+a 并不会改变,依旧为'abc'
+
+
\ No newline at end of file
diff --git a/docs/Leetcode_Solutions/Python/Summary/slide_windows_template.md b/docs/Leetcode_Solutions/Python/Summary/slide_windows_template.md
new file mode 100644
index 000000000..919d1c0f9
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/Summary/slide_windows_template.md
@@ -0,0 +1,185 @@
+能用此模板解决的题目目前有如下:
+[leetcode 003](https://github.com/Lisanaaa/thinking_in_lc/blob/master/003._longest_substring_without_repeating_characters.md),
+[leetcode 030](https://github.com/Lisanaaa/thinking_in_lc/edit/master/30._Substring_with_Concatenation_of_All_Words.md),
+[leetcode 076](https://github.com/Lisanaaa/thinking_in_lc/blob/master/076._Minimum_Window_Substring.md),
+[leetcode 159](https://github.com/Lisanaaa/thinking_in_lc/blob/master/159._Longest_Substring_with_At_Most_Two_Distinct_Characters.md),
+[leetcode 438](https://github.com/Lisanaaa/thinking_in_lc/blob/master/438._Find_All_Anagrams_in_a_String.md)
+
+
+
+带注释python版本
+```python
+class Solution(object):
+ def slideWindowTemplateByLisanaaa(self, s, t):
+ """
+ :type s: str
+ :type t: str
+ :rtype: 具体题目具体分析
+ """
+ # init a collection or int value to save the result according the question.
+ res = []
+ if len(t) > len(s):
+ return res
+
+ # create a hashmap to save the Characters of the target substring.
+ # (K, V) = (Character, Frequence of the Characters)
+ maps = collections.Counter(t)
+
+ # maintain a counter to check whether match the target string.
+ # must be the map size, NOT the string size because the char may be duplicate.
+ counter = len(maps.keys())
+
+ # Two Pointers: begin - left pointer of the window; end - right pointer of the window
+ begin, end = 0, 0
+
+ # the length of the substring which match the target string.
+ length = sys.maxint
+
+ # loop at the begining of the source string
+ while end < len(s):
+ if s[end] in maps:
+ maps[s[end]] -= 1 # plus or minus one
+ if maps[s[end]] == 0:
+ counter -= 1 # modify the counter according the requirement(different condition).
+ end += 1
+
+ # increase begin pointer to make it invalid/valid again
+ while counter == 0: # counter condition. different question may have different condition
+ if s[begin] in maps:
+ maps[s[begin]] += 1 # plus or minus one
+ if maps[s[begin]] > 0:
+ counter += 1 # modify the counter according the requirement(different condition).
+ begin += 1
+
+ '''
+ type your code here according to the question
+ 1. save / update(min/max) the result if find a target
+ 2. result: collections or int value
+ '''
+ return res
+```
+
+无注释python版本:
+```python
+class Solution(object):
+ def slideWindowTemplateByLisanaaa(self, s, t):
+ res = []
+ if len(t) > len(s):
+ return res
+ maps = collections.Counter(t)
+ counter = len(maps.keys())
+ begin, end = 0, 0
+ length = sys.maxint
+ while end < len(s):
+ if s[end] in maps:
+ maps[s[end]] -= 1
+ if maps[s[end]] == 0:
+ counter -= 1
+ end += 1
+ while counter == 0:
+ if s[begin] in maps:
+ maps[s[begin]] += 1
+ if maps[s[begin]] > 0:
+ counter += 1
+ begin += 1
+
+ '''
+ 1. save / update(min/max) the result if find a target
+ 2. result: collections or int value
+ '''
+ return res
+```
+带注释java版本
+```java
+public class Solution {
+ public List slidingWindowTemplateByHarryChaoyangHe(String s, String t) {
+ //init a collection or int value to save the result according the question.
+ List result = new LinkedList<>();
+ if(t.length()> s.length()) return result;
+
+ //create a hashmap to save the Characters of the target substring.
+ //(K, V) = (Character, Frequence of the Characters)
+ Map map = new HashMap<>();
+ for(char c : t.toCharArray()){
+ map.put(c, map.getOrDefault(c, 0) + 1);
+ }
+ //maintain a counter to check whether match the target string.
+ int counter = map.size();//must be the map size, NOT the string size because the char may be duplicate.
+
+ //Two Pointers: begin - left pointer of the window; end - right pointer of the window
+ int begin = 0, end = 0;
+
+ //the length of the substring which match the target string.
+ int len = Integer.MAX_VALUE;
+
+ //loop at the begining of the source string
+ while(end < s.length()){
+
+ char c = s.charAt(end);//get a character
+
+ if( map.containsKey(c) ){
+ map.put(c, map.get(c)-1);// plus or minus one
+ if(map.get(c) == 0) counter--;//modify the counter according the requirement(different condition).
+ }
+ end++;
+
+ //increase begin pointer to make it invalid/valid again
+ while(counter == 0 /* counter condition. different question may have different condition */){
+
+ char tempc = s.charAt(begin);//***be careful here: choose the char at begin pointer, NOT the end pointer
+ if(map.containsKey(tempc)){
+ map.put(tempc, map.get(tempc) + 1);//plus or minus one
+ if(map.get(tempc) > 0) counter++;//modify the counter according the requirement(different condition).
+ }
+
+ /* save / update(min/max) the result if find a target*/
+ // result collections or result int value
+
+ begin++;
+ }
+ }
+ return result;
+ }
+}
+```
+
+无注释java版本:
+```java
+public class Solution {
+ public List slidingWindowTemplateByHarryChaoyangHe(String s, String t) {
+ List result = new LinkedList<>();
+ if(t.length()> s.length()) return result;
+ Map map = new HashMap<>();
+ for(char c : t.toCharArray()){
+ map.put(c, map.getOrDefault(c, 0) + 1);
+ }
+ int counter = map.size();
+ int begin = 0, end = 0;
+ int len = Integer.MAX_VALUE;
+ while(end < s.length()){
+ char c = s.charAt(end);
+ if( map.containsKey(c) ){
+ map.put(c, map.get(c)-1);
+ if(map.get(c) == 0) counter--;
+ }
+ end++;
+ while(counter == 0){
+ char tempc = s.charAt(begin);
+ if(map.containsKey(tempc)){
+ map.put(tempc, map.get(tempc) + 1);
+ if(map.get(tempc) > 0) counter++;
+ }
+
+ /*
+ save / update(min/max) the result if find a target
+ result collections or result int value
+ */
+
+ begin++;
+ }
+ }
+ return result;
+ }
+}
+```
+
diff --git a/docs/Leetcode_Solutions/Python/Summary/union_find.md b/docs/Leetcode_Solutions/Python/Summary/union_find.md
new file mode 100644
index 000000000..408353475
--- /dev/null
+++ b/docs/Leetcode_Solutions/Python/Summary/union_find.md
@@ -0,0 +1,282 @@
+## 并查集(参考leetcode323题)
+
+### 应用场景:
+
+动态联通性
+
+- 网络连接判断:
+如果每个pair中的两个整数用来表示这两个节点是需要连通的,那么为所有的pairs建立了动态连通图后,就能够尽可能少的减少布线的需要,
+因为已经连通的两个节点会被直接忽略掉。例如[1,2]代表节点1和节点2是联通的,如果再次出现[2,1]我们就不需要再连接他们了,因为已经连接过一次了。
+
+- 变量名等同性(类似于指针的概念):
+在程序中,可以声明多个引用来指向同一对象,这个时候就可以通过为程序中声明的引用和实际对象建立动态连通图来判断哪些引用实际上是指向同一对象。
+
+### 对问题建模:
+
+在对问题进行建模的时候,我们应该尽量想清楚需要解决的问题是什么。因为模型中选择的数据结构和算法显然会根据问题的不同而不同,
+就动态连通性这个场景而言,我们需要解决的问题可能是:
+
+1. 给出两个节点,判断它们是否连通,如果连通,不需要给出具体的路径
+2. 给出两个节点,判断它们是否连通,如果连通,需要给出具体的路径
+
+就上面两种问题而言,虽然只有是否能够给出具体路径的区别,但是这个区别导致了选择算法的不同
+
+### 建模思路:
+
+最简单而直观的假设是,对于连通的所有节点,我们可以认为它们属于一个组,因此不连通的节点必然就属于不同的组。
+随着Pair的输入,我们需要首先判断输入的两个节点是否连通。如何判断呢?按照上面的假设,我们可以通过判断它们属于的组,然后看看这两个组是否相同。
+如果相同,那么这两个节点连通,反之不连通。为简单起见,我们将所有的节点以整数表示,即对N个节点使用0到N-1的整数表示。
+而在处理输入的Pair之前,每个节点必然都是孤立的,即他们分属于不同的组,可以使用数组来表示这一层关系。
+数组的index是节点的整数表示,而相应的值就是该节点的组号了。该数组可以初始化为:```uf = [i for i in range(n)]```
+
+初始化完毕之后,对该动态连通图有几种可能的操作:
+
+1. 查询节点属于的组
+
+数组对应位置的值即为组号
+
+2. 判断两个节点是否属于同一个组
+
+分别得到两个节点的组号,然后判断组号是否相等
+
+3. 连接两个节点,使之属于同一个组
+
+分别得到两个节点的组号,组号相同时操作结束,不同时,将其中的一个节点的组号换成另一个节点的组号
+
+4. 获取组的数目
+
+初始化为节点的数目,然后每次成功连接两个节点之后,递减1
+
+### API:
+
+我们可以设置对应的API
+```python
+def uf(n) # 初始化uf数组和组数目
+def union(x, y) # 连接两个节点
+def find(x) # 判断节点所属于的组
+def connected(x, y) # 判断两个节点是否联通
+def count() # 返回所有组的数目
+```
+
+注意其中使用整数来表示节点,如果需要使用其他的数据类型表示节点,比如使用字符串,那么可以用哈希表来进行映射,即将String映射成这里需要的Integer类型。
+
+分析以上的API,方法connected和union都依赖于find,connected对两个参数调用两次find方法,而union在真正执行union之前也需要判断是否连通,
+这又是两次调用find方法。因此我们需要把find方法的实现设计的尽可能的高效。所以就有了下面的Quick-Find实现。
+
+### Quick-Find实现
+
+```
+class Solution(object):
+ uf = [] # access to component id (site indexed)
+ count = 0 # number of components
+
+ def uf(self, n): # 初始化uf数组和组数目
+ self.count = n
+ self.uf = [i for i in range(n)]
+
+ def find(self, x): # 判断节点所属于的组
+ return uf[x]
+
+ def union(self, x, y): # 连接两个节点
+ x_root = find(x)
+ y_root = find(y)
+ if x_root == y_root:
+ return
+ for i in range(len(self.uf)):
+ if uf[i] == x_root:
+ uf[i] = y_root
+ count -= 1
+
+ def connected(self, x, y): # 判断两个节点是否联通
+ return find(x) == find(y)
+
+ def count(self): # 返回所有组的数目
+ return count
+```
+
+上述代码的find方法十分高效,因为仅仅需要一次数组读取操作就能够找到该节点的组号。
+但是问题随之而来,对于需要添加新路径的情况,就涉及到对于组号的修改,因为并不能确定哪些节点的组号需要被修改,
+因此就必须对整个数组进行遍历,找到需要修改的节点,逐一修改,这一下每次添加新路径带来的复杂度就是线性关系了,
+如果要添加的新路径的数量是M,节点数量是N,那么最后的时间复杂度就是MN,显然是一个平方阶的复杂度,对于大规模的数据而言,平方阶的算法是存在问题的,
+这种情况下,每次添加新路径就是“牵一发而动全身”,想要解决这个问题,关键就是要提高union方法的效率,让它不再需要遍历整个数组。
+
+
+### Quick-Union 算法:
+
+考虑一下,为什么以上的解法会造成“牵一发而动全身”?因为每个节点所属的组号都是单独记录,各自为政的,没有将它们以更好的方式组织起来,
+当涉及到修改的时候,除了逐一通知、修改,别无他法。所以现在的问题就变成了,如何将节点以更好的方式组织起来,组织的方式有很多种,
+但是最直观的还是将组号相同的节点组织在一起,想想所学的数据结构,什么样子的数据结构能够将一些节点给组织起来?
+常见的就是链表,图,树,什么的了。但是哪种结构对于查找和修改的效率最高?毫无疑问是树,因此考虑如何将节点和组的关系以树的形式表现出来。
+
+如果不改变底层数据结构,即不改变使用数组的表示方法的话。可以采用parent-link的方式将节点组织起来,
+举例而言,uf[p]的值就是p节点的父节点的序号,如果p是树根的话,uf[p]的值就是p,因此最后经过若干次查找,一个节点总是能够找到它的根节点,
+即满足uf[root] = root的节点也就是组的根节点了,然后就可以使用根节点的序号来表示组号。所以在处理一个pair的时候,
+将首先找到pair中每一个节点的组号(即它们所在树的根节点的序号),如果属于不同的组的话,就将其中一个根节点的父节点设置为另外一个根节点,
+相当于将一颗独立的树编程另一颗独立的树的子树。直观的过程如下图所示。但是这个时候又引入了问题。
+
+树这种数据结构容易出现极端情况,因为在建树的过程中,树的最终形态严重依赖于输入数据本身的性质,比如数据是否排序,是否随机分布等等。
+比如在输入数据是有序的情况下,构造的BST会退化成一个链表。在我们这个问题中,也是会出现的极端情况的。
+
+```
+class Solution(object):
+ uf = [] # access to component id (site indexed)
+ count = 0 # number of components
+
+ def uf(self, n): # 初始化uf数组和组数目
+ self.count = n
+ self.uf = [i for i in range(n)]
+
+ def find(self, x): # 判断节点所属于的组
+ # if uf[x] != x: ## 这种方式也可以,但是递归次数多了容易出问题
+ # uf[x] = find(uf[x])
+ while x != uf[x]:
+ x = uf[x]
+ return uf[x]
+
+ def union(self, x, y): # 连接两个节点
+ x_root = find(x)
+ y_root = find(y)
+ uf[x_root] = y_root
+ count -= 1
+
+ def connected(self, x, y): # 判断两个节点是否联通
+ return find(x) == find(y)
+
+ def count(self): # 返回所有组的数目
+ return count
+```
+
+为了克服这个问题,BST可以演变成为红黑树或者AVL树等等。
+
+然而,在我们考虑的这个应用场景中,每对节点之间是不具备可比性的。因此需要想其它的办法。在没有什么思路的时候,多看看相应的代码可能会有一些启发,
+考虑一下Quick-Union算法中的union方法实现:
+
+```
+def union(self, x, y): # 连接两个节点
+ x_root = find(x)
+ y_root = find(y)
+ uf[x_root] = y_root
+ count -= 1
+```
+
+上面 id[pRoot] = qRoot 这行代码看上去似乎不太对劲。因为这也属于一种“硬编码”,这样实现是基于一个约定,即p所在的树总是会被作为q所在树的子树,
+从而实现两颗独立的树的融合。那么这样的约定是不是总是合理的呢?显然不是,比如p所在的树的规模比q所在的树的规模大的多时,
+p和q结合之后形成的树就是十分不和谐的一头轻一头重的”畸形树“了。
+
+所以我们应该考虑树的大小,然后再来决定到底是调用 uf[x_root] = y_root 或者是 uf[y_root] = x_root
+
+即总是size小的树作为子树和size大的树进行合并。这样就能够尽量的保持整棵树的平衡。
+
+所以现在的问题就变成了:树的大小该如何确定?
+
+我们回到最初的情形,即每个节点最一开始都是属于一个独立的组,通过下面的代码进行初始化:
+```
+tree_size = [1 for i in range(n)]
+```
+
+然后:
+
+```
+def union(self, x, y): # 连接两个节点
+ x_root = find(x)
+ y_root = find(y)
+ if tree_size[x_root] <= tree_size[y_root]:
+ uf[x_root] = y_root
+ tree_size[y_root] += tree_size[x_root]
+ else:
+ uf[y_root] = x_root
+ tree_size[x_root] += tree_size[y_root]
+ count -= 1
+```
+
+可以发现,通过tree_size数组决定如何对两棵树进行合并之后,最后得到的树的高度大幅度减小了。这是十分有意义的。
+因为在Quick-Union算法中的任何操作,都不可避免的需要调用find方法,而该方法的执行效率依赖于树的高度。树的高度减小了,
+find方法的效率就增加了,从而也就增加了整个Quick-Union算法的效率。
+
+上面的论证其实还可以给我们一些启示,即对于Quick-Union算法而言,节点组织的理想情况应该是一颗十分扁平的树,所有的孩子节点应该都在height为1的地方,
+即所有的孩子都直接连接到根节点。这样的组织结构能够保证find操作的最高效率。
+
+那么如何构造这种理想结构呢?
+
+在find方法的执行过程中,不是需要进行一个while循环找到根节点嘛?如果保存所有路过的中间节点到一个数组中,然后在while循环结束之后,
+将这些中间节点的父节点指向根节点,不就行了么?但是这个方法也有问题,因为find操作的频繁性,会造成频繁生成中间节点数组,
+相应的分配销毁的时间自然就上升了。那么有没有更好的方法呢?还是有的,即将节点的父节点指向该节点的爷爷节点,这一点很巧妙,
+十分方便且有效,相当于在寻找根节点的同时,对路径进行了压缩,使整个树结构扁平化。相应的实现如下,实际上只需要添加一行代码:
+
+```
+def find(self, x): # 判断节点所属于的组
+ while x != uf[x]:
+ uf[x] = uf[uf[x]]
+ x = uf[x]
+ return uf[x]
+```
+综上,我决定以后解决问题的时候用这个模版就行了:
+
+```python
+class UnionFind(object):
+ def uf(self, n): # 初始化uf数组和组数目
+ self.count = n
+ self.uf = [i for i in range(n)]
+ self.size = [1] * n # 每个联通分量的size
+
+ def find(self, x): # 判断节点所属于的组
+ while x != self.uf[x]:
+ self.uf[x] = self.uf[self.uf[x]]
+ x = self.uf[x]
+ return self.uf[x]
+
+ def union(self, x, y): # 连接两个节点
+ x_root = self.find(x)
+ y_root = self.find(y)
+ if x_root != y_root:
+ size[y_root] += size[x_root]
+ self.uf[x_root] = y_root
+ self.count -= 1
+
+ def connected(self, x, y): # 判断两个节点是否联通
+ return self.find(x) == self.find(y)
+
+ def count(self): # 返回所有组的数目
+ return self.count
+```
+
+### 时间复杂度分析
+- find()操作的时间复杂度最坏情况下为O(N)
+- union()操作的时间复杂度最坏情况下为O(1)
+
+Quick union的表现将随着我们不断调用union()构建联通集而变差。因为代表这个联通集的树越来越高,调用find()的开销也就越来越大。
+
+至此,动态连通性相关的Union-Find算法基本上就介绍完了,从容易想到的Quick-Find到相对复杂但是更加高效的Quick-Union,然后到对Quick-Union的几项改进,
+让我们的算法的效率不断的提高。
+
+这几种算法的时间复杂度如下所示:
+
+
+对大规模数据进行处理,使用平方阶的算法是不合适的,比如简单直观的Quick-Find算法,通过发现问题的更多特点,找到合适的数据结构,然后有针对性的进行改进,
+得到了Quick-Union算法及其多种改进算法,最终使得算法的复杂度降低到了近乎线性复杂度。
+
+如果需要的功能不仅仅是检测两个节点是否连通,还需要在连通时得到具体的路径,那么就需要用到别的算法了,比如DFS或者BFS。
+
+并查集的应用,可以参考另外一篇文章[并查集应用举例](https://blog.csdn.net/dm_vincent/article/details/7769159)
+
+## References
+
+1. [并查集(Union-Find)算法介绍](https://blog.csdn.net/dm_vincent/article/details/7655764)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\200\344\272\233\346\223\215\344\275\234.md" "b/docs/Leetcode_Solutions/Python/Summary/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\200\344\272\233\346\223\215\344\275\234.md"
new file mode 100644
index 000000000..54d08ab00
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\344\272\214\345\217\211\346\240\221\347\232\204\344\270\200\344\272\233\346\223\215\344\275\234.md"
@@ -0,0 +1,245 @@
+### 1. 二叉搜索树(BSTree)的概念
+
+二叉搜索树又被称为二叉排序树,那么它本身也是一棵二叉树,那么满足以下性质的二叉树就是二叉搜索树,如图:
+
+- 若左子树不为空,则左子树上所有节点的值都小于根节点的值;
+- 若它的右子树不为空,则它的右子树上所有节点的值都大于根节点的值;
+- 它的左右子树也要分别是二叉搜索树。
+
+### 2. 二叉搜索树的插入
+
+- 如果插入值已经存在,则不插,return False
+- 如果not root,则返回TreeNode(val)
+- 根据与root.val的比较,在左右子树中进行递归操作
+
+代码中保证插入的值不存在,也是[leetcode第701题](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/701._Insert_into_a_Binary_Search_Tree.md)中所gurantee的
+```python
+# Definition for a binary tree node.
+# class TreeNode(object):
+# def __init__(self, x):
+# self.val = x
+# self.left = None
+# self.right = None
+
+class Solution(object):
+ def insertIntoBST(self, root, val):
+ """
+ :type root: TreeNode
+ :type val: int
+ :rtype: TreeNode
+ """
+ if not root:
+ return TreeNode(val)
+ if val < root.val:
+ root.left = self.insertIntoBST(root.left, val)
+ if val > root.val:
+ root.right = self.insertIntoBST(root.right, val)
+ return root
+```
+
+### 3. 二叉搜索树的搜索
+
+* 搜索节点
+```java
+public TreeNode search(int key) {
+ TreeNode pNode = root;
+ while (pNode != null) {
+ if (key == pNode.key) {
+ return pNode;
+ } else if (key > pNode.key) {
+ pNode = pNode.rchild;
+ } else if (key < pNode.key) {
+ pNode = pNode.lchild;
+ }
+ }
+ return null;// 如果没有搜索到结果那么就只能返回空值了
+}
+```
+
+* 获取最小节点
+
+```java
+public TreeNode minElemNode(TreeNode node) throws Exception {
+ if (node == null) {
+ throw new Exception("此树为空树!");
+ }
+ TreeNode pNode = node;
+ while (pNode.lchild != null) {
+ pNode = pNode.lchild;
+ }
+ return pNode;
+}
+```
+
+* 获取最大节点
+
+```java
+public TreeNode maxElemNode(TreeNode node) throws Exception {
+ if (node == null) {
+ throw new Exception("此树为空树!");
+ }
+ TreeNode pNode = node;
+ while (pNode.rchild != null) {
+ pNode = pNode.rchild;
+ }
+ return pNode;
+}
+```
+
+* 获取给定节点在中序遍历下的后续第一个节点(即找到该节点的右子树中的最左孩子)
+
+```java
+public TreeNode successor(TreeNode node) throws Exception {
+ if (node == null) {
+ throw new Exception("此树为空树!");
+ }
+ // 分两种情况考虑,此节点是否有右子树
+ // 当这个节点有右子树的情况下,那么右子树的最小关键字节点就是这个节点的后续节点
+ if (node.rchild != null) {
+ return minElemNode(node.rchild);
+ }
+
+ // 当这个节点没有右子树的情况下,即 node.rchild == null
+ // 如果这个节点是它父节点的左子树的话,那么就说明这个父节点就是后续节点了
+ TreeNode parentNode = node.parent;
+ while (parentNode != null && parentNode.rchild == node) {
+ node = parentNode;
+ parentNode = parentNode.parent;
+ }
+ return parentNode;
+}
+```
+
+
+* 获取给定节点在中序遍历下的前趋结点
+
+```java
+public TreeNode precessor(TreeNode node) throws Exception {
+ // 查找前趋节点也是分两种情况考虑
+ // 如果这个节点存在左子树,那么这个左子树的最大关键字就是这个节点的前趋节点
+ if (node.lchild != null) {
+ return maxElemNode(node.lchild);
+ }
+ // 如果这个节点不存在左子树,那么这个节点的父节点
+ TreeNode parentNode = node.parent;
+ while (parentNode != null && parentNode.lchild == node) {
+ node = parentNode;
+ parentNode = parentNode.lchild;
+ }
+ return parentNode;
+}
+```
+
+
+
+### 4. 二叉搜索树的删除
+
+- 要删除的节点不存在,return False
+- 要删除的节点没有子节点,直接删
+- 要删除的节点只有一个子节点(即只有一个左子节点或者一个右子节点),让被删除节点的父亲节点指向其子节点即可
+- 要删除的节点target有两个子节点(即左右均存在),则首先找到该节点的右子树中的最左孩子(也就是右子树中序遍历的第一个节点,分两种情况),
+然后将两者互换,再删除target即可
+
+```java
+ // 从二叉树当中删除指定的节点
+ public void delete(int key) throws Exception {
+ TreeNode pNode = search(key);
+ if (pNode == null) {
+ throw new Exception("此树中不存在要删除的这个节点!");
+ }
+
+ delete(pNode);
+ }
+
+ private void delete(TreeNode pNode) throws Exception {
+ // 第一种情况:删除没有子节点的节点
+ if (pNode.lchild == null && pNode.rchild == null) {
+ if (pNode == root) {// 如果是根节点,那么就删除整棵树
+ root = null;
+ } else if (pNode == pNode.parent.lchild) {
+ // 如果这个节点是父节点的左节点,则将父节点的左节点设为空
+ pNode.parent.lchild = null;
+ } else if (pNode == pNode.parent.rchild) {
+ // 如果这个节点是父节点的右节点,则将父节点的右节点设为空
+ pNode.parent.rchild = null;
+ }
+ }
+
+ // 第二种情况: (删除有一个子节点的节点)
+ // 如果要删除的节点只有右节点
+ if (pNode.lchild == null && pNode.rchild != null) {
+ if (pNode == root) {
+ root = pNode.rchild;
+ } else if (pNode == pNode.parent.lchild) {
+ pNode.parent.lchild = pNode.rchild;
+ pNode.rchild.parent = pNode.parent;
+ } else if (pNode == pNode.parent.rchild) {
+ pNode.parent.rchild = pNode.rchild;
+ pNode.rchild.parent = pNode.parent;
+ }
+ }
+ // 如果要删除的节点只有左节点
+ if (pNode.lchild != null && pNode.rchild == null) {
+ if (pNode == root) {
+ root = pNode.lchild;
+ } else if (pNode == pNode.parent.lchild) {
+ pNode.parent.lchild = pNode.lchild;
+ pNode.lchild.parent = pNode.parent;
+ } else if (pNode == pNode.parent.rchild) {
+ pNode.parent.rchild = pNode.lchild;
+ pNode.lchild.parent = pNode.parent;
+ }
+ }
+
+ // 第三种情况: (删除有两个子节点的节点,即左右子节点都非空)
+
+ // 方法是用要删除的节点的后续节点代替要删除的节点,并且删除后续节点(删除后续节点的时候需要递归操作)
+ // 解析:这里要用到的最多也就会发生两次,即后续节点不会再继续递归的删除下一个后续节点了,
+ // 因为,要删除的节点的后续节点肯定是:要删除的那个节点的右子树的最小关键字,而这个最小关键字肯定不会有左节点;
+ // 所以,在删除后续节点的时候肯定不会用到(两个节点都非空的判断 ),如有有子节点,肯定就是有一个右节点。
+ if (pNode.lchild != null && pNode.rchild != null) {
+ // 先找出后续节点
+ TreeNode successorNode = successor(pNode);
+ if (pNode == root) {
+ root.key = successorNode.key;
+ } else {
+ pNode.key = successorNode.key;// 赋值,将后续节点的值赋给要删除的那个节点
+ }
+ delete(successorNode);// 递归的删除后续节点
+ }
+ }
+```
+
+
+### 5. 二叉搜索树的遍历
+
+前序遍历:[leetcode第144题](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/144._binary_tree_preorder_traversal.md)
+
+中序遍历:[leetcode第94题](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/094._binary_tree_inorder_traversal.md)
+
+后序遍历:[leetcode第145题](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/145._binary_tree_postorder_traversal.md)
+
+
+层次遍历:[leetcode第102题](https://github.com/apachecn/LeetCode/blob/master/docs/Leetcode_Solutions/102._binary_tree_level_order_traversal.md)
+
+## References
+
+[数据结构与算法之二叉搜索树插入、查询与删除](https://blog.csdn.net/chenliguan/article/details/52956546)
+
+[二叉搜索树的插入与删除图解](http://www.cnblogs.com/MrListening/p/5782752.html)
+
+[二叉树算法删除代码实现](https://blog.csdn.net/tayanxunhua/article/details/11100113)
+
+[二叉树的Java实现及特点总结](http://www.cnblogs.com/lzq198754/p/5857597.html)
+
+
+
+
+
+
+
+
+
+
+
+
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\344\275\215\350\277\220\347\256\227.md" "b/docs/Leetcode_Solutions/Python/Summary/\344\275\215\350\277\220\347\256\227.md"
new file mode 100644
index 000000000..aeaa44c4d
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\344\275\215\350\277\220\347\256\227.md"
@@ -0,0 +1,38 @@
+### 位运算
+
+位运算包括: 加 减 乘 取反 and 异或
+
+- 0110 + 0110 = 0110 * 2 ,也就是0110左移1位
+
+- 0011 * 0100 0100 = 4, 一个数乘以 2^n 即是将这个数左移n
+
+- a ^(~a) = 0
+
+- x & (~0 << n ) 这样来看,0取反全部为1,然后将其右移n位,后面的全是0,x & (~0 <>:右移
+
+
+
+Bit Facts and Tricks
+
+```
+x ^ 0s = x x & 0s = 0 x | 0s = x
+x ^ 1s = ~x x & 1s = x x | 1s = 1s
+x ^ x = 0 x & x = x x | x = x
+```
+
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\345\205\250\346\216\222\345\210\227\347\256\227\346\263\225.md" "b/docs/Leetcode_Solutions/Python/Summary/\345\205\250\346\216\222\345\210\227\347\256\227\346\263\225.md"
new file mode 100644
index 000000000..767617664
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\345\205\250\346\216\222\345\210\227\347\256\227\346\263\225.md"
@@ -0,0 +1,194 @@
+### 全排列算法
+
+
+#### 46. Permutations
+
+
+Given a collection of distinct numbers, return all possible permutations.
+
+For example,
+[1,2,3] have the following permutations:
+
+ [
+ [1,2,3],
+ [1,3,2],
+ [2,1,3],
+ [2,3,1],
+ [3,1,2],
+ [3,2,1]
+ ]
+
+
+#####从空开始加
+
+先跳离开这道题,来看类似的'ABC',我们要求它的全排列
+
+
+```
+def recPermute(sofar, rest):
+ if rest == '':
+ print sofar
+ else:
+ for i in range(len(rest)):
+ nxt = sofar + rest[i]
+ remaining = rest[:i] + rest[i+1:]
+ recPermute(nxt, remaining)
+
+// "wrapper" function
+def listPermute(s):
+ recPermute('',s)
+```
+
+会正确输出`ABC ACB BAC BCA CAB CBA`,题目依靠的是每次我们从余下的字母中选一个,如果画图则会是这样:
+
+
+```
+ A B C
+ B C A C A B
+ C B C A B A
+```
+
+时间复杂度应该是O(n!)
+
+- n choose 1
+- n-1 choose 1
+- ...
+
+
+
+#####另一种市面上常见思路是交换:
+
+思路是这样的,同样看上面的图:
+
+- n个元素的全排列 = (n-1)个元素的全排列 + 另一个元素作为前缀
+- 如果只有一个元素,那么这个元素本身就是它的全排列
+- 不断将每个元素放作第一个元素,然后将这个元素作为前缀,并将其余元素继续全排列,等到出口,出口出去后还需要还原数组
+
+
+这个用数组来测试更容易写代码和直观:
+
+
+```
+def recPermute(nums,begin):
+ n = len(nums)
+ if begin == n:
+ print nums,
+
+ for i in range(begin,n):
+ nums[begin], nums[i] = nums[i],nums[begin]
+ recPermute(nums,begin+1)
+ nums[begin],nums[i] = nums[i],nums[begin]
+
+recPermute(['A','B','C'],0)
+
+```
+
+这样的写法更容易理解:
+
+
+```python
+class Solution:
+ # @param num, a list of integer
+ # @return a list of lists of integers
+ def permute(self, num):
+ if len(num) == 0: return []
+ if len(num) == 1: return [num]
+ res = []
+ for i in range(len(num)):
+ x = num[i]
+ xs = num[:i] + num[i+1:]
+ for j in self.permute(xs):
+ res.append([x] + j)
+ return res
+```
+
+每次用一个没有用过的头元素,然后加上全排列产生的结果.
+
+如果分析复杂度,应该也是O(n!)
+
+
+#### 47. Permutations II
+
+
+最简单的想法:
+
+- 排序
+- 如果碰到重复的就继续处理下一个
+
+```
+class Solution(object):
+ def permuteUnique(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: List[List[int]]
+ """
+ if len(nums) == 0: return []
+ if len(nums) == 1: return [nums]
+ res = []
+ nums.sort()
+ for i in range(len(nums)):
+ if i > 0 and nums[i] == nums[i-1]: continue
+ for j in self.permuteUnique(nums[:i] + nums[i+1:]):
+ res.append([nums[i]] + j)
+ return res
+
+```
+
+
+
+
+#### 31. Next Permutation
+
+实际上这个题目也就是Generation in lexicographic order,
+
+wikipedia 和 [这里](https://www.nayuki.io/page/next-lexicographical-permutation-algorithm) 有很好,很精妙的算法,也有点two pointer的意思
+
+
+```
+1. Find the highest index i such that s[i] < s[i+1]. If no such index exists, the permutation is the last permutation.
+2. Find the highest index j > i such that s[j] > s[i]. Such a j must exist, since i+1 is such an index.
+3. Swap s[i] with s[j].
+4. Reverse the order of all of the elements after index i till the last element.
+```
+
+
+看例子:
+
+125430
+
+
+- 从末尾开始,找到decreasing subsequence,5430,因为来调5330无论怎么调,都不可能有比它更小的,数也被自然的分成两部分(1,2) 和 (5,4,3,0)
+- 下一步是找这个sequence里面第一个比前面部分,比2大的,3,也很容易理解,因为下一个必定是(1,3)打头
+- 交换 3和2 ,变成 (1,3,5,4,2,0),再把后面的部分reverse,得到后面部分可得到的最小的
+
+这个时候,得到下一个sequence 130245
+
+
+
+```
+class Solution(object):
+ def nextPermutation(self, nums):
+ """
+ :type nums: List[int]
+ :rtype: void Do not return anything, modify nums in-place instead.
+ """
+ m, n = 0, 0
+ for i in range(len(nums) - 2, 0 , -1):
+ if nums[i] < nums[i+1]:
+ m = i
+ break
+
+ for i in range(len(nums) - 1, 0 , -1):
+ if nums[i] > nums[m]:
+ n = i
+ break
+
+ if m < n :
+ nums[m], nums[n] = nums[n], nums[m]
+ nums[m+1:] = nums[len(nums):m:-1]
+ else:
+ nums = nums.reverse()
+```
+
+
+所以可以用这个next permutation来解46/47也可以,然后我兴奋了一下,这个算法很快的!然后我又冷静了,因为permutation的个数是O(n!)个啊|||,所以也不可能有啥大的提升吧
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\345\205\253\346\216\222\345\272\217.md" "b/docs/Leetcode_Solutions/Python/Summary/\345\205\253\346\216\222\345\272\217.md"
new file mode 100644
index 000000000..83b327202
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\345\205\253\346\216\222\345\272\217.md"
@@ -0,0 +1,386 @@
+## 前言
+八大排序,三大查找是《数据结构》当中非常基础的知识点,在这里为了复习顺带总结了一下常见的八种排序算法。
+常见的八大排序算法,他们之间关系如下:
+
+
+
+他们的性能比较:
+
+
+
+### 直接插入排序 (Insertion sort)
+
+
+
+直接插入排序的核心思想就是:将数组中的所有元素依次跟前面已经排好的元素相比较,如果选择的元素比已排序的元素小,则交换,直到全部元素都比较过。
+因此,从上面的描述中我们可以发现,直接插入排序可以用两个循环完成:
+
+1. 第一层循环:遍历待比较的所有数组元素
+2. 第二层循环:将本轮选择的元素(selected)与已经排好序的元素(ordered)相比较。
+ - 如果```selected > ordered```,那么将二者交换
+
+```python
+#直接插入排序
+def insert_sort(L):
+ #遍历数组中的所有元素,其中0号索引元素默认已排序,因此从1开始
+ for x in range(1,len(L)):
+ #将该元素与已排序好的前序数组依次比较,如果该元素小,则交换
+ #range(x-1,-1,-1):从x-1倒序循环到0
+ for i in range(x-1,-1,-1):
+ #判断:如果符合条件则交换
+ if L[i] > L[i+1]:
+ L[i], L[i+1] = L[i+1], L[i]
+```
+### 希尔排序 (Shell sort)
+
+
+
+希尔排序的算法思想:将待排序数组按照步长gap进行分组,然后将每组的元素利用直接插入排序的方法进行排序;每次将gap折半减小,循环上述操作;当gap=1时,利用直接插入,完成排序。
+同样的:从上面的描述中我们可以发现:希尔排序的总体实现应该由三个循环完成:
+
+1. 第一层循环:将gap依次折半,对序列进行分组,直到gap=1
+2. 第二、三层循环:也即直接插入排序所需要的两次循环。具体描述见上。
+
+```python
+#希尔排序
+def insert_shell(L):
+ #初始化gap值,此处利用序列长度的一半为其赋值
+ gap = int(len(L)/2)
+ #第一层循环:依次改变gap值对列表进行分组
+ while (gap >= 1):
+ #下面:利用直接插入排序的思想对分组数据进行排序
+ #range(gap,len(L)):从gap开始
+ for x in range(gap,len(L)):
+ #range(x-gap,-1,-gap):从x-gap开始与选定元素开始倒序比较,每个比较元素之间间隔gap
+ for i in range(x-gap,-1,-gap):
+ #如果该组当中两个元素满足交换条件,则进行交换
+ if L[i] > L[i+gap]:
+ L[i], L[i+gap] = L[i+gap], L[i]
+ #while循环条件折半
+ gap = int((gap/2))
+```
+
+### 简单选择排序 (Selection sort)
+
+
+
+简单选择排序的基本思想:比较+交换。
+
+1. 从待排序序列中,找到关键字最小的元素;
+2. 如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;
+3. 从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束。
+因此我们可以发现,简单选择排序也是通过两层循环实现。
+ - 第一层循环:依次遍历序列当中的每一个元素
+ - 第二层循环:将遍历得到的当前元素依次与余下的元素进行比较,符合最小元素的条件,则交换。
+
+```python
+# 简单选择排序
+def select_sort(L):
+#依次遍历序列中的每一个元素
+ for x in range(0,len(L)):
+#将当前位置的元素定义此轮循环当中的最小值
+ minimum = L[x]
+#将该元素与剩下的元素依次比较寻找最小元素
+ for i in range(x+1,len(L)):
+ if L[i] < minimum:
+ L[i], minimum = minimum, L[i]
+#将比较后得到的真正的最小值赋值给当前位置
+ L[x] = minimum
+```
+
+### 堆排序 (Heap sort)
+
+#### 堆的概念
+
+堆:本质是一种数组对象。特别重要的一点性质:任意的叶子节点小于(或大于)它所有的父节点。对此,又分为大顶堆和小顶堆,大顶堆要求节点的元素都要大于其孩子,小顶堆要求节点元素都小于其左右孩子,两者对左右孩子的大小关系不做任何要求。
+利用堆排序,就是基于大顶堆或者小顶堆的一种排序方法。下面,我们通过大顶堆来实现。
+
+基本思想:
+堆排序可以按照以下步骤来完成:
+
+1. 首先将序列构建称为大顶堆;
+
+(这样满足了大顶堆那条性质:位于根节点的元素一定是当前序列的最大值)
+
+
+
+2. 取出当前大顶堆的根节点,将其与序列末尾元素进行交换;
+
+(此时:序列末尾的元素为已排序的最大值;由于交换了元素,当前位于根节点的堆并不一定满足大顶堆的性质)
+
+3. 对交换后的n-1个序列元素进行调整,使其满足大顶堆的性质;
+
+
+
+4. 重复2.3步骤,直至堆中只有1个元素为止
+
+```python
+#-------------------------堆排序--------------------------------
+#**********获取左右叶子节点**********
+def LEFT(i):
+ return 2*i + 1
+def RIGHT(i):
+ return 2*i + 2
+#********** 调整大顶堆 **********
+#L:待调整序列 length: 序列长度 i:需要调整的结点
+def adjust_max_heap(L, length, i):
+#定义一个int值保存当前序列最大值的下标
+ largest = i
+#获得序列左右叶子节点的下标
+ left, right = LEFT(i), RIGHT(i)
+#当左叶子节点的下标小于序列长度 并且 左叶子节点的值大于父节点时,将左叶子节点的下标赋值给largest
+ if (left < length) and (L[left] > L[i]):
+ largest = left
+#当右叶子节点的下标小于序列长度 并且 右叶子节点的值大于父节点时,将右叶子节点的下标值赋值给largest
+ if (right < length) and (L[right] > L[largest]):
+ largest = right
+#如果largest不等于i 说明当前的父节点不是最大值,需要交换值
+ if (largest != i):
+ L[i], L[largest] = L[largest], L[i]
+ # 执行递归操作:两个任务:1 寻找最大值的下标;2.最大值与父节点交换
+ adjust_max_heap(L, length, largest)
+#********** 建立大顶堆 **********
+def build_max_heap(L):
+ length = len(L)
+ for x in range(int((length-1)/2), -1, -1):
+ adjust_max_heap(L, length, x)
+#********** 堆排序 **********
+def heap_sort(L):
+#先建立大顶堆,保证最大值位于根节点;并且父节点的值大于叶子结点
+ build_max_heap(L)
+#i:当前堆中序列的长度.初始化为序列的长度
+ i = len(L)
+#执行循环:1. 每次取出堆顶元素置于序列的最后(len-1,len-2,len-3...)
+# 2. 调整堆,使其继续满足大顶堆的性质,注意实时修改堆中序列的长度
+ while (i > 0):
+ L[i-1], L[0] = L[0], L[i-1]
+#堆中序列长度减1
+ i -= 1
+#调整大顶堆
+ adjust_max_heap(L, i, 0)
+```
+### 冒泡排序 (Bubble sort)
+
+
+
+冒泡排序思路比较简单:
+
+1. 将序列当中的左右元素,依次比较,保证右边的元素始终大于左边的元素;
+( 第一轮结束后,序列最后一个元素一定是当前序列的最大值;)
+2. 对序列当中剩下的n-1个元素再次执行步骤1。
+3. 对于长度为n的序列,一共需要执行n-1轮比较
+(利用while循环可以减少执行次数)
+
+```python
+#冒泡排序
+def bubble_sort(L):
+ length = len(L)
+#序列长度为length,需要执行length-1轮交换
+ for x in range(1, length):
+#对于每一轮交换,都将序列当中的左右元素进行比较
+#每轮交换当中,由于序列最后的元素一定是最大的,因此每轮循环到序列未排序的位置即可
+ for i in range(0, length-x):
+ if L[i] > L[i+1]:
+ L[i], L[i+1] = L[i+1], L[i]
+```
+
+### 快速排序 (Quick sort)
+
+
+
+快速排序的基本思想:挖坑填数+分治法
+
+1. 从序列当中选择一个基准数(pivot)
+在这里我们选择序列当中第一个数作为基准数
+2. 将序列当中的所有数依次遍历,比基准数大的位于其右侧,比基准数小的位于其左侧
+3. 重复步骤1.2,直到所有子集当中只有一个元素为止。
+
+用伪代码描述如下:
+- i =L; j = R; 将基准数挖出形成第一个坑a[i]。
+- j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。
+- i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。
+- 再重复执行2,3二步,直到i==j,将基准数填入a[i]中
+
+```python
+#快速排序
+#L:待排序的序列;start排序的开始index,end序列末尾的index
+#对于长度为length的序列:start = 0;end = length-1
+def quick_sort(L, start, end):
+ if start < end:
+ i, j, pivot = start, end, L[start]
+ while i < j:
+#从右开始向左寻找第一个小于pivot的值
+ while (i < j) and (L[j] >= pivot):
+ j -= 1
+#将小于pivot的值移到左边
+ if (i < j):
+ L[i] = L[j]
+ i += 1
+#从左开始向右寻找第一个大于pivot的值
+ while (i < j) and (L[i] <= pivot):
+ i += 1
+#将大于pivot的值移到右边
+ if (i < j):
+ L[j] = L[i]
+ j -= 1
+#循环结束后,说明 i=j,此时左边的值全都小于pivot,右边的值全都大于pivot
+#pivot的位置移动正确,那么此时只需对左右两侧的序列调用此函数进一步排序即可
+#递归调用函数:依次对左侧序列:从0 ~ i-1//右侧序列:从i+1 ~ end
+ L[i] = pivot
+#左侧序列继续排序
+ quick_sort(L, start, i-1)
+#右侧序列继续排序
+ quick_sort(L, i+1, end)
+```
+
+### 归并排序 (Merge sort)
+
+
+
+1. 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个典型的应用。它的基本操作是:将已有的子序列合并,达到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
+2. 归并排序其实要做两件事:
+ - 分解----将序列每次折半拆分
+ - 合并----将划分后的序列段两两排序合并
+因此,归并排序实际上就是两个操作,拆分+合并
+3. 如何合并?
+ - L[first...mid]为第一段,L[mid+1...last]为第二段,并且两端已经有序,现在我们要将两端合成达到L[first...last]并且也有序。
+ - 首先依次从第一段与第二段中取出元素比较,将较小的元素赋值给temp[]
+ - 重复执行上一步,当某一段赋值结束,则将另一段剩下的元素赋值给temp[]
+ - 此时将temp[]中的元素复制给L[],则得到的L[first...last]有序
+4. 如何分解?
+ - 在这里,我们采用递归的方法,首先将待排序列分成A,B两组;
+ - 然后重复对A、B序列分组;
+ - 直到分组后组内只有一个元素,此时我们认为组内所有元素有序,则分组结束。
+
+```python
+# 归并排序
+#这是合并的函数
+# 将序列L[first...mid]与序列L[mid+1...last]进行合并
+def mergearray(L, first, mid, last, temp):
+#对i,j,k分别进行赋值
+ i, j, k = first, mid+1, 0
+#当左右两边都有数时进行比较,取较小的数
+ while (i <= mid) and (j <= last):
+ if L[i] <= L[j]:
+ temp[k] = L[i]
+ i += 1
+ k += 1
+ else:
+ temp[k] = L[j]
+ j += 1
+ k += 1
+#如果左边序列还有数
+ while (i <= mid):
+ temp[k] = L[i]
+ i += 1
+ k += 1
+#如果右边序列还有数
+ while (j <= last):
+ temp[k] = L[j]
+ j += 1
+ k += 1
+#将temp当中该段有序元素赋值给L待排序列使之部分有序
+ for x in range(0, k):
+ L[first+x] = temp[x]
+# 这是分组的函数
+def merge_sort(L, first, last, temp):
+ if first < last:
+ mid = int(((first + last) / 2))
+#使左边序列有序
+ merge_sort(L, first, mid, temp)
+#使右边序列有序
+ merge_sort(L, mid+1, last, temp)
+#将两个有序序列合并
+ mergearray(L, first, mid, last, temp)
+# 归并排序的函数
+def merge_sort_array(L):
+#声明一个长度为len(L)的空列表
+ temp = len(L)*[None]
+#调用归并排序
+ merge_sort(L, 0, len(L)-1, temp)
+```
+
+### 基数排序 (Radix sort)
+
+
+
+1. 基数排序:通过序列中各个元素的值,对排序的N个元素进行若干趟的“分配”与“收集”来实现排序。
+ - 分配:我们将L[i]中的元素取出,首先确定其个位上的数字,根据该数字分配到与之序号相同的桶中
+ - 收集:当序列中所有的元素都分配到对应的桶中,再按照顺序依次将桶中的元素收集形成新的一个待排序列L[ ]
+ - 对新形成的序列L[]重复执行分配和收集元素中的十位、百位...直到分配完该序列中的最高位,则排序结束
+2. 根据上述“基数排序”的展示,我们可以清楚的看到整个实现的过程
+
+```python
+#************************基数排序****************************
+#确定排序的次数
+#排序的顺序跟序列中最大数的位数相关
+def radix_sort_nums(L):
+ maxNum = L[0]
+#寻找序列中的最大数
+ for x in L:
+ if maxNum < x:
+ maxNum = x
+#确定序列中的最大元素的位数
+ times = 0
+ while (maxNum > 0):
+ maxNum = int((maxNum/10))
+ times += 1
+ return times
+#找到num从低到高第pos位的数据
+def get_num_pos(num, pos):
+ return (int((num/(10**(pos-1))))) % 10
+#基数排序
+def radix_sort(L):
+ count = 10 * [None] #存放各个桶的数据统计个数
+ bucket = len(L) * [None] #暂时存放排序结果
+#从低位到高位依次执行循环
+ for pos in range(1, radix_sort_nums(L)+1):
+ #置空各个桶的数据统计
+ for x in range(0, 10):
+ count[x] = 0
+ #统计当前该位(个位,十位,百位....)的元素数目
+ for x in range(0, len(L)):
+ #统计各个桶将要装进去的元素个数
+ j = get_num_pos(int(L[x]), pos)
+ count[j] += 1
+ #count[i]表示第i个桶的右边界索引
+ for x in range(1,10):
+ count[x] += count[x-1]
+ #将数据依次装入桶中
+ for x in range(len(L)-1, -1, -1):
+ #求出元素第K位的数字
+ j = get_num_pos(L[x], pos)
+ #放入对应的桶中,count[j]-1是第j个桶的右边界索引
+ bucket[count[j]-1] = L[x]
+ #对应桶的装入数据索引-1
+ count[j] -= 1
+ # 将已分配好的桶中数据再倒出来,此时已是对应当前位数有序的表
+ for x in range(0, len(L)):
+ L[x] = bucket[x]
+```
+
+## 运行时间实测
+
+10w数据
+```
+直接插入排序:1233.581131
+希尔排序:1409.8012320000003
+简单选择排序:466.66974500000015
+堆排序:1.2036720000000969
+冒泡排序:751.274449
+#****************************************************
+快速排序:1.0000003385357559e-06
+#快速排序有误:实际上并未执行
+#RecursionError: maximum recursion depth exceeded in comparison
+#****************************************************
+归并排序:0.8262230000000272
+基数排序:1.1162899999999354
+```
+从运行结果上来看,堆排序、归并排序、基数排序真的快。
+对于快速排序迭代深度超过的问题,可以将考虑将快排通过非递归的方式进行实现。
+
+## Resources
+
+1. [算法导论》笔记汇总](http://mindlee.com/2011/08/21/study-notes-directory/)
+2. [八大排序算法的 Python 实现](http://python.jobbole.com/82270/)
+3. [数据结构常见的八大排序算法(详细整理)](https://www.jianshu.com/p/7d037c332a9d)
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\345\255\220\351\233\206\345\220\210\351\227\256\351\242\230.md" "b/docs/Leetcode_Solutions/Python/Summary/\345\255\220\351\233\206\345\220\210\351\227\256\351\242\230.md"
new file mode 100644
index 000000000..0d4afa96a
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\345\255\220\351\233\206\345\220\210\351\227\256\351\242\230.md"
@@ -0,0 +1,114 @@
+###子集合问题
+
+####78. Subsets
+
+子集合是全排列的好朋友,也是combination组合的好朋友,排列·组合·子集,他们三个都是好朋友.
+
+
+#####从空开始加
+
+同样先来看'ABC'
+
+```
+def recsubsets(sofar, rest):
+ if rest == '':
+ print sofar,
+ else:
+ recsubsets(sofar, rest[1:])
+ recsubsets(sofar + rest[0], rest[1:])
+
+def listsubsets(s):
+ recsubsets('',s)
+
+
+listsubsets('ABC')
+```
+
+##### 市面流行思路
+
+市面上流行的思路:
+
+- [[],[1]] 是 [1] 的子集合
+- [[],[1],[2],[1,2]] 是 [1,2] 的子集合,实际上就是1的子集合们加了一个2
+
+
+所以用python写起来也很简单/精美
+
+```
+def subsets(nums):
+ """
+ :type nums: List[int]
+ :rtype: List[List[int]]
+ """
+ results = [[]]
+ for num in nums:
+ results.extend([result + [num] for result in results])
+ return results
+```
+我在这里犯过错,所以这一句
+
+`results.extend([result + [num] for result in results])` 实际上等于:
+
+
+```
+tmp = []
+for result in results:
+ tmp.append(result + [num])
+results.extend(tmp)
+```
+
+
+
+
+
+#### 90. Subsets II
+
+
+要去重了,比如如果有 [1,2,2],那么解答为:
+
+
+ [
+ [2],
+ [1],
+ [1,2,2],
+ [2,2],
+ [1,2],
+ []
+ ]
+
+
+现在来观察规律,与之前有不同之处是我们需要一个位置来mark,因为不再需要往之前出现过的地方再加了,看这个:
+
+
+```
+[[],[1]] 是 [1] 的子集合
+[[],[1],[2],[1,2]] 是 [1,2] 的子集合,实际上就是1的子集合们加了一个2
+新来的2不能再从头开始加了,它需要从[ .., [2],[1,2] ]加 才是合理的
+```
+
+所以看到非常精妙的代码
+
+
+```
+def subsets(nums):
+ """
+ :type nums: List[int]
+ :rtype: List[List[int]]
+ """
+ nums.sort()
+ result = [[]]
+ temp_size = 0
+
+ for i in range(len(nums)):
+ start = temp_size if i >= 1 and nums[i] == nums[i-1] else 0
+ temp_size = len(result)
+ #print start,temp_size,result
+ for j in range(start, temp_size):
+ result.append(result[j] + [nums[i]])
+ print result
+
+subsets([1,2,2])
+```
+
+这里这个start是来记录了之前一次数组的长度,temp_size记住目前数组的长度,然后用这个来达到去重的目的,非常聪明
+
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\346\200\273\347\273\223.md" "b/docs/Leetcode_Solutions/Python/Summary/\346\200\273\347\273\223.md"
new file mode 100644
index 000000000..99fcba752
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\346\200\273\347\273\223.md"
@@ -0,0 +1,120 @@
+# 1
+```solution```下自定义函数```func(self, fargs, *args, **kwargs)```, 调用时使用```self.func()```的格式
+
+# 2
+```not fargs``` 和 ```fargs == None```不一样,前者```fargs```可能为[], '', 0, etc
+
+# 3
+递归问题
+Any problem can be solved using dp. Solving using a greedy strategy is harder though, since you need to prove that greedy will work for that problem. There are some tell-tale signs of a problem where greedy may be applicable, but isn’t immediately apparent. Example:
+
+- Choice of an element depends only on its immediate neighbours (wiggle sort).
+- Answer is monotonically non-decreasing or non-increasing (sorting). This is also applicable for LIS for example.
+- Anything that requires lexicographically largest or smallest of something.
+- Anything where processing the input in sorted order will help.
+- Anything where processing the input in forward or reverse (as given) will help.
+- Anything which requires you to track the minimum or maximum of something (think of sliding window problems).
+
+There’s matroid theory which deal with greedy algorithms, but I don’t really understand it. If someone does, I’ll be super grateful to them to explain it to me in simple language!
+
+In general, try to see if for a problem, the solution doesn’t depend on a lot of history about the solution itself, but the next part of the solution is somewhat independent from the rest of the solution. These are all indicative of the fact that a greedy strategy could be applicable.
+
+# 4
+[Counter.elements()](https://docs.python.org/2/library/collections.html)
+
+# 5
+测试案例写法
+
+```python
+import unittest
+class Solution(object):
+ def isMatch(self, s, p):
+ """
+ :type s: str
+ :type p: str
+ :rtype: bool
+ """
+ m, n = len(s), len(p)
+ dp = [ [0 for i in range(n+1)] for j in range(m+1)]
+
+ dp[0][0] = 1
+
+ # init the first line
+ for i in range(2,n+1):
+ if p[i-1] == '*':
+ dp[0][i] = dp[0][i-2]
+
+ for i in range(1,m+1):
+ for j in range(1,n+1):
+ if p[j-1] == '*':
+ if p[j-2] != s[i-1] and p[j-2] != '.':
+ dp[i][j] = dp[i][j-2]
+ elif p[j-2] == s[i-1] or p[j-2] == '.':
+ dp[i][j] = dp[i-1][j] or dp[i][j-2]
+
+ elif s[i-1] == p[j-1] or p[j-1] == '.':
+ dp[i][j] = dp[i-1][j-1]
+
+ return dp[m][n] == 1
+
+
+class TestSolution(unittest.TestCase):
+ def test_none_0(self):
+ s = ""
+ p = ""
+ self.assertTrue(Solution().isMatch(s, p))
+
+ def test_none_1(self):
+ s = ""
+ p = "a"
+ self.assertFalse(Solution().isMatch(s, p))
+
+ def test_no_symbol_equal(self):
+ s = "abcd"
+ p = "abcd"
+ self.assertTrue(Solution().isMatch(s, p))
+
+ def test_no_symbol_not_equal_0(self):
+ s = "abcd"
+ p = "efgh"
+ self.assertFalse(Solution().isMatch(s, p))
+
+ def test_no_symbol_not_equal_1(self):
+ s = "ab"
+ p = "abb"
+ self.assertFalse(Solution().isMatch(s, p))
+
+ def test_symbol_0(self):
+ s = ""
+ p = "a*"
+ self.assertTrue(Solution().isMatch(s, p))
+
+ def test_symbol_1(self):
+ s = "a"
+ p = "ab*"
+ self.assertTrue(Solution().isMatch(s, p))
+
+ def test_symbol_2(self):
+ # E.g.
+ # s a b b
+ # p 1 0 0 0
+ # a 0 1 0 0
+ # b 0 0 1 0
+ # * 0 1 1 1
+ s = "abb"
+ p = "ab*"
+ self.assertTrue(Solution().isMatch(s, p))
+
+
+if __name__ == "__main__":
+ unittest.main()
+
+
+
+输出:
+........
+
+Ran 8 tests in 0.001s
+
+OK
+```
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\346\226\220\346\263\242\351\202\243\345\245\221\347\232\204DP\346\200\235\350\200\203.md" "b/docs/Leetcode_Solutions/Python/Summary/\346\226\220\346\263\242\351\202\243\345\245\221\347\232\204DP\346\200\235\350\200\203.md"
new file mode 100644
index 000000000..84ce8bbbf
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\346\226\220\346\263\242\351\202\243\345\245\221\347\232\204DP\346\200\235\350\200\203.md"
@@ -0,0 +1,42 @@
+Fibonacci 的DP版本
+
+对于DP的不同理解造成不同的写法
+Memoization will usually add on your time-complexity to your space-complexity (e.g. with tabulation you have more liberty to throw away calculations, like using tabulation with Fib lets you use O(1) space, but memoization with Fib uses O(N) stack space).
+详看
+
+[Dynamic programming and memoization: bottom-up vs top-down approaches](https://awjin.me/algos-js/dp/tab-memo.html)
+
+[Tabulation vs Memoizatation](http://www.geeksforgeeks.org/tabulation-vs-memoizatation/)
+- top-down(memorize)
+
+```
+def memorize_fib(n): # n为第几个Fibonacci数
+ memo = {1:1, 2:1}
+ if n in memo:
+ return memo[n]
+ else:
+ memo[n] = memorize_fib(n-1) + memorize_fib(n-2)
+ return memo[n]
+
+print(memorize_fib(4)) # 输出3
+```
+
+
+
+- bottom up(tabulation)
+
+```
+def tabulation_fib(n): # n为第几个Fibonacci数
+ fib = [1, 1, 2]
+ if n < 4:
+ return fib[n-1]
+ for k in range(3, n+1):
+ fib[2] = fib[0] + fib[1]
+ fib[0], fib[1] = fib[1], fib[2]
+ return fib[2]
+
+print(tabulation_fib(4)) # 输出3
+```
+
+
+这里memo用dict,用array也一样。当然用bottom up还有一点,可以只存每次最后两个数,可以save space.,这样就只用到constant space.
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\347\203\231\345\215\260\344\277\256\347\202\274\345\244\247\346\263\225.md" "b/docs/Leetcode_Solutions/Python/Summary/\347\203\231\345\215\260\344\277\256\347\202\274\345\244\247\346\263\225.md"
new file mode 100644
index 000000000..1765d341f
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\347\203\231\345\215\260\344\277\256\347\202\274\345\244\247\346\263\225.md"
@@ -0,0 +1,12 @@
+## 战略思想
+
+先要了解敌方的战略
+
+```
+自我介绍5分钟,闲聊20分钟,再给你半道题目,要求你15分钟内想出最优解
+且代码实现 bug free并完成test cases,没完成超时,完成不符合题意
+```
+
+## 应对方法
+
+没辙,🤷♂️
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\347\273\204\345\220\210\351\227\256\351\242\230.md" "b/docs/Leetcode_Solutions/Python/Summary/\347\273\204\345\220\210\351\227\256\351\242\230.md"
new file mode 100644
index 000000000..33f295e82
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\347\273\204\345\220\210\351\227\256\351\242\230.md"
@@ -0,0 +1,84 @@
+### 组合问题
+
+
+#### 77.Combinations
+
+
+##### 会超时的recursion
+
+
+
+```
+class Solution(object):
+ def combine(self, n, k):
+ """
+ :type n: int
+ :type k: int
+ :rtype: List[List[int]]
+ """
+ ans = []
+ self.dfs(n, k, 1, [], ans)
+ return ans
+
+ def dfs(self, n, k ,start, lst, ans):
+ if k == 0 :
+ ans.append(lst)
+ return
+ for i in range(start, n+1):
+ self.dfs(n, k - 1, i + 1,lst +[i], ans)
+```
+
+理解方式
+
+```
+
+ 1 2 3
+ 12 13 14 23 24 34
+```
+
+可以参照这里
+
+
+
+
+
+##### 市面上流行解法
+
+递归的思想: n选k
+
+- 如果 k==n ,则全选。
+- n > k 又可以分成两类:
+ - 选了n, 则在余下的n-1中选k-1
+ - 没有选n, 则在余下的n-1中选k
+
+注意一下会有两个base case,因为k在不断减小和n在不断减小,所以写起来可以这样:
+
+
+```
+def combine(n,k):
+ if k == 1:
+ return [[i+1] for i in range(n)]
+ if n == k:
+ return [range(1, k+1)]
+ # choose n , not choose n
+ return [r + [n] for r in combine(n-1,k-1)] + combine(n-1,k)
+
+
+print combine(20,16)
+```
+
+
+#### 39. Combination Sum
+
+
+使用正常递归思路
+
+
+#### 40. Combination Sum II
+
+重复做跳过处理
+
+#### 216. Combination Sum III
+
+
+#### 377. Combination Sum IV
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\347\274\226\347\250\213\346\200\235\350\267\257\346\200\273\347\273\223.md" "b/docs/Leetcode_Solutions/Python/Summary/\347\274\226\347\250\213\346\200\235\350\267\257\346\200\273\347\273\223.md"
new file mode 100644
index 000000000..53cde29b2
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\347\274\226\347\250\213\346\200\235\350\267\257\346\200\273\347\273\223.md"
@@ -0,0 +1,20 @@
+## 1. OJ 基本条件
+达尔大佬对刷leetcode和刷笔试题有几个建议:
+
+1. 一般oj是有要求时间的,一般是1秒。后台判题系统都是单核单线程跑,机器性能不会太好。1秒能运行的基本操作个数的量级是10^6-10^7,
+个别代码能跑到10^8,但很少见。这种情况下,看数据范围是可以大致了解到这个题目需要什么样子的时间复杂度。
+比如说,n<=1000的数据范围,o(n^3)的代码就不要写了,浪费时间而已。写代码之前得先计算自己代码的复杂度,预估自己代码跑的速度,再动手。
+2. 基本操作指的是逻辑和加减法,乘法比加减法慢得多,但在大复杂度的前提下,这种复杂度是可以忽略的。比如说,在一个算法o(n^3)中,
+代码中一个两层嵌套循环o(n^2)就显得没什么优化意义了。优化代码主要优化算法复杂度,而那些,要不要用位运算代替除法啊,
+或者两个一层循环要不要合并成一个一层循环啊,没有意义,不要纠结,同级复杂度,才有优化意义
+3. 高级编程语言每个api都有自己的复杂度,在没有了解复杂度之前不建议使用那些api,最好自己实现,比如哈希表啊,堆啊,
+什么语言都有实现,熟悉之前还是乖乖自己实现的好
+4. 注意精度误差。。。比如开方,如果开方开的是一个整数,结果也是整数,最好写个二分,或者写个牛顿迭代求零点,
+不要用内置函数sqrt,求出来是个浮点数,会有误差
+
+
+## 2. 判断环
+- 看到链表中的环就想到快慢指针
+- 看到图中的环就想到并查集,wisdompeak大佬说:用union find确实是判断图是否成环的一个很好的手段。但是它更常用在无向图。
+对于有向图,用并查集需要非常小心。这里的edge都是有向的,我觉得无脑用并查集会有风险。
+我的总结是:union find唯一能用在有向图的地方,就是只有我们试图保证这张图是树的时候。
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\351\200\222\345\275\222_recursion.md" "b/docs/Leetcode_Solutions/Python/Summary/\351\200\222\345\275\222_recursion.md"
new file mode 100644
index 000000000..413872965
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\351\200\222\345\275\222_recursion.md"
@@ -0,0 +1,39 @@
+#递归 Recursion
+
+### 递归
+
+递归绝对是一个非常重要的概念。比如安利? 不断的delegate,本来想要完成1000个人的销售,找10个人,每人完成100人的,这10个人每人再去找10个人,每人完成10人的销售,这样就完成了1000人的销售(不懂安利是否这样,拿来举例)。
+
+
+递归之所以重要,这里面存在的概念太多了,首先上面这个例子里面就有divide and conquer的意思,把task divide小,然后来解决它。
+
+
+同样有趣的例子 → 吃完一个bowl of chips:
+
+- for loop,知道多少薯片,然后从0开始吃到最后
+- while, while 碗里还有薯片,就吃
+- 递归,吃一片,然后继续吃剩下的 N - 1 片,直到碗里的薯片数量只剩下0片了
+
+
+典型的例子:
+
+- pow(x,n)
+- isPalindrome
+- TowerofHanoi
+- binarySearch
+
+
+
+### 链表, 树, 图
+
+链表(linked list) 是数据结构的基础,而链表本身就是具有递归特性的,看C++中对于linked list node的定义, next指向本身这样的结构,就是再这个node定义还未完成之时,我们已经指向自己。
+
+
+```
+struct node{
+ int data;
+ node* next;
+};
+```
+
+binary tree定义就是靠递归来实现的。
diff --git "a/docs/Leetcode_Solutions/Python/Summary/\351\235\242\350\257\225\347\241\256\350\256\244\351\242\230\347\233\256\347\273\206\350\212\202\351\227\256\351\242\230.md" "b/docs/Leetcode_Solutions/Python/Summary/\351\235\242\350\257\225\347\241\256\350\256\244\351\242\230\347\233\256\347\273\206\350\212\202\351\227\256\351\242\230.md"
new file mode 100644
index 000000000..90a8924a2
--- /dev/null
+++ "b/docs/Leetcode_Solutions/Python/Summary/\351\235\242\350\257\225\347\241\256\350\256\244\351\242\230\347\233\256\347\273\206\350\212\202\351\227\256\351\242\230.md"
@@ -0,0 +1,3 @@
+1. The length of the given array is positive and will not exceed 20?
+2. The sum of elements in the given array will not exceed 1000?
+3. The output answer is guaranteed to be fitted in a 32-bit integer?
diff --git a/docs/Leetcode_Solutions/ipynb/001._two_sum.ipynb b/docs/Leetcode_Solutions/ipynb/001._two_sum.ipynb
new file mode 100644
index 000000000..c1fc51bf0
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/001._two_sum.ipynb
@@ -0,0 +1,251 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 1. Two Sum 两数之和\n",
+ "\n",
+ "## 题目:\n",
+ "\n",
+ " - https://leetcode.com/problems/two-sum/\n",
+ " - https://leetcode-cn.com/problems/two-sum/description/\n",
+ "\n",
+ "```\n",
+ "给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。\n",
+ "\n",
+ "你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。\n",
+ "\n",
+ "> 示例:\n",
+ "\n",
+ "给定 nums = [2, 7, 11, 15], target = 9\n",
+ "\n",
+ "因为 nums[0] + nums[1] = 2 + 7 = 9\n",
+ "所以返回 [0, 1]\n",
+ "```\n",
+ "\n",
+ "## 难度:Easy\n",
+ "\n",
+ "这个题目略微有点简单,我们只要注意的是,同样的元素不能被重复利用两次。\n",
+ "\n",
+ "还有就是思考,是不是我们可以使用一次循环就能够找到这两个数呢?\n",
+ "\n",
+ "接下来我们看一下如何解决这个问题。\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ " - 简单判断一下,是否两个数都在 list 中,以及判断两个数不是重复利用一个元素即可。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[1, 2]\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def twoSum(self, nums, target):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :type target: int\n",
+ " :rtype: List[int]\n",
+ " \"\"\"\n",
+ " # 循环名为 nums 的 list\n",
+ " for num_one in nums:\n",
+ " # 判断 target 减去 num_one 是否仍在我们的 nums list 中,另一个条件是这两个数不是同一个元素\n",
+ " if target - num_one in nums and num_one is not target-num_one:\n",
+ " # 返回两个数对应的 index\n",
+ " return [nums.index(num_one), nums.index(target - num_one)]\n",
+ " \n",
+ "nums = [4, 3, 5, 15]\n",
+ "target = 8\n",
+ "s = Solution()\n",
+ "print(s.twoSum(nums, target))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ " - 其实我们上一个解决方案已经是弄的一个 for 循环了,这次我们换一个思路。\n",
+ " - 可以用 $O(n^2)$ 的循环(lookup)\n",
+ " - 其实也可以牺牲空间换取时间,异常聪明的 AC 解法\n",
+ " \n",
+ "```\n",
+ " 2 7 11 15\n",
+ " 不存在 存在之中 \n",
+ "lookup {2:0} [0, 1]\n",
+ "```\n",
+ "大体思路如下:\n",
+ "\n",
+ " - 建立字典 lookup 存放第一个数字,并存放该数字的 index\n",
+ " - 判断 lookup 中是否存在: target - 当前数字, 则表面 当前值和 lookup中的值加和为 target\n",
+ " - 如果存在,则返回: target - 当前数字 的 index 和 当前值的 index"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[1, 2]\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def twoSum(self, nums, target):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :type target: int\n",
+ " :rtype: List[int]\n",
+ " \"\"\"\n",
+ " # 创建 lookup 字典\n",
+ " lookup = {}\n",
+ " # 使用 enumerate 语法,返回的是每一个元素及其对应的 index\n",
+ " for i, num in enumerate(nums):\n",
+ " if target - num in lookup:\n",
+ " return [lookup[target - num],i]\n",
+ " lookup[num] = i\n",
+ " return []\n",
+ " \n",
+ "nums = [4, 3, 5, 15]\n",
+ "target = 8\n",
+ "s = Solution()\n",
+ "print(s.twoSum(nums, target))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 3\n",
+ "\n",
+ " - 对于 dict ,也就是其他语言的 map,判断一个元素在不在容器中,list 要遍历,而 set 和 dict 直接根据哈希算出,不需要遍历\n",
+ " - 我们可以仿照上面的代码,但是换个简单的写法。\n",
+ " - 对于字典的这种方式,如果我们只是判断 i 以及 target - i 是不是相等,这样是错误的,如果两个元素相同,但是不是同一个元素,那就会出错了。\n",
+ " \n",
+ "比如,我们先看一下错误的版本:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "None\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def twoSum(self, nums, target):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :type target: int\n",
+ " :rtype: List[int]\n",
+ " \"\"\"\n",
+ " dict1 = {}\n",
+ " for k, i in enumerate(nums):\n",
+ " dict1[i] = k\n",
+ " if target - i in dict1 and i is not target - i:\n",
+ " return [dict1[target - i], dict1[i]]\n",
+ "\n",
+ "nums = [3, 3]\n",
+ "target = 6\n",
+ "s = Solution()\n",
+ "print(s.twoSum(nums, target))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "上面的代码是存在问题的,对于相同的元素 [3, 3], target =6, 就得到了 None ,按理说,应该得到 [0, 1] 的。所以,这地方的判断是错误的。\n",
+ "\n",
+ " - 对于字典的那种方式,就只能索引为 key,数据为value,只是这样一来,判断在或者不在,还是多了一层循环\n",
+ " \n",
+ "下面的版本是正确的版本:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[0, 1]\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def twoSum(self, nums, target):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :type target: int\n",
+ " :rtype: List[int]\n",
+ " \"\"\"\n",
+ " for k, i in enumerate(nums):\n",
+ " if target - i in nums[k + 1:]:\n",
+ " return [k, nums[k + 1:].index(target - i) + k + 1]\n",
+ "\n",
+ "nums = [3, 3]\n",
+ "target = 6\n",
+ "s = Solution()\n",
+ "print(s.twoSum(nums, target)) "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 小结\n",
+ "\n",
+ "应该还有更加好的解法,大佬们积极贡献自己的解法哈。一起为好的工作,好的未来,加油。"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/002._add_two_numbers.ipynb b/docs/Leetcode_Solutions/ipynb/002._add_two_numbers.ipynb
new file mode 100644
index 000000000..7971d4200
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/002._add_two_numbers.ipynb
@@ -0,0 +1,245 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 2.Add Two Numbers\n",
+ "\n",
+ "### 难度:Medium\n",
+ "\n",
+ "## 刷题内容:\n",
+ "\n",
+ "> 原题链接:\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/add-two-numbers/description/\n",
+ " - 英文:https://leetcode.com/problems/add-two-numbers/\n",
+ "\n",
+ "> 内容描述:\n",
+ "\n",
+ "给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。\n",
+ "\n",
+ "你可以假设除了数字 0 之外,这两个数字都不会以零开头。\n",
+ "\n",
+ "示例:\n",
+ "```\n",
+ "输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)\n",
+ "输出:7 -> 0 -> 8\n",
+ "原因:342 + 465 = 807\n",
+ "```\n",
+ "\n",
+ "## 解法方案\n",
+ "\n",
+ "由于两数相加可能会出现进位,所以加法我们谁都会算,但是要着重注意的一点是,要考虑上一位的进位,并且传递给下一位计算时的进位。\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ "我们先构建一个空的头结点不动,然后尾结点从头结点开始向后不断生成新的结点。遍历两个链表的公共部分,每次相加相应位数字和进位,分配到结果的链表中。公共部分遍历完后再确定长的链表剩余的部分,同样的方式遍历完。\n",
+ "\n",
+ " - 需要注意的是遍历时每次都要更新进位,不断计算和时有没有发生进位,以防止之前数据的污染。\n",
+ " - 对于 python 来说,需要新的变量做游标来遍历两个链表,不能直接用形参,否则我们会修改原链表。\n",
+ " - 注意最后可能的进位。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "7\n",
+ "0\n",
+ "8\n",
+ "None\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Definition for singly-linked list.\n",
+ "class ListNode:\n",
+ " def __init__(self, x):\n",
+ " self.val = x\n",
+ " self.next = None\n",
+ "\n",
+ "class Solution: \n",
+ " def addTwoNumbers(self, l1, l2):\n",
+ " \"\"\"\n",
+ " :type l1: ListNode\n",
+ " :type l2: ListNode\n",
+ " :rtype: ListNode\n",
+ " \"\"\"\n",
+ " # 用 p1, p2 赋值为 l1 和 l2 ,以防止我们的操作改变原链表\n",
+ " p1, p2 = l1, l2\n",
+ " # 创建一个空链表用来返回结果,分别有头结点和尾结点\n",
+ " head = ListNode(0)\n",
+ " tail = head\n",
+ " # carry 表示进位值\n",
+ " carry = 0\n",
+ " # 处理两个链表的公共部分,也就是两个链表都不为空的部分\n",
+ " while p1 and p2:\n",
+ " # 计算当前位相加的和\n",
+ " num = p1.val + p2.val + carry\n",
+ " # 大于 9 ,应该向前进一位\n",
+ " if num > 9:\n",
+ " num -= 10\n",
+ " carry = 1\n",
+ " else:\n",
+ " carry = 0\n",
+ " # 添加结点\n",
+ " tail.next = ListNode(num)\n",
+ " # 尾结点向后移动\n",
+ " tail = tail.next\n",
+ " # 移动两条链表的公共部分\n",
+ " p1 = p1.next\n",
+ " p2 = p2.next\n",
+ " # 取长链表剩余的部分,也就是未参与上面计算的部分\n",
+ " if p2:\n",
+ " # 如果 p2 较长,将 p2 剩余的部分赋值给 p1 ,我们只需要处理 p1 就行了\n",
+ " p1 = p2\n",
+ " # 接下来,处理长链表剩余分部分\n",
+ " while p1:\n",
+ " # 最近的一位,我们要考虑一下,是否有进位\n",
+ " num = p1.val + carry\n",
+ " if num > 9:\n",
+ " num -= 10\n",
+ " carry = 1\n",
+ " else:\n",
+ " carry = 0\n",
+ " # 添加结点\n",
+ " tail.next = ListNode(num)\n",
+ " tail = tail.next\n",
+ " \n",
+ " # 移动我们处理的链表\n",
+ " p1 = p1.next\n",
+ " # 如果最后仍然有进位,我们需要再分配一个结点\n",
+ " if carry:\n",
+ " # 创建一个 val 为 1 的 ListNode 结点,然后将 tail 向后移动一位\n",
+ " tail.next = ListNode(1)\n",
+ " tail = tail.next\n",
+ " # 将所有的加和及进位都处理完成了,现在我们将链表收尾\n",
+ " tail.next = None\n",
+ " # 将 链表的头结点返回\n",
+ " return head.next # 去除掉我们初始化为 0 的头结点\n",
+ "\n",
+ "la = ListNode(2)\n",
+ "la.next = ListNode(4)\n",
+ "la.next.next = ListNode(3)\n",
+ "\n",
+ "lb = ListNode(5)\n",
+ "lb.next = ListNode(6)\n",
+ "lb.next.next = ListNode(4)\n",
+ "\n",
+ "s = Solution()\n",
+ "ss = s.addTwoNumbers(la, lb)\n",
+ "print(ss.val)\n",
+ "print(ss.next.val)\n",
+ "print(ss.next.next.val)\n",
+ "print(ss.next.next.next) "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "因此,这个地方我们可以考虑使用递归来求解,具体可以分为以下情况:\n",
+ "\n",
+ " - 当两个链表均不为空时,计算两个节点值与上一位进位的和 sum,取 sum 的个位数构建新的节点,更新进位为 sum 的十位数,令本节点的 next 指针指向下一位求和返回的节点。\n",
+ " - 当两个链表其中一个为空时,计算不为空的节点值与上一位进位的和 sum,更新进位为 sum 的十位数。若进位不为 0 ,取 sum 的个位数构建新节点,令本节点的 next 指针指向下一位求和返回的节点,注意只传递不为空的链表;若进位为 0,则直接更新不为空节点的值为 sum,此时此链表之后的所有高位值都不会更新,因此返回此节点。\n",
+ " - 若两个链表都为空,判断进位是否为 0。若进位为 0,直接返回 NULL;否则构建值为进位值的新节点,并返回此节点。\n",
+ " \n",
+ "> 思路 2\n",
+ "\n",
+ " - 跟 plus One ,add Binary 玩的同一个花样,但是相对上个思路来说,更加简单和简洁。\n",
+ " - 使用递归调用简化算法"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "7\n",
+ "0\n",
+ "8\n",
+ "None\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Definition for singly-linked list.\n",
+ "class ListNode:\n",
+ " def __init__(self, x):\n",
+ " self.val = x\n",
+ " self.next = None\n",
+ "\n",
+ "class Solution(object):\n",
+ " def addTwoNumbers(self, l1, l2):\n",
+ " \"\"\"\n",
+ " :type l1: ListNode\n",
+ " :type l2: ListNode\n",
+ " :rtype: ListNode\n",
+ " \"\"\"\n",
+ " # 特殊情况\n",
+ " if l1 == None:\n",
+ " return l2\n",
+ " if l2 == None:\n",
+ " return l1\n",
+ " # 如果 相加 小于 10 ,不需要进位\n",
+ " if l1.val + l2.val < 10:\n",
+ " l3 = ListNode(l1.val + l2.val)\n",
+ " l3.next = self.addTwoNumbers(l1.next, l2.next)\n",
+ " # 相加大于等于 10,需要进位\n",
+ " elif l1.val + l2.val >= 10:\n",
+ " l3 = ListNode(l1.val + l2.val - 10)\n",
+ " tmp = ListNode(1)\n",
+ " tmp.next = None\n",
+ " # 递归调用\n",
+ " l3.next = self.addTwoNumbers(l1.next, self.addTwoNumbers(l2.next ,tmp))\n",
+ " return l3\n",
+ " \n",
+ "la = ListNode(2)\n",
+ "la.next = ListNode(4)\n",
+ "la.next.next = ListNode(3)\n",
+ "\n",
+ "lb = ListNode(5)\n",
+ "lb.next = ListNode(6)\n",
+ "lb.next.next = ListNode(4)\n",
+ "\n",
+ "s = Solution()\n",
+ "ss = s.addTwoNumbers(la, lb)\n",
+ "print(ss.val)\n",
+ "print(ss.next.val)\n",
+ "print(ss.next.next.val)\n",
+ "print(ss.next.next.next)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/005._longest_palindromic_substring.ipynb b/docs/Leetcode_Solutions/ipynb/005._longest_palindromic_substring.ipynb
new file mode 100644
index 000000000..f0a71c9d4
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/005._longest_palindromic_substring.ipynb
@@ -0,0 +1,388 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 005. Longest Palindromic Substring 最长回文子串\n",
+ "\n",
+ "### 难度:Medium\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/longest-palindromic-substring/description/\n",
+ " - 英文:https://leetcode.com/problems/longest-palindromic-substring/\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。\n",
+ "\n",
+ "示例 1:\n",
+ "输入: \"babad\"\n",
+ "输出: \"bab\"\n",
+ "注意: \"aba\"也是一个有效答案。\n",
+ "\n",
+ "示例 2:\n",
+ "输入: \"cbbd\"\n",
+ "输出: \"bb\"\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ "如果一个字符串从左向右写和从右向左写是一样的,这样我们就把它叫做回文字符串。如 aba 或者 abba。\n",
+ "\n",
+ "首先想到的是一个最笨的方法,就是依次把每一个字符当做回文字符串的中间的那个字符,向两边扩展,找到以该字符为中间字符的回文串的最大长度。但是这需要将回文串长度是奇偶的情况分开来讨论。然后接下来要注意的关键是对边界的把握,确保下标不要越界。当子串已经包含首字符或最后一个字符且此时还是回文串的时候,下标分别会向两边多移一位,需要补回来。\n",
+ "\n",
+ "以 abba 这样一个字符串为例来看,abba 中,一共有偶数个字,第 1 位=倒数第 1 位,第 2 位=倒数第 2 位......第 N 位=倒数第 N 位\n",
+ "\n",
+ "以 aba 这样一个字符串为例来看,aba 中,一共有奇数个字符,排除掉正中间的那个字符后,第 1 位=倒数第 1 位......第 N 位=倒数第 N 位\n",
+ "\n",
+ "所以,假设找到一个长度为 len1 的子串后,我们接下去测试它是否满足,第 1 位=倒数第 1 位,第 2 位=倒数第 2 位......第 N 位=倒数第 N 位,也就是说,去测试从头尾到中点,字符是否逐一对应相等。如果一直进行了 [length/2] 次后,对应字符都相等,即满足第 i 位=倒数第 i 位。那么这个子串必然是palindromic string。并且,很容易知道,无论这个字符串长度为奇数还是偶数,都是 palindromic string,因为奇数位数的字符串相当于满足,第中间位=第中间位。\n",
+ "\n",
+ "于是,现在问题转化为能不能找到一个子串,满足,第 1 位=倒数第 1 位(下文叫做候选子串)。如果有,就对剩下的字符做进一步的检查。\n",
+ "\n",
+ "我们看一下下面的代码:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "cbc\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def longestPalindrome(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: str\n",
+ " \"\"\"\n",
+ " if not s:\n",
+ " return\n",
+ " n = len(s)\n",
+ " if n == 1:\n",
+ " return s\n",
+ " # Left index of the target substring\n",
+ " l = 0\n",
+ " # Right index of the target substring\n",
+ " r = 0\n",
+ " # Length of the longest palindromic substring for now \n",
+ " m = 0\n",
+ " # Length of the current substring\n",
+ " c = 0\n",
+ " # Whether the substring contains the first character or last character\n",
+ " # and is palindromic\n",
+ " b = True\n",
+ " # i 设置的是字符串的一个字符\n",
+ " for i in range(0, n):\n",
+ " # 奇数情况\n",
+ " # j 设置的是字符串的 i 字符的左右两边的 j 个字符是不是属于回文串,n-i 限制的是不能超出字符串末尾,i+1 限制的是不能越过字符串的开头\n",
+ " for j in range(0, min(n - i, i + 1)):\n",
+ " # 如果 以 i 字符为中央字符的情况,向两边扩展,不相等的话,代表不是回文串,停止继续比较\n",
+ " if (s[i - j] != s[i + j]):\n",
+ " b = False\n",
+ " break\n",
+ " else:\n",
+ " # 如果以 i 字符为中心字符向左右扩展 j 个字符是回文串,那么现在回文串的长度设置为 c\n",
+ " c = 2 * j + 1\n",
+ " # 判断 c 与 m 的大小,m 记录的是我们目前为止最长的回文串的长度,如果 c > m,那我们最长回文子串设置为 c ,否则仍然是原来的 m\n",
+ " if (c > m):\n",
+ " # 设置新的回文子串的左 index,b 是 True 就是等于 1,b 是 False 等于 0\n",
+ " l = i - j + 1 - b\n",
+ " # 设置新的回文子串的右 index\n",
+ " r = i + j + b\n",
+ " # 将新的最长回文子串赋值给 m\n",
+ " m = c\n",
+ " b = True\n",
+ " # 偶数情况\n",
+ " # i+1 限制的是不超越字符串的开头,n-i-1 限制的是不超过字符串末尾\n",
+ " for j in range(0, min(n - i - 1, i + 1)):\n",
+ " # 偶数情况下,对应位置上是够相等,相等则是回文串,不相等就不是回文串\n",
+ " if (s[i - j] != s[i + j + 1]):\n",
+ " b = False\n",
+ " break\n",
+ " else:\n",
+ " c = 2 * j + 2\n",
+ " if (c > m):\n",
+ " l = i - j + 1 - b\n",
+ " r = i + j + 1 + b\n",
+ " m = c\n",
+ " b = True\n",
+ " # 将最终的回文串返回\n",
+ " return s[l:r]\n",
+ " \n",
+ "s = Solution()\n",
+ "nums = \"acbcd\"\n",
+ "print(s.longestPalindrome(nums))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "上面是我们的一个参考版本,算是思路很清晰的。下面这个是 Lisanaaa 大佬根据上面版本进行修改的完成版本,总体思路是相同的,大家可以参考下。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "cbc\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def longestPalindrome(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: str\n",
+ " \"\"\"\n",
+ " n = len(s)\n",
+ "\n",
+ " m,l,r = 0,0,0\n",
+ "\n",
+ " for i in range(n):\n",
+ " # odd case\n",
+ " for j in range(min(i+1,n-i)):\n",
+ " if s[i-j] != s[i+j]:\n",
+ " break\n",
+ " if 2*j + 1 > m :\n",
+ " m = 2 * j + 1\n",
+ " l = i-j\n",
+ " r = i+j\n",
+ "\n",
+ "\n",
+ " if i+1 < n and s[i] == s[i+1]:\n",
+ " for j in range(min(i+1,n-i-1)):\n",
+ " if s[i-j] != s[i+j+1]:\n",
+ " break\n",
+ " if 2 * j + 2 > m :\n",
+ " m = 2*j +2\n",
+ " l = i-j\n",
+ " r = i+j+1\n",
+ "\n",
+ "\n",
+ " return s[l:r+1]\n",
+ " \n",
+ "s = Solution()\n",
+ "nums = \"acbcd\"\n",
+ "print(s.longestPalindrome(nums))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ "很明显的一个动态规划思路。\n",
+ "\n",
+ " - 这个问题可以联想我们之前做的动态规划的问题,也就是 72 题,思想是一样的,但是相对于我们的 72 题来说,已经是相当简单了。\n",
+ " - 一个比较好的想法是 s 和 reverse(s) 共有的最长的 substring 就是 longest palindromic substring,这样我们就把问题转化为求 Longest common substring 问题了。\n",
+ " - 我们来看一下下面的代码,你就懂得了。\n",
+ " - 如果还是看不懂,那就去看看我们 72 题的讲解,已经很清楚了。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "cbc\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution2(object):\n",
+ " def longestPalindrome(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: str\n",
+ " \"\"\"\n",
+ " def lcs(s1, s2):\n",
+ " m = [[0] * (1 + len(s2)) for i in range(1 + len(s1))]\n",
+ " longest, x_longest = 0, 0\n",
+ " for x in range(1, 1 + len(s1)):\n",
+ " for y in range(1, 1 + len(s2)):\n",
+ " if s1[x - 1] == s2[y - 1]:\n",
+ " m[x][y] = m[x - 1][y - 1] + 1\n",
+ " if m[x][y] > longest:\n",
+ " longest = m[x][y]\n",
+ " x_longest = x\n",
+ " else:\n",
+ " m[x][y] = 0\n",
+ " return s1[x_longest - longest: x_longest]\n",
+ "\n",
+ " return lcs(s, s[::-1])\n",
+ " \n",
+ "s_2 = Solution2()\n",
+ "nums = \"acbcd\"\n",
+ "print(s_2.longestPalindrome(nums))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "典型的动态规划问题。\n",
+ "\n",
+ "伪码如下:\n",
+ "\n",
+ "LCSuff(S1...p, T1...q) = LCS(S1...p1, T1...q-1) if S[p] = T[q] else 0\n",
+ "\n",
+ "代码可以参考:\n",
+ "\n",
+ "https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring#Python_2\n",
+ "\n",
+ "**但是我们上面的动态规划问题,仍然出现了超时的情况。**\n",
+ "\n",
+ "因为我们以为这样s[::-1]已经很快了.\n",
+ "\n",
+ "**特别注意:**\n",
+ "\n",
+ "这个方法是buggy的,看字符串 abcxgcba ,它 reverse 之后是 abcgxcba ,它们有公共字符串,但是这里面没有回文,修复方式是:\n",
+ "\n",
+ "we check if the substring’s indices are the same as the reversed substring’s original indices. If it is, then we attempt to update the longest palindrome found so far; if not, we skip this and find the next candidate.\n",
+ "\n",
+ "我觉得的修复方式这样么:\n",
+ "\n",
+ "```\n",
+ "原本 翻转\n",
+ "ABXYBA ABYXBA\n",
+ "\n",
+ "求出来的substring indices是 0:2 但是这个s1[0:2] 和 s2[0:2]一样,所以不行\n",
+ "同理common substring indices还是s[4:6] 和s2[4:6]一样,不行\n",
+ "\n",
+ "而比如ABAD和 DABA\n",
+ "\n",
+ "substring indice 一个是0:3, 一个是1:4,这样就没问题\n",
+ "```\n",
+ "\n",
+ "> 思路 3\n",
+ "\n",
+ "[Manacher算法,我私下叫马拉车算法,哈哈](https://www.felix021.com/blog/read.php?2040)\n",
+ "\n",
+ "Manacher 算法增加两个辅助变量 id 和 mx ,其中 id 表示最大回文子串中心的位置,mx 则为 id+P[id] ,也就是最大回文子串的边界。得到一个很重要的结论:\n",
+ "\n",
+ " - 如果 mx > i,那么 P[i] >= Min(P[2 * id - i], mx - i) . 为什么这样说呢,下面解释\n",
+ "\n",
+ "下面,令 j = 2 * id - i ,也就是说 j 是 i 关于 id 的对称点。\n",
+ "\n",
+ " - 当 mx - i > P[j] 的时候,以 S[j] 为中心的回文子串包含在以 S[id] 为中心的回文子串中,由于 i 和 j 对称,以 S[i] 为中心的回文子串必然包含在以 S[id] 为中心的回文子串中,所以必有 P[i] = P[j] ; \n",
+ "\n",
+ " - 当 P[j] >= mx - i 的时候,以 S[j] 为中心的回文子串不一定完全包含于以 S[id] 为中心的回文子串中,但是基于对称性可知,下图中两个绿框所包围的部分是相同的,也就是说以 S[i] 为中心的回文子串,其向右至少会扩张到 mx 的位置,也就是说 P[i] >= mx - i。至于 mx 之后的部分是否对称,再具体匹配。 所以 P[i] >= Min(P[2 * id - i], mx - i),因为以 j 为中心的绘回文子串的左边界可能会比 mx 关于 id 的对称点要大,此时只能证明 P[i]=P[2 * id - i]\n",
+ "\n",
+ " - 此外,对于 mx <= i 的情况,因为无法对 P[i] 做更多的假设,只能让 P[i] = 1,然后再去匹配。\n",
+ "\n",
+ "在下面的程序中我的 P 数组保存的是,以当前字符为回文子串中心时,该回文子串的长度(不包含当前字符自身)\n",
+ "\n",
+ "简单地用一个小例子来解释:原字符串为 'qacbcaw' ,一眼就可以看出来最大回文子串是 'acbca' , 下面是我做的图,累 shi 了!\n",
+ "\n",
+ "\n",
+ "\n",
+ "所以最终代码中的 max_i 就是字符 'b' 所对应的 index8 ,start 的值就是 (max_i - P[max_i] - 1) / 2 = 1 ,最终输出结果为 s[1:6] ,即‘acbca’"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "cbc\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution3(object):\n",
+ " def longestPalindrome(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: str\n",
+ " \"\"\"\n",
+ " def preProcess(s):\n",
+ " if not s:\n",
+ " return ['^', '&']\n",
+ " T = ['^']\n",
+ " for i in s:\n",
+ " T += ['#', i]\n",
+ " T += ['#', '$']\n",
+ " return T\n",
+ " T = preProcess(s)\n",
+ " P = [0] * len(T)\n",
+ " id, mx = 0, 0\n",
+ " for i in range(1, len(T)-1):\n",
+ " j = 2 * id - i\n",
+ " if mx > i:\n",
+ " P[i] = min(P[j], mx-i)\n",
+ " else:\n",
+ " P[i]= 0\n",
+ " while T[i+P[i]+1] == T[i-P[i]-1]:\n",
+ " P[i] += 1\n",
+ " if i + P[i] > mx:\n",
+ " id, mx = i, i + P[i]\n",
+ " max_i = P.index(max(P)) #保存的是当前最大回文子串中心位置的index\n",
+ " start = int((max_i - P[max_i] - 1) / 2)\n",
+ " res = s[start: start + P[max_i]]\n",
+ " return res\n",
+ " \n",
+ "s_3 = Solution3()\n",
+ "nums = \"acbcd\"\n",
+ "print(s_3.longestPalindrome(nums)) "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "run code的时候结果会跟expected不一样,但是该input确实2个结果都可以,所以放心地submit吧 还可以转到647题去看一看,也可以用这个算法解"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/007._Reverse_Integer.ipynb b/docs/Leetcode_Solutions/ipynb/007._Reverse_Integer.ipynb
new file mode 100644
index 000000000..d471473d6
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/007._Reverse_Integer.ipynb
@@ -0,0 +1,168 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 7. Reverse Integer 反转整数\n",
+ "\n",
+ "### 难度:Easy\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/reverse-integer/description/\n",
+ " - 英文:https://leetcode.com/problems/Reverse-Integer\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定一个 32 位有符号整数,将整数中的数字进行反转。\n",
+ "\n",
+ "示例 1:\n",
+ "输入: 123\n",
+ "输出: 321\n",
+ "\n",
+ "示例 2:\n",
+ "输入: -123\n",
+ "输出: -321\n",
+ "\n",
+ "示例 3:\n",
+ "输入: 120\n",
+ "输出: 21\n",
+ "\n",
+ "注意:\n",
+ "假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。根据这个假设,如果反转后的整数溢出,则返回 0。\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ " - x > 0, flag = 1; x < 0, flag = -1\n",
+ " - 将 x 转成字符串 s = str(abs(x)),然后再反转字符串 s1 = s[::-1]\n",
+ " - 字符串再转为整数:x1 = int(s1) * flag\n",
+ " - 判断是否溢出,将数据返回"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "21\n",
+ "-654\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def reverse(self, x):\n",
+ " \"\"\"\n",
+ " :type x: int\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " # 如果是负数,我们需要注意转化为绝对值\n",
+ " flag = 1\n",
+ " x_1 = 0\n",
+ " if x < 0:\n",
+ " flag = -1\n",
+ " x = int(str(abs(x))[::-1])\n",
+ " x_1 = x * flag\n",
+ " else:\n",
+ " flag = 1\n",
+ " x = int(str(x)[::-1])\n",
+ " x_1 = x * flag\n",
+ " if x_1 > 2**31-1 or x_1 < -2**31:\n",
+ " return 0\n",
+ " else:\n",
+ " return x_1\n",
+ "\n",
+ "s = Solution()\n",
+ "x = 120\n",
+ "y = -456\n",
+ "print(s.reverse(x))\n",
+ "print(s.reverse(y))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ " - 按照低位摘除,在按高位加上去其实就可以了\n",
+ " - 利用循环,每次将最后一位取出来(求余),然后将原来的数据除以 10 ,取整,这样就可以每次都得到个位数\n",
+ " - 按照取第二步,反向操作,取出来一个最后的个位数,然后乘以 10 ,再加上每一次得到的个位数,就实现了反转\n",
+ " - 注意一个点,python 中对一个数求余时,结果与 求余 的符号相同,比如 5 % 2 = 1, 5 % (-2) = -1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "21\n",
+ "-654\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def reverse(self, x):\n",
+ " \"\"\"\n",
+ " :type x: int\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " num = 0\n",
+ " flag = 1\n",
+ " if x > 0:\n",
+ " flag = 1\n",
+ " else:\n",
+ " flag = -1\n",
+ " while x != 0:\n",
+ " num = num * 10 + x % (10 * flag)\n",
+ " x = int(x / 10)\n",
+ " if num > 2**31-1 or num < -2**31:\n",
+ " return 0\n",
+ " else:\n",
+ " return num\n",
+ "s = Solution()\n",
+ "x = 120\n",
+ "y = -456\n",
+ "print(s.reverse(x))\n",
+ "print(s.reverse(y))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/009._Palindrome_Number.ipynb b/docs/Leetcode_Solutions/ipynb/009._Palindrome_Number.ipynb
new file mode 100644
index 000000000..4a643d0f0
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/009._Palindrome_Number.ipynb
@@ -0,0 +1,165 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 9.Palindrome Number 回文数\n",
+ "\n",
+ "### 难度:Easy\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/palindrome-number/description\n",
+ " - 英文:https://leetcode.com/problems/palindrome-number\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。\n",
+ "\n",
+ "示例 1:\n",
+ "\n",
+ "输入: 121\n",
+ "输出: true\n",
+ "\n",
+ "示例 2:\n",
+ "\n",
+ "输入: -121\n",
+ "输出: false\n",
+ "解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。\n",
+ "\n",
+ "示例 3:\n",
+ "\n",
+ "输入: 10\n",
+ "输出: false\n",
+ "解释: 从右向左读, 为 01 。因此它不是一个回文数。\n",
+ "\n",
+ "进阶:\n",
+ "\n",
+ "你能不将整数转为字符串来解决这个问题吗?\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ " - 首先负数肯定不是回文数\n",
+ " - 通过字符串进行反转,再转化为数字,对比数字是否相等就行"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "False\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def isPalindrome(self, x):\n",
+ " \"\"\"\n",
+ " :type x: int\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " # 如果是负数,肯定不是回文数,排除掉\n",
+ " if x < 0:\n",
+ " return False\n",
+ " # 我们将 数字转为 str ,然后反转,再转化为 int,比较,相等的话,就是回文数,不相等的话,就不是回文数\n",
+ " elif x != int(str(x)[::-1]):\n",
+ " return False\n",
+ " else:\n",
+ " return True\n",
+ " \n",
+ "s = Solution()\n",
+ "x = 2345\n",
+ "y = 121\n",
+ "print(s.isPalindrome(x))\n",
+ "print(s.isPalindrome(y))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ " - 负数一定不是回文数\n",
+ " - 如果一个数字是正数,并且能被我 0 整除那它肯定也不是 palidrome\n",
+ " - 这样我们就降低了复杂度"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "False\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def isPalindrome(self, x):\n",
+ " \"\"\"\n",
+ " :type x: int\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " # 处理特殊情况:\n",
+ " # 1、负数一定不是回文数\n",
+ " # 2、如果数字的最后一位是 0, 为了让数字是回文数字,则第一位数字也应该是 0,只有 0 满足这种情况\n",
+ " if x < 0 or (x % 10 == 0 and x is not 0):\n",
+ " return False\n",
+ " revertNumber = 0\n",
+ " while x > revertNumber:\n",
+ " revertNumber = revertNumber * 10 + x % 10\n",
+ " x /= 10\n",
+ " # 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。\n",
+ " # 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,\n",
+ " # 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。\n",
+ " return x == revertNumber or x == revertNumber/10\n",
+ "\n",
+ "s = Solution()\n",
+ "x = 2345\n",
+ "y = 121\n",
+ "print(s.isPalindrome(x))\n",
+ "print(s.isPalindrome(y))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/010._regular_expression_matching.ipynb b/docs/Leetcode_Solutions/ipynb/010._regular_expression_matching.ipynb
new file mode 100644
index 000000000..8a6af2b6e
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/010._regular_expression_matching.ipynb
@@ -0,0 +1,311 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 010. Regular Expression Matching 正则表达式匹配\n",
+ "\n",
+ "### 难度:Hard\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/two-sum/description\n",
+ " - 英文:https://leetcode.com/problems/two-sum\n",
+ "\n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定一个字符串 (s) 和一个字符模式 (p)。实现支持 '.' 和 '*' 的正则表达式匹配。\n",
+ "\n",
+ "'.' 匹配任意单个字符。\n",
+ "'*' 匹配零个或多个前面的元素。\n",
+ "匹配应该覆盖整个字符串 (s) ,而不是部分字符串。\n",
+ "\n",
+ "说明:\n",
+ " - s 可能为空,且只包含从 a-z 的小写字母。\n",
+ " - p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。\n",
+ "\n",
+ "示例 1:\n",
+ "输入:\n",
+ "s = \"aa\"\n",
+ "p = \"a\"\n",
+ "输出: false\n",
+ "解释: \"a\" 无法匹配 \"aa\" 整个字符串。\n",
+ "\n",
+ "示例 2:\n",
+ "输入:\n",
+ "s = \"aa\"\n",
+ "p = \"a*\"\n",
+ "输出: true\n",
+ "解释: '*' 代表可匹配零个或多个前面的元素, 即可以匹配 'a' 。因此, 重复 'a' 一次, 字符串可变为 \"aa\"。\n",
+ "\n",
+ "示例 3:\n",
+ "输入:\n",
+ "s = \"ab\"\n",
+ "p = \".*\"\n",
+ "输出: true\n",
+ "解释: \".*\" 表示可匹配零个或多个('*')任意字符('.')。\n",
+ "\n",
+ "示例 4:\n",
+ "输入:\n",
+ "s = \"aab\"\n",
+ "p = \"c*a*b\"\n",
+ "输出: true\n",
+ "解释: 'c' 可以不被重复, 'a' 可以被重复一次。因此可以匹配字符串 \"aab\"。\n",
+ "\n",
+ "示例 5:\n",
+ "输入:\n",
+ "s = \"mississippi\"\n",
+ "p = \"mis*is*p*.\"\n",
+ "输出: false\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ "暴力法。Lisanaaa 大佬想出来的,不得不赞一个,哈哈哈。之前想暴力法,把脑袋想爆掉了都没想全各种情况。那么,看看他是怎么解的吧。\n",
+ "\n",
+ "\".\" 很容易处理。难点就在 \"*\" 身上, \"*\" 是不会单独的,它一定是和前面的 一个字母或者 \".\" 配成一对 出现的。看成一对后是这样子的 \"X*\" ,它的性质是:要么匹配 0 个,要么匹配连续的 \"X\" 。所以尝试暴力法的时候一个 trick 是从后往前匹配。\n",
+ "\n",
+ "暴力解法也是可以 AC 的。\n",
+ "\n",
+ "下面这样来分情况:\n",
+ "\n",
+ " - 如果 s[i] = p[j] 或者 p[j]= . : 往前匹配一位\n",
+ " - 如果 p[j] = ' * ' , 检查一下,如果这个时候 p[j-1] = . 或者 p[j-1] = s[i] ,那么就往前匹配,如果这样能匹配过,就 return True , 否者我们忽略 'X* ' ,这里注意里面的递推关系。\n",
+ " - 再处理一下边界情况:\n",
+ " - s 已经匹配完了, 如果此时 p 还有,那么如果剩下的是 X* 这种可以过,所以需要检查一下\n",
+ " - p 匹配完毕,如果 s 还有没有匹配的话,那么就 return False"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def isMatch(self, s, p):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :type p: str\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " def helper(s, i, p, j):\n",
+ " if j == -1:\n",
+ " return i == -1\n",
+ " if i == -1:\n",
+ " if p[j] != '*':\n",
+ " return False\n",
+ " return helper(s, i, p, j-2)\n",
+ " if p[j] == '*':\n",
+ " if p[j-1] == '.' or p[j-1] == s[i]:\n",
+ " if helper(s, i-1, p, j):\n",
+ " return True\n",
+ " return helper(s, i, p, j-2)\n",
+ " if p[j] == '.' or p[j] == s[i]:\n",
+ " return helper(s, i-1, p, j-1)\n",
+ " return False\n",
+ "\n",
+ " return helper(s, len(s)-1, p, len(p)-1)\n",
+ " \n",
+ "s = 'abc'\n",
+ "p = 'a*abc'\n",
+ "ss = Solution()\n",
+ "print(ss.isMatch(s, p))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ "动态规划 解法。\n",
+ "\n",
+ "dp 优化,感觉和 edit distance 很像。DP优化待代码化,感觉学DP的一个重点除了递归学好以外,另一点是一定要会画表格。\n",
+ "\n",
+ "画一个表格来看一下状况\n",
+ "\n",
+ "```\n",
+ "\t\t\tc\t*\ta\t*\tb\n",
+ "\t\t0\t1\t2\t3\t4\t5\n",
+ "\t0\t1\t0\t1\t0\t1\t0\t\t\n",
+ "a\t1\t0\t0\t0\t1\t1\t0\t\t\t\t\t\n",
+ "a\t2\t0\t0\t0\t0\t1\t0\t\t\t\t\t\n",
+ "b\t3\t0\t0\t0\t0\t0\t1\t\t\t\n",
+ "```\n",
+ "\n",
+ "这里有几个取巧/容易出问题的敌方,这里画的表用的是1-based string。一上来,做的事包括:\n",
+ "\n",
+ " - 初始化,空字符匹配:dp[0][0] =1\n",
+ " - 第一行, c * 可以匹配空字符, c * a * 可以匹配空字符, p[j-1] != s[i] ,匹配空字符\n",
+ " - 然后进入第二行再来看,实际上我们可以看到,如果没有碰到 * 匹配还是很朴素的,但是碰到 * :\n",
+ " - 1 这个匹配可以从左侧传来,dp[i][j] = dp[i][j-1] ,that is 匹配 1 个\n",
+ " - 1 也可以有上方传来,这种情况是 p[j-1] = s[i] ,匹配多个 dp[i][j] = dp[i-1][j]\n",
+ " - 1 这个匹配也可以从间隔一个的左侧传来,that is 也可以有个性的匹配 0 个,如同匹配空字符一样 dp[i][j] = dp[i][j-2] ,但是注意匹配 0 个实际上有两种状况,如果 p[j-1]!=s[i] ,强制匹配 0 个,即使 p[j-1] == s[i] ,我们也可以傲娇的用它来匹配 0 个。\n",
+ " \n",
+ "再代码化一点:\n",
+ "\n",
+ " - s[i] == p[j] 或者 p[j] == '.' : dp[i][j] = dp[i-1][j-1]\n",
+ " - p[j] == '*' : 然后分几种情况\n",
+ " - p[j-1] != s[i] : dp[i][j] = dp[i][j-2] 匹配 0 个的状况\n",
+ " - p[j-1] == s[i] or p[i-1] == '.':\n",
+ " - dp[i][j] = dp[i-1][j] 匹配多个 s[i]\n",
+ " - dp[i][j] = dp[i][j-2] 匹配 0 个\n",
+ "\n",
+ "AC 代码,注意一下,因为上表为了表达方便,用的是 1-based string 系统,实际写代码的时候我们心里还是清楚这个 string 还是从 0 开始的,不过也可以尝试往前面添东西来方便。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def isMatch(self, s, p):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :type p: str\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " m, n = len(s), len(p)\n",
+ " dp = [ [0 for i in range(n+1)] for j in range(m+1)]\n",
+ "\n",
+ " dp[0][0] = 1\n",
+ "\n",
+ " # init the first line\n",
+ " for i in range(2,n+1):\n",
+ " if p[i-1] == '*':\n",
+ " dp[0][i] = dp[0][i-2]\n",
+ "\n",
+ " for i in range(1,m+1):\n",
+ " for j in range(1,n+1):\n",
+ " if p[j-1] == '*':\n",
+ " if p[j-2] != s[i-1] and p[j-2] != '.':\n",
+ " dp[i][j] = dp[i][j-2]\n",
+ " elif p[j-2] == s[i-1] or p[j-2] == '.':\n",
+ " dp[i][j] = dp[i-1][j] or dp[i][j-2]\n",
+ "\n",
+ " elif s[i-1] == p[j-1] or p[j-1] == '.':\n",
+ " dp[i][j] = dp[i-1][j-1]\n",
+ "\n",
+ " return dp[m][n] == 1 \n",
+ " \n",
+ "s = 'abc'\n",
+ "p = 'a*abc'\n",
+ "ss = Solution()\n",
+ "print(ss.isMatch(s, p))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "我做的动态规划和上面大体思路是类似的。\n",
+ "\n",
+ "直接说动态转移方程组了,我们首先定义一些变量方便解释,被匹配串为s,模式串为p。状态转移数组 dp[i][j]表示利用 p 的前 j 个字符匹配 s 的前 i 个字符的匹配结果(成功为 true,失败为 false)。\n",
+ "\n",
+ " - **s[i] == p[j] || p[j] == '.'** ,那么 dp[i][j] = dp[i-1][j-1] ,也就是既然 s 串的第 i 个字符能和 p 串的第 j 个字符匹配,那么如果 s 串的前 i-1 个字符和 p 串的前 j-1 个字符能匹配则 s 串的前 i 个和 p 串的前 j 个则能匹配,反之不能。\n",
+ " - **p[j] == '*'** :分情况讨论。\n",
+ " - **s[i] != p[j-1] && p[j-1] != '.'** ,那么 dp[i][j] = dp[i][j-2] ,也就是 * 号前面的那个字符在匹配的过程当中一个都不使用。\n",
+ " - **else,那么dp[i][j] = dp[i-1][j] || dp[i][j-1] || dp[i][j-2]**,也就是说要么使用 '*' 号进行匹配( dp[i-1][j] ),要么只使用 '*' 号前面的那个字符匹配,不使用 '*' 匹配( dp[i][j-1] ),要么 '*' 号前面的那个字符在匹配的过程当中一个都不使用( dp[i][j-2] ),只要有一个是 true 则能够匹配。\n",
+ " \n",
+ "最后考虑一下边界条件。一开始 i 是从 1 到 len(s) ,j 是 1 到 len(p) 。首先一来就能想到 dp[0][0] 是true,其他都是 false。但是这个边界条件是不够的。比如 isMatch(\"aab\", \"c * a * b\") ,dp[1][3] 应该是从 dp[0][2] 转移过来的,所以需要更多的边界条件,也就是一开始的 * 是能匹配空字符串的。所以我把 i 改到了从 0 开始,并且第二条也添加了 i=0,dp[i][j] = dp[i][j-2] 。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def isMatch(self, s, p):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :type p: str\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " dp = []\n",
+ " dp = [[False for i in range(len(p)+1)] for j in range(len(s)+1)]\n",
+ " dp[0][0] = True\n",
+ "# print(dp)\n",
+ " for i in range(len(s)+1):\n",
+ " for j in range(1, len(p)+1):\n",
+ " if i > 0 and (s[i-1] == p[j-1] or p[j-1] == '.'):\n",
+ "# print(\"1111111\",i)\n",
+ "# print(\"2222222\",j)\n",
+ " dp[i][j] = dp[i-1][j-1]\n",
+ "# print(\"3333333\",dp[i-1][j-1])\n",
+ " if p[j-1] == '*':\n",
+ " if i == 0 or (s[i-1] != p[j-2] and p[j-2] != '.'):\n",
+ "# print(\"4444444\",i)\n",
+ "# print(\"5555555\",j)\n",
+ " dp[i][j] = dp[i][j-2]\n",
+ "# print(\"6666666\",dp[i][j-2])\n",
+ " else:\n",
+ " dp[i][j] = dp[i-1][j] or dp[i][j-1] or dp[i][j-2]\n",
+ "# print(\"7777777\",i)\n",
+ "# print(\"8888888\",j)\n",
+ "# print(dp) \n",
+ " return dp[len(s)][len(p)]\n",
+ " \n",
+ "s = 'aa'\n",
+ "p = 'a*'\n",
+ "ss = Solution()\n",
+ "print(ss.isMatch(s, p))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/013._Roman_to_Integer.ipynb b/docs/Leetcode_Solutions/ipynb/013._Roman_to_Integer.ipynb
new file mode 100644
index 000000000..8ac444f28
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/013._Roman_to_Integer.ipynb
@@ -0,0 +1,197 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 013.Roman to Integer\n",
+ "\n",
+ "### 难度:Easy\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 英文:https://leetcode.com/problems/roman-to-integer/\n",
+ " - 中文:https://leetcode-cn.com/problems/roman-to-integer/description/\n",
+ "\n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "罗马数字包含以下七种字符:I, V, X, L,C,D 和 M。\n",
+ "\n",
+ "字符 数值\n",
+ "I 1\n",
+ "V 5\n",
+ "X 10\n",
+ "L 50\n",
+ "C 100\n",
+ "D 500\n",
+ "M 1000\n",
+ "\n",
+ "例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。\n",
+ "\n",
+ "通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:\n",
+ "\n",
+ "I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。\n",
+ "X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 \n",
+ "C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。\n",
+ "\n",
+ "给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。\n",
+ "\n",
+ "示例 1:\n",
+ "输入: \"III\"\n",
+ "输出: 3\n",
+ "\n",
+ "示例 2:\n",
+ "输入: \"IV\"\n",
+ "输出: 4\n",
+ "\n",
+ "示例 3:\n",
+ "输入: \"IX\"\n",
+ "输出: 9\n",
+ "\n",
+ "示例 4:\n",
+ "输入: \"LVIII\"\n",
+ "输出: 58\n",
+ "解释: C = 100, L = 50, XXX = 30, III = 3.\n",
+ "\n",
+ "示例 5:\n",
+ "输入: \"MCMXCIV\"\n",
+ "输出: 1994\n",
+ "解释: M = 1000, CM = 900, XC = 90, IV = 4.\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ " - 从前向后依次扫描,用一个临时变量记录当前数字。\n",
+ " - 如果没有出现题目中出现的特殊情况,那我们就可以一直一个一个加下去,这样就能得到正确结果。\n",
+ " - 特殊情况出现的时候,后一位数字比前一位数字大,而正常情况正好是相反的(后一位数字一定比前一位小),后一位减去前一位即可得到这两位得到的数值,但是要注意一点,我们在这之前已经将前一位进行加和了一次,所以这时候,我们要减去 2 次前一位数字。\n",
+ " - 其他地方没有太难的部分,以下是 AC 代码。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1994\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def romanToInt(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " lookup = {\n",
+ " 'M': 1000,\n",
+ " 'D': 500,\n",
+ " 'C': 100,\n",
+ " 'L': 50,\n",
+ " 'X': 10,\n",
+ " 'V': 5,\n",
+ " 'I': 1\n",
+ " }\n",
+ " res = 0\n",
+ " for i in range(len(s)):\n",
+ " if i > 0 and lookup[s[i]] > lookup[s[i-1]]:\n",
+ " res = res + lookup[s[i]] - 2 * lookup[s[i-1]]\n",
+ " else:\n",
+ " res += lookup[s[i]]\n",
+ " return res\n",
+ " \n",
+ "s = Solution()\n",
+ "string = \"MCMXCIV\"\n",
+ "print(s.romanToInt(string))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "可以修改一下的地方,我们可以将从字典中取数的逻辑封装到一个函数中,这样也比较优雅。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1994\n"
+ ]
+ }
+ ],
+ "source": [
+ "def getNum(x):\n",
+ " return {\"I\":1,\n",
+ " \"V\":5,\n",
+ " \"X\":10,\n",
+ " \"L\":50,\n",
+ " \"C\":100,\n",
+ " \"D\":500,\n",
+ " \"M\":1000}.get(x)\n",
+ "\n",
+ "class Solution: \n",
+ " def romanToInt(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " Num = {\n",
+ " 'M': 1000,\n",
+ " 'D': 500,\n",
+ " 'C': 100,\n",
+ " 'L': 50,\n",
+ " 'X': 10,\n",
+ " 'V': 5,\n",
+ " 'I': 1\n",
+ " }\n",
+ " result = 0\n",
+ " for i in range(len(s)):\n",
+ " if i > 0 and Num[s[i]] > Num[s[i-1]]:\n",
+ " result = result + Num[s[i]] - 2 * Num[s[i-1]]\n",
+ " else:\n",
+ " result += Num[s[i]]\n",
+ " return result\n",
+ " \n",
+ "s = Solution()\n",
+ "string = \"MCMXCIV\"\n",
+ "print(s.romanToInt(string))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/020._valid_parentheses.ipynb b/docs/Leetcode_Solutions/ipynb/020._valid_parentheses.ipynb
new file mode 100644
index 000000000..f665733dc
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/020._valid_parentheses.ipynb
@@ -0,0 +1,302 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 20. Valid Parentheses 有效的括号\n",
+ "\n",
+ "### 难度:Easy\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/valid-parentheses/description\n",
+ " - 英文:https://leetcode.com/problems/valid-parentheses\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。\n",
+ "\n",
+ "有效字符串需满足:\n",
+ "\n",
+ "1、左括号必须用相同类型的右括号闭合。\n",
+ "2、左括号必须以正确的顺序闭合。\n",
+ "\n",
+ "注意空字符串可被认为是有效字符串。\n",
+ "\n",
+ "示例1:\n",
+ "输入: \"()\"\n",
+ "输出: true\n",
+ "\n",
+ "示例2:\n",
+ "输入: \"()[]{}\"\n",
+ "输出: true\n",
+ "\n",
+ "示例3:\n",
+ "输入: \"(]\"\n",
+ "输出: false\n",
+ "\n",
+ "示例4:\n",
+ "输入: \"([)]\"\n",
+ "输出: false\n",
+ "\n",
+ "示例5:\n",
+ "输入: \"{[]}\"\n",
+ "输出: true\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ "我们只需要匹配三种情况: \"(\" -> \")\", \"[\" -> \"]\", \"{\" -> \"}\".\n",
+ "\n",
+ "但是这里最重要的思想是 栈 。一遇到左括号就入栈,右括号出栈,这样来寻找对应。\n",
+ "\n",
+ "需要检查几件事:\n",
+ "\n",
+ " - 出现右括号时 stack 里是否还有符号(无论左右)\n",
+ " - 出 stack 时是否对应\n",
+ " - 最终 stack 是否为空"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "False\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def isValid(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " LEFT = {'(', '[', '{'} # 左括号\n",
+ " RIGHT = {')', ']', '}'} # 右括号\n",
+ " stack = [] # 创建一个栈\n",
+ " for brackets in s: # 迭代传过来的所有字符串\n",
+ " if brackets in LEFT: # 如果当前字符在左括号内\n",
+ " stack.append(brackets) # 把当前左括号入栈\n",
+ " elif brackets in RIGHT: # 如果是右括号\n",
+ " if not stack or not 1 <= ord(brackets) - ord(stack[-1]) <= 2:\n",
+ " # 如果当前栈为空,()]\n",
+ " # 如果右括号减去左括号的值不是小于等于2大于等于1\n",
+ " return False # 返回False\n",
+ " stack.pop() # 删除左括号\n",
+ " return not stack # 如果栈内没有值则返回True,否则返回False\n",
+ " \n",
+ "s = Solution()\n",
+ "print(s.isValid(\"([[])[]{}\"))\n",
+ "print(s.isValid(\"([])[]{}\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "与 思路 1 相同,但是更加容易理解的版本:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "False\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def isValid(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " leftP = '([{'\n",
+ " rightP = ')]}'\n",
+ " stack = []\n",
+ " for char in s:\n",
+ " if char in leftP:\n",
+ " stack.append(char)\n",
+ " if char in rightP:\n",
+ " if not stack:\n",
+ " return False\n",
+ " tmp = stack.pop()\n",
+ " if char == ')' and tmp != '(':\n",
+ " return False\n",
+ " if char == ']' and tmp != '[':\n",
+ " return False \n",
+ " if char == '}' and tmp != '{':\n",
+ " return False\n",
+ " return stack == []\n",
+ " \n",
+ "s = Solution()\n",
+ "print(s.isValid(\"([[])[]{}\"))\n",
+ "print(s.isValid(\"([])[]{}\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ " - 扩展性和可理解性更强\n",
+ " - 使用字典类型来存储对应关系"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "False\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def isValid(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " if len(s) % 2 == 1:\n",
+ " return False\n",
+ "\n",
+ " index = 0\n",
+ " stack = [i for i in s]\n",
+ " map1 = {\"(\": \")\", \"[\": \"]\", \"{\": \"}\"}\n",
+ "\n",
+ " while len(stack) > 0:\n",
+ " # 判断索引是否超过边界\n",
+ " if index >= len(stack)-1:\n",
+ " return False\n",
+ " \n",
+ " b = stack[index]\n",
+ " e = stack[index+1]\n",
+ "\n",
+ " if b not in map1.keys():\n",
+ " return False\n",
+ " elif e in map1.keys():\n",
+ " index += 1\n",
+ " elif map1[b] == e:\n",
+ " stack.pop(index+1)\n",
+ " stack.pop(index)\n",
+ " index = 0 if index-1<0 else index-1\n",
+ " else:\n",
+ " return False\n",
+ "\n",
+ " return stack == []\n",
+ " \n",
+ "s = Solution()\n",
+ "print(s.isValid(\"([[])[]{}\"))\n",
+ "print(s.isValid(\"([])[]{}\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 3\n",
+ "\n",
+ " - 括号匹配,我们可以换用另一种方式\n",
+ " - 首先,不管它是否符合第一个符号是左括号的要求,我们先把它放到list 中,作为栈,然后一个一个遍历,符合配对顺序就弹出,最终只需要判断是否栈为空就可以了"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "False\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "l_d = {\n",
+ " '{': -3,\n",
+ " '(': -2,\n",
+ " '[': -1,\n",
+ " ']': 1,\n",
+ " ')': 2,\n",
+ " '}': 3,\n",
+ "}\n",
+ " \n",
+ "class Solution:\n",
+ " def isValid(self, s):\n",
+ " l_s = []\n",
+ " for c_r in s:\n",
+ " if len(l_s) == 0:\n",
+ " l_s.append(c_r)\n",
+ " continue\n",
+ "\n",
+ " c_l = l_s[-1]\n",
+ "\n",
+ " if l_d[c_l] + l_d[c_r] == 0 and l_d[c_l] < 0:\n",
+ " l_s.pop()\n",
+ " else:\n",
+ " l_s.append(c_r)\n",
+ "\n",
+ " if len(l_s) == 0:\n",
+ " return True\n",
+ " else:\n",
+ " return False\n",
+ " \n",
+ "s = Solution()\n",
+ "print(s.isValid(\"([[])[]{}\"))\n",
+ "print(s.isValid(\"([])[]{}\"))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/032._longest_valid_parentheses.ipynb b/docs/Leetcode_Solutions/ipynb/032._longest_valid_parentheses.ipynb
new file mode 100644
index 000000000..56e88640c
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/032._longest_valid_parentheses.ipynb
@@ -0,0 +1,180 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "collapsed": true
+ },
+ "source": [
+ "# 032.longest-valid-parentheses 最长有效括号\n",
+ "\n",
+ "### 难度:Easy\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/longest-valid-parentheses/description\n",
+ " - 英文:https://leetcode.com/problems/longest-valid-parentheses\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。\n",
+ "\n",
+ "示例 1:\n",
+ "输入: \"(()\"\n",
+ "输出: 2\n",
+ "解释: 最长有效括号子串为 \"()\"\n",
+ "\n",
+ "示例 2:\n",
+ "输入: \")()())\"\n",
+ "输出: 4\n",
+ "解释: 最长有效括号子串为 \"()()\"\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ "**注:** 千万注意,这个题上来就坑了一下,题目没有说清楚一种情况,比如 (()) ,这种情况,有效括号子串是 4 ,而不是错误的。\n",
+ "\n",
+ "实际上,在看到这个最长有效括号的题目的时候,我就想到了之前我们做的一个题目。LeetCode 20 题,它的解法是如何使用堆栈判断括号序列是否可以成功配对。我们仍然可以将堆栈的思想延续到这里。\n",
+ "\n",
+ "每当遇到一个左括号或者是无法成对的右括号,就将它压入栈中,可以成对的括号则从栈中 pop 出。这样栈中剩下的就是无法成对的括号的下标。这时我们可以判断这些下标间的距离来获得最大的成对括号长度。 **在这里,我们需要先遍历一遍字符串,再遍历一下非空的堆栈。一定要注意,这里我们遍历的非空的栈存储的是没有匹配上的括号下标,匹配上的我们都已经做了pop 处理。**"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6\n",
+ "4\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def longestValidParentheses(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " # 创建一个 stack ,用来做 栈 的操作\n",
+ " stack = []\n",
+ " # 第一次遍历 s 字符串\n",
+ " for i in range(len(s)):\n",
+ " # 如果当前循环到的 字符 是 右括号,那就要 检查一下栈内是否有与之匹配的 左括号\n",
+ " if s[i] == ')':\n",
+ " # stack 如果不为空,并且 stack 的栈顶元素存储的下标在 s 字符串中是 左括号\n",
+ " if stack and s[stack[-1]] == '(':\n",
+ " # 将栈顶元素 pop 出来,与当前的 右括号 配对\n",
+ " stack.pop()\n",
+ " # 直接 continue\n",
+ " continue\n",
+ " stack.append(i)\n",
+ " # 设置 最大长度\n",
+ " max_length = 0\n",
+ " # 设置为当前字符串 s 的长度\n",
+ " next_index = len(s)\n",
+ " # 遍历 非空的栈\n",
+ " while stack:\n",
+ " # 当前的栈顶存储的 s 的下标\n",
+ " cur_index = stack.pop()\n",
+ " # 计算下一个有效的最长括号长度\n",
+ " cur_length = next_index - cur_index - 1\n",
+ " # 将之与 之前存储的 max_length 比较,留下较大值\n",
+ " max_length = max(cur_length, max_length)\n",
+ " # 下一个的有效括号的右索引赋值,接着进入下一次循环,一直到 stack 为空\n",
+ " next_index = cur_index\n",
+ " # 遍历到最后的时候,肯定 next_index 即是有效符号的长度,与 max_length 做比较,取较大值\n",
+ " return max(next_index, max_length)\n",
+ " \n",
+ " \n",
+ "s = Solution()\n",
+ "print(s.longestValidParentheses(\"()(())\"))\n",
+ "print(s.longestValidParentheses(\"()()(()\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ "使用动态规划(dynamic programming)思想来做这个问题。\n",
+ "\n",
+ "下面是 片刻 大佬想出来的,我感觉思想真的超棒。参考链接:http://www.cnblogs.com/George1994/p/7531574.html\n",
+ "\n",
+ "1. 用一个 dp 数组来存放以每个 index 为结尾的最长有效括号子串长度,例如:dp[3] = 2 代表以 index 为 3 结尾的最长有效括号子串长度为 2\n",
+ "2. 很明显,dp[i] 和 dp[i-1] 之间是有关系的。\n",
+ " - 当 dp[i] 所在的索引 i 在字符串 s 中代表的字符是 \"(\" 时,也就是 s[i] == '(' ,很显然,此时的 dp[i] 与之前的一个关系是 dp[i] = dp[i-1] + 0,也就是不用处理。\n",
+ " - 当 dp[i] 所在的索引 i 在字符串 s 中代表的字符是 \")\" 时,也就是 s[i] == ')' 时,如果在 dp[i-1] 的所表示的最长有效括号子串之前还有一个 '(' 与 s[i] 对应,那么 dp[i] = dp[i-1] + 2,并且还可以继续往前追溯(如果前面还能连接起来的话)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6\n",
+ "4\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def longestValidParentheses(self, s):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " if len(s) == 0:\n",
+ " return 0\n",
+ " dp = [0 for i in range(len(s))]\n",
+ " for i in range(1, len(s)):\n",
+ " if s[i] == ')':\n",
+ " left = i - 1 - dp[i-1]\n",
+ " if left >= 0 and s[left] == '(':\n",
+ " dp[i] = dp[i-1] + 2\n",
+ " if left > 0: # 这个是判断 left 前面是否能与后面继续连起来\n",
+ " dp[i] += dp[left-1]\n",
+ " return max(dp)\n",
+ "\n",
+ "s = Solution()\n",
+ "print(s.longestValidParentheses(\"()(())\"))\n",
+ "print(s.longestValidParentheses(\"()()(()\"))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/053._maximum_subarray.ipynb b/docs/Leetcode_Solutions/ipynb/053._maximum_subarray.ipynb
new file mode 100644
index 000000000..1bbb8ab21
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/053._maximum_subarray.ipynb
@@ -0,0 +1,275 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 53. Maximum Subarray 最大子序和\n",
+ "\n",
+ "### 难度:Medium\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/maximum-subarray/description/\n",
+ " - 英文:https://leetcode.com/problems/maximum-subarray/\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。\n",
+ "\n",
+ "示例:\n",
+ "\n",
+ "输入: [-2,1,-3,4,-1,2,1,-5,4],\n",
+ "输出: 6\n",
+ "解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。\n",
+ "\n",
+ "进阶:\n",
+ "如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ " - 可以用 O(N^2) 循环\n",
+ " - 从i开始,计算i到n,存比较大的sum\n",
+ " - 会超时,不会 AC"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6\n",
+ "1\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def maxSubArray(self, nums):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " # 设置为无穷小\n",
+ " ans = float('-inf')\n",
+ " # 这个循环控制子串的元素个数\n",
+ " for i in range(1, len(nums)):\n",
+ " # 这个循环控制子串从原始串的哪个位置开始计算\n",
+ " for j in range(len(nums)-i):\n",
+ " big = 0\n",
+ " big = sum(nums[j : j+i])\n",
+ " if big > ans:\n",
+ " ans = big\n",
+ " return ans\n",
+ "\n",
+ "s = Solution()\n",
+ "nums_1 = [-2,1,-3,4,-1,2,1,-5,4]\n",
+ "nums_2 = [1, -1]\n",
+ "print(s.maxSubArray(nums_1))\n",
+ "print(s.maxSubArray(nums_2))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ " - 使用动态规划\n",
+ " - ms(i) = max(ms[i-1] + a[i], a[i])\n",
+ " - 我们只需要知道,计算到 i 处的最大值的两种可能,一个是加上 a[i],另一个是从 a[i] 开始重新计算子串。\n",
+ " - 比较 ms[i-1]+a[i] 与 a[i] 的值的大小关系,如果前者小于后者,就说明,前面的子串的最大的和是负数,我们可以抛弃掉,而从 a[i] 处开始起头重新计算子串;如果前者大于后者,说明,前面的子串的最大的和是正数,我们可以加上 a[i] 继续计算。\n",
+ " - 可以 AC"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6\n",
+ "1\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def maxSubArray(self, nums):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " n = len(nums)\n",
+ " maxSum = [nums[0] for i in range(n)]\n",
+ " for i in range(1,n):\n",
+ " \tmaxSum[i] = max(maxSum[i-1] + nums[i], nums[i])\n",
+ " return max(maxSum)\n",
+ " \n",
+ "s = Solution()\n",
+ "nums_1 = [-2,1,-3,4,-1,2,1,-5,4]\n",
+ "nums_2 = [1, -1]\n",
+ "print(s.maxSubArray(nums_1))\n",
+ "print(s.maxSubArray(nums_2))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 3\n",
+ "\n",
+ "Kadane’s Algorithm wikipedia可以查到,然后一般的是负的可以还回0,这里需要稍作修改,参考:\n",
+ "http://algorithms.tutorialhorizon.com/kadanes-algorithm-maximum-subarray-problem/\n",
+ "\n",
+ "```\n",
+ "start:\n",
+ " max_so_far = a[0]\n",
+ " max_ending_here = a[0]\n",
+ "\n",
+ "loop i= 1 to n\n",
+ " (i) max_end_here = Max(arrA[i], max_end_here+a[i]);\n",
+ " (ii) max_so_far = Max(max_so_far,max_end_here);\n",
+ "\n",
+ "return max_so_far\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "AC 代码如下:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "6\n",
+ "1\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def maxSubArray(self, nums):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " n = len(nums)\n",
+ " maxSum , maxEnd = nums[0], nums[0]\n",
+ " \n",
+ " for i in range(1,n):\n",
+ " maxEnd = max(nums[i],maxEnd + nums[i])\n",
+ " maxSum = max(maxEnd,maxSum)\n",
+ " return maxSum\n",
+ " \n",
+ "s = Solution()\n",
+ "nums_1 = [-2,1,-3,4,-1,2,1,-5,4]\n",
+ "nums_2 = [1, -1]\n",
+ "print(s.maxSubArray(nums_1))\n",
+ "print(s.maxSubArray(nums_2))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 4\n",
+ "\n",
+ "参见clrs 第71页,用divide and conquer,有伪码\n",
+ "\n",
+ "最大的 subarray sum 有三个可能,左半段或者右半段,或者跨越左右半段,\n",
+ "\n",
+ "速度比较慢,AC代码,复杂度O(NlogN)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "class Solution(object):\n",
+ " def maxSubArray(self, nums):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " def find_max_crossing_subarray(nums, low, mid, high):\n",
+ " left_sum = float('-inf')\n",
+ " sum = 0\n",
+ " for i in xrange(mid,low-1,-1):\n",
+ " sum = sum + nums[i]\n",
+ " if sum > left_sum:\n",
+ " left_sum = sum\n",
+ "\n",
+ " right_sum = float('-inf')\n",
+ " sum = 0\n",
+ " for j in range(mid+1,high+1):\n",
+ " sum = sum + nums[j]\n",
+ " if sum > right_sum:\n",
+ " right_sum = sum\n",
+ "\n",
+ " return left_sum + right_sum\n",
+ "\n",
+ " def find_max_subarray(nums,low,high):\n",
+ " if low == high: \n",
+ " return nums[low]\n",
+ " else:\n",
+ " mid = (low + high) / 2\n",
+ " left_sum = find_max_subarray(nums, low, mid)\n",
+ " right_sum = find_max_subarray(nums,mid+1,high)\n",
+ " cross_sum = find_max_crossing_subarray(nums,low,mid,high)\n",
+ " # print left_sum, right_sum, cross_sum\n",
+ " # print mid, low, high\n",
+ " return max(left_sum, right_sum, cross_sum)\n",
+ "\n",
+ " return find_max_subarray(nums, 0, len(nums)-1)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/062._unique_paths.ipynb b/docs/Leetcode_Solutions/ipynb/062._unique_paths.ipynb
new file mode 100644
index 000000000..372560e09
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/062._unique_paths.ipynb
@@ -0,0 +1,167 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 062.unique_paths 不同路径\n",
+ "\n",
+ "### 难度:Medium\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/unique-paths/description\n",
+ " - 英文:https://leetcode.com/problems/unique-paths\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。\n",
+ "\n",
+ "机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。\n",
+ "\n",
+ "问总共有多少条不同的路径?\n",
+ "\n",
+ "说明:m 和 n 的值均不超过 100。\n",
+ "\n",
+ "示例 1:\n",
+ "输入: m = 3, n = 2\n",
+ "输出: 3\n",
+ "解释:\n",
+ "从左上角开始,总共有 3 条路径可以到达右下角。\n",
+ "1. 向右 -> 向右 -> 向下\n",
+ "2. 向右 -> 向下 -> 向右\n",
+ "3. 向下 -> 向右 -> 向右\n",
+ "\n",
+ "示例 2:\n",
+ "输入: m = 7, n = 3\n",
+ "输出: 28\n",
+ "\n",
+ "例如,下图是一个3 x 7 的网格。有多少可能的路径?\n",
+ "```\n",
+ "\n",
+ "\n",
+ "\n",
+ "## 解决方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ "数学思路。\n",
+ "\n",
+ "本质上,这道题就是排列组合,一共走 m + n - 步,其中 m - 1 步是向右边走,所以不就是从 m + n - 2 中选择 m-1 个的问题,阶乘问题,so easy !妈妈再也不用担心我的学习!!!这个方法 beats 99.97% 。\n",
+ "\n",
+ "补充一下,math 模块中自带 factorial 函数,只要 import math 之后调用即可。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "28.0\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def uniquePaths(self, m, n):\n",
+ " \"\"\"\n",
+ " :type m: int\n",
+ " :type n: int\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " def factorial(num):\n",
+ " res = 1\n",
+ " for i in range(1, num+1):\n",
+ " res *= i\n",
+ " return res\n",
+ " return factorial(m+n-2)/factorial(n-1)/factorial(m-1)\n",
+ " \n",
+ "s = Solution()\n",
+ "print(s.uniquePaths(7,3))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "collapsed": true
+ },
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ "片刻大佬 想到的这个思想,真的棒!\n",
+ "\n",
+ "| | | |\n",
+ "| - | - | - |\n",
+ "| 1 | 1 | 1 |\n",
+ "| 1 | 2 | 3 |\n",
+ "| 1 | 3 | 6 |\n",
+ "| 1 | 4 | 10 |\n",
+ "| 1 | 5 | 15 |\n",
+ "| 1 | 6 | 21 |\n",
+ "| 1 | 7 | 28 |"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "28\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def uniquePaths(self, m, n):\n",
+ " \"\"\"\n",
+ " :type m: int\n",
+ " :type n: int\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " if m < 1 or n < 1:\n",
+ " return 0\n",
+ " dp = [0] *n\n",
+ " dp[0] = 1 \n",
+ " for i in range(0,m):\n",
+ " for j in range(1,n):\n",
+ " dp[j] += dp[j-1]\n",
+ " return dp[n-1]\n",
+ " \n",
+ "s = Solution()\n",
+ "print(s.uniquePaths(7,3))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/064._minimum_path_sum.ipynb b/docs/Leetcode_Solutions/ipynb/064._minimum_path_sum.ipynb
new file mode 100644
index 000000000..2844c4953
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/064._minimum_path_sum.ipynb
@@ -0,0 +1,160 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 064. Minimum Path Sum 最小路径和\n",
+ "\n",
+ "### 难度:Medium\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/minimum-path-sum/description\n",
+ " - 英文:https://leetcode.com/problems/minimum-path-sum\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。\n",
+ "\n",
+ "说明:每次只能向下或者向右移动一步。\n",
+ "\n",
+ "示例:\n",
+ "\n",
+ "输入:\n",
+ "[\n",
+ " [1,3,1],\n",
+ " [1,5,1],\n",
+ " [4,2,1]\n",
+ "]\n",
+ "输出: 7\n",
+ "解释: 因为路径 1→3→1→1→1 的总和最小。\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ "使用 动态规划 ,我们考虑到,一个位于 [i][j] 位置的格子,到达它的路径只有 2 条:1 条是从上到下到达这个格子([i-1][j] -> [i][j]),另一条是从左到右到达这个格子([i][j-1] -> [i][j])。我们只需要关注这两条路径中,哪条路径的路径和最小就好了。 另外可以参考 072.编辑距离 。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "7\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def minPathSum(self, grid):\n",
+ " \"\"\"\n",
+ " :type grid: List[List[int]]\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " m = len(grid)\n",
+ " n = len(grid[0])\n",
+ " dp = grid.copy()\n",
+ " for i in range(1, n):\n",
+ " dp[0][i] = dp[0][i-1] + grid[0][i]\n",
+ " for i in range(1, m):\n",
+ " dp[i][0] = dp[i-1][0] + grid[i][0]\n",
+ " for i in range(1, m):\n",
+ " for j in range(1, n):\n",
+ " dp[i][j] = min(dp[i][j-1] + grid[i][j], dp[i-1][j] + grid[i][j])\n",
+ " return dp[m-1][n-1]\n",
+ " \n",
+ "s = Solution()\n",
+ "grid = [\n",
+ " [1,3,1],\n",
+ " [1,5,1],\n",
+ " [4,2,1]\n",
+ "]\n",
+ "print(s.minPathSum(grid))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "上面的版本是我最初写成的,后来听大佬们说,尽量减少 for 循环的个数。改成下面的最终版本,已经 AC 。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "7\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def minPathSum(self, grid):\n",
+ " \"\"\"\n",
+ " :type grid: List[List[int]]\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " if not grid or len(grid) == 0:\n",
+ " return 0\n",
+ " row = len(grid)\n",
+ " col = len(grid[0]) if row else 0\n",
+ " dp = [[0 for j in range(col)] for i in range(row)]\n",
+ " for i in range(row):\n",
+ " for j in range(col):\n",
+ " if i > 0 and j > 0:\n",
+ " dp[i][j] = min(dp[i-1][j]+grid[i][j], dp[i][j-1]+grid[i][j])\n",
+ " elif i > 0 and j == 0:\n",
+ " dp[i][j] = sum([grid[k][0] for k in range(i+1)])\n",
+ " elif i == 0 and j > 0:\n",
+ " dp[i][j] = sum([grid[0][k] for k in range(j+1)])\n",
+ " else:\n",
+ " dp[i][j] = grid[0][0]\n",
+ " return dp[-1][-1]\n",
+ " \n",
+ "s = Solution()\n",
+ "grid = [\n",
+ " [1,3,1],\n",
+ " [1,5,1],\n",
+ " [4,2,1]\n",
+ "]\n",
+ "print(s.minPathSum(grid))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/072._edit_distance.ipynb b/docs/Leetcode_Solutions/ipynb/072._edit_distance.ipynb
new file mode 100644
index 000000000..9c8a9d1c8
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/072._edit_distance.ipynb
@@ -0,0 +1,211 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 072. Edit Distance 编辑距离\n",
+ "\n",
+ "### 难度:Hard\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/edit-distance/description/\n",
+ " - 英文:https://leetcode.com/problems/edit-distance/\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。\n",
+ "\n",
+ "你可以对一个单词进行如下三种操作:\n",
+ "\n",
+ "插入一个字符\n",
+ "删除一个字符\n",
+ "替换一个字符\n",
+ "\n",
+ "示例 1:\n",
+ "输入: word1 = \"horse\", word2 = \"ros\"\n",
+ "输出: 3\n",
+ "解释: \n",
+ "horse -> rorse (将 'h' 替换为 'r')\n",
+ "rorse -> rose (删除 'r')\n",
+ "rose -> ros (删除 'e')\n",
+ "\n",
+ "示例 2:\n",
+ "输入: word1 = \"intention\", word2 = \"execution\"\n",
+ "输出: 5\n",
+ "解释: \n",
+ "intention -> inention (删除 't')\n",
+ "inention -> enention (将 'i' 替换为 'e')\n",
+ "enention -> exention (将 'n' 替换为 'x')\n",
+ "exention -> exection (将 'n' 替换为 'c')\n",
+ "exection -> execution (插入 'u')\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "这个题目是动态规划的典型例题,在 wikipedia 中是有相应页面介绍的。\n",
+ "\n",
+ " - https://en.wikipedia.org/wiki/Edit_distance#Common_algorithm\n",
+ " - https://en.wikipedia.org/wiki/Levenshtein_distance\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ " - 使用动态规划\n",
+ "\n",
+ "下面我们说说,这个题的思路。具体来描述一下。\n",
+ "\n",
+ "要始终明确一点, dp[i][j] 的含义是使得 word1 的前 i 字符子串与 word2 的前 j 字符子串相等所需要的操作数,这也是为什么我们需要在初始化 dp 矩阵时需要行列数均加上 1 。\n",
+ "\n",
+ "我们创建一个 dp[][] 二维数组,表示从 word1 的前 i 个字符(下标为:0~ i-1)到 word2 的前 j 个字符(下标为:0~j-1)的编辑过程中,需要的最少步数,那么:\n",
+ "\n",
+ "如果 $word1[i] = word2[j]$ 则 $dp[i][j] = dp[i-1][j-1]$\n",
+ "\n",
+ "如果 $word1[i] != word2[j]$ 则 $dp[i][j] = min ( dp[i-1][j] , dp[i][j-1], dp[i-1][j-1] ) + 1$\n",
+ "\n",
+ "下面就是我们对上述动态规划过程的解释:\n",
+ "\n",
+ "第一个条件比较容易理解,就是说 word1 的下标为 i 的字符 和 word2 的下标为 j 的字符相同,那么这个位置的字符我们不需要进行操作,所以我们只需要关注 word1 和 word2 去除掉相应位置的字符之后的子串的结果即可。\n",
+ "\n",
+ "我们下面对第二个条件的三种情况进行重点讲解:\n",
+ "\n",
+ "假设 word1 的前 i+1 (下标为 0~i)的子串为 \"abcde\"\n",
+ "假设 word2 的前 j+1 (下标为 0~j)的子串为 \"abcddgf\"\n",
+ "现在 word1[i] != word2[j],也就是 'e' != 'f'\n",
+ "\n",
+ "那么我们接下来应该怎么做呢?\n",
+ "\n",
+ "我们会发现,我们做的三种解释实际上就是把我们题中写到的三种操作模拟在最后一步实现。每种操作都是额外加一的操作。\n",
+ "\n",
+ "简单说,就是这样:\n",
+ " - 1.delete:dp[i-1][j] + 1 —— 保留了从 word1[0~i-1] 转变到 word2[0~j] 的最优操作次数,因为我们的 word1 的 0~i-1 已经能够转变到 word2 了,所以我们就直接把 word1 中的最后一个字符删除掉就行了。所以就需要额外进行一个 删除 操作。\n",
+ " - 2.insert:dp[i][j-1] + 1 —— 保留了从 word1[0~i] 转变到 word2[0~j-1] 的最优操作次数,因为我们的 word1 的 0~i 只能转变到 word2 的倒数第二位,所以我们就直接在 word1 的末尾添加一个与 word2 的最后一个字符相同的字符就可以了。所以就需要额外进行一个 插入 操作。\n",
+ " - 3.replace:dp[i-1][j-1] + 1 —— 保留了从 word1[0~i-1] 转变到 word2[0~j-1] 的最优操作次数,因为我们的 word1 的 0~i-1 只能转变到 word2 的倒数第二位,而 word1 的最后一位与 word2 的最后一位是不同的,所以现在的情况只需要额外的一个 替换 操作即可。\n",
+ "\n",
+ "\n",
+ "无论我们选取上面 3 中操作的哪种操作,我们选其中最小的值就可以了。\n",
+ "\n",
+ "参考链接:http://www.cnblogs.com/pandora/archive/2009/12/20/levenshtein_distance.html\n",
+ "\n",
+ "下面我们看一下代码:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "3\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def minDistance(self, word1, word2):\n",
+ " \"\"\"\n",
+ " :type word1: str\n",
+ " :type word2: str\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " # 初始化一个 len(word1)+1 * len(word2)+1 的矩阵\n",
+ " matrix = [[i+j for j in range(len(word2) + 1)] for i in range(len(word1) + 1)]\n",
+ " # 辅助理解,matrix 矩阵的样子\n",
+ " # print(matrix)\n",
+ " for i in range(1, len(word1)+1):\n",
+ " for j in range(1,len(word2)+1):\n",
+ " if word1[i-1] == word2[j-1]:\n",
+ " d = 0\n",
+ " else:\n",
+ " d = 1\n",
+ " matrix[i][j] = min(matrix[i-1][j]+1, matrix[i][j-1]+1, matrix[i-1][j-1]+d)\n",
+ "\n",
+ " return matrix[len(word1)][len(word2)]\n",
+ " \n",
+ "s = Solution()\n",
+ "word1 = 'horse'\n",
+ "word2 = 'ros'\n",
+ "print(s.minDistance(word1, word2))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "上面代码的 matrix 矩阵生成,可能会让大家产生理解误差,我在这个地方的理解也是通过大佬问,我才知道具体是怎么回事的。\n",
+ "\n",
+ "下面我们把它打印一下。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "matrix([[0, 1, 2, 3],\n",
+ " [1, 2, 3, 4],\n",
+ " [2, 3, 4, 5],\n",
+ " [3, 4, 5, 6],\n",
+ " [4, 5, 6, 7],\n",
+ " [5, 6, 7, 8]])"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "juzhen = [[i+j for j in range(len(word2) + 1)] for i in range(len(word1) + 1)]\n",
+ "juzhen = np.mat(juzhen)\n",
+ "juzhen"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "以 numpy 的样子打印出来,看这样子比较清晰。各行各列对应比较整齐。\n",
+ "\n",
+ "我要说明的是:\n",
+ "\n",
+ " - 这个 matrix 的 第 1 行(下标为0的行)的 [0, 1, 2, 3] 这个维度的意思,对应的是 dp[i][j] 。也就是说,word1 取前 i 个字符,然后编辑成 word2 时所需要转换的最少步数。因为这里 i = 0,也就是 word1 取 0 个字符,而 j 我们取 0 - 3 个字符的时候,我们从 word1 变换到 word2 的时候所需要经过的最小步数。本质上,就是在 **空的** word1 上进行对应插入 word2 对应的字符就可以变换到 word2 。word2 取几个字符,我们的最小变换次数就是几。也就对应这个维度上的数字。\n",
+ "\n",
+ " - 另一个维度上,matrix 的第 1 列(下标为 0 的列),对应的是 [0, 1, 2, 3, 4, 5] 也是对应的 dp[i][j]。只不过我们这里调换了顺序,i 现在不为 0 了,而是 j 为 0 。也就是 word1 取 0~ i 个字符的时候,变换到 word2 的最小步骤数。实际上 word2 是空的,也就是说,我们 word1 有几个字符,我们对应删除几个字符就可以得到 word2 。这就对应着我们的这个列维度上的数字。\n",
+ " \n",
+ " - 其他维度,i 和 j 都不为 0 的部分,我们的初始化的数字是没有意义的。我们在迭代过程中会全部都更改一遍。"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/139._word_break.ipynb b/docs/Leetcode_Solutions/ipynb/139._word_break.ipynb
new file mode 100644
index 000000000..ffbac6d1d
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/139._word_break.ipynb
@@ -0,0 +1,222 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Word Break 单词拆分\n",
+ "\n",
+ "### 难度:Medium\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/word-break/description/\n",
+ " - 英文:https://leetcode.com/problems/word-break/\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。\n",
+ "\n",
+ "说明:\n",
+ "\n",
+ "1、拆分时可以重复使用字典中的单词。\n",
+ "2、你可以假设字典中没有重复的单词。\n",
+ "\n",
+ "示例 1:\n",
+ "输入: s = \"leetcode\", wordDict = [\"leet\", \"code\"]\n",
+ "输出: true\n",
+ "解释: 返回 true 因为 \"leetcode\" 可以被拆分成 \"leet code\"。\n",
+ "\n",
+ "示例 2:\n",
+ "输入: s = \"applepenapple\", wordDict = [\"apple\", \"pen\"]\n",
+ "输出: true\n",
+ "解释: 返回 true 因为 \"applepenapple\" 可以被拆分成 \"apple pen apple\"。\n",
+ " 注意你可以重复使用字典中的单词。\n",
+ "\n",
+ "示例 3:\n",
+ "输入: s = \"catsandog\", wordDict = [\"cats\", \"dog\", \"sand\", \"and\", \"cat\"]\n",
+ "输出: false\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ " - 字符串 S ,它的长度为 N ,如果 S 能够被 字典集合(dict)中的单词拼接而成,那么所要满足的条件为:\n",
+ " - F(0, N) = F(0, i) && F(i, j) && F(j, N)\n",
+ " - 这样,如果我们想知道某个子串是否可由 Dict 中的几个单词拼接而成就可以用这样的方式得到结果(满足条件为True,不满足条件为 False)存入到一个 boolean 数组的对应位置上,这样,最后 boolean 数组的最后一位就是 F(0, N) 的值,为 True 表示这个字符串 S 可以由 Dict 中的单词拼接,否则是不行的。\n",
+ " - AC 代码如下"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution:\n",
+ " def wordBreak(self, s, wordDict):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :type wordDict: List[str]\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " # 参数校验\n",
+ " if s is None or len(s) < 1 or wordDict is None or len(wordDict) < 1:\n",
+ " return False\n",
+ " # 标记是否匹配,match[i] 表示 [0, i-1] 都匹配\n",
+ " length = len(s)\n",
+ " match = [False for i in range(length + 1)]\n",
+ " match[0] = True\n",
+ " \n",
+ " for i in range(1, length +1):\n",
+ " for j in range(i):\n",
+ " if match[j] and s[j:i] in wordDict:\n",
+ " match[i] = True\n",
+ " break\n",
+ " return match[length]\n",
+ "\n",
+ "\n",
+ "sss = Solution()\n",
+ "s = \"leetcode\"\n",
+ "wordDict = [\"leet\", \"code\"]\n",
+ "print(sss.wordBreak(s, wordDict))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "collapsed": true
+ },
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ " - **ok[i] 表示 s[:i] 是不是存在于我们的字典中。**\n",
+ " - 原理类似于我们上面的 思路 1"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def wordBreak(self, s, wordDict):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :type wordDict: List[str]\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " ok = [True]\n",
+ " for i in range(1, len(s)+1):\n",
+ " ok += [any(ok[j] and s[j:i] in wordDict for j in range(i))]\n",
+ " return ok[-1]\n",
+ " \n",
+ "sss = Solution()\n",
+ "s = \"leetcode\"\n",
+ "wordDict = [\"leet\", \"code\"]\n",
+ "print(sss.wordBreak(s, wordDict))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "但是往list里面加数据的方法有快有慢,下面是对比:\n",
+ "\n",
+ "```python\n",
+ ">>> from timeit import timeit\n",
+ ">>> timeit('x.append(1)', 'x = []', number=10000000)\n",
+ "1.9880003412529277\n",
+ ">>> timeit('x += 1,', 'x = []', number=10000000)\n",
+ "1.2676891852971721\n",
+ ">>> timeit('x += [1]', 'x = []', number=10000000)\n",
+ "3.361207239950204\n",
+ "```\n",
+ "\n",
+ "因此我们可以将代码直接换成下面的格式:\n",
+ "\n",
+ "```python\n",
+ "ok += any(ok[j] and s[j:i] in wordDict for j in range(i)) # 会报错\n",
+ "```\n",
+ "\n",
+ "但是这样会报错,TypeError: 'bool' object is not iterable,因此bool类型数据不能这样加,别的可以(list类型本身当然要注意哈)\n",
+ "\n",
+ "因此在这个例子中我们这样:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def wordBreak(self, s, wordDict):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :type wordDict: List[str]\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " ok = [True]\n",
+ " for i in range(1, len(s)+1):\n",
+ " ok += any(ok[j] and s[j:i] in wordDict for j in range(i)),\n",
+ " return ok[-1]\n",
+ " \n",
+ "sss = Solution()\n",
+ "s = \"leetcode\"\n",
+ "wordDict = [\"leet\", \"code\"]\n",
+ "print(sss.wordBreak(s, wordDict))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/179._Largest_Number.ipynb b/docs/Leetcode_Solutions/ipynb/179._Largest_Number.ipynb
new file mode 100644
index 000000000..9ce763484
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/179._Largest_Number.ipynb
@@ -0,0 +1,186 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 179.Largest Number 最大数\n",
+ "\n",
+ "### 难度:Medium\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/largest-number/description/\n",
+ " - 英文:https://leetcode.com/problems/largest-number/\n",
+ "\n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。\n",
+ "\n",
+ "示例 1:\n",
+ "输入: [10,2]\n",
+ "输出: 210\n",
+ "\n",
+ "示例 2:\n",
+ "输入: [3,30,34,5,9]\n",
+ "输出: 9534330\n",
+ "说明: 输出结果可能非常大,所以你需要返回一个字符串而不是整数。\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ " - 先排序,后合并,若最后为空字符串,则返回 '0'\n",
+ "\n",
+ "其中的排序思想是字符串的经典比较:\n",
+ "\n",
+ "【注】:在 Python3 中没有了 cmp,只有 key,我们可以使用 functools.cmp_to_key 去修饰一下。\n",
+ "\n",
+ "cmp 函数比较两个对象,如 (x, y),若 x > y,则返回 1,if x == y,return 0,如果 x < y,则返回 -1 。\n",
+ "\n",
+ "下面这个是 python2 的解决方案,可以 AC ,但是在我们的 Python3 中就会报如下错误"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "'cmp' is an invalid keyword argument for this function",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 11\u001b[0m \u001b[0ms\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mSolution\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 12\u001b[0m \u001b[0mnums\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 13\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ms\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlargestNumber\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnums\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
+ "\u001b[1;32m\u001b[0m in \u001b[0;36mlargestNumber\u001b[1;34m(self, nums)\u001b[0m\n\u001b[0;32m 6\u001b[0m \"\"\"\n\u001b[0;32m 7\u001b[0m \u001b[0mnums\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mstr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnum\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mnum\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mnums\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 8\u001b[1;33m \u001b[0mnums\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msort\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcmp\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mcmp\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m+\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m+\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 9\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;34m''\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnum\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlstrip\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'0'\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mif\u001b[0m \u001b[1;34m''\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnum\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlstrip\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'0'\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32melse\u001b[0m \u001b[1;34m'0'\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
+ "\u001b[1;31mTypeError\u001b[0m: 'cmp' is an invalid keyword argument for this function"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def largestNumber(self, nums):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :rtype: str\n",
+ " \"\"\"\n",
+ " nums = [str(num) for num in nums]\n",
+ " nums.sort(cmp=lambda x, y: cmp(y+x, x+y))\n",
+ " return ''.join(num).lstrip('0') if ''.join(num).lstrip('0') else '0'\n",
+ " \n",
+ "s = Solution()\n",
+ "nums = [10, 2]\n",
+ "print(s.largestNumber(nums))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "或者更简单的写法,可以写成下面这样(Python2适用,python3 会报错):"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "'cmp' is an invalid keyword argument for this function",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 11\u001b[0m \u001b[0ms\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mSolution\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 12\u001b[0m \u001b[0mnums\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 13\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ms\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlargestNumber\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnums\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
+ "\u001b[1;32m\u001b[0m in \u001b[0;36mlargestNumber\u001b[1;34m(self, nums)\u001b[0m\n\u001b[0;32m 6\u001b[0m \"\"\"\n\u001b[0;32m 7\u001b[0m \u001b[0mnums\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mstr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnum\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mnum\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mnums\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 8\u001b[1;33m \u001b[0mnums\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msort\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcmp\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;32mlambda\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0my\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mcmp\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m+\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mx\u001b[0m\u001b[1;33m+\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 9\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[1;34m''\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnum\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlstrip\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'0'\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mor\u001b[0m \u001b[1;34m'0'\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
+ "\u001b[1;31mTypeError\u001b[0m: 'cmp' is an invalid keyword argument for this function"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def largestNumber(self, nums):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :rtype: str\n",
+ " \"\"\"\n",
+ " nums = [str(num) for num in nums]\n",
+ " nums.sort(cmp=lambda x, y: cmp(y+x, x+y))\n",
+ " return ''.join(num).lstrip('0') or '0'\n",
+ " \n",
+ "s = Solution()\n",
+ "nums = [10, 2]\n",
+ "print(s.largestNumber(nums))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "下面这个解法就是我们在 Python3 中的解法"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "210\n"
+ ]
+ }
+ ],
+ "source": [
+ "from functools import cmp_to_key\n",
+ "\n",
+ "# 比较函数\n",
+ "def compare(a, b):\n",
+ " return int(b + a) - int(a + b)\n",
+ "\n",
+ "class Solution(object):\n",
+ " def largestNumber(self, nums):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :rtype: str\n",
+ " \"\"\"\n",
+ " nums = sorted([str(x) for x in nums], key=cmp_to_key(compare))\n",
+ " return str(int(''.join(nums)))\n",
+ " \n",
+ "s = Solution()\n",
+ "nums = [10, 2]\n",
+ "print(s.largestNumber(nums))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/242._valid_anagram.ipynb b/docs/Leetcode_Solutions/ipynb/242._valid_anagram.ipynb
new file mode 100644
index 000000000..26218f62d
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/242._valid_anagram.ipynb
@@ -0,0 +1,189 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 242. Valid Anagram 有效的字母异位词\n",
+ "\n",
+ "### 难度:Easy\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/valid-anagram/description/\n",
+ " - 英文:https://leetcode.com/problems/valid-anagram/\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词。\n",
+ "\n",
+ "示例 1:\n",
+ "输入: s = \"anagram\", t = \"nagaram\"\n",
+ "输出: true\n",
+ "\n",
+ "示例 2:\n",
+ "输入: s = \"rat\", t = \"car\"\n",
+ "输出: false\n",
+ "\n",
+ "说明:\n",
+ "你可以假设字符串只包含小写字母。\n",
+ "\n",
+ "进阶:\n",
+ "如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ " - 一行瞬秒!\n",
+ " - 适用 collections.Counter() 方法"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "import collections\n",
+ "\n",
+ "class Solution(object):\n",
+ " def isAnagram(self, s, t):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :type t: str\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " return collections.Counter(s) == collections.Counter(t)\n",
+ " \n",
+ "s = \"anagram\"\n",
+ "t = \"nagaram\"\n",
+ "ss = Solution()\n",
+ "print(ss.isAnagram(s, t))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "collapsed": true
+ },
+ "source": [
+ "> 思路 2\n",
+ "\n",
+ " - 同样是一行瞬秒!\n",
+ " - 适用 sorted() 函数"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def isAnagram(self, s, t):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :type t: str\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " return sorted(s) == sorted(t)\n",
+ "s = \"anagram\"\n",
+ "t = \"nagaram\"\n",
+ "ss = Solution()\n",
+ "print(ss.isAnagram(s, t))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 3\n",
+ "\n",
+ " - 用字数统计,因为只可能是 26 个字母"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def isAnagram(self, s, t):\n",
+ " \"\"\"\n",
+ " :type s: str\n",
+ " :type t: str\n",
+ " :rtype: bool\n",
+ " \"\"\"\n",
+ " if len(s) != len(t):\n",
+ " return False\n",
+ " \n",
+ " charCnt = [0] * 26\n",
+ " \n",
+ " for i in range(len(s)):\n",
+ " charCnt[ord(s[i]) - 97] += 1\n",
+ " charCnt[ord(t[i]) - 97] -= 1 \n",
+ " \n",
+ " for cnt in charCnt:\n",
+ " if cnt != 0:\n",
+ " return False\n",
+ " return True\n",
+ " \n",
+ "s = \"anagram\"\n",
+ "t = \"nagaram\"\n",
+ "ss = Solution()\n",
+ "print(ss.isAnagram(s, t))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/Leetcode_Solutions/ipynb/287._Find_the_Duplicate_Number.ipynb b/docs/Leetcode_Solutions/ipynb/287._Find_the_Duplicate_Number.ipynb
new file mode 100644
index 000000000..62e7895dc
--- /dev/null
+++ b/docs/Leetcode_Solutions/ipynb/287._Find_the_Duplicate_Number.ipynb
@@ -0,0 +1,244 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# 287.Find the Duplicate Number 找到重复的数\n",
+ "\n",
+ "### 难度:Medium\n",
+ "\n",
+ "## 刷题内容\n",
+ "\n",
+ "> 原题链接\n",
+ "\n",
+ " - 中文:https://leetcode-cn.com/problems/find-the-duplicate-number/description/\n",
+ " - 英文:https://leetcode.com/problems/find-the-duplicate-number\n",
+ " \n",
+ "> 内容描述\n",
+ "\n",
+ "```\n",
+ "给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。\n",
+ "\n",
+ "示例 1:\n",
+ "输入: [1,3,4,2,2]\n",
+ "输出: 2\n",
+ "\n",
+ "示例 2:\n",
+ "输入: [3,1,3,4,2]\n",
+ "输出: 3\n",
+ "\n",
+ "说明:\n",
+ "不能更改原数组(假设数组是只读的)。\n",
+ "只能使用额外的 O(1) 的空间。\n",
+ "时间复杂度小于 O(n2) 。\n",
+ "数组中只有一个重复的数字,但它可能不止重复出现一次。\n",
+ "```\n",
+ "\n",
+ "## 解题方案\n",
+ "\n",
+ "> 思路 1\n",
+ "\n",
+ "实际上,我们在阅读完题目的时候,直观感觉,题目不是很难。但是,在我们看到下面的说明,也就是对我们题目的限制条件的时候,会猛然发现,题目的难度瞬间提升了好多倍。\n",
+ "\n",
+ "下面我列出咱们需要注意的点:\n",
+ " - 包含 n+1 个整数的数组\n",
+ " - 数组中的数字都在 1 到 n 之间(包括 1 和 n ,但是可以不连续,比如 [1,4,4,3,4])\n",
+ " - 重复的数字,可以重复很多次,并不限于重复 1 次,2次,3次..\n",
+ " - 不能更改原数组(这条是最要命的,原本我的想法是,我们可以排序完成之后,再进行二分查找法,碍于这个规定,无法进行)\n",
+ " - 只能用额外的 O(1) 的空间。(O(1) 空间的意思是不会因数组的长度改变而改变,对应本题就是不管我们的数组多长,我们能用的额外控制只能是 m 这个m 是一个确定的数,不会随着 n 的改变而改变。)\n",
+ " - 时间的复杂度小于 $O(n^2)$\n",
+ " \n",
+ "注意的点差不多就是上面所说的了。\n",
+ "\n",
+ "```\n",
+ "这个思路我们使用 二分查找(binary search)+ 鸽笼原理(Pigeonhole Principle)\n",
+ "参考维基百科关于鸽笼原理的词条链接:https://en.wikipedia.org/wiki/Pigeonhole_principle\n",
+ "\n",
+ "\"不允许修改数组\" 与 \"常数空间复杂度\" 这两个限制条件意味着:禁止排序,并且不能使用 Map 等数据结构\n",
+ "\n",
+ "小于 O(n^2) 的运行时间复杂度可以联想到使用二分将其中的一个 n 化简为 log n\n",
+ "可以参考 LeetCode Discuss:https://leetcode.com/discuss/60830/python-solution-explanation-without-changing-input-array\n",
+ "\n",
+ "二分枚举答案范围,使用鸽笼原理进行检验\n",
+ "\n",
+ "根据鸽笼原理,给定 n+1 个范围为 [1, n]的整数,其中一定存在数字出现至少两次。\n",
+ "假设枚举的数字为 n / 2 :\n",
+ "遍历数组,若数组中不大于 n / 2 的数字个数超过 n / 2 ,则可以确定 [1, n/2] 范围内一定有解,否则可以确定解落在 (n/2, n]范围内。\n",
+ "```\n",
+ "\n",
+ "也可以这样分析一下:\n",
+ "```\n",
+ "\n",
+ "如果n 是5,那么就会有1 2 3 4 5 一共5个数字的可能,而array size 是6,那么其中一个数字肯定会至少出现两次。\n",
+ "\n",
+ "如果没有重复的数字,小于等于1的数字 出现的次数 等于 1;\n",
+ "\n",
+ "小于等于2的数字 出现的次数 等于 2;\n",
+ "\n",
+ "... 同理3;4;5。\n",
+ "\n",
+ "如果有重复的数字,如果重复的是1,那么 小于等于1的数字 出现的次数 肯定大于1;\n",
+ "\n",
+ "基于这个理论,我们可以在1 2 3 4 5 选出一个 mid, 遍历array来count 小于等于mid 的数字个数 小于等于 它自己mid 还是 大于 mid?\n",
+ "\n",
+ "如果count 小于等于mid, 说明 1 到 mid 这些数字 没有重复项, 重复项在 右半边 mid 到n, 所以缩小到右半边继续搜索;\n",
+ "\n",
+ "如果count 大于mid, 说明 1 到 mid 这些数字中 有重复项,缩小到 左半边继续搜索。\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "3\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def findDuplicate(self, nums):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " low, high = 1, len(nums) - 1\n",
+ " while low <= high:\n",
+ " mid = (low + high) >> 1\n",
+ " cnt = sum(x <= mid for x in nums)\n",
+ " if cnt > mid:\n",
+ " high = mid - 1\n",
+ " else:\n",
+ " low = mid + 1\n",
+ " return low\n",
+ " \n",
+ "s = Solution()\n",
+ "nums = [1,2,3,3]\n",
+ "print(s.findDuplicate(nums))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "思路 1 的解法是时间复杂度为 $O(nlogn)$ 的解法,思路 2 则是时间复杂度为 $O(n)$ ,但是相对来说,是投机取巧了些。\n",
+ "> 思路 2\n",
+ "\n",
+ "一次遍历统计,另一次遍历输出即可。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "3\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def findDuplicate(self, nums):\n",
+ " \"\"\"\n",
+ " :type nums: List[int]\n",
+ " :rtype: int\n",
+ " \"\"\"\n",
+ " dic = dict()\n",
+ " for n in nums:\n",
+ " dic[n] = dic.get(n, 0) + 1\n",
+ " if dic[n] >= 2:\n",
+ " return n\n",
+ "\n",
+ "s = Solution()\n",
+ "nums = [1,2,3,3]\n",
+ "print(s.findDuplicate(nums))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "> 思路 3 \n",
+ "\n",
+ "思路 3 则是更加完整的 $O(n)$ 的解法,现在我还没有完全搞懂,我先写在下面吧,大佬们可以提前学习了解。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "3\n"
+ ]
+ }
+ ],
+ "source": [
+ "class Solution(object):\n",
+ " def findDuplicate(self, nums):\n",
+ " # The \"tortoise and hare\" step. We start at the end of the array and try\n",
+ " # to find an intersection point in the cycle.\n",
+ " slow = 0\n",
+ " fast = 0\n",
+ " \n",
+ " # Keep advancing 'slow' by one step and 'fast' by two steps until they\n",
+ " # meet inside the loop.\n",
+ " while True:\n",
+ " slow = nums[slow]\n",
+ " fast = nums[nums[fast]]\n",
+ " \n",
+ " if slow == fast:\n",
+ " break\n",
+ " \n",
+ " # Start up another pointer from the end of the array and march it forward\n",
+ " # until it hits the pointer inside the array.\n",
+ " finder = 0\n",
+ " while True:\n",
+ " slow = nums[slow]\n",
+ " finder = nums[finder]\n",
+ " \n",
+ " # If the two hit, the intersection index is the duplicate element.\n",
+ " if slow == finder:\n",
+ " return slow\n",
+ " \n",
+ "s = Solution()\n",
+ "nums = [1,2,3,3]\n",
+ "print(s.findDuplicate(nums))"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/docs/jianzhioffer/java/03_01_DuplicationInArray.md b/docs/jianzhioffer/java/03_01_DuplicationInArray.md
deleted file mode 100644
index e8094f1de..000000000
--- a/docs/jianzhioffer/java/03_01_DuplicationInArray.md
+++ /dev/null
@@ -1,72 +0,0 @@
-## 找出数组中重复的数字
-
-### 题目描述
-在一个长度为 `n` 的数组里的所有数字都在 `0` 到 `n-1` 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为 `7` 的数组 `{2, 3, 1, 0, 2, 5, 3}`,那么对应的输出是重复的数字 `2` 或者 `3`。
-
-
-### 解法
-#### 解法一
-排序后,顺序扫描,判断是否有重复,时间复杂度为 `O(n²)`。
-
-#### 解法二
-利用哈希表,遍历数组,如果哈希表中没有该元素,则存入哈希表中,否则返回重复的元素。时间复杂度为 `O(n)`,空间复杂度为 `O(n)`。
-
-#### 解法三
-长度为 `n`,元素的数值范围也为 `n`,如果没有重复元素,那么数组每个下标对应的值与下标相等。
-
-从头到尾遍历数组,当扫描到下标 `i` 的数字 `nums[i]`:
-- 如果等于 `i`,继续向下扫描;
-- 如果不等于 `i`,拿它与第 `nums[i]` 个数进行比较,如果相等,说明有重复值,返回 `nums[i]`。如果不相等,就把第 `i` 个数 和第 `nums[i]` 个数交换。重复这个比较交换的过程。
-
-此算法时间复杂度为 `O(n)`,因为每个元素最多只要两次交换,就能确定位置。空间复杂度为 `O(1)`。
-
-```java
-
-/**
- * @author bingo
- * @since 2018/10/27
- */
-
-public class Solution {
- /**
- * 查找数组中的重复元素
- * @param numbers 数组
- * @param length 数组长度
- * @param duplication duplication[0]存储重复元素
- * @return boolean
- */
- public boolean duplicate(int[] numbers, int length, int[] duplication) {
- if (numbers == null || length < 1) {
- return false;
- }
- for (int e : numbers) {
- if (e >= length) {
- return false;
- }
- }
-
- for (int i = 0; i < length; ++i) {
- while (numbers[i] != i) {
- if (numbers[i] == numbers[numbers[i]]) {
- duplication[0] = numbers[i];
- return true;
- }
- swap(numbers, i, numbers[i]);
- }
- }
-
- return false;
- }
-
- private void swap(int[] numbers, int i, int j) {
- int t = numbers[i];
- numbers[i] = numbers[j];
- numbers[j] = t;
- }
-}
-```
-
-### 测试用例
-1. 长度为 n 的数组中包含一个或多个重复的数字;
-2. 数组中不包含重复的数字;
-3. 无效测试输入用例(输入空指针;长度为 n 的数组中包含 0~n-1 之外的数字)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/03_02_DuplicationInArrayNoEdit.md b/docs/jianzhioffer/java/03_02_DuplicationInArrayNoEdit.md
deleted file mode 100644
index 5fdac9cdc..000000000
--- a/docs/jianzhioffer/java/03_02_DuplicationInArrayNoEdit.md
+++ /dev/null
@@ -1,86 +0,0 @@
-## 不修改数组找出重复的数字
-
-### 题目描述
-在一个长度为 `n+1` 的数组里的所有数字都在 `1` 到 `n` 的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。例如,如果输入长度为 `8` 的数组 `{2, 3, 5, 4, 3, 2, 6, 7}`,那么对应的输出是重复的数字 `2` 或者 `3`。
-
-
-### 解法
-#### 解法一
-创建长度为 `n+1` 的辅助数组,把原数组的元素复制到辅助数组中。如果原数组被复制的数是 `m`,则放到辅助数组第 `m` 个位置。这样很容易找出重复元素。空间复杂度为 `O(n)`。
-
-#### 解法二
-数组元素的取值范围是 `[1, n]`,对该范围对半划分,分成 `[1, middle]`, `[middle+1, n]`。计算数组中有多少个(count)元素落在 `[1, middle]` 区间内,如果 count 大于 middle-1+1,那么说明这个范围内有重复元素,否则在另一个范围内。继续对这个范围对半划分,继续统计区间内元素数量。
-
-时间复杂度 `O(n * log n)`,空间复杂度 `O(1)`。
-
-注意,此方法无法找出所有重复的元素。
-
-```java
-/**
- * @author bingo
- * @since 2018/10/27
- */
-
-public class Solution {
- /**
- * 不修改数组查找重复的元素,没有则返回-1
- * @param numbers 数组
- * @return 重复的元素
- */
- public int getDuplication(int[] numbers) {
- if (numbers == null || numbers.length < 1) {
- return -1;
- }
-
- int start = 1;
- int end = numbers.length - 1;
- while (end >= start) {
- int middle = start + ((end - start) >> 1);
-
- // 调用 log n 次
- int count = countRange(numbers, start, middle);
- if (start == end) {
- if (count > 1) {
- return start;
- }
- break;
- } else {
- // 无法找出所有重复的数
- if (count > (middle - start) + 1) {
- end = middle;
- } else {
- start = middle + 1;
- }
- }
- }
- return -1;
- }
-
-
- /**
- * 计算整个数组中有多少个数的取值在[start, end] 之间
- * 时间复杂度 O(n)
- * @param numbers 数组
- * @param start 左边界
- * @param end 右边界
- * @return 数量
- */
- private int countRange(int[] numbers, int start, int end) {
- if (numbers == null) {
- return 0;
- }
- int count = 0;
- for(int e : numbers) {
- if (e >= start && e <= end) {
- ++count;
- }
- }
- return count;
- }
-}
-```
-
-### 测试用例
-1. 长度为 n 的数组中包含一个或多个重复的数字;
-2. 数组中不包含重复的数字;
-3. 无效测试输入用例(输入空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/04_FindInPartiallySortedMatrix.md b/docs/jianzhioffer/java/04_FindInPartiallySortedMatrix.md
deleted file mode 100644
index 70ab58be7..000000000
--- a/docs/jianzhioffer/java/04_FindInPartiallySortedMatrix.md
+++ /dev/null
@@ -1,57 +0,0 @@
-## 二维数组中的查找
-
-### 题目描述
-在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
-
-
-### 解法
-从二维数组的右上方开始查找:
-- 若元素值等于 `target`,返回 `true`;
-- 若元素值大于 `target`,砍掉这一列,即 `--j`;
-- 若元素值小于 `target`,砍掉这一行,即 `++i`。
-
-也可以从二维数组的左下方开始查找,以下代码使用左下方作为查找的起点。
-
-注意,不能选择左上方或者右下方的数字,因为这样无法缩小查找的范围。
-
-```java
-/**
- * @author bingo
- * @since 2018/10/27
- */
-
-public class Solution {
- /**
- * 二维数组中的查找
- * @param target 目标值
- * @param array 二维数组
- * @return boolean
- */
- public boolean find(int target, int[][] array) {
- if (array == null) {
- return false;
- }
- int rows = array.length;
- int columns = array[0].length;
-
- int i = rows - 1;
- int j = 0;
- while (i >= 0 && j < columns) {
- if (array[i][j] == target) {
- return true;
- }
- if (array[i][j] < target) {
- ++j;
- } else {
- --i;
- }
- }
- return false;
- }
-}
-```
-
-### 测试用例
-1. 二维数组中包含查找的数字(查找的数字是数组中的最大值和最小值;查找的数字介于数组中的最大值和最小值之间);
-2. 二维数组中没有查找的数字(查找的数字大于/小于数组中的最大值;查找的数字在数组的最大值和最小值之间但数组中没有这个数字);
-3. 特殊输入测试(输入空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/05_ReplaceSpaces.md b/docs/jianzhioffer/java/05_ReplaceSpaces.md
deleted file mode 100644
index eb3e00d3b..000000000
--- a/docs/jianzhioffer/java/05_ReplaceSpaces.md
+++ /dev/null
@@ -1,98 +0,0 @@
-## 替换空格
-
-### 题目描述
-请实现一个函数,将一个字符串中的每个空格替换成 `%20`。例如,当字符串为 `We Are Happy`,则经过替换之后的字符串为 `We%20Are%20Happy`。
-
-
-### 解法
-#### 解法一
-创建 `StringBuilder`,遍历原字符串,遇到非空格,直接 append 到 `StringBuilder` 中,遇到空格则将 `%20` append 到 `StringBuilder` 中。
-```java
-/**
- * @author bingo
- * @since 2018/10/27
- */
-
-public class Solution {
- /**
- * 将字符串中的所有空格替换为%20
- * @param str 字符串
- * @return 替换后的字符串
- */
- public String replaceSpace(StringBuffer str) {
- if (str == null || str.length() == 0) {
- return str.toString();
- }
- StringBuilder sb = new StringBuilder();
- int len = str.length();
- for (int i = 0; i < len; ++i) {
- char ch = str.charAt(i);
- sb.append(ch == ' ' ? "%20" : ch);
- }
-
- return sb.toString();
- }
-}
-```
-
-#### 解法二【推荐】
-先遍历原字符串,遇到空格,则在原字符串末尾 `append` 任意两个字符,如两个空格。
-
-用指针 `p` 指向原字符串末尾,`q` 指向现字符串末尾,`p`, `q` 从后往前遍历,当 `p` 遇到空格,`q` 位置依次要 `append` '02%',若不是空格,直接 `append` `p` 指向的字符。
-
-> 🤔思路扩展:
-在合并两个数组(包括字符串)时,如果从前往后复制每个数字(或字符)需要重复移动数字(或字符)多次,那么我们可以考虑从后往前复制,这样就能减少移动的次数,从而提高效率。
-
-```java
-/**
- * @author bingo
- * @since 2018/10/27
- */
-
-public class Solution {
- /**
- * 将字符串中的所有空格替换为%20
- * @param str 字符串
- * @return 替换后的字符串
- */
- public String replaceSpace(StringBuffer str) {
- if (str == null || str.length() == 0) {
- return str.toString();
- }
-
- int len = str.length();
- for (int i = 0; i < len; ++i) {
- if (str.charAt(i) == ' ') {
- // append 两个空格
- str.append(" ");
- }
- }
-
- // p 指向原字符串末尾
- int p = len - 1;
-
- // q 指向现字符串末尾
- int q = str.length() - 1;
-
- while (p >= 0) {
- char ch = str.charAt(p--);
- if (ch == ' ') {
- str.setCharAt(q--, '0');
- str.setCharAt(q--, '2');
- str.setCharAt(q--, '%');
- } else {
- str.setCharAt(q--, ch);
- }
- }
-
- return str.toString();
-
- }
-}
-```
-
-
-### 测试用例
-1. 输入的字符串包含空格(空格位于字符串的最前面/最后面/中间;字符串有多个连续的空格);
-2. 输入的字符串中没有空格;
-3. 特殊输入测试(字符串是一个空指针;字符串是一个空字符串;字符串只有一个空格字符;字符串中有多个连续空格)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/06_PrintListInReversedOrder.md b/docs/jianzhioffer/java/06_PrintListInReversedOrder.md
deleted file mode 100644
index 60e99a538..000000000
--- a/docs/jianzhioffer/java/06_PrintListInReversedOrder.md
+++ /dev/null
@@ -1,110 +0,0 @@
-## 从尾到头打印链表
-
-### 题目描述
-输入一个链表,按链表值从尾到头的顺序返回一个 `ArrayList`。
-
-
-### 解法
-#### 解法一【推荐】
-遍历链表,每个链表结点值 `push` 进栈,最后将栈中元素依次 `pop` 到 `list` 中。
-```java
-/**
-* public class ListNode {
-* int val;
-* ListNode next = null;
-*
-* ListNode(int val) {
-* this.val = val;
-* }
-* }
-*
-*/
-import java.util.ArrayList;
-import java.util.Stack;
-
-/**
- * @author bingo
- * @since 2018/10/28
- */
-public class Solution {
- /**
- * 从尾到头打印链表
- * @param listNode 链表头节点
- * @return list
- */
- public ArrayList printListFromTailToHead(ListNode listNode) {
- ArrayList res = new ArrayList<>();
- if (listNode == null) {
- return res;
- }
- Stack stack = new Stack<>();
- while (listNode != null) {
- stack.push(listNode.val);
- listNode = listNode.next;
- }
- while (!stack.isEmpty()) {
- res.add(stack.pop());
- }
-
- return res;
- }
-}
-```
-
-#### 解法二【不推荐】
-利用递归方式:
-- 若不是链表尾结点,继续递归;
-- 若是,添加到 `list` 中。
-
-这种方式不推荐,当递归层数过多时,容易发生 `Stack Overflow`。
-
-```java
-/**
-* public class ListNode {
-* int val;
-* ListNode next = null;
-*
-* ListNode(int val) {
-* this.val = val;
-* }
-* }
-*
-*/
-import java.util.ArrayList;
-import java.util.Stack;
-
-/**
- * @author bingo
- * @since 2018/10/28
- */
-public class Solution {
- /**
- * 从尾到头打印链表
- * @param listNode 链表头结点
- * @return list
- */
- public ArrayList printListFromTailToHead(ListNode listNode) {
- ArrayList res = new ArrayList<>();
- if (listNode == null) {
- return res;
- }
-
- addElement(listNode, res);
- return res;
-
- }
-
- private void addElement(ListNode listNode, ArrayList res) {
- if (listNode.next != null) {
- // 递归调用
- addElement(listNode.next, res);
- }
- res.add(listNode.val);
- }
-}
-```
-
-
-### 测试用例
-1. 功能测试(输入的链表有多个结点;输入的链表只有一个结点);
-2. 特殊输入测试(输入的链表结点指针为空)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/07_ConstructBinaryTree.md b/docs/jianzhioffer/java/07_ConstructBinaryTree.md
deleted file mode 100644
index f8c824a2e..000000000
--- a/docs/jianzhioffer/java/07_ConstructBinaryTree.md
+++ /dev/null
@@ -1,82 +0,0 @@
-## 重建二叉树
-
-### 题目描述
-输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列 `{1,2,4,7,3,5,6,8}` 和中序遍历序列 `{4,7,2,1,5,3,8,6}`,则重建二叉树并返回。
-
-
-### 解法
-在二叉树的前序遍历序列中,第一个数字总是根结点的值。在中序遍历序列中,根结点的值在序列的中间,左子树的结点位于根结点左侧,而右子树的结点位于根结点值的右侧。
-
-遍历中序序列,找到根结点,递归构建左子树与右子树。
-
-注意添加特殊情况的 `if` 判断。
-
-```java
-/**
- * Definition for binary tree
- * public class TreeNode {
- * int val;
- * TreeNode left;
- * TreeNode right;
- * TreeNode(int x) { val = x; }
- * }
- */
-
-/**
- * @author bingo
- * @since 2018/10/28
- */
-
-public class Solution {
- /**
- * 重建二叉树
- *
- * @param pre 先序序列
- * @param in 中序序列
- * @return 二叉树根结点
- */
- public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
- if (pre == null || in == null || pre.length != in.length) {
- return null;
- }
- int n = pre.length;
- return constructBinaryTree(pre, 0, n - 1, in, 0, n - 1);
- }
-
- private TreeNode constructBinaryTree(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn) {
- TreeNode node = new TreeNode(pre[startPre]);
- if (startPre == endPre) {
- if (startIn == endIn) {
- return node;
- }
- throw new IllegalArgumentException("Invalid input!");
- }
-
- int inOrder = startIn;
- while (in[inOrder] != pre[startPre]) {
- ++inOrder;
- if (inOrder > endIn) {
- new IllegalArgumentException("Invalid input!");
- }
- }
- int len = inOrder - startIn;
- if (len > 0) {
- // 递归构建左子树
- node.left = constructBinaryTree(pre, startPre + 1, startPre + len, in, startIn, inOrder - 1);
- }
-
- if (inOrder < endIn) {
- // 递归构建右子树
- node.right = constructBinaryTree(pre, startPre + len + 1, endPre, in, inOrder + 1, endIn);
- }
- return node;
-
- }
-}
-```
-
-
-### 测试用例
-1. 普通二叉树(完全二叉树;不完全二叉树);
-2. 特殊二叉树(所有结点都没有左/右子结点;只有一个结点的二叉树);
-3. 特殊输入测试(二叉树根结点为空;输入的前序序列和中序序列不匹配)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/08_NextNodeInBinaryTrees.md b/docs/jianzhioffer/java/08_NextNodeInBinaryTrees.md
deleted file mode 100644
index e16037ce7..000000000
--- a/docs/jianzhioffer/java/08_NextNodeInBinaryTrees.md
+++ /dev/null
@@ -1,74 +0,0 @@
-## 二叉树的下一个结点
-
-### 题目描述
-给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
-
-
-### 解法
-对于结点 `pNode`:
-- 如果它有右子树,则**右子树的最左结点**就是它的下一个结点;
-- 如果它没有右子树,判断它与父结点 `pNode.next` 的位置情况:
- - 如果它是父结点的左孩子,那么父结点 `pNode.next` 就是它的下一个结点;
- - 如果它是父结点的右孩子,一直向上寻找,直到找到某个结点,它是它父结点的左孩子,那么该父结点就是 `pNode` 的下一个结点。
-
-```java
-/*
-public class TreeLinkNode {
- int val;
- TreeLinkNode left = null;
- TreeLinkNode right = null;
- TreeLinkNode next = null;
-
- TreeLinkNode(int val) {
- this.val = val;
- }
-}
-*/
-
-/**
- * @author bingo
- * @since 2018/10/28
- */
-
-public class Solution {
- /**
- * 获取中序遍历结点的下一个结点
- * @param pNode 某个结点
- * @return pNode的下一个结点
- */
- public TreeLinkNode GetNext(TreeLinkNode pNode) {
- if (pNode == null) {
- return null;
- }
-
- if (pNode.right != null) {
- TreeLinkNode t = pNode.right;
- while (t.left != null) {
- t = t.left;
- }
- return t;
- }
-
- // 须保证 pNode.next 不为空,否则会出现 NPE
- if (pNode.next != null && pNode.next.left == pNode) {
- return pNode.next;
- }
-
- while (pNode.next != null) {
- if (pNode.next.left == pNode) {
- return pNode.next;
- }
- pNode = pNode.next;
- }
-
- return null;
-
- }
-}
-```
-
-
-### 测试用例
-1. 普通二叉树(完全二叉树;不完全二叉树);
-2. 特殊二叉树(所有结点都没有左/右子结点;只有一个结点的二叉树;二叉树的根结点为空);
-3. 不同位置的结点的下一个结点(下一个结点为当前结点的右子结点、右子树的最左子结点、父结点、跨层的父结点等;当前结点没有下一个结点)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/09_01_QueueWithTwoStacks.md b/docs/jianzhioffer/java/09_01_QueueWithTwoStacks.md
deleted file mode 100644
index 9dc32d0d2..000000000
--- a/docs/jianzhioffer/java/09_01_QueueWithTwoStacks.md
+++ /dev/null
@@ -1,47 +0,0 @@
-## 用两个栈实现队列
-
-### 题目描述
-用两个栈来实现一个队列,完成队列的 `Push` 和 `Pop` 操作。 队列中的元素为 `int` 类型。
-
-
-### 解法
-`Push` 操作,每次都存入 `stack1`;
-`Pop` 操作,每次从 `stack2` 取:
-- `stack2` 栈不为空时,不能将 `stack1` 元素倒入;
-- `stack2` 栈为空时,需要一次将 `stack1` 元素全部倒入。
-
-```java
-import java.util.Stack;
-
-/**
- * @author bingo
- * @since 2018/10/28
- */
-
-public class Solution {
- Stack stack1 = new Stack();
- Stack stack2 = new Stack();
-
- public void push(int node) {
- stack1.push(node);
- }
-
- public int pop() {
- if (stack2.isEmpty()) {
- if (stack1.isEmpty()) {
- return -1;
- }
- while (!stack1.isEmpty()) {
- stack2.push(stack1.pop());
- }
- }
- return stack2.pop();
- }
-}
-```
-
-
-### 测试用例
-1. 往空的队列里添加、删除元素;
-2. 往非空的队列添加、删除元素;
-3. 连续删除元素直至队列为空。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/09_02_StackWithTwoQueues.md b/docs/jianzhioffer/java/09_02_StackWithTwoQueues.md
deleted file mode 100644
index 823b8fa29..000000000
--- a/docs/jianzhioffer/java/09_02_StackWithTwoQueues.md
+++ /dev/null
@@ -1,55 +0,0 @@
-## 用两个队列实现栈
-
-### 题目描述
-用两个队列来实现一个栈,完成栈的 `Push` 和 `Pop` 操作。 栈中的元素为 `int` 类型。
-
-
-### 解法
-`Push` 操作,每次都存入 `queue1`;
-`Pop` 操作,每次从 `queue1` 取:
-- 将 `queue1` 中的元素依次倒入 `queue2`,直到 `queue1` 剩下一个元素,这个元素就是要 `pop` 出去的;
-- 将 `queue1` 与 `queue2` 进行交换,这样保证每次都从 `queue1` 中存取元素,`queue2` 只起到辅助暂存的作用。
-
-```java
-import java.util.LinkedList;
-import java.util.Queue;
-
-/**
- * @author bingo
- * @since 2018/10/29
- */
-
-public class Solution {
-
- private Queue queue1 = new LinkedList<>();
- private Queue queue2 = new LinkedList<>();
-
- public void push(int node) {
- queue1.offer(node);
- }
-
- public int pop() {
- if (queue1.isEmpty()) {
- throw new RuntimeException("Empty stack!");
- }
-
- while (queue1.size() > 1) {
- queue2.offer(queue1.poll());
- }
-
- int val = queue1.poll();
-
- Queue t = queue1;
- queue1 = queue2;
- queue2 = t;
- return val;
-
- }
-}
-```
-
-
-### 测试用例
-1. 往空的栈里添加、删除元素;
-2. 往非空的栈添加、删除元素;
-3. 连续删除元素直至栈为空。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/10_01_Fibonacci.md b/docs/jianzhioffer/java/10_01_Fibonacci.md
deleted file mode 100644
index 31ac8b0ec..000000000
--- a/docs/jianzhioffer/java/10_01_Fibonacci.md
+++ /dev/null
@@ -1,79 +0,0 @@
-## 斐波那契数列
-
-### 题目描述
-大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第 `n` 项(从 `0` 开始,第 `0` 项为 `0`)。`n<=39`
-
-
-### 解法
-#### 解法一
-采用递归方式,简洁明了,但效率很低,存在大量的重复计算。
-```
- f(10)
- / \
- f(9) f(8)
- / \ / \
- f(8) f(7) f(7) f(6)
- / \ / \
- f(7) f(6) f(6) f(5)
-```
-
-```java
-
-/**
- * @author bingo
- * @since 2018/10/29
- */
-
-public class Solution {
- /**
- * 求斐波那契数列的第n项,n从0开始
- * @param n 第n项
- * @return 第n项的值
- */
- public int Fibonacci(int n) {
- if (n < 2) {
- return n;
- }
- // 递归调用
- return Fibonacci(n - 1) + Fibonacci(n - 2);
- }
-}
-```
-
-#### 解法二
-从下往上计算,递推,时间复杂度 `O(n)`。
-
-```java
-
-/**
- * @author bingo
- * @since 2018/10/29
- */
-
-public class Solution {
- /**
- * 求斐波那契数列的第n项,n从0开始
- * @param n 第n项
- * @return 第n项的值
- */
- public int Fibonacci(int n) {
- if (n < 2) {
- return n;
- }
- int[] res = new int[n + 1];
- res[0] = 0;
- res[1] = 1;
- for (int i = 2; i <= n; ++i) {
- res[i] = res[i - 1] + res[i - 2];
- }
- return res[n];
-
- }
-}
-```
-
-
-### 测试用例
-1. 功能测试(如输入 3、5、10 等);
-2. 边界值测试(如输入 0、1、2);
-3. 性能测试(输入较大的数字,如 40、50、100 等)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/10_02_JumpFloor.md b/docs/jianzhioffer/java/10_02_JumpFloor.md
deleted file mode 100644
index 268b7c8af..000000000
--- a/docs/jianzhioffer/java/10_02_JumpFloor.md
+++ /dev/null
@@ -1,42 +0,0 @@
-## 跳台阶
-
-### 题目描述
-一只青蛙一次可以跳上`1`级台阶,也可以跳上`2`级。求该青蛙跳上一个`n`级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
-
-### 解法
-跳上 `n` 级台阶,可以从 `n-1` 级跳 `1` 级上去,也可以从 `n-2` 级跳 `2` 级上去。所以
-```
-f(n) = f(n-1) + f(n-2)
-```
-
-```java
-/**
- * @author bingo
- * @since 2018/11/23
- */
-
-public class Solution {
- /**
- * 青蛙跳台阶
- * @param target 跳上的那一级台阶
- * @return 多少种跳法
- */
- public int JumpFloor(int target) {
- if (target < 3) {
- return target;
- }
- int[] res = new int[target + 1];
- res[1] = 1;
- res[2] = 2;
- for (int i = 3; i <= target; ++i) {
- res[i] = res[i - 1] + res[i - 2];
- }
- return res[target];
- }
-}
-```
-
-### 测试用例
-1. 功能测试(如输入 3、5、10 等);
-2. 边界值测试(如输入 0、1、2);
-3. 性能测试(输入较大的数字,如 40、50、100 等)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/10_03_JumpFloorII.md b/docs/jianzhioffer/java/10_03_JumpFloorII.md
deleted file mode 100644
index 91f3ac3ea..000000000
--- a/docs/jianzhioffer/java/10_03_JumpFloorII.md
+++ /dev/null
@@ -1,48 +0,0 @@
-## 变态跳台阶
-
-### 题目描述
-一只青蛙一次可以跳上`1`级台阶,也可以跳上`2`级……它也可以跳上`n`级。求该青蛙跳上一个`n`级的台阶总共有多少种跳法。
-
-### 解法
-跳上 `n-1` 级台阶,可以从 `n-2` 级跳 `1` 级上去,也可以从 `n-3` 级跳 `2` 级上去...也可以从 `0` 级跳上去。那么
-```
-f(n-1) = f(0) + f(1) + ... + f(n-2) ①
-```
-
-跳上 `n` 级台阶,可以从 `n-1` 级跳 `1` 级上去,也可以从 `n-2` 级跳 `2` 级上去...也可以从 `0` 级跳上去。那么
-```
-f(n) = f(0) + f(1) + ... + f(n-2) + f(n-1) ②
-
-②-①:
-f(n) - f(n-1) = f(n-1)
-f(n) = 2f(n-1)
-```
-
-所以 f(n) 是一个等比数列:
-```
-f(n) = 2^(n-1)
-```
-
-
-```java
-/**
- * @author bingo
- * @since 2018/11/23
- */
-
-public class Solution {
- /**
- * 青蛙跳台阶II
- * @param target 跳上的那一级台阶
- * @return 多少种跳法
- */
- public int JumpFloorII(int target) {
- return (int) Math.pow(2, target - 1);
- }
-}
-```
-
-### 测试用例
-1. 功能测试(如输入 3、5、10 等);
-2. 边界值测试(如输入 0、1、2);
-3. 性能测试(输入较大的数字,如 40、50、100 等)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/10_04_RectCover.md b/docs/jianzhioffer/java/10_04_RectCover.md
deleted file mode 100644
index 07ddc850c..000000000
--- a/docs/jianzhioffer/java/10_04_RectCover.md
+++ /dev/null
@@ -1,73 +0,0 @@
-## 矩形覆盖
-
-### 题目描述
-我们可以用`2*1`的小矩形横着或者竖着去覆盖更大的矩形。请问用`n`个`2*1`的小矩形无重叠地覆盖一个`2*n`的大矩形,总共有多少种方法?
-
-### 解法
-覆盖 `2*n` 的矩形:
-- 可以先覆盖 `2*n-1` 的矩形,再覆盖一个 `2*1` 的矩形;
-- 也可以先覆盖 `2*(n-2)` 的矩形,再覆盖两个 `1*2` 的矩形。
-
-#### 解法一:利用数组存放结果
-```java
-/**
- * @author bingo
- * @since 2018/11/23
- */
-
-public class Solution {
- /**
- * 矩形覆盖
- * @param target 2*target大小的矩形
- * @return 多少种覆盖方法
- */
- public int RectCover(int target) {
- if (target < 3) {
- return target;
- }
- int[] res = new int[target + 1];
- res[1] = 1;
- res[2] = 2;
- for (int i = 3; i <= target; ++i) {
- res[i] = res[i - 1] + res[i - 2];
- }
- return res[target];
- }
-}
-```
-
-#### 解法二:直接用变量存储结果
-```java
-/**
- * @author bingo
- * @since 2018/11/23
- */
-
-public class Solution {
- /**
- * 矩形覆盖
- * @param target 2*target大小的矩形
- * @return 多少种覆盖方法
- */
- public int RectCover(int target) {
- if (target < 3) {
- return target;
- }
- int res1 = 1;
- int res2 = 2;
- int res = 0;
- for (int i = 3; i <= target; ++i) {
- res = res1 + res2;
- res1 = res2;
- res2 = res;
- }
- return res;
- }
-}
-```
-
-
-### 测试用例
-1. 功能测试(如输入 3、5、10 等);
-2. 边界值测试(如输入 0、1、2);
-3. 性能测试(输入较大的数字,如 40、50、100 等)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/11_MinNumberInRotatedArray.md b/docs/jianzhioffer/java/11_MinNumberInRotatedArray.md
deleted file mode 100644
index e8fcdad00..000000000
--- a/docs/jianzhioffer/java/11_MinNumberInRotatedArray.md
+++ /dev/null
@@ -1,119 +0,0 @@
-## 旋转数组的最小数字
-
-### 题目描述
-把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组 `{3,4,5,1,2}` 为 `{1,2,3,4,5}` 的一个旋转,该数组的最小值为 `1`。
-
-**NOTE:**给出的所有元素都大于 `0`,若数组大小为 `0`,请返回 `0`。
-
-
-### 解法
-#### 解法一
-直接遍历数组找最小值,时间复杂度 `O(n)`,不推荐。
-
-```java
-
-/**
- * @author bingo
- * @since 2018/10/30
- */
-
-public class Solution {
- /**
- * 获取旋转数组的最小元素
- * @param array 旋转数组
- * @return 数组中的最小值
- */
- public int minNumberInRotateArray(int[] array) {
- if (array == null || array.length == 0) {
- return 0;
- }
-
- int n = array.length;
- if (n == 1 || array[0] < array[n - 1]) {
- return array[0];
- }
-
- int min = array[0];
- for (int i = 1; i < n; ++i) {
- min = array[i] < min ? array[i] : min;
- }
-
- return min;
- }
-
-}
-```
-
-#### 解法二
-利用指针 `p`,`q` 指向数组的首尾,如果 `array[p] < array[q]`,说明数组是递增数组,直接返回 `array[p]`。否则进行如下讨论。
-
-计算中间指针 `mid`:
-- 如果此时 `array[p]`, `array[q]`, `array[mid]` 两两相等,此时无法采用二分方式,只能通过遍历区间 `[p,q]` 获取最小值;
-- 如果此时 `p`,`q` 相邻,说明此时 `q` 指向的元素是最小值,返回 `array[q]`;
-- 如果此时 `array[mid] >= array[p]`,说明 `mid` 位于左边的递增数组中,最小值在右边,因此,把 `p` 指向 `mid`,此时保持了 `p` 指向左边递增子数组;
-- 如果此时 `array[mid] <= array[q]`,说明 `mid` 位于右边的递增数组中,最小值在左边,因此,把 `q` 指向 `mid`,此时保持了 `q` 指向右边递增子数组。
-
-```java
-
-
-/**
- * @author bingo
- * @since 2018/10/30
- */
-
-public class Solution {
- /**
- * 获取旋转数组的最小元素
- * @param array 旋转数组
- * @return 数组中的最小值
- */
- public int minNumberInRotateArray(int[] array) {
- if (array == null || array.length == 0) {
- return 0;
- }
-
- int p = 0;
- // mid初始为p,为了兼容当数组是递增数组(即不满足 array[p] >= array[q])时,返回 array[p]
- int mid = p;
- int q = array.length - 1;
- while (array[p] >= array[q]) {
- if (q - p == 1) {
- // 当p,q相邻时(距离为1),那么q指向的元素就是最小值
- mid = q;
- break;
- }
- mid = p + ((q - p) >> 1);
-
- // 当p,q,mid指向的值相等时,此时只能通过遍历查找最小值
- if (array[p] == array[q] && array[mid] == array[p]) {
- mid = getMinIndex(array, p, q);
- break;
- }
-
- if (array[mid] >= array[p]) {
- p = mid;
- } else if (array[mid] <= array[q]) {
- q = mid;
- }
- }
-
- return array[mid];
-
-
- }
-
- private int getMinIndex(int[] array, int p, int q) {
- int minIndex = p;
- for (int i = p + 1; i <= q; ++i) {
- minIndex = array[i] < array[minIndex] ? i : minIndex;
- }
- return minIndex;
- }
-}
-```
-
-
-### 测试用例
-1. 功能测试(输入的数组是升序排序数组的一个旋转,数组中有重复数字或者没有重复数字);
-2. 边界值测试(输入的数组是一个升序排序的数组,只包含一个数字的数组);
-3. 特殊输入测试(输入空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/12_StringPathInMatrix.md b/docs/jianzhioffer/java/12_StringPathInMatrix.md
deleted file mode 100644
index 9a87e9e3e..000000000
--- a/docs/jianzhioffer/java/12_StringPathInMatrix.md
+++ /dev/null
@@ -1,66 +0,0 @@
-## 矩阵中的路径
-
-### 题目描述
-请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 `a b c e s f c s a d e e` 这样的 `3 X 4` 矩阵中包含一条字符串`"bcced"`的路径,但是矩阵中不包含`"abcb"`路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
-
-### 解法
-回溯法。首先,任选一个格子作为路径起点。假设格子对应的字符为 ch,并且对应路径上的第 i 个字符。若相等,到相邻格子寻找路径上的第 i+1 个字符。重复这一过程。
-
-```java
-/**
- * @author bingo
- * @since 2018/11/20
- */
-
-public class Solution {
- /**
- * 判断矩阵中是否包含某条路径
- * @param matrix 矩阵
- * @param rows 行数
- * @param cols 列数
- * @param str 路径
- * @return bool
- */
- public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
- if (matrix == null || rows < 1 || cols < 1 || str == null) {
- return false;
- }
- boolean[] visited = new boolean[matrix.length];
- int pathLength = 0;
- for (int i = 0; i < rows; ++i) {
- for (int j = 0; j < cols; ++j) {
- if (hasPath(matrix, rows, cols, str, i, j, pathLength, visited)) {
- return true;
- }
- }
- }
- return false;
- }
-
- private boolean hasPath(char[] matrix, int rows, int cols, char[] str, int i, int j, int pathLength, boolean[] visited) {
- if (pathLength == str.length) {
- return true;
- }
- boolean hasPath = false;
- if (i >= 0 && i < rows && j >= 0 && j < cols && matrix[i * cols + j] == str[pathLength] && !visited[i * cols + j]) {
- ++pathLength;
- visited[i * cols + j] = true;
- hasPath = hasPath(matrix, rows, cols, str, i - 1, j, pathLength, visited)
- || hasPath(matrix, rows, cols, str, i + 1, j, pathLength, visited)
- || hasPath(matrix, rows, cols, str, i, j - 1, pathLength, visited)
- || hasPath(matrix, rows, cols, str, i, j + 1, pathLength, visited);
- if (!hasPath) {
- --pathLength;
- visited[i * cols + j] = false;
- }
- }
- return hasPath;
- }
-}
-
-```
-
-### 测试用例
-1. 功能测试(在多行多列的矩阵中存在或者不存在路径);
-2. 边界值测试(矩阵只有一行或者一列;矩阵和路径中的所有字母都是相同的);
-3. 特殊输入测试(输入空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/13_RobotMove.md b/docs/jianzhioffer/java/13_RobotMove.md
deleted file mode 100644
index 7a4e8d5ed..000000000
--- a/docs/jianzhioffer/java/13_RobotMove.md
+++ /dev/null
@@ -1,66 +0,0 @@
-## 机器人的移动范围
-
-### 题目描述
-地上有一个`m`行和`n`列的方格。一个机器人从坐标`0,0`的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于`k`的格子。 例如,当`k`为`18`时,机器人能够进入方格`(35,37)`,因为`3+5+3+7 = 18`。但是,它不能进入方格`(35,38)`,因为`3+5+3+8 = 19`。请问该机器人能够达到多少个格子?
-
-### 解法
-从坐标(0, 0) 开始移动,当它准备进入坐标(i, j),判断是否能进入,如果能,再判断它能否进入 4 个相邻的格子 (i-1, j), (i+1, j), (i, j-1), (i, j+1)。
-
-```java
-/**
- * @author bingo
- * @since 2018/11/20
- */
-
-public class Solution {
- /**
- * 计算能到达的格子数
- * @param threshold 限定的数字
- * @param rows 行数
- * @param cols 列数
- * @return 格子数
- */
- public int movingCount(int threshold, int rows, int cols) {
- if (threshold < 0 || rows < 1 || cols < 1) {
- return 0;
- }
- boolean[] visited = new boolean[rows * cols];
- return getCount(threshold, 0, 0, rows, cols, visited);
- }
-
- private int getCount(int threshold, int i, int j, int rows, int cols, boolean[] visited) {
- if (check(threshold, i, j, rows, cols, visited)) {
- visited[i * cols + j] = true;
- return 1
- + getCount(threshold, i - 1, j, rows, cols, visited)
- + getCount(threshold, i + 1, j, rows, cols, visited)
- + getCount(threshold, i, j - 1, rows, cols, visited)
- + getCount(threshold, i, j + 1, rows, cols, visited);
- }
- return 0;
- }
-
- private boolean check(int threshold, int i, int j, int rows, int cols, boolean[] visited) {
- return i >= 0
- && i < rows
- && j >= 0
- && j < cols
- && !visited[i * cols + j]
- && getDigitSum(i) + getDigitSum(j) <= threshold;
- }
-
- private int getDigitSum(int i) {
- int res = 0;
- while (i > 0) {
- res += i % 10;
- i /= 10;
- }
- return res;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(方格为多行多列;k 为正数);
-2. 边界值测试(方格只有一行或者一列;k = 0);
-3. 特殊输入测试(k < 0)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/14_CuttingRope.md b/docs/jianzhioffer/java/14_CuttingRope.md
deleted file mode 100644
index c120a5b78..000000000
--- a/docs/jianzhioffer/java/14_CuttingRope.md
+++ /dev/null
@@ -1,102 +0,0 @@
-## 剪绳子
-
-### 题目描述
-给你一根长度为`n`绳子,请把绳子剪成`m`段(`m`、`n`都是整数,`n>1`并且`m≥1`)。每段的绳子的长度记为k[0]、k[1]、……、k[m]。k[0]*k[1]*…*k[m]可能的最大乘积是多少?例如当绳子的长度是 8 时,我们把它剪成长度分别为 `2、3、3` 的三段,此时得到最大的乘积`18`。
-
-### 解法
-#### 解法一:动态规划法
-时间复杂度`O(n²)`,空间复杂度`O(n)`。
-
-- 长度为 2,只可能剪成长度为 1 的两段,因此 f(2)=1
-- 长度为 3,剪成长度分别为 1 和 2 的两段,乘积比较大,因此 f(3) = 2
-- 长度为 n,在剪第一刀的时候,有 n-1 种可能的选择,剪出来的绳子又可以继续剪,可以看出,原问题可以划分为子问题,子问题又有重复子问题。
-
-```java
-/**
- * @author bingo
- * @since 2018/11/20
- */
-
-public class Solution {
-
- /**
- * 剪绳子求最大乘积
- * @param length 绳子长度
- * @return 乘积最大值
- */
- public int maxProductAfterCutting(int length) {
- if (length < 2) {
- return 0;
- }
- if (length < 4) {
- return length - 1;
- }
-
- // res[i] 表示当长度为i时的最大乘积
- int[] res = new int[length + 1];
- res[1] = 1;
- res[2] = 2;
- res[3] = 3;
- // 从长度为4开始计算
- for (int i = 4; i <= length; ++i) {
- int max = 0;
- for (int j = 1; j <= i / 2; ++j) {
- max = Math.max(max, res[j] * res[i - j]);
- }
- res[i] = max;
- }
-
- return res[length];
-
- }
-}
-
-```
-
-#### 贪心算法
-时间复杂度`O(1)`,空间复杂度`O(1)`。
-
-贪心策略:
-- 当 n>=5 时,尽可能多地剪长度为 3 的绳子
-- 当剩下的绳子长度为 4 时,就把绳子剪成两段长度为 2 的绳子。
-
-**证明:**
-- 当 n>=5 时,可以证明 2(n-2)>n,并且 3(n-3)>n。也就是说,当绳子剩下长度大于或者等于 5 的时候,可以把它剪成长度为 3 或者 2 的绳子段。
-- 当 n>=5 时,3(n-3)>=2(n-2),因此,应该尽可能多地剪长度为 3 的绳子段。
-- 当 n=4 时,剪成两根长度为 2 的绳子,其实没必要剪,只是题目的要求是至少要剪一刀。
-
-```java
-/**
- * @author bingo
- * @since 2018/11/20
- */
-
-public class Solution {
-
- /**
- * 剪绳子求最大乘积
- * @param length 绳子长度
- * @return 乘积最大值
- */
- public int maxProductAfterCutting(int length) {
- if (length < 2) {
- return 0;
- }
- if (length < 4) {
- return length - 1;
- }
-
- int timesOf3 = length / 3;
- if (length % 3 == 1) {
- --timesOf3;
- }
- int timesOf2 = (length - timesOf3 * 3) >> 1;
- return (int) (Math.pow(3, timesOf3) * Math.pow(2, timesOf2));
- }
-}
-
-```
-
-### 测试用例
-1. 功能测试(绳子的初始长度大于 5);
-2. 边界值测试(绳子的初始长度分别为 0、1、2、3、4)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/15_NumberOf1InBinary.md b/docs/jianzhioffer/java/15_NumberOf1InBinary.md
deleted file mode 100644
index 23bf9351a..000000000
--- a/docs/jianzhioffer/java/15_NumberOf1InBinary.md
+++ /dev/null
@@ -1,73 +0,0 @@
-## 二进制中 1 的个数
-
-### 题目描述
-输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
-
-### 解法
-#### 解法一
-利用整数 1,依次左移每次与 n 进行与运算,若结果不为0,说明这一位上数字为 1,++cnt。
-
-此解法 i 需要左移 32 次。
-
-不要用 n 去右移并与 1 进行与运算,因为n 可能为负数,右移时会陷入死循环。
-
-```java
-public class Solution {
- public int NumberOf1(int n) {
- int cnt = 0;
- int i = 1;
- while (i != 0) {
- if ((n & i) != 0) {
- ++cnt;
- }
- i <<= 1;
- }
- return cnt;
- }
-}
-```
-
-#### 解法二(推荐)
-- 运算 (n - 1) & n,直至 n 为 0。运算的次数即为 n 的二进制中 1 的个数。
-
-因为 n-1 会将 n 的最右边一位 1 改为 0,如果右边还有 0,则所有 0 都会变成 1。结果与 n 进行与运算,会去除掉最右边的一个1。
-
-举个栗子:
-```
-若 n = 1100,
-n - 1 = 1011
-n & (n - 1) = 1000
-
-即:把最右边的 1 变成了 0。
-```
-
-> 把一个整数减去 1 之后再和原来的整数做位与运算,得到的结果相当于把整数的二进制表示中最右边的 1 变成 0。很多二进制的问题都可以用这种思路解决。
-
-```java
-/**
- * @author bingo
- * @since 2018/11/20
- */
-
-public class Solution {
- /**
- * 计算整数的二进制表示里1的个数
- * @param n 整数
- * @return 1的个数
- */
- public int NumberOf1(int n) {
- int cnt = 0;
- while (n != 0) {
- n = (n - 1 ) & n;
- ++cnt;
- }
- return cnt;
- }
-}
-
-```
-
-### 测试用例
-1. 正数(包括边界值 1、0x7FFFFFFF);
-2. 负数(包括边界值 0x80000000、0xFFFFFFFF);
-3. 0。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/16_Power.md b/docs/jianzhioffer/java/16_Power.md
deleted file mode 100644
index f1bbc09c8..000000000
--- a/docs/jianzhioffer/java/16_Power.md
+++ /dev/null
@@ -1,36 +0,0 @@
-## 数值的整数次方
-
-### 题目描述
-给定一个 `double` 类型的浮点数 `base` 和 `int` 类型的整数 `exponent`。求 `base`的 `exponent` 次方。
-
-### 解法
-注意判断值数是否小于 0。另外 0 的 0 次方没有意义,也需要考虑一下,看具体题目要求。
-
-```java
-/**
- * @author bingo
- * @since 2018/11/20
- */
-
-public class Solution {
- /**
- * 计算数值的整数次方
- * @param base 底数
- * @param exponent 指数
- * @return 数值的整数次方
- */
- public double Power(double base, int exponent) {
- double result = 1.0;
- int n = Math.abs(exponent);
- for (int i = 0; i < n; ++i) {
- result *= base;
- }
-
- return exponent < 0 ? 1.0 / result : result;
- }
-}
-
-```
-
-### 测试用例
-1. 把底数和指数分别设为正数、负数和零。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/17_Print1ToMaxOfNDigits.md b/docs/jianzhioffer/java/17_Print1ToMaxOfNDigits.md
deleted file mode 100644
index 86b8e8fa3..000000000
--- a/docs/jianzhioffer/java/17_Print1ToMaxOfNDigits.md
+++ /dev/null
@@ -1,90 +0,0 @@
-## 打印从 1 到最大的 n 位数
-
-### 题目描述
-输入数字 `n`,按顺序打印出从 `1` 最大的 `n` 位十进制数。比如输入 `3`,则打印出 `1、2、3` 一直到最大的 3 位数即 999。
-
-### 解法
-此题需要注意 n 位数构成的数字可能超出最大的 int 或者 long long 能表示的范围。因此,采用字符数组来存储数字。
-
-关键是:
-- 对字符数组表示的数进行递增操作
-- 输出数字(0开头的需要把0去除)
-
-```java
-/**
- * @author bingo
- * @since 2018/11/20
- */
-
-public class Solution {
-
- /**
- * 打印从1到最大的n位数
- * @param n n位
- */
- public void print1ToMaxOfNDigits(int n) {
- if (n < 1) {
- return;
- }
-
- char[] chars = new char[n];
- for (int i = 0; i < n; ++i) {
- chars[i] = '0';
- }
-
- while (!increment(chars)) {
- printNumber(chars);
- }
- }
-
- /**
- * 打印数字(去除前面的0)
- * @param chars 数字数组
- */
- private void printNumber(char[] chars) {
- int index = 0;
- int n = chars.length;
- for (char ch : chars) {
- if (ch != '0') {
- break;
- }
- ++index;
- }
- StringBuilder sb = new StringBuilder();
- for (int i = index; i < n; ++i) {
- sb.append(chars[i]);
- }
- System.out.println(sb.toString());
- }
-
- /**
- * 数字加1
- * @param chars 数字数组
- * @return 是否溢出
- */
- private boolean increment(char[] chars) {
- boolean flag = false;
- int n = chars.length;
- int carry = 1;
- for (int i = n - 1; i >= 0; --i) {
-
- int num = chars[i] - '0' + carry;
- if (num > 9) {
- if (i == 0) {
- flag = true;
- break;
- }
- chars[i] = '0';
- } else {
- ++chars[i];
- break;
- }
- }
- return flag;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入 1、2、3......);
-2. 特殊输入测试(输入 -1、0)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/18_01_DeleteNodeInList.md b/docs/jianzhioffer/java/18_01_DeleteNodeInList.md
deleted file mode 100644
index fdebe01dc..000000000
--- a/docs/jianzhioffer/java/18_01_DeleteNodeInList.md
+++ /dev/null
@@ -1,59 +0,0 @@
-## 在O(1)时间内删除链表节点
-
-### 题目描述
-给定单向链表的头指针和一个节点指针,定义一个函数在 O(1) 时间内删除该节点。
-
-### 解法
-判断要删除的节点是否是尾节点,若是,直接删除;若不是,把要删除节点的下一个节点赋给要删除的节点即可。
-
-### ```进行n次操作,平均时间复杂度为:( (n-1) * O(1) + O(n) ) / n = O(1),所以符合题目上说的O(1)```
-
-```java
-/**
- * @author bingo
- * @since 2018/11/20
- */
-
-public class Solution {
-
- class ListNode {
- int val;
- ListNode next;
- }
-
- /**
- * 删除链表的节点
- * @param head 链表头节点
- * @param tobeDelete 要删除的节点
- */
- public ListNode deleteNode(ListNode head, ListNode tobeDelete) {
- if (head == null || tobeDelete == null) {
- return head;
- }
-
- // 删除的不是尾节点
- if (tobeDelete.next != null) {
- tobeDelete.val = tobeDelete.next.val;
- tobeDelete.next = tobeDelete.next.next;
- }
- // 链表中仅有一个节点
- else if (head == tobeDelete) {
- head = null;
- }
- // 删除的是尾节点
- else {
- ListNode ptr = head;
- while (ptr.next != tobeDelete) {
- ptr = ptr.next;
- }
- ptr.next = null;
- }
-
- return head;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(从有多个节点的链表的中间/头部/尾部删除一个节点;从只有一个节点的链表中删除唯一的节点);
-2. 特殊输入测试(指向链表头节点的为空指针;指向要删除节点的为空指针)。
diff --git a/docs/jianzhioffer/java/18_02_DeleteDuplicatedNode.md b/docs/jianzhioffer/java/18_02_DeleteDuplicatedNode.md
deleted file mode 100644
index 054e6e341..000000000
--- a/docs/jianzhioffer/java/18_02_DeleteDuplicatedNode.md
+++ /dev/null
@@ -1,94 +0,0 @@
-## 删除链表中重复的节点
-
-### 题目描述
-在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表`1->2->3->3->4->4->5` 处理后为 `1->2->5`。
-
-### 解法
-#### 解法一:递归
-
-```java
-/**
- * @author bingo
- * @since 2018/11/21
- */
-
-/*
- public class ListNode {
- int val;
- ListNode next = null;
-
- ListNode(int val) {
- this.val = val;
- }
-}
-*/
-public class Solution {
- /**
- * 删除链表重复的节点
- * @param pHead 链表头节点
- * @return 删除节点后的链表
- */
- public ListNode deleteDuplication(ListNode pHead) {
- if (pHead == null || pHead.next == null) {
- return pHead;
- }
-
- if (pHead.val == pHead.next.val) {
- if (pHead.next.next == null) {
- return null;
- }
- if (pHead.next.next.val == pHead.val) {
- return deleteDuplication(pHead.next);
- }
- return deleteDuplication(pHead.next.next);
- }
- pHead.next = deleteDuplication(pHead.next);
- return pHead;
- }
-}
-```
-
-#### 解法二
-```java
-/*
- public class ListNode {
- int val;
- ListNode next = null;
-
- ListNode(int val) {
- this.val = val;
- }
-}
-*/
-public class Solution {
- public ListNode deleteDuplication(ListNode pHead) {
- if (pHead == null || pHead.next == null) {
- return pHead;
- }
-
- ListNode pre = null;
- ListNode cur = pHead;
- while (cur != null) {
- if (cur.next != null && cur.next.val == cur.val) {
- int val = cur.val;
- while (cur.next != null && cur.next.val == val) {
- cur = cur.next;
- }
- if (pre == null) {
- pHead = cur.next;
- } else {
- pre.next = cur.next;
- }
- } else {
- pre = cur;
- }
- cur = cur.next;
- }
- return pHead;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(重复的节点位于链表的头部/中间/尾部;链表中没有重复的节点);
-2. 特殊输入测试(指向链表头节点的为空指针;链表中所有节点都是重复的)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/19_RegularExpressionsMatching.md b/docs/jianzhioffer/java/19_RegularExpressionsMatching.md
deleted file mode 100644
index 5cd4833bb..000000000
--- a/docs/jianzhioffer/java/19_RegularExpressionsMatching.md
+++ /dev/null
@@ -1,68 +0,0 @@
-## 正则表达式匹配
-
-### 题目描述
-请实现一个函数用来匹配包括`.`和`*`的正则表达式。模式中的字符`.`表示任意一个字符,而`*`表示它前面的字符可以出现任意次(包含`0`次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串`aaa`与模式`a.a`和`ab*ac*a`匹配,但是与`aa.a`和`ab*a`均不匹配。
-
-### 解法
-判断模式中第二个字符是否是 `*`:
-- 若是,看如果模式串第一个字符与字符串第一个字符是否匹配:
- - 1. 若不匹配,在模式串上向右移动两个字符`j+2`,相当于 a* 被忽略
- - 2. 若匹配,字符串后移`i+1`。此时模式串可以移动两个字符`j+2`,也可以不移动`j`。
-- 若不是,看当前字符与模式串的当前字符是否匹配,即 str[i] == pattern[j] || pattern[j] == '.':
- - 1. 若匹配,则字符串与模式串都向右移动一位,`i+1`,`j+1`。
- - 2. 若不匹配,返回 fasle。
-
-```java
-/**
- * @author bingo
- * @since 2018/11/21
- */
-
-public class Solution {
- /**
- * 判断字符串是否与模式串匹配
- * @param str 字符串
- * @param pattern 模式串
- * @return 是否匹配
- */
- public boolean match(char[] str, char[] pattern) {
- if (str == null || pattern == null) {
- return false;
- }
- return match(str, 0, str.length, pattern, 0, pattern.length);
- }
-
- private boolean match(char[] str, int i, int len1,
- char[] pattern, int j, int len2) {
- if (i == len1 && j == len2) {
- return true;
- }
-
- // "",".*"
- if (i != len1 && j == len2) {
- return false;
- }
-
- if (j + 1 < len2 && pattern[j + 1] == '*') {
- if (i < len1 && (str[i] == pattern[j] || pattern[j] == '.')) {
- return match(str, i, len1, pattern, j + 2, len2)
- || match(str, i + 1, len1, pattern, j, len2)
- || match(str, i + 1, len1, pattern,j + 2, len2);
- }
-
- // "",".*"
- return match(str, i, len1, pattern, j + 2, len2);
-
- }
- if (i < len1 && (str[i] == pattern[j] || pattern[j] == '.')) {
- return match(str, i + 1, len1, pattern, j + 1, len2);
- }
- return false;
-
- }
-}
-```
-
-### 测试用例
-1. 功能测试(模式字符串里包含普通字符、`.`、`*`;模式字符串和输入字符串匹配/不匹配);
-2. 特殊输入测试(输入字符串和模式字符串是空指针、空字符串)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/20_NumericStrings.md b/docs/jianzhioffer/java/20_NumericStrings.md
deleted file mode 100644
index 55fa620c8..000000000
--- a/docs/jianzhioffer/java/20_NumericStrings.md
+++ /dev/null
@@ -1,115 +0,0 @@
-## 表示数值的字符串
-
-### 题目描述
-请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。
-
-### 解法
-
-#### 解法一
-
-利用正则表达式匹配即可。
-```
-[] : 字符集合
-() : 分组
-? : 重复 0 ~ 1
-+ : 重复 1 ~ n
-* : 重复 0 ~ n
-. : 任意字符
-\\. : 转义后的 .
-\\d : 数字
-```
-
-```java
-/**
- * @author bingo
- * @since 2018/11/21
- */
-
-public class Solution {
- /**
- * 判断是否是数字
- * @param str
- * @return
- */
- public boolean isNumeric(char[] str) {
- return str != null
- && str.length != 0
- && new String(str).matches("[+-]?\\d*(\\.\\d+)?([eE][+-]?\\d+)?");
- }
-}
-```
-
-#### 解法二【剑指offer解法】
-
-表示数值的字符串遵循模式`A[.[B]][e|EC]`或者`.B[e|EC]`,其中A为数值的整数部分,B紧跟小数点为数值的小数部分,C紧跟着e或者E为数值的指数部分。上述A和C都有可能以 `+` 或者 `-` 开头的0~9的数位串,B也是0~9的数位串,但前面不能有正负号。
-
-```java
-/**
- * @author mcrwayfun
- * @version v1.0
- * @date Created in 2018/12/29
- * @description
- */
-public class Solution {
-
- private int index = 0;
-
- /**
- * 判断是否是数值
- * @param str
- * @return
- */
- public boolean isNumeric(char[] str) {
- if (str == null || str.length < 1) {
- return false;
- }
-
- // 判断是否存在整数
- boolean flag = scanInteger(str);
-
- // 小数部分
- if (index < str.length && str[index] == '.') {
- index++;
- // 小数部分可以有整数或者没有整数
- // 所以使用 ||
- flag = scanUnsignedInteger(str) || flag;
- }
-
- if (index < str.length && (str[index] == 'e' || str[index] == 'E')) {
- index++;
- // e或E前面必须有数字
- // e或者E后面必须有整数
- // 所以使用 &&
- flag = scanInteger(str) && flag;
- }
-
- return flag && index == str.length;
-
- }
-
- private boolean scanInteger(char[] str) {
- // 去除符号
- while (index < str.length && (str[index] == '+' || str[index] == '-')) {
- index++;
- }
-
- return scanUnsignedInteger(str);
- }
-
- private boolean scanUnsignedInteger(char[] str) {
- int start = index;
- while (index < str.length && str[index] >= '0' && str[index] <= '9') {
- index++;
- }
- // 判断是否存在整数
- return index > start;
- }
-}
-```
-
-
-
-### 测试用例
-
-1. 功能测试(正数或者负数;包含或者不包含整数部分的数值;包含或者不包含效数部分的值;包含或者不包含指数部分的值;各种不能表达有效数值的字符串);
-2. 特殊输入测试(输入字符串和模式字符串是空指针、空字符串)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/21_ReorderArray.md b/docs/jianzhioffer/java/21_ReorderArray.md
deleted file mode 100644
index a4730a321..000000000
--- a/docs/jianzhioffer/java/21_ReorderArray.md
+++ /dev/null
@@ -1,68 +0,0 @@
-## 调整数组顺序使奇数位于偶数前面
-
-### 题目描述
-输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
-
-### 解法
-#### 解法一
-计算出奇数的个数,就很容易写出来了。
-
-```java
-import java.util.Arrays;
-
-/**
- * @author bingo
- * @since 2018/11/21
- */
-
-public class Solution {
- /**
- * 调整数组元素顺序,使得奇数元素位于偶数元素前面,且保证奇数和奇数,偶数和偶数之间的相对位置不变。
- * @param array 数组
- */
- public void reOrderArray(int [] array) {
- if (array == null || array.length < 2) {
- return;
- }
-
- int numsOfOdd = 0;
- for (int val : array) {
- if (val % 2 == 1) {
- ++numsOfOdd;
- }
- }
- int[] bak = Arrays.copyOf(array, array.length);
- int i = 0, j = numsOfOdd;
- for (int val : bak) {
- if (val % 2 == 1) {
- array[i++] = val;
- } else {
- array[j++] = val;
- }
- }
- }
-
-}
-```
-
-#### 解法二
-```java
-import java.util.Arrays;
-
-public class Solution {
- public void reOrderArray(int [] array) {
- if (array == null || array.length < 2) {
- return;
- }
- Integer[] bak = new Integer[array.length];
- Arrays.setAll(bak, i -> array[i]);
- Arrays.sort(bak, (x, y) -> (y & 1) - (x & 1));
- Arrays.setAll(array, i -> bak[i]);
- }
-
-}
-```
-
-### 测试用例
-1. 功能测试(输入数组中的奇数、偶数交替出现;输入的数组中所有偶数都出现在奇数的前面;输入的数组中所有偶数都出现在奇数的前面;输入的数组中所有奇数都出现在偶数的前面);
-2. 特殊输入测试(输入空指针;输入的数组只包含一个数字)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/22_KthNodeFromEnd.md b/docs/jianzhioffer/java/22_KthNodeFromEnd.md
deleted file mode 100644
index 2e54c99e4..000000000
--- a/docs/jianzhioffer/java/22_KthNodeFromEnd.md
+++ /dev/null
@@ -1,61 +0,0 @@
-## 链表中倒数第k个结点
-
-### 题目描述
-输入一个链表,输出该链表中倒数第k个结点。
-
-### 解法
-pre 指针走 `k-1` 步。之后 cur 指针指向 phead,然后两个指针同时走,直至 pre 指针到达尾结点。
-
-> 当用一个指针遍历链表不能解决问题的时候,可以尝试用两个指针来遍历链表。可以让其中一个指针遍历的速度快一些。
-
-此题需要考虑一些特殊情况。比如 k 的值小于 0 或者大于链表长度。
-
-```java
-/**
- * @author bingo
- * @since 2018/11/21
- */
-
-/*
-public class ListNode {
- int val;
- ListNode next = null;
-
- ListNode(int val) {
- this.val = val;
- }
-}*/
-public class Solution {
- /**
- * 找出链表倒数第k个节点,k从1开始
- * @param head 链表头部
- * @param k 第k个节点
- * @return 倒数第k个节点
- */
- public ListNode FindKthToTail(ListNode head,int k) {
- if (head == null || k < 1) {
- return null;
- }
-
- ListNode pre = head;
- for (int i = 0; i < k - 1; ++i) {
- if (pre.next != null) {
- pre = pre.next;
- } else {
- return null;
- }
- }
-
- ListNode cur = head;
- while (pre.next != null) {
- pre = pre.next;
- cur = cur.next;
- }
- return cur;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(第 k 个节点在链表的中间/头部/尾部);
-2. 特殊输入测试(输入空指针;链表的节点总数小于 k;k=0)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/23_EntryNodeInListLoop.md b/docs/jianzhioffer/java/23_EntryNodeInListLoop.md
deleted file mode 100644
index 262cd9f58..000000000
--- a/docs/jianzhioffer/java/23_EntryNodeInListLoop.md
+++ /dev/null
@@ -1,83 +0,0 @@
-## 链表中环的入口结点
-
-### 题目描述
-给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出`null`。
-
-### 解法
-- 先利用快慢指针。若能相遇,说明存在环,且相遇点一定是在环上;若没有相遇,说明不存在环,返回 `null`。
-- 固定当前相遇点,用一个指针继续走,同时累积结点数。计算出环的结点个数 `cnt`。
-- 指针 p1 先走 `cnt` 步,p2 指向链表头部,之后 `p1`,`p2` 同时走,相遇时,相遇点一定是在环的入口处。因为 `p1` 比 `p2` 多走了环的一圈。
-
-```java
-
-/**
- * @author bingo
- * @since 2018/11/22
- */
-
-/*
- public class ListNode {
- int val;
- ListNode next = null;
-
- ListNode(int val) {
- this.val = val;
- }
-}
-*/
-public class Solution {
-
- /**
- * 求链表环的入口,若没有环,返回null
- * @param pHead 链表头
- * @return 环的入口点
- */
- public ListNode EntryNodeOfLoop(ListNode pHead) {
- if (pHead == null || pHead.next == null) {
- return null;
- }
- ListNode fast = pHead;
- ListNode slow = pHead;
- boolean flag = false;
- while (fast != null && fast.next != null) {
- slow = slow.next;
- fast = fast.next.next;
- if (fast == slow) {
- flag = true;
- break;
- }
- }
-
- // 快指针与慢指针没有相遇,说明无环,返回 null
- if (!flag) {
- return null;
- }
-
- ListNode cur = slow.next;
- // 求出环中结点个数
- int cnt = 1;
- while (cur != slow) {
- cur = cur.next;
- ++cnt;
- }
-
- // 指针p1先走cnt步
- ListNode p1 = pHead;
- for (int i = 0; i < cnt; ++i) {
- p1 = p1.next;
- }
-
- // p2指向链表头,然后p1/p2同时走,首次相遇的地方就是环的入口
- ListNode p2 = pHead;
- while (p1 != p2) {
- p1 = p1.next;
- p2 = p2.next;
- }
- return p1;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(链表中包含/不包含环;链表中有多个或者只有一个节点);
-2. 特殊输入测试(链表头节点为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/24_ReverseList.md b/docs/jianzhioffer/java/24_ReverseList.md
deleted file mode 100644
index 118d65874..000000000
--- a/docs/jianzhioffer/java/24_ReverseList.md
+++ /dev/null
@@ -1,94 +0,0 @@
-## 反转链表
-
-### 题目描述
-输入一个链表,反转链表后,输出新链表的表头。
-
-### 解法
-#### 解法一
-利用头插法解决。
-
-```java
-
-/**
- * @author bingo
- * @since 2018/11/22
- */
-
-/*
-public class ListNode {
- int val;
- ListNode next = null;
-
- ListNode(int val) {
- this.val = val;
- }
-}*/
-public class Solution {
- /**
- * 反转链表
- * @param head 链表头部
- * @return 反转后的链表
- */
- public ListNode ReverseList(ListNode head) {
- if (head == null || head.next == null) {
- return head;
- }
-
- ListNode dummy = new ListNode(-1);
- dummy.next = null;
- ListNode p1 = head;
- ListNode p2 = p1.next;
- while (p1 != null) {
- p1.next = dummy.next;
- dummy.next = p1;
- p1 = p2;
- if (p1 == null) {
- break;
- }
- p2 = p1.next;
- }
-
- return dummy.next;
- }
-}
-```
-
-#### 解法二:递归
-
-```java
-/**
- * @author bingo
- * @since 2018/11/22
- */
-
-
-/*
-public class ListNode {
- int val;
- ListNode next = null;
-
- ListNode(int val) {
- this.val = val;
- }
-}*/
-public class Solution {
- public ListNode ReverseList(ListNode head) {
- if (head == null || head.next == null) {
- return head;
- }
-
- ListNode next = ReverseList(head.next);
- ListNode cur = next;
- while (cur.next != null) {
- cur = cur.next;
- }
- cur.next = head;
- head.next = null;
- return next;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(链表中有多个结点/只有一个节点);
-2. 特殊输入测试(链表头节点为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/25_MergeSortedLists.md b/docs/jianzhioffer/java/25_MergeSortedLists.md
deleted file mode 100644
index 9bcc3c7b0..000000000
--- a/docs/jianzhioffer/java/25_MergeSortedLists.md
+++ /dev/null
@@ -1,112 +0,0 @@
-## 合并两个排序的链表
-
-### 题目描述
-输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
-
-### 解法
-#### 解法一
-同时遍历两链表进行 `merge`。
-
-```java
-
-/**
- * @author bingo
- * @since 2018/11/22
- */
-
-/*
-public class ListNode {
- int val;
- ListNode next = null;
-
- ListNode(int val) {
- this.val = val;
- }
-}*/
-public class Solution {
- /**
- * 合并两个排序链表
- * @param list1 链表1
- * @param list2 链表2
- * @return 合并后的单调不递减链表
- */
- public ListNode Merge(ListNode list1, ListNode list2) {
- if (list1 == null) {
- return list2;
- }
- if (list2 == null) {
- return list1;
- }
-
- ListNode dummy = new ListNode(-1);
- ListNode cur = dummy;
- ListNode p1 = list1;
- ListNode p2 = list2;
- while (p1 != null && p2 != null) {
- if (p1.val < p2.val) {
- ListNode t = p1.next;
- cur.next = p1;
- p1.next = null;
- p1 = t;
- } else {
- ListNode t = p2.next;
- cur.next = p2;
- p2.next = null;
- p2 = t;
- }
- cur = cur.next;
- }
-
- cur.next = p1 == null ? p2 : p1;
- return dummy.next;
-
- }
-}
-```
-
-#### 解法二:递归
-```java
-
-/**
- * @author bingo
- * @since 2018/11/22
- */
-
-/*
-public class ListNode {
- int val;
- ListNode next = null;
-
- ListNode(int val) {
- this.val = val;
- }
-}*/
-public class Solution {
- /**
- * 合并两个排序链表
- * @param list1 链表1
- * @param list2 链表2
- * @return 合并后的单调不递减链表
- */
- public ListNode Merge(ListNode list1, ListNode list2) {
- if (list1 == null) {
- return list2;
- }
- if (list2 == null) {
- return list1;
- }
-
- if (list1.val < list2.val) {
- list1.next = Merge(list1.next, list2);
- return list1;
- }
-
- list2.next = Merge(list1, list2.next);
- return list2;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入的两个链表有多个节点;节点的值互不相同或者存在值相等的多个节点);
-2. 特殊输入测试(两个链表的一个或者两个头节点为空指针;两个链表中只有一个节点)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/26_SubstructureInTree.md b/docs/jianzhioffer/java/26_SubstructureInTree.md
deleted file mode 100644
index 24b852e96..000000000
--- a/docs/jianzhioffer/java/26_SubstructureInTree.md
+++ /dev/null
@@ -1,69 +0,0 @@
-## 树的子结构
-
-### 题目描述
-输入两棵二叉树`A`,`B`,判断`B`是不是`A`的子结构。(ps:我们约定空树不是任意一个树的子结构)
-
-### 解法
-递归方式遍历:
-
-- 在树A中找到和树B的根结点值一样的结点R
-- 判断树A以R为根结点的子树是否包含与树B一样的结构
-
-这道题的time complexity应该为O(n * m),其中n为root1的节点数,m为root2的节点数。
-
-```java
-/**
-public class TreeNode {
- int val = 0;
- TreeNode left = null;
- TreeNode right = null;
-
- public TreeNode(int val) {
- this.val = val;
-
- }
-}
-*/
-
-/**
- * @author mcrwayfun
- * @version v1.0
- * @date Created in 2019/01/01
- * @description
- */
-public class Solution {
-
- public boolean HasSubtree(TreeNode root1, TreeNode root2) {
-
- if (root1 == null || root2 == null) {
- return false;
- }
-
- return isSame(root1, root2) ||
- HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2);
- }
-
- private boolean isSame(TreeNode root1, TreeNode root2) {
-
- if (root2 == null) {
- return true;
- }
-
- // 在root2,root1遍历完成后,仍未找到符合的结构,返回false
- if (root1 == null) {
- return false;
- }
-
- if (root1.val != root2.val) {
- return false;
- }
-
- return isSame(root1.left, root2.left) && isSame(root1.right, root2.right);
- }
-
-}
-```
-
-### 测试用例
-1. 功能测试(树A和树B都是普通的二叉树;树B是/不是树A的子结构);
-2. 特殊输入测试(两棵二叉树的一个或者两个根结点为空指针,二叉树的所有结点都没有左/右子树)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/27_MirrorOfBinaryTree.md b/docs/jianzhioffer/java/27_MirrorOfBinaryTree.md
deleted file mode 100644
index 8e036d5c2..000000000
--- a/docs/jianzhioffer/java/27_MirrorOfBinaryTree.md
+++ /dev/null
@@ -1,70 +0,0 @@
-## 二叉树的镜像
-
-### 题目描述
-操作给定的二叉树,将其变换为源二叉树的镜像。
-
-```
-源二叉树
- 8
- / \
- 6 10
- / \ / \
- 5 7 9 11
-
-镜像二叉树
- 8
- / \
- 10 6
- / \ / \
- 11 9 7 5
-```
-
-### 解法
-将根结点的左右孩子互换,之后递归左右孩子。
-
-```java
-
-/**
- * @author bingo
- * @since 2018/11/22
- */
-
-/*
- public class TreeNode {
- int val = 0;
- TreeNode left = null;
- TreeNode right = null;
-
- public TreeNode(int val) {
- this.val = val;
-
- }
-
- }
- */
-public class Solution {
- /**
- * 将二叉树转换为它的镜像
- * @param root 二叉树的根结点
- */
- public void Mirror(TreeNode root) {
- if (root == null || !hasChild(root)) {
- return;
- }
-
- TreeNode t = root.left;
- root.left = root.right;
- root.right = t;
- Mirror(root.left);
- Mirror(root.right);
- }
-
- private boolean hasChild(TreeNode root) {
- return root.left != null || root.right != null;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(普通的二叉树;二叉树的所有结点都没有左/右子树;只有一个结点的二叉树);
-2. 特殊输入测试(二叉树的根结点为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/28_SymmetricalBinaryTree.md b/docs/jianzhioffer/java/28_SymmetricalBinaryTree.md
deleted file mode 100644
index 6b13edefe..000000000
--- a/docs/jianzhioffer/java/28_SymmetricalBinaryTree.md
+++ /dev/null
@@ -1,58 +0,0 @@
-## 对称的二叉树
-
-### 题目描述
-请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
-
-### 解法
-比较二叉树的前序遍历序列和对称前序遍历序列是否一样,若是,说明是对称的。
-
-```java
-
-/**
- * @author bingo
- * @since 2018/11/22
- */
-
-/*
-public class TreeNode {
- int val = 0;
- TreeNode left = null;
- TreeNode right = null;
-
- public TreeNode(int val) {
- this.val = val;
-
- }
-
-}
-*/
-public class Solution {
- /**
- * 判断是否是对称二叉树
- * @param pRoot 二叉树的根结点
- * @return 是否为对称二叉树
- */
- boolean isSymmetrical(TreeNode pRoot) {
- return isSymmetrical(pRoot, pRoot);
- }
-
- private boolean isSymmetrical(TreeNode pRoot1, TreeNode pRoot2) {
- if (pRoot1 == null && pRoot2 == null) {
- return true;
- }
- if (pRoot1 == null || pRoot2 == null) {
- return false;
- }
- if (pRoot1.val != pRoot2.val) {
- return false;
- }
-
- return isSymmetrical(pRoot1.left, pRoot2.right) && isSymmetrical(pRoot1.right, pRoot2.left);
-
- }
-}
-```
-
-### 测试用例
-1. 功能测试(对称的二叉树;因结构而不对称的二叉树;结构对称但节点的值不对称的二叉树);
-2. 特殊输入测试(二叉树的根结点为空指针;只有一个节点的二叉树;所有节点的值都相同的二叉树)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/29_PrintMatrix.md b/docs/jianzhioffer/java/29_PrintMatrix.md
deleted file mode 100644
index e47e18c89..000000000
--- a/docs/jianzhioffer/java/29_PrintMatrix.md
+++ /dev/null
@@ -1,103 +0,0 @@
-## 顺时针打印矩阵
-
-### 题目描述
-输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下 `4 X 4` 矩阵:
-```
-1 2 3 4
-5 6 7 8
-9 10 11 12
-13 14 15 16
-```
-
-则依次打印出数字:
-```
-1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
-```
-### 解法
-剑指offer上的思路有点复杂,需要考虑坐标变换太多,考虑用另一种思路来解决。
-
-在矩阵中,使用左上角坐标(tR,tC)和右下角的坐标(dR,dC)就可以表示一个矩阵。比如题目中的矩阵,当(tR,tC) = (0,0)和(dR,dC) = (3,3)时,表示的子矩阵就是整个矩阵:
-
-```java
-1 2 3 4
-5 8
-9 12
-13 14 15 16
-```
-
-当外层循环遍历后,可以令tR和tC加1,dR和dC减1,执行内层循环。当左上角的坐标跑到右下角坐标的右方或者下方,则整个过程就终止。
-
-```java
-/**
- * @author mcrwayfun
- * @version 1.0
- * @description
- * @date Created in 2019/1/2
- */
-public class Solution {
- /**
- * 转圈打印矩阵
- * @param matrix 矩阵
- * @return 存放结果的list
- */
- public ArrayList printMatrix(int[][] matrix) {
- ArrayList reList = new ArrayList<>();
- if (matrix == null) {
- return reList;
- }
-
- int tR = 0;
- int tC = 0;
- int dR = matrix.length - 1;
- int dC = matrix[0].length - 1;
-
- while (tR <= dR && tC <= dC) {
- printMatrix(matrix, tR++, tC++, dR--, dC--, reList);
- }
-
- return reList;
- }
-
- public void printMatrix(int[][] matrix, int tR, int tC, int dR, int dC, ArrayList reList) {
- // 只有一行
- if (tR == dR) {
- for (int i = tC; i <= dC; i++) {
- reList.add(matrix[tR][i]);
- }
- }
- // 只有一列
- else if (tC == dC) {
- for (int i = tR; i <= dR; i++) {
- reList.add(matrix[i][tC]);
- }
- } else {
- int curR = tR;
- int curC = tC;
- // 从左到右
- while (curC != dC) {
- reList.add(matrix[tR][curC]);
- curC++;
- }
- // 从上到下
- while (curR != dR) {
- reList.add(matrix[curR][dC]);
- curR++;
- }
- // 从右到左
- while (curC != tC) {
- reList.add(matrix[dR][curC]);
- curC--;
- }
- // 从下到上
- while (curR != tR) {
- reList.add(matrix[curR][tC]);
- curR--;
- }
- }
-
- }
-}
-```
-
-### 测试用例
-1. 数组中有多行多列;数组中只有一行;数组中只有一列;数组中只有一行一列。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/30_MinInStack.md b/docs/jianzhioffer/java/30_MinInStack.md
deleted file mode 100644
index 38353b273..000000000
--- a/docs/jianzhioffer/java/30_MinInStack.md
+++ /dev/null
@@ -1,63 +0,0 @@
-## 包含min函数的栈
-
-### 题目描述
-定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为`O(1)`)。
-
-### 解法
-定义两个`stack`。
-
-压栈时,先将元素`node`压入`stack1`。然后判断`stack2`的情况:
-- `stack2`栈为空或者栈顶元素大于`node`,则将`node`压入`stack2`中。
-- `stack2`栈不为空且栈定元素小于`node`,则重复压入栈顶元素。
-
-获取最小元素时,从`stack2`中获取栈顶元素即可。
-
-```java
-import java.util.Stack;
-
-/**
- * @author bingo
- * @since 2018/11/22
- */
-
-
-public class Solution {
-
- private Stack stack1 = new Stack<>();
- private Stack stack2 = new Stack<>();
-
- /**
- * 压栈
- * @param node 待压入的元素
- */
- public void push(int node) {
- stack1.push(node);
- if (stack2.isEmpty() || stack2.peek() >= node) {
- stack2.push(node);
- } else {
- stack2.push(stack2.peek());
- }
- }
-
- public void pop() {
- stack1.pop();
- stack2.pop();
- }
-
- public int top() {
- return stack2.peek();
- }
-
- /**
- * O(1)获取栈中最小值
- * @return 最小值
- */
- public int min() {
- return stack2.peek();
- }
-}
-```
-
-### 测试用例
-1. 新压入栈的数字比之前的最小值大/小。
-2. 弹出栈的数字是/不是最小元素。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/31_StackPushPopOrder.md b/docs/jianzhioffer/java/31_StackPushPopOrder.md
deleted file mode 100644
index 3b2a5e590..000000000
--- a/docs/jianzhioffer/java/31_StackPushPopOrder.md
+++ /dev/null
@@ -1,58 +0,0 @@
-## 栈的压入、弹出序列
-
-### 题目描述
-输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列`1,2,3,4,5`是某栈的压入顺序,序列`4,5,3,2,1`是该压栈序列对应的一个弹出序列,但`4,3,5,1,2`就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
-
-### 解法
-判断下一个要弹出的元素:
-- 如果刚好是栈顶元素,直接弹出。
-- 如果不在栈顶,则把压栈序列中还没有入栈的数字压入栈,直到待弹出的数字压入栈顶。
-- 如果所有数字都压入栈顶后依然没有后找到下一个弹出的数字,则不可能是弹出序列。
-
-```java
-import java.util.Stack;
-
-/**
- * @author bingo
- * @since 2018/11/22
- */
-
-
-public class Solution {
- /**
- * 判断是否是弹出序列
- * @param pushA 压栈序列
- * @param popA 弹栈序列
- * @return 是否是弹出序列
- */
- public boolean IsPopOrder(int[] pushA,int[] popA) {
- if (pushA == null || popA == null || pushA.length != popA.length) {
- return false;
- }
-
- Stack stack = new Stack<>();
- int i = 0;
- int n = pushA.length;
- boolean flag = false;
- for (int val : popA) {
- while (stack.isEmpty() || stack.peek() != val) {
- if (i >= n) {
- flag = true;
- break;
- }
- stack.push(pushA[i++]);
- }
- if (flag) {
- break;
- }
- stack.pop();
- }
-
- return stack.isEmpty();
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入的两个数组含有多个数字或者只有一个数字:第二个数组是/不是第一个数组表示的压入序列对应的栈的弹出序列);
-2. 特殊输入测试(输入两个空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/32_01_PrintTreeFromTopToBottom.md b/docs/jianzhioffer/java/32_01_PrintTreeFromTopToBottom.md
deleted file mode 100644
index c93a997e5..000000000
--- a/docs/jianzhioffer/java/32_01_PrintTreeFromTopToBottom.md
+++ /dev/null
@@ -1,64 +0,0 @@
-## 不分行从上到下打印二叉树
-
-### 题目描述
-从上往下打印出二叉树的每个节点,同层节点从左至右打印。
-
-### 解法
-先将根节点进入队列。
-
-队头元素出队,将值存入 list,判断该元素是否有左/右子树,有的话依次进入队列中。队列为空时结束。
-
-```java
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.Queue;
-
-/**
- * @author bingo
- * @since 2018/11/23
- */
-
-/**
- public class TreeNode {
- int val = 0;
- TreeNode left = null;
- TreeNode right = null;
-
- public TreeNode(int val) {
- this.val = val;
-
- }
-
- }
- */
-public class Solution {
- /**
- * 从上到下打印二叉树
- * @param root 二叉树根节点
- * @return 结果list
- */
- public ArrayList PrintFromTopToBottom(TreeNode root) {
- ArrayList list = new ArrayList<>();
- if (root == null) {
- return list;
- }
- Queue queue = new LinkedList<>();
- queue.offer(root);
- while (!queue.isEmpty()) {
- TreeNode node = queue.poll();
- if (node.left != null) {
- queue.offer(node.left);
- }
- if (node.right != null) {
- queue.offer(node.right);
- }
- list.add(node.val);
- }
- return list;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(完全二叉树;所有节点只有左/右子树);
-2. 特殊输入测试(二叉树根节点为空指针;只有一个节点的二叉树)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/32_02_PrintTreesInLines.md b/docs/jianzhioffer/java/32_02_PrintTreesInLines.md
deleted file mode 100644
index 4904948ff..000000000
--- a/docs/jianzhioffer/java/32_02_PrintTreesInLines.md
+++ /dev/null
@@ -1,73 +0,0 @@
-## 把二叉树打印成多行
-
-### 题目描述
-从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
-
-### 解法
-与上一题类似,只不过需要用变量记录每一层要打印多少个节点。
-
-```java
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.Queue;
-
-/**
- * @author bingo
- * @since 2018/11/23
- */
-
-/*
-public class TreeNode {
- int val = 0;
- TreeNode left = null;
- TreeNode right = null;
-
- public TreeNode(int val) {
- this.val = val;
-
- }
-
-}
-*/
-public class Solution {
- /**
- * 把二叉树打印成多行
- * @param pRoot 二叉树根节点
- * @return 结果list
- */
- ArrayList > Print(TreeNode pRoot) {
- ArrayList> list = new ArrayList<>();
- if (pRoot == null) {
- return list;
- }
-
- Queue queue = new LinkedList<>();
- queue.offer(pRoot);
- int cnt = 1;
- while (cnt > 0) {
- int num = cnt;
- cnt = 0;
- ArrayList res = new ArrayList<>();
- for (int i = 0; i < num; ++i) {
- TreeNode node = queue.poll();
- if (node.left != null) {
- queue.offer(node.left);
- ++cnt;
- }
- if (node.right != null) {
- queue.offer(node.right);
- ++cnt;
- }
- res.add(node.val);
- }
- list.add(res);
- }
- return list;
- }
-
-}
-```
-
-### 测试用例
-1. 功能测试(完全二叉树;所有节点只有左/右子树);
-2. 特殊输入测试(二叉树根节点为空指针;只有一个节点的二叉树)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/32_03_PrintTreesInZigzag.md b/docs/jianzhioffer/java/32_03_PrintTreesInZigzag.md
deleted file mode 100644
index 538f10c0a..000000000
--- a/docs/jianzhioffer/java/32_03_PrintTreesInZigzag.md
+++ /dev/null
@@ -1,104 +0,0 @@
-## 按之字形打印二叉树
-
-### 题目描述
-请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
-
-如二叉树:
-```
- 1
- / \
- 2 3
- / \ / \
- 4 5 6 7
-```
-
-打印结果为:
-```
-1
-3 2
-4 5 6 7
-```
-
-### 解法
-对于上述二叉树:
-
-首先访问根结点,之后把2、3存入某结构。打印的时候,先打印3、2。这不就是栈?
-
-依次弹出栈元素,分别是3、2。弹出时需要把3、2的子结点存入结构。由于访问时顺序是`4 5 6 7`。所以也需要用栈来存放。而且,此时需要先存放右孩子,再存放左孩子。(奇数层/偶数层存放左右孩子的顺序不同)
-
-这里需要用两个栈来实现。如果只用一个栈,那么当弹出3、2 时,先将 3 的孩子节点压入栈。之后弹栈的时候不是先弹出 2,而是弹出了 3 的 孩子节点,就错了。
-
-
-```java
-import java.util.ArrayList;
-import java.util.Stack;
-
-/**
- * @author bingo
- * @since 2018/11/23
- */
-
-/*
-public class TreeNode {
- int val = 0;
- TreeNode left = null;
- TreeNode right = null;
-
- public TreeNode(int val) {
- this.val = val;
-
- }
-
-}
-*/
-public class Solution {
- /**
- * 按之字形打印二叉树
- * @param pRoot 二叉树的根节点
- * @return 结果list
- */
- public ArrayList> Print(TreeNode pRoot) {
- ArrayList> res = new ArrayList<>();
- if (pRoot == null) {
- return res;
- }
- Stack stack1 = new Stack<>();
- Stack stack2 = new Stack<>();
- stack1.push(pRoot);
- int i = 1;
- Stack stack = stack1;
- while (!stack.isEmpty()) {
- ArrayList list = new ArrayList<>();
- while (!stack.isEmpty()) {
- TreeNode node = stack.pop();
- list.add(node.val);
- if (i % 2 == 1) {
- if (node.left != null) {
- stack2.push(node.left);
- }
- if (node.right != null) {
- stack2.push(node.right);
- }
- } else {
- if (node.right != null) {
- stack1.push(node.right);
- }
- if (node.left != null) {
- stack1.push(node.left);
- }
- }
- }
- res.add(list);
- ++i;
- stack = stack1.isEmpty() ? stack2 : stack1;
- }
-
- return res;
- }
-
-}
-```
-
-### 测试用例
-1. 功能测试(完全二叉树;所有节点只有左/右子树);
-2. 特殊输入测试(二叉树根节点为空指针;只有一个节点的二叉树)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/33_SquenceOfBST.md b/docs/jianzhioffer/java/33_SquenceOfBST.md
deleted file mode 100644
index 4d99624f8..000000000
--- a/docs/jianzhioffer/java/33_SquenceOfBST.md
+++ /dev/null
@@ -1,60 +0,0 @@
-## 二叉搜索树的后序遍历序列
-
-### 题目描述
-输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出`Yes`,否则输出`No`。假设输入的数组的任意两个数字都互不相同。
-
-### 解法
-序列的最后一个元素是二叉搜索树的根节点。
-
-在序列中从左到右找到根节点的左子树(比根节点小)、右子树(比根节点大)。
-- 如果右子树中出现比根节点小的元素,那么为 false。
-- 否则递归左右子树。
-
-
-```java
-/**
- * @author bingo
- * @since 2018/11/23
- */
-
-public class Solution {
- /**
- * 判断数组是否是某个二叉搜索树的后序遍历序列
- *
- * @param sequence 数组
- * @return 是否属于某二叉搜索树的后序遍历序列
- */
- public boolean VerifySquenceOfBST(int[] sequence) {
- if (sequence == null || sequence.length < 1) {
- return false;
- }
- return verify(sequence, 0, sequence.length - 1);
- }
-
- private boolean verify(int[] sequence, int start, int end) {
- if (start >= end) {
- return true;
- }
- int val = sequence[end];
- int i = start;
- for (; i <= end; ++i) {
- if (sequence[i] >= val) {
- break;
- }
- }
-
- for (int j = i; j < end; ++j) {
- if (sequence[j] < val) {
- return false;
- }
- }
-
- return verify(sequence, start, i - 1) && verify(sequence, i, end - 1);
-
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入的后序遍历序列对应一棵二叉树,包括完全二叉树、所有节点都没有左/右子树的二叉树、只有一个节点的二叉树;输入的后续遍历序列没有对应一棵二叉树);
-2. 特殊输入测试(后序遍历序列为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/34_PathInTree.md b/docs/jianzhioffer/java/34_PathInTree.md
deleted file mode 100644
index d4dfc62a6..000000000
--- a/docs/jianzhioffer/java/34_PathInTree.md
+++ /dev/null
@@ -1,64 +0,0 @@
-## 二叉树中和为某一值的路径
-
-### 题目描述
-输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的`list`中,数组长度大的数组靠前)
-
-### 解法
-
-```java
-import java.util.ArrayList;
-
-/**
- * @author bingo
- * @since 2018/11/23
- */
-
-/**
- public class TreeNode {
- int val = 0;
- TreeNode left = null;
- TreeNode right = null;
-
- public TreeNode(int val) {
- this.val = val;
-
- }
-
- }
- */
-public class Solution {
-
- private ArrayList> res = new ArrayList<>();
-
- /**
- * 找出二叉树中和为某一值的路径(必须从根节点到叶节点)
- *
- * @param root 二叉树的根结点
- * @param target 目标值
- * @return 结果list
- */
- public ArrayList> FindPath(TreeNode root, int target) {
- findPath(root, target, new ArrayList<>());
- return res;
- }
-
- private void findPath(TreeNode root, int target, ArrayList list) {
- if (root == null) {
- return;
- }
- list.add(root.val);
- target -= root.val;
- if (target == 0 && root.left == null && root.right == null) {
- res.add(new ArrayList<>(list));
- } else {
- findPath(root.left, target, list);
- findPath(root.right, target, list);
- }
- list.remove(list.size() - 1);
- }
-}
-```
-
-### 测试用例
-1. 功能测试(二叉树中有一条、多条符合要求的路径;二叉树中没有符合要求的路径);
-2. 特殊输入测试(指向二叉树根节点的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/35_CopyComplexList.md b/docs/jianzhioffer/java/35_CopyComplexList.md
deleted file mode 100644
index 762e595c8..000000000
--- a/docs/jianzhioffer/java/35_CopyComplexList.md
+++ /dev/null
@@ -1,73 +0,0 @@
-## 复杂链表的复制
-
-### 题目描述
-输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的 `head`。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
-
-### 解法
-可以分为3步:
-
-1. 复制每个节点,并插入到被复制节点的后面。比如1->2->3 clone 1->1->2->2->3->3
-2. 复制随机节点。当遍历到的当前节点存在随机节点时,则其复制节点也应该存在随机节点。比如当前节点`cur.random != null`,则`RandomListNode clone = cur.next;clone.random = cur.random.next;`
-3. 分离两个链表。其中奇数链表为原链表,偶数链表为复制的链表
-
-这道题的time complexity为O(n)。
-
-```java
-/**
- * @author bingo
- * @since 2018/11/24
- */
-
-/*
-public class RandomListNode {
- int label;
- RandomListNode next = null;
- RandomListNode random = null;
-
- RandomListNode(int label) {
- this.label = label;
- }
-}
-*/
-public class Solution {
- /**
- * 复杂链表的复制
- * @param pHead 链表头结点
- * @return 复制的链表
- */
- public RandomListNode Clone(RandomListNode pHead) {
- if (pHead == null) {
- return null;
- }
- RandomListNode cur = pHead;
- while (cur != null) {
- RandomListNode node = new RandomListNode(cur.label);
- node.next = cur.next;
- cur.next = node;
- cur = node.next;
- }
-
- cur = pHead;
- while (cur != null) {
- RandomListNode clone = cur.next;
- if (cur.random != null) {
- clone.random = cur.random.next;
- }
- cur = clone.next;
- }
-
- cur = pHead;
- RandomListNode cloneHead = pHead.next;
- while (cur.next != null) {
- RandomListNode clone = cur.next;
- cur.next = clone.next;
- cur = clone;
- }
- return cloneHead;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(结点中的 random 指针指向结点自身;两个结点的 random 形成环状结构;链表中只有一个结点);
-2. 特殊输入测试(指向链表头结点的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/36_ConvertBinarySearchTree.md b/docs/jianzhioffer/java/36_ConvertBinarySearchTree.md
deleted file mode 100644
index d80076e29..000000000
--- a/docs/jianzhioffer/java/36_ConvertBinarySearchTree.md
+++ /dev/null
@@ -1,76 +0,0 @@
-## 二叉搜索树与双向链表
-
-### 题目描述
-输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
-
-### 解法
-由于是二叉搜索树,因此中序遍历的结果就是排序的。
-
-中序遍历利用栈来实现。遍历时,前一个结点的 right 指向后一个结点,后一个结点的 left 指向前一个结点。
-```java
-pre.right = cur
-cur.left = pre
-```
-
-```java
-import java.util.Stack;
-
-/**
- * @author bingo
- * @since 2018/11/24
- */
-
-/**
- public class TreeNode {
- int val = 0;
- TreeNode left = null;
- TreeNode right = null;
-
- public TreeNode(int val) {
- this.val = val;
-
- }
-
- }
- */
-public class Solution {
- /**
- * 将二叉搜索树转换为双向链表
- *
- * @param pRootOfTree
- * @return
- */
- public TreeNode Convert(TreeNode pRootOfTree) {
- if (pRootOfTree == null) {
- return null;
- }
- Stack stack = new Stack<>();
- TreeNode cur = pRootOfTree;
- TreeNode res = null;
- TreeNode pre = null;
- while (cur != null || !stack.isEmpty()) {
- if (cur != null) {
- stack.push(cur);
- cur = cur.left;
- } else {
- cur = stack.pop();
- if (pre == null) {
- pre = cur;
- res = pre;
- } else {
- pre.right = cur;
- cur.left = pre;
- pre = cur;
- }
- cur = cur.right;
-
- }
- }
- return res;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入的二叉树是完全二叉树;所有结点都没有左/右子树;只有一个结点的二叉树);
-2. 特殊输入测试(指向二叉树根结点的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/37_SerializeBinaryTrees.md b/docs/jianzhioffer/java/37_SerializeBinaryTrees.md
deleted file mode 100644
index e9795c2f3..000000000
--- a/docs/jianzhioffer/java/37_SerializeBinaryTrees.md
+++ /dev/null
@@ -1,89 +0,0 @@
-## 序列化二叉树
-
-### 题目描述
-请实现两个函数,分别用来序列化和反序列化二叉树。使用前序遍历实现,空节点使用字符`#` 表示。
-
-比如有如下二叉树:
-
-```java
- 1
- 2 3
- 4 # 5 6
- # # # # # #
-```
-
-序列化的结果为 `1,2,4,#,#,#,3,5,#,#,6,#,#`
-
-反序列化的结果为上述二叉树
-
-### 解法
-使用前序遍历进行序列化和反序列化。对格式没有要求,只要序列化得到的结果,再反序列化后能与原树相同即可。
-```java
-/**
- * @author mcrwayfun
- * @version 1.0
- * @description
- * @date Created in 2019/1/12
- */
-public class Solution {
-
-
- public String Serialize(TreeNode root) {
-
- StringBuilder res = new StringBuilder();
- if (root == null) {
- return res.toString();
- }
-
- serializeHelper(root, res);
- // 移除最后一个的符号","
- res.deleteCharAt(res.lastIndexOf(","));
- return res.toString();
- }
-
- private void serializeHelper(TreeNode root, StringBuilder res) {
-
- if (root == null) {
- res.append("#");
- res.append(",");
- return;
- }
-
- res.append(root.val);
- res.append(",");
- serializeHelper(root.left, res);
- serializeHelper(root.right, res);
- }
-
- private int index = -1;
-
- public TreeNode Deserialize(String str) {
-
- if (str == null || str.length() == 0) {
- return null;
- }
-
- String[] treeNodeStr = str.split(",");
- return deserializeHelper(treeNodeStr);
- }
-
- private TreeNode deserializeHelper(String[] treeNodeStr) {
-
- index++;
- TreeNode node = null;
-
- // index不越界并且当前节点不为#
- if (index < treeNodeStr.length && !"#".equals(treeNodeStr[index])) {
- node = new TreeNode(Integer.valueOf(treeNodeStr[index]));
- node.left = deserializeHelper(treeNodeStr);
- node.right = deserializeHelper(treeNodeStr);
- }
-
- return node;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入的二叉树是完全二叉树;所有节点都没有左/右子树的二叉树;只有一个节点的二叉树;所有节点的值都相同的二叉树);
-2. 特殊输入测试(指向二叉树根结点的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/38_StringPermutation.md b/docs/jianzhioffer/java/38_StringPermutation.md
deleted file mode 100644
index b603cb511..000000000
--- a/docs/jianzhioffer/java/38_StringPermutation.md
+++ /dev/null
@@ -1,74 +0,0 @@
-## 字符串的排列
-
-### 题目描述
-输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。(输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母)。ps:牛客上的测试用例对返回的list要排序。
-
-### 解法
-对整个字符串的排列可以看成两部分。第一步求所有可能出现在第一个位置的字符,即把第一个字符与后面所有非重复的字符进行交换。第二步固定第一个字符,求后面所有字符的排列;第二步中后面的所有字符又可以看成一个完整的字符,继续执行这两个步骤。
-
-注意存在重复值得情况,比如输入字符串bab,将首字符b作为固定字符串,对于将第2个下标的b换到首位仍然是bab,所有这种情况无需输出。
-
-**这道题的时间复杂度应该为O(n!)**
-
-```java
-/**
- * @author mcrwayfun
- * @version 1.0
- * @description
- * @date Created in 2019/1/14
- */
-public class Solution {
-
- public ArrayList Permutation(String str) {
-
- ArrayList reList = new ArrayList<>();
-
- if (str == null || str.length() == 0) {
- return reList;
- }
-
- char[] chars = str.toCharArray();
-
- // 递归输出字符串排列
- permutationHelper(chars, 0, reList);
- Collections.sort(reList);
- return reList;
- }
-
- private void permutationHelper(char[] chars, int index, ArrayList list) {
-
- if (index == chars.length - 1) {
- list.add(new String(chars));
- return;
- }
-
- Set set = new HashSet<>();
- // 确定交换的字符,包括自己[index,length-1]
- for (int i = index; i < chars.length; i++) {
-
- // 排除出现重复字符
- // hash表,查询花费O(1)
- if (!set.contains(chars[i])) {
- set.add(chars[i]);
- // 固定字符index
- swap(chars, i, index);
- // 递归固定剩余字符[index+1,length-1]
- permutationHelper(chars, index + 1, list);
- // 恢复原数组
- swap(chars, index, i);
- }
- }
- }
-
- private void swap(char[] chars, int x, int y) {
-
- char temp = chars[x];
- chars[x] = chars[y];
- chars[y] = temp;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入的字符串有一个或多个字符);
-2. 特殊输入测试(输入的字符串为nullptr指针或者内容为空)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/39_MoreThanHalfNumber.md b/docs/jianzhioffer/java/39_MoreThanHalfNumber.md
deleted file mode 100644
index a256e5abe..000000000
--- a/docs/jianzhioffer/java/39_MoreThanHalfNumber.md
+++ /dev/null
@@ -1,162 +0,0 @@
-## 数组中出现次数超过一半的数字
-
-### 题目描述
-数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为 9 的数组 `{1,2,3,2,2,2,5,4,2}`。由于数字 2 在数组中出现了 5 次,超过数组长度的一半,因此输出 2。如果不存在则输出 0。
-
-### 解法
-#### 解法一
-利用快排中的 partition 思想。
-
-数组中有一个数字出现次数超过了数组长度的一半,那么排序后,数组中间的数字一定就是我们要找的数字。我们随机选一个数字,利用 partition() 函数,使得比选中数字小的数字都排在它左边,比选中数字大的数字都排在它的右边。
-
-判断选中数字的下标 `index`:
-
-- 如果 `index = n/2`,那么这个数字就是中位数。
-- 如果 `index > n/2`,那么接着在 index 的左边进行 partition。
-- 如果 `index < n/2`,则在 index 的右边继续进行 partition。
-
-**注意:**这种方法会修改输入的数组。时间复杂度为 `O(n)`。
-
-```java
-/**
- * @author bingo
- * @since 2018/12/6
- */
-
-public class Solution {
- /**
- * 查找数组中出现次数超过一次的数字
- *
- * @param array 数组
- * @return 返回该数,不存在则返回0
- */
- public int MoreThanHalfNum_Solution(int[] array) {
- if (array == null || array.length == 0) {
- return 0;
- }
- int n = array.length;
- int start = 0, end = n - 1;
- int mid = n >> 1;
- int index = partition(array, start, end);
- while (index != mid) {
- if (index > mid) {
- end = index - 1;
- } else {
- start = index + 1;
- }
- index = partition(array, start, end);
- }
-
- return isMoreThanHalf(array, array[index]) ? array[index] : 0;
- }
-
- /**
- * 快排中的 partition 方法
- *
- * @param array 数组
- * @param start 开始位置
- * @param end 结束位置
- * @return
- */
- private int partition(int[] array, int start, int end) {
- int small = start - 1;
- for (int i = start; i < end; ++i) {
- if (array[i] < array[end]) {
- swap(array, i, ++small);
- }
- }
- ++small;
- swap(array, small, end);
- return small;
-
- }
-
- private void swap(int[] array, int i, int j) {
- int t = array[i];
- array[i] = array[j];
- array[j] = t;
- }
-
- /**
- * 判断val元素是否真的超过数组元素个数的一半
- *
- * @param array 数组
- * @param val 某元素
- * @return boolean
- */
- private boolean isMoreThanHalf(int[] array, int val) {
- int cnt = 0;
- for (int e : array) {
- if (e == val) {
- ++cnt;
- }
- }
-
- return cnt * 2 > array.length;
- }
-}
-```
-
-#### 解法二
-利用多数投票算法,从头到尾遍历数组,遇到两个不一样的数就把这两个数同时除去。除去的两个数可能都不是 majority,也可能一个是 majority 另一个不是,但是因为 majority 总数大于一半,所以这么删完最后剩下的肯定是 majority。
-
-此方法时间复杂度为 `O(n)`,且不会改变数组。
-
-```java
-/**
- * @author bingo
- * @since 2018/12/6
- */
-
-public class Solution {
- /**
- * 查找数组中出现次数超过一次的数字
- *
- * @param array 数组
- * @return 返回该数,不存在则返回0
- */
- public int MoreThanHalfNum_Solution(int[] array) {
- if (array == null || array.length == 0) {
- return 0;
- }
-
- int res = array[0];
- int times = 1;
- for (int i = 1; i < array.length; ++i) {
- if (times == 0) {
- res = array[i];
- times = 1;
- } else if (array[i] == res) {
- ++times;
- } else {
- --times;
- }
- }
-
- return isMoreThanHalf(array, res) ? res : 0;
- }
-
-
- /**
- * 判断val元素是否真的超过数组元素个数的一半
- *
- * @param array 数组
- * @param val 某元素
- * @return boolean
- */
- private boolean isMoreThanHalf(int[] array, int val) {
- int cnt = 0;
- for (int e : array) {
- if (e == val) {
- ++cnt;
- }
- }
-
- return cnt * 2 > array.length;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入的数组中存在/不存在一个出现次数超过数组长度一半的数字);
-2. 特殊输入测试(输入的数组只有一个数字;输入空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/40_KLeastNumbers.md b/docs/jianzhioffer/java/40_KLeastNumbers.md
deleted file mode 100644
index 645478a08..000000000
--- a/docs/jianzhioffer/java/40_KLeastNumbers.md
+++ /dev/null
@@ -1,132 +0,0 @@
-## 获取数组中最小的k个数
-
-### 题目描述
-输入 n 个整数,找出其中最小的 K 个数。例如输入 `4,5,1,6,2,7,3,8` 这 8 个数字,则最小的 4 个数字是 `1,2,3,4`。
-
-### 解法
-#### 解法一
-利用快排中的 partition 思想。
-
-数组中有一个数字出现次数超过了数组长度的一半,那么排序后,数组中间的数字一定就是我们要找的数字。我们随机选一个数字,利用 partition() 函数,使得比选中数字小的数字都排在它左边,比选中数字大的数字都排在它的右边。
-
-判断选中数字的下标 `index`:
-
-- 如果 `index = k-1`,结束循环,返回前 k 个数。
-- 如果 `index > k-1`,那么接着在 index 的左边进行 partition。
-- 如果 `index < k-1`,则在 index 的右边继续进行 partition。
-
-**注意**,这种方法会修改输入的数组。时间复杂度为 `O(n)`。
-
-```java
-import java.util.ArrayList;
-
-/**
- * @author bingo
- * @since 2018/12/6
- */
-
-public class Solution {
-
- /**
- * 获取数组中最小的k个数
- *
- * @param input 输入的数组
- * @param k 元素个数
- * @return 最小的k的数列表
- */
- public ArrayList GetLeastNumbers_Solution(int[] input, int k) {
- ArrayList res = new ArrayList<>();
- if (input == null || input.length == 0 || input.length < k || k < 1) {
- return res;
- }
- int n = input.length;
- int start = 0, end = n - 1;
- int index = partition(input, start, end);
- while (index != k - 1) {
- if (index > k - 1) {
- end = index - 1;
- } else {
- start = index + 1;
- }
- index = partition(input, start, end);
- }
- for (int i = 0; i < k; ++i) {
- res.add(input[i]);
- }
- return res;
- }
-
- private int partition(int[] input, int start, int end) {
- int index = start - 1;
- for (int i = start; i < end; ++i) {
- if (input[i] < input[end]) {
- swap(input, i, ++index);
- }
- }
- ++index;
- swap(input, index, end);
- return index;
- }
-
- private void swap(int[] array, int i, int j) {
- int t = array[i];
- array[i] = array[j];
- array[j] = t;
- }
-}
-```
-
-#### 解法二
-利用大根堆,存储最小的 k 个数,最后返回即可。
-
-此方法时间复杂度为 `O(nlogk)`。虽然慢一点,但是它不会改变输入的数组,并且它**适合海量数据的输入**。
-
-假设题目要求从海量的数据中找出最小的 k 个数,由于内存的大小是有限的,有可能不能把这些海量的数据一次性全部载入内存。这个时候,用这种方法是最合适的。就是说它适合 n 很大并且 k 较小的问题。
-
-```java
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.PriorityQueue;
-
-/**
- * @author bingo
- * @since 2018/12/6
- */
-
-public class Solution {
-
- /**
- * 获取数组中最小的k个数
- *
- * @param input 输入的数组
- * @param k 元素个数
- * @return 最小的k的数列表
- */
- public ArrayList GetLeastNumbers_Solution(int[] input, int k) {
- ArrayList res = new ArrayList<>();
- if (input == null || input.length == 0 || input.length < k || k < 1) {
- return res;
- }
-
- PriorityQueue maxHeap = new PriorityQueue<>(k, Comparator.reverseOrder());
- System.out.println(maxHeap.size());
- for (int e : input) {
- if (maxHeap.size() < k) {
- maxHeap.add(e);
- } else {
- if (maxHeap.peek() > e) {
- maxHeap.poll();
- maxHeap.add(e);
- }
-
- }
- }
- res.addAll(maxHeap);
- return res;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入的数组中存在/不存在一个出现次数超过数组长度一半的数字);
-2. 特殊输入测试(输入的数组只有一个数字;输入空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/41_StreamMedian.md b/docs/jianzhioffer/java/41_StreamMedian.md
deleted file mode 100644
index f3e3ce8ed..000000000
--- a/docs/jianzhioffer/java/41_StreamMedian.md
+++ /dev/null
@@ -1,67 +0,0 @@
-## 数据流中的中位数
-
-### 题目描述
-如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用`Insert()`方法读取数据流,使用`GetMedian()`方法获取当前读取数据的中位数。
-
-### 解法
-利用大根堆存放较小的一半元素,小根堆存放较大的一半元素。维持大小堆的元素个数差不超过 1。
-
-
-```java
-import java.util.Comparator;
-import java.util.PriorityQueue;
-
-/**
- * @author bingo
- * @since 2018/12/7
- */
-
-public class Solution {
-
- private PriorityQueue minHeap = new PriorityQueue<>();
- private PriorityQueue maxHeap = new PriorityQueue<>(Comparator.reverseOrder());
-
- /**
- * 插入一个数
- *
- * @param num 数
- */
- public void Insert(Integer num) {
-
- if (maxHeap.isEmpty() || num < maxHeap.peek()) {
- maxHeap.offer(num);
- if (maxHeap.size() - minHeap.size() > 1) {
- minHeap.offer(maxHeap.poll());
- }
-
- } else {
- minHeap.offer(num);
- if (minHeap.size() - maxHeap.size() > 1) {
- maxHeap.offer(minHeap.poll());
- }
- }
- }
-
- /**
- * 获取中位数
- *
- * @return 中位数
- */
- public Double GetMedian() {
- int size1 = maxHeap.size();
- int size2 = minHeap.size();
- if (size1 > size2) {
- return (double) maxHeap.peek();
- }
- if (size1 < size2) {
- return (double) minHeap.peek();
- }
-
- return (maxHeap.peek() + minHeap.peek()) / 2.0;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(从数据流中读出奇数/偶数个数字);
-2. 边界值测试(从数据流中读出 0/1/2 个数字)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/42_GreatestSumOfSubarrays.md b/docs/jianzhioffer/java/42_GreatestSumOfSubarrays.md
deleted file mode 100644
index e5a2d99c6..000000000
--- a/docs/jianzhioffer/java/42_GreatestSumOfSubarrays.md
+++ /dev/null
@@ -1,49 +0,0 @@
-## 连续子数组的最大和
-
-### 题目描述
-输入一个**非空**整型数组,数组里的数可能为正,也可能为负。
-数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。
-
-要求时间复杂度为`O(n)`。
-
-### 解法
-动态规划法。
-
-res[i] 表示以第 i 个数字结尾的子数组的最大和,那么求出 `max(res[i])` 即可。
-
-- `res[i] = array[i]`, if `res[i - 1] < 0`
-- `res[i] = res[i - 1] + array[i]`, if `res[i - 1] >= 0`
-
-```java
-
-/**
- * @author bingo
- * @since 2018/12/7
- */
-
-public class Solution {
- /**
- * 求连续子数组的最大和
- *
- * @param array 数组
- * @return 最大和
- */
- public int FindGreatestSumOfSubArray(int[] array) {
- int n = array.length;
- int[] res = new int[n];
- res[0] = array[0];
- int max = res[0];
- for (int i = 1; i < n; ++i) {
- res[i] = res[i - 1] > 0 ? res[i - 1] + array[i] : array[i];
- max = Math.max(max, res[i]);
- }
- return max;
- }
-}
-
-
-```
-
-### 测试用例
-1. 功能测试(输入的数组中有正数也有负数;输入的数组中全是正数;输入的数组中全是负数);
-2. 特殊输入测试(表示数组的指针位为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/43_NumberOf1.md b/docs/jianzhioffer/java/43_NumberOf1.md
deleted file mode 100644
index 27352aafc..000000000
--- a/docs/jianzhioffer/java/43_NumberOf1.md
+++ /dev/null
@@ -1,66 +0,0 @@
-## 整数中1出现的次数
-
-### 题目描述
-求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。
-
-### 解法
-- 编程之美上给出的规律:
-
- 1. 如果第i位(自右至左,从1开始标号)上的数字为0,则第i位可能出现1的次数由更高位决定(若没有高位,视高位为0),等于更高位数字X当前位数的权重10^(i-1)。
- 2. 如果第i位上的数字为1,则第i位上可能出现1的次数不仅受更高位影响,还受低位影响(若没有低位,视低位为0),等于更高位数字X当前位数的权重10^(i-1)+(低位数字+1)。
- 3. 如果第i位上的数字大于1,则第i位上可能出现1的次数仅由更高位决定(若没有高位,视高位为0),等于(更高位数字+1)X当前位数的权重10^(i-1)。
-
- 总结一下以上的算法,可以看到,当计算右数第 i 位包含的 X 的个数时:
-
- 1. 取第 i 位左边(高位)的数字,乘以 10i−1,得到**基础值** a。
- 2. 取第 i 位数字,计算**修正值**:
- 1. 如果大于 X,则结果为 a+10i−1。
- 2. 如果小于 X,则结果为 a。
- 3. 如果等 X,则取第 i 位右边(低位)数字,设为 b,最后结果为 a+b+1。
-
- 相应的代码非常简单,效率也非常高,时间复杂度只有 O(logn)。
-
-```java
-
-/**
- * @author mcrwayfun
- * @version 1.0
- * @description
- * @date Created in 2019/1/17
- */
-public class Solution {
-
- public int NumberOf1Between1AndN_Solution(int n) {
-
- if (n < 1) {
- return 0;
- }
-
- int high, low, curr, tmp, i = 1;
- high = n;
- int number = 0;
- while (high != 0) {
- // 获取第i位的高位
- high = n / (int) Math.pow(10, i);
- tmp = n % (int) Math.pow(10, i);
- // 获取第i位
- curr = tmp / (int) Math.pow(10, i - 1);
- // 获取第i位的低位
- low = tmp % (int) Math.pow(10, i - 1);
- if (curr == 1) {
- number += high * (int) Math.pow(10, i - 1) + low + 1;
- } else if (curr < 1) {
- number += high * (int) Math.pow(10, i - 1);
- } else {
- number += (high + 1) * (int) Math.pow(10, i - 1);
- }
- i++;
- }
- return number;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入1~n的数字);
-2. 特殊输入测试(输入的数字小于0)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/44_DigitsInSequence.md b/docs/jianzhioffer/java/44_DigitsInSequence.md
deleted file mode 100644
index 427f37445..000000000
--- a/docs/jianzhioffer/java/44_DigitsInSequence.md
+++ /dev/null
@@ -1,71 +0,0 @@
-## 数字序列中某一位的数字
-
-### 题目描述
-数字以 `0123456789101112131415…` 的格式序列化到一个字符序列中。
-
-在这个序列中,第 5 位(从 0 开始计数)是 5,第 13 位是 1,第 19 位是 4,等等。
-
-请写一个函数求任意位对应的数字。
-
-### 解法
-举个栗子,求序列第 1001 位。
-
-序列的前 10 位是 `0~9`, 这 10 个只有一位的数字。显然第 1001 位在这 10 个数字之后,因此这 10 个数字可以直接跳过。再从后面序列中找第 991(991=1001-10) 位的数字。接下来有 90 个两位数,共 180 位,由于 991>180,所以继续跳过。从 881 找...最后可以找到对应的数字以及数字的某一位。
-
-```java
-/**
- * @author bingo
- * @since 2018/12/7
- */
-
-public class Solution {
- /**
- * 求数字序列中某一位的数字
- *
- * @param n 第n位
- * @return 第n位的数字
- */
- public int digitAtIndex(int n) {
- if (n < 0) {
- return -1;
- }
- int digits = 1;
- while (true) {
- long numbers = countOfIntegers(digits);
- if (n < digits * numbers) {
- break;
- }
- n -= numbers * digits;
- ++digits;
- }
- return digitAtIndex(digits, n);
-
- }
-
- private long countOfIntegers(int digits) {
- return digits == 1
- ? 10
- : (int) (9 * Math.pow(10, digits - 1));
- }
-
- private int digitAtIndex(int digits, int n) {
- int beginNumber = getBeginNumber(digits);
- int val = beginNumber + n / digits;
- int indexFromRight = digits - n % digits;
- for (int i = 1; i < indexFromRight; ++i) {
- val /= 10;
- }
- return val % 10;
- }
-
- private int getBeginNumber(int digits) {
- return digits == 1
- ? 0
- : (int) Math.pow(10, digits - 1);
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入 10、190、1000);
-2. 边界值测试(输入 0、1)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/45_SortArrayForMinNumber.md b/docs/jianzhioffer/java/45_SortArrayForMinNumber.md
deleted file mode 100644
index b563cb46e..000000000
--- a/docs/jianzhioffer/java/45_SortArrayForMinNumber.md
+++ /dev/null
@@ -1,50 +0,0 @@
-## 把数组排成最小的数
-
-### 题目描述
-输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
-
-例如输入数组 `[3, 32, 321]`,则打印出这3个数字能排成的最小数字`321323`。
-
-### 解法
-
-
-```java
-import java.util.Arrays;
-
-/**
- * @author bingo
- * @since 2018/12/8
- */
-
-class Solution {
-
- /**
- * 打印数组元素组成的最小的数字
- *
- * @param nums 数组
- * @return 最小的数字
- */
- public String printMinNumber(int[] nums) {
- if (nums == null || nums.length == 0) {
- return "";
- }
- int n = nums.length;
- String[] strNums = new String[n];
- for (int i = 0; i < n; ++i) {
- strNums[i] = String.valueOf(nums[i]);
- }
-
- Arrays.sort(strNums, (o1, o2) -> (o1 + o2).compareTo(o2 + o1));
-
- StringBuilder sb = new StringBuilder();
- for (String str : strNums) {
- sb.append(str);
- }
- return sb.toString();
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入的数组中有多个数字;输入的数组中的数字有重复的数位;输入的数组中只有一个数字);
-2. 特殊输入测试(表示数组的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/46_TranslateNumbersToStrings.md b/docs/jianzhioffer/java/46_TranslateNumbersToStrings.md
deleted file mode 100644
index 759b1f9c3..000000000
--- a/docs/jianzhioffer/java/46_TranslateNumbersToStrings.md
+++ /dev/null
@@ -1,56 +0,0 @@
-## 把数字翻译成字符串
-
-### 题目描述
-给定一个数字,我们按照如下规则把它翻译为字符串:
-
-0 翻译成 ”a”,1 翻译成 ”b”,……,11 翻译成 ”l”,……,25 翻译成 ”z”。
-
-一个数字可能有多个翻译。例如 12258 有 5 种不同的翻译,它们分别是 ”bccfi”、”bwfi”、”bczi”、”mcfi”和”mzi”。
-
-请编程实现一个函数用来计算一个数字有多少种不同的翻译方法。
-
-### 解法
-先写入递推式,res 表示共有多少种翻译方法。看最后一个字符,判断它与前一个字符能否构成有效翻译,计算 res[i]:
-
-- 能,那么 `res[i] = res[i - 1] + res[i - 2]`;
-- 不能,那么 `res[i] = res[i - 1]`。
-
-
-```java
-/**
- * @author bingo
- * @since 2018/12/8
- */
-
-class Solution {
- /**
- * 获取翻译字符串的方法个数
- *
- * @param s 字符串
- * @return 个数
- */
- public int getTranslationCount(String s) {
- if (s == null || s.length() < 2) {
- return 1;
- }
- char[] chars = s.toCharArray();
- int n = chars.length;
- int[] res = new int[n];
- res[0] = 1;
- res[1] = isInRange(chars[0], chars[1]) ? 2 : 1;
- for (int i = 2; i < n; ++i) {
- res[i] = res[i - 1] + (isInRange(chars[i - 1], chars[i]) ? res[i - 2] : 0);
- }
- return res[n - 1];
- }
-
- private boolean isInRange(char a, char b) {
- int s = (a - '0') * 10 + (b -'0');
- return s >= 10 && s <= 25;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(只有一位数字;包含多位数字);
-2. 特殊输入测试(负数;0;包含 25、26 的数字)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/47_MaxValueOfGifts.md b/docs/jianzhioffer/java/47_MaxValueOfGifts.md
deleted file mode 100644
index 8af6ff5b2..000000000
--- a/docs/jianzhioffer/java/47_MaxValueOfGifts.md
+++ /dev/null
@@ -1,57 +0,0 @@
-## 礼物的最大价值
-
-### 题目描述
-在一个 `m×n` 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。
-
-你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或者向下移动一格直到到达棋盘的右下角。
-
-给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?
-
-### 解法
-写出递推式,res 表示获得的最大礼物。
-
-```java
-res[i][j] = Math.max(res[i - 1][j], res[i][j - 1]) + grid[i][j];
-```
-
-
-```java
-/**
- * @author bingo
- * @since 2018/12/8
- */
-
-class Solution {
- /**
- * 获取礼物的最大价值
- *
- * @param grid 数组
- * @return 最大价值
- */
- public int getMaxValue(int[][] grid) {
- if (grid == null || grid.length == 0) {
- return 0;
- }
- int m = grid.length;
- int n = grid[0].length;
- int[][] res = new int[m][n];
- res[0][0] = grid[0][0];
- for (int j = 1; j < n; ++j) {
- res[0][j] = res[0][j - 1] + grid[0][j];
- }
- for (int i = 1; i < m; ++i) {
- res[i][0] = res[i - 1][0] + grid[i][0];
- }
- for (int i = 1; i < m; ++i) {
- for (int j = 1; j < n; ++j) {
- res[i][j] = Math.max(res[i - 1][j], res[i][j - 1]) + grid[i][j];
- }
- }
- return res[m - 1][n - 1];
- }
-}
-```
-
-### 测试用例
-1. 功能测试(多行多列的矩阵;一行或者一列的矩阵;只有一个数字的矩阵);
-2. 特殊输入测试(指向矩阵数组的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/48_LongestSubstringWithoutDup.md b/docs/jianzhioffer/java/48_LongestSubstringWithoutDup.md
deleted file mode 100644
index 0012f287b..000000000
--- a/docs/jianzhioffer/java/48_LongestSubstringWithoutDup.md
+++ /dev/null
@@ -1,63 +0,0 @@
-## 最长不含重复字符的子字符串
-
-### 题目描述
-请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
-
-假设字符串中只包含从 `a` 到 `z`的字符。
-
-### 解法
-动态规划。
-
-`res[i]` 表示以 `s[i]` 字符结尾的最长不重复字符串的长度。判断 `s[i]`:
-- 若 `s[i]` 在前面没出现过,那么 `res[i] = res[i - 1] + 1`;
-- 若 `s[i]` 在前面有出现过,判断它上一次出现的位置 `index` 到 `i` 的距离 `d` 与 `res[i - 1]` 的大小关系:
- - 若 `d <= res[i - 1]`,说明它被包含在 `res[i - 1]` 构成的子串中,那么 `res[i] = d`;
- - 若 `d > res[i - 1]`,说明它在 `res[i - 1]` 构成的子串的左侧,那么 `res[i] = res[i - 1] + 1`。
-
-需要用一个数组 t 记录一下当前出现的字符在哪个位置。
-
-```java
-/**
- * @author bingo
- * @since 2018/12/8
- */
-
-class Solution {
- /**
- * 最长不含重复字符的子字符串
- *
- * @param s 字符串
- * @return 最长不重复字符子串
- */
- public int longestSubstringWithoutDuplication(String s) {
- if (s == null || s.length() == 0) {
- return 0;
- }
- char[] chars = s.toCharArray();
- int[] t = new int[26];
- for (int i = 0; i < 26; ++i) {
- t[i] = -1;
- }
- t[chars[0] - 'a'] = 0;
- int n = chars.length;
- int[] res = new int[n];
- res[0] = 1;
- int max = res[0];
- for (int i = 1; i < n; ++i) {
- int index = t[chars[i] - 'a'];
- int d = i - index;
- res[i] = (index == -1 || d > res[i - 1])
- ? res[i - 1] + 1
- : d;
-
- t[chars[i] - 'a'] = i;
- max = Math.max(max, res[i]);
- }
- return max;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(包含多个字符的字符串;只有一个字符的字符串;所有字符都唯一的字符串;所有字符都相同的字符串);
-2. 特殊输入测试(空字符串)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/49_UglyNumber.md b/docs/jianzhioffer/java/49_UglyNumber.md
deleted file mode 100644
index bec37fd34..000000000
--- a/docs/jianzhioffer/java/49_UglyNumber.md
+++ /dev/null
@@ -1,106 +0,0 @@
-## 丑数
-
-### 题目描述
-把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
-
-### 解法1
-由题目可以得知,丑数必定可以整除2、3或者5(除了丑数1之外),也就是说,如果一个数能够被2整除,就连续除以2;能够被3整除,就连续除以3;能够被5整除,就连续除以5;如果最后得到1,那么这个数便是丑数。因此我们可以使用暴力的方式遍历到第N个丑数。
-
-该解法的time complexity为O(count),比如第1500个丑数为859963392,那么就需要枚举1到859963392
-
-```java
-/**
- * @author mcrwayfun
- * @version v1.0
- * @date Created in 2019/01/23
- * @description
- */
-public class Solution {
-
- private boolean isUgly(int number){
- if(number % 2 == 0)
- number /= 2;
- if(number % 3 == 0)
- number /= 3;
- if(number % 5 == 0)
- number /= 5;
- return number == 1;
- }
-
- public int GetUglyNumber_Solution(int index){
- if(index <= 0)
- return 0;
-
- int number = 0;
- int count = 0;
- while(count < index){
- number++;
- if(isUgly(number)){
- count++;
- }
- }
-
- return number;
- }
-}
-```
-
-### 解法2
-
-把15以内的丑数列出来:`1、2、3、4、5、6、8、9、10、12、15` ,你会发现新丑数必定是旧丑数乘以因子2、3或者5得来的。所以可以使用一个list来存储已经出现的丑数以此来计算出新的丑数,从而避免对非丑数的计算。
-
-通过维护3个下标i2,i3,i5和它们对应的值m2,m3,m5,每次向list中添加的为m2,m3,m5中的最小值,以此来维护list的有序性。
-
-该解法的time complexity为O(n),space complexity为O(n),属于典型的用空间换时间的解决方法。
-
-```java
-/**
- * @author mcrwayfun
- * @version v1.0
- * @date Created in 2019/01/23
- * @description
- */
-public class Solution {
-
- public int GetUglyNumber_Solution(int index) {
-
- if (index <= 0)
- return 0;
-
- List reList = new ArrayList<>();
- // 第一个丑数为1
- reList.add(1);
- int i2 = 0, i3 = 0, i5 = 0;
- while (reList.size() < index) {
-
- int m2 = reList.get(i2) * 2;
- int m3 = reList.get(i3) * 3;
- int m5 = reList.get(i5) * 5;
-
- // 求出m2、m3、m5中的最小值,该值为加入list的丑数
- int min = Math.min(m2, Math.min(m3, m5));
-
- if (m2 == min) {
- i2++;
- }
- if (m3 == min) {
- i3++;
- }
- if (m5 == min) {
- i5++;
- }
-
- reList.add(min);
- }
-
- // O(1)
- return reList.get(reList.size() - 1);
- }
-}
-```
-
-### 测试用例
-
-1. 功能测试(输入2、3、4、5、6等)。
-2. 特殊输入测试(边界值1;无效输入0)。
-3. 性能测试(输入较大的数字,比如1500)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/50_01_FirstNotRepeatingChar.md b/docs/jianzhioffer/java/50_01_FirstNotRepeatingChar.md
deleted file mode 100644
index ebf2baeb5..000000000
--- a/docs/jianzhioffer/java/50_01_FirstNotRepeatingChar.md
+++ /dev/null
@@ -1,43 +0,0 @@
-## 第一个只出现一次的字符
-
-### 题目描述
-在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).
-
-### 解法1
-使用HashMap来统计字符出现的次数,因为字符的多少是固定的(大小写字母一共52个),所以可以认为使用HashMap的空间复杂度为O(1)。该解法时间复杂度为O(n)。
-
-```java
-/**
- * @author mcrwayfun
- * @version v1.0
- * @date Created in 2019/01/24
- * @description
- */
-public class Solution {
-
- public int FirstNotRepeatingChar(String str) {
-
- if (str == null || str.length() == 0) {
- return -1;
- }
-
- Map characterMap = new HashMap<>();
- // hashMap is HashTable,search cost O(1)
- for (int i = 0; i < str.length(); i++) {
- characterMap.put(str.charAt(i), characterMap.getOrDefault(str.charAt(i), 0) + 1);
- }
-
- for (int i = 0; i < str.length(); i++) {
- if (characterMap.get(str.charAt(i)) == 1) {
- return i;
- }
- }
-
- return -1;
- }
-}
-```
-### 测试用例
-
-1. 功能测试(字符串中仅存在只出现一次的字符;字符串中不存在只出现一次的字符;字符串中所有字符都只出现一次)。
-2. 特殊输入测试(字符串为null)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/50_02_FristCharacterInStream.md b/docs/jianzhioffer/java/50_02_FristCharacterInStream.md
deleted file mode 100644
index 2d67dbcca..000000000
--- a/docs/jianzhioffer/java/50_02_FristCharacterInStream.md
+++ /dev/null
@@ -1,45 +0,0 @@
-## 字符流中第一个不重复的字符
-
-### 题目描述
-
-请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。如果当前字符流没有存在出现一次的字符,返回#字符。
-
-
-### 解法1
-与上一道题的思路是一致的。
-
-```java
-/**
- * @author mcrwayfun
- * @version v1.0
- * @date Created in 2019/01/25
- * @description
- */
-public class Solution {
-
- private StringBuilder res = new StringBuilder();
- private Map characterMap = new HashMap<>();
-
- // Insert one char from stringstream
- public void Insert(char ch) {
- res.append(ch);
- characterMap.put(ch, characterMap.getOrDefault(ch, 0) + 1);
- }
-
- // return the first appearence once char in current stringstream
- public char FirstAppearingOnce() {
-
- for (char c : res.toString().toCharArray()) {
- if (characterMap.get(c) == 1) {
- return c;
- }
- }
-
- return '#';
- }
-}
-```
-### 测试用例
-
-1. 功能测试(读入一个字符;读入多个字符;读入的所有字符都是唯一的;读入的所有字符都是重复出现的)。
-2. 特殊输入测试(读入0个字符)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/52_FirstCommonNodesInLists.md b/docs/jianzhioffer/java/52_FirstCommonNodesInLists.md
deleted file mode 100644
index 78fe0068b..000000000
--- a/docs/jianzhioffer/java/52_FirstCommonNodesInLists.md
+++ /dev/null
@@ -1,86 +0,0 @@
-## 两个链表的第一个公共结点
-
-### 题目描述
-输入两个链表,找出它们的第一个公共结点。
-
-**样例**
-```
-给出两个链表如下所示:
-A: a1 → a2
- ↘
- c1 → c2 → c3
- ↗
-B: b1 → b2 → b3
-
-输出第一个公共节点c1
-```
-
-### 解法
-先遍历两链表,求出两链表的长度,再求长度差 `|n1 - n2|`。
-
-较长的链表先走 `|n1 - n2|` 步,之后两链表再同时走,首次相遇时的节点即为两链表的第一个公共节点。
-
-
-```java
-/**
- * @author bingo
- * @since 2018/12/8
- */
-
-/**
- * Definition for singly-linked list.
- * public class ListNode {
- * int val;
- * ListNode next;
- * ListNode(int x) {
- * val = x;
- * next = null;
- * }
- * }
- */
-class Solution {
-
- /**
- * 求两链表第一个公共节点
- *
- * @param headA 链表A
- * @param headB 链表B
- * @return 第一个公共节点
- */
- public ListNode findFirstCommonNode(ListNode headA, ListNode headB) {
- if (headA == null || headB == null) {
- return null;
- }
- int n1 = len(headA), n2 = len(headB);
- ListNode p1 = headA, p2 = headB;
- if (n1 > n2) {
- for (int i = 0; i < n1 - n2; ++i) {
- p1 = p1.next;
- }
- } else if (n1 < n2) {
- for (int i = 0; i < n2 - n1; ++i) {
- p2 = p2.next;
- }
- }
- while (p1 != p2 && p1 != null && p2 != null) {
- p1 = p1.next;
- p2 = p2.next;
- }
- return (p1 == null || p2 == null) ? null : p1;
- }
-
- private int len(ListNode head) {
- int n = 0;
- ListNode cur = head;
- while (cur != null) {
- ++n;
- cur = cur.next;
- }
- return n;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入的两个链表有公共节点;第一个公共节点在链表的中间,第一个公共节点在链表的末尾,第一个公共节点是链表的头节点;输入的两个链表没有公共节点);
-2. 特殊输入测试(输入的链表头节点是空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/53_01_NumberOfK.md b/docs/jianzhioffer/java/53_01_NumberOfK.md
deleted file mode 100644
index 76cb7d228..000000000
--- a/docs/jianzhioffer/java/53_01_NumberOfK.md
+++ /dev/null
@@ -1,99 +0,0 @@
-## 数字在排序数组中出现的次数
-
-### 题目描述
-统计一个数字在排序数组中出现的次数。
-
-例如输入排序数组 `[1, 2, 3, 3, 3, 3, 4, 5]` 和数字 3,由于 3 在这个数组中出现了 4 次,因此输出 4。
-
-**样例**
-
-```
-输入:[1, 2, 3, 3, 3, 3, 4, 5] , 3
-
-输出:4
-```
-
-### 解法
-找出第一个 k 和最后一个 k 出现的位置。
-
-找第一个 k 时,利用二分法,如果 `nums[m] == k`,判断它的前一个位置是不是也是 k,如果不是,说明这是第一个 k,直接返回。如果是,那么递归在左边查找第一个 k。
-
-找最后一个 k 也同理。
-
-
-```java
-/**
- * @author bingo
- * @since 2018/12/8
- */
-
-class Solution {
- /**
- * 求数字k在排序数组中出现的次数
- *
- * @param nums 数组
- * @param k 数字k
- * @return k在数组中出现的次数
- */
- public int getNumberOfK(int[] nums, int k) {
- if (nums == null || nums.length == 0) {
- return 0;
- }
- int start = 0, end = nums.length - 1;
- int first = getFirstK(nums, start, end, k);
- int last = getLastK(nums, start, end, k);
- if (first > -1 && last > -1) {
- return last - first + 1;
- }
- return 0;
- }
-
- private int getFirstK(int[] nums, int start, int end, int k) {
- if (start > end) {
- return -1;
- }
- int m = start + ((end - start) >> 1);
- if (nums[m] == k) {
- if (m == 0 || (m > 0 && nums[m - 1] != k)) {
- return m;
- } else {
- end = m - 1;
- }
- } else {
- if (nums[m] > k) {
- end = m - 1;
- } else {
- start = m + 1;
- }
- }
- return getFirstK(nums, start, end, k);
- }
-
- private int getLastK(int[] nums, int start, int end, int k) {
- if (start > end) {
- return -1;
- }
- int m = start + ((end - start) >> 1);
- if (nums[m] == k) {
- if (m == nums.length - 1 || (m < nums.length - 1 && nums[m + 1] != k)) {
- return m;
- } else {
- start = m + 1;
- }
- } else {
- if (nums[m] > k) {
- end = m - 1;
- } else {
- start = m + 1;
- }
- }
- return getLastK(nums, start, end, k);
-
- }
-}
-```
-
-### 测试用例
-1. 功能测试(数组中包含要查找的数字;数组中没有要查找的数字;要查找的数字在数组中出现一次/多次);
-2. 边界值测试(查找数组中的最大值、最小值;数组中只有一个数字);
-3. 特殊输入测试(表示数组的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/53_02_MissingNumber.md b/docs/jianzhioffer/java/53_02_MissingNumber.md
deleted file mode 100644
index ab3f8db5b..000000000
--- a/docs/jianzhioffer/java/53_02_MissingNumber.md
+++ /dev/null
@@ -1,62 +0,0 @@
-## 0到n-1中缺失的数字
-
-### 题目描述
-一个长度为 `n-1` 的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围 `0` 到 `n-1` 之内。
-
-在范围 `0` 到 `n-1` 的 `n` 个数字中有且只有一个数字不在该数组中,请找出这个数字。
-
-**样例**
-```
-输入:[0,1,2,4]
-
-输出:3
-```
-
-### 解法
-找出第一个与下标不对应的数字即可。
-
-特殊情况:
-- 下标都对应,那么应该返回 `最后一个数+1`;
-- 缺失的数字是第一个,那么返回 0。
-
-
-```java
-/**
- * @author bingo
- * @since 2018/12/8
- */
-
-class Solution {
- /**
- * 获取0~n-1缺失的数字
- *
- * @param nums 数组
- * @return 缺失的数字
- */
- public int getMissingNumber(int[] nums) {
- if (nums == null || nums.length == 0) {
- return 0;
- }
- int n = nums.length;
- int start = 0, end = n - 1;
- while (start <= end) {
- int mid = start + ((end - start) >> 1);
- if (nums[mid] != mid) {
- if (mid == 0 || nums[mid - 1] == mid - 1) {
- return mid;
- }
- end = mid - 1;
- } else {
- start = mid + 1;
- }
- }
- return start == n ? n : -1;
-
- }
-}
-```
-
-### 测试用例
-1. 功能测试(缺失的数字位于数组的开始、中间或者末尾);
-2. 边界值测试(数组中只有一个数字 0);
-3. 特殊输入测试(表示数组的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/53_03_IntegerIdenticalToIndex.md b/docs/jianzhioffer/java/53_03_IntegerIdenticalToIndex.md
deleted file mode 100644
index 6ea63a4a4..000000000
--- a/docs/jianzhioffer/java/53_03_IntegerIdenticalToIndex.md
+++ /dev/null
@@ -1,63 +0,0 @@
-## 数组中数值和下标相等的元素
-
-### 题目描述
-假设一个单调递增的数组里的每个元素都是整数并且是唯一的。
-
-请编程实现一个函数找出数组中任意一个数值等于其下标的元素。
-
-例如,在数组 `[-3, -1, 1, 3, 5]` 中,数字 3 和它的下标相等。
-
-**样例**
-```
-输入:[-3, -1, 1, 3, 5]
-
-输出:3
-```
-
-**注意**:如果不存在,则返回 -1。
-
-### 解法
-二分法查找。
-- 当前元素等于对应的下标,直接返回该下标;
-- 当前元素大于该下标,在左边查找;
-- 当前元素小于该下标,在右边查找。
-
-
-```java
-/**
- * @author bingo
- * @since 2018/12/10
- */
-
-class Solution {
- /**
- * 找出单调递增数组中数值和下标相等的元素
- *
- * @param nums 数组
- * @return 数值与下标相等的元素
- */
- public int getNumberSameAsIndex(int[] nums) {
- if (nums == null || nums.length == 0) {
- return -1;
- }
- int start = 0, end = nums.length - 1;
- while (start <= end) {
- int mid = start + ((end - start) >> 1);
- if (nums[mid] == mid) {
- return mid;
- }
- if (nums[mid] < mid) {
- start = mid + 1;
- } else {
- end = mid - 1;
- }
- }
- return -1;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(数组中包含或者不包含数值和下标相等的元素);
-2. 边界值测试(数组中只有一个数字;数值和下标相等的元素位于数组的开头或者结尾);
-3. 特殊输入测试(表示数组的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/54_KthNodeInBST.md b/docs/jianzhioffer/java/54_KthNodeInBST.md
deleted file mode 100644
index be0bc7996..000000000
--- a/docs/jianzhioffer/java/54_KthNodeInBST.md
+++ /dev/null
@@ -1,54 +0,0 @@
-## 二叉搜索树的第k个结点
-
-### 题目描述
-给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4
-
-### 解法
-因为BST的中序遍历得到的是一个升序的列表,所以在进行中序遍历行进行判断即可。所以该算法的时间复杂度为O(logn)
-
-
-```java
-/**
- * @author mcrwayfun
- * @version 1.0
- * @description
- * @date Created in 2019/1/28
- */
-class Solution {
-
- private int count = 0;
-
- public TreeNode KthNode(TreeNode pRoot, int k) {
-
- if (pRoot == null || k == 0) {
- return null;
- }
-
- // 左递归
- TreeNode retNode = KthNode(pRoot.left, k);
-
- if (retNode != null) {
- return retNode;
- }
-
- // 符合条件则返回
- count++;
- if (count == k) {
- return pRoot;
- }
-
- // 右递归
- retNode = KthNode(pRoot.right, k);
- if (retNode != null) {
- return retNode;
- }
-
- return null;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(各种形态不同的二叉搜索树);
-2. 边界值测试(输入k为0、1、二叉搜索树的结点数、二叉搜索树的结点数+1);
-3. 特殊输入测试(指向二叉搜索树的节点的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/55_01_TreeDepth.md b/docs/jianzhioffer/java/55_01_TreeDepth.md
deleted file mode 100644
index 99797309c..000000000
--- a/docs/jianzhioffer/java/55_01_TreeDepth.md
+++ /dev/null
@@ -1,59 +0,0 @@
-## 二叉树的深度
-
-### 题目描述
-输入一棵二叉树的根结点,求该树的深度。
-
-从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
-
-**样例**
-```
-输入:二叉树[8, 12, 2, null, null, 6, 4, null, null, null, null]如下图所示:
- 8
- / \
- 12 2
- / \
- 6 4
-
-输出:3
-```
-
-### 解法
-递归即可。
-
-
-```java
-/**
- * @author bingo
- * @since 2018/12/10
- */
-
-/**
- * Definition for a binary tree node.
- * public class TreeNode {
- * int val;
- * TreeNode left;
- * TreeNode right;
- * TreeNode(int x) { val = x; }
- * }
- */
-class Solution {
- /**
- * 求二叉树的深度
- *
- * @param root 二叉树根结点
- * @return 深度
- */
- public int treeDepth(TreeNode root) {
- if (root == null) {
- return 0;
- }
- int lDepth = treeDepth(root.left);
- int rDepth = treeDepth(root.right);
- return 1 + Math.max(lDepth, rDepth);
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入普通的二叉树;二叉树中所有节点都没有左/右子树);
-2. 特殊输入测试(二叉树只有一个节点;二叉树的头节点为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/55_02_BalancedBinaryTree.md b/docs/jianzhioffer/java/55_02_BalancedBinaryTree.md
deleted file mode 100644
index 521e1ceb7..000000000
--- a/docs/jianzhioffer/java/55_02_BalancedBinaryTree.md
+++ /dev/null
@@ -1,127 +0,0 @@
-## 平衡二叉树
-
-### 题目描述
-输入一棵二叉树的根结点,判断该树是不是平衡二叉树。
-
-如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
-
-**注意:**
-
-- 规定空树也是一棵平衡二叉树。
-
-**样例**
-```
-输入:二叉树[5,7,11,null,null,12,9,null,null,null,null]如下所示,
- 5
- / \
- 7 11
- / \
- 12 9
-
-输出:true
-```
-
-### 解法
-#### 解法一
-求每个节点左右孩子的深度,判断该节点是否平衡。
-
-这种方法需要重复遍历节点多次,不推荐。
-
-
-```java
-/**
- * @author bingo
- * @since 2018/12/10
- */
-
-/**
- * Definition for a binary tree node.
- * public class TreeNode {
- * int val;
- * TreeNode left;
- * TreeNode right;
- * TreeNode(int x) { val = x; }
- * }
- */
-class Solution {
- /**
- * 判断是否是平衡二叉树
- *
- * @param root 二叉树根结点
- * @return 是否是平衡二叉树
- */
- public boolean isBalanced(TreeNode root) {
- if (root == null) {
- return true;
- }
- if (Math.abs(treeDepth(root.left) - treeDepth(root.right)) > 1) {
- return false;
- }
- return isBalanced(root.left) && isBalanced(root.right);
- }
-
- private int treeDepth(TreeNode root) {
- if (root == null) {
- return 0;
- }
- int lDepth = treeDepth(root.left);
- int rDepth = treeDepth(root.right);
- return 1 + Math.max(lDepth, rDepth);
- }
-}
-```
-
-#### 解法二
-
-```java
-/**
- * @author bingo
- * @since 2018/12/10
- */
-
-/**
- * Definition for a binary tree node.
- * public class TreeNode {
- * int val;
- * TreeNode left;
- * TreeNode right;
- * TreeNode(int x) { val = x; }
- * }
- */
-class Solution {
- private boolean isBalanced;
-
- /**
- * 判断是否是平衡二叉树
- *
- * @param root 二叉树根结点
- * @return 是否是平衡二叉树
- */
- public boolean isBalanced(TreeNode root) {
- if (root == null) {
- return true;
- }
- isBalanced = true;
- treeDepth(root);
- return isBalanced;
- }
-
- private int treeDepth(TreeNode root) {
- if (root == null || !isBalanced) {
- return 0;
- }
- int lDepth = treeDepth(root.left);
- int rDepth = treeDepth(root.right);
- if (Math.abs(lDepth - rDepth) > 1) {
- isBalanced = false;
- }
- return 1 + Math.max(lDepth, rDepth);
-
- }
-}
-```
-
-
-### 测试用例
-1. 功能测试(平衡的二叉树;不是平衡的二叉树;二叉树中所有节点都没有左/右子树);
-2. 特殊输入测试(二叉树只有一个节点;二叉树的头节点为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/56_01_NumbersAppearOnce.md b/docs/jianzhioffer/java/56_01_NumbersAppearOnce.md
deleted file mode 100644
index 1576feee2..000000000
--- a/docs/jianzhioffer/java/56_01_NumbersAppearOnce.md
+++ /dev/null
@@ -1,77 +0,0 @@
-## 数组中只出现一次的两个数字
-
-### 题目描述
-一个整型数组里除了两个数字之外,其他的数字都出现了两次。
-
-请写程序找出这两个只出现一次的数字。
-
-你可以假设这两个数字一定存在。
-
-**样例**
-```
-输入:[1,2,3,3,4,4]
-
-输出:[1,2]
-```
-
-### 解法
-如果数组有一个数字出现一次,其它数字都出现两次。那么我们很容易通过异或 `^` 运算求出来。
-
-而现在是有两个数字出现一次,那么我们考虑一下怎么将这两个数字隔开,之后我们对隔开的数组分别进行异或,不就求出来了?
-
-我们先异或,求得的结果是两个不相同的数字异或的结果,结果一定不为 0。那么它的二进制表示中一定有 1。我们根据这个 1 在二进制中出现的位置。将数组划分,这样,两个只出现一次的数字就会被隔开,之后求异或即可。
-
-```java
-/**
- * @author bingo
- * @since 2018/12/10
- */
-
-class Solution {
- /**
- * 求数组中只出现一次的两个数字
- *
- * @param nums 数字
- * @return 两个数字组成的数组
- */
- public int[] findNumsAppearOnce(int[] nums) {
- if (nums == null || nums.length < 2) {
- return null;
- }
- int xorRes = 0;
- for (int e : nums) {
- xorRes ^= e;
- }
- int[] res = new int[2];
- int index = indexOf1(xorRes);
- for (int e : nums) {
- if (isBit1(e, index)) {
- res[0] ^= e;
- } else {
- res[1] ^= e;
- }
- }
- return res;
-
-
- }
-
- private int indexOf1(int val) {
- int index = 0;
- while ((val & 1) == 0) {
- val = val >> 1;
- ++index;
- }
- return index;
- }
-
- private boolean isBit1(int val, int index) {
- val = val >> index;
- return (val & 1) == 1;
- }
-}
-```
-
-
-### 测试用例
-1. 功能测试(数组中有多对重复的数字;数组中没有重复的数字)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/56_02_NumberAppearingOnce.md b/docs/jianzhioffer/java/56_02_NumberAppearingOnce.md
deleted file mode 100644
index f6e101c3c..000000000
--- a/docs/jianzhioffer/java/56_02_NumberAppearingOnce.md
+++ /dev/null
@@ -1,55 +0,0 @@
-## 数组中唯一只出现一次的数字
-
-### 题目描述
-在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。
-
-请找出那个只出现一次的数字。
-
-你可以假设满足条件的数字一定存在。
-
-**思考题:**
-
-- 如果要求只使用 `O(n)` 的时间和额外 `O(1)` 的空间,该怎么做呢?
-
-### 解法
-分别累加数组中每个元素的二进制中出现的数字,那么出现三次的数字,二进制位上最后累加的结果一定能被 3 整除。不能被 3 整除的位,就属于只出现一次的数字。
-
-```java
-/**
- * @author bingo
- * @since 2018/12/10
- */
-
-class Solution {
- /**
- * 找出数组中只出现一次的数字,其它数字都出现三次
- *
- * @param nums 数字
- * @return 只出现一次的数字
- */
- public int findNumberAppearingOnce(int[] nums) {
- if (nums == null || nums.length == 0) {
- return 0;
- }
- int[] bits = new int[32];
- int n = nums.length;
- for (int i = 0; i < n; ++i) {
- int val = nums[i];
- for (int j = 0; j < 32; ++j) {
- bits[j] += (val & 1);
- val = val >> 1;
- }
- }
- int res = 0;
- for (int i = 0; i < 32; ++i) {
- if (bits[i] % 3 != 0) {
- res += Math.pow(2, i);
- }
- }
- return res;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(唯一只出现一次的数字分别是 0、正数、负数;重复出现三次的数字分别是 0、正数、负数)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/57_01_TwoNumbersWithSum.md b/docs/jianzhioffer/java/57_01_TwoNumbersWithSum.md
deleted file mode 100644
index 0b4770178..000000000
--- a/docs/jianzhioffer/java/57_01_TwoNumbersWithSum.md
+++ /dev/null
@@ -1,55 +0,0 @@
-## 和为S的两个数字
-
-### 题目描述
-输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。ps:对应每个测试案例,输出两个数,小的先输出。
-
-### 解法
-定义两个指针,start指向数组头,end指向数组末尾。如果:
-
-- `sum == array[start] + array[end]`,则返回结果
-- `sum > array[start] + array[end]`,则start++,因为数组是递增的,所以从小数右边找一个大数与 `array[end]` 求和再次判断
-- 否则 end--
-
-```java
-/**
- * @author mcrwayfun
- * @version v1.0
- * @date Created in 2019/02/02
- * @description
- */
-public class Solution {
-
- public ArrayList FindNumbersWithSum(int[] array, int sum) {
-
- ArrayList reList = new ArrayList<>();
-
- if (array == null || array.length < 2 || sum <= array[0]) {
- return reList;
- }
-
- int start = 0;
- int end = array.length - 1;
-
- while (start < end) {
-
- int curSum = array[start] + array[end];
- if (curSum == sum) {
- reList.add(array[start]);
- reList.add(array[end]);
- return reList;
- } else if (curSum < sum) {
- start++;
- } else {
- end--;
- }
- }
-
- // 查无
- return reList;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(数组中存在和为 s 的两个数;数组中不存在和为 s 的两个数);
-2. 特殊输入测试(表示数组的指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/57_02_ContinuousSquenceWithSum.md b/docs/jianzhioffer/java/57_02_ContinuousSquenceWithSum.md
deleted file mode 100644
index c837b5875..000000000
--- a/docs/jianzhioffer/java/57_02_ContinuousSquenceWithSum.md
+++ /dev/null
@@ -1,77 +0,0 @@
-## 和为S的连续正数序列
-
-### 题目描述
-输入一个正数 s,打印出所有和为 s 的连续正数序列(至少含有两个数)。
-
-例如输入 15,由于 `1+2+3+4+5=4+5+6=7+8=15`,所以结果打印出 3 个连续序列 1~5、4~6 和 7~8。
-
-**样例**
-```
-输入:15
-
-输出:[[1,2,3,4,5],[4,5,6],[7,8]]
-```
-
-### 解法
-这道题同样利用两个指针left和right,将(1,2)作为初始序列。当序列和大于所求值,则left向前走,把最小的数排除了;当序列和小于所求值,则right向前走,把一个更大的数包进序列中;如果序列和等于所求值,则求值区间[left,right]中的所有数并加入到列表中,并且right向前走,把一个更大的值包入序列中。循环直到 `left < (sum + 1)/2` 。
-
-这道题的time complexity为O(n^2),space complexity为O(1)
-
-```java
-/**
- * @author mcrwayfun
- * @version v1.0
- * @date Created in 2019/02/03
- * @description
- */
-public class Solution {
-
- public List> findContinuousSequence(int sum) {
-
- List> reList = new ArrayList<>();
-
- if (sum < 3) {
- return reList;
- }
-
- int left = 1;
- int right = 2;
- int mid = (sum + 1) / 2;
- int curSum = left + right;
-
- // left小于sum一半即可(1/2n)
- while (left < mid) {
-
- // 等与sum则加入列表中(2~1/2n)
- if (curSum == sum) {
- reList.add(getListFromleftToright(left, right));
- // right增加并重新寻找序列
- right++;
- curSum += right;
- } else if (curSum > sum) {
- curSum -= left;
- left++;
- } else {
- right++;
- curSum += right;
- }
- }
-
- return reList;
- }
-
- private List getListFromleftToright(int left, int right) {
-
- List tempList = new ArrayList<>();
- for (int i = left; i <= right; i++) {
- tempList.add(i);
- }
-
- return tempList;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(存在和为 s 的连续序列,如 9、100 等;不存在和为 s 的连续序列,如 4、0 等);
-2. 边界值测试(连续序列的最小和 3)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/58_01_ReverseWordsInSentence.md b/docs/jianzhioffer/java/58_01_ReverseWordsInSentence.md
deleted file mode 100644
index 87f557479..000000000
--- a/docs/jianzhioffer/java/58_01_ReverseWordsInSentence.md
+++ /dev/null
@@ -1,55 +0,0 @@
-## 翻转单词顺序
-
-### 题目描述
-输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
-
-为简单起见,标点符号和普通字母一样处理。
-
-例如输入字符串 `"I am a student."`,则输出 `"student. a am I"`。
-
-**样例**
-```
-输入:"I am a student."
-
-输出:"student. a am I"
-```
-
-### 解法
-先对字符串按空格切割成数组,再逆序数组后,最后将元素拼接并返回。
-
-```java
-/**
- * @author bingo
- * @since 2018/12/12
- */
-
-class Solution {
- /**
- * 翻转单词
- *
- * @param s 字符串
- * @return 翻转后的字符串
- */
- public String reverseWords(String s) {
- if (s == null || s.length() == 0 || s.trim().equals("")) {
- return s;
- }
-
- String[] arr = s.split(" ");
- int p = 0, q = arr.length - 1;
- while (p < q) {
- swap(arr, p++, q--);
- }
- return String.join(" ", arr);
- }
- private void swap(String[] arr, int p, int q) {
- String t = arr[p];
- arr[p] = arr[q];
- arr[q] = t;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(句子中有多个单词;句子中只有一个单词);
-2. 特殊输入测试(字符串指针为空指针;字符串的内容为空;字符串中只有空格)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/58_02_LeftRotateString.md b/docs/jianzhioffer/java/58_02_LeftRotateString.md
deleted file mode 100644
index e78dc16bd..000000000
--- a/docs/jianzhioffer/java/58_02_LeftRotateString.md
+++ /dev/null
@@ -1,67 +0,0 @@
-## 左旋转字符串
-
-### 题目描述
-字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。
-
-请定义一个函数实现字符串左旋转操作的功能。
-
-比如输入字符串 `"abcdefg"` 和数字 2,该函数将返回左旋转 2 位得到的结果 `"cdefgab"`。
-
-**注意:**
-
-- 数据保证 n 小于等于输入字符串的长度。
-
-**样例**
-```
-输入:"abcdefg" , n=2
-
-输出:"cdefgab"
-```
-
-### 解法
-先翻转前 n 个字符,再翻转后面的字符,最后整体翻转。
-
-```java
-/**
- * @author bingo
- * @since 2018/12/12
- */
-
-class Solution {
-
- /**
- * 左旋转字符串
- *
- * @param str 字符串
- * @param n 左旋的位数
- * @return 旋转后的字符串
- */
- public String leftRotateString(String str, int n) {
- if (str == null || n < 1 || n > str.length()) {
- return str;
- }
- char[] chars = str.toCharArray();
- int len = chars.length;
- reverse(chars, 0, n - 1);
- reverse(chars, n, len - 1);
- reverse(chars, 0, len - 1);
- return new String(chars);
- }
-
- private void reverse(char[] chars, int p, int q) {
- while (p < q) {
- swap(chars, p++, q--);
- }
- }
-
- private void swap(char[] chars, int p, int q) {
- char t = chars[p];
- chars[p] = chars[q];
- chars[q] = t;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(把长度为 n 的字符串左旋转 0/1/2/n-1/n/n+1 个字符);
-2. 特殊输入测试(字符串指针为空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/59_01_MaxInSlidingWindow.md b/docs/jianzhioffer/java/59_01_MaxInSlidingWindow.md
deleted file mode 100644
index f568e9b30..000000000
--- a/docs/jianzhioffer/java/59_01_MaxInSlidingWindow.md
+++ /dev/null
@@ -1,75 +0,0 @@
-## 滑动窗口的最大值
-
-### 题目描述
-给定一个数组和滑动窗口的大小,请找出所有滑动窗口里的最大值。
-
-例如,如果输入数组 `[2, 3, 4, 2, 6, 2, 5, 1]` 及滑动窗口的大小 3,那么一共存在 6 个滑动窗口,它们的最大值分别为 `[4, 4, 6, 6, 6, 5]`。
-
-**注意:**
-
-- 数据保证 k 大于 0,且 k 小于等于数组长度。
-
-**样例**
-
-```
-输入:[2, 3, 4, 2, 6, 2, 5, 1] , k=3
-
-输出: [4, 4, 6, 6, 6, 5]
-```
-
-### 解法
-使用一个双端队列,保证队首存放的是窗口最大值的下标。遍历数组,
-
-1. 队尾元素比要入队的元素小,则把其移除(因为不可能成为窗口最大值)。
-2. 队首下标对应的元素不在窗口内(即窗口最大值),将其从队列中移除。
-3. 把每次滑动值的下标加入队列中(经过步骤1、2,此时加入队列的下标要么是当前窗口最大值的下标,要么是小于窗口最大值的下标)。
-4. 滑动窗口的首地址i大于size就写入窗口最大值。
-
-time complexity:O(n)
-
-space complexity:O(k) , k is the size
-
-```java
-/**
- * @author mcrwayfun
- * @version v1.0
- * @date Created in 2019/02/05
- * @description
- */
-class Solution {
-
- public ArrayList maxInWindows(int[] num, int size) {
-
- ArrayList reList = new ArrayList<>();
- if (num == null || num.length < size || size < 1) {
- return reList;
- }
-
- Deque deque = new LinkedList<>();
- for (int i = 0; i < num.length; i++) {
-
- // 队尾元素比要入队的元素小,则把其移除(因为不可能成为窗口最大值)
- while (!deque.isEmpty() && num[deque.getLast()] <= num[i]) {
- deque.pollLast();
- }
- // 队首下标对应的元素不在窗口内(即窗口最大值),将其从队列中移除
- while (!deque.isEmpty() && (i - deque.getFirst() + 1 > size)) {
- deque.pollFirst();
- }
- // 把每次滑动的值加入到队列中
- deque.add(i);
- // 滑动窗口的首地址i大于size就写入窗口最大值
- if (!deque.isEmpty() && i + 1 >= size) {
- reList.add(num[deque.getFirst()]);
- }
- }
-
- return reList;
- }
-}
-```
-
-### 测试用例
-1. 功能测试(输入数组的数字大小无序;输入数组的数字单调递增;输入数组的数字单调递减);
-2. 边界值测试(滑动窗口的大小为 0、1、等于输入数组的长度、大于输入数组的长度);
-3. 特殊输入测试(输入数组为空)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/61_ContinousCards.md b/docs/jianzhioffer/java/61_ContinousCards.md
deleted file mode 100644
index 9ff94a437..000000000
--- a/docs/jianzhioffer/java/61_ContinousCards.md
+++ /dev/null
@@ -1,78 +0,0 @@
-## 扑克牌的顺子
-
-### 题目描述
-从扑克牌中随机抽 `5` 张牌,判断是不是一个顺子,即这5张牌是不是连续的。
-
-`2~10` 为数字本身,`A` 为`1`,`J` 为 `11`,`Q` 为 `12`,`K` 为 `13`,大小王可以看做任意数字。
-
-为了方便,大小王均以 `0` 来表示,并且假设这副牌中大小王均有两张。
-
-**样例1**
-```
-输入:[8,9,10,11,12]
-
-输出:true
-```
-
-**样例2**
-```
-输入:[0,8,9,11,12]
-
-输出:true
-```
-
-### 解法
-- 对数组排序;
-- 计算出 0 的个数 `zeroCount`;
-- 从第一个不是 0 的数字开始遍历,与后一个数字比较,如果相等,直接返回 `false`;否则累计 `gap`;
-- 判断 `zeroCount` 是否大于等于 `gap`。
-
-
-```java
-import java.util.Arrays;
-
-/**
- * @author bingo
- * @since 2018/12/12
- */
-
-class Solution {
-
- /**
- * 判断是否是连续的数字
- *
- * @param numbers 数组
- * @return 是否是顺子
- */
- public boolean isContinuous(int [] numbers) {
- if (numbers == null || numbers.length == 0) {
- return false;
- }
- int zeroCount = 0;
- Arrays.sort(numbers);
- for (int e : numbers) {
- if (e > 0) {
- break;
- }
- ++zeroCount;
- }
-
- int p = zeroCount, q = p + 1, n = numbers.length;
- int gap = 0;
- while (q < n) {
- if (numbers[p] == numbers[q]) {
- return false;
- }
- gap += (numbers[q] - numbers[p] - 1);
- p = q;
- ++q;
- }
- return gap <= zeroCount;
-
- }
-}
-```
-
-### 测试用例
-1. 功能测试(抽出的牌中有一个或者多个大、小王;抽出的牌中没有大、小王;抽出的牌中有对子);
-2. 特殊输入测试(输入空指针)。
\ No newline at end of file
diff --git a/docs/jianzhioffer/java/README.md b/docs/jianzhioffer/java/README.md
deleted file mode 100644
index a7e31d6e0..000000000
--- a/docs/jianzhioffer/java/README.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# 剑指 Offer Java 题解
-
-> 来源:[《剑指 Offer》 Java 版实现](https://github.com/doocs/coding-interview)
-
-| # | Title |
-|---|---|
-| 03_01 | [Find Duplication In Array](/docs/剑指offer/Java/03_01_DuplicationInArray) |
-| 03_02 | [Find Duplication In Array II](/docs/剑指offer/Java/03_02_DuplicationInArrayNoEdit) |
-| 04 | [Find In Partially Sorted Matrix](/docs/剑指offer/Java/04_FindInPartiallySortedMatrix) |
-| 05 | [Replace Spaces](/docs/剑指offer/Java/05_ReplaceSpaces) |
-| 06 | [Print List In Reversed Order](/docs/剑指offer/Java/06_PrintListInReversedOrder) |
-| 07 | [Construct Binary Tree](/docs/剑指offer/Java/07_ConstructBinaryTree) |
-| 08 | [Next Node In Binary Trees](/docs/剑指offer/Java/08_NextNodeInBinaryTrees) |
-| 09_01 | [Queue With Two Stacks](/docs/剑指offer/Java/09_01_QueueWithTwoStacks) |
-| 09_02 | [Stack With Two Queues](/docs/剑指offer/Java/09_02_StackWithTwoQueues) |
-| 10_01 | [Fibonacci](/docs/剑指offer/Java/10_01_Fibonacci) |
-| 10_02 | [Jump Floor](/docs/剑指offer/Java/10_02_JumpFloor) |
-| 10_03 | [Jump Floor II](/docs/剑指offer/Java/10_03_JumpFloorII) |
-| 10_04 | [Rect Cover](/docs/剑指offer/Java/10_04_RectCover) |
-| 11 | [Min Number In Rotated Array](/docs/剑指offer/Java/11_MinNumberInRotatedArray) |
-| 12 | [String Path In Matrix](/docs/剑指offer/Java/12_StringPathInMatrix) |
-| 13 | [Robot Move](/docs/剑指offer/Java/13_RobotMove) |
-| 14 | [Cutting Rope](/docs/剑指offer/Java/14_CuttingRope) |
-| 15 | [Number Of 1 In Binary](/docs/剑指offer/Java/15_NumberOf1InBinary) |
-| 16 | [Power](/docs/剑指offer/Java/16_Power) |
-| 17 | [Print 1 To Max Of N Digits](/docs/剑指offer/Java/17_Print1ToMaxOfNDigits) |
-| 18_01 | [Delete Node In List](/docs/剑指offer/Java/18_01_DeleteNodeInList) |
-| 18_02 | [Delete Duplicated Node](/docs/剑指offer/Java/18_02_DeleteDuplicatedNode) |
-| 19 | [Regular Expressions Matching](/docs/剑指offer/Java/19_RegularExpressionsMatching) |
-| 20 | [Numeric Strings](/docs/剑指offer/Java/20_NumericStrings) |
-| 21 | [Reorder Array](/docs/剑指offer/Java/21_ReorderArray) |
-| 22 | [Kth Node From End](/docs/剑指offer/Java/22_KthNodeFromEnd) |
-| 23 | [Entry Node In List Loop](/docs/剑指offer/Java/23_EntryNodeInListLoop) |
-| 24 | [Reverse List](/docs/剑指offer/Java/24_ReverseList) |
-| 25 | [Merge Sorted Lists](/docs/剑指offer/Java/25_MergeSortedLists) |
-| 26 | [Substructure In Tree](/docs/剑指offer/Java/26_SubstructureInTree) |
-| 27 | [Mirror Of Binary Tree](/docs/剑指offer/Java/27_MirrorOfBinaryTree) |
-| 28 | [Symmetrical Binary Tree](/docs/剑指offer/Java/28_SymmetricalBinaryTree) |
-| 29 | [Print Matrix](/docs/剑指offer/Java/29_PrintMatrix) |
-| 30 | [Min In Stack](/docs/剑指offer/Java/30_MinInStack) |
-| 31 | [Stack Push Pop Order](/docs/剑指offer/Java/31_StackPushPopOrder) |
-| 32_01 | [Print Tree From Top To Bottom](/docs/剑指offer/Java/32_01_PrintTreeFromTopToBottom) |
-| 32_02 | [Print Trees In Lines](/docs/剑指offer/Java/32_02_PrintTreesInLines) |
-| 32_03 | [Print Trees In Zigzag](/docs/剑指offer/Java/32_03_PrintTreesInZigzag) |
-| 33 | [Squence Of BST](/docs/剑指offer/Java/33_SquenceOfBST) |
-| 34 | [Path In Tree](/docs/剑指offer/Java/34_PathInTree) |
-| 35 | [Copy Complex List](/docs/剑指offer/Java/35_CopyComplexList) |
-| 36 | [Convert Binary Search Tree](/docs/剑指offer/Java/36_ConvertBinarySearchTree) |
-| 39 | [More Than Half Number](/docs/剑指offer/Java/39_MoreThanHalfNumber) |
-| 40 | [K Least Numbers](/docs/剑指offer/Java/40_KLeastNumbers) |
-| 41 | [Stream Median](/docs/剑指offer/Java/41_StreamMedian) |
-| 42 | [Greatest Sum Of Subarrays](/docs/剑指offer/Java/42_GreatestSumOfSubarrays) |
-| 44 | [Digits In Sequence](/docs/剑指offer/Java/44_DigitsInSequence) |
-| 45 | [Sort Array For Min Number](/docs/剑指offer/Java/45_SortArrayForMinNumber) |
-| 46 | [Translate Numbers To Strings](/docs/剑指offer/Java/46_TranslateNumbersToStrings) |
-| 47 | [Max Value Of Gifts](/docs/剑指offer/Java/47_MaxValueOfGifts) |
-| 48 | [Longest Substring Without Dup](/docs/剑指offer/Java/48_LongestSubstringWithoutDup) |
-| 52 | [First Common Nodes In Lists](/docs/剑指offer/Java/52_FirstCommonNodesInLists) |
-| 53_01 | [Number Of K](/docs/剑指offer/Java/53_01_NumberOfK) |
-| 53_02 | [Missing Number](/docs/剑指offer/Java/53_02_MissingNumber) |
-| 53_03 | [Integer Identical To Index](/docs/剑指offer/Java/53_03_IntegerIdenticalToIndex) |
-| 55_01 | [Tree Depth](/docs/剑指offer/Java/55_01_TreeDepth) |
-| 55_02 | [Balanced Binary Tree](/docs/剑指offer/Java/55_02_BalancedBinaryTree) |
-| 56_01 | [Numbers Appear Once](/docs/剑指offer/Java/56_01_NumbersAppearOnce) |
-| 56_02 | [Number Appearing Once](/docs/剑指offer/Java/56_02_NumberAppearingOnce) |
-| 57_01 | [Two Numbers With Sum](/docs/剑指offer/Java/57_01_TwoNumbersWithSum) |
-| 57_02 | [Continuous Squence With Sum](/docs/剑指offer/Java/57_02_ContinuousSquenceWithSum) |
-| 58_01 | [Reverse Words In Sentence](/docs/剑指offer/Java/58_01_ReverseWordsInSentence) |
-| 58_02 | [Left Rotate String](/docs/剑指offer/Java/58_02_LeftRotateString) |
-| 59_01 | [Max In Sliding Window](/docs/剑指offer/Java/59_01_MaxInSlidingWindow) |
-| 61 | [Continous Cards](/docs/剑指offer/Java/61_ContinousCards) |
diff --git a/docs/jianzhioffer/java/SUMMARY.md b/docs/jianzhioffer/java/SUMMARY.md
deleted file mode 100644
index 528c38641..000000000
--- a/docs/jianzhioffer/java/SUMMARY.md
+++ /dev/null
@@ -1,73 +0,0 @@
-+ [剑指 Offer Java 题解](README.md)
-+ [找出数组中重复的数字](03_01_DuplicationInArray.md)
-+ [不修改数组找出重复的数字](03_02_DuplicationInArrayNoEdit.md)
-+ [二维数组中的查找](04_FindInPartiallySortedMatrix.md)
-+ [替换空格](05_ReplaceSpaces.md)
-+ [从尾到头打印链表](06_PrintListInReversedOrder.md)
-+ [重建二叉树](07_ConstructBinaryTree.md)
-+ [二叉树的下一个结点](08_NextNodeInBinaryTrees.md)
-+ [用两个栈实现队列](09_01_QueueWithTwoStacks.md)
-+ [用两个队列实现栈](09_02_StackWithTwoQueues.md)
-+ [斐波那契数列](10_01_Fibonacci.md)
-+ [跳台阶](10_02_JumpFloor.md)
-+ [变态跳台阶](10_03_JumpFloorII.md)
-+ [矩形覆盖](10_04_RectCover.md)
-+ [旋转数组的最小数字](11_MinNumberInRotatedArray.md)
-+ [矩阵中的路径](12_StringPathInMatrix.md)
-+ [机器人的移动范围](13_RobotMove.md)
-+ [剪绳子](14_CuttingRope.md)
-+ [二进制中 1 的个数](15_NumberOf1InBinary.md)
-+ [数值的整数次方](16_Power.md)
-+ [打印从 1 到最大的 n 位数](17_Print1ToMaxOfNDigits.md)
-+ [在O(1)时间内删除链表节点](18_01_DeleteNodeInList.md)
-+ [删除链表中重复的节点](18_02_DeleteDuplicatedNode.md)
-+ [正则表达式匹配](19_RegularExpressionsMatching.md)
-+ [表示数值的字符串](20_NumericStrings.md)
-+ [调整数组顺序使奇数位于偶数前面](21_ReorderArray.md)
-+ [链表中倒数第k个结点](22_KthNodeFromEnd.md)
-+ [链表中环的入口结点](23_EntryNodeInListLoop.md)
-+ [反转链表](24_ReverseList.md)
-+ [合并两个排序的链表](25_MergeSortedLists.md)
-+ [树的子结构](26_SubstructureInTree.md)
-+ [二叉树的镜像](27_MirrorOfBinaryTree.md)
-+ [对称的二叉树](28_SymmetricalBinaryTree.md)
-+ [顺时针打印矩阵](29_PrintMatrix.md)
-+ [包含min函数的栈](30_MinInStack.md)
-+ [栈的压入、弹出序列](31_StackPushPopOrder.md)
-+ [不分行从上到下打印二叉树](32_01_PrintTreeFromTopToBottom.md)
-+ [把二叉树打印成多行](32_02_PrintTreesInLines.md)
-+ [按之字形打印二叉树](32_03_PrintTreesInZigzag.md)
-+ [二叉搜索树的后序遍历序列](33_SquenceOfBST.md)
-+ [二叉树中和为某一值的路径](34_PathInTree.md)
-+ [复杂链表的复制](35_CopyComplexList.md)
-+ [二叉搜索树与双向链表](36_ConvertBinarySearchTree.md)
-+ [序列化二叉树](37_SerializeBinaryTrees.md)
-+ [字符串的排列](38_StringPermutation.md)
-+ [数组中出现次数超过一半的数字](39_MoreThanHalfNumber.md)
-+ [获取数组中最小的k个数](40_KLeastNumbers.md)
-+ [数据流中的中位数](41_StreamMedian.md)
-+ [连续子数组的最大和](42_GreatestSumOfSubarrays.md)
-+ [整数中1出现的次数](43_NumberOf1.md)
-+ [数字序列中某一位的数字](44_DigitsInSequence.md)
-+ [把数组排成最小的数](45_SortArrayForMinNumber.md)
-+ [把数字翻译成字符串](46_TranslateNumbersToStrings.md)
-+ [礼物的最大价值](47_MaxValueOfGifts.md)
-+ [最长不含重复字符的子字符串](48_LongestSubstringWithoutDup.md)
-+ [丑数](49_UglyNumber.md)
-+ [第一个只出现一次的字符](50_01_FirstNotRepeatingChar.md)
-+ [字符流中第一个不重复的字符](50_02_FristCharacterInStream.md)
-+ [两个链表的第一个公共结点](52_FirstCommonNodesInLists.md)
-+ [数字在排序数组中出现的次数](53_01_NumberOfK.md)
-+ [0到n-1中缺失的数字](53_02_MissingNumber.md)
-+ [数组中数值和下标相等的元素](53_03_IntegerIdenticalToIndex.md)
-+ [二叉搜索树的第k个结点](54_KthNodeInBST.md)
-+ [二叉树的深度](55_01_TreeDepth.md)
-+ [平衡二叉树](55_02_BalancedBinaryTree.md)
-+ [数组中只出现一次的两个数字](56_01_NumbersAppearOnce.md)
-+ [数组中唯一只出现一次的数字](56_02_NumberAppearingOnce.md)
-+ [和为S的两个数字](57_01_TwoNumbersWithSum.md)
-+ [和为S的连续正数序列](57_02_ContinuousSquenceWithSum.md)
-+ [翻转单词顺序](58_01_ReverseWordsInSentence.md)
-+ [左旋转字符串](58_02_LeftRotateString.md)
-+ [滑动窗口的最大值](59_01_MaxInSlidingWindow.md)
-+ [扑克牌的顺子](61_ContinousCards.md)
diff --git a/docs/leetcode/cpp/0001._Two_Sum.md b/docs/leetcode/cpp/0001._Two_Sum.md
deleted file mode 100644
index 917f83e6f..000000000
--- a/docs/leetcode/cpp/0001._Two_Sum.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# 1. Two Sum
- **难度: Easy**
- ## 刷题内容
- > 原题连接
- * https://leetcode.com/problems/two-sum
-* https://leetcode-cn.com/problems/two-sum
- > 内容描述
- ```
-给定 nums = [2, 7, 11, 15], target = 9
- 因为 nums[0] + nums[1] = 2 + 7 = 9
-所以返回 [0, 1]
-```
- ## 解题方案
- > 思路 1
-******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
- 采用双指针法,先将数组排序形成了一个有序的区间,指针i,j分别指向头尾,
-```
-当 nums1[i] + nums[j] > traget 时,j--,
-nums[i] + nums[j] < target 时,i++,
-直到 nums[i] + nums[j] == target
-```
-```cpp
-class Solution
-{
-public:
- vector twoSum(vector& nums, int target)
- {
- vector > nums1;
- for(int i = 0;i < nums.size();++i)
- nums1.push_back(make_pair(nums[i],i));
- sort(nums1.begin(),nums1.end());
- int i = 0,j = nums1.size() - 1;
- vector ret;
- while(i < j)
- {
- if(nums1[i].first + nums1[j].first == target)
- {
- ret.push_back(nums1[i].second);
- ret.push_back(nums1[j].second);
- return ret;
- }
- nums1[i].first +nums1[j].first < target ? ++i : --j;
- }
- }
-};
-```
-> 思路 2
-******- 时间复杂度: O(N)******- 空间复杂度: O(N)******
- c++中提供了 unordered_map 的容器,unordered_map 中的元素没有按照它们的键值或映射值的任何顺序排序,
-而是根据它们的散列值组织成桶以允许通过它们的键值直接快速访问单个元素(具有常数平均时间复杂度)
-将先出现的元素储存在 unorder_map 中,遍历数组,每次查找 target - nums[i] 是否存在即可。
- ```cpp
-class Solution
-{
-public:
- vector twoSum(vector& nums, int target)
- {
- unordered_map m;
- vector res;
- for (int i = 0; i < nums.size(); ++i) {
- m[nums[i]] = i;
- }
- for (int i = 0; i < nums.size(); ++i) {
- int t = target - nums[i];
- if (m.count(t) && m[t] != i) {
- res.push_back(i);
- res.push_back(m[t]);
- break;
- }
- }
- return res;
- }
-};
-```
diff --git a/docs/leetcode/cpp/0002._Add_Two_Numbers.md b/docs/leetcode/cpp/0002._Add_Two_Numbers.md
deleted file mode 100644
index 728077ac6..000000000
--- a/docs/leetcode/cpp/0002._Add_Two_Numbers.md
+++ /dev/null
@@ -1,70 +0,0 @@
-# 2. Add Two Numbers
-
-**难度:Medium**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/add-two-numbers
-
-> 内容描述
-
-```
-给定两个链表代表两个非负数,求这两个数的和
-(2 -> 4 -> 3) + (5 -> 6 -> 4)
-因为 342 + 465 = 807
-所以返回 7 -> 0 -> 8
-```
-
-## 解题方案
-
-> 思路
-
-
-这题的的关键在于链表的数储存是倒序的,因此只要从链表头相加,再将所得数挨个储存即可,但是要注意两数相加有可能大于10要进一位。
-```cpp
-/**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode(int x) : val(x), next(NULL) {}
- * };
- */
-class Solution {
-public:
- ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
- ListNode* current;
- ListNode* ret = nullptr;
- int num = 0;
- while(l1 && l2)
- {
- int sum = l1 ->val + l2 ->val + num;
- ListNode* node = new ListNode(sum % 10);
- num = sum / 10;
- ret ? current ->next = node : ret = node;
- current = node;
- l1 = l1 ->next;
- l2 = l2 ->next;
- }
- if(l2)
- l1 = l2;
- while(l1)
- {
- int sum = num + l1 ->val;
- ListNode* node = new ListNode(sum % 10);
- num = sum / 10;
- current ->next = node;
- current = node;
- l1 = l1 ->next;
- }
- if(num)
- {
- ListNode* node = new ListNode(num);
- current ->next = node;
- }
- return ret;
- }
-};
-```
diff --git a/docs/leetcode/cpp/0003._Longest_Substring_Without_Repeating_Characters.md b/docs/leetcode/cpp/0003._Longest_Substring_Without_Repeating_Characters.md
deleted file mode 100644
index 983bad57c..000000000
--- a/docs/leetcode/cpp/0003._Longest_Substring_Without_Repeating_Characters.md
+++ /dev/null
@@ -1,97 +0,0 @@
-# 3. Longest Substring Without Repeating Characters
-
-**难度:Medium**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/longest-substring-without-repeating-characters
-
-> 内容描述
-
-```
-
-Given a string, find the length of the longest substring without repeating characters.
-
-Example 1:
-
-Input: "abcabcbb"
-Output: 3
-Explanation: The answer is "abc", with the length of 3.
-Example 2:
-
-Input: "bbbbb"
-Output: 1
-Explanation: The answer is "b", with the length of 1.
-Example 3:
-
-Input: "pwwkew"
-Output: 3
-Explanation: The answer is "wke", with the length of 3.
- Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
-```
-
-## 解题方案
-
-> 思路 1
-******- 时间复杂度: O(NlgN)******- 空间复杂度: O(N)******
-
-
-用 map储存 key为字符,value 为这个字符的位置,我们可以维护一个子字符串(无重复字符),记录它的起始位置,遍历 string s 当无法在map中找到字符或者小于子字符串的起始位置,就是没有在这个字符串中出现,反之则字符重复,不过 map查找为 O(lgn),因此总的时间复杂度为O(NlgN)
-```cpp
-class Solution {
-public:
- int lengthOfLongestSubstring(string s) {
- map m;
- int beg = 0,length = s.length(),ll = 0,ans = 0;
- for(int i = 0;i < length;++i)
- {
- if(m.find(s[i]) == m.end() || m[s[i]] < beg)
- ll++;
- else
- {
- int pos = m[s[i]];
- ans = max(ll,ans);
- ll = ll - (pos - beg);
- beg = pos + 1;
- }
- m[s[i]] = i;
- }
- ans = max(ans,ll);
- return ans;
- }
-};
-```
-
-> 思路 2
-******- 时间复杂度: O(NlgN)******- 空间复杂度: O(1)******
-
-这个思路和上面差不多,用到了一个小窍门,因为储存的是字符,char为8位,因此能储存的最大数为256,这样空间复杂度就为O(1)
-
-```cpp
-class Solution {
-public:
- int lengthOfLongestSubstring(string s) {
- int m[256];
- for(int i = 0;i < 256;++i)
- m[i] = -1;
- int beg = 0,length = s.length(),ll = 0,ans = 0;
- for(int i = 0;i < length;++i)
- {
- if(m[s[i]] < beg)
- ll++;
- else
- {
- int pos = m[s[i]];
- ans = max(ll,ans);
- ll = ll - (pos - beg);
- beg = pos + 1;
- }
- m[s[i]] = i;
- }
- ans = max(ans,ll);
- return ans;
- }
-};
-```
diff --git a/docs/leetcode/cpp/0004._Median_of_Two_Sorted_Arrays.md b/docs/leetcode/cpp/0004._Median_of_Two_Sorted_Arrays.md
deleted file mode 100644
index be2f433bb..000000000
--- a/docs/leetcode/cpp/0004._Median_of_Two_Sorted_Arrays.md
+++ /dev/null
@@ -1,159 +0,0 @@
-# 004. Median of Two Sorted Arrays
-
-**难度Hard**
-
-## 刷题内容
-> 原题连接
-
-* https://leetcode.com/problems/median-of-two-sorted-arrays/submissions/
-
-> 内容描述
-
-```
-There are two sorted arrays nums1 and nums2 of size m and n respectively.
-
-Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
-
-You may assume nums1 and nums2 cannot be both empty.
-
-Example 1:
-
-nums1 = [1, 3]
-nums2 = [2]
-
-The median is 2.0
-Example 2:
-
-nums1 = [1, 2]
-nums2 = [3, 4]
-
-The median is (2 + 3)/2 = 2.5
-```
-
-> 思路1
-******- 时间复杂度: O(n + m)******- 空间复杂度: O(1)******
-
-直接用暴利搜索,类似与归并两个有序的数组。遍历两个数组,当总长度等于(m+n)/ 2,注意区分总长度奇数和偶数
-```cpp
-class Solution {
-public:
- double findMedianSortedArrays(vector& nums1, vector& nums2) {
- int temp = (nums1.size() + nums2.size()) / 2,count1 = 0,i = 0,j = 0,current,pre;
- while(i < nums1.size() && j < nums2.size() && count1 <= temp)
- {
- pre = current;
- if(nums1[i] > nums2[j])
- current = nums2[j++];
- else
- current = nums1[i++];
- ++count1;
- }
- if(count1 <= temp)
- {
- if(i < nums1.size())
- while(count1 <= temp)
- {
- pre = current;
- current = nums1[i++];
- ++count1;
- }
- else
- while(count1 <= temp)
- {
- pre = current;
- current = nums2[j++];
- ++count1;
- }
- }
- if((nums1.size() + nums2.size()) % 2)
- return current;
- double ans = (current + pre) / 2.0;
- return ans;
- }
-};
-```
-> 思路2
-******- 时间复杂度: O(lg(min(n.m)))******- 空间复杂度: O(1)******
-
-我们可以通过二分查找优化算法,利用中位数的定义,将两个数组划分为左右两个部分,nums1左半部分加nums2左半部分等于nums1右半部分加nums2的右半部分,如果总长度为偶数,那么nums1左半部分加nums2左半部分等于nums1右半部分加nums2的右半部分加1。并且```max(nums1[i],nums2[j]) <= max(nums1[i + 1],nums2[j + 1])```,接下来我们只要二分查找找i,并且要注意边界情况
-
-```cpp
-class Solution {
-public:
- double findMedianSortedArrays(vector& nums1, vector& nums2) {
- int m = nums1.size(),n = nums2.size(),sum = m + n;
- if(!nums1.size())
- return sum % 2 ? nums2[sum / 2] : (nums2[sum /2] + nums2[sum / 2 - 1]) / 2.0;
- if(!nums2.size())
- return sum % 2 ? nums1[sum / 2] : (nums1[sum /2] + nums1[sum / 2 - 1]) / 2.0;
- if(m > n)
- return findMedianSortedArrays(nums2,nums1);
- int l = 0,r = m - 1;
- while(l < r)
- {
- int mid = (l + r) / 2;
- int j = (sum + 1) / 2 - mid - 2;
- int min1 = max(nums1[mid],nums2[j]),max1 = min(nums1[mid + 1],nums2[j + 1]);
- if(min1 <= max1)
- return sum % 2 ? min1 : (min1 + max1) / 2.0;
- else if(nums1[mid] > nums2[j])
- r = mid - 1;
- else
- l = mid + 1;
- }
- int j = (sum + 1) / 2 - l - 2;
- int min1,max1;
- if(j < 0)
- min1 = nums1[l];
- else
- min1 = max(nums1[l],nums2[j]);
- if(l == nums1.size() - 1)
- max1 = nums2[j + 1];
- else
- max1 = min(nums1[l + 1],nums2[j + 1]);
- if(min1 <= max1)
- return sum % 2 ? min1 : (min1 + max1) / 2.0;
- j++;
- if(j < nums2.size() - 1)
- max1 = min(nums1[l],nums2[j + 1]);
- else
- max1 = nums1[l];
- min1 = nums2[j];
- return sum % 2 ? min1 : (min1 + max1) / 2.0;
- }
-};
-```
-> 思路3
-******- 时间复杂度: O(lg(n+m))******- 空间复杂度: O(1)******
-
-由于题目中建议我们在时间复杂度O(lg(m+n))中完成,我们可以把这题看成寻找第k大的值,这样我们可以递归的去做,每次查找k/2,知道k等于1,注意边界值的处理
-```cpp
-class Solution {
-public:
-int getKth(vector nums1, int start1, int end1, vector nums2, int start2, int end2, int k) {
- int len1 = end1 - start1 + 1;
- int len2 = end2 - start2 + 1;
- if (len1 > len2) return getKth(nums2, start2, end2, nums1, start1, end1, k);
- if (len1 == 0) return nums2[start2 + k - 1];
-
- if (k == 1) return min(nums1[start1], nums2[start2]);
-
- int i = start1 + min(len1, k / 2) - 1;
- int j = start2 + min(len2, k / 2) - 1;
-
- if (nums1[i] > nums2[j]) {
- return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1));
- }
- else {
- return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1));
- }
- }
-double findMedianSortedArrays(vector nums1, vector nums2) {
- int n = nums1.size();
- int m = nums2.size();
- int left = (n + m + 1) / 2;
- int right = (n + m + 2) / 2;
- return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5;
-}
-};
-```
diff --git a/docs/leetcode/cpp/0005._Longest_Palindromic_Substring.md b/docs/leetcode/cpp/0005._Longest_Palindromic_Substring.md
deleted file mode 100644
index b535fbe5d..000000000
--- a/docs/leetcode/cpp/0005._Longest_Palindromic_Substring.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# 5. Longest Palindromic Substring
-
-**难度:Medium**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/longest-palindromic-substring
-
-> 内容描述
-
-```
-Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
-
-Example 1:
-
-Input: "babad"
-Output: "bab"
-Note: "aba" is also a valid answer.
-Example 2:
-
-Input: "cbbd"
-Output: "bb"
-```
-
-## 解题方案
-
-> 思路 1
-******- 时间复杂度: O(N^2)******- 空间复杂度: O(N^2)******
-
-
-这题如果用单纯暴力的解法,时间复杂度为 O(n ^ 3),肯定超时,那么就要对这个算法进行优化,这里采用的是DP思想,定义 p(i,j)为s中的第i个数到s中的第j个数的子串,不难看出 p(i,j)中的子串有重复计算,接下来就可以写出状态转移方程 P(i,j)=(P(i+1,j?1) and S[i] == S[j])
-
-```cpp
-class Solution {
-public:
- int dp[1000][1000] = {0};
- string longestPalindrome(string s) {
- int beg = 0,en = 1,ans = 0;
- int length = s.length();
- for(int i = 0;i < length;++i)
- {
- dp[i][i] = 1;
- if(i + 1 < length && s[i] == s[i + 1])
- dp[i][i + 1] = 1;
- }
- for(int i = 0;i < length;++i)
- for(int j = 0;j <= i;++j)
- {
- if(i > j + 1)
- dp[j][i] = (dp[j + 1][i - 1] && s[i] == s[j]);
- if(dp[j][i] && i - j + 1 > ans)
- {
- ans = i - j + 1;
- beg = j;
- en = i + 1;
- }
- }
- string ret(s.begin() + beg,s.begin() + en);
- return ret;
- }
-};
-```
diff --git a/docs/leetcode/cpp/0006._ZigZag_Conversion.md b/docs/leetcode/cpp/0006._ZigZag_Conversion.md
deleted file mode 100644
index 6cbbc25c6..000000000
--- a/docs/leetcode/cpp/0006._ZigZag_Conversion.md
+++ /dev/null
@@ -1,96 +0,0 @@
-# 6. ZigZag Conversion
-
-**难度:Medium**
-
-## 刷题内容
-
-> 原题连接
-
-*https://leetcode.com/problems/zigzag-conversion
-*
-> 内容描述
-
-```
-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 s, int numRows);
-Example 1:
-
-Input: s = "PAYPALISHIRING", numRows = 3
-Output: "PAHNAPLSIIGYIR"
-Example 2:
-
-Input: s = "PAYPALISHIRING", numRows = 4
-Output: "PINALSIGYAHRPI"
-Explanation:
-
-P I N
-A L S I G
-Y A H R
-P I
-```
-
-## 解题方案
-
-> 思路1
-******- 时间复杂度: O(N)******- 空间复杂度: O(N + numRows)******
-
-
-这道题理解了题目意思其实不难,一般人可能会开一个二维数组,然后就按题目意思储存,这样做的话时间复杂度和空间复杂度都比较大,这里我用的方法先用一个 string 类型变量 str ,resize 和输入的 s 长度相等,接着只要遍历找到 s[i] 在 str 中的位置即可
-
-
-```cpp
-class Solution {
-public:
- string convert(string s, int numRows) {
- string newStr;
- if(!s.length() || numRows == 1)
- return s;
- newStr.resize(s.length());
- int num = numRows * 2 - 2,col = s.length() / num,rem = (s.length() - 1) % num;
- vector rowNum;
- for(int i = 0;i < numRows;++i)
- if(!i)
- s.length() % num ? rowNum.push_back(col + 1) : rowNum.push_back(col);
- else
- {
- if(i == numRows - 1)
- rem >= i ? rowNum.push_back(rowNum[i - 1] + (s.length() - 1) / num + 1) : rowNum.push_back(rowNum[i - 1] + (s.length() - 1) / num);
- else
- {
- int temp = 2 * numRows - i - 2,col1 = (s.length() - 1) / num;
- if(rem >= temp)
- rowNum.push_back(rowNum[i - 1] + (col1 + 1) * 2);
- else if(rem >= i)
- rowNum.push_back(rowNum[i - 1] + col1 * 2 + 1);
- else
- rowNum.push_back(rowNum[i - 1] + col1 * 2);
- }
- }
- for(int i = 0;i < s.length();++i)
- {
- int index1 = i % num;
- int index2 = i / num;
- if(!index1)
- newStr[index2] = s[i];
- else if(index1 == numRows - 1)
- newStr[index2 + rowNum[index1 - 1]] = s[i];
- else if(index1 < numRows)
- newStr[index2 * 2 + rowNum[index1 - 1]] = s[i];
- else
- {
- int index3 = 2 * numRows - index1 - 2;
- newStr[index2 * 2 + 1 + rowNum[index3 - 1]] = s[i];
- }
- }
- return newStr;
- }
-};
-```
diff --git a/docs/leetcode/cpp/0007._Reverse_Integer.md b/docs/leetcode/cpp/0007._Reverse_Integer.md
deleted file mode 100644
index 296913158..000000000
--- a/docs/leetcode/cpp/0007._Reverse_Integer.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# 7. Reverse Integer
-
-**�Ѷ�:Easy**
-
-## ˢ������
-> ԭ������
-
-* https://leetcode.com/problems/reverse-integer/
-
-> ��������
-
-```
-Given a 32-bit signed integer, reverse digits of an integer.
-
-Example 1:
-
-Input: 123
-Output: 321
-Example 2:
-
-Input: -123
-Output: -321
-Example 3:
-
-Input: 120
-Output: 21
-Note:
-Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [?231, 231 ? 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.
-```
-
-> ˼·1
-******- ʱ�临�Ӷ�: O(n)******- �ռ临�Ӷ�: O(1)******
-
-һ��easy����Ŀ�����μ������λ����������Ҫע�ⳬ��int�ķ�Χ��
-
-```cpp
-class Solution {
-public:
- int reverse(int x) {
- long long val = 0;
- do
- {
- val = val * 10 + x % 10;
- x /= 10;
- } while (x);
-
- return (val > INT_MAX || val < INT_MIN) ? 0 : val;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0008._String_to_Integer_(atoi).md b/docs/leetcode/cpp/0008._String_to_Integer_(atoi).md
deleted file mode 100644
index 66c9454fa..000000000
--- a/docs/leetcode/cpp/0008._String_to_Integer_(atoi).md
+++ /dev/null
@@ -1,104 +0,0 @@
-# 8. String to Integer (atoi)
-
-**�Ѷ�:Medium**
-
-## ˢ������
-> ԭ������
-
-* https://leetcode.com/problems/string-to-integer-atoi/
-
-> ��������
-
-```
-Implement atoi which converts a string to an integer.
-
-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.
-
-Note:
-
-Only the space character ' ' is considered as whitespace character.
-Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [?231, 231 ? 1]. If the numerical value is out of the range of representable values, INT_MAX (231 ? 1) or INT_MIN (?231) is returned.
-Example 1:
-
-Input: "42"
-Output: 42
-Example 2:
-
-Input: " -42"
-Output: -42
-Explanation: The first non-whitespace character is '-', which is the minus sign.
- Then take as many numerical digits as possible, which gets 42.
-Example 3:
-
-Input: "4193 with words"
-Output: 4193
-Explanation: Conversion stops at digit '3' as the next character is not a numerical digit.
-Example 4:
-
-Input: "words and 987"
-Output: 0
-Explanation: The first non-whitespace character is 'w', which is not a numerical
- digit or a +/- sign. Therefore no valid conversion could be performed.
-Example 5:
-
-Input: "-91283472332"
-Output: -2147483648
-Explanation: The number "-91283472332" is out of the range of a 32-bit signed integer.
- Thefore INT_MIN (?231) is returned.
-```
-
-> ˼·
-******- ʱ�临�Ӷ�: O(N)******- �ռ临�Ӷ�: O(N)******
-
-��һ���ַ���ת�����֣�����ַ���ֻ������ֻҪ�����ַ���ת��int���͵����ּ��ɣ������������������ģ����Ҫע��߽�ֵ���ж����ֵ�����������Ϊ�����Ч�ʡ��ȼ�����10��32�η���10��n�η���ֵ��
-
-```cpp
-class Solution {
-public:
- int myAtoi(string str) {
- int i = 0,count1 = 0;
- long long arr[34];
- arr[0] = 1;
- for(int i = 1;i < 34;++i)
- arr[i] = arr[i - 1] * 10;
- while(str[i] == ' ')
- i++;
- if(str[i] == '-' || str[i] == '+')
- {
- if(str[i] == '-')
- count1 = 1;
- i++;
- }
- if(!isdigit(str[i]))
- return 0;
- while(str[i] == '0')
- i++;
- long long num = 0;
- int j = i;
- while(j < str.length() && isdigit(str[j]))
- j++;
- if(j - i > 33)
- return count1 ? INT_MIN : INT_MAX;
- j--;
- int t = 0;
- while(j >= i)
- {
- num += (str[j] - '0') * arr[t++];
- if(!count1 && num > INT_MAX)
- return INT_MAX;
- if(count1 && num * -1 < INT_MIN)
- return INT_MIN;
- j--;
- }
- if(count1)
- num *= -1;
- return num;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0009._Palindrome_Number.md b/docs/leetcode/cpp/0009._Palindrome_Number.md
deleted file mode 100644
index 788beb123..000000000
--- a/docs/leetcode/cpp/0009._Palindrome_Number.md
+++ /dev/null
@@ -1,102 +0,0 @@
-# 9. Palindrome Number
-
-**难度:Medium**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/palindrome-number
-*
-> 内容描述
-
-```
-Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward.
-
-Example 1:
-
-Input: 121
-Output: true
-Example 2:
-
-Input: -121
-Output: false
-Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
-Example 3:
-
-Input: 10
-Output: false
-Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
-Follow up:
-
-Coud you solve it without converting the integer to a string?
-```
-
-## 解题方案
-
-> 思路1
-******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
-
-
-这题的难度不大,由于是数字,判断回文只需要求出倒过来的数字,判断两者是否相等,不过要注意负数一定不是回文
-
-
-```cpp
-class Solution {
-public:
- bool isPalindrome(int x) {
- long long ret = 0;
- int num = x;
- if(x < 0)
- return false;
- while(num)
- {
- ret = 10 * ret + num % 10;
- num /= 10;
- }
- if(ret == x)
- return true;
- return false;
- }
-};
-```
-> 思路2
-******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
-
-
-计算出数字的长度,用双指针法,一个指针指向头,另一个指向尾,相等就前一个指针加一,后一个指针减一,若不相等则返回 false
-
-
-```cpp
-class Solution {
-public:
- bool isPalindrome(int x) {
- if (x < 0)
- return false;
-
- int cnt = 0;
- long fac = 1;
- int div = INT_MAX;
- while (div != 0) {
- cnt++;
- fac *= 10;
- div = x/fac;
- }
-
- fac /= 10;
- for (int i=0; i难度: Hard**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/regular-expression-matching
-
-> 内容描述
-
-```
-Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.
-
-'.' Matches any single character.
-'*' Matches zero or more of the preceding element.
-The matching should cover the entire input string (not partial).
-
-Note:
-
-s could be empty and contains only lowercase letters a-z.
-p could be empty and contains only lowercase letters a-z, and characters like . or *.
-
-Example 1:
-
-Input:
-s = "aa"
-p = "a"
-Output: false
-Explanation: "a" does not match the entire string "aa".
-
-Example 2:
-
-Input:
-s = "aa"
-p = "a*"
-Output: true
-Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
-
-Example 3:
-
-Input:
-s = "ab"
-p = ".*"
-Output: true
-Explanation: ".*" means "zero or more (*) of any character (.)".
-
-Example 4:
-
-Input:
-s = "aab"
-p = "c*a*b"
-Output: true
-Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".
-
-Example 5:
-
-Input:
-s = "mississippi"
-p = "mis*is*p*."
-Output: false
-```
-
-## 解题方案
-
-> 思路1
-******- 时间复杂度: O(n^2)******- 空间复杂度: O(n^2)******
-
-用动态规划的思路去解,dp[i][j]代表字符串s中第i个字符之前的字符串与p中第j个字符串之前的字符是否匹配。写出状态转移方程。当```s[i] == p[j] || p[j] == '.'```时。```dp[i + 1][j + 1] = dp[i][j]```。当```p[j] == '*'```时,可以匹配0个,1个或多个之前相同的字符。当之前的字符```s[i] == p[j - 1] || p[j - 1] == '*'```时。```dp[i + 1][j + 1] = dp[i][j] || dp[i][j + 1]```表示匹配1个或者多个。还可匹配0个。因此```dp[i + 1][j + 1] = dp[i + 1][j + 1] || dp[i + 1][j - 1]```
-
-```cpp
-class Solution {
-public:
- bool isMatch(string s, string p) {
- s.push_back(' ');
- p.push_back(' ');
- int len1 = s.length(),len2 = p.length();
- int dp[len1 + 1][len2 + 1];
- memset(dp,0,sizeof(dp));
- dp[0][0] = 1;
- for(int i = 1;i < len2;++i)
- if(p[i] == '*')
- dp[0][i + 1] = dp[0][i - 1];
- for(int i = 0;i < len1;++i)
- for(int j = 0;j < len2;++j)
- if(j && p[j] == '*')
- {
- dp[i + 1][j + 1] = (p[j - 1] == s[i] || p[j - 1] == '.') && (dp[i][j] || dp[i][j + 1]);
- dp[i + 1][j + 1] = dp[i + 1][j + 1] || dp[i + 1][j - 1];
- }
- else if(s[i] == p[j] || p[j] == '.')
- dp[i + 1][j + 1] = dp[i][j];
- return dp[len1][len2];
- }
-};
-```
diff --git a/docs/leetcode/cpp/0011._Container_With_Most_Water.md b/docs/leetcode/cpp/0011._Container_With_Most_Water.md
deleted file mode 100644
index 1a610d4da..000000000
--- a/docs/leetcode/cpp/0011._Container_With_Most_Water.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# 11. container with most water
-
-**难度:Medium**
-
-## 刷题内容
-
-> 原题连接
-
-*https://leetcode.com/problems/container-with-most-water/
-*
-> 内容描述
-
-```
-Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
-
-Note: You may not slant the container and n is at least 2.
-```
-
-## 解题方案
-
-> 思路
-******- 时间复杂度: O(N)******- 空间复杂度: O(1)******
-
-这道题刚开始很容易想到用暴力的方法去解,但是时间复杂度为 O(n^2) 测试之后发现是 TLE,那么我们就要对算法进行优化,这里我们用双指针法,定义两个指针,一个指向头,另一个指向尾部,比较两个指针指向的数的大小,若头部的大,则指向头部的指针向后移动一位,反之,则指向尾部的指针向前移动一位。
-
-
-```cpp
-class Solution {
-public:
- int maxArea(vector& height) {
- int i = 0,j = height.size() - 1,ans = INT_MIN;
- while(i < j)
- {
- int t = min(height[i],height[j]);
- ans = max(ans,t * (j - i));
- height[i] < height[j] ? i++ : j--;
- }
- return ans;
- }
-};
-```
diff --git a/docs/leetcode/cpp/0012._Integer_to_Roman.md b/docs/leetcode/cpp/0012._Integer_to_Roman.md
deleted file mode 100644
index e646d8a4c..000000000
--- a/docs/leetcode/cpp/0012._Integer_to_Roman.md
+++ /dev/null
@@ -1,164 +0,0 @@
-# 12. Integer to Roman
-
-**�Ѷ�:Medium**
-
-## ˢ������
-
-> ԭ������
-
-* https://leetcode.com/problems/rotate-list/
-
-> ��������
-
-```
-Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.
-
-Symbol Value
-I 1
-V 5
-X 10
-L 50
-C 100
-D 500
-M 1000
-For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II.
-
-Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used:
-
-I can be placed before V (5) and X (10) to make 4 and 9.
-X can be placed before L (50) and C (100) to make 40 and 90.
-C can be placed before D (500) and M (1000) to make 400 and 900.
-Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999.
-
-Example 1:
-
-Input: 3
-Output: "III"
-Example 2:
-
-Input: 4
-Output: "IV"
-Example 3:
-
-Input: 9
-Output: "IX"
-Example 4:
-
-Input: 58
-Output: "LVIII"
-Explanation: L = 50, V = 5, III = 3.
-Example 5:
-
-Input: 1994
-Output: "MCMXCIV"
-Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.
-
-```
-
-
-
-> ˼·1
-
-******- ʱ�临�Ӷ�: O(n)******- �ռ临�Ӷ�: O(n)******
-
-��Ŀ���ѣ�ֱ����һ�ֱ�����д��
-
-```cpp
-class Solution {
-public:
- string intToRoman(int num) {
- string ans;
- vector table;
- int a = 0;
- int count = 0;
- while(num){
- a = num%10;
- num /= 10;
- ++count;
- if(count==1){
- if(a==1) table.push_back("I");
- else if(a==2) table.push_back("II");
- else if(a==3) table.push_back("III");
- else if(a==4) table.push_back("IV");
- else if(a==5) table.push_back("V");
- else if(a==6) table.push_back("VI");
- else if(a==7) table.push_back("VII");
- else if(a==8) table.push_back("VIII");
- else if(a==9) table.push_back("IX");
- }
- else if(count==2){
- if(a==1) table.push_back("X");
- else if(a==2) table.push_back("XX");
- else if(a==3) table.push_back("XXX");
- else if(a==4) table.push_back("XL");
- else if(a==5) table.push_back("L");
- else if(a==6) table.push_back("LX");
- else if(a==7) table.push_back("LXX");
- else if(a==8) table.push_back("LXXX");
- else if(a==9) table.push_back("XC");
- }
- else if(count==3){
- if(a==1) table.push_back("C");
- else if(a==2) table.push_back("CC");
- else if(a==3) table.push_back("CCC");
- else if(a==4) table.push_back("CD");
- else if(a==5) table.push_back("D");
- else if(a==6) table.push_back("DC");
- else if(a==7) table.push_back("DCC");
- else if(a==8) table.push_back("DCCC");
- else if(a==9) table.push_back("CM");
- }
- else if(count==4){
- if(a==1) table.push_back("M");
- else if(a==2) table.push_back("MM");
- else if(a==3) table.push_back("MMM");
- }
- }
- for(int i = table.size()-1; i >= 0; --i){
- ans += table[i];
- }
- return ans;
- }
-};
-```
-
-> ˼·2
-
-******- ʱ�临�Ӷ�: O(n)******- �ռ临�Ӷ�: O(1)******
-
-̫���if else���IJ��ÿ������ǿ��Ի�һ�ָ����ŵ�д�����ô�����ÿ���
-
-```cpp
-class Solution {
-public:
- int arr[7] = {'I','V','X','L','C','D','M'};
- int arr1[13] = {1,4,5,9,10,40,50,90,100,400,500,900,1000};
- void f(int& num,int i,string& ans)
- {
- if(i % 2)
- {
- ans.push_back(arr[i / 4 * 2]);
- ans.push_back(arr[i / 2 + 1]);
- }
- else
- ans.push_back(arr[i / 2]);
- num -= arr1[i];
- }
- string intToRoman(int num) {
- string ans;
- while(num)
- {
- int i;
- for(i = 0;i < 13;++i)
- if(num < arr1[i])
- {
- f(num,i - 1,ans);
- break;
- }
- if(i == 13)
- f(num,i - 1,ans);
- }
- return ans;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0014._Longest_Common_Prefix.md b/docs/leetcode/cpp/0014._Longest_Common_Prefix.md
deleted file mode 100644
index d87e89f1d..000000000
--- a/docs/leetcode/cpp/0014._Longest_Common_Prefix.md
+++ /dev/null
@@ -1,58 +0,0 @@
-# 14. Longest Common Prefix
-
-**�Ѷ�:Easy**
-
-## ˢ������
-> ԭ������
-
-* https://leetcode.com/problems/longest-common-prefix/
-
-> ��������
-
-```
-Write a function to find the longest common prefix string amongst an array of strings.
-
-If there is no common prefix, return an empty string "".
-
-Example 1:
-
-Input: ["flower","flow","flight"]
-Output: "fl"
-Example 2:
-
-Input: ["dog","racecar","car"]
-Output: ""
-Explanation: There is no common prefix among the input strings.
-Note:
-
-All given inputs are in lowercase letters a-z.
-```
-
-> ˼·1
-******- ʱ�临�Ӷ�: O(n^2)******- �ռ临�Ӷ�: O(1)******
-
-���ǰ�����Ӵ���ֻ�б��������Ӵ������������Ӵ����ɣ�����Ҫע����ܴ��ڿ��ַ���
-
-```cpp
-class Solution {
-public:
- string longestCommonPrefix(vector& strs) {
- string temp;
- if(!strs.size() || !strs[0].length())
- return temp;
- int j = 0;
- while(1)
- {
- int i = 0;
- int ch = strs[0][j];
- for(;i < strs.size();++i)
- if(j >= strs[i].length() || strs[i][j] != ch)
- break;
- if(i != strs.size())
- break;
- temp.push_back(strs[0][j++]);
- }
- return temp;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0015._3sum.md b/docs/leetcode/cpp/0015._3sum.md
deleted file mode 100644
index bbcbb74e8..000000000
--- a/docs/leetcode/cpp/0015._3sum.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# 15. 3sum
-
-**难度:Medium**
-
-## 刷题内容
-
-> 原题连接
-
-*https://leetcode.com/problems/3sum
-*
-> 内容描述
-
-```
-Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
-
-Note:
-
-The solution set must not contain duplicate triplets.
-```
-
-## 解题方案
-
-> 思路
-******- 时间复杂度: O(N ^ 2)******- 空间复杂度: O(N)******
-
-之前做过两个数之和等于某个数的题目,其实这题也差不多,三数之和等于0,那么我们只要让另外两个数之和等于第三个数的相反数即可,不过这里要注意会存在重复,所以要去重
-
-
-```cpp
-class Solution {
-public:
- vector> threeSum(vector& nums) {
- vector > ret;
- sort(nums.begin(),nums.end());
- for(int i = 0;i < nums.size();++i)
- {
- int t1 = i + 1,t2 = nums.size() - 1;
- if(i && nums[i] == nums[i - 1])
- continue;
- while(t1 < t2)
- if(nums[t1] + nums[t2] == -nums[i])
- {
- vector v;
- v.push_back(nums[i]);
- v.push_back(nums[t1]);
- v.push_back(nums[t2]);
- ret.push_back(v);
- ++t1;
- --t2;
- }
- else if(nums[t1] + nums[t2] < -nums[i])
- ++t1;
- else
- --t2;
- }
- auto pos = unique(ret.begin(),ret.end());
- ret.erase(pos,ret.end());
- return ret;
- }
-};
-```
diff --git a/docs/leetcode/cpp/0016._3Sum_Closest.md b/docs/leetcode/cpp/0016._3Sum_Closest.md
deleted file mode 100644
index 496ac062c..000000000
--- a/docs/leetcode/cpp/0016._3Sum_Closest.md
+++ /dev/null
@@ -1,45 +0,0 @@
-## 16. 3Sum Closest
-
-难度:Medium
-
-## 内容
-
-> 原题链接:https://leetcode.com/problems/3sum-closest
-
-Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
-
-Example:
-
-```
-Given array nums = [-1, 2, 1, -4], and target = 1.
-
-The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
-```
-
-## 思路
-
-先排序,遍历第一个数,第二和第三个数通过双指针查找,转化为2sum closest的问题。如果遇到和等于target的三个数,直接返回target。
-
-## 代码
-
-```
-class Solution {
-public:
- int threeSumClosest(vector& nums, int target) {
- std::sort(nums.begin(), nums.end());
- int min_distance{INT_MAX}, sum{0}, cur_sum{0};
- for (auto it = nums.cbegin(); it != nums.cend(); ++it)
- for (auto left_idx = std::next(it), right_idx = std::prev(nums.cend()); left_idx < right_idx; cur_sum > target ? --right_idx : ++left_idx) {
- cur_sum = *it + *left_idx + *right_idx;
- auto cur_distance = std::abs(cur_sum - target);
- if (cur_sum == target)
- return target;
- else if (cur_distance < min_distance) {
- min_distance = cur_distance;
- sum = cur_sum;
- }
- }
- return sum;
- }
-};
-```
diff --git a/docs/leetcode/cpp/0017._Letter_Combinations_of_a_Phone_Number.md b/docs/leetcode/cpp/0017._Letter_Combinations_of_a_Phone_Number.md
deleted file mode 100644
index d7a240e85..000000000
--- a/docs/leetcode/cpp/0017._Letter_Combinations_of_a_Phone_Number.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# 17. Letter Combinations of a Phone Number
-
-**�Ѷ�:Medium**
-
-## ˢ������
-> ԭ������
-
-* https://leetcode.com/problems/letter-combinations-of-a-phone-number/
-
-> ��������
-
-```
-Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent.
-
-A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.
-
-
-
-Example:
-
-Input: "23"
-Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
-Note:
-
-Although the above answer is in lexicographical order, your answer could be in any order you want.
-```
-
-> ˼·1
-******- ʱ�临�Ӷ�: O(2^n)******- �ռ临�Ӷ�: O(1)******
-
-�û��ݷ�ȥ�⣬�Ƚ������ַ���ת�����֡�����7��9֮����������ֶ���3����ĸ�������ÿ�����ִ�������ĸ���������û��ݷ�
-
-```cpp
-class Solution {
-public:
- void DFS(string& s,int i,vector& ans,string& temp)
- {
- if(i == s.length())
- {
- ans.push_back(temp);
- return;
- }
- int t = s[i] - '2';
- int ch_beg;
- if(t < 6)
- ch_beg = 'a' + t * 3;
- else
- ch_beg = 'a' + (t - 1) * 3 + 4;
- int en = 3;
- if(t == 5 || t == 7)
- en = 4;
- for(int j = 0;j < en;++j)
- {
- temp.push_back(ch_beg + j);
- DFS(s,i + 1,ans,temp);
- temp.pop_back();
- }
- }
- vector letterCombinations(string digits) {
- vector ans;
- if(!digits.size())
- return ans;
- string temp;
- DFS(digits,0,ans,temp);
- return ans;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0018._4Sum.md b/docs/leetcode/cpp/0018._4Sum.md
deleted file mode 100644
index c3e0db2cb..000000000
--- a/docs/leetcode/cpp/0018._4Sum.md
+++ /dev/null
@@ -1,57 +0,0 @@
-## 18. 4Sum
-
-难度:Medium
-
-## 内容
-
-题目链接:https://leetcode.com/problems/4sum
-
-Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
-
-Note:
-
-The solution set must not contain duplicate quadruplets.
-
-Example:
-
-```
-Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.
-
-A solution set is:
-[
- [-1, 0, 0, 1],
- [-2, -1, 1, 2],
- [-2, 0, 0, 2]
-]
-```
-
-## 思路
-
-思路和 3Sum 类似,多了一层for循环。为了避免重复,在存储结果的时候使用STL的set。
-
-## 代码
-
-```
-class Solution {
-public:
- vector> fourSum(vector& nums, int target) {
- if (nums.size() < 4) return vector>{};
- std::set> res;
- std::sort(nums.begin(), nums.end());
- for (size_t i = 0; i < nums.size() - 3; ++i)
- for (size_t j = i + 1; j < nums.size() - 2; ++j) {
- auto left_idx = j + 1; auto right_idx = nums.size() - 1;
- int sum = 0;
- for (left_idx = j + 1, right_idx = nums.size() - 1; left_idx < right_idx; sum > target ? --right_idx : ++left_idx) {
- sum = nums[i] + nums[j] + nums[left_idx] + nums[right_idx];
- if (sum == target) {
- vector res_single{nums[i], nums[j], nums[left_idx], nums[right_idx]};
- res.insert(res_single);
- }
-
- }
- }
- return vector>(res.begin(), res.end());
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0019._Remove_Nth_Node_From_End_of_List.md b/docs/leetcode/cpp/0019._Remove_Nth_Node_From_End_of_List.md
deleted file mode 100644
index 2c1fc990f..000000000
--- a/docs/leetcode/cpp/0019._Remove_Nth_Node_From_End_of_List.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# 19. Remove Nth Node From End of List
-
-**�Ѷ�:Medium**
-
-## ˢ������
-> ԭ������
-
-* https://leetcode.com/problems/remove-nth-node-from-end-of-list/
-
-> ��������
-
-```
-Given a linked list, remove the n-th node from the end of list and return its head.
-
-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.
-```
-
-> ˼·
-******- ʱ�临�Ӷ�: O(n)******- �ռ临�Ӷ�: O(1)******
-
-ɾ��������n������Ϊ�˷�ֹ��������Ϊ1ʱ�Ŀ�ָ���쳣���Ȳ���һ������ͷ����������ֻҪ�ȱ���������������������ܳ��ȣ������ܳ��ȼ�ȥ n ��������Ҫɾ��������ǰһ����������ͷ�ij��ȣ�������ֻҪ�ø�ѭ���ҵ���ɾ��Ҫɾ���Ľڵ㼴�ɡ�
-
-```cpp
-/**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode(int x) : val(x), next(NULL) {}
- * };
- */
-class Solution {
-public:
- ListNode* removeNthFromEnd(ListNode* head, int n) {
- ListNode* current = head;
- int num = 0;
- while(current)
- {
- num++;
- current = current ->next;
- }
- ListNode* n1 = new ListNode(0);
- n1 ->next = head;
- current = n1;
- num -= n;
- while(num)
- {
- num--;
- current = current ->next;
- }
- ListNode* temp = current ->next;
- current ->next = temp ->next;
- return n1 ->next;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0020._Valid_Parentheses.md b/docs/leetcode/cpp/0020._Valid_Parentheses.md
deleted file mode 100644
index 102c66ca6..000000000
--- a/docs/leetcode/cpp/0020._Valid_Parentheses.md
+++ /dev/null
@@ -1,55 +0,0 @@
-## 20. Valid Parentheses
- **难度: Easy**
-## 刷题内容
-> 原题连接
-* https://leetcode-cn.com/problems/valid-parentheses/
-> 内容描述
-```
-Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
-
-An input string is valid if:
-
-Open brackets must be closed by the same type of brackets.
-Open brackets must be closed in the correct order.
-Note that an empty string is also considered valid.
-
-### Example
-1. Input: "()" -> Output: true
-
-2. Input: "()[]{}" -> Output: true
-
-3. Input: "(]" -> Output: false
-
-4. Input: "([)]" -> Output: false
-
-5. Input: "{[]}" -> Output: true
-```
-## 解题方案
-> 思路:
-```
-利用栈先进后出的先天优势,解决匹配问题。
-```
-```cpp
-bool isValid(string s) {
- stack stacks;
- for(int i=0;i难度:Easy**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/merge-two-sorted-lists
-*
-> 内容描述
-
-```
-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.
-
-Example:
-
-Input: 1->2->4, 1->3->4
-Output: 1->1->2->3->4->4
-```
-
-## 解题方案
-
-> 思路
-******- 时间复杂度: O(N + M)******- 空间复杂度: O(1)******
-
-首先这两个链表是排序好的,那么我们先定义一个空链表,再定义两个指针 i,j,按照顺序比较两个链表,如果 i 指向的数字小于 j指向的数字,i 指向的节点插入新链表中,i = i -> next,反之则操作 j。不过要注意其中一个链表可能会先结束,所以另一个未结束的链表直接插入新链表即可
-
-
-```cpp
-/**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode(int x) : val(x), next(NULL) {}
- * };
- */
-class Solution {
-public:
- ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
- ListNode* h1 = l1;
- ListNode* h2 = l2;
- ListNode* t = new ListNode(0);
- ListNode* curr = t;
- while (h1 && h2)
- {
- if (h1->val <= h2->val) {
- curr->next = h1;
- h1 = h1->next;
- }
- else{
- curr->next = h2;
- h2 = h2->next;
- }
- curr = curr->next;
- }
- while (h1)
- {
- curr->next = h1;
- h1 = h1->next;
- curr = curr->next;
- }
- while(h2)
- {
- curr->next = h2;
- h2 = h2->next;
- curr = curr->next;
- }
- ListNode* res = t->next;
- delete t;
- return res;
- }
-};
-```
diff --git a/docs/leetcode/cpp/0022._Generate_Parentheses.md b/docs/leetcode/cpp/0022._Generate_Parentheses.md
deleted file mode 100644
index 469322c3a..000000000
--- a/docs/leetcode/cpp/0022._Generate_Parentheses.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# 22. Generate Parentheses
-
- **难度: Medium**
-
- ## 刷题内容
-
- > 原题连接
-
-* https://leetcode-cn.com/problems/generate-parentheses/
-
- > 内容描述
-
- ```
-给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。
-
-例如,给出 n = 3,生成结果为:
-
-[
- "((()))",
- "(()())",
- "(())()",
- "()(())",
- "()()()"
-]
- ```
-
-## 解题方案
-> 思路 1
-```
-回溯法
-```
-
-```cpp
-void dfs(int left, int total, string path, vector& ans){
- if(total==0&&left==0){
- ans.push_back(path);
- return ;
- }
- if(left>0)
- dfs(left-1, total-1, path+"(", ans);
- if(left generateParenthesis(int n) {
- vector ans;
- string path="";
- dfs(n, n*2, path, ans);
- return ans;
-}
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0023._Merge_K_Sorted_Lists.md b/docs/leetcode/cpp/0023._Merge_K_Sorted_Lists.md
deleted file mode 100644
index bddfa6bb4..000000000
--- a/docs/leetcode/cpp/0023._Merge_K_Sorted_Lists.md
+++ /dev/null
@@ -1,125 +0,0 @@
-# 23. merge k sorted lists
-
-**难度: Hard**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/merge-k-sorted-lists/
-
-> 内容描述
-
-```
-Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
-
-Example:
-
-Input:
-[
- 1->4->5,
- 1->3->4,
- 2->6
-]
-Output: 1->1->2->3->4->4->5->6
-```
-
-## 解题方案
-
-> 思路1
-******- 时间复杂度: O(Nlg(K))******- 空间复杂度: O(K)******
-
-这里运用最小堆,先去每个链表的第一个元素构建最小堆,由于链表都是已排序的,因此,每次堆的顶部都是最小的元素,这里用优先队列实现最小堆。
-
-
-```cpp
-/**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode(int x) : val(x), next(NULL) {}
- * };
- */
-class Solution {
-public:
- struct cmp
- {
- bool operator()(ListNode* a, ListNode* b) const
- {
- return a ->val > b ->val;
- }
- };
- ListNode* mergeKLists(vector& lists) {
- priority_queue,cmp> pq;
- ListNode* ret = nullptr;
- ListNode* current = nullptr;
- for(int i = 0;i < lists.size();++i)
- if(lists[i])
- pq.push(lists[i]);
- while(pq.size())
- {
- ListNode* temp = pq.top();
- pq.pop();
- if(!ret)
- ret = temp;
- else
- current ->next = temp;
- current = temp;
- if(temp ->next)
- pq.push(temp ->next);
- }
- return ret;
- }
-};
-```
-> 思路2
-******- 时间复杂度: O(Nlg(K))******- 空间复杂度: O(1)******
-
-这个思路用分治思想,我们可以通过归并排序解决,首先前面已经做过了两个有序链表的排序,我们可以把链表看做元素,只要对数组 Lists进行归并排序即可。
-
-```cpp
-class Solution {
-public:
- ListNode* merge(ListNode* list1, ListNode* list2) {
- ListNode head(0);
- ListNode* tail = &head;
- auto cur1 = list1;
- auto cur2 = list2;
- while (cur1 != nullptr && cur2 != nullptr) {
- if (cur1->val < cur2->val) {
- tail->next = cur1;
- tail = tail->next;
- cur1 = cur1->next;
- } else {
- tail->next = cur2;
- tail = tail->next;
- cur2 = cur2->next;
- }
- }
- auto cur = cur1 == nullptr ? cur2 : cur1;
- while (cur != nullptr) {
- tail->next = cur;
- tail = tail->next;
- cur = cur->next;
- }
- return head.next;
- }
- ListNode* mergeSort(vector& lists, int start, int end) {
- if (start > end) {
- return nullptr;
- }
- if (start == end) {
- return lists[start];
- }
- int mid = start + (end - start) / 2;
- auto list1 = mergeSort(lists, start, mid);
- auto list2 = mergeSort(lists, mid + 1, end);
- return merge(list1, list2);
- }
- ListNode* mergeKLists(vector& lists) {
- int n = lists.size();
- return mergeSort(lists, 0, n - 1);
- }
-};
-```
diff --git a/docs/leetcode/cpp/0024._Swap_Nodes_in_Pairs.md b/docs/leetcode/cpp/0024._Swap_Nodes_in_Pairs.md
deleted file mode 100644
index 4e812adab..000000000
--- a/docs/leetcode/cpp/0024._Swap_Nodes_in_Pairs.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# 24. Swap Nodes in Pairs
-
- **难度: Medium**
-
- ## 刷题内容
-
- > 原题连接
-
-* https://leetcode-cn.com/problems/swap-nodes-in-pairs/
-
- > 内容描述
-
- ```
-给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
-
-示例:
-
-给定 1->2->3->4, 你应该返回 2->1->4->3.
-说明:
-
-你的算法只能使用常数的额外空间。
-你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
- ```
-
-## 解题方案
-> 思路 1
-```
-链表反转
-```
-
-```cpp
-ListNode* swapPairs(ListNode* head) {
- if(head==NULL||head->next==NULL)
- return head;
-
- ListNode* slow=head;
- ListNode* fast=head->next;
- ListNode* pre=new ListNode(0);
- ListNode* ans = pre;
- while(slow&&fast){
- slow->next = fast->next;
- fast->next = slow;
- pre->next = fast;
- if(slow->next==NULL||slow->next->next==NULL){
- break;
- }
- fast = slow->next->next;
- pre = slow;
- slow = slow->next;
- }
- return ans->next;
-}
-```
diff --git a/docs/leetcode/cpp/0025._Reverse_Nodes_In_K_Group.md b/docs/leetcode/cpp/0025._Reverse_Nodes_In_K_Group.md
deleted file mode 100644
index cdc28074c..000000000
--- a/docs/leetcode/cpp/0025._Reverse_Nodes_In_K_Group.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# 25.reverse nodes in k group
-
-**�Ѷ�Hard**
-
-## ˢ������
-
-> ԭ������
-
-* https://leetcode.com/problems/reverse-nodes-in-k-group/
-
-> ��������
-
-```
-Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
-
-k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.
-
-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
-
-Note:
-
-Only constant extra memory is allowed.
-You may not alter the values in the list's nodes, only nodes itself may be changed.
-```
-> ˼·1
-******- ʱ�临�Ӷ�: O(N)******- �ռ临�Ӷ�: O(1)******
-
-��Ŀ�������ѣ����������˵ݹ�ķ���ȥ�⣬����Ŀ�е�note��˵�����ж���Ĵ���ռ䣬���ݹ�����ɸ����Ŀռ䣬���ѵݹ�ij�ѭ�����������»��ǵݹ�İ汾
-
-```cpp
-/**
- * Definition for singly-linked list.
- * struct ListNode {
- * int val;
- * ListNode *next;
- * ListNode(int x) : val(x), next(NULL) {}
- * };
- */
-class Solution {
-public:
- ListNode* reverseKGroup(ListNode* head, int k) {
- if(!head)
- return head;
- ListNode* current = head,*next1,*pre = nullptr;
- int m = 1;
- while(m <= k && current)
- {
- next1 = current ->next;
- current ->next = pre;
- pre = current;
- current = next1;
- ++m;
- }
- if(m <= k)
- {
- while(current != head)
- {
- ListNode* temp = pre ->next;
- pre ->next = current;
- current = pre;
- pre = temp;
- }
- pre = head;
- }
- else
- head ->next = reverseKGroup(current,k);
- return pre;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0026._Remove_Duplicates_From_Sorted_Array.md b/docs/leetcode/cpp/0026._Remove_Duplicates_From_Sorted_Array.md
deleted file mode 100644
index 9dfffb6a3..000000000
--- a/docs/leetcode/cpp/0026._Remove_Duplicates_From_Sorted_Array.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# 26.Remove Duplicates From Sorted Array
-
-**�Ѷ�Easy**
-
-## ˢ������
-
-> ԭ������
-
-* https://leetcode.com/problems/remove-duplicates-from-sorted-array/
-> ��������
-
-```
-Given a sorted array nums, 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 by modifying the input array in-place with O(1) extra memory.
-
-Example 1:
-
-Given nums = [1,1,2],
-
-Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.
-
-It doesn't matter what you leave beyond the returned length.
-Example 2:
-
-Given nums = [0,0,1,1,1,2,2,3,3,4],
-
-Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively.
-
-It doesn't matter what values are set beyond the returned length.
-Clarification:
-
-Confused why the returned value is an integer but your answer is an array?
-
-Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.
-
-Internally you can think of this:
-
-// nums is passed in by reference. (i.e., without making a copy)
-int len = removeDuplicates(nums);
-
-// any modification to nums in your function would be known by the caller.
-// using the length returned by your function, it prints the first len elements.
-for (int i = 0; i < len; i++) {
- print(nums[i]);
-}
-```
-> ˼·
-******- ʱ�临�Ӷ�: O(N)******- �ռ临�Ӷ�: O(1)******
-
-���������Ѿ�����õģ�����ֱ�ӱ������飬��һ��ָ�� i ָ��ʼ������һ�� j ָ��ڶ������� j ָ����������� i ָ���������```++i,++j```������ֻ```++j```
-
-```cpp
-class Solution {
-public:
- int removeDuplicates(vector& nums) {
- int j = 0;
- if(!nums.size())
- return 0;
- for(int i = 1;i < nums.size();)
- {
- while(nums[j] == nums[i] && i < nums.size())
- ++i;
- if(i == nums.size())
- break;
- swap(nums[++j],nums[i++]);
- }
- return j + 1;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0027._Remove_Element.md b/docs/leetcode/cpp/0027._Remove_Element.md
deleted file mode 100644
index 30694b543..000000000
--- a/docs/leetcode/cpp/0027._Remove_Element.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# 27.Remove Element
-
-**�Ѷ�Easy**
-
-## ˢ������
-> ԭ������
-
-* https://leetcode.com/problems/remove-element/
-
-> ��������
-
-```
-Given an array nums and a value val, remove all instances of that value in-place and return the new length.
-
-Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
-
-The order of elements can be changed. It doesn't matter what you leave beyond the new length.
-
-Example 1:
-
-Given nums = [3,2,2,3], val = 3,
-
-Your function should return length = 2, with the first two elements of nums being 2.
-
-It doesn't matter what you leave beyond the returned length.
-Example 2:
-
-Given nums = [0,1,2,2,3,0,4,2], val = 2,
-
-Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4.
-
-Note that the order of those five elements can be arbitrary.
-
-It doesn't matter what values are set beyond the returned length.
-Clarification:
-
-Confused why the returned value is an integer but your answer is an array?
-
-Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.
-
-Internally you can think of this:
-
-// nums is passed in by reference. (i.e., without making a copy)
-int len = removeElement(nums, val);
-
-// any modification to nums in your function would be known by the caller.
-// using the length returned by your function, it prints the first len elements.
-for (int i = 0; i < len; i++) {
- print(nums[i]);
-}
-```
-> ˼·
-******- ʱ�临�Ӷ�: O(n)******- �ռ临�Ӷ�: O(1)******
-
-���ǿ��Ա������飬�ѵ��� val �����ŵ�����ĺ�벿�־��С����ǿ�����˫ָ��ʵ�֡��� nums[i] != val ʱ��nums[j++] = nums[i]
-```cpp
-class Solution {
-public:
- int removeElement(vector& nums, int val) {
- int i ,count = 0,j = 0,numsSize = nums.size();
- for(i = 0;i < numsSize;i++)
- {
- if(nums[i] == val)
- {
- count++;
- }
- else
- nums[j++] = nums[i];
- }
- return numsSize - count;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0028._Implement_Strstr.md b/docs/leetcode/cpp/0028._Implement_Strstr.md
deleted file mode 100644
index b80786a76..000000000
--- a/docs/leetcode/cpp/0028._Implement_Strstr.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# 28.implement strstr
-
-**�Ѷ�Easy**
-
-## ˢ������
-
-> ԭ������
-
-* https://leetcode.com/problems/implement-strstr/
-> ��������
-
-```
-Implement strStr().
-
-Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
-
-Example 1:
-
-Input: haystack = "hello", needle = "ll"
-Output: 2
-Example 2:
-
-Input: haystack = "aaaaa", needle = "bba"
-Output: -1
-Clarification:
-
-What should we return when needle is an empty string? This is a great question to ask during an interview.
-
-For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf().
-```
-> ˼·
-******- ʱ�临�Ӷ�: O(N)******- �ռ临�Ӷ�: O(1)******
-
-����ֱ�ӱ��� haystack ��ƥ�䵽�� needle ��һ���ַ����ʱ���ͱ��� needle�������Ƚ��ַ���
-
-```cpp
-class Solution {
-public:
- int strStr(string haystack, string needle) {
- int j = 0,i = 0,index= 0;
- while(i < haystack.size() && j < needle.size())
- {
- if(haystack[i] == needle[j])
- {
- if(!j)
- index = i;
- j++;
- i++;
- }
- else
- {
- i = ++index;
- j = 0;
- }
- }
- if(j == needle.size())
- return index;
- return -1;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0029._Divide_Two_Integers.md b/docs/leetcode/cpp/0029._Divide_Two_Integers.md
deleted file mode 100644
index 432bb349a..000000000
--- a/docs/leetcode/cpp/0029._Divide_Two_Integers.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# 29.divide two integers
-
-**�Ѷ�Medium**
-
-## ˢ������
-
-> ԭ������
-
-* https://leetcode.com/problems/divide-two-integers/
-> ��������
-
-```
-Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.
-
-Return the quotient after dividing dividend by divisor.
-
-The integer division should truncate toward zero.
-
-Example 1:
-
-Input: dividend = 10, divisor = 3
-Output: 3
-Example 2:
-
-Input: dividend = 7, divisor = -3
-Output: -2
-Note:
-
-Both dividend and divisor will be 32-bit signed integers.
-The divisor will never be 0.
-Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [?231, 231 ? 1]. For the purpose of this problem, assume that your function returns 231 ? 1 when the division result overflows.
-
-```
-> ˼·
-******- ʱ�临�Ӷ�: O(N)******- �ռ临�Ӷ�: O(1)******
-
-�������ֱ���ñ����ķ����϶���ʱ�������������˿ռ任ʱ�䣬�������� int ���Ϊ2^31 - 1 ��������Ĵ�СҲ�ǹ̶��ġ����������ñ��������ȶ���һ��res = 0��ÿ�ζ����� res += divisor * 2^n ֱ������dividend �������ٴ� res = divisor * 2^(n-1)��ʼ��ֱ��ij��res + divisor > dividend
-
-
-```cpp
-class Solution {
-public:
- int divide(int dividend, int divisor) {
- if(!dividend)
- return 0;
- long long arr[33];
- arr[0] = 1;
- for(int i = 1;i < 33;++i)
- arr[i] = arr[i - 1] * 2;
- long long temp1 = dividend,temp2 = divisor;
- if(temp1 < 0)
- temp1 *= -1;
- if(temp2 < 0)
- temp2 *= -1;
- long long res,pre = 0,ret = 0;
- int count1 = 0;
- while(1)
- {
- res = pre + arr[count1] * temp2;
- if(res > temp1)
- {
- if(!count1)
- break;
- pre = pre + arr[count1 - 1] * temp2;
- ret += arr[count1 - 1];
- count1 = 0;
- }
- else
- count1++;
- }
- if(dividend < 0)
- ret *= -1;
- if(divisor < 0)
- ret *= -1;
- if(ret == 2147483648)
- return ret - 1;
- return ret;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0030._Substring_With_Concatenation_Of_All_Words.md b/docs/leetcode/cpp/0030._Substring_With_Concatenation_Of_All_Words.md
deleted file mode 100644
index 52efa1f10..000000000
--- a/docs/leetcode/cpp/0030._Substring_With_Concatenation_Of_All_Words.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# 30.substring with concatenation of all words
-
-**难度Hard**
-
-## 刷题内容
-
-> 原题连接
-
-* https://leetcode.com/problems/substring-with-concatenation-of-all-words/
-
-> 内容描述
-
-```
-You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.
-
-Example 1:
-
-Input:
- s = "barfoothefoobarman",
- words = ["foo","bar"]
-Output: [0,9]
-Explanation: Substrings starting at index 0 and 9 are "barfoor" and "foobar" respectively.
-The output order does not matter, returning [9,0] is fine too.
-Example 2:
-
-Input:
- s = "wordgoodstudentgoodword",
- words = ["word","student"]
-Output: []
-
-```
-> 思路
-******- 时间复杂度: O(mlgn)******- 空间复杂度: O(m+n)******
-
-这题可以两个 map 来解决,第一个 map 中存放了 words 中的所有单词和出现的次数,接下来遍历字符串,固定区间的大小为 words 的长度,存入另一个map,两个 map 相等就放入返回数组中
-
-```cpp
-class Solution {
-public:
- vector findSubstring(string s, vector& words) {
- vector ans;
- if(!s.length() || !words.size())
- return ans;
- unordered_map m1;
- int len = words.size(),wl = words[0].length(),sl = s.length();
- for(int i = 0;i < words.size();++i)
- m1[words[i]]++;
- int count1 = 0,reLen = wl * len,left = 0;
- for(int i = 0;i < sl - wl * len + 1;++i)
- {
- unordered_map m2;
- for(int j = 0,left = i;j < len;j ++)
- {
- string temp = s.substr(left,wl);
- left += wl;
- m2[temp]++;
- }
- if(m2 == m1)
- ans.push_back(i);
- }
- return ans;
- }
-};
-```
diff --git a/docs/leetcode/cpp/0031._Next_Permutatio.md b/docs/leetcode/cpp/0031._Next_Permutatio.md
deleted file mode 100644
index 5266def01..000000000
--- a/docs/leetcode/cpp/0031._Next_Permutatio.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# 31.Next Permutatio
-
-**难度Medium**
-
-## 刷题内容
-> 原题连接
-
-* https://leetcode.com/problems/next-permutation/
-
-> 内容描述
-
-```
-Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
-
-If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
-
-The replacement must be in-place and use only constant extra memory.
-
-Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
-
-1,2,3 → 1,3,2
-3,2,1 → 1,2,3
-1,1,5 → 1,5,1
-```
-> 思路
-******- 时间复杂度: O(n)******- 空间复杂度: O(1)******
-
-我们可以用两个指针表示需要交换的两个数,遍历数组。这题的最坏的情况下,数组降序排列,排序算法的复杂度也是O(n)。
-
-```cpp
-class Solution {
-public:
- void nextPermutation(vector& nums) {
- int n1 = 0,n2 = 0;
- for(int i = 1;i < nums.size();++i)
- if(nums[i] > nums[n2])
- {
- n1 = n2;
- n2 = i;
- }
- else if((nums[i] < nums[n2] && nums[i] > nums[n1]) || nums[i] == nums[n2])
- n2 = i;
- else if(nums[i] <= nums[n1])
- {
- int j = i;
- for(;j < nums.size() - 1;++j)
- if(nums[j + 1] > nums[j])
- {
- n1 = j;
- n2 = j + 1;
- break;
- }
- i = j + 1;
- }
- if(n1 == n2)
- sort(nums.begin(),nums.end());
- else
- {
- swap(nums[n1],nums[n2]);
- sort(nums.begin() + n1 + 1,nums.end());
- }
- }
-};
-```
diff --git a/docs/leetcode/cpp/0032._Longest_Valid_Parentheses.md b/docs/leetcode/cpp/0032._Longest_Valid_Parentheses.md
deleted file mode 100644
index dfa13eae0..000000000
--- a/docs/leetcode/cpp/0032._Longest_Valid_Parentheses.md
+++ /dev/null
@@ -1,57 +0,0 @@
-# 32. Longest Valid Parentheses
-
-**�Ѷ�:Hard**
-
-## ˢ������
-> ԭ������
-
-* https://leetcode.com/problems/longest-valid-parentheses/
-
-> ��������
-
-```
-Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.
-
-Example 1:
-
-Input: "(()"
-Output: 2
-Explanation: The longest valid parentheses substring is "()"
-Example 2:
-
-Input: ")()())"
-Output: 4
-Explanation: The longest valid parentheses substring is "()()"
-```
-
-> ˼·1
-******- ʱ�临�Ӷ�: O(n)******- �ռ临�Ӷ�: O(n)******
-
-��DP�ķ��������⡣������һ��ջȥ����������ߵIJ��֣���'('��λ�ã�ֱ��������һ��')'ʱ���ͼ�¼ջ����'('λ�ã����������ǾͿ���д��״̬ת�Ʒ��̡���������dp[i]�����ַ����е�i������������Զ��λ�á�����һ������')'ʱ��dp[i] = ջ��'('��λ�á����ڿ��Դ������������ţ���dp[dp[i] - 1]���ڣ���dp[i] = dp[dp[i] - 1]����Ҫע��߽缴�ɡ�
-
-```cpp
-class Solution {
-public:
- int longestValidParentheses(string s) {
- int len = s.length();
- if(!len)
- return 0;
- int dp[len];
- memset(dp,-1,sizeof(dp));
- int ans = 0;
- vector v;
- for(int i = 0;i < len;++i)
- if(s[i] == '(')
- v.push_back(i);
- else if(s[i] == ')' && v.size())
- {
- dp[i] = v[v.size() - 1];
- if(dp[i] && dp[dp[i] - 1] >= 0)
- dp[i] = dp[dp[i] - 1];
- ans = max(ans,i - dp[i] + 1);
- v.pop_back();
- }
- return ans;
- }
-};
-```
\ No newline at end of file
diff --git a/docs/leetcode/cpp/0033._Search_in_Rotated_Sorted_Array.md b/docs/leetcode/cpp/0033._Search_in_Rotated_Sorted_Array.md
deleted file mode 100644
index 275307b05..000000000
--- a/docs/leetcode/cpp/0033._Search_in_Rotated_Sorted_Array.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# 033. Search in Rotated Sorted Array
-
-**难度Medium