diff --git a/docs/notes/10.1 斐波那契数列.md b/docs/notes/10.1 斐波那契数列.md new file mode 100644 index 00000000..c2940fb9 --- /dev/null +++ b/docs/notes/10.1 斐波那契数列.md @@ -0,0 +1,67 @@ +# 10.1 斐波那契数列 + +[NowCoder](https://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3?tpId=13&tqId=11160&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +求斐波那契数列的第 n 项,n <= 39。 + + + + + +## 解题思路 + +如果使用递归求解,会重复计算一些子问题。例如,计算 f(4) 需要计算 f(3) 和 f(2),计算 f(3) 需要计算 f(2) 和 f(1),可以看到 f(2) 被重复计算了。 + + + +递归是将一个问题划分成多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,从而避免重复求解子问题。 + +```java +public int Fibonacci(int n) { + if (n <= 1) + return n; + int[] fib = new int[n + 1]; + fib[1] = 1; + for (int i = 2; i <= n; i++) + fib[i] = fib[i - 1] + fib[i - 2]; + return fib[n]; +} +``` + +考虑到第 i 项只与第 i-1 和第 i-2 项有关,因此只需要存储前两项的值就能求解第 i 项,从而将空间复杂度由 O(N) 降低为 O(1)。 + +```java +public int Fibonacci(int n) { + if (n <= 1) + return n; + int pre2 = 0, pre1 = 1; + int fib = 0; + for (int i = 2; i <= n; i++) { + fib = pre2 + pre1; + pre2 = pre1; + pre1 = fib; + } + return fib; +} +``` + +由于待求解的 n 小于 40,因此可以将前 40 项的结果先进行计算,之后就能以 O(1) 时间复杂度得到第 n 项的值。 + +```java +public class Solution { + + private int[] fib = new int[40]; + + public Solution() { + fib[1] = 1; + for (int i = 2; i < fib.length; i++) + fib[i] = fib[i - 1] + fib[i - 2]; + } + + public int Fibonacci(int n) { + return fib[n]; + } +} +``` diff --git a/docs/notes/10.2 矩形覆盖.md b/docs/notes/10.2 矩形覆盖.md new file mode 100644 index 00000000..2242e70f --- /dev/null +++ b/docs/notes/10.2 矩形覆盖.md @@ -0,0 +1,40 @@ +# 10.2 矩形覆盖 + +[NowCoder](https://www.nowcoder.com/practice/72a5a919508a4251859fb2cfb987a0e6?tpId=13&tqId=11163&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +我们可以用 2\*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2\*1 的小矩形无重叠地覆盖一个 2\*n 的大矩形,总共有多少种方法? + + + +## 解题思路 + +当 n 为 1 时,只有一种覆盖方法: + + + +当 n 为 2 时,有两种覆盖方法: + + + +要覆盖 2\*n 的大矩形,可以先覆盖 2\*1 的矩形,再覆盖 2\*(n-1) 的矩形;或者先覆盖 2\*2 的矩形,再覆盖 2\*(n-2) 的矩形。而覆盖 2\*(n-1) 和 2\*(n-2) 的矩形可以看成子问题。该问题的递推公式如下: + + + + + +```java +public int RectCover(int n) { + if (n <= 2) + return n; + int pre2 = 1, pre1 = 2; + int result = 0; + for (int i = 3; i <= n; i++) { + result = pre2 + pre1; + pre2 = pre1; + pre1 = result; + } + return result; +} +``` diff --git a/docs/notes/10.3 跳台阶.md b/docs/notes/10.3 跳台阶.md new file mode 100644 index 00000000..829dfb01 --- /dev/null +++ b/docs/notes/10.3 跳台阶.md @@ -0,0 +1,38 @@ +# 10.3 跳台阶 + +[NowCoder](https://www.nowcoder.com/practice/8c82a5b80378478f9484d87d1c5f12a4?tpId=13&tqId=11161&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 + + + +## 解题思路 + +当 n = 1 时,只有一种跳法: + + + +当 n = 2 时,有两种跳法: + + + +跳 n 阶台阶,可以先跳 1 阶台阶,再跳 n-1 阶台阶;或者先跳 2 阶台阶,再跳 n-2 阶台阶。而 n-1 和 n-2 阶台阶的跳法可以看成子问题,该问题的递推公式为: + + + +```java +public int JumpFloor(int n) { + if (n <= 2) + return n; + int pre2 = 1, pre1 = 2; + int result = 0; + for (int i = 2; i < n; i++) { + result = pre2 + pre1; + pre2 = pre1; + pre1 = result; + } + return result; +} +``` diff --git a/docs/notes/10.4 变态跳台阶.md b/docs/notes/10.4 变态跳台阶.md new file mode 100644 index 00000000..03973f3e --- /dev/null +++ b/docs/notes/10.4 变态跳台阶.md @@ -0,0 +1,58 @@ +# 10.4 变态跳台阶 + +[NowCoder](https://www.nowcoder.com/practice/22243d016f6b47f2a6928b4313c85387?tpId=13&tqId=11162&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级... 它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 + + + +## 解题思路 + +### 动态规划 + +```java +public int JumpFloorII(int target) { + int[] dp = new int[target]; + Arrays.fill(dp, 1); + for (int i = 1; i < target; i++) + for (int j = 0; j < i; j++) + dp[i] += dp[j]; + return dp[target - 1]; +} +``` + +### 数学推导 + +跳上 n-1 级台阶,可以从 n-2 级跳 1 级上去,也可以从 n-3 级跳 2 级上去...,那么 + +``` +f(n-1) = f(n-2) + f(n-3) + ... + f(0) +``` + +同样,跳上 n 级台阶,可以从 n-1 级跳 1 级上去,也可以从 n-2 级跳 2 级上去... ,那么 + +``` +f(n) = f(n-1) + f(n-2) + ... + f(0) +``` + +综上可得 + +``` +f(n) - f(n-1) = f(n-1) +``` + +即 + +``` +f(n) = 2*f(n-1) +``` + +所以 f(n) 是一个等比数列 + +```source-java +public int JumpFloorII(int target) { + return (int) Math.pow(2, target - 1); +} +``` diff --git a/docs/notes/11. 旋转数组的最小数字.md b/docs/notes/11. 旋转数组的最小数字.md new file mode 100644 index 00000000..688fc161 --- /dev/null +++ b/docs/notes/11. 旋转数组的最小数字.md @@ -0,0 +1,65 @@ +# 11. 旋转数组的最小数字 + +[NowCoder](https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=13&tqId=11159&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 + + + +## 解题思路 + +将旋转数组对半分可以得到一个包含最小元素的新旋转数组,以及一个非递减排序的数组。新的旋转数组的数组元素是原数组的一半,从而将问题规模减少了一半,这种折半性质的算法的时间复杂度为 O(logN)(为了方便,这里将 log2N 写为 logN)。 + + + +此时问题的关键在于确定对半分得到的两个数组哪一个是旋转数组,哪一个是非递减数组。我们很容易知道非递减数组的第一个元素一定小于等于最后一个元素。 + +通过修改二分查找算法进行求解(l 代表 low,m 代表 mid,h 代表 high): + +- 当 nums[m] <= nums[h] 时,表示 [m, h] 区间内的数组是非递减数组,[l, m] 区间内的数组是旋转数组,此时令 h = m; +- 否则 [m + 1, h] 区间内的数组是旋转数组,令 l = m + 1。 + +```java +public int minNumberInRotateArray(int[] nums) { + if (nums.length == 0) + return 0; + int l = 0, h = nums.length - 1; + while (l < h) { + int m = l + (h - l) / 2; + if (nums[m] <= nums[h]) + h = m; + else + l = m + 1; + } + return nums[l]; +} +``` + +如果数组元素允许重复,会出现一个特殊的情况:nums[l] == nums[m] == nums[h],此时无法确定解在哪个区间,需要切换到顺序查找。例如对于数组 {1,1,1,0,1},l、m 和 h 指向的数都为 1,此时无法知道最小数字 0 在哪个区间。 + +```java +public int minNumberInRotateArray(int[] nums) { + if (nums.length == 0) + return 0; + int l = 0, h = nums.length - 1; + while (l < h) { + int m = l + (h - l) / 2; + if (nums[l] == nums[m] && nums[m] == nums[h]) + return minNumber(nums, l, h); + else if (nums[m] <= nums[h]) + h = m; + else + l = m + 1; + } + return nums[l]; +} + +private int minNumber(int[] nums, int l, int h) { + for (int i = l; i < h; i++) + if (nums[i] > nums[i + 1]) + return nums[i + 1]; + return nums[l]; +} +``` diff --git a/docs/notes/12. 矩阵中的路径.md b/docs/notes/12. 矩阵中的路径.md new file mode 100644 index 00000000..06a410d8 --- /dev/null +++ b/docs/notes/12. 矩阵中的路径.md @@ -0,0 +1,64 @@ +# 12. 矩阵中的路径 + +[NowCoder](https://www.nowcoder.com/practice/c61c6999eecb4b8f88a98f66b273a3cc?tpId=13&tqId=11218&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向上下左右移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 + +例如下面的矩阵包含了一条 bfce 路径。 + + + +## 解题思路 + +使用回溯法(backtracking)进行求解,它是一种暴力搜索方法,通过搜索所有可能的结果来求解问题。回溯法在一次搜索结束时需要进行回溯(回退),将这一次搜索过程中设置的状态进行清除,从而开始一次新的搜索过程。例如下图示例中,从 f 开始,下一步有 4 种搜索可能,如果先搜索 b,需要将 b 标记为已经使用,防止重复使用。在这一次搜索结束之后,需要将 b 的已经使用状态清除,并搜索 c。 + + + +本题的输入是数组而不是矩阵(二维数组),因此需要先将数组转换成矩阵。 + +```java +private final static int[][] next = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}}; +private int rows; +private int cols; + +public boolean hasPath(char[] array, int rows, int cols, char[] str) { + if (rows == 0 || cols == 0) return false; + this.rows = rows; + this.cols = cols; + boolean[][] marked = new boolean[rows][cols]; + char[][] matrix = buildMatrix(array); + for (int i = 0; i < rows; i++) + for (int j = 0; j < cols; j++) + if (backtracking(matrix, str, marked, 0, i, j)) + return true; + + return false; +} + +private boolean backtracking(char[][] matrix, char[] str, + boolean[][] marked, int pathLen, int r, int c) { + + if (pathLen == str.length) return true; + if (r < 0 || r >= rows || c < 0 || c >= cols + || matrix[r][c] != str[pathLen] || marked[r][c]) { + + return false; + } + marked[r][c] = true; + for (int[] n : next) + if (backtracking(matrix, str, marked, pathLen + 1, r + n[0], c + n[1])) + return true; + marked[r][c] = false; + return false; +} + +private char[][] buildMatrix(char[] array) { + char[][] matrix = new char[rows][cols]; + for (int r = 0, idx = 0; r < rows; r++) + for (int c = 0; c < cols; c++) + matrix[r][c] = array[idx++]; + return matrix; +} +``` diff --git a/docs/notes/13. 机器人的运动范围.md b/docs/notes/13. 机器人的运动范围.md new file mode 100644 index 00000000..766b1bd6 --- /dev/null +++ b/docs/notes/13. 机器人的运动范围.md @@ -0,0 +1,58 @@ +# 13. 机器人的运动范围 + +[NowCoder](https://www.nowcoder.com/practice/6e5207314b5241fb83f2329e89fdecc8?tpId=13&tqId=11219&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +地上有一个 m 行和 n 列的方格。一个机器人从坐标 (0, 0) 的格子开始移动,每一次只能向左右上下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 k 的格子。 + +例如,当 k 为 18 时,机器人能够进入方格 (35,37),因为 3+5+3+7=18。但是,它不能进入方格 (35,38),因为 3+5+3+8=19。请问该机器人能够达到多少个格子? + +## 解题思路 + +使用深度优先搜索(Depth First Search,DFS)方法进行求解。回溯是深度优先搜索的一种特例,它在一次搜索过程中需要设置一些本次搜索过程的局部状态,并在本次搜索结束之后清除状态。而普通的深度优先搜索并不需要使用这些局部状态,虽然还是有可能设置一些全局状态。 + +```java +private static final int[][] next = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}}; +private int cnt = 0; +private int rows; +private int cols; +private int threshold; +private int[][] digitSum; + +public int movingCount(int threshold, int rows, int cols) { + this.rows = rows; + this.cols = cols; + this.threshold = threshold; + initDigitSum(); + boolean[][] marked = new boolean[rows][cols]; + dfs(marked, 0, 0); + return cnt; +} + +private void dfs(boolean[][] marked, int r, int c) { + if (r < 0 || r >= rows || c < 0 || c >= cols || marked[r][c]) + return; + marked[r][c] = true; + if (this.digitSum[r][c] > this.threshold) + return; + cnt++; + for (int[] n : next) + dfs(marked, r + n[0], c + n[1]); +} + +private void initDigitSum() { + int[] digitSumOne = new int[Math.max(rows, cols)]; + for (int i = 0; i < digitSumOne.length; i++) { + int n = i; + while (n > 0) { + digitSumOne[i] += n % 10; + n /= 10; + } + } + this.digitSum = new int[rows][cols]; + for (int i = 0; i < this.rows; i++) + for (int j = 0; j < this.cols; j++) + this.digitSum[i][j] = digitSumOne[i] + digitSumOne[j]; +} +``` diff --git a/docs/notes/14. 剪绳子.md b/docs/notes/14. 剪绳子.md new file mode 100644 index 00000000..b3fd9478 --- /dev/null +++ b/docs/notes/14. 剪绳子.md @@ -0,0 +1,52 @@ +# 14. 剪绳子 + +[Leetcode](https://leetcode.com/problems/integer-break/description/) + +## 题目描述 + +把一根绳子剪成多段,并且使得每段的长度乘积最大。 + +```html +n = 2 +return 1 (2 = 1 + 1) + +n = 10 +return 36 (10 = 3 + 3 + 4) +``` + +## 解题思路 + +### 贪心 + +尽可能多剪长度为 3 的绳子,并且不允许有长度为 1 的绳子出现。如果出现了,就从已经切好长度为 3 的绳子中拿出一段与长度为 1 的绳子重新组合,把它们切成两段长度为 2 的绳子。 + +证明:当 n >= 5 时,3(n - 3) - n = 2n - 9 > 0,且 2(n - 2) - n = n - 4 > 0。因此在 n >= 5 的情况下,将绳子剪成一段为 2 或者 3,得到的乘积会更大。又因为 3(n - 3) - 2(n - 2) = n - 5 >= 0,所以剪成一段长度为 3 比长度为 2 得到的乘积更大。 + +```java +public int integerBreak(int n) { + if (n < 2) + return 0; + if (n == 2) + return 1; + if (n == 3) + return 2; + int timesOf3 = n / 3; + if (n - timesOf3 * 3 == 1) + timesOf3--; + int timesOf2 = (n - timesOf3 * 3) / 2; + return (int) (Math.pow(3, timesOf3)) * (int) (Math.pow(2, timesOf2)); +} +``` + +### 动态规划 + +```java +public int integerBreak(int n) { + int[] dp = new int[n + 1]; + dp[1] = 1; + for (int i = 2; i <= n; i++) + for (int j = 1; j < i; j++) + dp[i] = Math.max(dp[i], Math.max(j * (i - j), dp[j] * (i - j))); + return dp[n]; +} +``` diff --git a/docs/notes/15. 二进制中 1 的个数.md b/docs/notes/15. 二进制中 1 的个数.md new file mode 100644 index 00000000..703e6211 --- /dev/null +++ b/docs/notes/15. 二进制中 1 的个数.md @@ -0,0 +1,40 @@ +# 15. 二进制中 1 的个数 + +[NowCoder](https://www.nowcoder.com/practice/8ee967e43c2c4ec193b040ea7fbb10b8?tpId=13&tqId=11164&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个整数,输出该数二进制表示中 1 的个数。 + +### n&(n-1) + +该位运算去除 n 的位级表示中最低的那一位。 + +``` +n : 10110100 +n-1 : 10110011 +n&(n-1) : 10110000 +``` + +时间复杂度:O(M),其中 M 表示 1 的个数。 + + +```java +public int NumberOf1(int n) { + int cnt = 0; + while (n != 0) { + cnt++; + n &= (n - 1); + } + return cnt; +} +``` + + +### Integer.bitCount() + +```java +public int NumberOf1(int n) { + return Integer.bitCount(n); +} +``` diff --git a/docs/notes/16. 数值的整数次方.md b/docs/notes/16. 数值的整数次方.md new file mode 100644 index 00000000..286f3fe6 --- /dev/null +++ b/docs/notes/16. 数值的整数次方.md @@ -0,0 +1,36 @@ +# 16. 数值的整数次方 + +[NowCoder](https://www.nowcoder.com/practice/1a834e5e3e1a4b7ba251417554e07c00?tpId=13&tqId=11165&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +给定一个 double 类型的浮点数 base 和 int 类型的整数 exponent,求 base 的 exponent 次方。 + +## 解题思路 + +下面的讨论中 x 代表 base,n 代表 exponent。 + + + + + + +因为 (x\*x)n/2 可以通过递归求解,并且每次递归 n 都减小一半,因此整个算法的时间复杂度为 O(logN)。 + +```java +public double Power(double base, int exponent) { + if (exponent == 0) + return 1; + if (exponent == 1) + return base; + boolean isNegative = false; + if (exponent < 0) { + exponent = -exponent; + isNegative = true; + } + double pow = Power(base * base, exponent / 2); + if (exponent % 2 != 0) + pow = pow * base; + return isNegative ? 1 / pow : pow; +} +``` diff --git a/docs/notes/17. 打印从 1 到最大的 n 位数.md b/docs/notes/17. 打印从 1 到最大的 n 位数.md new file mode 100644 index 00000000..4a05f379 --- /dev/null +++ b/docs/notes/17. 打印从 1 到最大的 n 位数.md @@ -0,0 +1,40 @@ +# 17. 打印从 1 到最大的 n 位数 + +## 题目描述 + +输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数即 999。 + +## 解题思路 + +由于 n 可能会非常大,因此不能直接用 int 表示数字,而是用 char 数组进行存储。 + +使用回溯法得到所有的数。 + +```java +public void print1ToMaxOfNDigits(int n) { + if (n <= 0) + return; + char[] number = new char[n]; + print1ToMaxOfNDigits(number, 0); +} + +private void print1ToMaxOfNDigits(char[] number, int digit) { + if (digit == number.length) { + printNumber(number); + return; + } + for (int i = 0; i < 10; i++) { + number[digit] = (char) (i + '0'); + print1ToMaxOfNDigits(number, digit + 1); + } +} + +private void printNumber(char[] number) { + int index = 0; + while (index < number.length && number[index] == '0') + index++; + while (index < number.length) + System.out.print(number[index++]); + System.out.println(); +} +``` diff --git a/docs/notes/18.1 在 O(1) 时间内删除链表节点.md b/docs/notes/18.1 在 O(1) 时间内删除链表节点.md new file mode 100644 index 00000000..769dd08e --- /dev/null +++ b/docs/notes/18.1 在 O(1) 时间内删除链表节点.md @@ -0,0 +1,37 @@ +# 18.1 在 O(1) 时间内删除链表节点 + +## 解题思路 + +① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,然后令该节点指向下下个节点,再删除下一个节点,时间复杂度为 O(1)。 + + + +② 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向 null,时间复杂度为 O(N)。 + + + +综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个尾节点以 O(N) 的时间复杂度操作节点的总次数。(2N-1)/N \~ 2,因此该算法的平均时间复杂度为 O(1)。 + +```java +public ListNode deleteNode(ListNode head, ListNode tobeDelete) { + if (head == null || tobeDelete == null) + return null; + if (tobeDelete.next != null) { + // 要删除的节点不是尾节点 + ListNode next = tobeDelete.next; + tobeDelete.val = next.val; + tobeDelete.next = next.next; + } else { + if (head == tobeDelete) + // 只有一个节点 + head = null; + else { + ListNode cur = head; + while (cur.next != tobeDelete) + cur = cur.next; + cur.next = null; + } + } + return head; +} +``` diff --git a/docs/notes/18.2 删除链表中重复的结点.md b/docs/notes/18.2 删除链表中重复的结点.md new file mode 100644 index 00000000..09d0d419 --- /dev/null +++ b/docs/notes/18.2 删除链表中重复的结点.md @@ -0,0 +1,25 @@ +# 18.2 删除链表中重复的结点 + +[NowCoder](https://www.nowcoder.com/practice/fc533c45b73a41b0b44ccba763f866ef?tpId=13&tqId=11209&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + + + +## 解题描述 + +```java +public ListNode deleteDuplication(ListNode pHead) { + if (pHead == null || pHead.next == null) + return pHead; + ListNode next = pHead.next; + if (pHead.val == next.val) { + while (next != null && pHead.val == next.val) + next = next.next; + return deleteDuplication(next); + } else { + pHead.next = deleteDuplication(pHead.next); + return pHead; + } +} +``` diff --git a/docs/notes/19. 正则表达式匹配.md b/docs/notes/19. 正则表达式匹配.md new file mode 100644 index 00000000..97de47d7 --- /dev/null +++ b/docs/notes/19. 正则表达式匹配.md @@ -0,0 +1,40 @@ +# 19. 正则表达式匹配 + +[NowCoder](https://www.nowcoder.com/practice/45327ae22b7b413ea21df13ee7d6429c?tpId=13&tqId=11205&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +请实现一个函数用来匹配包括 '.' 和 '\*' 的正则表达式。模式中的字符 '.' 表示任意一个字符,而 '\*' 表示它前面的字符可以出现任意次(包含 0 次)。 + +在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串 "aaa" 与模式 "a.a" 和 "ab\*ac\*a" 匹配,但是与 "aa.a" 和 "ab\*a" 均不匹配。 + +## 解题思路 + +应该注意到,'.' 是用来当做一个任意字符,而 '\*' 是用来重复前面的字符。这两个的作用不同,不能把 '.' 的作用和 '\*' 进行类比,从而把它当成重复前面字符一次。 + +```java +public boolean match(char[] str, char[] pattern) { + + int m = str.length, n = pattern.length; + boolean[][] dp = new boolean[m + 1][n + 1]; + + dp[0][0] = true; + for (int i = 1; i <= n; i++) + if (pattern[i - 1] == '*') + dp[0][i] = dp[0][i - 2]; + + for (int i = 1; i <= m; i++) + for (int j = 1; j <= n; j++) + if (str[i - 1] == pattern[j - 1] || pattern[j - 1] == '.') + dp[i][j] = dp[i - 1][j - 1]; + else if (pattern[j - 1] == '*') + if (pattern[j - 2] == str[i - 1] || pattern[j - 2] == '.') { + dp[i][j] |= dp[i][j - 1]; // a* counts as single a + dp[i][j] |= dp[i - 1][j]; // a* counts as multiple a + dp[i][j] |= dp[i][j - 2]; // a* counts as empty + } else + dp[i][j] = dp[i][j - 2]; // a* only counts as empty + + return dp[m][n]; +} +``` diff --git a/docs/notes/20. 表示数值的字符串.md b/docs/notes/20. 表示数值的字符串.md new file mode 100644 index 00000000..c03369ba --- /dev/null +++ b/docs/notes/20. 表示数值的字符串.md @@ -0,0 +1,49 @@ +# 20. 表示数值的字符串 + +[NowCoder](https://www.nowcoder.com/practice/6f8c901d091949a5837e24bb82a731f2?tpId=13&tqId=11206&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +``` +true + +"+100" +"5e2" +"-123" +"3.1416" +"-1E-16" +``` + +``` +false + +"12e" +"1a3.14" +"1.2.3" +"+-5" +"12e+4.3" +``` + + +## 解题思路 + +使用正则表达式进行匹配。 + +```html +[] : 字符集合 +() : 分组 +? : 重复 0 ~ 1 次 ++ : 重复 1 ~ n 次 +* : 重复 0 ~ n 次 +. : 任意字符 +\\. : 转义后的 . +\\d : 数字 +``` + +```java +public boolean isNumeric(char[] str) { + if (str == null || str.length == 0) + return false; + return new String(str).matches("[+-]?\\d*(\\.\\d+)?([eE][+-]?\\d+)?"); +} +``` diff --git a/docs/notes/21. 调整数组顺序使奇数位于偶数前面.md b/docs/notes/21. 调整数组顺序使奇数位于偶数前面.md new file mode 100644 index 00000000..631a718d --- /dev/null +++ b/docs/notes/21. 调整数组顺序使奇数位于偶数前面.md @@ -0,0 +1,60 @@ +# 21. 调整数组顺序使奇数位于偶数前面 + +[NowCoder](https://www.nowcoder.com/practice/beb5aa231adc45b2a5dcc5b62c93f593?tpId=13&tqId=11166&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +需要保证奇数和奇数,偶数和偶数之间的相对位置不变,这和书本不太一样。 + + + +## 解题思路 + +方法一:创建一个新数组,时间复杂度 O(N),空间复杂度 O(N)。 + +```java +public void reOrderArray(int[] nums) { + // 奇数个数 + int oddCnt = 0; + for (int x : nums) + if (!isEven(x)) + oddCnt++; + int[] copy = nums.clone(); + int i = 0, j = oddCnt; + for (int num : copy) { + if (num % 2 == 1) + nums[i++] = num; + else + nums[j++] = num; + } +} + +private boolean isEven(int x) { + return x % 2 == 0; +} +``` + +方法二:使用冒泡思想,每次都当前偶数上浮到当前最右边。时间复杂度 O(N2),空间复杂度 O(1),时间换空间。 + +```java +public void reOrderArray(int[] nums) { + int N = nums.length; + for (int i = N - 1; i > 0; i--) { + for (int j = 0; j < i; j++) { + if (isEven(nums[j]) && !isEven(nums[j + 1])) { + swap(nums, j, j + 1); + } + } + } +} + +private boolean isEven(int x) { + return x % 2 == 0; +} + +private void swap(int[] nums, int i, int j) { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; +} +``` diff --git a/docs/notes/22. 链表中倒数第 K 个结点.md b/docs/notes/22. 链表中倒数第 K 个结点.md new file mode 100644 index 00000000..fdd8e250 --- /dev/null +++ b/docs/notes/22. 链表中倒数第 K 个结点.md @@ -0,0 +1,27 @@ +# 22. 链表中倒数第 K 个结点 + +[NowCoder](https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&tqId=11167&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +设链表的长度为 N。设置两个指针 P1 和 P2,先让 P1 移动 K 个节点,则还有 N - K 个节点可以移动。此时让 P1 和 P2 同时移动,可以知道当 P1 移动到链表结尾时,P2 移动到第 N - K 个节点处,该位置就是倒数第 K 个节点。 + + + +```java +public ListNode FindKthToTail(ListNode head, int k) { + if (head == null) + return null; + ListNode P1 = head; + while (P1 != null && k-- > 0) + P1 = P1.next; + if (k > 0) + return null; + ListNode P2 = head; + while (P1 != null) { + P1 = P1.next; + P2 = P2.next; + } + return P2; +} +``` diff --git a/docs/notes/23. 链表中环的入口结点.md b/docs/notes/23. 链表中环的入口结点.md new file mode 100644 index 00000000..8623d6a9 --- /dev/null +++ b/docs/notes/23. 链表中环的入口结点.md @@ -0,0 +1,33 @@ +# 23. 链表中环的入口结点 + +[NowCoder](https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4?tpId=13&tqId=11208&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +一个链表中包含环,请找出该链表的环的入口结点。要求不能使用额外的空间。 + +## 解题思路 + +使用双指针,一个指针 fast 每次移动两个节点,一个指针 slow 每次移动一个节点。因为存在环,所以两个指针必定相遇在环中的某个节点上。假设相遇点在下图的 z1 位置,此时 fast 移动的节点数为 x+2y+z,slow 为 x+y,由于 fast 速度比 slow 快一倍,因此 x+2y+z=2(x+y),得到 x=z。 + +在相遇点,slow 要到环的入口点还需要移动 z 个节点,如果让 fast 重新从头开始移动,并且速度变为每次移动一个节点,那么它到环入口点还需要移动 x 个节点。在上面已经推导出 x=z,因此 fast 和 slow 将在环入口点相遇。 + + + +```java +public ListNode EntryNodeOfLoop(ListNode pHead) { + if (pHead == null || pHead.next == null) + return null; + ListNode slow = pHead, fast = pHead; + do { + fast = fast.next.next; + slow = slow.next; + } while (slow != fast); + fast = pHead; + while (slow != fast) { + slow = slow.next; + fast = fast.next; + } + return slow; +} +``` diff --git a/docs/notes/24. 反转链表.md b/docs/notes/24. 反转链表.md new file mode 100644 index 00000000..05bc439f --- /dev/null +++ b/docs/notes/24. 反转链表.md @@ -0,0 +1,36 @@ +# 24. 反转链表 + +[NowCoder](https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca?tpId=13&tqId=11168&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +### 递归 + +```java +public ListNode ReverseList(ListNode head) { + if (head == null || head.next == null) + return head; + ListNode next = head.next; + head.next = null; + ListNode newHead = ReverseList(next); + next.next = head; + return newHead; +} +``` + +### 迭代 + +使用头插法。 + +```java +public ListNode ReverseList(ListNode head) { + ListNode newList = new ListNode(-1); + while (head != null) { + ListNode next = head.next; + head.next = newList.next; + newList.next = head; + head = next; + } + return newList.next; +} +``` diff --git a/docs/notes/25. 合并两个排序的链表.md b/docs/notes/25. 合并两个排序的链表.md new file mode 100644 index 00000000..4923e835 --- /dev/null +++ b/docs/notes/25. 合并两个排序的链表.md @@ -0,0 +1,51 @@ +# 25. 合并两个排序的链表 + +[NowCoder](https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337?tpId=13&tqId=11169&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + + + +## 解题思路 + +### 递归 + +```java +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; + } else { + list2.next = Merge(list1, list2.next); + return list2; + } +} +``` + +### 迭代 + +```java +public ListNode Merge(ListNode list1, ListNode list2) { + ListNode head = new ListNode(-1); + ListNode cur = head; + while (list1 != null && list2 != null) { + if (list1.val <= list2.val) { + cur.next = list1; + list1 = list1.next; + } else { + cur.next = list2; + list2 = list2.next; + } + cur = cur.next; + } + if (list1 != null) + cur.next = list1; + if (list2 != null) + cur.next = list2; + return head.next; +} +``` diff --git a/docs/notes/26. 树的子结构.md b/docs/notes/26. 树的子结构.md new file mode 100644 index 00000000..79dabc80 --- /dev/null +++ b/docs/notes/26. 树的子结构.md @@ -0,0 +1,27 @@ +# 26. 树的子结构 + +[NowCoder](https://www.nowcoder.com/practice/6e196c44c7004d15b1610b9afca8bd88?tpId=13&tqId=11170&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + + + +## 解题思路 + +```java +public boolean HasSubtree(TreeNode root1, TreeNode root2) { + if (root1 == null || root2 == null) + return false; + return isSubtreeWithRoot(root1, root2) || HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2); +} + +private boolean isSubtreeWithRoot(TreeNode root1, TreeNode root2) { + if (root2 == null) + return true; + if (root1 == null) + return false; + if (root1.val != root2.val) + return false; + return isSubtreeWithRoot(root1.left, root2.left) && isSubtreeWithRoot(root1.right, root2.right); +} +``` diff --git a/docs/notes/27. 二叉树的镜像.md b/docs/notes/27. 二叉树的镜像.md new file mode 100644 index 00000000..3a55d573 --- /dev/null +++ b/docs/notes/27. 二叉树的镜像.md @@ -0,0 +1,25 @@ +# 27. 二叉树的镜像 + +[NowCoder](https://www.nowcoder.com/practice/564f4c26aa584921bc75623e48ca3011?tpId=13&tqId=11171&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + + + +## 解题思路 + +```java +public void Mirror(TreeNode root) { + if (root == null) + return; + swap(root); + Mirror(root.left); + Mirror(root.right); +} + +private void swap(TreeNode root) { + TreeNode t = root.left; + root.left = root.right; + root.right = t; +} +``` diff --git a/docs/notes/28. 对称的二叉树.md b/docs/notes/28. 对称的二叉树.md new file mode 100644 index 00000000..0a258ec6 --- /dev/null +++ b/docs/notes/28. 对称的二叉树.md @@ -0,0 +1,27 @@ +# 28. 对称的二叉树 + +[NowCoder](https://www.nowcoder.com/practice/ff05d44dfdb04e1d83bdbdab320efbcb?tpId=13&tqId=11211&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + + + +## 解题思路 + +```java +boolean isSymmetrical(TreeNode pRoot) { + if (pRoot == null) + return true; + return isSymmetrical(pRoot.left, pRoot.right); +} + +boolean isSymmetrical(TreeNode t1, TreeNode t2) { + if (t1 == null && t2 == null) + return true; + if (t1 == null || t2 == null) + return false; + if (t1.val != t2.val) + return false; + return isSymmetrical(t1.left, t2.right) && isSymmetrical(t1.right, t2.left); +} +``` diff --git a/docs/notes/29. 顺时针打印矩阵.md b/docs/notes/29. 顺时针打印矩阵.md new file mode 100644 index 00000000..7ac6adb5 --- /dev/null +++ b/docs/notes/29. 顺时针打印矩阵.md @@ -0,0 +1,32 @@ +# 29. 顺时针打印矩阵 + +[NowCoder](https://www.nowcoder.com/practice/9b4c81a02cd34f76be2659fa0d54342a?tpId=13&tqId=11172&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +下图的矩阵顺时针打印结果为:1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10 + + + +## 解题思路 + +```java +public ArrayList printMatrix(int[][] matrix) { + ArrayList ret = new ArrayList<>(); + int r1 = 0, r2 = matrix.length - 1, c1 = 0, c2 = matrix[0].length - 1; + while (r1 <= r2 && c1 <= c2) { + for (int i = c1; i <= c2; i++) + ret.add(matrix[r1][i]); + for (int i = r1 + 1; i <= r2; i++) + ret.add(matrix[i][c2]); + if (r1 != r2) + for (int i = c2 - 1; i >= c1; i--) + ret.add(matrix[r2][i]); + if (c1 != c2) + for (int i = r2 - 1; i > r1; i--) + ret.add(matrix[i][c1]); + r1++; r2--; c1++; c2--; + } + return ret; +} +``` diff --git a/docs/notes/3. 数组中重复的数字.md b/docs/notes/3. 数组中重复的数字.md new file mode 100644 index 00000000..306e6edd --- /dev/null +++ b/docs/notes/3. 数组中重复的数字.md @@ -0,0 +1,49 @@ +# 3. 数组中重复的数字 + +[NowCoder](https://www.nowcoder.com/practice/623a5ac0ea5b4e5f95552655361ae0a8?tpId=13&tqId=11203&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 + +```html +Input: +{2, 3, 1, 0, 2, 5} + +Output: +2 +``` + +## 解题思路 + +要求时间复杂度 O(N),空间复杂度 O(1)。因此不能使用排序的方法,也不能使用额外的标记数组。 + +对于这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素调整到第 i 个位置上进行求解。 + +以 (2, 3, 1, 0, 2, 5) 为例,遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复: + + + + +```java +public boolean duplicate(int[] nums, int length, int[] duplication) { + if (nums == null || length <= 0) + return false; + for (int i = 0; i < length; i++) { + while (nums[i] != i) { + if (nums[i] == nums[nums[i]]) { + duplication[0] = nums[i]; + return true; + } + swap(nums, i, nums[i]); + } + } + return false; +} + +private void swap(int[] nums, int i, int j) { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; +} +``` diff --git a/docs/notes/30. 包含 min 函数的栈.md b/docs/notes/30. 包含 min 函数的栈.md new file mode 100644 index 00000000..49bc324a --- /dev/null +++ b/docs/notes/30. 包含 min 函数的栈.md @@ -0,0 +1,32 @@ +# 30. 包含 min 函数的栈 + +[NowCoder](https://www.nowcoder.com/practice/4c776177d2c04c2494f2555c9fcc1e49?tpId=13&tqId=11173&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的 min 函数。 + +## 解题思路 + +```java +private Stack dataStack = new Stack<>(); +private Stack minStack = new Stack<>(); + +public void push(int node) { + dataStack.push(node); + minStack.push(minStack.isEmpty() ? node : Math.min(minStack.peek(), node)); +} + +public void pop() { + dataStack.pop(); + minStack.pop(); +} + +public int top() { + return dataStack.peek(); +} + +public int min() { + return minStack.peek(); +} +``` diff --git a/docs/notes/31. 栈的压入、弹出序列.md b/docs/notes/31. 栈的压入、弹出序列.md new file mode 100644 index 00000000..4ecea9f0 --- /dev/null +++ b/docs/notes/31. 栈的压入、弹出序列.md @@ -0,0 +1,29 @@ +# 31. 栈的压入、弹出序列 + +[NowCoder](https://www.nowcoder.com/practice/d77d11405cc7470d82554cb392585106?tpId=13&tqId=11174&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。 + +例如序列 1,2,3,4,5 是某栈的压入顺序,序列 4,5,3,2,1 是该压栈序列对应的一个弹出序列,但 4,3,5,1,2 就不可能是该压栈序列的弹出序列。 + +## 解题思路 + +使用一个栈来模拟压入弹出操作。 + +```java +public boolean IsPopOrder(int[] pushSequence, int[] popSequence) { + int n = pushSequence.length; + Stack stack = new Stack<>(); + for (int pushIndex = 0, popIndex = 0; pushIndex < n; pushIndex++) { + stack.push(pushSequence[pushIndex]); + while (popIndex < n && !stack.isEmpty() + && stack.peek() == popSequence[popIndex]) { + stack.pop(); + popIndex++; + } + } + return stack.isEmpty(); +} +``` diff --git a/docs/notes/32.1 从上往下打印二叉树.md b/docs/notes/32.1 从上往下打印二叉树.md new file mode 100644 index 00000000..92046582 --- /dev/null +++ b/docs/notes/32.1 从上往下打印二叉树.md @@ -0,0 +1,37 @@ +# 32.1 从上往下打印二叉树 + +[NowCoder](https://www.nowcoder.com/practice/7fe2212963db4790b57431d9ed259701?tpId=13&tqId=11175&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +从上往下打印出二叉树的每个节点,同层节点从左至右打印。 + +例如,以下二叉树层次遍历的结果为:1,2,3,4,5,6,7 + + + +## 解题思路 + +使用队列来进行层次遍历。 + +不需要使用两个队列分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。 + +```java +public ArrayList PrintFromTopToBottom(TreeNode root) { + Queue queue = new LinkedList<>(); + ArrayList ret = new ArrayList<>(); + queue.add(root); + while (!queue.isEmpty()) { + int cnt = queue.size(); + while (cnt-- > 0) { + TreeNode t = queue.poll(); + if (t == null) + continue; + ret.add(t.val); + queue.add(t.left); + queue.add(t.right); + } + } + return ret; +} +``` diff --git a/docs/notes/32.2 把二叉树打印成多行.md b/docs/notes/32.2 把二叉树打印成多行.md new file mode 100644 index 00000000..2366963c --- /dev/null +++ b/docs/notes/32.2 把二叉树打印成多行.md @@ -0,0 +1,32 @@ +# 32.2 把二叉树打印成多行 + +[NowCoder](https://www.nowcoder.com/practice/445c44d982d04483b04a54f298796288?tpId=13&tqId=11213&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +和上题几乎一样。 + +## 解题思路 + +```java +ArrayList> Print(TreeNode pRoot) { + ArrayList> ret = new ArrayList<>(); + Queue queue = new LinkedList<>(); + queue.add(pRoot); + while (!queue.isEmpty()) { + ArrayList list = new ArrayList<>(); + int cnt = queue.size(); + while (cnt-- > 0) { + TreeNode node = queue.poll(); + if (node == null) + continue; + list.add(node.val); + queue.add(node.left); + queue.add(node.right); + } + if (list.size() != 0) + ret.add(list); + } + return ret; +} +``` diff --git a/docs/notes/32.3 按之字形顺序打印二叉树.md b/docs/notes/32.3 按之字形顺序打印二叉树.md new file mode 100644 index 00000000..640caaad --- /dev/null +++ b/docs/notes/32.3 按之字形顺序打印二叉树.md @@ -0,0 +1,36 @@ +# 32.3 按之字形顺序打印二叉树 + +[NowCoder](https://www.nowcoder.com/practice/91b69814117f4e8097390d107d2efbe0?tpId=13&tqId=11212&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。 + +## 解题思路 + +```java +public ArrayList> Print(TreeNode pRoot) { + ArrayList> ret = new ArrayList<>(); + Queue queue = new LinkedList<>(); + queue.add(pRoot); + boolean reverse = false; + while (!queue.isEmpty()) { + ArrayList list = new ArrayList<>(); + int cnt = queue.size(); + while (cnt-- > 0) { + TreeNode node = queue.poll(); + if (node == null) + continue; + list.add(node.val); + queue.add(node.left); + queue.add(node.right); + } + if (reverse) + Collections.reverse(list); + reverse = !reverse; + if (list.size() != 0) + ret.add(list); + } + return ret; +} +``` diff --git a/docs/notes/33. 二叉搜索树的后序遍历序列.md b/docs/notes/33. 二叉搜索树的后序遍历序列.md new file mode 100644 index 00000000..24dd9832 --- /dev/null +++ b/docs/notes/33. 二叉搜索树的后序遍历序列.md @@ -0,0 +1,34 @@ +# 33. 二叉搜索树的后序遍历序列 + +[NowCoder](https://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd?tpId=13&tqId=11176&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。假设输入的数组的任意两个数字都互不相同。 + +例如,下图是后序遍历序列 1,3,2 所对应的二叉搜索树。 + + + +## 解题思路 + +```java +public boolean VerifySquenceOfBST(int[] sequence) { + if (sequence == null || sequence.length == 0) + return false; + return verify(sequence, 0, sequence.length - 1); +} + +private boolean verify(int[] sequence, int first, int last) { + if (last - first <= 1) + return true; + int rootVal = sequence[last]; + int cutIndex = first; + while (cutIndex < last && sequence[cutIndex] <= rootVal) + cutIndex++; + for (int i = cutIndex; i < last; i++) + if (sequence[i] < rootVal) + return false; + return verify(sequence, first, cutIndex - 1) && verify(sequence, cutIndex, last - 1); +} +``` diff --git a/docs/notes/34. 二叉树中和为某一值的路径.md b/docs/notes/34. 二叉树中和为某一值的路径.md new file mode 100644 index 00000000..dd767ec0 --- /dev/null +++ b/docs/notes/34. 二叉树中和为某一值的路径.md @@ -0,0 +1,36 @@ +# 34. 二叉树中和为某一值的路径 + +[NowCoder](https://www.nowcoder.com/practice/b736e784e3e34731af99065031301bca?tpId=13&tqId=11177&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。 + +下图的二叉树有两条和为 22 的路径:10, 5, 7 和 10, 12 + + + +## 解题思路 + +```java +private ArrayList> ret = new ArrayList<>(); + +public ArrayList> FindPath(TreeNode root, int target) { + backtracking(root, target, new ArrayList<>()); + return ret; +} + +private void backtracking(TreeNode node, int target, ArrayList path) { + if (node == null) + return; + path.add(node.val); + target -= node.val; + if (target == 0 && node.left == null && node.right == null) { + ret.add(new ArrayList<>(path)); + } else { + backtracking(node.left, target, path); + backtracking(node.right, target, path); + } + path.remove(path.size() - 1); +} +``` diff --git a/docs/notes/35. 复杂链表的复制.md b/docs/notes/35. 复杂链表的复制.md new file mode 100644 index 00000000..5e5ce7f9 --- /dev/null +++ b/docs/notes/35. 复杂链表的复制.md @@ -0,0 +1,67 @@ +# 35. 复杂链表的复制 + +[NowCoder](https://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba?tpId=13&tqId=11178&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的 head。 + +```java +public class RandomListNode { + int label; + RandomListNode next = null; + RandomListNode random = null; + + RandomListNode(int label) { + this.label = label; + } +} +``` + + + +## 解题思路 + +第一步,在每个节点的后面插入复制的节点。 + + + +第二步,对复制节点的 random 链接进行赋值。 + + + +第三步,拆分。 + + + +```java +public RandomListNode Clone(RandomListNode pHead) { + if (pHead == null) + return null; + // 插入新节点 + RandomListNode cur = pHead; + while (cur != null) { + RandomListNode clone = new RandomListNode(cur.label); + clone.next = cur.next; + cur.next = clone; + cur = clone.next; + } + // 建立 random 链接 + cur = pHead; + while (cur != null) { + RandomListNode clone = cur.next; + if (cur.random != null) + clone.random = cur.random.next; + cur = clone.next; + } + // 拆分 + cur = pHead; + RandomListNode pCloneHead = pHead.next; + while (cur.next != null) { + RandomListNode next = cur.next; + cur.next = next.next; + cur = next; + } + return pCloneHead; +} +``` diff --git a/docs/notes/36. 二叉搜索树与双向链表.md b/docs/notes/36. 二叉搜索树与双向链表.md new file mode 100644 index 00000000..e794ebf4 --- /dev/null +++ b/docs/notes/36. 二叉搜索树与双向链表.md @@ -0,0 +1,34 @@ +# 36. 二叉搜索树与双向链表 + +[NowCoder](https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&tqId=11179&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 + + + +## 解题思路 + +```java +private TreeNode pre = null; +private TreeNode head = null; + +public TreeNode Convert(TreeNode root) { + inOrder(root); + return head; +} + +private void inOrder(TreeNode node) { + if (node == null) + return; + inOrder(node.left); + node.left = pre; + if (pre != null) + pre.right = node; + pre = node; + if (head == null) + head = node; + inOrder(node.right); +} +``` diff --git a/docs/notes/37. 序列化二叉树.md b/docs/notes/37. 序列化二叉树.md new file mode 100644 index 00000000..69ca3396 --- /dev/null +++ b/docs/notes/37. 序列化二叉树.md @@ -0,0 +1,39 @@ +# 37. 序列化二叉树 + +[NowCoder](https://www.nowcoder.com/practice/cf7e25aa97c04cc1a68c8f040e71fb84?tpId=13&tqId=11214&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +请实现两个函数,分别用来序列化和反序列化二叉树。 + +## 解题思路 + +```java +private String deserializeStr; + +public String Serialize(TreeNode root) { + if (root == null) + return "#"; + return root.val + " " + Serialize(root.left) + " " + Serialize(root.right); +} + +public TreeNode Deserialize(String str) { + deserializeStr = str; + return Deserialize(); +} + +private TreeNode Deserialize() { + if (deserializeStr.length() == 0) + return null; + int index = deserializeStr.indexOf(" "); + String node = index == -1 ? deserializeStr : deserializeStr.substring(0, index); + deserializeStr = index == -1 ? "" : deserializeStr.substring(index + 1); + if (node.equals("#")) + return null; + int val = Integer.valueOf(node); + TreeNode t = new TreeNode(val); + t.left = Deserialize(); + t.right = Deserialize(); + return t; +} +``` diff --git a/docs/notes/38. 字符串的排列.md b/docs/notes/38. 字符串的排列.md new file mode 100644 index 00000000..149b3772 --- /dev/null +++ b/docs/notes/38. 字符串的排列.md @@ -0,0 +1,40 @@ +# 38. 字符串的排列 + +[NowCoder](https://www.nowcoder.com/practice/fe6b651b66ae47d7acce78ffdd9a96c7?tpId=13&tqId=11180&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串 abc,则打印出由字符 a, b, c 所能排列出来的所有字符串 abc, acb, bac, bca, cab 和 cba。 + +## 解题思路 + +```java +private ArrayList ret = new ArrayList<>(); + +public ArrayList Permutation(String str) { + if (str.length() == 0) + return ret; + char[] chars = str.toCharArray(); + Arrays.sort(chars); + backtracking(chars, new boolean[chars.length], new StringBuilder()); + return ret; +} + +private void backtracking(char[] chars, boolean[] hasUsed, StringBuilder s) { + if (s.length() == chars.length) { + ret.add(s.toString()); + return; + } + for (int i = 0; i < chars.length; i++) { + if (hasUsed[i]) + continue; + if (i != 0 && chars[i] == chars[i - 1] && !hasUsed[i - 1]) /* 保证不重复 */ + continue; + hasUsed[i] = true; + s.append(chars[i]); + backtracking(chars, hasUsed, s); + s.deleteCharAt(s.length() - 1); + hasUsed[i] = false; + } +} +``` diff --git a/docs/notes/39. 数组中出现次数超过一半的数字.md b/docs/notes/39. 数组中出现次数超过一半的数字.md new file mode 100644 index 00000000..50877830 --- /dev/null +++ b/docs/notes/39. 数组中出现次数超过一半的数字.md @@ -0,0 +1,27 @@ +# 39. 数组中出现次数超过一半的数字 + +[NowCoder](https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=13&tqId=11181&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +多数投票问题,可以利用 Boyer-Moore Majority Vote Algorithm 来解决这个问题,使得时间复杂度为 O(N)。 + +使用 cnt 来统计一个元素出现的次数,当遍历到的元素和统计元素相等时,令 cnt++,否则令 cnt--。如果前面查找了 i 个元素,且 cnt == 0,说明前 i 个元素没有 majority,或者有 majority,但是出现的次数少于 i / 2 ,因为如果多于 i / 2 的话 cnt 就一定不会为 0 。此时剩下的 n - i 个元素中,majority 的数目依然多于 (n - i) / 2,因此继续查找就能找出 majority。 + +```java +public int MoreThanHalfNum_Solution(int[] nums) { + int majority = nums[0]; + for (int i = 1, cnt = 1; i < nums.length; i++) { + cnt = nums[i] == majority ? cnt + 1 : cnt - 1; + if (cnt == 0) { + majority = nums[i]; + cnt = 1; + } + } + int cnt = 0; + for (int val : nums) + if (val == majority) + cnt++; + return cnt > nums.length / 2 ? majority : 0; +} +``` diff --git a/docs/notes/4. 二维数组中的查找.md b/docs/notes/4. 二维数组中的查找.md new file mode 100644 index 00000000..be4e2c71 --- /dev/null +++ b/docs/notes/4. 二维数组中的查找.md @@ -0,0 +1,47 @@ +# 4. 二维数组中的查找 + +[NowCoder](https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&tqId=11154&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序。给定一个数,判断这个数是否在该二维数组中。 + +```html +Consider the following matrix: +[ + [1, 4, 7, 11, 15], + [2, 5, 8, 12, 19], + [3, 6, 9, 16, 22], + [10, 13, 14, 17, 24], + [18, 21, 23, 26, 30] +] + +Given target = 5, return true. +Given target = 20, return false. +``` + +## 解题思路 + +要求时间复杂度 O(M + N),空间复杂度 O(1)。其中 M 为行数,N 为 列数。 + +该二维数组中的一个数,小于它的数一定在其左边,大于它的数一定在其下边。因此,从右上角开始查找,就可以根据 target 和当前元素的大小关系来缩小查找区间,当前元素的查找区间为左下角的所有元素。 + + + +```java +public boolean Find(int target, int[][] matrix) { + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) + return false; + int rows = matrix.length, cols = matrix[0].length; + int r = 0, c = cols - 1; // 从右上角开始 + while (r <= rows - 1 && c >= 0) { + if (target == matrix[r][c]) + return true; + else if (target > matrix[r][c]) + r++; + else + c--; + } + return false; +} +``` diff --git a/docs/notes/40. 最小的 K 个数.md b/docs/notes/40. 最小的 K 个数.md new file mode 100644 index 00000000..8fcfda48 --- /dev/null +++ b/docs/notes/40. 最小的 K 个数.md @@ -0,0 +1,81 @@ +# 40. 最小的 K 个数 + +[NowCoder](https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf?tpId=13&tqId=11182&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +### 快速选择 + +- 复杂度:O(N) + O(1) +- 只有当允许修改数组元素时才可以使用 + +快速排序的 partition() 方法,会返回一个整数 j 使得 a[l..j-1] 小于等于 a[j],且 a[j+1..h] 大于等于 a[j],此时 a[j] 就是数组的第 j 大元素。可以利用这个特性找出数组的第 K 个元素,这种找第 K 个元素的算法称为快速选择算法。 + +```java +public ArrayList GetLeastNumbers_Solution(int[] nums, int k) { + ArrayList ret = new ArrayList<>(); + if (k > nums.length || k <= 0) + return ret; + findKthSmallest(nums, k - 1); + /* findKthSmallest 会改变数组,使得前 k 个数都是最小的 k 个数 */ + for (int i = 0; i < k; i++) + ret.add(nums[i]); + return ret; +} + +public void findKthSmallest(int[] nums, int k) { + int l = 0, h = nums.length - 1; + while (l < h) { + int j = partition(nums, l, h); + if (j == k) + break; + if (j > k) + h = j - 1; + else + l = j + 1; + } +} + +private int partition(int[] nums, int l, int h) { + int p = nums[l]; /* 切分元素 */ + int i = l, j = h + 1; + while (true) { + while (i != h && nums[++i] < p) ; + while (j != l && nums[--j] > p) ; + if (i >= j) + break; + swap(nums, i, j); + } + swap(nums, l, j); + return j; +} + +private void swap(int[] nums, int i, int j) { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; +} +``` + +### 大小为 K 的最小堆 + +- 复杂度:O(NlogK) + O(K) +- 特别适合处理海量数据 + +应该使用大顶堆来维护最小堆,而不能直接创建一个小顶堆并设置一个大小,企图让小顶堆中的元素都是最小元素。 + +维护一个大小为 K 的最小堆过程如下:在添加一个元素之后,如果大顶堆的大小大于 K,那么需要将大顶堆的堆顶元素去除。 + +```java +public ArrayList GetLeastNumbers_Solution(int[] nums, int k) { + if (k > nums.length || k <= 0) + return new ArrayList<>(); + PriorityQueue maxHeap = new PriorityQueue<>((o1, o2) -> o2 - o1); + for (int num : nums) { + maxHeap.add(num); + if (maxHeap.size() > k) + maxHeap.poll(); + } + return new ArrayList<>(maxHeap); +} +``` diff --git a/docs/notes/41.1 数据流中的中位数.md b/docs/notes/41.1 数据流中的中位数.md new file mode 100644 index 00000000..eb4990bb --- /dev/null +++ b/docs/notes/41.1 数据流中的中位数.md @@ -0,0 +1,40 @@ +# 41.1 数据流中的中位数 + +[NowCoder](https://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1?tpId=13&tqId=11216&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。 + +## 解题思路 + +```java +/* 大顶堆,存储左半边元素 */ +private PriorityQueue left = new PriorityQueue<>((o1, o2) -> o2 - o1); +/* 小顶堆,存储右半边元素,并且右半边元素都大于左半边 */ +private PriorityQueue right = new PriorityQueue<>(); +/* 当前数据流读入的元素个数 */ +private int N = 0; + +public void Insert(Integer val) { + /* 插入要保证两个堆存于平衡状态 */ + if (N % 2 == 0) { + /* N 为偶数的情况下插入到右半边。 + * 因为右半边元素都要大于左半边,但是新插入的元素不一定比左半边元素来的大, + * 因此需要先将元素插入左半边,然后利用左半边为大顶堆的特点,取出堆顶元素即为最大元素,此时插入右半边 */ + left.add(val); + right.add(left.poll()); + } else { + right.add(val); + left.add(right.poll()); + } + N++; +} + +public Double GetMedian() { + if (N % 2 == 0) + return (left.peek() + right.peek()) / 2.0; + else + return (double) right.peek(); +} +``` diff --git a/docs/notes/41.2 字符流中第一个不重复的字符.md b/docs/notes/41.2 字符流中第一个不重复的字符.md new file mode 100644 index 00000000..fdf64aa0 --- /dev/null +++ b/docs/notes/41.2 字符流中第一个不重复的字符.md @@ -0,0 +1,25 @@ +# 41.2 字符流中第一个不重复的字符 + +[NowCoder](https://www.nowcoder.com/practice/00de97733b8e4f97a3fb5c680ee10720?tpId=13&tqId=11207&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符 "go" 时,第一个只出现一次的字符是 "g"。当从该字符流中读出前六个字符“google" 时,第一个只出现一次的字符是 "l"。 + +## 解题思路 + +```java +private int[] cnts = new int[256]; +private Queue queue = new LinkedList<>(); + +public void Insert(char ch) { + cnts[ch]++; + queue.add(ch); + while (!queue.isEmpty() && cnts[queue.peek()] > 1) + queue.poll(); +} + +public char FirstAppearingOnce() { + return queue.isEmpty() ? '#' : queue.peek(); +} +``` diff --git a/docs/notes/42. 连续子数组的最大和.md b/docs/notes/42. 连续子数组的最大和.md new file mode 100644 index 00000000..dce17c1e --- /dev/null +++ b/docs/notes/42. 连续子数组的最大和.md @@ -0,0 +1,24 @@ +# 42. 连续子数组的最大和 + +[NowCoder](https://www.nowcoder.com/practice/459bd355da1549fa8a49e350bf3df484?tpId=13&tqId=11183&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +{6, -3, -2, 7, -15, 1, 2, 2},连续子数组的最大和为 8(从第 0 个开始,到第 3 个为止)。 + +## 解题思路 + +```java +public int FindGreatestSumOfSubArray(int[] nums) { + if (nums == null || nums.length == 0) + return 0; + int greatestSum = Integer.MIN_VALUE; + int sum = 0; + for (int val : nums) { + sum = sum <= 0 ? val : sum + val; + greatestSum = Math.max(greatestSum, sum); + } + return greatestSum; +} +``` + diff --git a/docs/notes/43. 从 1 到 n 整数中 1 出现的次数.md b/docs/notes/43. 从 1 到 n 整数中 1 出现的次数.md new file mode 100644 index 00000000..89323cc8 --- /dev/null +++ b/docs/notes/43. 从 1 到 n 整数中 1 出现的次数.md @@ -0,0 +1,18 @@ +# 43. 从 1 到 n 整数中 1 出现的次数 + +[NowCoder](https://www.nowcoder.com/practice/bd7f978302044eee894445e244c7eee6?tpId=13&tqId=11184&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +```java +public int NumberOf1Between1AndN_Solution(int n) { + int cnt = 0; + for (int m = 1; m <= n; m *= 10) { + int a = n / m, b = n % m; + cnt += (a + 8) / 10 * m + (a % 10 == 1 ? b + 1 : 0); + } + return cnt; +} +``` + +> [Leetcode : 233. Number of Digit One](https://leetcode.com/problems/number-of-digit-one/discuss/64381/4+-lines-O(log-n)-C++JavaPython) diff --git a/docs/notes/44. 数字序列中的某一位数字.md b/docs/notes/44. 数字序列中的某一位数字.md new file mode 100644 index 00000000..3d869f3a --- /dev/null +++ b/docs/notes/44. 数字序列中的某一位数字.md @@ -0,0 +1,54 @@ +# 44. 数字序列中的某一位数字 + +## 题目描述 + +数字以 0123456789101112131415... 的格式序列化到一个字符串中,求这个字符串的第 index 位。 + +## 解题思路 + +```java +public int getDigitAtIndex(int index) { + if (index < 0) + return -1; + int place = 1; // 1 表示个位,2 表示 十位... + while (true) { + int amount = getAmountOfPlace(place); + int totalAmount = amount * place; + if (index < totalAmount) + return getDigitAtIndex(index, place); + index -= totalAmount; + place++; + } +} + +/** + * place 位数的数字组成的字符串长度 + * 10, 90, 900, ... + */ +private int getAmountOfPlace(int place) { + if (place == 1) + return 10; + return (int) Math.pow(10, place - 1) * 9; +} + +/** + * place 位数的起始数字 + * 0, 10, 100, ... + */ +private int getBeginNumberOfPlace(int place) { + if (place == 1) + return 0; + return (int) Math.pow(10, place - 1); +} + +/** + * 在 place 位数组成的字符串中,第 index 个数 + */ +private int getDigitAtIndex(int index, int place) { + int beginNumber = getBeginNumberOfPlace(place); + int shiftNumber = index / place; + String number = (beginNumber + shiftNumber) + ""; + int count = index % place; + return number.charAt(count) - '0'; +} +``` diff --git a/docs/notes/45. 把数组排成最小的数.md b/docs/notes/45. 把数组排成最小的数.md new file mode 100644 index 00000000..8d98b005 --- /dev/null +++ b/docs/notes/45. 把数组排成最小的数.md @@ -0,0 +1,27 @@ +# 45. 把数组排成最小的数 + +[NowCoder](https://www.nowcoder.com/practice/8fecd3f8ba334add803bf2a06af1b993?tpId=13&tqId=11185&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组 {3,32,321},则打印出这三个数字能排成的最小数字为 321323。 + +## 解题思路 + +可以看成是一个排序问题,在比较两个字符串 S1 和 S2 的大小时,应该比较的是 S1+S2 和 S2+S1 的大小,如果 S1+S2 < S2+S1,那么应该把 S1 排在前面,否则应该把 S2 排在前面。 + +```java +public String PrintMinNumber(int[] numbers) { + if (numbers == null || numbers.length == 0) + return ""; + int n = numbers.length; + String[] nums = new String[n]; + for (int i = 0; i < n; i++) + nums[i] = numbers[i] + ""; + Arrays.sort(nums, (s1, s2) -> (s1 + s2).compareTo(s2 + s1)); + String ret = ""; + for (String str : nums) + ret += str; + return ret; +} +``` diff --git a/docs/notes/46. 把数字翻译成字符串.md b/docs/notes/46. 把数字翻译成字符串.md new file mode 100644 index 00000000..fcbd92fe --- /dev/null +++ b/docs/notes/46. 把数字翻译成字符串.md @@ -0,0 +1,31 @@ +# 46. 把数字翻译成字符串 + +[Leetcode](https://leetcode.com/problems/decode-ways/description/) + +## 题目描述 + +给定一个数字,按照如下规则翻译成字符串:1 翻译成“a”,2 翻译成“b”... 26 翻译成“z”。一个数字有多种翻译可能,例如 12258 一共有 5 种,分别是 abbeh,lbeh,aveh,abyh,lyh。实现一个函数,用来计算一个数字有多少种不同的翻译方法。 + +## 解题思路 + +```java +public int numDecodings(String s) { + if (s == null || s.length() == 0) + return 0; + int n = s.length(); + int[] dp = new int[n + 1]; + dp[0] = 1; + dp[1] = s.charAt(0) == '0' ? 0 : 1; + for (int i = 2; i <= n; i++) { + int one = Integer.valueOf(s.substring(i - 1, i)); + if (one != 0) + dp[i] += dp[i - 1]; + if (s.charAt(i - 2) == '0') + continue; + int two = Integer.valueOf(s.substring(i - 2, i)); + if (two <= 26) + dp[i] += dp[i - 2]; + } + return dp[n]; +} +``` diff --git a/docs/notes/47. 礼物的最大价值.md b/docs/notes/47. 礼物的最大价值.md new file mode 100644 index 00000000..e46fb0d0 --- /dev/null +++ b/docs/notes/47. 礼物的最大价值.md @@ -0,0 +1,35 @@ +# 47. 礼物的最大价值 + +[NowCoder](https://www.nowcoder.com/questionTerminal/72a99e28381a407991f2c96d8cb238ab) + +## 题目描述 + +在一个 m\*n 的棋盘的每一个格都放有一个礼物,每个礼物都有一定价值(大于 0)。从左上角开始拿礼物,每次向右或向下移动一格,直到右下角结束。给定一个棋盘,求拿到礼物的最大价值。例如,对于如下棋盘 + +``` +1 10 3 8 +12 2 9 6 +5 7 4 11 +3 7 16 5 +``` + +礼物的最大价值为 1+12+5+7+7+16+5=53。 + +## 解题思路 + +应该用动态规划求解,而不是深度优先搜索,深度优先搜索过于复杂,不是最优解。 + +```java +public int getMost(int[][] values) { + if (values == null || values.length == 0 || values[0].length == 0) + return 0; + int n = values[0].length; + int[] dp = new int[n]; + for (int[] value : values) { + dp[0] += value[0]; + for (int i = 1; i < n; i++) + dp[i] = Math.max(dp[i], dp[i - 1]) + value[i]; + } + return dp[n - 1]; +} +``` diff --git a/docs/notes/48. 最长不含重复字符的子字符串.md b/docs/notes/48. 最长不含重复字符的子字符串.md new file mode 100644 index 00000000..576c3905 --- /dev/null +++ b/docs/notes/48. 最长不含重复字符的子字符串.md @@ -0,0 +1,29 @@ +# 48. 最长不含重复字符的子字符串 + +## 题目描述 + +输入一个字符串(只包含 a\~z 的字符),求其最长不含重复字符的子字符串的长度。例如对于 arabcacfr,最长不含重复字符的子字符串为 acfr,长度为 4。 + +## 解题思路 + +```java +public int longestSubStringWithoutDuplication(String str) { + int curLen = 0; + int maxLen = 0; + int[] preIndexs = new int[26]; + Arrays.fill(preIndexs, -1); + for (int curI = 0; curI < str.length(); curI++) { + int c = str.charAt(curI) - 'a'; + int preI = preIndexs[c]; + if (preI == -1 || curI - preI > curLen) { + curLen++; + } else { + maxLen = Math.max(maxLen, curLen); + curLen = curI - preI; + } + preIndexs[c] = curI; + } + maxLen = Math.max(maxLen, curLen); + return maxLen; +} +``` diff --git a/docs/notes/49. 丑数.md b/docs/notes/49. 丑数.md new file mode 100644 index 00000000..f92d4d12 --- /dev/null +++ b/docs/notes/49. 丑数.md @@ -0,0 +1,30 @@ +# 49. 丑数 + +[NowCoder](https://www.nowcoder.com/practice/6aa9e04fc3794f68acf8778237ba065b?tpId=13&tqId=11186&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,但 14 不是,因为它包含因子 7。习惯上我们把 1 当做是第一个丑数。求按从小到大的顺序的第 N 个丑数。 + +## 解题思路 + +```java +public int GetUglyNumber_Solution(int N) { + if (N <= 6) + return N; + int i2 = 0, i3 = 0, i5 = 0; + int[] dp = new int[N]; + dp[0] = 1; + for (int i = 1; i < N; i++) { + int next2 = dp[i2] * 2, next3 = dp[i3] * 3, next5 = dp[i5] * 5; + dp[i] = Math.min(next2, Math.min(next3, next5)); + if (dp[i] == next2) + i2++; + if (dp[i] == next3) + i3++; + if (dp[i] == next5) + i5++; + } + return dp[N - 1]; +} +``` diff --git a/docs/notes/5. 替换空格.md b/docs/notes/5. 替换空格.md new file mode 100644 index 00000000..bc2c1abc --- /dev/null +++ b/docs/notes/5. 替换空格.md @@ -0,0 +1,48 @@ +# 5. 替换空格 + +[NowCoder](https://www.nowcoder.com/practice/4060ac7e3e404ad1a894ef3e17650423?tpId=13&tqId=11155&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + + +将一个字符串中的空格替换成 "%20"。 + +```text +Input: +"A B" + +Output: +"A%20B" +``` + +## 解题思路 + +在字符串尾部填充任意字符,使得字符串的长度等于替换之后的长度。因为一个空格要替换成三个字符(%20),因此当遍历到一个空格时,需要在尾部填充两个任意字符。 + +令 P1 指向字符串原来的末尾位置,P2 指向字符串现在的末尾位置。P1 和 P2 从后向前遍历,当 P1 遍历到一个空格时,就需要令 P2 指向的位置依次填充 02%(注意是逆序的),否则就填充上 P1 指向字符的值。 + +从后向前遍是为了在改变 P2 所指向的内容时,不会影响到 P1 遍历原来字符串的内容。 + + + +```java +public String replaceSpace(StringBuffer str) { + int P1 = str.length() - 1; + for (int i = 0; i <= P1; i++) + if (str.charAt(i) == ' ') + str.append(" "); + + int P2 = str.length() - 1; + while (P1 >= 0 && P2 > P1) { + char c = str.charAt(P1--); + if (c == ' ') { + str.setCharAt(P2--, '0'); + str.setCharAt(P2--, '2'); + str.setCharAt(P2--, '%'); + } else { + str.setCharAt(P2--, c); + } + } + return str.toString(); +} +``` diff --git a/docs/notes/50. 第一个只出现一次的字符位置.md b/docs/notes/50. 第一个只出现一次的字符位置.md new file mode 100644 index 00000000..e25a7098 --- /dev/null +++ b/docs/notes/50. 第一个只出现一次的字符位置.md @@ -0,0 +1,49 @@ +# 50. 第一个只出现一次的字符位置 + +[NowCoder](https://www.nowcoder.com/practice/1c82e8cf713b4bbeb2a5b31cf5b0417c?tpId=13&tqId=11187&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +在一个字符串中找到第一个只出现一次的字符,并返回它的位置。 + +``` +Input: abacc +Output: b +``` + +## 解题思路 + +最直观的解法是使用 HashMap 对出现次数进行统计,但是考虑到要统计的字符范围有限,因此可以使用整型数组代替 HashMap,从而将空间复杂度由 O(N) 降低为 O(1)。 + +```java +public int FirstNotRepeatingChar(String str) { + int[] cnts = new int[256]; + for (int i = 0; i < str.length(); i++) + cnts[str.charAt(i)]++; + for (int i = 0; i < str.length(); i++) + if (cnts[str.charAt(i)] == 1) + return i; + return -1; +} +``` + +以上实现的空间复杂度还不是最优的。考虑到只需要找到只出现一次的字符,那么需要统计的次数信息只有 0,1,更大,使用两个比特位就能存储这些信息。 + +```java +public int FirstNotRepeatingChar2(String str) { + BitSet bs1 = new BitSet(256); + BitSet bs2 = new BitSet(256); + for (char c : str.toCharArray()) { + if (!bs1.get(c) && !bs2.get(c)) + bs1.set(c); // 0 0 -> 0 1 + else if (bs1.get(c) && !bs2.get(c)) + bs2.set(c); // 0 1 -> 1 1 + } + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (bs1.get(c) && !bs2.get(c)) // 0 1 + return i; + } + return -1; +} +``` diff --git a/docs/notes/51. 数组中的逆序对.md b/docs/notes/51. 数组中的逆序对.md new file mode 100644 index 00000000..959857d9 --- /dev/null +++ b/docs/notes/51. 数组中的逆序对.md @@ -0,0 +1,48 @@ +# 51. 数组中的逆序对 + +[NowCoder](https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。 + +## 解题思路 + +```java +private long cnt = 0; +private int[] tmp; // 在这里声明辅助数组,而不是在 merge() 递归函数中声明 + +public int InversePairs(int[] nums) { + tmp = new int[nums.length]; + mergeSort(nums, 0, nums.length - 1); + return (int) (cnt % 1000000007); +} + +private void mergeSort(int[] nums, int l, int h) { + if (h - l < 1) + return; + int m = l + (h - l) / 2; + mergeSort(nums, l, m); + mergeSort(nums, m + 1, h); + merge(nums, l, m, h); +} + +private void merge(int[] nums, int l, int m, int h) { + int i = l, j = m + 1, k = l; + while (i <= m || j <= h) { + if (i > m) + tmp[k] = nums[j++]; + else if (j > h) + tmp[k] = nums[i++]; + else if (nums[i] <= nums[j]) + tmp[k] = nums[i++]; + else { + tmp[k] = nums[j++]; + this.cnt += m - i + 1; // nums[i] > nums[j],说明 nums[i...mid] 都大于 nums[j] + } + k++; + } + for (k = l; k <= h; k++) + nums[k] = tmp[k]; +} +``` diff --git a/docs/notes/52. 两个链表的第一个公共结点.md b/docs/notes/52. 两个链表的第一个公共结点.md new file mode 100644 index 00000000..8bf22071 --- /dev/null +++ b/docs/notes/52. 两个链表的第一个公共结点.md @@ -0,0 +1,24 @@ +# 52. 两个链表的第一个公共结点 + +[NowCoder](https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tpId=13&tqId=11189&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + + + +## 解题思路 + +设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a。 + +当访问链表 A 的指针访问到链表尾部时,令它从链表 B 的头部重新开始访问链表 B;同样地,当访问链表 B 的指针访问到链表尾部时,令它从链表 A 的头部重新开始访问链表 A。这样就能控制访问 A 和 B 两个链表的指针能同时访问到交点。 + +```java +public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { + ListNode l1 = pHead1, l2 = pHead2; + while (l1 != l2) { + l1 = (l1 == null) ? pHead2 : l1.next; + l2 = (l2 == null) ? pHead1 : l2.next; + } + return l1; +} +``` diff --git a/docs/notes/53. 数字在排序数组中出现的次数.md b/docs/notes/53. 数字在排序数组中出现的次数.md new file mode 100644 index 00000000..6737a2f1 --- /dev/null +++ b/docs/notes/53. 数字在排序数组中出现的次数.md @@ -0,0 +1,36 @@ +# 53. 数字在排序数组中出现的次数 + +[NowCoder](https://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2?tpId=13&tqId=11190&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +```html +Input: +nums = 1, 2, 3, 3, 3, 3, 4, 6 +K = 3 + +Output: +4 +``` + +## 解题思路 + +```java +public int GetNumberOfK(int[] nums, int K) { + int first = binarySearch(nums, K); + int last = binarySearch(nums, K + 1); + return (first == nums.length || nums[first] != K) ? 0 : last - first; +} + +private int binarySearch(int[] nums, int K) { + int l = 0, h = nums.length; + while (l < h) { + int m = l + (h - l) / 2; + if (nums[m] >= K) + h = m; + else + l = m + 1; + } + return l; +} +``` diff --git a/docs/notes/54. 二叉查找树的第 K 个结点.md b/docs/notes/54. 二叉查找树的第 K 个结点.md new file mode 100644 index 00000000..7f932fe9 --- /dev/null +++ b/docs/notes/54. 二叉查找树的第 K 个结点.md @@ -0,0 +1,27 @@ +# 54. 二叉查找树的第 K 个结点 + +[NowCoder](https://www.nowcoder.com/practice/ef068f602dde4d28aab2b210e859150a?tpId=13&tqId=11215&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +利用二叉查找树中序遍历有序的特点。 + +```java +private TreeNode ret; +private int cnt = 0; + +public TreeNode KthNode(TreeNode pRoot, int k) { + inOrder(pRoot, k); + return ret; +} + +private void inOrder(TreeNode root, int k) { + if (root == null || cnt >= k) + return; + inOrder(root.left, k); + cnt++; + if (cnt == k) + ret = root; + inOrder(root.right, k); +} +``` diff --git a/docs/notes/55.1 二叉树的深度.md b/docs/notes/55.1 二叉树的深度.md new file mode 100644 index 00000000..e0e7d510 --- /dev/null +++ b/docs/notes/55.1 二叉树的深度.md @@ -0,0 +1,17 @@ +# 55.1 二叉树的深度 + +[NowCoder](https://www.nowcoder.com/practice/435fb86331474282a3499955f0a41e8b?tpId=13&tqId=11191&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 + + + +## 解题思路 + +```java +public int TreeDepth(TreeNode root) { + return root == null ? 0 : 1 + Math.max(TreeDepth(root.left), TreeDepth(root.right)); +} +``` diff --git a/docs/notes/55.2 平衡二叉树.md b/docs/notes/55.2 平衡二叉树.md new file mode 100644 index 00000000..31ef6ac6 --- /dev/null +++ b/docs/notes/55.2 平衡二叉树.md @@ -0,0 +1,30 @@ +# 55.2 平衡二叉树 + +[NowCoder](https://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId=13&tqId=11192&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +平衡二叉树左右子树高度差不超过 1。 + + + +## 解题思路 + +```java +private boolean isBalanced = true; + +public boolean IsBalanced_Solution(TreeNode root) { + height(root); + return isBalanced; +} + +private int height(TreeNode root) { + if (root == null || !isBalanced) + return 0; + int left = height(root.left); + int right = height(root.right); + if (Math.abs(left - right) > 1) + isBalanced = false; + return 1 + Math.max(left, right); +} +``` diff --git a/docs/notes/56. 数组中只出现一次的数字.md b/docs/notes/56. 数组中只出现一次的数字.md new file mode 100644 index 00000000..a8b77c5e --- /dev/null +++ b/docs/notes/56. 数组中只出现一次的数字.md @@ -0,0 +1,28 @@ +# 56. 数组中只出现一次的数字 + +[NowCoder](https://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?tpId=13&tqId=11193&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +一个整型数组里除了两个数字之外,其他的数字都出现了两次,找出这两个数。 + +## 解题思路 + +两个不相等的元素在位级表示上必定会有一位存在不同,将数组的所有元素异或得到的结果为不存在重复的两个元素异或的结果。 + +diff &= -diff 得到出 diff 最右侧不为 0 的位,也就是不存在重复的两个元素在位级表示上最右侧不同的那一位,利用这一位就可以将两个元素区分开来。 + +```java +public void FindNumsAppearOnce(int[] nums, int num1[], int num2[]) { + int diff = 0; + for (int num : nums) + diff ^= num; + diff &= -diff; + for (int num : nums) { + if ((num & diff) == 0) + num1[0] ^= num; + else + num2[0] ^= num; + } +} +``` diff --git a/docs/notes/57.1 和为 S 的两个数字.md b/docs/notes/57.1 和为 S 的两个数字.md new file mode 100644 index 00000000..caf0f3c8 --- /dev/null +++ b/docs/notes/57.1 和为 S 的两个数字.md @@ -0,0 +1,31 @@ +# 57.1 和为 S 的两个数字 + +[NowCoder](https://www.nowcoder.com/practice/390da4f7a00f44bea7c2f3d19491311b?tpId=13&tqId=11195&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个递增排序的数组和一个数字 S,在数组中查找两个数,使得他们的和正好是 S。如果有多对数字的和等于 S,输出两个数的乘积最小的。 + +## 解题思路 + +使用双指针,一个指针指向元素较小的值,一个指针指向元素较大的值。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。 + +- 如果两个指针指向元素的和 sum == target,那么得到要求的结果; +- 如果 sum > target,移动较大的元素,使 sum 变小一些; +- 如果 sum < target,移动较小的元素,使 sum 变大一些。 + +```java +public ArrayList FindNumbersWithSum(int[] array, int sum) { + int i = 0, j = array.length - 1; + while (i < j) { + int cur = array[i] + array[j]; + if (cur == sum) + return new ArrayList<>(Arrays.asList(array[i], array[j])); + if (cur < sum) + i++; + else + j--; + } + return new ArrayList<>(); +} +``` diff --git a/docs/notes/57.2 和为 S 的连续正数序列.md b/docs/notes/57.2 和为 S 的连续正数序列.md new file mode 100644 index 00000000..6a3683d5 --- /dev/null +++ b/docs/notes/57.2 和为 S 的连续正数序列.md @@ -0,0 +1,43 @@ +# 57.2 和为 S 的连续正数序列 + +[NowCoder](https://www.nowcoder.com/practice/c451a3fd84b64cb19485dad758a55ebe?tpId=13&tqId=11194&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输出所有和为 S 的连续正数序列。 + +例如和为 100 的连续序列有: + +``` +[9, 10, 11, 12, 13, 14, 15, 16] +[18, 19, 20, 21, 22]。 +``` + +## 解题思路 + +```java +public ArrayList> FindContinuousSequence(int sum) { + ArrayList> ret = new ArrayList<>(); + int start = 1, end = 2; + int curSum = 3; + while (end < sum) { + if (curSum > sum) { + curSum -= start; + start++; + } else if (curSum < sum) { + end++; + curSum += end; + } else { + ArrayList list = new ArrayList<>(); + for (int i = start; i <= end; i++) + list.add(i); + ret.add(list); + curSum -= start; + start++; + end++; + curSum += end; + } + } + return ret; +} +``` diff --git a/docs/notes/58.1 翻转单词顺序列.md b/docs/notes/58.1 翻转单词顺序列.md new file mode 100644 index 00000000..403ced39 --- /dev/null +++ b/docs/notes/58.1 翻转单词顺序列.md @@ -0,0 +1,47 @@ +# 58.1 翻转单词顺序列 + +[NowCoder](https://www.nowcoder.com/practice/3194a4f4cf814f63919d0790578d51f3?tpId=13&tqId=11197&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +```html +Input: +"I am a student." + +Output: +"student. a am I" +``` + +## 解题思路 + +题目应该有一个隐含条件,就是不能用额外的空间。虽然 Java 的题目输入参数为 String 类型,需要先创建一个字符数组使得空间复杂度为 O(N),但是正确的参数类型应该和原书一样,为字符数组,并且只能使用该字符数组的空间。任何使用了额外空间的解法在面试时都会大打折扣,包括递归解法。 + +正确的解法应该是和书上一样,先旋转每个单词,再旋转整个字符串。 + +```java +public String ReverseSentence(String str) { + int n = str.length(); + char[] chars = str.toCharArray(); + int i = 0, j = 0; + while (j <= n) { + if (j == n || chars[j] == ' ') { + reverse(chars, i, j - 1); + i = j + 1; + } + j++; + } + reverse(chars, 0, n - 1); + return new String(chars); +} + +private void reverse(char[] c, int i, int j) { + while (i < j) + swap(c, i++, j--); +} + +private void swap(char[] c, int i, int j) { + char t = c[i]; + c[i] = c[j]; + c[j] = t; +} +``` diff --git a/docs/notes/58.2 左旋转字符串.md b/docs/notes/58.2 左旋转字符串.md new file mode 100644 index 00000000..663b0322 --- /dev/null +++ b/docs/notes/58.2 左旋转字符串.md @@ -0,0 +1,41 @@ +# 58.2 左旋转字符串 + +[NowCoder](https://www.nowcoder.com/practice/12d959b108cb42b1ab72cef4d36af5ec?tpId=13&tqId=11196&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +```html +Input: +S="abcXYZdef" +K=3 + +Output: +"XYZdefabc" +``` + +## 解题思路 + +先将 "abc" 和 "XYZdef" 分别翻转,得到 "cbafedZYX",然后再把整个字符串翻转得到 "XYZdefabc"。 + +```java +public String LeftRotateString(String str, int n) { + if (n >= str.length()) + return str; + char[] chars = str.toCharArray(); + reverse(chars, 0, n - 1); + reverse(chars, n, chars.length - 1); + reverse(chars, 0, chars.length - 1); + return new String(chars); +} + +private void reverse(char[] chars, int i, int j) { + while (i < j) + swap(chars, i++, j--); +} + +private void swap(char[] chars, int i, int j) { + char t = chars[i]; + chars[i] = chars[j]; + chars[j] = t; +} +``` diff --git a/docs/notes/59. 滑动窗口的最大值.md b/docs/notes/59. 滑动窗口的最大值.md new file mode 100644 index 00000000..a4442ffe --- /dev/null +++ b/docs/notes/59. 滑动窗口的最大值.md @@ -0,0 +1,29 @@ +# 59. 滑动窗口的最大值 + +[NowCoder](https://www.nowcoder.com/practice/1624bc35a45c42c0bc17d17fa0cba788?tpId=13&tqId=11217&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。 + +例如,如果输入数组 {2, 3, 4, 2, 6, 2, 5, 1} 及滑动窗口的大小 3,那么一共存在 6 个滑动窗口,他们的最大值分别为 {4, 4, 6, 6, 6, 5}。 + +## 解题思路 + +```java +public ArrayList maxInWindows(int[] num, int size) { + ArrayList ret = new ArrayList<>(); + if (size > num.length || size < 1) + return ret; + PriorityQueue heap = new PriorityQueue<>((o1, o2) -> o2 - o1); /* 大顶堆 */ + for (int i = 0; i < size; i++) + heap.add(num[i]); + ret.add(heap.peek()); + for (int i = 0, j = i + size; j < num.length; i++, j++) { /* 维护一个大小为 size 的大顶堆 */ + heap.remove(num[i]); + heap.add(num[j]); + ret.add(heap.peek()); + } + return ret; +} +``` diff --git a/docs/notes/6. 从尾到头打印链表.md b/docs/notes/6. 从尾到头打印链表.md new file mode 100644 index 00000000..f6e7871a --- /dev/null +++ b/docs/notes/6. 从尾到头打印链表.md @@ -0,0 +1,78 @@ +# 6. 从尾到头打印链表 + +[NowCoder](https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId=13&tqId=11156&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +从尾到头反过来打印出每个结点的值。 + + + +## 解题思路 + +### 使用递归 + +要逆序打印链表 1->2->3(3,2,1),可以先逆序打印链表 2->3(3,2),最后再打印第一个节点 1。而链表 2->3 可以看成一个新的链表,要逆序打印该链表可以继续使用求解函数,也就是在求解函数中调用自己,这就是递归函数。 + +```java +public ArrayList printListFromTailToHead(ListNode listNode) { + ArrayList ret = new ArrayList<>(); + if (listNode != null) { + ret.addAll(printListFromTailToHead(listNode.next)); + ret.add(listNode.val); + } + return ret; +} +``` + +### 使用头插法 + +使用头插法可以得到一个逆序的链表。 + +头结点和第一个节点的区别: + +- 头结点是在头插法中使用的一个额外节点,这个节点不存储值; +- 第一个节点就是链表的第一个真正存储值的节点。 + + + +```java +public ArrayList printListFromTailToHead(ListNode listNode) { + // 头插法构建逆序链表 + ListNode head = new ListNode(-1); + while (listNode != null) { + ListNode memo = listNode.next; + listNode.next = head.next; + head.next = listNode; + listNode = memo; + } + // 构建 ArrayList + ArrayList ret = new ArrayList<>(); + head = head.next; + while (head != null) { + ret.add(head.val); + head = head.next; + } + return ret; +} +``` + +### 使用栈 + +栈具有后进先出的特点,在遍历链表时将值按顺序放入栈中,最后出栈的顺序即为逆序。 + + + +```java +public ArrayList printListFromTailToHead(ListNode listNode) { + Stack stack = new Stack<>(); + while (listNode != null) { + stack.add(listNode.val); + listNode = listNode.next; + } + ArrayList ret = new ArrayList<>(); + while (!stack.isEmpty()) + ret.add(stack.pop()); + return ret; +} +``` diff --git a/docs/notes/60. n 个骰子的点数.md b/docs/notes/60. n 个骰子的点数.md new file mode 100644 index 00000000..c743de07 --- /dev/null +++ b/docs/notes/60. n 个骰子的点数.md @@ -0,0 +1,72 @@ +# 60. n 个骰子的点数 + +[Lintcode](https://www.lintcode.com/en/problem/dices-sum/) + +## 题目描述 + +把 n 个骰子扔在地上,求点数和为 s 的概率。 + + + +## 解题思路 + +### 动态规划 + +使用一个二维数组 dp 存储点数出现的次数,其中 dp[i][j] 表示前 i 个骰子产生点数 j 的次数。 + +空间复杂度:O(N2) + +```java +public List> dicesSum(int n) { + final int face = 6; + final int pointNum = face * n; + long[][] dp = new long[n + 1][pointNum + 1]; + + for (int i = 1; i <= face; i++) + dp[1][i] = 1; + + for (int i = 2; i <= n; i++) + for (int j = i; j <= pointNum; j++) /* 使用 i 个骰子最小点数为 i */ + for (int k = 1; k <= face && k <= j; k++) + dp[i][j] += dp[i - 1][j - k]; + + final double totalNum = Math.pow(6, n); + List> ret = new ArrayList<>(); + for (int i = n; i <= pointNum; i++) + ret.add(new AbstractMap.SimpleEntry<>(i, dp[n][i] / totalNum)); + + return ret; +} +``` + +### 动态规划 + 旋转数组 + +空间复杂度:O(N) + +```java +public List> dicesSum(int n) { + final int face = 6; + final int pointNum = face * n; + long[][] dp = new long[2][pointNum + 1]; + + for (int i = 1; i <= face; i++) + dp[0][i] = 1; + + int flag = 1; /* 旋转标记 */ + for (int i = 2; i <= n; i++, flag = 1 - flag) { + for (int j = 0; j <= pointNum; j++) + dp[flag][j] = 0; /* 旋转数组清零 */ + + for (int j = i; j <= pointNum; j++) + for (int k = 1; k <= face && k <= j; k++) + dp[flag][j] += dp[1 - flag][j - k]; + } + + final double totalNum = Math.pow(6, n); + List> ret = new ArrayList<>(); + for (int i = n; i <= pointNum; i++) + ret.add(new AbstractMap.SimpleEntry<>(i, dp[1 - flag][i] / totalNum)); + + return ret; +} +``` diff --git a/docs/notes/61. 扑克牌顺子.md b/docs/notes/61. 扑克牌顺子.md new file mode 100644 index 00000000..c0e014e3 --- /dev/null +++ b/docs/notes/61. 扑克牌顺子.md @@ -0,0 +1,37 @@ +# 61. 扑克牌顺子 + +[NowCoder](https://www.nowcoder.com/practice/762836f4d43d43ca9deb273b3de8e1f4?tpId=13&tqId=11198&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +五张牌,其中大小鬼为癞子,牌面为 0。判断这五张牌是否能组成顺子。 + + + + +## 解题思路 + +```java +public boolean isContinuous(int[] nums) { + + if (nums.length < 5) + return false; + + Arrays.sort(nums); + + // 统计癞子数量 + int cnt = 0; + for (int num : nums) + if (num == 0) + cnt++; + + // 使用癞子去补全不连续的顺子 + for (int i = cnt; i < nums.length - 1; i++) { + if (nums[i + 1] == nums[i]) + return false; + cnt -= nums[i + 1] - nums[i] - 1; + } + + return cnt >= 0; +} +``` diff --git a/docs/notes/62. 圆圈中最后剩下的数.md b/docs/notes/62. 圆圈中最后剩下的数.md new file mode 100644 index 00000000..5e32a090 --- /dev/null +++ b/docs/notes/62. 圆圈中最后剩下的数.md @@ -0,0 +1,21 @@ +# 62. 圆圈中最后剩下的数 + +[NowCoder](https://www.nowcoder.com/practice/f78a359491e64a50bce2d89cff857eb6?tpId=13&tqId=11199&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +让小朋友们围成一个大圈。然后,随机指定一个数 m,让编号为 0 的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续 0...m-1 报数 .... 这样下去 .... 直到剩下最后一个小朋友,可以不用表演。 + +## 解题思路 + +约瑟夫环,圆圈长度为 n 的解可以看成长度为 n-1 的解再加上报数的长度 m。因为是圆圈,所以最后需要对 n 取余。 + +```java +public int LastRemaining_Solution(int n, int m) { + if (n == 0) /* 特殊输入的处理 */ + return -1; + if (n == 1) /* 递归返回条件 */ + return 0; + return (LastRemaining_Solution(n - 1, m) + m) % n; +} +``` diff --git a/docs/notes/63. 股票的最大利润.md b/docs/notes/63. 股票的最大利润.md new file mode 100644 index 00000000..702bf999 --- /dev/null +++ b/docs/notes/63. 股票的最大利润.md @@ -0,0 +1,27 @@ +# 63. 股票的最大利润 + +[Leetcode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/) + +## 题目描述 + +可以有一次买入和一次卖出,买入必须在前。求最大收益。 + + + +## 解题思路 + +使用贪心策略,假设第 i 轮进行卖出操作,买入操作价格应该在 i 之前并且价格最低。 + +```java +public int maxProfit(int[] prices) { + if (prices == null || prices.length == 0) + return 0; + int soFarMin = prices[0]; + int maxProfit = 0; + for (int i = 1; i < prices.length; i++) { + soFarMin = Math.min(soFarMin, prices[i]); + maxProfit = Math.max(maxProfit, prices[i] - soFarMin); + } + return maxProfit; +} +``` diff --git a/docs/notes/64. 求 1+2+3+...+n.md b/docs/notes/64. 求 1+2+3+...+n.md new file mode 100644 index 00000000..7e9d0768 --- /dev/null +++ b/docs/notes/64. 求 1+2+3+...+n.md @@ -0,0 +1,23 @@ +# 64. 求 1+2+3+...+n + +[NowCoder](https://www.nowcoder.com/practice/7a0da8fc483247ff8800059e12d7caf1?tpId=13&tqId=11200&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +要求不能使用乘除法、for、while、if、else、switch、case 等关键字及条件判断语句 A ? B : C。 + +## 解题思路 + +使用递归解法最重要的是指定返回条件,但是本题无法直接使用 if 语句来指定返回条件。 + +条件与 && 具有短路原则,即在第一个条件语句为 false 的情况下不会去执行第二个条件语句。利用这一特性,将递归的返回条件取非然后作为 && 的第一个条件语句,递归的主体转换为第二个条件语句,那么当递归的返回条件为 true 的情况下就不会执行递归的主体部分,递归返回。 + +本题的递归返回条件为 n <= 0,取非后就是 n > 0;递归的主体部分为 sum += Sum_Solution(n - 1),转换为条件语句后就是 (sum += Sum_Solution(n - 1)) > 0。 + +```java +public int Sum_Solution(int n) { + int sum = n; + boolean b = (n > 0) && ((sum += Sum_Solution(n - 1)) > 0); + return sum; +} +``` diff --git a/docs/notes/65. 不用加减乘除做加法.md b/docs/notes/65. 不用加减乘除做加法.md new file mode 100644 index 00000000..e15652a2 --- /dev/null +++ b/docs/notes/65. 不用加减乘除做加法.md @@ -0,0 +1,19 @@ +# 65. 不用加减乘除做加法 + +[NowCoder](https://www.nowcoder.com/practice/59ac416b4b944300b617d4f7f111b215?tpId=13&tqId=11201&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +写一个函数,求两个整数之和,要求不得使用 +、-、\*、/ 四则运算符号。 + +## 解题思路 + +a ^ b 表示没有考虑进位的情况下两数的和,(a & b) << 1 就是进位。 + +递归会终止的原因是 (a & b) << 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。 + +```java +public int Add(int a, int b) { + return b == 0 ? a : Add(a ^ b, (a & b) << 1); +} +``` diff --git a/docs/notes/66. 构建乘积数组.md b/docs/notes/66. 构建乘积数组.md new file mode 100644 index 00000000..5f532991 --- /dev/null +++ b/docs/notes/66. 构建乘积数组.md @@ -0,0 +1,24 @@ +# 66. 构建乘积数组 + +[NowCoder](https://www.nowcoder.com/practice/94a4d381a68b47b7a8bed86f2975db46?tpId=13&tqId=11204&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +给定一个数组 A[0, 1,..., n-1],请构建一个数组 B[0, 1,..., n-1],其中 B 中的元素 B[i]=A[0]\*A[1]\*...\*A[i-1]\*A[i+1]\*...\*A[n-1]。要求不能使用除法。 + + + + +## 解题思路 + +```java +public int[] multiply(int[] A) { + int n = A.length; + int[] B = new int[n]; + for (int i = 0, product = 1; i < n; product *= A[i], i++) /* 从左往右累乘 */ + B[i] = product; + for (int i = n - 1, product = 1; i >= 0; product *= A[i], i--) /* 从右往左累乘 */ + B[i] *= product; + return B; +} +``` diff --git a/docs/notes/67. 把字符串转换成整数.md b/docs/notes/67. 把字符串转换成整数.md new file mode 100644 index 00000000..ec6dc914 --- /dev/null +++ b/docs/notes/67. 把字符串转换成整数.md @@ -0,0 +1,37 @@ +# 67. 把字符串转换成整数 + +[NowCoder](https://www.nowcoder.com/practice/1277c681251b4372bdef344468e4f26e?tpId=13&tqId=11202&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +将一个字符串转换成一个整数,字符串不是一个合法的数值则返回 0,要求不能使用字符串转换整数的库函数。 + +```html +Iuput: ++2147483647 +1a33 + +Output: +2147483647 +0 +``` + +## 解题思路 + +```java +public int StrToInt(String str) { + if (str == null || str.length() == 0) + return 0; + boolean isNegative = str.charAt(0) == '-'; + int ret = 0; + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (i == 0 && (c == '+' || c == '-')) /* 符号判定 */ + continue; + if (c < '0' || c > '9') /* 非法输入 */ + return 0; + ret = ret * 10 + (c - '0'); + } + return isNegative ? -ret : ret; +} +``` diff --git a/docs/notes/68. 树中两个节点的最低公共祖先.md b/docs/notes/68. 树中两个节点的最低公共祖先.md new file mode 100644 index 00000000..b6cb095b --- /dev/null +++ b/docs/notes/68. 树中两个节点的最低公共祖先.md @@ -0,0 +1,41 @@ +# 68. 树中两个节点的最低公共祖先 + +## 解题思路 + +### 二叉查找树 + +[Leetcode : 235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description/) + +二叉查找树中,两个节点 p, q 的公共祖先 root 满足 root.val >= p.val && root.val <= q.val。 + + + +```java +public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) + return root; + if (root.val > p.val && root.val > q.val) + return lowestCommonAncestor(root.left, p, q); + if (root.val < p.val && root.val < q.val) + return lowestCommonAncestor(root.right, p, q); + return root; +} +``` + +### 普通二叉树 + +[Leetcode : 236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/) + +在左右子树中查找是否存在 p 或者 q,如果 p 和 q 分别在两个子树中,那么就说明根节点就是最低公共祖先。 + + + +```java +public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null || root == p || root == q) + return root; + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + return left == null ? right : right == null ? left : root; +} +``` diff --git a/docs/notes/7. 重建二叉树.md b/docs/notes/7. 重建二叉树.md new file mode 100644 index 00000000..ca5385dd --- /dev/null +++ b/docs/notes/7. 重建二叉树.md @@ -0,0 +1,38 @@ +# 7. 重建二叉树 + +[NowCoder](https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 + + + + +## 解题思路 + +前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两部分,左部分为树的左子树中序遍历结果,右部分为树的右子树中序遍历的结果。 + + + +```java +// 缓存中序遍历数组每个值对应的索引 +private Map indexForInOrders = new HashMap<>(); + +public TreeNode reConstructBinaryTree(int[] pre, int[] in) { + for (int i = 0; i < in.length; i++) + indexForInOrders.put(in[i], i); + return reConstructBinaryTree(pre, 0, pre.length - 1, 0); +} + +private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int inL) { + if (preL > preR) + return null; + TreeNode root = new TreeNode(pre[preL]); + int inIndex = indexForInOrders.get(root.val); + int leftTreeSize = inIndex - inL; + root.left = reConstructBinaryTree(pre, preL + 1, preL + leftTreeSize, inL); + root.right = reConstructBinaryTree(pre, preL + leftTreeSize + 1, preR, inL + leftTreeSize + 1); + return root; +} +``` diff --git a/docs/notes/8. 二叉树的下一个结点.md b/docs/notes/8. 二叉树的下一个结点.md new file mode 100644 index 00000000..4a697083 --- /dev/null +++ b/docs/notes/8. 二叉树的下一个结点.md @@ -0,0 +1,50 @@ +# 8. 二叉树的下一个结点 + +[NowCoder](https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 + +```java +public class TreeLinkNode { + + int val; + TreeLinkNode left = null; + TreeLinkNode right = null; + TreeLinkNode next = null; + + TreeLinkNode(int val) { + this.val = val; + } +} +``` + +## 解题思路 + +① 如果一个节点的右子树不为空,那么该节点的下一个节点是右子树的最左节点; + + + +② 否则,向上找第一个左链接指向的树包含该节点的祖先节点。 + + + +```java +public TreeLinkNode GetNext(TreeLinkNode pNode) { + if (pNode.right != null) { + TreeLinkNode node = pNode.right; + while (node.left != null) + node = node.left; + return node; + } else { + while (pNode.next != null) { + TreeLinkNode parent = pNode.next; + if (parent.left == pNode) + return parent; + pNode = pNode.next; + } + } + return null; +} +``` diff --git a/docs/notes/9. 用两个栈实现队列.md b/docs/notes/9. 用两个栈实现队列.md new file mode 100644 index 00000000..eb9f5796 --- /dev/null +++ b/docs/notes/9. 用两个栈实现队列.md @@ -0,0 +1,33 @@ +# 9. 用两个栈实现队列 + +[NowCoder](https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。 + +## 解题思路 + +in 栈用来处理入栈(push)操作,out 栈用来处理出栈(pop)操作。一个元素进入 in 栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入 out 栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,先进入的元素先退出,这就是队列的顺序。 + + + +```java +Stack in = new Stack(); +Stack out = new Stack(); + +public void push(int node) { + in.push(node); +} + +public int pop() throws Exception { + if (out.isEmpty()) + while (!in.isEmpty()) + out.push(in.pop()); + + if (out.isEmpty()) + throw new Exception("queue is empty"); + + return out.pop(); +} +``` diff --git a/docs/notes/Docker.md b/docs/notes/Docker.md index 23e33e7e..18bca531 100644 --- a/docs/notes/Docker.md +++ b/docs/notes/Docker.md @@ -1,12 +1,4 @@ - -* [一、解决的问题](#一解决的问题) -* [二、与虚拟机的比较](#二与虚拟机的比较) -* [三、优势](#三优势) -* [四、使用场景](#四使用场景) -* [五、镜像与容器](#五镜像与容器) -* [参考资料](#参考资料) - - +[TOC] # 一、解决的问题 @@ -14,13 +6,13 @@ Docker 主要解决环境配置问题,它是一种虚拟化技术,对进程进行隔离,被隔离的进程独立于宿主操作系统和其它隔离的进程。使用 Docker 可以不修改应用程序代码,不需要开发人员学习特定环境下的技术,就能够将现有的应用程序部署在其它机器上。 -

+ # 二、与虚拟机的比较 虚拟机也是一种虚拟化技术,它与 Docker 最大的区别在于它是通过模拟硬件,并在硬件上安装操作系统来实现。 -

+ ## 启动速度 @@ -74,7 +66,7 @@ Docker 轻量级的特点使得它很适合用于部署、维护、组合微服 构建容器时,通过在镜像的基础上添加一个可写层(writable layer),用来保存着容器运行过程中的修改。 -

+![](pics/docker-filesystems-busyboxrw.png) # 参考资料 @@ -87,10 +79,3 @@ Docker 轻量级的特点使得它很适合用于部署、维护、组合微服 - [What is Docker](https://www.docker.com/what-docker) - [持续集成是什么?](http://www.ruanyifeng.com/blog/2015/09/continuous-integration.html) - - - - - - -
diff --git a/docs/notes/Git.md b/docs/notes/Git.md index e84f1871..c13bb181 100644 --- a/docs/notes/Git.md +++ b/docs/notes/Git.md @@ -1,24 +1,10 @@ - -* [集中式与分布式](#集中式与分布式) -* [中心服务器](#中心服务器) -* [工作流](#工作流) -* [分支实现](#分支实现) -* [冲突](#冲突) -* [Fast forward](#fast-forward) -* [分支管理策略](#分支管理策略) -* [储藏(Stashing)](#储藏stashing) -* [SSH 传输设置](#ssh-传输设置) -* [.gitignore 文件](#gitignore-文件) -* [Git 命令一览](#git-命令一览) -* [参考资料](#参考资料) - - +[TOC] # 集中式与分布式 Git 属于分布式版本控制系统,而 SVN 属于集中式。 -

+ 集中式版本控制只有中心服务器拥有一份代码,而分布式版本控制每个人的电脑上就有一份完整的代码。 @@ -40,45 +26,45 @@ Github 就是一个中心服务器。 Git 的版本库有一个称为 Stage 的暂存区以及最后的 History 版本库,History 存储所有分支信息,使用一个 HEAD 指针指向当前分支。 -

+ - git add files 把文件的修改添加到暂存区 - git commit 把暂存区的修改提交到当前分支,提交之后暂存区就被清空了 - git reset -- files 使用当前分支上的修改覆盖暂存区,用来撤销最后一次 git add files - git checkout -- files 使用暂存区的修改覆盖工作目录,用来撤销本地修改 -

+ 可以跳过暂存区域直接从分支中取出修改,或者直接提交修改到分支中。 - git commit -a 直接把所有文件的修改添加到暂存区然后执行提交 - git checkout HEAD -- files 取出最后一次修改,可以用来进行回滚操作 -

+ # 分支实现 使用指针将每个提交连接成一条时间线,HEAD 指针指向当前分支指针。 -

+ 新建分支是新建一个指针指向时间线的最后一个节点,并让 HEAD 指针指向新分支,表示新分支成为当前分支。 -

+ 每次提交只会让当前分支指针向前移动,而其它分支指针不会移动。 -

+ 合并分支也只需要改变指针即可。 -

+ # 冲突 当两个分支都对同一个文件的同一行进行了修改,在分支合并时就会产生冲突。 -

+ Git 会使用 <<<<<<< ,======= ,>>>>>>> 标记出不同分支的内容,只需要把不同分支中冲突部分修改成一样就能解决冲突。 @@ -100,7 +86,7 @@ Creating a new branch is quick AND simple. $ git merge --no-ff -m "merge with no-ff" dev ``` -

+ # 分支管理策略 @@ -108,7 +94,7 @@ master 分支应该是非常稳定的,只用来发布新版本; 日常开发在开发分支 dev 上进行。 -

+ # 储藏(Stashing) @@ -148,7 +134,7 @@ $ ssh-keygen -t rsa -C "youremail@example.com" # Git 命令一览 -

+ 比较详细的地址:http://www.cheat-sheets.org/saved-copy/git-cheat-sheet.pdf @@ -158,10 +144,3 @@ $ ssh-keygen -t rsa -C "youremail@example.com" - [图解 Git](http://marklodato.github.io/visual-git-guide/index-zh-cn.html) - [廖雪峰 : Git 教程](https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000) - [Learn Git Branching](https://learngitbranching.js.org/) - - - - - - -
diff --git a/docs/notes/HTTP.md b/docs/notes/HTTP.md index 5f1385f0..6225018c 100644 --- a/docs/notes/HTTP.md +++ b/docs/notes/HTTP.md @@ -1,60 +1,4 @@ - -* [一 、基础概念](#一-基础概念) - * [URI](#uri) - * [请求和响应报文](#请求和响应报文) -* [二、HTTP 方法](#二http-方法) - * [GET](#get) - * [HEAD](#head) - * [POST](#post) - * [PUT](#put) - * [PATCH](#patch) - * [DELETE](#delete) - * [OPTIONS](#options) - * [CONNECT](#connect) - * [TRACE](#trace) -* [三、HTTP 状态码](#三http-状态码) - * [1XX 信息](#1xx-信息) - * [2XX 成功](#2xx-成功) - * [3XX 重定向](#3xx-重定向) - * [4XX 客户端错误](#4xx-客户端错误) - * [5XX 服务器错误](#5xx-服务器错误) -* [四、HTTP 首部](#四http-首部) - * [通用首部字段](#通用首部字段) - * [请求首部字段](#请求首部字段) - * [响应首部字段](#响应首部字段) - * [实体首部字段](#实体首部字段) -* [五、具体应用](#五具体应用) - * [连接管理](#连接管理) - * [Cookie](#cookie) - * [缓存](#缓存) - * [内容协商](#内容协商) - * [内容编码](#内容编码) - * [范围请求](#范围请求) - * [分块传输编码](#分块传输编码) - * [多部分对象集合](#多部分对象集合) - * [虚拟主机](#虚拟主机) - * [通信数据转发](#通信数据转发) -* [六、HTTPS](#六https) - * [加密](#加密) - * [认证](#认证) - * [完整性保护](#完整性保护) - * [HTTPS 的缺点](#https-的缺点) -* [七、HTTP/2.0](#七http20) - * [HTTP/1.x 缺陷](#http1x-缺陷) - * [二进制分帧层](#二进制分帧层) - * [服务端推送](#服务端推送) - * [首部压缩](#首部压缩) -* [八、HTTP/1.1 新特性](#八http11-新特性) -* [九、GET 和 POST 比较](#九get-和-post-比较) - * [作用](#作用) - * [参数](#参数) - * [安全](#安全) - * [幂等性](#幂等性) - * [可缓存](#可缓存) - * [XMLHttpRequest](#xmlhttprequest) -* [参考资料](#参考资料) - - +[TOC] # 一 、基础概念 @@ -62,17 +6,17 @@ URI 包含 URL 和 URN。 -

+ ## 请求和响应报文 ### 1. 请求报文 -

+ ### 2. 响应报文 -

+ # 二、HTTP 方法 @@ -159,7 +103,7 @@ DELETE /file.html HTTP/1.1 CONNECT www.example.com:443 HTTP/1.1 ``` -

+ ## TRACE @@ -302,7 +246,7 @@ CONNECT www.example.com:443 HTTP/1.1 ## 连接管理 -

+ ### 1. 短连接与长连接 @@ -631,11 +575,11 @@ HTTP/1.1 使用虚拟主机技术,使得一台服务器拥有多个域名, - 用户察觉得到正向代理的存在。 -

+ - 而反向代理一般位于内部网络中,用户察觉不到。 -

+ ### 2. 网关 @@ -657,7 +601,7 @@ HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer) 通过使用 SSL,HTTPS 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。 -

+ ## 加密 @@ -668,7 +612,7 @@ HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer) - 优点:运算速度快; - 缺点:无法安全地将密钥传输给通信方。 -

+ ### 2.非对称密钥加密 @@ -681,13 +625,13 @@ HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer) - 优点:可以更安全地将公开密钥传输给通信发送方; - 缺点:运算速度慢。 -

+ ### 3. HTTPS 采用的加密方式 HTTPS 采用混合的加密机制,使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性,之后使用对称密钥加密进行通信来保证通信过程的效率。(下图中的 Session Key 就是对称密钥) -

+ ## 认证 @@ -699,7 +643,7 @@ HTTPS 采用混合的加密机制,使用非对称密钥加密用于传输对 进行 HTTPS 通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证,如果验证通过,就可以开始通信了。 -

+ ## 完整性保护 @@ -728,7 +672,7 @@ HTTP/1.x 实现简单是以牺牲性能为代价的: HTTP/2.0 将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式的。 -

+ 在通信过程中,只会有一个 TCP 连接存在,它承载了任意数量的双向数据流(Stream)。 @@ -736,13 +680,13 @@ HTTP/2.0 将报文分成 HEADERS 帧和 DATA 帧,它们都是二进制格式 - 消息(Message)是与逻辑请求或响应对应的完整的一系列帧。 - 帧(Frame)是最小的通信单位,来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装。 -

+ ## 服务端推送 HTTP/2.0 在客户端请求一个资源时,会把相关的资源一起发送给客户端,客户端就不需要再次发起请求了。例如客户端请求 page.html 页面,服务端就把 script.js 和 style.css 等与之相关的资源一起发给客户端。 -

+ ## 首部压缩 @@ -752,7 +696,7 @@ HTTP/2.0 要求客户端和服务器同时维护和更新一个包含之前见 不仅如此,HTTP/2.0 也使用 Huffman 编码对首部字段进行压缩。 -

+ # 八、HTTP/1.1 新特性 @@ -877,10 +821,3 @@ DELETE /idX/delete HTTP/1.1 -> Returns 404 - [Symmetric vs. Asymmetric Encryption – What are differences?](https://www.ssl2buy.com/wiki/symmetric-vs-asymmetric-encryption-what-are-differences) - [Web 性能优化与 HTTP/2](https://www.kancloud.cn/digest/web-performance-http2) - [HTTP/2 简介](https://developers.google.com/web/fundamentals/performance/http2/?hl=zh-cn) - - - - - - -
diff --git a/docs/notes/Java IO.md b/docs/notes/Java IO.md index 912d5bb3..910789b8 100644 --- a/docs/notes/Java IO.md +++ b/docs/notes/Java IO.md @@ -1,35 +1,4 @@ - -* [一、概览](#一概览) -* [二、磁盘操作](#二磁盘操作) -* [三、字节操作](#三字节操作) - * [实现文件复制](#实现文件复制) - * [装饰者模式](#装饰者模式) -* [四、字符操作](#四字符操作) - * [编码与解码](#编码与解码) - * [String 的编码方式](#string-的编码方式) - * [Reader 与 Writer](#reader-与-writer) - * [实现逐行输出文本文件的内容](#实现逐行输出文本文件的内容) -* [五、对象操作](#五对象操作) - * [序列化](#序列化) - * [Serializable](#serializable) - * [transient](#transient) -* [六、网络操作](#六网络操作) - * [InetAddress](#inetaddress) - * [URL](#url) - * [Sockets](#sockets) - * [Datagram](#datagram) -* [七、NIO](#七nio) - * [流与块](#流与块) - * [通道与缓冲区](#通道与缓冲区) - * [缓冲区状态变量](#缓冲区状态变量) - * [文件 NIO 实例](#文件-nio-实例) - * [选择器](#选择器) - * [套接字 NIO 实例](#套接字-nio-实例) - * [内存映射文件](#内存映射文件) - * [对比](#对比) -* [八、参考资料](#八参考资料) - - +[TOC] # 一、概览 @@ -97,7 +66,7 @@ Java I/O 使用了装饰者模式来实现。以 InputStream 为例, - FileInputStream 是 InputStream 的子类,属于具体组件,提供了字节流的输入操作; - FilterInputStream 属于抽象装饰者,装饰者用于装饰组件,为组件提供额外的功能。例如 BufferedInputStream 为 FileInputStream 提供缓存的功能。 -

+ 实例化一个具有缓存功能的字节流对象时,只需要在 FileInputStream 对象上再套一层 BufferedInputStream 对象即可。 @@ -277,7 +246,7 @@ public static void main(String[] args) throws IOException { - Socket:客户端类 - 服务器和客户端通过 InputStream 和 OutputStream 进行输入输出。 -

+ ## Datagram @@ -339,23 +308,23 @@ I/O 包和 NIO 已经很好地集成了,java.io.\* 已经以 NIO 为基础重 ① 新建一个大小为 8 个字节的缓冲区,此时 position 为 0,而 limit = capacity = 8。capacity 变量不会改变,下面的讨论会忽略它。 -

+![](pics/1bea398f-17a7-4f67-a90b-9e2d243eaa9a.png) ② 从输入通道中读取 5 个字节数据写入缓冲区中,此时 position 为 5,limit 保持不变。 -

+![](pics/80804f52-8815-4096-b506-48eef3eed5c6.png) ③ 在将缓冲区的数据写到输出通道之前,需要先调用 flip() 方法,这个方法将 limit 设置为当前 position,并将 position 设置为 0。 -

+![](pics/952e06bd-5a65-4cab-82e4-dd1536462f38.png) ④ 从缓冲区中取 4 个字节到输出缓冲中,此时 position 设为 4。 -

+![](pics/b5bdcbe2-b958-4aef-9151-6ad963cb28b4.png) ⑤ 最后需要调用 clear() 方法来清空缓冲区,此时 position 和 limit 都被设置为最初位置。 -

+![](pics/67bf5487-c45d-49b6-b9c0-a058d8c68902.png) ## 文件 NIO 实例 @@ -413,7 +382,7 @@ NIO 实现了 IO 多路复用中的 Reactor 模型,一个线程 Thread 使用 应该注意的是,只有套接字 Channel 才能配置为非阻塞,而 FileChannel 不能,为 FileChannel 配置非阻塞也没有意义。 -

+ ### 1. 创建选择器 @@ -618,10 +587,3 @@ NIO 与普通 I/O 的区别主要有以下两点: - [NIO 与传统 IO 的区别](http://blog.csdn.net/shimiso/article/details/24990499) - [Decorator Design Pattern](http://stg-tud.github.io/sedc/Lecture/ws13-14/5.3-Decorator.html#mode=document) - [Socket Multicast](http://labojava.blogspot.com/2012/12/socket-multicast.html) - - - - - - -
diff --git a/docs/notes/Java 基础.md b/docs/notes/Java 基础.md index 0e4092d3..64080c8c 100644 --- a/docs/notes/Java 基础.md +++ b/docs/notes/Java 基础.md @@ -1,44 +1,4 @@ - -* [一、数据类型](#一数据类型) - * [基本类型](#基本类型) - * [包装类型](#包装类型) - * [缓存池](#缓存池) -* [二、String](#二string) - * [概览](#概览) - * [不可变的好处](#不可变的好处) - * [String, StringBuffer and StringBuilder](#string,-stringbuffer-and-stringbuilder) - * [String Pool](#string-pool) - * [new String("abc")](#new-string"abc") -* [三、运算](#三运算) - * [参数传递](#参数传递) - * [float 与 double](#float-与-double) - * [隐式类型转换](#隐式类型转换) - * [switch](#switch) -* [四、继承](#四继承) - * [访问权限](#访问权限) - * [抽象类与接口](#抽象类与接口) - * [super](#super) - * [重写与重载](#重写与重载) -* [五、Object 通用方法](#五object-通用方法) - * [概览](#概览) - * [equals()](#equals) - * [hashCode()](#hashcode) - * [toString()](#tostring) - * [clone()](#clone) -* [六、关键字](#六关键字) - * [final](#final) - * [static](#static) -* [七、反射](#七反射) -* [八、异常](#八异常) -* [九、泛型](#九泛型) -* [十、注解](#十注解) -* [十一、特性](#十一特性) - * [Java 各版本的新特性](#java-各版本的新特性) - * [Java 与 C++ 的区别](#java-与-c-的区别) - * [JRE or JDK](#jre-or-jdk) -* [参考资料](#参考资料) - - +[TOC] # 一、数据类型 @@ -193,7 +153,7 @@ value 数组被声明为 final,这意味着 value 数组初始化之后就不 如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。 -

+ **3. 安全性** @@ -1356,7 +1316,7 @@ Throwable 可以用来表示任何可以作为异常抛出的类,分为两种 - **受检异常** :需要用 try...catch... 语句捕获并进行处理,并且可以从异常中恢复; - **非受检异常** :是程序运行时错误,例如除 0 会引发 Arithmetic Exception,此时程序崩溃并且无法恢复。 -

+ - [Java 入门之异常处理](https://www.tianmaying.com/tutorial/Java-Exception) - [Java 异常的面试问题及答案 -Part 1](http://www.importnew.com/7383.html) @@ -1432,10 +1392,3 @@ Java 注解是附加在代码中的一些元信息,用于一些工具在编译 - Eckel B. Java 编程思想[M]. 机械工业出版社, 2002. - Bloch J. Effective java[M]. Addison-Wesley Professional, 2017. - - - - - - -
diff --git a/docs/notes/Java 容器.md b/docs/notes/Java 容器.md index f9394b26..f566e600 100644 --- a/docs/notes/Java 容器.md +++ b/docs/notes/Java 容器.md @@ -1,22 +1,4 @@ - -* [一、概览](#一概览) - * [Collection](#collection) - * [Map](#map) -* [二、容器中的设计模式](#二容器中的设计模式) - * [迭代器模式](#迭代器模式) - * [适配器模式](#适配器模式) -* [三、源码分析](#三源码分析) - * [ArrayList](#arraylist) - * [Vector](#vector) - * [CopyOnWriteArrayList](#copyonwritearraylist) - * [LinkedList](#linkedlist) - * [HashMap](#hashmap) - * [ConcurrentHashMap](#concurrenthashmap) - * [LinkedHashMap](#linkedhashmap) - * [WeakHashMap](#weakhashmap) -* [参考资料](#参考资料) - - +[TOC] # 一、概览 @@ -24,7 +6,7 @@ ## Collection -

+ ### 1. Set @@ -50,7 +32,7 @@ ## Map -

+ - TreeMap:基于红黑树实现。 @@ -65,7 +47,7 @@ ## 迭代器模式 -

+ Collection 继承了 Iterable 接口,其中的 iterator() 方法能够产生一个 Iterator 对象,通过这个对象就可以迭代遍历 Collection 中的元素。 @@ -126,7 +108,7 @@ public class ArrayList extends AbstractList private static final int DEFAULT_CAPACITY = 10; ``` -

+ ### 2. 扩容 @@ -430,7 +412,7 @@ transient Node first; transient Node last; ``` -

+ ### 2. 与 ArrayList 的比较 @@ -452,7 +434,7 @@ transient Entry[] table; Entry 存储着键值对。它包含了四个字段,从 next 字段我们可以看出 Entry 是一个链表。即数组中的每个位置被当成一个桶,一个桶存放一个链表。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值和散列桶取模运算结果相同的 Entry。 -

+ ```java static class Entry implements Map.Entry { @@ -528,7 +510,7 @@ map.put("K3", "V3"); - 计算键值对所在的桶; - 在链表上顺序查找,时间复杂度显然和链表的长度成正比。 -

+ ### 3. put 操作 @@ -864,7 +846,7 @@ final Segment[] segments; static final int DEFAULT_CONCURRENCY_LEVEL = 16; ``` -

+ ### 2. size 操作 @@ -1150,10 +1132,3 @@ public final class ConcurrentCache { - [Java 集合细节(二):asList 的缺陷](http://wiki.jikexueyuan.com/project/java-enhancement/java-thirtysix.html) - [Java Collection Framework – The LinkedList Class](http://javaconceptoftheday.com/java-collection-framework-linkedlist-class/) - - - - - - -
diff --git a/docs/notes/Java 并发.md b/docs/notes/Java 并发.md index bf26f702..4f1e412f 100644 --- a/docs/notes/Java 并发.md +++ b/docs/notes/Java 并发.md @@ -1,67 +1,8 @@ - -* [一、线程状态转换](#一线程状态转换) - * [新建(New)](#新建new) - * [可运行(Runnable)](#可运行runnable) - * [阻塞(Blocked)](#阻塞blocked) - * [无限期等待(Waiting)](#无限期等待waiting) - * [限期等待(Timed Waiting)](#限期等待timed-waiting) - * [死亡(Terminated)](#死亡terminated) -* [二、使用线程](#二使用线程) - * [实现 Runnable 接口](#实现-runnable-接口) - * [实现 Callable 接口](#实现-callable-接口) - * [继承 Thread 类](#继承-thread-类) - * [实现接口 VS 继承 Thread](#实现接口-vs-继承-thread) -* [三、基础线程机制](#三基础线程机制) - * [Executor](#executor) - * [Daemon](#daemon) - * [sleep()](#sleep) - * [yield()](#yield) -* [四、中断](#四中断) - * [InterruptedException](#interruptedexception) - * [interrupted()](#interrupted) - * [Executor 的中断操作](#executor-的中断操作) -* [五、互斥同步](#五互斥同步) - * [synchronized](#synchronized) - * [ReentrantLock](#reentrantlock) - * [比较](#比较) - * [使用选择](#使用选择) -* [六、线程之间的协作](#六线程之间的协作) - * [join()](#join) - * [wait() notify() notifyAll()](#wait-notify-notifyall) - * [await() signal() signalAll()](#await-signal-signalall) -* [七、J.U.C - AQS](#七juc---aqs) - * [CountDownLatch](#countdownlatch) - * [CyclicBarrier](#cyclicbarrier) - * [Semaphore](#semaphore) -* [八、J.U.C - 其它组件](#八juc---其它组件) - * [FutureTask](#futuretask) - * [BlockingQueue](#blockingqueue) - * [ForkJoin](#forkjoin) -* [九、线程不安全示例](#九线程不安全示例) -* [十、Java 内存模型](#十java-内存模型) - * [主内存与工作内存](#主内存与工作内存) - * [内存间交互操作](#内存间交互操作) - * [内存模型三大特性](#内存模型三大特性) - * [先行发生原则](#先行发生原则) -* [十一、线程安全](#十一线程安全) - * [不可变](#不可变) - * [互斥同步](#互斥同步) - * [非阻塞同步](#非阻塞同步) - * [无同步方案](#无同步方案) -* [十二、锁优化](#十二锁优化) - * [自旋锁](#自旋锁) - * [锁消除](#锁消除) - * [锁粗化](#锁粗化) - * [轻量级锁](#轻量级锁) - * [偏向锁](#偏向锁) -* [十三、多线程开发良好的实践](#十三多线程开发良好的实践) -* [参考资料](#参考资料) - - +[TOC] # 一、线程状态转换 -

+ ## 新建(New) @@ -736,7 +677,7 @@ java.util.concurrent(J.U.C)大大提高了并发性能,AQS 被认为是 J. 维护了一个计数器 cnt,每次调用 countDown() 方法会让计数器的值减 1,减到 0 的时候,那些因为调用 await() 方法而在等待的线程就会被唤醒。 -

+ ```java public class CountdownLatchExample { @@ -785,7 +726,7 @@ public CyclicBarrier(int parties) { } ``` -

+ ```java public class CyclicBarrierExample { @@ -1022,7 +963,7 @@ public class ForkJoinPool extends AbstractExecutorService ForkJoinPool 实现了工作窃取算法来提高 CPU 的利用率。每个线程都维护了一个双端队列,用来存储需要执行的任务。工作窃取算法允许空闲的线程从其它线程的双端队列中窃取一个任务来执行。窃取的任务必须是最晚的任务,避免和队列所属线程发生竞争。例如下图中,Thread2 从 Thread1 的队列中拿出最晚的 Task1 任务,Thread1 会拿出 Task2 来执行,这样就避免发生竞争。但是如果队列中只有一个任务时还是会发生竞争。 -

+ # 九、线程不安全示例 @@ -1077,19 +1018,19 @@ Java 内存模型试图屏蔽各种硬件和操作系统的内存访问差异, 加入高速缓存带来了一个新的问题:缓存一致性。如果多个缓存共享同一块主内存区域,那么多个缓存的数据可能会不一致,需要一些协议来解决这个问题。 -

+ 所有的变量都存储在主内存中,每个线程还有自己的工作内存,工作内存存储在高速缓存或者寄存器中,保存了该线程使用的变量的主内存副本拷贝。 线程只能直接操作工作内存中的变量,不同线程之间的变量值传递需要通过主内存来完成。 -

+ ## 内存间交互操作 Java 内存模型定义了 8 个操作来完成主内存和工作内存的交互操作。 -

+ - read:把一个变量的值从主内存传输到工作内存中 - load:在 read 之后执行,把 read 得到的值放入工作内存的变量副本中 @@ -1112,11 +1053,11 @@ Java 内存模型保证了 read、load、use、assign、store、write、lock 和 下图演示了两个线程同时对 cnt 进行操作,load、assign、store 这一系列操作整体上看不具备原子性,那么在 T1 修改 cnt 并且还没有将修改后的值写入主内存,T2 依然可以读入旧值。可以看出,这两个线程虽然执行了两次自增运算,但是主内存中 cnt 的值最后为 1 而不是 2。因此对 int 类型读写操作满足原子性只是说明 load、assign、store 这些单个操作具备原子性。 -

+ AtomicInteger 能保证多个线程修改的原子性。 -

+ 使用 AtomicInteger 重写之前线程不安全的代码之后得到以下线程安全实现: @@ -1224,7 +1165,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即 在一个线程内,在程序前面的操作先行发生于后面的操作。 -

+ ### 2. 管程锁定规则 @@ -1232,7 +1173,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即 一个 unlock 操作先行发生于后面对同一个锁的 lock 操作。 -

+ ### 3. volatile 变量规则 @@ -1240,7 +1181,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即 对一个 volatile 变量的写操作先行发生于后面对这个变量的读操作。 -

+ ### 4. 线程启动规则 @@ -1248,7 +1189,7 @@ volatile 关键字通过添加内存屏障的方式来禁止指令重排,即 Thread 对象的 start() 方法调用先行发生于此线程的每一个动作。 -

+ ### 5. 线程加入规则 @@ -1256,7 +1197,7 @@ Thread 对象的 start() 方法调用先行发生于此线程的每一个动作 Thread 对象的结束先行发生于 join() 方法返回。 -

+ ### 6. 线程中断规则 @@ -1474,7 +1415,7 @@ public class ThreadLocalExample1 { 它所对应的底层结构图为: -

+ 每个 Thread 都有一个 ThreadLocal.ThreadLocalMap 对象。 @@ -1577,17 +1518,17 @@ JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态: 以下是 HotSpot 虚拟机对象头的内存布局,这些数据被称为 Mark Word。其中 tag bits 对应了五个状态,这些状态在右侧的 state 表格中给出。除了 marked for gc 状态,其它四个状态已经在前面介绍过了。 -

+ 下图左侧是一个线程的虚拟机栈,其中有一部分称为 Lock Record 的区域,这是在轻量级锁运行过程创建的,用于存放锁对象的 Mark Word。而右侧就是一个锁对象,包含了 Mark Word 和其它信息。 -

+ 轻量级锁是相对于传统的重量级锁而言,它使用 CAS 操作来避免重量级锁使用互斥量的开销。对于绝大部分的锁,在整个同步周期内都是不存在竞争的,因此也就不需要都使用互斥量进行同步,可以先采用 CAS 操作进行同步,如果 CAS 失败了再改用互斥量进行同步。 当尝试获取一个锁对象时,如果锁对象标记为 0 01,说明锁对象的锁未锁定(unlocked)状态。此时虚拟机在当前线程的虚拟机栈中创建 Lock Record,然后使用 CAS 操作将对象的 Mark Word 更新为 Lock Record 指针。如果 CAS 操作成功了,那么线程就获取了该对象上的锁,并且对象的 Mark Word 的锁标记变为 00,表示该对象处于轻量级锁状态。 -

+ 如果 CAS 操作失败了,虚拟机首先会检查对象的 Mark Word 是否指向当前线程的虚拟机栈,如果是的话说明当前线程已经拥有了这个锁对象,那就可以直接进入同步块继续执行,否则说明这个锁对象已经被其他线程线程抢占了。如果有两条以上的线程争用同一个锁,那轻量级锁就不再有效,要膨胀为重量级锁。 @@ -1599,7 +1540,7 @@ JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态: 当有另外一个线程去尝试获取这个锁对象时,偏向状态就宣告结束,此时撤销偏向(Revoke Bias)后恢复到未锁定状态或者轻量级锁状态。 -

+ # 十三、多线程开发良好的实践 @@ -1634,10 +1575,3 @@ JDK 1.6 引入了偏向锁和轻量级锁,从而让锁拥有了四个状态: - [JAVA FORK JOIN EXAMPLE](http://www.javacreed.com/java-fork-join-example/ "Java Fork Join Example") - [聊聊并发(八)——Fork/Join 框架介绍](http://ifeve.com/talk-concurrency-forkjoin/) - [Eliminating SynchronizationRelated Atomic Operations with Biased Locking and Bulk Rebiasing](http://www.oracle.com/technetwork/java/javase/tech/biasedlocking-oopsla2006-preso-150106.pdf) - - - - - - -
diff --git a/docs/notes/Java 虚拟机.md b/docs/notes/Java 虚拟机.md index 9ec015c7..9e676a3f 100644 --- a/docs/notes/Java 虚拟机.md +++ b/docs/notes/Java 虚拟机.md @@ -1,38 +1,10 @@ - -* [一、运行时数据区域](#一运行时数据区域) - * [程序计数器](#程序计数器) - * [Java 虚拟机栈](#java-虚拟机栈) - * [本地方法栈](#本地方法栈) - * [堆](#堆) - * [方法区](#方法区) - * [运行时常量池](#运行时常量池) - * [直接内存](#直接内存) -* [二、垃圾收集](#二垃圾收集) - * [判断一个对象是否可被回收](#判断一个对象是否可被回收) - * [引用类型](#引用类型) - * [垃圾收集算法](#垃圾收集算法) - * [垃圾收集器](#垃圾收集器) -* [三、内存分配与回收策略](#三内存分配与回收策略) - * [Minor GC 和 Full GC](#minor-gc-和-full-gc) - * [内存分配策略](#内存分配策略) - * [Full GC 的触发条件](#full-gc-的触发条件) -* [四、类加载机制](#四类加载机制) - * [类的生命周期](#类的生命周期) - * [类加载过程](#类加载过程) - * [类初始化时机](#类初始化时机) - * [类与类加载器](#类与类加载器) - * [类加载器分类](#类加载器分类) - * [双亲委派模型](#双亲委派模型) - * [自定义类加载器实现](#自定义类加载器实现) -* [参考资料](#参考资料) - - +[TOC] 本文大部分内容参考 **周志明《深入理解 Java 虚拟机》** ,想要深入学习的话请看原书。 # 一、运行时数据区域 -

+ ## 程序计数器 @@ -42,7 +14,7 @@ 每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。 -

+ 可以通过 -Xss 这个虚拟机参数来指定每个线程的 Java 虚拟机栈内存大小,在 JDK 1.4 中默认为 256K,而在 JDK 1.5+ 默认为 1M: @@ -61,7 +33,7 @@ java -Xss2M HackTheJava 本地方法一般是用其它语言(C、C++ 或汇编语言等)编写的,并且被编译为基于本机硬件和操作系统的程序,对待这些方法需要特别处理。 -

+ ## 堆 @@ -146,7 +118,7 @@ Java 虚拟机使用该算法来判断对象是否可被回收,GC Roots 一般 - 方法区中类静态属性引用的对象 - 方法区中的常量引用的对象 -

+ ### 3. 方法区的回收 @@ -227,7 +199,7 @@ obj = null; ### 1. 标记 - 清除 -

+ 在标记阶段,程序会检查每个对象是否为活动对象,如果是活动对象,则程序会在对象头部打上标记。 @@ -242,7 +214,7 @@ obj = null; ### 2. 标记 - 整理 -

+ 让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。 @@ -256,7 +228,7 @@ obj = null; ### 3. 复制 -

+ 将内存划分为大小相等的两块,每次只使用其中一块,当这一块内存用完了就将还存活的对象复制到另一块上面,然后再把使用过的内存空间进行一次清理。 @@ -277,7 +249,7 @@ HotSpot 虚拟机的 Eden 和 Survivor 大小比例默认为 8:1,保证了内 ## 垃圾收集器 -

+ 以上是 HotSpot 虚拟机中的 7 个垃圾收集器,连线表示垃圾收集器可以配合使用。 @@ -286,7 +258,7 @@ HotSpot 虚拟机的 Eden 和 Survivor 大小比例默认为 8:1,保证了内 ### 1. Serial 收集器 -

+ Serial 翻译为串行,也就是说它以串行的方式执行。 @@ -298,7 +270,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。 ### 2. ParNew 收集器 -

+ 它是 Serial 收集器的多线程版本。 @@ -318,7 +290,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。 ### 4. Serial Old 收集器 -

+ 是 Serial 收集器的老年代版本,也是给 Client 场景下的虚拟机使用。如果用在 Server 场景下,它有两大用途: @@ -327,7 +299,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。 ### 5. Parallel Old 收集器 -

+ 是 Parallel Scavenge 收集器的老年代版本。 @@ -335,7 +307,7 @@ Serial 翻译为串行,也就是说它以串行的方式执行。 ### 6. CMS 收集器 -

+ CMS(Concurrent Mark Sweep),Mark Sweep 指的是标记 - 清除算法。 @@ -360,17 +332,17 @@ G1(Garbage-First),它是一款面向服务端应用的垃圾收集器, 堆被分为新生代和老年代,其它收集器进行收集的范围都是整个新生代或者老年代,而 G1 可以直接对新生代和老年代一起回收。 -

+ G1 把堆划分成多个大小相等的独立区域(Region),新生代和老年代不再物理隔离。 -

+ 通过引入 Region 的概念,从而将原来的一整块内存空间划分成多个的小空间,使得每个小空间可以单独进行垃圾回收。这种划分方法带来了很大的灵活性,使得可预测的停顿时间模型成为可能。通过记录每个 Region 垃圾回收时间以及回收所获得的空间(这两个值是通过过去回收的经验获得),并维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的 Region。 每个 Region 都有一个 Remembered Set,用来记录该 Region 对象的引用对象所在的 Region。通过使用 Remembered Set,在做可达性分析的时候就可以避免全堆扫描。 -

+ 如果不计算维护 Remembered Set 的操作,G1 收集器的运作大致可划分为以下几个步骤: @@ -458,7 +430,7 @@ G1 把堆划分成多个大小相等的独立区域(Region),新生代和 ## 类的生命周期 -

+ 包括以下 7 个阶段: @@ -521,11 +493,9 @@ public static final int value = 123; 其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。
- ### 5. 初始化
- 初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段是虚拟机执行类构造器 <clinit>() 方法的过程。在准备阶段,类变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划去初始化类变量和其它资源。 <clinit>() 是由编译器自动收集类中所有类变量的赋值动作和静态语句块中的语句合并产生的,编译器收集的顺序由语句在源文件中出现的顺序决定。特别注意的是,静态语句块只能访问到定义在它之前的类变量,定义在它之后的类变量只能赋值,不能访问。例如以下代码: @@ -624,14 +594,13 @@ System.out.println(ConstClass.HELLOWORLD); - 应用程序类加载器(Application ClassLoader)这个类加载器是由 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。由于这个类加载器是 ClassLoader 中的 getSystemClassLoader() 方法的返回值,因此一般称为系统类加载器。它负责加载用户类路径(ClassPath)上所指定的类库,开发者可以直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。
- ## 双亲委派模型 应用程序是由三种类加载器互相配合从而实现类加载,除此之外还可以加入自己定义的类加载器。 下图展示了类加载器之间的层次关系,称为双亲委派模型(Parents Delegation Model)。该模型要求除了顶层的启动类加载器外,其它的类加载器都要有自己的父类加载器。这里的父子关系一般通过组合关系(Composition)来实现,而不是继承关系(Inheritance)。 -

+ ### 1. 工作过程 @@ -756,10 +725,3 @@ public class FileSystemClassLoader extends ClassLoader { - [深入探讨 Java 类加载器](https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html#code6) - [Guide to WeakHashMap in Java](http://www.baeldung.com/java-weakhashmap) - [Tomcat example source code file (ConcurrentCache.java)](https://alvinalexander.com/java/jwarehouse/apache-tomcat-6.0.16/java/org/apache/el/util/ConcurrentCache.java.shtml) - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 二分查找.md b/docs/notes/Leetcode 题解 - 二分查找.md index 1a7c44be..4e6ef976 100644 --- a/docs/notes/Leetcode 题解 - 二分查找.md +++ b/docs/notes/Leetcode 题解 - 二分查找.md @@ -1,14 +1,6 @@ - -* [1. 求开方](#1-求开方) -* [2. 大于给定元素的最小元素](#2-大于给定元素的最小元素) -* [3. 有序数组的 Single Element](#3-有序数组的-single-element) -* [4. 第一个错误的版本](#4-第一个错误的版本) -* [5. 旋转数组的最小数字](#5-旋转数组的最小数字) -* [6. 查找区间](#6-查找区间) - +[TOC] - -**正常实现** +正常实现** ```text Input : [1,2,3,4,5] @@ -301,10 +293,3 @@ private int binarySearch(int[] nums, int target) { } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 位运算.md b/docs/notes/Leetcode 题解 - 位运算.md index a9fd6121..d6ca2040 100644 --- a/docs/notes/Leetcode 题解 - 位运算.md +++ b/docs/notes/Leetcode 题解 - 位运算.md @@ -1,19 +1,4 @@ - -* [1. 统计两个数的二进制表示有多少位不同](#1-统计两个数的二进制表示有多少位不同) -* [2. 数组中唯一一个不重复的元素](#2-数组中唯一一个不重复的元素) -* [3. 找出数组中缺失的那个数](#3-找出数组中缺失的那个数) -* [4. 数组中不重复的两个元素](#4-数组中不重复的两个元素) -* [5. 翻转一个数的比特位](#5-翻转一个数的比特位) -* [6. 不用额外变量交换两个整数](#6-不用额外变量交换两个整数) -* [7. 判断一个数是不是 2 的 n 次方](#7-判断一个数是不是-2-的-n-次方) -* [8. 判断一个数是不是 4 的 n 次方](#8--判断一个数是不是-4-的-n-次方) -* [9. 判断一个数的位级表示是否不会出现连续的 0 和 1](#9-判断一个数的位级表示是否不会出现连续的-0-和-1) -* [10. 求一个数的补码](#10-求一个数的补码) -* [11. 实现整数的加法](#11-实现整数的加法) -* [12. 字符串数组最大乘积](#12-字符串数组最大乘积) -* [13. 统计从 0 \~ n 每个数的二进制表示中 1 的个数](#13-统计从-0-\~-n-每个数的二进制表示中-1-的个数) - - +[TOC] **基本原理** @@ -440,10 +425,3 @@ public int[] countBits(int num) { } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 分治.md b/docs/notes/Leetcode 题解 - 分治.md index aa715127..8bb7abee 100644 --- a/docs/notes/Leetcode 题解 - 分治.md +++ b/docs/notes/Leetcode 题解 - 分治.md @@ -1,8 +1,4 @@ - -* [1. 给表达式加括号](#1-给表达式加括号) -* [2. 不同的二叉搜索树](#2-不同的二叉搜索树) - - +[TOC] # 1. 给表达式加括号 @@ -108,10 +104,3 @@ private List generateSubtrees(int s, int e) { return res; } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 动态规划.md b/docs/notes/Leetcode 题解 - 动态规划.md index c54cbb15..e828f05f 100644 --- a/docs/notes/Leetcode 题解 - 动态规划.md +++ b/docs/notes/Leetcode 题解 - 动态规划.md @@ -1,43 +1,5 @@ - -* [斐波那契数列](#斐波那契数列) - * [1. 爬楼梯](#1-爬楼梯) - * [2. 强盗抢劫](#2-强盗抢劫) - * [3. 强盗在环形街区抢劫](#3-强盗在环形街区抢劫) - * [4. 信件错排](#4-信件错排) - * [5. 母牛生产](#5-母牛生产) -* [矩阵路径](#矩阵路径) - * [1. 矩阵的最小路径和](#1-矩阵的最小路径和) - * [2. 矩阵的总路径数](#2-矩阵的总路径数) -* [数组区间](#数组区间) - * [1. 数组区间和](#1-数组区间和) - * [2. 数组中等差递增子区间的个数](#2-数组中等差递增子区间的个数) -* [分割整数](#分割整数) - * [1. 分割整数的最大乘积](#1-分割整数的最大乘积) - * [2. 按平方数来分割整数](#2-按平方数来分割整数) - * [3. 分割整数构成字母字符串](#3-分割整数构成字母字符串) -* [最长递增子序列](#最长递增子序列) - * [1. 最长递增子序列](#1-最长递增子序列) - * [2. 一组整数对能够构成的最长链](#2-一组整数对能够构成的最长链) - * [3. 最长摆动子序列](#3-最长摆动子序列) -* [最长公共子序列](#最长公共子序列) -* [0-1 背包](#0-1-背包) - * [1. 划分数组为和相等的两部分](#1-划分数组为和相等的两部分) - * [2. 改变一组数的正负号使得它们的和为一给定数](#2-改变一组数的正负号使得它们的和为一给定数) - * [3. 01 字符构成最多的字符串](#3-01-字符构成最多的字符串) - * [4. 找零钱的最少硬币数](#4-找零钱的最少硬币数) - * [5. 找零钱的硬币数组合](#5-找零钱的硬币数组合) - * [6. 字符串按单词列表分割](#6-字符串按单词列表分割) - * [7. 组合总和](#7-组合总和) -* [股票交易](#股票交易) - * [1. 需要冷却期的股票交易](#1-需要冷却期的股票交易) - * [2. 需要交易费用的股票交易](#2-需要交易费用的股票交易) - * [3. 只能进行两次的股票交易](#3-只能进行两次的股票交易) - * [4. 只能进行 k 次的股票交易](#4-只能进行-k-次的股票交易) -* [字符串编辑](#字符串编辑) - * [1. 删除两个字符串的字符使它们相等](#1-删除两个字符串的字符使它们相等) - * [2. 编辑距离](#2-编辑距离) - * [3. 复制粘贴字符](#3-复制粘贴字符) - +[TOC] + 递归和动态规划都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划保存了子问题的解,避免重复计算。 @@ -58,7 +20,7 @@ -

+ 考虑到 dp[i] 只与 dp[i - 1] 和 dp[i - 2] 有关,因此可以只用两个变量来存储 dp[i - 1] 和 dp[i - 2],使得原来的 O(N) 空间复杂度优化为 O(1) 复杂度。 @@ -91,7 +53,7 @@ public int climbStairs(int n) { -

+ ```java public int rob(int[] nums) { @@ -147,7 +109,7 @@ private int rob(int[] nums, int first, int last) { -

+ ## 5. 母牛生产 @@ -159,7 +121,7 @@ private int rob(int[] nums, int first, int last) { -

+ # 矩阵路径 @@ -209,7 +171,7 @@ public int minPathSum(int[][] grid) { 题目描述:统计从矩阵左上角到右下角的路径总数,每次只能向右或者向下移动。 -

+ ```java public int uniquePaths(int m, int n) { @@ -440,7 +402,7 @@ public int numDecodings(String s) { -

+ 对于一个长度为 N 的序列,最长递增子序列并不一定会以 SN 为结尾,因此 dp[N] 不是序列的最长递增子序列的长度,需要遍历 dp 数组找出最大值才是所要的结果,max{ dp[i] | 1 <= i <= N} 即为所求。 @@ -613,7 +575,7 @@ public int wiggleMaxLength(int[] nums) { -

+ 对于长度为 N 的序列 S1 和长度为 M 的序列 S2,dp[N][M] 就是序列 S1 和序列 S2 的最长公共子序列长度。 @@ -653,7 +615,7 @@ public int lengthOfLCS(int[] nums1, int[] nums2) { -

+ ```java // W 为背包总体积 @@ -682,7 +644,7 @@ public int knapsack(int W, int N, int[] weights, int[] values) { -

+ 因为 dp[j-w] 表示 dp[i-1][j-w],因此不能先求 dp[i][j-w],防止将 dp[i-1][j-w] 覆盖。也就是说要先计算 dp[i][j] 再计算 dp[i][j-w],在程序实现时需要按倒序来循环求解。 @@ -1046,7 +1008,7 @@ public int combinationSum4(int[] nums, int target) { 题目描述:交易之后需要有一天的冷却时间。 -

+ ```java public int maxProfit(int[] prices) { @@ -1089,7 +1051,7 @@ The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8. 题目描述:每交易一次,都要支付一定的费用。 -

+ ```java public int maxProfit(int[] prices, int fee) { @@ -1301,10 +1263,3 @@ public int minSteps(int n) { return dp[n]; } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 双指针.md b/docs/notes/Leetcode 题解 - 双指针.md index c97b1aa2..f720e21d 100644 --- a/docs/notes/Leetcode 题解 - 双指针.md +++ b/docs/notes/Leetcode 题解 - 双指针.md @@ -1,13 +1,4 @@ - -* [1. 有序数组的 Two Sum](#1-有序数组的-two-sum) -* [2. 两数平方和](#2-两数平方和) -* [3. 反转字符串中的元音字符](#3-反转字符串中的元音字符) -* [4. 回文字符串](#4-回文字符串) -* [5. 归并两个有序数组](#5-归并两个有序数组) -* [6. 判断链表是否存在环](#6-判断链表是否存在环) -* [7. 最长子序列](#7-最长子序列) - - +[TOC] 双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。 @@ -32,7 +23,7 @@ Output: index1=1, index2=2 数组中的元素最多遍历一次,时间复杂度为 O(N)。只使用了两个额外变量,空间复杂度为 O(1)。 -

+ ```java public int[] twoSum(int[] numbers, int target) { @@ -102,7 +93,7 @@ Explanation: 1 * 1 + 2 * 2 = 5 Given s = "leetcode", return "leotcede". ``` -

+ 使用双指针,一个指针从头向尾遍历,一个指针从尾到头遍历,当两个指针都遍历到元音字符时,交换这两个元音字符。 @@ -111,7 +102,7 @@ Given s = "leetcode", return "leotcede". - 时间复杂度为 O(N):只需要遍历所有元素一次 - 空间复杂度 O(1):只需要使用两个额外变量 -

+ ```java private final static HashSet vowels = new HashSet<>( @@ -155,7 +146,7 @@ Explanation: You could delete the character 'c'. 使用双指针可以很容易判断一个字符串是否是回文字符串:令一个指针从左到右遍历,一个指针从右到左遍历,这两个指针同时移动一个位置,每次都判断两个指针指向的字符是否相同,如果都相同,字符串才是具有左右对称性质的回文字符串。 -

+ 本题的关键是处理删除一个字符。在使用双指针遍历字符串时,如果出现两个指针指向的字符不相等的情况,我们就试着删除一个字符,再判断删除完之后的字符串是否是回文字符串。 @@ -163,7 +154,7 @@ Explanation: You could delete the character 'c'. 在试着删除字符时,我们既可以删除左指针指向的字符,也可以删除右指针指向的字符。 -

+ ```java public boolean validPalindrome(String s) { @@ -290,10 +281,3 @@ private boolean isSubstr(String s, String target) { return j == target.length(); } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 哈希表.md b/docs/notes/Leetcode 题解 - 哈希表.md index 34ed2004..465d9dc1 100644 --- a/docs/notes/Leetcode 题解 - 哈希表.md +++ b/docs/notes/Leetcode 题解 - 哈希表.md @@ -1,10 +1,4 @@ - -* [1. 数组中两个数的和为给定值](#1-数组中两个数的和为给定值) -* [2. 判断数组是否含有重复元素](#2-判断数组是否含有重复元素) -* [3. 最长和谐序列](#3-最长和谐序列) -* [4. 最长连续序列](#4-最长连续序列) - - +[TOC] 哈希表使用 O(N) 空间复杂度存储数据,并且以 O(1) 时间复杂度求解问题。 @@ -131,10 +125,3 @@ private int maxCount(Map countForNum) { return max; } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 图.md b/docs/notes/Leetcode 题解 - 图.md index c284e328..3efe5c10 100644 --- a/docs/notes/Leetcode 题解 - 图.md +++ b/docs/notes/Leetcode 题解 - 图.md @@ -1,13 +1,4 @@ - -* [二分图](#二分图) - * [1. 判断是否为二分图](#1-判断是否为二分图) -* [拓扑排序](#拓扑排序) - * [1. 课程安排的合法性](#1-课程安排的合法性) - * [2. 课程安排的顺序](#2-课程安排的顺序) -* [并查集](#并查集) - * [1. 冗余连接](#1-冗余连接) - - +[TOC] # 二分图 @@ -263,10 +254,3 @@ private class UF { } } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 字符串.md b/docs/notes/Leetcode 题解 - 字符串.md index 2fcf7fb3..96e0d2bb 100644 --- a/docs/notes/Leetcode 题解 - 字符串.md +++ b/docs/notes/Leetcode 题解 - 字符串.md @@ -1,15 +1,4 @@ - -* [1. 字符串循环移位包含](#1-字符串循环移位包含) -* [2. 字符串循环移位](#2-字符串循环移位) -* [3. 字符串中单词的翻转](#3-字符串中单词的翻转) -* [4. 两个字符串包含的字符是否完全相同](#4-两个字符串包含的字符是否完全相同) -* [5. 计算一组字符集合可以组成的回文字符串的最大长度](#5-计算一组字符集合可以组成的回文字符串的最大长度) -* [6. 字符串同构](#6-字符串同构) -* [7. 回文子字符串个数](#7-回文子字符串个数) -* [8. 判断一个整数是否是回文数](#8-判断一个整数是否是回文数) -* [9. 统计二进制字符串中连续 1 和连续 0 数量相同的子字符串个数](#9-统计二进制字符串中连续-1-和连续-0-数量相同的子字符串个数) - - +[TOC] # 1. 字符串循环移位包含 @@ -235,10 +224,3 @@ public int countBinarySubstrings(String s) { return count; } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 排序.md b/docs/notes/Leetcode 题解 - 排序.md index b9af8eb9..39c2c769 100644 --- a/docs/notes/Leetcode 题解 - 排序.md +++ b/docs/notes/Leetcode 题解 - 排序.md @@ -1,14 +1,4 @@ - -* [快速选择](#快速选择) -* [堆](#堆) - * [1. Kth Element](#1-kth-element) -* [桶排序](#桶排序) - * [1. 出现频率最多的 k 个元素](#1-出现频率最多的-k-个元素) - * [2. 按照字符出现次数对字符串排序](#2-按照字符出现次数对字符串排序) -* [荷兰国旗问题](#荷兰国旗问题) - * [1. 按颜色进行排序](#1-按颜色进行排序) - - +[TOC] # 快速选择 @@ -200,7 +190,7 @@ public String frequencySort(String s) { 有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列。它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素、等于切分元素、大于切分元素,而该算法是将数组分成三个区间:等于红色、等于白色、等于蓝色。 -

+![](pics/7a3215ec-6fb7-4935-8b0d-cb408208f7cb.png) ## 1. 按颜色进行排序 @@ -236,10 +226,3 @@ private void swap(int[] nums, int i, int j) { nums[j] = t; } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 搜索.md b/docs/notes/Leetcode 题解 - 搜索.md index 4b544517..3b6874ff 100644 --- a/docs/notes/Leetcode 题解 - 搜索.md +++ b/docs/notes/Leetcode 题解 - 搜索.md @@ -1,38 +1,10 @@ - -* [BFS](#bfs) - * [1. 计算在网格中从原点到特定点的最短路径长度](#1-计算在网格中从原点到特定点的最短路径长度) - * [2. 组成整数的最小平方数数量](#2-组成整数的最小平方数数量) - * [3. 最短单词路径](#3-最短单词路径) -* [DFS](#dfs) - * [1. 查找最大的连通面积](#1-查找最大的连通面积) - * [2. 矩阵中的连通分量数目](#2-矩阵中的连通分量数目) - * [3. 好友关系的连通分量数目](#3-好友关系的连通分量数目) - * [4. 填充封闭区域](#4-填充封闭区域) - * [5. 能到达的太平洋和大西洋的区域](#5-能到达的太平洋和大西洋的区域) -* [Backtracking](#backtracking) - * [1. 数字键盘组合](#1-数字键盘组合) - * [2. IP 地址划分](#2-ip-地址划分) - * [3. 在矩阵中寻找字符串](#3-在矩阵中寻找字符串) - * [4. 输出二叉树中所有从根到叶子的路径](#4-输出二叉树中所有从根到叶子的路径) - * [5. 排列](#5-排列) - * [6. 含有相同元素求排列](#6-含有相同元素求排列) - * [7. 组合](#7-组合) - * [8. 组合求和](#8-组合求和) - * [9. 含有相同元素的组合求和](#9-含有相同元素的组合求和) - * [10. 1-9 数字的组合求和](#10-1-9-数字的组合求和) - * [11. 子集](#11-子集) - * [12. 含有相同元素求子集](#12-含有相同元素求子集) - * [13. 分割字符串使得每个部分都是回文数](#13-分割字符串使得每个部分都是回文数) - * [14. 数独](#14-数独) - * [15. N 皇后](#15-n-皇后) - - +[TOC] 深度优先搜索和广度优先搜索广泛运用于树和图中,但是它们的应用远远不止如此。 # BFS -

+![](pics/95903878-725b-4ed9-bded-bc4aae0792a9.jpg) 广度优先搜索一层一层地进行遍历,每层遍历都以上一层遍历的结果作为起点,遍历一个距离能访问到的所有节点。需要注意的是,遍历过的节点不能再次被遍历。 @@ -269,7 +241,7 @@ private int getShortestPath(List[] graphic, int start, int end) { # DFS -

+![](pics/74dc31eb-6baa-47ea-ab1c-d27a0ca35093.png) 广度优先搜索一层一层遍历,每一层得到的所有新节点,要用队列存储起来以备下一层遍历的时候再遍历。 @@ -591,7 +563,7 @@ Backtracking(回溯)属于 DFS。 [Leetcode](https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/) / [力扣](https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/description/) -

+![](pics/9823768c-212b-4b1a-b69a-b3f59e07b977.jpg) ```html Input:Digit string "23" @@ -1194,7 +1166,7 @@ private boolean isPalindrome(String s, int begin, int end) { [Leetcode](https://leetcode.com/problems/sudoku-solver/description/) / [力扣](https://leetcode-cn.com/problems/sudoku-solver/description/) -

+![](pics/0e8fdc96-83c1-4798-9abe-45fc91d70b9d.png) ```java private boolean[][] rowsUsed = new boolean[9][10]; @@ -1253,7 +1225,7 @@ private int cubeNum(int i, int j) { [Leetcode](https://leetcode.com/problems/n-queens/description/) / [力扣](https://leetcode-cn.com/problems/n-queens/description/) -

+![](pics/067b310c-6877-40fe-9dcf-10654e737485.jpg) 在 n\*n 的矩阵中摆放 n 个皇后,并且每个皇后不能在同一行,同一列,同一对角线上,求所有的 n 皇后的解。 @@ -1261,12 +1233,12 @@ private int cubeNum(int i, int j) { 45 度对角线标记数组的长度为 2 \* n - 1,通过下图可以明确 (r, c) 的位置所在的数组下标为 r + c。 -

+ 135 度对角线标记数组的长度也是 2 \* n - 1,(r, c) 的位置所在的数组下标为 n - 1 - (r - c)。 -

+ ```java private List> solutions; @@ -1314,10 +1286,3 @@ private void backtracking(int row) { } } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 数学.md b/docs/notes/Leetcode 题解 - 数学.md index 00524e9c..38acbbb6 100644 --- a/docs/notes/Leetcode 题解 - 数学.md +++ b/docs/notes/Leetcode 题解 - 数学.md @@ -1,30 +1,4 @@ - -* [素数分解](#素数分解) -* [整除](#整除) -* [最大公约数最小公倍数](#最大公约数最小公倍数) - * [1. 生成素数序列](#1-生成素数序列) - * [2. 最大公约数](#2-最大公约数) - * [3. 使用位操作和减法求解最大公约数](#3-使用位操作和减法求解最大公约数) -* [进制转换](#进制转换) - * [1. 7 进制](#1-7-进制) - * [2. 16 进制](#2-16-进制) - * [3. 26 进制](#3-26-进制) -* [阶乘](#阶乘) - * [1. 统计阶乘尾部有多少个 0](#1-统计阶乘尾部有多少个-0) -* [字符串加法减法](#字符串加法减法) - * [1. 二进制加法](#1-二进制加法) - * [2. 字符串加法](#2-字符串加法) -* [相遇问题](#相遇问题) - * [1. 改变数组元素使所有的数组元素都相等](#1-改变数组元素使所有的数组元素都相等) -* [多数投票问题](#多数投票问题) - * [1. 数组中出现次数多于 n / 2 的元素](#1-数组中出现次数多于-n--2-的元素) -* [其它](#其它) - * [1. 平方数](#1-平方数) - * [2. 3 的 n 次方](#2-3-的-n-次方) - * [3. 乘积数组](#3-乘积数组) - * [4. 找出数组中的乘积最大的三个数](#4-找出数组中的乘积最大的三个数) - - +[TOC] # 素数分解 @@ -531,10 +505,3 @@ public int maximumProduct(int[] nums) { return Math.max(max1*max2*max3, max1*min1*min2); } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 数组与矩阵.md b/docs/notes/Leetcode 题解 - 数组与矩阵.md index 2e6270ea..fb0f8a42 100644 --- a/docs/notes/Leetcode 题解 - 数组与矩阵.md +++ b/docs/notes/Leetcode 题解 - 数组与矩阵.md @@ -1,18 +1,4 @@ - -* [1. 把数组中的 0 移到末尾](#1-把数组中的-0-移到末尾) -* [2. 改变矩阵维度](#2-改变矩阵维度) -* [3. 找出数组中最长的连续 1](#3-找出数组中最长的连续-1) -* [4. 有序矩阵查找](#4-有序矩阵查找) -* [5. 有序矩阵的 Kth Element](#5-有序矩阵的-kth-element) -* [6. 一个数组元素在 [1, n] 之间,其中一个数被替换为另一个数,找出重复的数和丢失的数](#6-一个数组元素在-[1,-n]-之间,其中一个数被替换为另一个数,找出重复的数和丢失的数) -* [7. 找出数组中重复的数,数组值在 [1, n] 之间](#7-找出数组中重复的数,数组值在-[1,-n]-之间) -* [8. 数组相邻差值的个数](#8-数组相邻差值的个数) -* [9. 数组的度](#9-数组的度) -* [10. 对角元素相等的矩阵](#10-对角元素相等的矩阵) -* [11. 嵌套数组](#11-嵌套数组) -* [12. 分隔数组](#12-分隔数组) - - +[TOC] # 1. 把数组中的 0 移到末尾 @@ -461,10 +447,3 @@ public int maxChunksToSorted(int[] arr) { return ret; } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 栈和队列.md b/docs/notes/Leetcode 题解 - 栈和队列.md index 5494bbbb..02eae2da 100644 --- a/docs/notes/Leetcode 题解 - 栈和队列.md +++ b/docs/notes/Leetcode 题解 - 栈和队列.md @@ -1,12 +1,4 @@ - -* [1. 用栈实现队列](#1-用栈实现队列) -* [2. 用队列实现栈](#2-用队列实现栈) -* [3. 最小值栈](#3-最小值栈) -* [4. 用栈实现括号匹配](#4-用栈实现括号匹配) -* [5. 数组中元素与下一个比它大的元素之间的距离](#5-数组中元素与下一个比它大的元素之间的距离) -* [6. 循环数组中比当前元素大的下一个元素](#6-循环数组中比当前元素大的下一个元素) - - +[TOC] # 1. 用栈实现队列 @@ -230,10 +222,3 @@ public int[] nextGreaterElements(int[] nums) { return next; } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 树.md b/docs/notes/Leetcode 题解 - 树.md index da7eab1c..d7be1fcf 100644 --- a/docs/notes/Leetcode 题解 - 树.md +++ b/docs/notes/Leetcode 题解 - 树.md @@ -1,42 +1,4 @@ - -* [递归](#递归) - * [1. 树的高度](#1-树的高度) - * [2. 平衡树](#2-平衡树) - * [3. 两节点的最长路径](#3-两节点的最长路径) - * [4. 翻转树](#4-翻转树) - * [5. 归并两棵树](#5-归并两棵树) - * [6. 判断路径和是否等于一个数](#6-判断路径和是否等于一个数) - * [7. 统计路径和等于一个数的路径数量](#7-统计路径和等于一个数的路径数量) - * [8. 子树](#8-子树) - * [9. 树的对称](#9-树的对称) - * [10. 最小路径](#10-最小路径) - * [11. 统计左叶子节点的和](#11-统计左叶子节点的和) - * [12. 相同节点值的最大路径长度](#12-相同节点值的最大路径长度) - * [13. 间隔遍历](#13-间隔遍历) - * [14. 找出二叉树中第二小的节点](#14-找出二叉树中第二小的节点) -* [层次遍历](#层次遍历) - * [1. 一棵树每层节点的平均数](#1-一棵树每层节点的平均数) - * [2. 得到左下角的节点](#2-得到左下角的节点) -* [前中后序遍历](#前中后序遍历) - * [1. 非递归实现二叉树的前序遍历](#1-非递归实现二叉树的前序遍历) - * [2. 非递归实现二叉树的后序遍历](#2-非递归实现二叉树的后序遍历) - * [3. 非递归实现二叉树的中序遍历](#3-非递归实现二叉树的中序遍历) -* [BST](#bst) - * [1. 修剪二叉查找树](#1-修剪二叉查找树) - * [2. 寻找二叉查找树的第 k 个元素](#2-寻找二叉查找树的第-k-个元素) - * [3. 把二叉查找树每个节点的值都加上比它大的节点的值](#3-把二叉查找树每个节点的值都加上比它大的节点的值) - * [4. 二叉查找树的最近公共祖先](#4-二叉查找树的最近公共祖先) - * [5. 二叉树的最近公共祖先](#5-二叉树的最近公共祖先) - * [6. 从有序数组中构造二叉查找树](#6-从有序数组中构造二叉查找树) - * [7. 根据有序链表构造平衡的二叉查找树](#7-根据有序链表构造平衡的二叉查找树) - * [8. 在二叉查找树中寻找两个节点,使它们的和为一个给定值](#8-在二叉查找树中寻找两个节点,使它们的和为一个给定值) - * [9. 在二叉查找树中查找两个节点之差的最小绝对值](#9-在二叉查找树中查找两个节点之差的最小绝对值) - * [10. 寻找二叉查找树中出现次数最多的值](#10-寻找二叉查找树中出现次数最多的值) -* [Trie](#trie) - * [1. 实现一个 Trie](#1-实现一个-trie) - * [2. 实现一个 Trie,用来求前缀和](#2-实现一个-trie,用来求前缀和) - - +[TOC] # 递归 @@ -1045,7 +1007,7 @@ private void inOrder(TreeNode node, List nums) { # Trie -

+![](pics/5c638d59-d4ae-4ba4-ad44-80bdc30f38dd.jpg) Trie,又称前缀树或字典树,用于判断字符串是否存在或者是否具有某种字符串前缀。 @@ -1180,10 +1142,3 @@ class MapSum { } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 目录.md b/docs/notes/Leetcode 题解 - 目录.md index 2458e510..e40505e8 100644 --- a/docs/notes/Leetcode 题解 - 目录.md +++ b/docs/notes/Leetcode 题解 - 目录.md @@ -1,5 +1,3 @@ - - 本文从 Leetcode 中精选大概 200 左右的题目,去除了某些繁杂但是没有多少算法思想的题目,同时保留了面试中经常被问到的经典题目。 # 算法思想 @@ -33,10 +31,3 @@ - 何海涛, 软件工程师. 剑指 Offer: 名企面试官精讲典型编程题[M]. 电子工业出版社, 2014. - 《编程之美》小组. 编程之美[M]. 电子工业出版社, 2008. - 左程云. 程序员代码面试指南[M]. 电子工业出版社, 2015. - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 目录1.md b/docs/notes/Leetcode 题解 - 目录1.md index 40c1cee2..d93b96a2 100644 --- a/docs/notes/Leetcode 题解 - 目录1.md +++ b/docs/notes/Leetcode 题解 - 目录1.md @@ -1,5 +1,3 @@ - - 本文从 Leetcode 中精选大概 200 左右的题目,去除了某些繁杂但是没有多少算法思想的题目,同时保留了面试中经常被问到的经典题目。 # 算法思想 @@ -33,10 +31,3 @@ - 何海涛, 软件工程师. 剑指 Offer: 名企面试官精讲典型编程题[M]. 电子工业出版社, 2014. - 《编程之美》小组. 编程之美[M]. 电子工业出版社, 2008. - 左程云. 程序员代码面试指南[M]. 电子工业出版社, 2015. - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 贪心思想.md b/docs/notes/Leetcode 题解 - 贪心思想.md index 3462be84..4d0e1215 100644 --- a/docs/notes/Leetcode 题解 - 贪心思想.md +++ b/docs/notes/Leetcode 题解 - 贪心思想.md @@ -1,17 +1,4 @@ - -* [1. 分配饼干](#1-分配饼干) -* [2. 不重叠的区间个数](#2-不重叠的区间个数) -* [3. 投飞镖刺破气球](#3-投飞镖刺破气球) -* [4. 根据身高和序号重组队列](#4-根据身高和序号重组队列) -* [5. 买卖股票最大的收益](#5-买卖股票最大的收益) -* [6. 买卖股票的最大收益 II](#6-买卖股票的最大收益-ii) -* [7. 种植花朵](#7-种植花朵) -* [8. 判断是否为子序列](#8-判断是否为子序列) -* [9. 修改一个数成为非递减数组](#9-修改一个数成为非递减数组) -* [10. 子数组最大的和](#10-子数组最大的和) -* [11. 分隔字符串使同种字符出现在一起](#11-分隔字符串使同种字符出现在一起) - - +[TOC] 保证每次操作都是局部最优的,并且最后得到的结果是全局最优的。 @@ -35,7 +22,7 @@ Output: 2 证明:假设在某次选择中,贪心策略选择给当前满足度最小的孩子分配第 m 个饼干,第 m 个饼干为可以满足该孩子的最小饼干。假设存在一种最优策略,可以给该孩子分配第 n 个饼干,并且 m < n。我们可以发现,经过这一轮分配,贪心策略分配后剩下的饼干一定有一个比最优策略来得大。因此在后续的分配中,贪心策略一定能满足更多的孩子。也就是说不存在比贪心策略更优的策略,即贪心策略就是最优策略。 -

+ ```java public int findContentChildren(int[] grid, int[] size) { @@ -390,10 +377,3 @@ private int char2Index(char c) { return c - 'a'; } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解 - 链表.md b/docs/notes/Leetcode 题解 - 链表.md index d5892146..e47344cf 100644 --- a/docs/notes/Leetcode 题解 - 链表.md +++ b/docs/notes/Leetcode 题解 - 链表.md @@ -1,16 +1,4 @@ - -* [1. 找出两个链表的交点](#1-找出两个链表的交点) -* [2. 链表反转](#2-链表反转) -* [3. 归并两个有序的链表](#3-归并两个有序的链表) -* [4. 从有序链表中删除重复节点](#4-从有序链表中删除重复节点) -* [5. 删除链表的倒数第 n 个节点](#5-删除链表的倒数第-n-个节点) -* [6. 交换链表中的相邻结点](#6-交换链表中的相邻结点) -* [7. 链表求和](#7-链表求和) -* [8. 回文链表](#8-回文链表) -* [9. 分隔链表](#9-分隔链表) -* [10. 链表元素按奇偶聚集](#10-链表元素按奇偶聚集) - - +[TOC] 链表是空节点,或者有一个值和一个指向下一个链表的指针,因此很多链表问题可以用递归来处理。 @@ -361,10 +349,3 @@ public ListNode oddEvenList(ListNode head) { return head; } ``` - - - - - - -
diff --git a/docs/notes/Leetcode 题解.md b/docs/notes/Leetcode 题解.md index a29a0f11..5df5d8b7 100644 --- a/docs/notes/Leetcode 题解.md +++ b/docs/notes/Leetcode 题解.md @@ -1,12 +1 @@ - - - - [Leetcode 题解](https://github.com/CyC2018/CS-Notes/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3%20-%20%E7%9B%AE%E5%BD%95.md) - - - - - - -
diff --git a/docs/notes/Leetcode-Database 题解.md b/docs/notes/Leetcode-Database 题解.md index 898c66d1..c109eb68 100644 --- a/docs/notes/Leetcode-Database 题解.md +++ b/docs/notes/Leetcode-Database 题解.md @@ -1,21 +1,4 @@ - -* [595. Big Countries](#595-big-countries) -* [627. Swap Salary](#627-swap-salary) -* [620. Not Boring Movies](#620-not-boring-movies) -* [596. Classes More Than 5 Students](#596-classes-more-than-5-students) -* [182. Duplicate Emails](#182-duplicate-emails) -* [196. Delete Duplicate Emails](#196-delete-duplicate-emails) -* [175. Combine Two Tables](#175-combine-two-tables) -* [181. Employees Earning More Than Their Managers](#181-employees-earning-more-than-their-managers) -* [183. Customers Who Never Order](#183-customers-who-never-order) -* [184. Department Highest Salary](#184-department-highest-salary) -* [176. Second Highest Salary](#176-second-highest-salary) -* [177. Nth Highest Salary](#177-nth-highest-salary) -* [178. Rank Scores](#178-rank-scores) -* [180. Consecutive Numbers](#180-consecutive-numbers) -* [626. Exchange Seats](#626-exchange-seats) - - +[TOC] # 595. Big Countries @@ -1003,10 +986,3 @@ WHERE ORDER BY id; ``` - - - - - - -
diff --git a/docs/notes/Linux.md b/docs/notes/Linux.md index 705140b7..d36592aa 100644 --- a/docs/notes/Linux.md +++ b/docs/notes/Linux.md @@ -1,71 +1,4 @@ - -* [一、常用操作以及概念](#一常用操作以及概念) - * [快捷键](#快捷键) - * [求助](#求助) - * [关机](#关机) - * [PATH](#path) - * [sudo](#sudo) - * [包管理工具](#包管理工具) - * [发行版](#发行版) - * [VIM 三个模式](#vim-三个模式) - * [GNU](#gnu) - * [开源协议](#开源协议) -* [二、磁盘](#二磁盘) - * [磁盘接口](#磁盘接口) - * [磁盘的文件名](#磁盘的文件名) -* [三、分区](#三分区) - * [分区表](#分区表) - * [开机检测程序](#开机检测程序) -* [四、文件系统](#四文件系统) - * [分区与文件系统](#分区与文件系统) - * [组成](#组成) - * [文件读取](#文件读取) - * [磁盘碎片](#磁盘碎片) - * [block](#block) - * [inode](#inode) - * [目录](#目录) - * [日志](#日志) - * [挂载](#挂载) - * [目录配置](#目录配置) -* [五、文件](#五文件) - * [文件属性](#文件属性) - * [文件与目录的基本操作](#文件与目录的基本操作) - * [修改权限](#修改权限) - * [默认权限](#默认权限) - * [目录的权限](#目录的权限) - * [链接](#链接) - * [获取文件内容](#获取文件内容) - * [指令与文件搜索](#指令与文件搜索) -* [六、压缩与打包](#六压缩与打包) - * [压缩文件名](#压缩文件名) - * [压缩指令](#压缩指令) - * [打包](#打包) -* [七、Bash](#七bash) - * [特性](#特性) - * [变量操作](#变量操作) - * [指令搜索顺序](#指令搜索顺序) - * [数据流重定向](#数据流重定向) -* [八、管道指令](#八管道指令) - * [提取指令](#提取指令) - * [排序指令](#排序指令) - * [双向输出重定向](#双向输出重定向) - * [字符转换指令](#字符转换指令) - * [分区指令](#分区指令) -* [九、正则表达式](#九正则表达式) - * [grep](#grep) - * [printf](#printf) - * [awk](#awk) -* [十、进程管理](#十进程管理) - * [查看进程](#查看进程) - * [进程状态](#进程状态) - * [SIGCHLD](#sigchld) - * [wait()](#wait) - * [waitpid()](#waitpid) - * [孤儿进程](#孤儿进程) - * [僵尸进程](#僵尸进程) -* [参考资料](#参考资料) - - +[TOC] # 一、常用操作以及概念 @@ -155,7 +88,7 @@ Linux 发行版是 Linux 内核及各种应用软件的集成版本。 - 编辑模式(Insert mode):按下 "i" 等按键之后进入,可以对文本进行编辑; - 指令列模式(Bottom-line mode):按下 ":" 按键之后进入,用于保存退出等操作。 -

+ 在指令列模式下,有以下命令用于离开或者保存文件。 @@ -189,25 +122,25 @@ GNU 计划,译为革奴计划,它的目标是创建一套完全自由的操 IDE(ATA)全称 Advanced Technology Attachment,接口速度最大为 133MB/s,因为并口线的抗干扰性太差,且排线占用空间较大,不利电脑内部散热,已逐渐被 SATA 所取代。 -

+ ### 2. SATA SATA 全称 Serial ATA,也就是使用串口的 ATA 接口,抗干扰性强,且对数据线的长度要求比 ATA 低很多,支持热插拔等功能。SATA-II 的接口速度为 300MiB/s,而 SATA-III 标准可达到 600MiB/s 的传输速度。SATA 的数据线也比 ATA 的细得多,有利于机箱内的空气流通,整理线材也比较方便。 -

+ ### 3. SCSI SCSI 全称是 Small Computer System Interface(小型机系统接口),SCSI 硬盘广为工作站以及个人电脑以及服务器所使用,因此会使用较为先进的技术,如碟片转速 15000rpm 的高转速,且传输时 CPU 占用率较低,但是单价也比相同容量的 ATA 及 SATA 硬盘更加昂贵。 -

+ ### 4. SAS SAS(Serial Attached SCSI)是新一代的 SCSI 技术,和 SATA 硬盘相同,都是采取序列式技术以获得更高的传输速度,可达到 6Gb/s。此外也通过缩小连接线改善系统内部空间等。 -

+ ## 磁盘的文件名 @@ -242,7 +175,7 @@ GPT 没有扩展分区概念,都是主分区,每个 LBA 可以分 4 个分 MBR 不支持 2.2 TB 以上的硬盘,GPT 则最多支持到 233 TB = 8 ZB。 -

+ ## 开机检测程序 @@ -250,7 +183,7 @@ MBR 不支持 2.2 TB 以上的硬盘,GPT 则最多支持到 233 TB BIOS(Basic Input/Output System,基本输入输出系统),它是一个固件(嵌入在硬件中的软件),BIOS 程序存放在断电后内容不会丢失的只读内存中。 -

+![](pics/50831a6f-2777-46ea-a571-29f23c85cc21.jpg) BIOS 是开机的时候计算机执行的第一个程序,这个程序知道可以开机的磁盘,并读取磁盘第一个扇区的主要开机记录(MBR),由主要开机记录(MBR)执行其中的开机管理程序,这个开机管理程序会加载操作系统的核心文件。 @@ -258,7 +191,7 @@ BIOS 是开机的时候计算机执行的第一个程序,这个程序知道可 下图中,第一扇区的主要开机记录(MBR)中的开机管理程序提供了两个选单:M1、M2,M1 指向了 Windows 操作系统,而 M2 指向其它分区的启动扇区,里面包含了另外一个开机管理程序,提供了一个指向 Linux 的选单。 -

+ 安装多重引导,最好先安装 Windows 再安装 Linux。因为安装 Windows 时会覆盖掉主要开机记录(MBR),而 Linux 可以选择将开机管理程序安装在主要开机记录(MBR)或者其它分区的启动扇区,并且可以设置开机管理程序的选单。 @@ -284,17 +217,17 @@ BIOS 不可以读取 GPT 分区表,而 UEFI 可以。 - superblock:记录文件系统的整体信息,包括 inode 和 block 的总量、使用量、剩余量,以及文件系统的格式与相关信息等; - block bitmap:记录 block 是否被使用的位图。 -

+ ## 文件读取 对于 Ext2 文件系统,当要读取一个文件的内容时,先在 inode 中查找文件内容所在的所有 block,然后把所有 block 的内容读出来。 -

+ 而对于 FAT 文件系统,它没有 inode,每个 block 中存储着下一个 block 的编号。 -

+ ## 磁盘碎片 @@ -331,7 +264,7 @@ inode 具有以下特点: inode 中记录了文件内容所在的 block 编号,但是每个 block 非常小,一个大文件随便都需要几十万的 block。而一个 inode 大小有限,无法直接引用这么多 block 编号。因此引入了间接、双间接、三间接引用。间接引用让 inode 记录的引用 block 块记录引用信息。 -

+ ## 目录 @@ -357,7 +290,7 @@ ext3/ext4 文件系统引入了日志功能,可以利用日志来修复文件 - /usr (unix software resource):所有系统默认软件都会安装到这个目录; - /var (variable):存放系统或程序运行过程中的数据文件。 -

+ # 五、文件 @@ -524,7 +457,7 @@ cp [-adfilprsu] source destination ## 链接 -

+ ```html @@ -652,7 +585,7 @@ example: find . -name "shadow*" +4、4 和 -4 的指示的时间范围如下: -

+ **② 与文件拥有者和所属群组有关的选项** @@ -1166,7 +1099,7 @@ dmtsai lines: 5 columns: 9 | T | stopped (either by a job control signal or because it is being traced)
结束,进程既可以被作业控制信号结束,也可能是正在被追踪。|
-

+ ## SIGCHLD @@ -1179,7 +1112,7 @@ dmtsai lines: 5 columns: 9 在子进程退出时,它的进程描述符不会立即释放,这是为了让父进程得到子进程信息,父进程通过 wait() 和 waitpid() 来获得一个已经退出的子进程的信息。 -

+ ## wait() @@ -1243,10 +1176,3 @@ options 参数主要有 WNOHANG 和 WUNTRACED 两个选项,WNOHANG 可以使 w - [File system design case studies](https://www.cs.rutgers.edu/\~pxk/416/notes/13-fs-studies.html) - [Programming Project #4](https://classes.soe.ucsc.edu/cmps111/Fall08/proj4.shtml) - [FILE SYSTEM DESIGN](http://web.cs.ucla.edu/classes/fall14/cs111/scribe/11a/index.html) - - - - - - -
diff --git a/docs/notes/MySQL.md b/docs/notes/MySQL.md index fb4a2cd1..ef1c5f27 100644 --- a/docs/notes/MySQL.md +++ b/docs/notes/MySQL.md @@ -1,34 +1,4 @@ - -* [一、索引](#一索引) - * [B+ Tree 原理](#b-tree-原理) - * [MySQL 索引](#mysql-索引) - * [索引优化](#索引优化) - * [索引的优点](#索引的优点) - * [索引的使用条件](#索引的使用条件) -* [二、查询性能优化](#二查询性能优化) - * [使用 Explain 进行分析](#使用-explain-进行分析) - * [优化数据访问](#优化数据访问) - * [重构查询方式](#重构查询方式) -* [三、存储引擎](#三存储引擎) - * [InnoDB](#innodb) - * [MyISAM](#myisam) - * [比较](#比较) -* [四、数据类型](#四数据类型) - * [整型](#整型) - * [浮点数](#浮点数) - * [字符串](#字符串) - * [时间和日期](#时间和日期) -* [五、切分](#五切分) - * [水平切分](#水平切分) - * [垂直切分](#垂直切分) - * [Sharding 策略](#sharding-策略) - * [Sharding 存在的问题](#sharding-存在的问题) -* [六、复制](#六复制) - * [主从复制](#主从复制) - * [读写分离](#读写分离) -* [参考资料](#参考资料) - - +[TOC] # 一、索引 @@ -42,7 +12,7 @@ B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具 在 B+ Tree 中,一个节点中的 key 从左到右非递减排列,如果某个指针的左右相邻 key 分别是 keyi 和 keyi+1,且不为 null,则该指针指向节点的所有 key 大于等于 keyi 且小于等于 keyi+1。 -

+ ### 2. 操作 @@ -84,11 +54,11 @@ B+ Tree 是基于 B Tree 和叶子节点顺序访问指针进行实现,它具 InnoDB 的 B+Tree 索引分为主索引和辅助索引。主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。 -

+ 辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到主索引中进行查找。 -

+ ### 2. 哈希索引 @@ -350,7 +320,7 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 当一个表的数据不断增多时,Sharding 是必然的选择,它可以将数据分布到集群的不同节点上,从而缓存单个数据库的压力。 -

+ ## 垂直切分 @@ -358,7 +328,7 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 在数据库的层面使用垂直切分将按数据库中表的密集程度部署到不同的库中,例如将原来的电商数据库垂直切分成商品数据库、用户数据库等。 -

+ ## Sharding 策略 @@ -392,7 +362,7 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 - **I/O 线程** :负责从主服务器上读取二进制日志,并写入从服务器的中继日志(Relay log)。 - **SQL 线程** :负责读取中继日志,解析出主服务器已经执行的数据更改并在从服务器中重放(Replay)。 -

+ ## 读写分离 @@ -406,7 +376,7 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 读写分离常用代理方式来实现,代理服务器接收应用层传来的读写请求,然后决定转发到哪个服务器。 -

+ # 参考资料 @@ -421,10 +391,3 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 - [How Sharding Works](https://medium.com/@jeeyoungk/how-sharding-works-b4dec46b3f6) - [大众点评订单系统分库分表实践](https://tech.meituan.com/dianping_order_db_sharding.html) - [B + 树](https://zh.wikipedia.org/wiki/B%2B%E6%A0%91) - - - - - - -
diff --git a/docs/notes/Redis.md b/docs/notes/Redis.md index 067522b1..f1dc5462 100644 --- a/docs/notes/Redis.md +++ b/docs/notes/Redis.md @@ -1,49 +1,4 @@ - -* [一、概述](#一概述) -* [二、数据类型](#二数据类型) - * [STRING](#string) - * [LIST](#list) - * [SET](#set) - * [HASH](#hash) - * [ZSET](#zset) -* [三、数据结构](#三数据结构) - * [字典](#字典) - * [跳跃表](#跳跃表) -* [四、使用场景](#四使用场景) - * [计数器](#计数器) - * [缓存](#缓存) - * [查找表](#查找表) - * [消息队列](#消息队列) - * [会话缓存](#会话缓存) - * [分布式锁实现](#分布式锁实现) - * [其它](#其它) -* [五、Redis 与 Memcached](#五redis-与-memcached) - * [数据类型](#数据类型) - * [数据持久化](#数据持久化) - * [分布式](#分布式) - * [内存管理机制](#内存管理机制) -* [六、键的过期时间](#六键的过期时间) -* [七、数据淘汰策略](#七数据淘汰策略) -* [八、持久化](#八持久化) - * [RDB 持久化](#rdb-持久化) - * [AOF 持久化](#aof-持久化) -* [九、事务](#九事务) -* [十、事件](#十事件) - * [文件事件](#文件事件) - * [时间事件](#时间事件) - * [事件的调度与执行](#事件的调度与执行) -* [十一、复制](#十一复制) - * [连接过程](#连接过程) - * [主从链](#主从链) -* [十二、Sentinel](#十二sentinel) -* [十三、分片](#十三分片) -* [十四、一个简单的论坛系统分析](#十四一个简单的论坛系统分析) - * [文章信息](#文章信息) - * [点赞功能](#点赞功能) - * [对文章进行排序](#对文章进行排序) -* [参考资料](#参考资料) - - +[TOC] # 一、概述 @@ -67,7 +22,7 @@ Redis 支持很多特性,例如将内存中的数据持久化到硬盘中, ## STRING -

+ ```html > set hello world @@ -82,7 +37,7 @@ OK ## LIST -

+ ```html > rpush list-key item @@ -110,7 +65,7 @@ OK ## SET -

+ ```html > sadd set-key item @@ -144,7 +99,7 @@ OK ## HASH -

+ ```html > hset hash-key sub-key1 value1 @@ -175,7 +130,7 @@ OK ## ZSET -

+ ```html > zadd zset-key 728 member1 @@ -317,11 +272,11 @@ int dictRehash(dict *d, int n) { 跳跃表是基于多指针有序链表实现的,可以看成多个有序链表。 -

+ 在查找时,从上层指针开始查找,找到对应的区间之后再到下一层去查找。下图演示了查找 22 的过程。 -

+ 与红黑树等平衡树相比,跳跃表具有以下优点: @@ -472,7 +427,7 @@ Redis 服务器是一个事件驱动程序。 Redis 基于 Reactor 模式开发了自己的网络事件处理器,使用 I/O 多路复用程序来同时监听多个套接字,并将到达的事件传送给文件事件分派器,分派器会根据套接字产生的事件类型调用相应的事件处理器。 -

+ ## 时间事件 @@ -525,7 +480,7 @@ def main(): 从事件处理的角度来看,服务器运行流程如下: -

+ # 十一、复制 @@ -545,7 +500,7 @@ def main(): 随着负载不断上升,主服务器可能无法很快地更新所有从服务器,或者重新连接和重新同步从服务器将导致系统超载。为了解决这个问题,可以创建一个中间层来分担主服务器的复制工作。中间层的服务器是最上层服务器的从服务器,又是最下层服务器的主服务器。 -

+ # 十二、Sentinel @@ -580,7 +535,7 @@ Sentinel(哨兵)可以监听集群中的服务器,并在主服务器进入 Redis 没有关系型数据库中的表这一概念来将同种类型的数据存放在一起,而是使用命名空间的方式来实现这一功能。键名的前面部分存储命名空间,后面部分的内容存储 ID,通常使用 : 来进行分隔。例如下面的 HASH 的键名为 article:92617,其中 article 为命名空间,ID 为 92617。 -

+ ## 点赞功能 @@ -588,13 +543,13 @@ Redis 没有关系型数据库中的表这一概念来将同种类型的数据 为了节约内存,规定一篇文章发布满一周之后,就不能再对它进行投票,而文章的已投票集合也会被删除,可以为文章的已投票集合设置一个一周的过期时间就能实现这个规定。 -

+ ## 对文章进行排序 为了按发布时间和点赞数进行排序,可以建立一个文章发布时间的有序集合和一个文章点赞数的有序集合。(下图中的 score 就是这里所说的点赞数;下面所示的有序集合分值并不直接是时间和点赞数,而是根据时间和点赞数间接计算出来的) -

+ # 参考资料 @@ -606,10 +561,3 @@ Redis 没有关系型数据库中的表这一概念来将同种类型的数据 - [Redis 3.0 中文版- 分片](http://wiki.jikexueyuan.com/project/redis-guide) - [Redis 应用场景](http://www.scienjus.com/redis-use-case/) - [Using Redis as an LRU cache](https://redis.io/topics/lru-cache) - - - - - - -
diff --git a/docs/notes/SQL.md b/docs/notes/SQL.md index 067d975b..05d0f47f 100644 --- a/docs/notes/SQL.md +++ b/docs/notes/SQL.md @@ -1,30 +1,4 @@ - -* [一、基础](#一基础) -* [二、创建表](#二创建表) -* [三、修改表](#三修改表) -* [四、插入](#四插入) -* [五、更新](#五更新) -* [六、删除](#六删除) -* [七、查询](#七查询) -* [八、排序](#八排序) -* [九、过滤](#九过滤) -* [十、通配符](#十通配符) -* [十一、计算字段](#十一计算字段) -* [十二、函数](#十二函数) -* [十三、分组](#十三分组) -* [十四、子查询](#十四子查询) -* [十五、连接](#十五连接) -* [十六、组合查询](#十六组合查询) -* [十七、视图](#十七视图) -* [十八、存储过程](#十八存储过程) -* [十九、游标](#十九游标) -* [二十、触发器](#二十触发器) -* [二十一、事务管理](#二十一事务管理) -* [二十二、字符集](#二十二字符集) -* [二十三、权限管理](#二十三权限管理) -* [参考资料](#参考资料) - - +[TOC] # 一、基础 @@ -769,10 +743,3 @@ SET PASSWROD FOR myuser = Password('new_password'); # 参考资料 - BenForta. SQL 必知必会 [M]. 人民邮电出版社, 2013. - - - - - - -
diff --git a/docs/notes/Socket.md b/docs/notes/Socket.md index d7395aff..b1393e41 100644 --- a/docs/notes/Socket.md +++ b/docs/notes/Socket.md @@ -1,21 +1,4 @@ - -* [一、I/O 模型](#一io-模型) - * [阻塞式 I/O](#阻塞式-io) - * [非阻塞式 I/O](#非阻塞式-io) - * [I/O 复用](#io-复用) - * [信号驱动 I/O](#信号驱动-io) - * [异步 I/O](#异步-io) - * [五大 I/O 模型比较](#五大-io-模型比较) -* [二、I/O 复用](#二io-复用) - * [select](#select) - * [poll](#poll) - * [比较](#比较) - * [epoll](#epoll) - * [工作模式](#工作模式) - * [应用场景](#应用场景) -* [参考资料](#参考资料) - - +[TOC] # 一、I/O 模型 @@ -46,7 +29,7 @@ Unix 有五种 I/O 模型: ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); ``` -

+![](pics/1492928416812_4.png) ## 非阻塞式 I/O @@ -54,7 +37,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 由于 CPU 要处理更多的系统调用,因此这种模型的 CPU 利用率比较低。 -

+![](pics/1492929000361_5.png) ## I/O 复用 @@ -64,7 +47,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 如果一个 Web 服务器没有 I/O 复用,那么每一个 Socket 连接都需要创建一个线程去处理。如果同时有几万个连接,那么就需要创建相同数量的线程。相比于多进程和多线程技术,I/O 复用不需要进程线程创建和切换的开销,系统开销更小。 -

+![](pics/1492929444818_6.png) ## 信号驱动 I/O @@ -72,7 +55,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 相比于非阻塞式 I/O 的轮询方式,信号驱动 I/O 的 CPU 利用率更高。 -

+![](pics/1492929553651_7.png) ## 异步 I/O @@ -80,7 +63,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 异步 I/O 与信号驱动 I/O 的区别在于,异步 I/O 的信号是通知应用进程 I/O 完成,而信号驱动 I/O 的信号是通知应用进程可以开始 I/O。 -

+![](pics/1492930243286_8.png) ## 五大 I/O 模型比较 @@ -91,7 +74,7 @@ ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr * 非阻塞式 I/O 、信号驱动 I/O 和异步 I/O 在第一阶段不会阻塞。 -

+![](pics/1492928105791_3.png) # 二、I/O 复用 @@ -333,10 +316,3 @@ poll 没有最大描述符数量的限制,如果平台支持并且对实时性 - [poll vs select vs event-based](https://daniel.haxx.se/docs/poll-vs-select.html) - [select / poll / epoll: practical difference for system architects](http://www.ulduzsoft.com/2014/01/select-poll-epoll-practical-difference-for-system-architects/) - [Browse the source code of userspace/glibc/sysdeps/unix/sysv/linux/ online](https://code.woboq.org/userspace/glibc/sysdeps/unix/sysv/linux/) - - - - - - -
diff --git a/docs/notes/代码可读性.md b/docs/notes/代码可读性.md index e37ccfd7..562f2f96 100644 --- a/docs/notes/代码可读性.md +++ b/docs/notes/代码可读性.md @@ -1,20 +1,4 @@ - -* [一、可读性的重要性](#一可读性的重要性) -* [二、用名字表达代码含义](#二用名字表达代码含义) -* [三、名字不能带来歧义](#三名字不能带来歧义) -* [四、良好的代码风格](#四良好的代码风格) -* [五、为何编写注释](#五为何编写注释) -* [六、如何编写注释](#六如何编写注释) -* [七、提高控制流的可读性](#七提高控制流的可读性) -* [八、拆分长表达式](#八拆分长表达式) -* [九、变量与可读性](#九变量与可读性) -* [十、抽取函数](#十抽取函数) -* [十一、一次只做一件事](#十一一次只做一件事) -* [十二、用自然语言表述代码](#十二用自然语言表述代码) -* [十三、减少代码量](#十三减少代码量) -* [参考资料](#参考资料) - - +[TOC] # 一、可读性的重要性 @@ -48,11 +32,11 @@ - 用 min、max 表示数量范围; - 用 first、last 表示访问空间的包含范围; -

+ - begin、end 表示访问空间的排除范围,即 end 不包含尾部。 -

+ # 四、良好的代码风格 @@ -331,10 +315,3 @@ public int findClostElement(int[] arr) { # 参考资料 - Dustin, Boswell, Trevor, 等. 编写可读代码的艺术 [M]. 机械工业出版社, 2012. - - - - - - -
diff --git a/docs/notes/代码风格规范.md b/docs/notes/代码风格规范.md index a2e6ea80..cc266519 100644 --- a/docs/notes/代码风格规范.md +++ b/docs/notes/代码风格规范.md @@ -1,14 +1,3 @@ - - - - - [Twitter Java Style Guide](https://github.com/twitter/commons/blob/master/src/java/com/twitter/common/styleguide.md) - [Google Java Style Guide](http://google.github.io/styleguide/javaguide.html) - [阿里巴巴Java开发手册](https://github.com/alibaba/p3c) - - - - - - -
diff --git a/docs/notes/分布式.md b/docs/notes/分布式.md index 70e2d115..df00f6ab 100644 --- a/docs/notes/分布式.md +++ b/docs/notes/分布式.md @@ -1,31 +1,4 @@ - -* [一、分布式锁](#一分布式锁) - * [数据库的唯一索引](#数据库的唯一索引) - * [Redis 的 SETNX 指令](#redis-的-setnx-指令) - * [Redis 的 RedLock 算法](#redis-的-redlock-算法) - * [Zookeeper 的有序节点](#zookeeper-的有序节点) -* [二、分布式事务](#二分布式事务) - * [2PC](#2pc) - * [本地消息表](#本地消息表) -* [三、CAP](#三cap) - * [一致性](#一致性) - * [可用性](#可用性) - * [分区容忍性](#分区容忍性) - * [权衡](#权衡) -* [四、BASE](#四base) - * [基本可用](#基本可用) - * [软状态](#软状态) - * [最终一致性](#最终一致性) -* [五、Paxos](#五paxos) - * [执行过程](#执行过程) - * [约束条件](#约束条件) -* [六、Raft](#六raft) - * [单个 Candidate 的竞选](#单个-candidate-的竞选) - * [多个 Candidate 竞选](#多个-candidate-竞选) - * [数据同步](#数据同步) -* [参考](#参考) - - +[TOC] # 一、分布式锁 @@ -70,7 +43,7 @@ EXPIRE 指令可以为一个键值对设置一个过期时间,从而避免了 Zookeeper 提供了一种树形结构的命名空间,/app1/p_1 节点的父节点为 /app1。 -

+ ### 2. 节点类型 @@ -113,7 +86,7 @@ Zookeeper 提供了一种树形结构的命名空间,/app1/p_1 节点的父节 协调者询问参与者事务是否执行成功,参与者发回事务执行结果。 -

+ #### 1.2 提交阶段 @@ -121,7 +94,7 @@ Zookeeper 提供了一种树形结构的命名空间,/app1/p_1 节点的父节 需要注意的是,在准备阶段,参与者执行了事务,但是还未提交。只有在提交阶段接收到协调者发来的通知后,才进行提交或者回滚。 -

+ ### 2. 存在的问题 @@ -149,14 +122,14 @@ Zookeeper 提供了一种树形结构的命名空间,/app1/p_1 节点的父节 2. 之后将本地消息表中的消息转发到消息队列中,如果转发成功则将消息从本地消息表中删除,否则继续重新转发。 3. 在分布式事务操作的另一方从消息队列中读取一个消息,并执行消息中的操作。 -

+ # 三、CAP 分布式系统不可能同时满足一致性(C:Consistency)、可用性(A:Availability)和分区容忍性(P:Partition Tolerance),最多只能同时满足其中两项。 -

+ ## 一致性 @@ -220,7 +193,7 @@ ACID 要求强一致性,通常运用在传统的数据库系统上。而 BASE - 接受者(Acceptor):对每个提议进行投票; - 告知者(Learner):被告知投票的结果,不参与投票过程。 -

+![](pics/b988877c-0f0a-4593-916d-de2081320628.jpg) ## 执行过程 @@ -230,19 +203,19 @@ ACID 要求强一致性,通常运用在传统的数据库系统上。而 BASE 下图演示了两个 Proposer 和三个 Acceptor 的系统中运行该算法的初始过程,每个 Proposer 都会向所有 Acceptor 发送 Prepare 请求。 -

+![](pics/1a9977e4-2f5c-49a6-aec9-f3027c9f46a7.png) 当 Acceptor 接收到一个 Prepare 请求,包含的提议为 [n1, v1],并且之前还未接收过 Prepare 请求,那么发送一个 Prepare 响应,设置当前接收到的提议为 [n1, v1],并且保证以后不会再接受序号小于 n1 的提议。 如下图,Acceptor X 在收到 [n=2, v=8] 的 Prepare 请求时,由于之前没有接收过提议,因此就发送一个 [no previous] 的 Prepare 响应,设置当前接收到的提议为 [n=2, v=8],并且保证以后不会再接受序号小于 2 的提议。其它的 Acceptor 类似。 -

+![](pics/fb44307f-8e98-4ff7-a918-31dacfa564b4.jpg) 如果 Acceptor 接收到一个 Prepare 请求,包含的提议为 [n2, v2],并且之前已经接收过提议 [n1, v1]。如果 n1 > n2,那么就丢弃该提议请求;否则,发送 Prepare 响应,该 Prepare 响应包含之前已经接收过的提议 [n1, v1],设置当前接收到的提议为 [n2, v2],并且保证以后不会再接受序号小于 n2 的提议。 如下图,Acceptor Z 收到 Proposer A 发来的 [n=2, v=8] 的 Prepare 请求,由于之前已经接收过 [n=4, v=5] 的提议,并且 n > 2,因此就抛弃该提议请求;Acceptor X 收到 Proposer B 发来的 [n=4, v=5] 的 Prepare 请求,因为之前接收到的提议为 [n=2, v=8],并且 2 <= 4,因此就发送 [n=2, v=8] 的 Prepare 响应,设置当前接收到的提议为 [n=4, v=5],并且保证以后不会再接受序号小于 4 的提议。Acceptor Y 类似。 -

+![](pics/2bcc58ad-bf7f-485c-89b5-e7cafc211ce2.jpg) ### 2. Accept 阶段 @@ -252,13 +225,13 @@ Proposer A 接收到两个 Prepare 响应之后,就发送 [n=2, v=8] Accept Proposer B 过后也收到了两个 Prepare 响应,因此也开始发送 Accept 请求。需要注意的是,Accept 请求的 v 需要取它收到的最大提议编号对应的 v 值,也就是 8。因此它发送 [n=4, v=8] 的 Accept 请求。 -

+![](pics/9b838aee-0996-44a5-9b0f-3d1e3e2f5100.png) ### 3. Learn 阶段 Acceptor 接收到 Accept 请求时,如果序号大于等于该 Acceptor 承诺的最小序号,那么就发送 Learn 提议给所有的 Learner。当 Learner 发现有大多数的 Acceptor 接收了某个提议,那么该提议的提议值就被 Paxos 选择出来。 -

+![](pics/bf667594-bb4b-4634-bf9b-0596a45415ba.jpg) ## 约束条件 @@ -284,47 +257,47 @@ Raft 也是分布式一致性协议,主要是用来竞选主节点。 - 下图展示一个分布式系统的最初阶段,此时只有 Follower 没有 Leader。Node A 等待一个随机的竞选超时时间之后,没收到 Leader 发来的心跳包,因此进入竞选阶段。 -

+![](pics/111521118015898.gif) - 此时 Node A 发送投票请求给其它所有节点。 -

+![](pics/111521118445538.gif) - 其它节点会对请求进行回复,如果超过一半的节点回复了,那么该 Candidate 就会变成 Leader。 -

+![](pics/111521118483039.gif) - 之后 Leader 会周期性地发送心跳包给 Follower,Follower 接收到心跳包,会重新开始计时。 -

+![](pics/111521118640738.gif) ## 多个 Candidate 竞选 - 如果有多个 Follower 成为 Candidate,并且所获得票数相同,那么就需要重新开始投票。例如下图中 Node B 和 Node D 都获得两票,需要重新开始投票。 -

+![](pics/111521119203347.gif) - 由于每个节点设置的随机竞选超时时间不同,因此下一次再次出现多个 Candidate 并获得同样票数的概率很低。 -

+![](pics/111521119368714.gif) ## 数据同步 - 来自客户端的修改都会被传入 Leader。注意该修改还未被提交,只是写入日志中。 -

+![](pics/71550414107576.gif) - Leader 会把修改复制到所有 Follower。 -

+![](pics/91550414131331.gif) - Leader 会等待大多数的 Follower 也进行了修改,然后才将修改提交。 -

+![](pics/101550414151983.gif) - 此时 Leader 会通知的所有 Follower 让它们也提交修改,此时所有节点的值达成一致。 -

+![](pics/111550414182638.gif) # 参考 @@ -340,10 +313,3 @@ Raft 也是分布式一致性协议,主要是用来竞选主节点。 - [NEAT ALGORITHMS - PAXOS](http://harry.me/blog/2014/12/27/neat-algorithms-paxos/) - [Paxos By Example](https://angus.nyc/2012/paxos-by-example/) - - - - - - -
diff --git a/docs/notes/剑指 Offer 题解 - 10~19.md b/docs/notes/剑指 Offer 题解 - 10~19.md index 28dab1f6..668b6638 100644 --- a/docs/notes/剑指 Offer 题解 - 10~19.md +++ b/docs/notes/剑指 Offer 题解 - 10~19.md @@ -1,20 +1,4 @@ - -* [10.1 斐波那契数列](#101-斐波那契数列) -* [10.2 矩形覆盖](#102-矩形覆盖) -* [10.3 跳台阶](#103-跳台阶) -* [10.4 变态跳台阶](#104-变态跳台阶) -* [11. 旋转数组的最小数字](#11-旋转数组的最小数字) -* [12. 矩阵中的路径](#12-矩阵中的路径) -* [13. 机器人的运动范围](#13-机器人的运动范围) -* [14. 剪绳子](#14-剪绳子) -* [15. 二进制中 1 的个数](#15-二进制中-1-的个数) -* [16. 数值的整数次方](#16-数值的整数次方) -* [17. 打印从 1 到最大的 n 位数](#17-打印从-1-到最大的-n-位数) -* [18.1 在 O(1) 时间内删除链表节点](#181-在-o1-时间内删除链表节点) -* [18.2 删除链表中重复的结点](#182-删除链表中重复的结点) -* [19. 正则表达式匹配](#19-正则表达式匹配) - - +[TOC] # 10.1 斐波那契数列 @@ -26,13 +10,13 @@ -

+ ## 解题思路 如果使用递归求解,会重复计算一些子问题。例如,计算 f(4) 需要计算 f(3) 和 f(2),计算 f(3) 需要计算 f(2) 和 f(1),可以看到 f(2) 被重复计算了。 -

+ 递归是将一个问题划分成多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,从而避免重复求解子问题。 @@ -92,23 +76,23 @@ public class Solution { 我们可以用 2\*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2\*1 的小矩形无重叠地覆盖一个 2\*n 的大矩形,总共有多少种方法? -

+ ## 解题思路 当 n 为 1 时,只有一种覆盖方法: -

+ 当 n 为 2 时,有两种覆盖方法: -

+ 要覆盖 2\*n 的大矩形,可以先覆盖 2\*1 的矩形,再覆盖 2\*(n-1) 的矩形;或者先覆盖 2\*2 的矩形,再覆盖 2\*(n-2) 的矩形。而覆盖 2\*(n-1) 和 2\*(n-2) 的矩形可以看成子问题。该问题的递推公式如下: -

+ ```java public int RectCover(int n) { @@ -133,21 +117,21 @@ public int RectCover(int n) { 一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 -

+ ## 解题思路 当 n = 1 时,只有一种跳法: -

+ 当 n = 2 时,有两种跳法: -

+ 跳 n 阶台阶,可以先跳 1 阶台阶,再跳 n-1 阶台阶;或者先跳 2 阶台阶,再跳 n-2 阶台阶。而 n-1 和 n-2 阶台阶的跳法可以看成子问题,该问题的递推公式为: -

+ ```java public int JumpFloor(int n) { @@ -172,7 +156,7 @@ public int JumpFloor(int n) { 一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级... 它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 -

+ ## 解题思路 @@ -232,13 +216,13 @@ public int JumpFloorII(int target) { 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 -

+ ## 解题思路 将旋转数组对半分可以得到一个包含最小元素的新旋转数组,以及一个非递减排序的数组。新的旋转数组的数组元素是原数组的一半,从而将问题规模减少了一半,这种折半性质的算法的时间复杂度为 O(logN)(为了方便,这里将 log2N 写为 logN)。 -

+ 此时问题的关键在于确定对半分得到的两个数组哪一个是旋转数组,哪一个是非递减数组。我们很容易知道非递减数组的第一个元素一定小于等于最后一个元素。 @@ -300,13 +284,13 @@ private int minNumber(int[] nums, int l, int h) { 例如下面的矩阵包含了一条 bfce 路径。 -

+ ## 解题思路 使用回溯法(backtracking)进行求解,它是一种暴力搜索方法,通过搜索所有可能的结果来求解问题。回溯法在一次搜索结束时需要进行回溯(回退),将这一次搜索过程中设置的状态进行清除,从而开始一次新的搜索过程。例如下图示例中,从 f 开始,下一步有 4 种搜索可能,如果先搜索 b,需要将 b 标记为已经使用,防止重复使用。在这一次搜索结束之后,需要将 b 的已经使用状态清除,并搜索 c。 -

+ 本题的输入是数组而不是矩阵(二维数组),因此需要先将数组转换成矩阵。 @@ -522,7 +506,7 @@ public int NumberOf1(int n) { -

+ 因为 (x\*x)n/2 可以通过递归求解,并且每次递归 n 都减小一半,因此整个算法的时间复杂度为 O(logN)。 @@ -592,11 +576,11 @@ private void printNumber(char[] number) { ① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,然后令该节点指向下下个节点,再删除下一个节点,时间复杂度为 O(1)。 -

+ ② 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向 null,时间复杂度为 O(N)。 -

+ 综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个尾节点以 O(N) 的时间复杂度操作节点的总次数。(2N-1)/N \~ 2,因此该算法的平均时间复杂度为 O(1)。 @@ -630,7 +614,7 @@ public ListNode deleteNode(ListNode head, ListNode tobeDelete) { ## 题目描述 -

+ ## 解题描述 @@ -690,10 +674,3 @@ public boolean match(char[] str, char[] pattern) { return dp[m][n]; } ``` - - - - - - -
diff --git a/docs/notes/剑指 Offer 题解 - 20~29.md b/docs/notes/剑指 Offer 题解 - 20~29.md index 7f211b68..66a5953e 100644 --- a/docs/notes/剑指 Offer 题解 - 20~29.md +++ b/docs/notes/剑指 Offer 题解 - 20~29.md @@ -1,16 +1,4 @@ - -* [20. 表示数值的字符串](#20-表示数值的字符串) -* [21. 调整数组顺序使奇数位于偶数前面](#21-调整数组顺序使奇数位于偶数前面) -* [22. 链表中倒数第 K 个结点](#22-链表中倒数第-k-个结点) -* [23. 链表中环的入口结点](#23-链表中环的入口结点) -* [24. 反转链表](#24-反转链表) -* [25. 合并两个排序的链表](#25-合并两个排序的链表) -* [26. 树的子结构](#26-树的子结构) -* [27. 二叉树的镜像](#27-二叉树的镜像) -* [28 对称的二叉树](#28-对称的二叉树) -* [29. 顺时针打印矩阵](#29-顺时针打印矩阵) - - +[TOC] # 20. 表示数值的字符串 @@ -70,7 +58,7 @@ public boolean isNumeric(char[] str) { 需要保证奇数和奇数,偶数和偶数之间的相对位置不变,这和书本不太一样。 -

+ ## 解题思路 @@ -131,7 +119,7 @@ private void swap(int[] nums, int i, int j) { 设链表的长度为 N。设置两个指针 P1 和 P2,先让 P1 移动 K 个节点,则还有 N - K 个节点可以移动。此时让 P1 和 P2 同时移动,可以知道当 P1 移动到链表结尾时,P2 移动到第 N - K 个节点处,该位置就是倒数第 K 个节点。 -

+ ```java public ListNode FindKthToTail(ListNode head, int k) { @@ -165,7 +153,7 @@ public ListNode FindKthToTail(ListNode head, int k) { 在相遇点,slow 要到环的入口点还需要移动 z 个节点,如果让 fast 重新从头开始移动,并且速度变为每次移动一个节点,那么它到环入口点还需要移动 x 个节点。在上面已经推导出 x=z,因此 fast 和 slow 将在环入口点相遇。 -

+ ```java public ListNode EntryNodeOfLoop(ListNode pHead) { @@ -228,7 +216,7 @@ public ListNode ReverseList(ListNode head) { ## 题目描述 -

+ ## 解题思路 @@ -280,7 +268,7 @@ public ListNode Merge(ListNode list1, ListNode list2) { ## 题目描述 -

+ ## 解题思路 @@ -308,7 +296,7 @@ private boolean isSubtreeWithRoot(TreeNode root1, TreeNode root2) { ## 题目描述 -

+ ## 解题思路 @@ -334,7 +322,7 @@ private void swap(TreeNode root) { ## 题目描述 -

+ ## 解题思路 @@ -364,7 +352,7 @@ boolean isSymmetrical(TreeNode t1, TreeNode t2) { 下图的矩阵顺时针打印结果为:1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10 -

+ ## 解题思路 @@ -388,10 +376,3 @@ public ArrayList printMatrix(int[][] matrix) { return ret; } ``` - - - - - - -
diff --git a/docs/notes/剑指 Offer 题解 - 30~39.md b/docs/notes/剑指 Offer 题解 - 30~39.md index 75c45bf1..180bd975 100644 --- a/docs/notes/剑指 Offer 题解 - 30~39.md +++ b/docs/notes/剑指 Offer 题解 - 30~39.md @@ -1,18 +1,4 @@ - -* [30. 包含 min 函数的栈](#30-包含-min-函数的栈) -* [31. 栈的压入、弹出序列](#31-栈的压入弹出序列) -* [32.1 从上往下打印二叉树](#321-从上往下打印二叉树) -* [32.2 把二叉树打印成多行](#322-把二叉树打印成多行) -* [32.3 按之字形顺序打印二叉树](#323-按之字形顺序打印二叉树) -* [33. 二叉搜索树的后序遍历序列](#33-二叉搜索树的后序遍历序列) -* [34. 二叉树中和为某一值的路径](#34-二叉树中和为某一值的路径) -* [35. 复杂链表的复制](#35-复杂链表的复制) -* [36. 二叉搜索树与双向链表](#36-二叉搜索树与双向链表) -* [37. 序列化二叉树](#37-序列化二叉树) -* [38. 字符串的排列](#38-字符串的排列) -* [39. 数组中出现次数超过一半的数字](#39-数组中出现次数超过一半的数字) - - +[TOC] # 30. 包含 min 函数的栈 @@ -87,7 +73,7 @@ public boolean IsPopOrder(int[] pushSequence, int[] popSequence) { 例如,以下二叉树层次遍历的结果为:1,2,3,4,5,6,7 -

+ ## 解题思路 @@ -195,7 +181,7 @@ public ArrayList> Print(TreeNode pRoot) { 例如,下图是后序遍历序列 1,3,2 所对应的二叉搜索树。 -

+ ## 解题思路 @@ -230,7 +216,7 @@ private boolean verify(int[] sequence, int first, int last) { 下图的二叉树有两条和为 22 的路径:10, 5, 7 和 10, 12 -

+ ## 解题思路 @@ -277,21 +263,21 @@ public class RandomListNode { } ``` -

+ ## 解题思路 第一步,在每个节点的后面插入复制的节点。 -

+ 第二步,对复制节点的 random 链接进行赋值。 -

+ 第三步,拆分。 -

+ ```java public RandomListNode Clone(RandomListNode pHead) { @@ -333,7 +319,7 @@ public RandomListNode Clone(RandomListNode pHead) { 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 -

+ ## 解题思路 @@ -468,10 +454,3 @@ public int MoreThanHalfNum_Solution(int[] nums) { return cnt > nums.length / 2 ? majority : 0; } ``` - - - - - - -
diff --git a/docs/notes/剑指 Offer 题解 - 3~9.md b/docs/notes/剑指 Offer 题解 - 3~9.md index b236ac36..eb9a3eca 100644 --- a/docs/notes/剑指 Offer 题解 - 3~9.md +++ b/docs/notes/剑指 Offer 题解 - 3~9.md @@ -1,13 +1,4 @@ - -* [3. 数组中重复的数字](#3-数组中重复的数字) -* [4. 二维数组中的查找](#4-二维数组中的查找) -* [5. 替换空格](#5-替换空格) -* [6. 从尾到头打印链表](#6-从尾到头打印链表) -* [7. 重建二叉树](#7-重建二叉树) -* [8. 二叉树的下一个结点](#8-二叉树的下一个结点) -* [9. 用两个栈实现队列](#9-用两个栈实现队列) - - +[TOC] # 3. 数组中重复的数字 @@ -33,7 +24,7 @@ Output: 以 (2, 3, 1, 0, 2, 5) 为例,遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复: -

+ ```java @@ -87,7 +78,7 @@ Given target = 20, return false. 该二维数组中的一个数,小于它的数一定在其左边,大于它的数一定在其下边。因此,从右上角开始查找,就可以根据 target 和当前元素的大小关系来缩小查找区间,当前元素的查找区间为左下角的所有元素。 -

+ ```java public boolean Find(int target, int[][] matrix) { @@ -132,7 +123,7 @@ Output: 从后向前遍是为了在改变 P2 所指向的内容时,不会影响到 P1 遍历原来字符串的内容。 -

+ ```java public String replaceSpace(StringBuffer str) { @@ -164,7 +155,7 @@ public String replaceSpace(StringBuffer str) { 从尾到头反过来打印出每个结点的值。 -

+ ## 解题思路 @@ -192,7 +183,7 @@ public ArrayList printListFromTailToHead(ListNode listNode) { - 头结点是在头插法中使用的一个额外节点,这个节点不存储值; - 第一个节点就是链表的第一个真正存储值的节点。 -

+ ```java public ArrayList printListFromTailToHead(ListNode listNode) { @@ -219,7 +210,7 @@ public ArrayList printListFromTailToHead(ListNode listNode) { 栈具有后进先出的特点,在遍历链表时将值按顺序放入栈中,最后出栈的顺序即为逆序。 -

+ ```java public ArrayList printListFromTailToHead(ListNode listNode) { @@ -244,13 +235,13 @@ public ArrayList printListFromTailToHead(ListNode listNode) { 根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 -

+ ## 解题思路 前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两部分,左部分为树的左子树中序遍历结果,右部分为树的右子树中序遍历的结果。 -

+ ```java // 缓存中序遍历数组每个值对应的索引 @@ -300,11 +291,11 @@ public class TreeLinkNode { ① 如果一个节点的右子树不为空,那么该节点的下一个节点是右子树的最左节点; -

+ ② 否则,向上找第一个左链接指向的树包含该节点的祖先节点。 -

+ ```java public TreeLinkNode GetNext(TreeLinkNode pNode) { @@ -337,7 +328,7 @@ public TreeLinkNode GetNext(TreeLinkNode pNode) { in 栈用来处理入栈(push)操作,out 栈用来处理出栈(pop)操作。一个元素进入 in 栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入 out 栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,先进入的元素先退出,这就是队列的顺序。 -

+ ```java Stack in = new Stack(); @@ -359,10 +350,3 @@ public int pop() throws Exception { } ``` - - - - - - -
diff --git a/docs/notes/剑指 Offer 题解 - 40~49.md b/docs/notes/剑指 Offer 题解 - 40~49.md index 8bf7eaba..5ba1f2ab 100644 --- a/docs/notes/剑指 Offer 题解 - 40~49.md +++ b/docs/notes/剑指 Offer 题解 - 40~49.md @@ -1,18 +1,3 @@ - -* [40. 最小的 K 个数](#40-最小的-k-个数) -* [41.1 数据流中的中位数](#411-数据流中的中位数) -* [41.2 字符流中第一个不重复的字符](#412-字符流中第一个不重复的字符) -* [42. 连续子数组的最大和](#42-连续子数组的最大和) -* [43. 从 1 到 n 整数中 1 出现的次数](#43-从-1-到-n-整数中-1-出现的次数) -* [44. 数字序列中的某一位数字](#44-数字序列中的某一位数字) -* [45. 把数组排成最小的数](#45-把数组排成最小的数) -* [46. 把数字翻译成字符串](#46-把数字翻译成字符串) -* [47. 礼物的最大价值](#47-礼物的最大价值) -* [48. 最长不含重复字符的子字符串](#48-最长不含重复字符的子字符串) -* [49. 丑数](#49-丑数) - - - # 40. 最小的 K 个数 [NowCoder](https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf?tpId=13&tqId=11182&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) @@ -416,10 +401,3 @@ public int GetUglyNumber_Solution(int N) { return dp[N - 1]; } ``` - - - - - - -
diff --git a/docs/notes/剑指 Offer 题解 - 50~59.md b/docs/notes/剑指 Offer 题解 - 50~59.md index b2b53493..82397bc1 100644 --- a/docs/notes/剑指 Offer 题解 - 50~59.md +++ b/docs/notes/剑指 Offer 题解 - 50~59.md @@ -1,19 +1,4 @@ - -* [50. 第一个只出现一次的字符位置](#50-第一个只出现一次的字符位置) -* [51. 数组中的逆序对](#51-数组中的逆序对) -* [52. 两个链表的第一个公共结点](#52-两个链表的第一个公共结点) -* [53. 数字在排序数组中出现的次数](#53-数字在排序数组中出现的次数) -* [54. 二叉查找树的第 K 个结点](#54-二叉查找树的第-k-个结点) -* [55.1 二叉树的深度](#551-二叉树的深度) -* [55.2 平衡二叉树](#552-平衡二叉树) -* [56. 数组中只出现一次的数字](#56-数组中只出现一次的数字) -* [57.1 和为 S 的两个数字](#571-和为-s-的两个数字) -* [57.2 和为 S 的连续正数序列](#572-和为-s-的连续正数序列) -* [58.1 翻转单词顺序列](#581-翻转单词顺序列) -* [58.2 左旋转字符串](#582-左旋转字符串) -* [59. 滑动窗口的最大值](#59-滑动窗口的最大值) - - +[TOC] # 50. 第一个只出现一次的字符位置 @@ -120,7 +105,7 @@ private void merge(int[] nums, int l, int m, int h) { ## 题目描述 -

+ ## 解题思路 @@ -212,7 +197,7 @@ private void inOrder(TreeNode root, int k) { 从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 -

+ ## 解题思路 @@ -230,7 +215,7 @@ public int TreeDepth(TreeNode root) { 平衡二叉树左右子树高度差不超过 1。 -

+ ## 解题思路 @@ -477,10 +462,3 @@ public ArrayList maxInWindows(int[] num, int size) { return ret; } ``` - - - - - - -
diff --git a/docs/notes/剑指 Offer 题解 - 60~68.md b/docs/notes/剑指 Offer 题解 - 60~68.md index 8f701f01..856cae67 100644 --- a/docs/notes/剑指 Offer 题解 - 60~68.md +++ b/docs/notes/剑指 Offer 题解 - 60~68.md @@ -1,15 +1,4 @@ - -* [60. n 个骰子的点数](#60-n-个骰子的点数) -* [61. 扑克牌顺子](#61-扑克牌顺子) -* [62. 圆圈中最后剩下的数](#62-圆圈中最后剩下的数) -* [63. 股票的最大利润](#63-股票的最大利润) -* [64. 求 1+2+3+...+n](#64-求-123n) -* [65. 不用加减乘除做加法](#65-不用加减乘除做加法) -* [66. 构建乘积数组](#66-构建乘积数组) -* [67. 把字符串转换成整数](#67-把字符串转换成整数) -* [68. 树中两个节点的最低公共祖先](#68-树中两个节点的最低公共祖先) - - +[TOC] # 60. n 个骰子的点数 @@ -19,7 +8,7 @@ 把 n 个骰子扔在地上,求点数和为 s 的概率。 -

+ ## 解题思路 @@ -92,7 +81,7 @@ public List> dicesSum(int n) { 五张牌,其中大小鬼为癞子,牌面为 0。判断这五张牌是否能组成顺子。 -

+ ## 解题思路 @@ -152,7 +141,7 @@ public int LastRemaining_Solution(int n, int m) { 可以有一次买入和一次卖出,买入必须在前。求最大收益。 -

+ ## 解题思路 @@ -224,7 +213,7 @@ public int Add(int a, int b) { 给定一个数组 A[0, 1,..., n-1],请构建一个数组 B[0, 1,..., n-1],其中 B 中的元素 B[i]=A[0]\*A[1]\*...\*A[i-1]\*A[i+1]\*...\*A[n-1]。要求不能使用除法。 -

+ ## 解题思路 @@ -289,7 +278,7 @@ public int StrToInt(String str) { 二叉查找树中,两个节点 p, q 的公共祖先 root 满足 root.val >= p.val && root.val <= q.val。 -

+ ```java public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { @@ -309,7 +298,7 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 在左右子树中查找是否存在 p 或者 q,如果 p 和 q 分别在两个子树中,那么就说明根节点就是最低公共祖先。 -

+ ```java public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { @@ -320,10 +309,3 @@ public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { return left == null ? right : right == null ? left : root; } ``` - - - - - - -
diff --git a/docs/notes/剑指 Offer 题解 - 目录.md b/docs/notes/剑指 Offer 题解 - 目录.md index b4492ec2..301242e2 100644 --- a/docs/notes/剑指 Offer 题解 - 目录.md +++ b/docs/notes/剑指 Offer 题解 - 目录.md @@ -1,22 +1,83 @@ - - # 目录 -- [3\~9](剑指%20Offer%20题解%20-%203\~9.md) -- [10\~19](剑指%20Offer%20题解%20-%2010\~19.md) -- [20\~29](剑指%20Offer%20题解%20-%2020\~29.md) -- [30\~39](剑指%20Offer%20题解%20-%2030\~39.md) -- [40\~49](剑指%20Offer%20题解%20-%2040\~49.md) -- [50\~59](剑指%20Offer%20题解%20-%2050\~59.md) -- [60\~68](剑指%20Offer%20题解%20-%2060\~68.md) + +- [3. 数组中重复的数字.md](3.%20数组中重复的数字.md) +- [4. 二维数组中的查找.md](4.%20二维数组中的查找.md) +- [5. 替换空格.md](5.%20替换空格.md) +- [6. 从尾到头打印链表.md](6.%20从尾到头打印链表.md) +- [7. 重建二叉树.md](7.%20重建二叉树.md) +- [8. 二叉树的下一个结点.md](8.%20二叉树的下一个结点.md) +- [9. 用两个栈实现队列.md](9.%20用两个栈实现队列.md) +- [10.1 斐波那契数列.md](10.1%20斐波那契数列.md) +- [10.2 矩形覆盖.md](10.2%20矩形覆盖.md) +- [10.3 跳台阶.md](10.3%20跳台阶.md) +- [10.4 变态跳台阶.md](10.4%20变态跳台阶.md) +- [11. 旋转数组的最小数字.md](11.%20旋转数组的最小数字.md) +- [12. 矩阵中的路径.md](12.%20矩阵中的路径.md) +- [13. 机器人的运动范围.md](13.%20机器人的运动范围.md) +- [14. 剪绳子.md](14.%20剪绳子.md) +- [15. 二进制中 1 的个数.md](15.%20二进制中%201%20的个数.md) +- [16. 数值的整数次方.md](16.%20数值的整数次方.md) +- [17. 打印从 1 到最大的 n 位数.md](17.%20打印从%201%20到最大的%20n%20位数.md) +- [18.1 在 O(1) 时间内删除链表节点.md](18.1%20在%20O(1)%20时间内删除链表节点.md) +- [18.2 删除链表中重复的结点.md](18.2%20删除链表中重复的结点.md) +- [19. 正则表达式匹配.md](19.%20正则表达式匹配.md) +- [20. 表示数值的字符串.md](20.%20表示数值的字符串.md) +- [21. 调整数组顺序使奇数位于偶数前面.md](21.%20调整数组顺序使奇数位于偶数前面.md) +- [22. 链表中倒数第 K 个结点.md](22.%20链表中倒数第%20K%20个结点.md) +- [23. 链表中环的入口结点.md](23.%20链表中环的入口结点.md) +- [24. 反转链表.md](24.%20反转链表.md) +- [25. 合并两个排序的链表.md](25.%20合并两个排序的链表.md) +- [26. 树的子结构.md](26.%20树的子结构.md) +- [27. 二叉树的镜像.md](27.%20二叉树的镜像.md) +- [28. 对称的二叉树.md](28.%20对称的二叉树.md) +- [29. 顺时针打印矩阵.md](29.%20顺时针打印矩阵.md) +- [30. 包含 min 函数的栈.md](30.%20包含%20min%20函数的栈.md) +- [31. 栈的压入、弹出序列.md](31.%20栈的压入、弹出序列.md) +- [32.1 从上往下打印二叉树.md](32.1%20从上往下打印二叉树.md) +- [32.2 把二叉树打印成多行.md](32.2%20把二叉树打印成多行.md) +- [32.3 按之字形顺序打印二叉树.md](32.3%20按之字形顺序打印二叉树.md) +- [33. 二叉搜索树的后序遍历序列.md](33.%20二叉搜索树的后序遍历序列.md) +- [34. 二叉树中和为某一值的路径.md](34.%20二叉树中和为某一值的路径.md) +- [35. 复杂链表的复制.md](35.%20复杂链表的复制.md) +- [36. 二叉搜索树与双向链表.md](36.%20二叉搜索树与双向链表.md) +- [37. 序列化二叉树.md](37.%20序列化二叉树.md) +- [38. 字符串的排列.md](38.%20字符串的排列.md) +- [39. 数组中出现次数超过一半的数字.md](39.%20数组中出现次数超过一半的数字.md) +- [40. 最小的 K 个数.md](40.%20最小的%20K%20个数.md) +- [41.1 数据流中的中位数.md](41.1%20数据流中的中位数.md) +- [41.2 字符流中第一个不重复的字符.md](41.2%20字符流中第一个不重复的字符.md) +- [42. 连续子数组的最大和.md](42.%20连续子数组的最大和.md) +- [43. 从 1 到 n 整数中 1 出现的次数.md](43.%20从%201%20到%20n%20整数中%201%20出现的次数.md) +- [44. 数字序列中的某一位数字.md](44.%20数字序列中的某一位数字.md) +- [45. 把数组排成最小的数.md](45.%20把数组排成最小的数.md) +- [46. 把数字翻译成字符串.md](46.%20把数字翻译成字符串.md) +- [47. 礼物的最大价值.md](47.%20礼物的最大价值.md) +- [48. 最长不含重复字符的子字符串.md](48.%20最长不含重复字符的子字符串.md) +- [49. 丑数.md](49.%20丑数.md) +- [50. 第一个只出现一次的字符位置.md](50.%20第一个只出现一次的字符位置.md) +- [51. 数组中的逆序对.md](51.%20数组中的逆序对.md) +- [52. 两个链表的第一个公共结点.md](52.%20两个链表的第一个公共结点.md) +- [53. 数字在排序数组中出现的次数.md](53.%20数字在排序数组中出现的次数.md) +- [54. 二叉查找树的第 K 个结点.md](54.%20二叉查找树的第%20K%20个结点.md) +- [55.1 二叉树的深度.md](55.1%20二叉树的深度.md) +- [55.2 平衡二叉树.md](55.2%20平衡二叉树.md) +- [56. 数组中只出现一次的数字.md](56.%20数组中只出现一次的数字.md) +- [57.1 和为 S 的两个数字.md](57.1%20和为%20S%20的两个数字.md) +- [57.2 和为 S 的连续正数序列.md](57.2%20和为%20S%20的连续正数序列.md) +- [58.1 翻转单词顺序列.md](58.1%20翻转单词顺序列.md) +- [58.2 左旋转字符串.md](58.2%20左旋转字符串.md) +- [59. 滑动窗口的最大值.md](59.%20滑动窗口的最大值.md) +- [60. n 个骰子的点数.md](60.%20n%20个骰子的点数.md) +- [61. 扑克牌顺子.md](61.%20扑克牌顺子.md) +- [62. 圆圈中最后剩下的数.md](62.%20圆圈中最后剩下的数.md) +- [63. 股票的最大利润.md](63.%20股票的最大利润.md) +- [64. 求 1+2+3+...+n.md](64.%20求%201+2+3+...+n.md) +- [65. 不用加减乘除做加法.md](65.%20不用加减乘除做加法.md) +- [66. 构建乘积数组.md](66.%20构建乘积数组.md) +- [67. 把字符串转换成整数.md](67.%20把字符串转换成整数.md) +- [68. 树中两个节点的最低公共祖先.md](68.%20树中两个节点的最低公共祖先.md) # 参考文献 何海涛. 剑指 Offer[M]. 电子工业出版社, 2012. - - - - - - -
diff --git a/docs/notes/剑指 Offer 题解 - 目录1.md b/docs/notes/剑指 Offer 题解 - 目录1.md index 25dbddd6..a4c6701a 100644 --- a/docs/notes/剑指 Offer 题解 - 目录1.md +++ b/docs/notes/剑指 Offer 题解 - 目录1.md @@ -1,22 +1,83 @@ - - # 目录 -- [3\~9](notes/剑指%20Offer%20题解%20-%203\~9.md) -- [10\~19](notes/剑指%20Offer%20题解%20-%2010\~19.md) -- [20\~29](notes/剑指%20Offer%20题解%20-%2020\~29.md) -- [30\~39](notes/剑指%20Offer%20题解%20-%2030\~39.md) -- [40\~49](notes/剑指%20Offer%20题解%20-%2040\~49.md) -- [50\~59](notes/剑指%20Offer%20题解%20-%2050\~59.md) -- [60\~68](notes/剑指%20Offer%20题解%20-%2060\~68.md) +- [3. 数组中重复的数字.md](notes/3.%20数组中重复的数字.md) +- [4. 二维数组中的查找.md](notes/4.%20二维数组中的查找.md) +- [5. 替换空格.md](notes/5.%20替换空格.md) +- [6. 从尾到头打印链表.md](notes/6.%20从尾到头打印链表.md) +- [7. 重建二叉树.md](notes/7.%20重建二叉树.md) +- [8. 二叉树的下一个结点.md](notes/8.%20二叉树的下一个结点.md) +- [9. 用两个栈实现队列.md](notes/9.%20用两个栈实现队列.md) +- [10.1 斐波那契数列.md](notes/10.1%20斐波那契数列.md) +- [10.2 矩形覆盖.md](notes/10.2%20矩形覆盖.md) +- [10.3 跳台阶.md](notes/10.3%20跳台阶.md) +- [10.4 变态跳台阶.md](notes/10.4%20变态跳台阶.md) +- [11. 旋转数组的最小数字.md](notes/11.%20旋转数组的最小数字.md) +- [12. 矩阵中的路径.md](notes/12.%20矩阵中的路径.md) +- [13. 机器人的运动范围.md](notes/13.%20机器人的运动范围.md) +- [14. 剪绳子.md](notes/14.%20剪绳子.md) +- [15. 二进制中 1 的个数.md](notes/15.%20二进制中%201%20的个数.md) +- [16. 数值的整数次方.md](notes/16.%20数值的整数次方.md) +- [17. 打印从 1 到最大的 n 位数.md](notes/17.%20打印从%201%20到最大的%20n%20位数.md) +- [18.1 在 O(1) 时间内删除链表节点.md](notes/18.1%20在%20O(1)%20时间内删除链表节点.md) +- [18.2 删除链表中重复的结点.md](notes/18.2%20删除链表中重复的结点.md) +- [19. 正则表达式匹配.md](notes/19.%20正则表达式匹配.md) +- [20. 表示数值的字符串.md](notes/20.%20表示数值的字符串.md) +- [21. 调整数组顺序使奇数位于偶数前面.md](notes/21.%20调整数组顺序使奇数位于偶数前面.md) +- [22. 链表中倒数第 K 个结点.md](notes/22.%20链表中倒数第%20K%20个结点.md) +- [23. 链表中环的入口结点.md](notes/23.%20链表中环的入口结点.md) +- [24. 反转链表.md](notes/24.%20反转链表.md) +- [25. 合并两个排序的链表.md](notes/25.%20合并两个排序的链表.md) +- [26. 树的子结构.md](notes/26.%20树的子结构.md) +- [27. 二叉树的镜像.md](notes/27.%20二叉树的镜像.md) +- [28. 对称的二叉树.md](notes/28.%20对称的二叉树.md) +- [29. 顺时针打印矩阵.md](notes/29.%20顺时针打印矩阵.md) +- [30. 包含 min 函数的栈.md](notes/30.%20包含%20min%20函数的栈.md) +- [31. 栈的压入、弹出序列.md](notes/31.%20栈的压入、弹出序列.md) +- [32.1 从上往下打印二叉树.md](notes/32.1%20从上往下打印二叉树.md) +- [32.2 把二叉树打印成多行.md](notes/32.2%20把二叉树打印成多行.md) +- [32.3 按之字形顺序打印二叉树.md](notes/32.3%20按之字形顺序打印二叉树.md) +- [33. 二叉搜索树的后序遍历序列.md](notes/33.%20二叉搜索树的后序遍历序列.md) +- [34. 二叉树中和为某一值的路径.md](notes/34.%20二叉树中和为某一值的路径.md) +- [35. 复杂链表的复制.md](notes/35.%20复杂链表的复制.md) +- [36. 二叉搜索树与双向链表.md](notes/36.%20二叉搜索树与双向链表.md) +- [37. 序列化二叉树.md](notes/37.%20序列化二叉树.md) +- [38. 字符串的排列.md](notes/38.%20字符串的排列.md) +- [39. 数组中出现次数超过一半的数字.md](notes/39.%20数组中出现次数超过一半的数字.md) +- [40. 最小的 K 个数.md](notes/40.%20最小的%20K%20个数.md) +- [41.1 数据流中的中位数.md](notes/41.1%20数据流中的中位数.md) +- [41.2 字符流中第一个不重复的字符.md](notes/41.2%20字符流中第一个不重复的字符.md) +- [42. 连续子数组的最大和.md](notes/42.%20连续子数组的最大和.md) +- [43. 从 1 到 n 整数中 1 出现的次数.md](notes/43.%20从%201%20到%20n%20整数中%201%20出现的次数.md) +- [44. 数字序列中的某一位数字.md](notes/44.%20数字序列中的某一位数字.md) +- [45. 把数组排成最小的数.md](notes/45.%20把数组排成最小的数.md) +- [46. 把数字翻译成字符串.md](notes/46.%20把数字翻译成字符串.md) +- [47. 礼物的最大价值.md](notes/47.%20礼物的最大价值.md) +- [48. 最长不含重复字符的子字符串.md](notes/48.%20最长不含重复字符的子字符串.md) +- [49. 丑数.md](notes/49.%20丑数.md) +- [50. 第一个只出现一次的字符位置.md](notes/50.%20第一个只出现一次的字符位置.md) +- [51. 数组中的逆序对.md](notes/51.%20数组中的逆序对.md) +- [52. 两个链表的第一个公共结点.md](notes/52.%20两个链表的第一个公共结点.md) +- [53. 数字在排序数组中出现的次数.md](notes/53.%20数字在排序数组中出现的次数.md) +- [54. 二叉查找树的第 K 个结点.md](notes/54.%20二叉查找树的第%20K%20个结点.md) +- [55.1 二叉树的深度.md](notes/55.1%20二叉树的深度.md) +- [55.2 平衡二叉树.md](notes/55.2%20平衡二叉树.md) +- [56. 数组中只出现一次的数字.md](notes/56.%20数组中只出现一次的数字.md) +- [57.1 和为 S 的两个数字.md](notes/57.1%20和为%20S%20的两个数字.md) +- [57.2 和为 S 的连续正数序列.md](notes/57.2%20和为%20S%20的连续正数序列.md) +- [58.1 翻转单词顺序列.md](notes/58.1%20翻转单词顺序列.md) +- [58.2 左旋转字符串.md](notes/58.2%20左旋转字符串.md) +- [59. 滑动窗口的最大值.md](notes/59.%20滑动窗口的最大值.md) +- [60. n 个骰子的点数.md](notes/60.%20n%20个骰子的点数.md) +- [61. 扑克牌顺子.md](notes/61.%20扑克牌顺子.md) +- [62. 圆圈中最后剩下的数.md](notes/62.%20圆圈中最后剩下的数.md) +- [63. 股票的最大利润.md](notes/63.%20股票的最大利润.md) +- [64. 求 1+2+3+...+n.md](notes/64.%20求%201+2+3+...+n.md) +- [65. 不用加减乘除做加法.md](notes/65.%20不用加减乘除做加法.md) +- [66. 构建乘积数组.md](notes/66.%20构建乘积数组.md) +- [67. 把字符串转换成整数.md](notes/67.%20把字符串转换成整数.md) +- [68. 树中两个节点的最低公共祖先.md](notes/68.%20树中两个节点的最低公共祖先.md) + # 参考文献 何海涛. 剑指 Offer[M]. 电子工业出版社, 2012. - - - - - - -
diff --git a/docs/notes/剑指 offer 题解.md b/docs/notes/剑指 offer 题解.md index d04ad9bc..a8c498b1 100644 --- a/docs/notes/剑指 offer 题解.md +++ b/docs/notes/剑指 offer 题解.md @@ -1,12 +1 @@ - - - - [剑指 Offer 题解](https://github.com/CyC2018/CS-Notes/blob/master/notes/%E5%89%91%E6%8C%87%20Offer%20%E9%A2%98%E8%A7%A3%20-%20%E7%9B%AE%E5%BD%95.md) - - - - - - -
diff --git a/docs/notes/攻击技术.md b/docs/notes/攻击技术.md index b8407b56..6ba68f32 100644 --- a/docs/notes/攻击技术.md +++ b/docs/notes/攻击技术.md @@ -1,11 +1,4 @@ - -* [一、跨站脚本攻击](#一跨站脚本攻击) -* [二、跨站请求伪造](#二跨站请求伪造) -* [三、SQL 注入攻击](#三sql-注入攻击) -* [四、拒绝服务攻击](#四拒绝服务攻击) -* [参考资料](#参考资料) - - +[TOC] # 一、跨站脚本攻击 @@ -191,10 +184,3 @@ ResultSet rs = stmt.executeQuery(); - [维基百科:SQL 注入攻击](https://zh.wikipedia.org/wiki/SQL%E8%B3%87%E6%96%99%E9%9A%B1%E7%A2%BC%E6%94%BB%E6%93%8A) - [维基百科:跨站点请求伪造](https://zh.wikipedia.org/wiki/%E8%B7%A8%E7%AB%99%E8%AF%B7%E6%B1%82%E4%BC%AA%E9%80%A0) - [维基百科:拒绝服务攻击](https://zh.wikipedia.org/wiki/%E9%98%BB%E6%96%B7%E6%9C%8D%E5%8B%99%E6%94%BB%E6%93%8A) - - - - - - -
diff --git a/docs/notes/数据库系统原理.md b/docs/notes/数据库系统原理.md index b90f2ba0..b1a572a3 100644 --- a/docs/notes/数据库系统原理.md +++ b/docs/notes/数据库系统原理.md @@ -1,45 +1,4 @@ - -* [一、事务](#一事务) - * [概念](#概念) - * [ACID](#acid) - * [AUTOCOMMIT](#autocommit) -* [二、并发一致性问题](#二并发一致性问题) - * [丢失修改](#丢失修改) - * [读脏数据](#读脏数据) - * [不可重复读](#不可重复读) - * [幻影读](#幻影读) -* [三、封锁](#三封锁) - * [封锁粒度](#封锁粒度) - * [封锁类型](#封锁类型) - * [封锁协议](#封锁协议) - * [MySQL 隐式与显示锁定](#mysql-隐式与显示锁定) -* [四、隔离级别](#四隔离级别) - * [未提交读(READ UNCOMMITTED)](#未提交读read-uncommitted) - * [提交读(READ COMMITTED)](#提交读read-committed) - * [可重复读(REPEATABLE READ)](#可重复读repeatable-read) - * [可串行化(SERIALIZABLE)](#可串行化serializable) -* [五、多版本并发控制](#五多版本并发控制) - * [版本号](#版本号) - * [隐藏的列](#隐藏的列) - * [Undo 日志](#undo-日志) - * [实现过程](#实现过程) - * [快照读与当前读](#快照读与当前读) -* [六、Next-Key Locks](#六next-key-locks) - * [Record Locks](#record-locks) - * [Gap Locks](#gap-locks) - * [Next-Key Locks](#next-key-locks) -* [七、关系数据库设计理论](#七关系数据库设计理论) - * [函数依赖](#函数依赖) - * [异常](#异常) - * [范式](#范式) -* [八、ER 图](#八er-图) - * [实体的三种联系](#实体的三种联系) - * [表示出现多次的关系](#表示出现多次的关系) - * [联系的多向性](#联系的多向性) - * [表示子类](#表示子类) -* [参考资料](#参考资料) - - +[TOC] # 一、事务 @@ -47,7 +6,7 @@ 事务指的是满足 ACID 特性的一组操作,可以通过 Commit 提交一个事务,也可以使用 Rollback 进行回滚。 -

+ ## ACID @@ -80,7 +39,7 @@ - 在并发的情况下,多个事务并行执行,事务不仅要满足原子性,还需要满足隔离性,才能满足一致性。 - 事务满足持久化是为了能应对数据库崩溃的情况。 -

+ ## AUTOCOMMIT @@ -94,25 +53,25 @@ MySQL 默认采用自动提交模式。也就是说,如果不显式使用`STAR T1 和 T2 两个事务都对一个数据进行修改,T1 先修改,T2 随后修改,T2 的修改覆盖了 T1 的修改。 -

+ ## 读脏数据 T1 修改一个数据,T2 随后读取这个数据。如果 T1 撤销了这次修改,那么 T2 读取的数据是脏数据。 -

+ ## 不可重复读 T2 读取一个数据,T1 对该数据做了修改。如果 T2 再次读取这个数据,此时读取的结果和第一次读取的结果不同。 -

+ ## 幻影读 T1 读取某个范围的数据,T2 在这个范围内插入新的数据,T1 再次读取这个范围的数据,此时读取的结果和和第一次读取的结果不同。 -

+ ---- @@ -322,7 +281,7 @@ MVCC 在每行记录后面都保存着两个隐藏的列,用来存储两个版 MVCC 使用到的快照存储在 Undo 日志中,该日志通过回滚指针把一个数据行(Record)的所有快照连接起来。 -

+ ## 实现过程 @@ -536,7 +495,7 @@ Entity-Relationship,有三个组成部分:实体、属性、联系。 下图的 Course 和 Student 是一对多的关系。 -

+ ## 表示出现多次的关系 @@ -544,19 +503,19 @@ Entity-Relationship,有三个组成部分:实体、属性、联系。 下图表示一个课程的先修关系,先修关系出现两个 Course 实体,第一个是先修课程,后一个是后修课程,因此需要用两条线来表示这种关系。 -

+ ## 联系的多向性 虽然老师可以开设多门课,并且可以教授多名学生,但是对于特定的学生和课程,只有一个老师教授,这就构成了一个三元联系。 -

+ ## 表示子类 用一个三角形和两条线来连接类和子类,与子类有关的属性和联系都连到子类上,而与父类和子类都有关的连到父类上。 -

+ # 参考资料 @@ -572,10 +531,3 @@ Entity-Relationship,有三个组成部分:实体、属性、联系。 - [MySQL locking for the busy web developer](https://www.brightbox.com/blog/2013/10/31/on-mysql-locks/) - [浅入浅出 MySQL 和 InnoDB](https://draveness.me/mysql-innodb) - [Innodb 中的事务隔离级别和锁的关系](https://tech.meituan.com/2014/08/20/innodb-lock.html) - - - - - - -
diff --git a/docs/notes/构建工具.md b/docs/notes/构建工具.md index a5a6c5ce..a22592d9 100644 --- a/docs/notes/构建工具.md +++ b/docs/notes/构建工具.md @@ -1,10 +1,4 @@ - -* [一、构建工具的作用](#一构建工具的作用) -* [二、Java 主流构建工具](#二java-主流构建工具) -* [三、Maven](#三maven) -* [参考资料](#参考资料) - - +[TOC] # 一、构建工具的作用 @@ -35,7 +29,7 @@ Ant 具有编译、测试和打包功能,其后出现的 Maven 在 Ant 的功能基础上又新增了依赖管理功能,而最新的 Gradle 又在 Maven 的功能基础上新增了对 Groovy 语言的支持。 -

+ Gradle 和 Maven 的区别是,它使用 Groovy 这种特定领域语言(DSL)来管理构建脚本,而不再使用 XML 这种标记性语言。因为项目如果庞大的话,XML 很容易就变得臃肿。 @@ -139,10 +133,3 @@ A -> C -> X(2.0) - [maven 2 gradle](http://sagioto.github.io/maven2gradle/) - [新一代构建工具 gradle](https://www.imooc.com/learn/833) - - - - - - -
diff --git a/docs/notes/正则表达式.md b/docs/notes/正则表达式.md index 4df6c4b5..b44f02e4 100644 --- a/docs/notes/正则表达式.md +++ b/docs/notes/正则表达式.md @@ -1,17 +1,4 @@ - -* [一、概述](#一概述) -* [二、匹配单个字符](#二匹配单个字符) -* [三、匹配一组字符](#三匹配一组字符) -* [四、使用元字符](#四使用元字符) -* [五、重复匹配](#五重复匹配) -* [六、位置匹配](#六位置匹配) -* [七、使用子表达式](#七使用子表达式) -* [八、回溯引用](#八回溯引用) -* [九、前后查找](#九前后查找) -* [十、嵌入条件](#十嵌入条件) -* [参考资料](#参考资料) - - +[TOC] # 一、概述 @@ -173,7 +160,7 @@ a.+c ^\s*\/\/.*$ ``` -

+![](pics/600e9c75-5033-4dad-ae2b-930957db638e.png) **匹配结果** @@ -388,10 +375,3 @@ aBCd # 参考资料 - BenForta. 正则表达式必知必会 [M]. 人民邮电出版社, 2007. - - - - - - -
diff --git a/docs/notes/消息队列.md b/docs/notes/消息队列.md index fc628807..c6b34b73 100644 --- a/docs/notes/消息队列.md +++ b/docs/notes/消息队列.md @@ -1,17 +1,4 @@ - -* [一、消息模型](#一消息模型) - * [点对点](#点对点) - * [发布/订阅](#发布订阅) -* [二、使用场景](#二使用场景) - * [异步处理](#异步处理) - * [流量削锋](#流量削锋) - * [应用解耦](#应用解耦) -* [三、可靠性](#三可靠性) - * [发送端的可靠性](#发送端的可靠性) - * [接收端的可靠性](#接收端的可靠性) -* [参考资料](#参考资料) - - +[TOC] # 一、消息模型 @@ -19,20 +6,20 @@ 消息生产者向消息队列中发送了一个消息之后,只能被一个消费者消费一次。 -

+ ## 发布/订阅 消息生产者向频道发送一个消息之后,多个消费者可以从该频道订阅到这条消息并消费。 -

+ 发布与订阅模式和观察者模式有以下不同: - 观察者模式中,观察者和主题都知道对方的存在;而在发布与订阅模式中,生产者与消费者不知道对方的存在,它们之间通过频道进行通信。 - 观察者模式是同步的,当事件触发时,主题会调用观察者的方法,然后等待方法返回;而发布与订阅模式是异步的,生产者向频道发送一个消息之后,就不需要关心消费者何时去订阅这个消息,可以立即返回。 -

+ # 二、使用场景 @@ -77,10 +64,3 @@ - [Observer vs Pub-Sub](http://developers-club.com/posts/270339/) - [消息队列中点对点与发布订阅区别](https://blog.csdn.net/lizhitao/article/details/47723105) - - - - - - -
diff --git a/docs/notes/算法 - 其它.md b/docs/notes/算法 - 其它.md index 748e44c5..5d057683 100644 --- a/docs/notes/算法 - 其它.md +++ b/docs/notes/算法 - 其它.md @@ -1,12 +1,6 @@ - -* [汉诺塔](#汉诺塔) -* [哈夫曼编码](#哈夫曼编码) - - - # 汉诺塔 -

+ 有三个柱子,分别为 from、buffer、to。需要将 from 上的圆盘全部移动到 to 上,并且要保证小圆盘始终在大圆盘上。 @@ -14,15 +8,15 @@ ① 将 n-1 个圆盘从 from -> buffer -

+ ② 将 1 个圆盘从 from -> to -

+ ③ 将 n-1 个圆盘从 buffer -> to -

+ 如果只有一个圆盘,那么只需要进行一次移动操作。 @@ -73,7 +67,7 @@ from H1 to H3 生成编码时,从根节点出发,向左遍历则添加二进制位 0,向右则添加二进制位 1,直到遍历到叶子节点,叶子节点代表的字符的编码就是这个路径编码。 -

+ ```java public class Huffman { @@ -132,10 +126,3 @@ public class Huffman { } } ``` - - - - - - -
diff --git a/docs/notes/算法 - 并查集.md b/docs/notes/算法 - 并查集.md index 22e40b21..d0918e0e 100644 --- a/docs/notes/算法 - 并查集.md +++ b/docs/notes/算法 - 并查集.md @@ -1,18 +1,10 @@ - -* [前言](#前言) -* [Quick Find](#quick-find) -* [Quick Union](#quick-union) -* [加权 Quick Union](#加权-quick-union) -* [路径压缩的加权 Quick Union](#路径压缩的加权-quick-union) -* [比较](#比较) - - +[TOC] # 前言 用于解决动态连通性问题,能动态连接两个点,并且判断两个点是否连通。 -

+ | 方法 | 描述 | | :---: | :---: | @@ -51,7 +43,7 @@ public abstract class UF { 但是 union 操作代价却很高,需要将其中一个连通分量中的所有节点 id 值都修改为另一个节点的 id 值。 -

+ ```java public class QuickFindUF extends UF { @@ -91,7 +83,7 @@ public class QuickFindUF extends UF { 但是 find 操作开销很大,因为同一个连通分量的节点 id 值不同,id 值只是用来指向另一个节点。因此需要一直向上查找操作,直到找到最上层的节点。 -

+ ```java public class QuickUnionUF extends UF { @@ -124,7 +116,7 @@ public class QuickUnionUF extends UF { 这种方法可以快速进行 union 操作,但是 find 操作和树高成正比,最坏的情况下树的高度为节点的数目。 -

+ # 加权 Quick Union @@ -132,7 +124,7 @@ public class QuickUnionUF extends UF { 理论研究证明,加权 quick-union 算法构造的树深度最多不超过 logN。 -

+ ```java public class WeightedQuickUnionUF extends UF { @@ -190,10 +182,3 @@ public class WeightedQuickUnionUF extends UF { | Quick Union | 树高 | 树高 | | 加权 Quick Union | logN | logN | | 路径压缩的加权 Quick Union | 非常接近 1 | 非常接近 1 | - - - - - - -
diff --git a/docs/notes/算法 - 排序.md b/docs/notes/算法 - 排序.md index a3b88963..51697fea 100644 --- a/docs/notes/算法 - 排序.md +++ b/docs/notes/算法 - 排序.md @@ -1,32 +1,3 @@ - -* [约定](#约定) -* [选择排序](#选择排序) -* [冒泡排序](#冒泡排序) -* [插入排序](#插入排序) -* [希尔排序](#希尔排序) -* [归并排序](#归并排序) - * [1. 归并方法](#1-归并方法) - * [2. 自顶向下归并排序](#2-自顶向下归并排序) - * [3. 自底向上归并排序](#3-自底向上归并排序) -* [快速排序](#快速排序) - * [1. 基本算法](#1-基本算法) - * [2. 切分](#2-切分) - * [3. 性能分析](#3-性能分析) - * [4. 算法改进](#4-算法改进) - * [5. 基于切分的快速选择算法](#5-基于切分的快速选择算法) -* [堆排序](#堆排序) - * [1. 堆](#1-堆) - * [2. 上浮和下沉](#2-上浮和下沉) - * [3. 插入元素](#3-插入元素) - * [4. 删除最大元素](#4-删除最大元素) - * [5. 堆排序](#5-堆排序) - * [6. 分析](#6-分析) -* [小结](#小结) - * [1. 排序算法的比较](#1-排序算法的比较) - * [2. Java 的排序算法实现](#2-java-的排序算法实现) - - - # 约定 待排序的元素需要实现 Java 的 Comparable 接口,该接口有 compareTo() 方法,可以用它来判断两个元素的大小关系。 @@ -58,7 +29,7 @@ public abstract class Sort> { 选择排序需要 \~N2/2 次比较和 \~N 次交换,它的运行时间与输入无关,这个特点使得它对一个已经排序的数组也需要这么多的比较和交换操作。 -

+ ```java public class Selection> extends Sort { @@ -85,7 +56,7 @@ public class Selection> extends Sort { 在一轮循环中,如果没有发生交换,那么说明数组已经是有序的,此时可以直接退出。 -

+ ```java public class Bubble> extends Sort { @@ -119,7 +90,7 @@ public class Bubble> extends Sort { - 最坏的情况下需要 \~N2/2 比较以及 \~N2/2 次交换,最坏的情况是数组是倒序的; - 最好的情况下需要 N-1 次比较和 0 次交换,最好的情况就是数组已经有序了。 -

+ ```java public class Insertion> extends Sort { @@ -142,7 +113,7 @@ public class Insertion> extends Sort { 希尔排序使用插入排序对间隔 h 的序列进行排序。通过不断减小 h,最后令 h=1,就可以使得整个数组是有序的。 -

+ ```java public class Shell> extends Sort { @@ -176,7 +147,7 @@ public class Shell> extends Sort { 归并排序的思想是将数组分成两部分,分别进行排序,然后归并起来。 -

+ ## 1. 归并方法 @@ -272,7 +243,7 @@ public class Down2UpMergeSort> extends MergeSort { - 归并排序将数组分为两个子数组分别排序,并将有序的子数组归并使得整个数组排序; - 快速排序通过一个切分元素将数组分为两个子数组,左子数组小于等于切分元素,右子数组大于等于切分元素,将这两个子数组排序也就将整个数组排序了。 -

+ ```java public class QuickSort> extends Sort { @@ -303,7 +274,7 @@ public class QuickSort> extends Sort { 取 a[l] 作为切分元素,然后从数组的左端向右扫描直到找到第一个大于等于它的元素,再从数组的右端向左扫描找到第一个小于它的元素,交换这两个元素。不断进行这个过程,就可以保证左指针 i 的左侧元素都不大于切分元素,右指针 j 的右侧元素都不小于切分元素。当两个指针相遇时,将切分元素 a[l] 和 a[j] 交换位置。 -

+ ```java private int partition(T[] nums, int l, int h) { @@ -407,7 +378,7 @@ public T select(T[] nums, int k) { 堆可以用数组来表示,这是因为堆是完全二叉树,而完全二叉树很容易就存储在数组中。位置 k 的节点的父节点位置为 k/2,而它的两个子节点的位置分别为 2k 和 2k+1。这里不使用数组索引为 0 的位置,是为了更清晰地描述节点的位置关系。 -

+ ```java public class Heap> { @@ -443,7 +414,7 @@ public class Heap> { 在堆中,当一个节点比父节点大,那么需要交换这个两个节点。交换后还可能比它新的父节点大,因此需要不断地进行比较和交换操作,把这种操作称为上浮。 -

+ ```java private void swim(int k) { @@ -456,7 +427,7 @@ private void swim(int k) { 类似地,当一个节点比子节点来得小,也需要不断地向下进行比较和交换操作,把这种操作称为下沉。一个节点如果有两个子节点,应当与两个子节点中最大那个节点进行交换。 -

+ ```java private void sink(int k) { @@ -505,13 +476,13 @@ public T delMax() { 无序数组建立堆最直接的方法是从左到右遍历数组进行上浮操作。一个更高效的方法是从右至左进行下沉操作,如果一个节点的两个节点都已经是堆有序,那么进行下沉操作可以使得这个节点为根节点的堆有序。叶子节点不需要进行下沉操作,可以忽略叶子节点的元素,因此只需要遍历一半的元素即可。 -

+ #### 5.2 交换堆顶元素与最后一个元素 交换之后需要进行下沉操作维持堆的有序状态。 -

+ ```java public class HeapSort> extends Sort { @@ -580,10 +551,3 @@ public class HeapSort> extends Sort { ## 2. Java 的排序算法实现 Java 主要排序方法为 java.util.Arrays.sort(),对于原始数据类型使用三向切分的快速排序,对于引用类型使用归并排序。 - - - - - - -
diff --git a/docs/notes/算法 - 栈和队列.md b/docs/notes/算法 - 栈和队列.md index 36b21586..8d58c346 100644 --- a/docs/notes/算法 - 栈和队列.md +++ b/docs/notes/算法 - 栈和队列.md @@ -1,10 +1,4 @@ - -* [栈](#栈) - * [1. 数组实现](#1-数组实现) - * [2. 链表实现](#2-链表实现) -* [队列](#队列) - - +[TOC] # 栈 @@ -316,10 +310,3 @@ public class ListQueue implements MyQueue { } } ``` - - - - - - -
diff --git a/docs/notes/算法 - 目录.md b/docs/notes/算法 - 目录.md index 9605ed05..2f66d5b3 100644 --- a/docs/notes/算法 - 目录.md +++ b/docs/notes/算法 - 目录.md @@ -1,5 +1,3 @@ - - # 目录 - [算法分析](算法%20-%20算法分析.md) @@ -12,10 +10,3 @@ # 参考资料 - Sedgewick, Robert, and Kevin Wayne. _Algorithms_. Addison-Wesley Professional, 2011. - - - - - - -
diff --git a/docs/notes/算法 - 目录1.md b/docs/notes/算法 - 目录1.md index 4d590961..aa982d16 100644 --- a/docs/notes/算法 - 目录1.md +++ b/docs/notes/算法 - 目录1.md @@ -1,5 +1,3 @@ - - # 目录 - [算法分析](notes/算法%20-%20算法分析.md) @@ -12,10 +10,3 @@ # 参考资料 - Sedgewick, Robert, and Kevin Wayne. _Algorithms_. Addison-Wesley Professional, 2011. - - - - - - -
diff --git a/docs/notes/算法 - 符号表.md b/docs/notes/算法 - 符号表.md index 3ab00a6b..cf77b103 100644 --- a/docs/notes/算法 - 符号表.md +++ b/docs/notes/算法 - 符号表.md @@ -1,38 +1,4 @@ - -* [前言](#前言) -* [初级实现](#初级实现) - * [1. 链表实现无序符号表](#1-链表实现无序符号表) - * [2. 二分查找实现有序符号表](#2-二分查找实现有序符号表) -* [二叉查找树](#二叉查找树) - * [1. get()](#1-get) - * [2. put()](#2-put) - * [3. 分析](#3-分析) - * [4. floor()](#4-floor) - * [5. rank()](#5-rank) - * [6. min()](#6-min) - * [7. deleteMin()](#7-deletemin) - * [8. delete()](#8-delete) - * [9. keys()](#9-keys) - * [10. 分析](#10-分析) -* [2-3 查找树](#2-3-查找树) - * [1. 插入操作](#1-插入操作) - * [2. 性质](#2-性质) -* [红黑树](#红黑树) - * [1. 左旋转](#1-左旋转) - * [2. 右旋转](#2-右旋转) - * [3. 颜色转换](#3-颜色转换) - * [4. 插入](#4-插入) - * [5. 分析](#5-分析) -* [散列表](#散列表) - * [1. 散列函数](#1-散列函数) - * [2. 拉链法](#2-拉链法) - * [3. 线性探测法](#3-线性探测法) -* [小结](#小结) - * [1. 符号表算法比较](#1-符号表算法比较) - * [2. Java 的符号表实现](#2-java-的符号表实现) - * [3. 稀疏向量乘法](#3-稀疏向量乘法) - - +[TOC] # 前言 @@ -245,13 +211,13 @@ public class BinarySearchOrderedST, Value> implement **二叉树** 是一个空链接,或者是一个有左右两个链接的节点,每个链接都指向一颗子二叉树。 -

+ **二叉查找树** (BST)是一颗二叉树,并且每个节点的值都大于等于其左子树中的所有节点的值而小于等于右子树的所有节点的值。 BST 有一个重要性质,就是它的中序遍历结果递增排序。 -

+ 基本数据结构: @@ -325,7 +291,7 @@ private Value get(Node x, Key key) { 当插入的键不存在于树中,需要创建一个新节点,并且更新上层节点的链接指向该节点,使得该节点正确地链接到树中。 -

+ ```java @Override @@ -354,11 +320,11 @@ private Node put(Node x, Key key, Value value) { 最好的情况下树是完全平衡的,每条空链接和根节点的距离都为 logN。 -

+ 在最坏的情况下,树的高度为 N。 -

+ ## 4. floor() @@ -436,7 +402,7 @@ private Node min(Node x) { 令指向最小节点的链接指向最小节点的右子树。 -

+ ```java public void deleteMin() { @@ -457,7 +423,7 @@ public Node deleteMin(Node x) { - 如果待删除的节点只有一个子树, 那么只需要让指向待删除节点的链接指向唯一的子树即可; - 否则,让右子树的最小节点替换该节点。 -

+ ```java public void delete(Key key) { @@ -520,7 +486,7 @@ private List keys(Node x, Key l, Key h) { 2-3 查找树引入了 2- 节点和 3- 节点,目的是为了让树平衡。一颗完美平衡的 2-3 查找树的所有空链接到根节点的距离应该是相同的。 -

+ ## 1. 插入操作 @@ -530,11 +496,11 @@ private List keys(Node x, Key l, Key h) { - 如果插入到 2- 节点上,那么直接将新节点和原来的节点组成 3- 节点即可。 -

+ - 如果是插入到 3- 节点上,就会产生一个临时 4- 节点时,需要将 4- 节点分裂成 3 个 2- 节点,并将中间的 2- 节点移到上层节点中。如果上移操作继续产生临时 4- 节点则一直进行分裂上移,直到不存在临时 4- 节点。 -

+ ## 2. 性质 @@ -546,7 +512,7 @@ private List keys(Node x, Key l, Key h) { 红黑树是 2-3 查找树,但它不需要分别定义 2- 节点和 3- 节点,而是在普通的二叉查找树之上,为节点添加颜色。指向一个节点的链接颜色如果为红色,那么这个节点和上层节点表示的是一个 3- 节点,而黑色则是普通链接。 -

+ 红黑树具有以下性质: @@ -555,7 +521,7 @@ private List keys(Node x, Key l, Key h) { 画红黑树时可以将红链接画平。 -

+ ```java public class RedBlackBST, Value> extends BST { @@ -575,7 +541,7 @@ public class RedBlackBST, Value> extends BST
+ ```java public Node rotateLeft(Node h) { @@ -594,7 +560,7 @@ public Node rotateLeft(Node h) { 进行右旋转是为了转换两个连续的左红链接,这会在之后的插入过程中探讨。 -

+ ```java public Node rotateRight(Node h) { @@ -613,7 +579,7 @@ public Node rotateRight(Node h) { 一个 4- 节点在红黑树中表现为一个节点的左右子节点都是红色的。分裂 4- 节点除了需要将子节点的颜色由红变黑之外,同时需要将父节点的颜色由黑变红,从 2-3 树的角度看就是将中间节点移到上层节点。 -

+ ```java void flipColors(Node h) { @@ -631,7 +597,7 @@ void flipColors(Node h) { - 如果左子节点是红色的,而且左子节点的左子节点也是红色的,进行右旋转; - 如果左右子节点均为红色的,进行颜色转换。 -

+ ```java @Override @@ -756,7 +722,7 @@ public class Transaction { 对于 N 个键,M 条链表 (N>M),如果哈希函数能够满足均匀性的条件,每条链表的大小趋向于 N/M,因此未命中的查找和插入操作所需要的比较次数为 \~N/M。 -

+ ## 3. 线性探测法 @@ -765,7 +731,7 @@ public class Transaction { 使用线性探测法,数组的大小 M 应当大于键的个数 N(M>N)。 -

+ ```java public class LinearProbingHashST implements UnorderedST { @@ -867,7 +833,7 @@ public void delete(Key key) { 线性探测法的成本取决于连续条目的长度,连续条目也叫聚簇。当聚簇很长时,在查找和插入时也需要进行很多次探测。例如下图中 2\~4 位置就是一个聚簇。 -

+ α = N/M,把 α 称为使用率。理论证明,当 α 小于 1/2 时探测的预计次数只在 1.5 到 2.5 之间。为了保证散列表的性能,应当调整数组的大小,使得 α 在 [1/4, 1/2] 之间。 @@ -938,10 +904,3 @@ public class SparseVector { } } ``` - - - - - - -
diff --git a/docs/notes/算法 - 算法分析.md b/docs/notes/算法 - 算法分析.md index 336568ae..74813bb4 100644 --- a/docs/notes/算法 - 算法分析.md +++ b/docs/notes/算法 - 算法分析.md @@ -1,22 +1,4 @@ - -* [数学模型](#数学模型) - * [1. 近似](#1-近似) - * [2. 增长数量级](#2-增长数量级) - * [3. 内循环](#3-内循环) - * [4. 成本模型](#4-成本模型) -* [注意事项](#注意事项) - * [1. 大常数](#1-大常数) - * [2. 缓存](#2-缓存) - * [3. 对最坏情况下的性能的保证](#3-对最坏情况下的性能的保证) - * [4. 随机化算法](#4-随机化算法) - * [5. 均摊分析](#5-均摊分析) -* [ThreeSum](#threesum) - * [1. ThreeSumSlow](#1-threesumslow) - * [2. ThreeSumBinarySearch](#2-threesumbinarysearch) - * [3. ThreeSumTwoPointer](#3-threesumtwopointer) -* [倍率实验](#倍率实验) - - +[TOC] # 数学模型 @@ -234,10 +216,3 @@ public class StopWatch { } } ``` - - - - - - -
diff --git a/docs/notes/算法.md b/docs/notes/算法.md index 72023263..ff8a64d0 100644 --- a/docs/notes/算法.md +++ b/docs/notes/算法.md @@ -1,12 +1 @@ - - - - [算法](https://github.com/CyC2018/CS-Notes/blob/master/notes/%E7%AE%97%E6%B3%95%20-%20%E7%9B%AE%E5%BD%95.md) - - - - - - -
diff --git a/docs/notes/系统设计基础.md b/docs/notes/系统设计基础.md index 815135bf..5caedb10 100644 --- a/docs/notes/系统设计基础.md +++ b/docs/notes/系统设计基础.md @@ -1,12 +1,4 @@ - -* [一、性能](#一性能) -* [二、伸缩性](#二伸缩性) -* [三、扩展性](#三扩展性) -* [四、可用性](#四可用性) -* [五、安全性](#五安全性) -* [参考资料](#参考资料) - - +[TOC] # 一、性能 @@ -107,10 +99,3 @@ # 参考资料 - 大型网站技术架构:核心原理与案例分析 - - - - - - -
diff --git a/docs/notes/缓存.md b/docs/notes/缓存.md index 5a171e72..e98dbbfd 100644 --- a/docs/notes/缓存.md +++ b/docs/notes/缓存.md @@ -1,14 +1,4 @@ - -* [一、缓存特征](#一缓存特征) -* [二、LRU](#二lru) -* [三、缓存位置](#三缓存位置) -* [四、CDN](#四cdn) -* [五、缓存问题](#五缓存问题) -* [六、数据分布](#六数据分布) -* [七、一致性哈希](#七一致性哈希) -* [参考资料](#参考资料) - - +[TOC] # 一、缓存特征 @@ -211,7 +201,7 @@ CDN 主要有以下优点: - 通过部署多台服务器,从而提高系统整体的带宽性能; - 多台服务器可以看成是一种冗余机制,从而具有高可用性。 -

+![](pics/15313ed8-a520-4799-a300-2b6b36be314f.jpg) # 五、缓存问题 @@ -285,11 +275,11 @@ Distributed Hash Table(DHT) 是一种哈希分布方式,其目的是为了 将哈希空间 [0, 2n-1] 看成一个哈希环,每个服务器节点都配置到哈希环上。每个数据对象通过哈希取模得到哈希值之后,存放到哈希环中顺时针方向第一个大于等于该哈希值的节点上。 -

+![](pics/68b110b9-76c6-4ee2-b541-4145e65adb3e.jpg) 一致性哈希在增加或者删除节点时只会影响到哈希环中相邻的节点,例如下图中新增节点 X,只需要将它前一个节点 C 上的数据重新进行分布即可,对于节点 A、B、D 都没有影响。 -

+![](pics/66402828-fb2b-418f-83f6-82153491bcfe.jpg) ## 虚拟节点 @@ -306,10 +296,3 @@ Distributed Hash Table(DHT) 是一种哈希分布方式,其目的是为了 - [一致性哈希算法](https://my.oschina.net/jayhu/blog/732849) - [内容分发网络](https://zh.wikipedia.org/wiki/%E5%85%A7%E5%AE%B9%E5%82%B3%E9%81%9E%E7%B6%B2%E8%B7%AF) - [How Aspiration CDN helps to improve your website loading speed?](https://www.aspirationhosting.com/aspiration-cdn/) - - - - - - -
diff --git a/docs/notes/计算机操作系统 - 内存管理.md b/docs/notes/计算机操作系统 - 内存管理.md index 3aa7bca0..9d988334 100644 --- a/docs/notes/计算机操作系统 - 内存管理.md +++ b/docs/notes/计算机操作系统 - 内存管理.md @@ -1,18 +1,4 @@ - -* [虚拟内存](#虚拟内存) -* [分页系统地址映射](#分页系统地址映射) -* [页面置换算法](#页面置换算法) - * [1. 最佳](#1-最佳) - * [2. 最近最久未使用](#2-最近最久未使用) - * [3. 最近未使用](#3-最近未使用) - * [4. 先进先出](#4-先进先出) - * [5. 第二次机会算法](#5-第二次机会算法) - * [6. 时钟](#6-时钟) -* [分段](#分段) -* [段页式](#段页式) -* [分页与分段的比较](#分页与分段的比较) - - +[TOC] # 虚拟内存 @@ -22,7 +8,7 @@ 从上面的描述中可以看出,虚拟内存允许程序不用将地址空间中的每一页都映射到物理内存,也就是说一个程序不需要全部调入内存就可以运行,这使得有限的内存运行大程序成为可能。例如有一台计算机可以产生 16 位地址,那么一个程序的地址空间范围是 0\~64K。该计算机只有 32KB 的物理内存,虚拟内存技术允许该计算机运行一个 64K 大小的程序。 -

+![](pics/7b281b1e-0595-402b-ae35-8c91084c33c1.png) # 分页系统地址映射 @@ -32,7 +18,7 @@ 下图的页表存放着 16 个页,这 16 个页需要用 4 个比特位来进行索引定位。例如对于虚拟地址(0010 000000000100),前 4 位是存储页面号 2,读取表项内容为(110 1),页表项最后一位表示是否存在于内存中,1 表示存在。后 12 位存储偏移量。这个页对应的页框的地址为 (110 000000000100)。 -

+ # 页面置换算法 @@ -72,8 +58,7 @@ 4,7,0,7,1,0,1,2,1,2,6 ``` -

- +
![](pics/eb859228-c0f2-4bce-910d-d9f76929352b.png)
## 3. 最近未使用 > NRU, Not Recently Used @@ -103,7 +88,7 @@ FIFO 算法可能会把经常使用的页面置换出去,为了避免这一问 当页面被访问 (读或写) 时设置该页面的 R 位为 1。需要替换的时候,检查最老页面的 R 位。如果 R 位是 0,那么这个页面既老又没有被使用,可以立刻置换掉;如果是 1,就将 R 位清 0,并把该页面放到链表的尾端,修改它的装入时间使它就像刚装入的一样,然后继续从链表的头部开始搜索。 -

+![](pics/ecf8ad5d-5403-48b9-b6e7-f2e20ffe8fca.png) ## 6. 时钟 @@ -111,7 +96,7 @@ FIFO 算法可能会把经常使用的页面置换出去,为了避免这一问 第二次机会算法需要在链表中移动页面,降低了效率。时钟算法使用环形链表将页面连接起来,再使用一个指针指向最老的页面。 -

+![](pics/5f5ef0b6-98ea-497c-a007-f6c55288eab1.png) # 分段 @@ -119,11 +104,11 @@ FIFO 算法可能会把经常使用的页面置换出去,为了避免这一问 下图为一个编译器在编译过程中建立的多个表,有 4 个表是动态增长的,如果使用分页系统的一维地址空间,动态增长的特点会导致覆盖问题的出现。 -

+![](pics/22de0538-7c6e-4365-bd3b-8ce3c5900216.png) 分段的做法是把每个表分成段,一个段构成一个独立的地址空间。每个段的长度可以不同,并且可以动态增长。 -

+![](pics/e0900bb2-220a-43b7-9aa9-1d5cd55ff56e.png) # 段页式 @@ -138,10 +123,3 @@ FIFO 算法可能会把经常使用的页面置换出去,为了避免这一问 - 大小是否可以改变:页的大小不可变,段的大小可以动态改变。 - 出现的原因:分页主要用于实现虚拟内存,从而获得更大的地址空间;分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护。 - - - - - - -
diff --git a/docs/notes/计算机操作系统 - 概述.md b/docs/notes/计算机操作系统 - 概述.md index 035e15bf..5b58083c 100644 --- a/docs/notes/计算机操作系统 - 概述.md +++ b/docs/notes/计算机操作系统 - 概述.md @@ -1,24 +1,4 @@ - -* [基本特征](#基本特征) - * [1. 并发](#1-并发) - * [2. 共享](#2-共享) - * [3. 虚拟](#3-虚拟) - * [4. 异步](#4-异步) -* [基本功能](#基本功能) - * [1. 进程管理](#1-进程管理) - * [2. 内存管理](#2-内存管理) - * [3. 文件管理](#3-文件管理) - * [4. 设备管理](#4-设备管理) -* [系统调用](#系统调用) -* [大内核和微内核](#大内核和微内核) - * [1. 大内核](#1-大内核) - * [2. 微内核](#2-微内核) -* [中断分类](#中断分类) - * [1. 外中断](#1-外中断) - * [2. 异常](#2-异常) - * [3. 陷入](#3-陷入) - - +[TOC] # 基本特征 @@ -76,7 +56,7 @@ 如果一个进程在用户态需要使用内核态的功能,就进行系统调用从而陷入内核,由操作系统代为完成。 -

+ Linux 的系统调用主要有以下这些: @@ -105,7 +85,7 @@ Linux 的系统调用主要有以下这些: 因为需要频繁地在用户态和核心态之间进行切换,所以会有一定的性能损失。 -

+![](pics/2_14_microkernelArchitecture.jpg) # 中断分类 @@ -120,10 +100,3 @@ Linux 的系统调用主要有以下这些: ## 3. 陷入 在用户程序中使用系统调用。 - - - - - - -
diff --git a/docs/notes/计算机操作系统 - 死锁.md b/docs/notes/计算机操作系统 - 死锁.md index be20dd80..370fc4a0 100644 --- a/docs/notes/计算机操作系统 - 死锁.md +++ b/docs/notes/计算机操作系统 - 死锁.md @@ -1,26 +1,8 @@ - -* [必要条件](#必要条件) -* [处理方法](#处理方法) -* [鸵鸟策略](#鸵鸟策略) -* [死锁检测与死锁恢复](#死锁检测与死锁恢复) - * [1. 每种类型一个资源的死锁检测](#1-每种类型一个资源的死锁检测) - * [2. 每种类型多个资源的死锁检测](#2-每种类型多个资源的死锁检测) - * [3. 死锁恢复](#3-死锁恢复) -* [死锁预防](#死锁预防) - * [1. 破坏互斥条件](#1-破坏互斥条件) - * [2. 破坏占有和等待条件](#2-破坏占有和等待条件) - * [3. 破坏不可抢占条件](#3-破坏不可抢占条件) - * [4. 破坏环路等待](#4-破坏环路等待) -* [死锁避免](#死锁避免) - * [1. 安全状态](#1-安全状态) - * [2. 单个资源的银行家算法](#2-单个资源的银行家算法) - * [3. 多个资源的银行家算法](#3-多个资源的银行家算法) - - +[TOC] # 必要条件 -

+![](pics/c037c901-7eae-4e31-a1e4-9d41329e5c3e.png) - 互斥:每个资源要么已经分配给了一个进程,要么就是可用的。 - 占有和等待:已经得到了某个资源的进程可以再请求新的资源。 @@ -52,7 +34,7 @@ ## 1. 每种类型一个资源的死锁检测 -

+![](pics/b1fa0453-a4b0-4eae-a352-48acca8fff74.png) 上图为资源分配图,其中方框表示资源,圆圈表示进程。资源指向进程表示该资源已经分配给该进程,进程指向资源表示进程请求获取该资源。 @@ -62,7 +44,7 @@ ## 2. 每种类型多个资源的死锁检测 -

+![](pics/e1eda3d5-5ec8-4708-8e25-1a04c5e11f48.png) 上图中,有三个进程四个资源,每个数据代表的含义如下: @@ -111,7 +93,7 @@ ## 1. 安全状态 -

+![](pics/ed523051-608f-4c3f-b343-383e2d194470.png) 图 a 的第二列 Has 表示已拥有的资源数,第三列 Max 表示总共需要的资源数,Free 表示还有可以使用的资源数。从图 a 开始出发,先让 B 拥有所需的所有资源(图 b),运行结束后释放 B,此时 Free 变为 5(图 c);接着以同样的方式运行 C 和 A,使得所有进程都能成功运行,因此可以称图 a 所示的状态时安全的。 @@ -123,13 +105,13 @@ 一个小城镇的银行家,他向一群客户分别承诺了一定的贷款额度,算法要做的是判断对请求的满足是否会进入不安全状态,如果是,就拒绝请求;否则予以分配。 -

+![](pics/d160ec2e-cfe2-4640-bda7-62f53e58b8c0.png) 上图 c 为不安全状态,因此算法会拒绝之前的请求,从而避免进入图 c 中的状态。 ## 3. 多个资源的银行家算法 -

+![](pics/62e0dd4f-44c3-43ee-bb6e-fedb9e068519.png) 上图中有五个进程,四个资源。左边的图表示已经分配的资源,右边的图表示还需要分配的资源。最右边的 E、P 以及 A 分别表示:总资源、已分配资源以及可用资源,注意这三个为向量,而不是具体数值,例如 A=(1020),表示 4 个资源分别还剩下 1/0/2/0。 @@ -140,10 +122,3 @@ - 重复以上两步,直到所有进程都标记为终止,则状态时安全的。 如果一个状态不是安全的,需要拒绝进入这个状态。 - - - - - - -
diff --git a/docs/notes/计算机操作系统 - 目录.md b/docs/notes/计算机操作系统 - 目录.md index 57f42022..c7d161fc 100644 --- a/docs/notes/计算机操作系统 - 目录.md +++ b/docs/notes/计算机操作系统 - 目录.md @@ -1,5 +1,3 @@ - - # 目录 - [概述](计算机操作系统%20-%20概述.md) @@ -20,10 +18,3 @@ - [Processes](http://cse.csusb.edu/tongyu/courses/cs460/notes/process.php) - [Inter Process Communication Presentation[1]](https://www.slideshare.net/rkolahalam/inter-process-communication-presentation1) - [Decoding UCS Invicta – Part 1](https://blogs.cisco.com/datacenter/decoding-ucs-invicta-part-1) - - - - - - -
diff --git a/docs/notes/计算机操作系统 - 目录1.md b/docs/notes/计算机操作系统 - 目录1.md index 492b4d63..e4895e72 100644 --- a/docs/notes/计算机操作系统 - 目录1.md +++ b/docs/notes/计算机操作系统 - 目录1.md @@ -1,5 +1,3 @@ - - # 目录 - [概述](notes/计算机操作系统%20-%20概述.md) @@ -20,10 +18,3 @@ - [Processes](http://cse.csusb.edu/tongyu/courses/cs460/notes/process.php) - [Inter Process Communication Presentation[1]](https://www.slideshare.net/rkolahalam/inter-process-communication-presentation1) - [Decoding UCS Invicta – Part 1](https://blogs.cisco.com/datacenter/decoding-ucs-invicta-part-1) - - - - - - -
diff --git a/docs/notes/计算机操作系统 - 设备管理.md b/docs/notes/计算机操作系统 - 设备管理.md index 535c5e01..e1abf3ed 100644 --- a/docs/notes/计算机操作系统 - 设备管理.md +++ b/docs/notes/计算机操作系统 - 设备管理.md @@ -1,11 +1,4 @@ - -* [磁盘结构](#磁盘结构) -* [磁盘调度算法](#磁盘调度算法) - * [1. 先来先服务](#1-先来先服务) - * [2. 最短寻道时间优先](#2-最短寻道时间优先) - * [3. 电梯算法](#3-电梯算法) - - +[TOC] # 磁盘结构 @@ -16,7 +9,7 @@ - 制动手臂(Actuator arm):用于在磁道之间移动磁头; - 主轴(Spindle):使整个盘面转动。 -

+![](pics/014fbc4d-d873-4a12-b160-867ddaed9807.jpg) # 磁盘调度算法 @@ -44,7 +37,7 @@ 虽然平均寻道时间比较低,但是不够公平。如果新到达的磁道请求总是比一个在等待的磁道请求近,那么在等待的磁道请求会一直等待下去,也就是出现饥饿现象。具体来说,两端的磁道请求更容易出现饥饿现象。 -

+![](pics/4e2485e4-34bd-4967-9f02-0c093b797aaa.png) ## 3. 电梯算法 @@ -56,11 +49,4 @@ 因为考虑了移动方向,因此所有的磁盘请求都会被满足,解决了 SSTF 的饥饿问题。 -

- - - - - - -
+![](pics/271ce08f-c124-475f-b490-be44fedc6d2e.png) diff --git a/docs/notes/计算机操作系统 - 进程管理.md b/docs/notes/计算机操作系统 - 进程管理.md index b2592ddb..6991951c 100644 --- a/docs/notes/计算机操作系统 - 进程管理.md +++ b/docs/notes/计算机操作系统 - 进程管理.md @@ -1,30 +1,4 @@ - -* [进程与线程](#进程与线程) - * [1. 进程](#1-进程) - * [2. 线程](#2-线程) - * [3. 区别](#3-区别) -* [进程状态的切换](#进程状态的切换) -* [进程调度算法](#进程调度算法) - * [1. 批处理系统](#1-批处理系统) - * [2. 交互式系统](#2-交互式系统) - * [3. 实时系统](#3-实时系统) -* [进程同步](#进程同步) - * [1. 临界区](#1-临界区) - * [2. 同步与互斥](#2-同步与互斥) - * [3. 信号量](#3-信号量) - * [4. 管程](#4-管程) -* [经典同步问题](#经典同步问题) - * [1. 读者-写者问题](#1-读者-写者问题) - * [2. 哲学家进餐问题](#2-哲学家进餐问题) -* [进程通信](#进程通信) - * [1. 管道](#1-管道) - * [2. FIFO](#2-fifo) - * [3. 消息队列](#3-消息队列) - * [4. 信号量](#4-信号量) - * [5. 共享存储](#5-共享存储) - * [6. 套接字](#6-套接字) - - +[TOC] # 进程与线程 @@ -36,7 +10,7 @@ 下图显示了 4 个程序创建了 4 个进程,这 4 个进程可以并发地执行。 -

+![](pics/a6ac2b08-3861-4e85-baa8-382287bfee9f.png) ## 2. 线程 @@ -46,7 +20,7 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 HTTP 请求线程、事件响应线程、渲染线程等等,线程的并发执行使得在浏览器中点击一个新链接从而发起 HTTP 请求时,浏览器还可以响应用户的其它事件。 -

+![](pics/3cd630ea-017c-488d-ad1d-732b4efeddf5.png) ## 3. 区别 @@ -68,7 +42,7 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H # 进程状态的切换 -

+ - 就绪状态(ready):等待被调度 - 运行状态(running) @@ -116,7 +90,7 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H - 因为进程切换都要保存进程的信息并且载入新进程的信息,如果时间片太小,会导致进程切换得太频繁,在进程切换上就会花过多时间。 - 而如果时间片过长,那么实时性就不能得到保证。 -

+![](pics/8c662999-c16c-481c-9f40-1fdba5bc9167.png) **2.2 优先级调度** @@ -134,7 +108,7 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H 可以将这种调度算法看成是时间片轮转调度算法和优先级调度算法的结合。 -

+![](pics/042cf928-3c8e-4815-ae9c-f2780202c68f.png) ## 3. 实时系统 @@ -453,7 +427,7 @@ void reader() ## 2. 哲学家进餐问题 -

+![](pics/a9077f06-7584-4f2b-8c20-3a8e46928820.jpg) 五个哲学家围着一张圆桌,每个哲学家面前放着食物。哲学家的生活有两种交替活动:吃饭以及思考。当一个哲学家吃饭时,需要先拿起自己左右两边的两根筷子,并且一次只能拿起一根筷子。 @@ -547,7 +521,7 @@ int pipe(int fd[2]); - 只支持半双工通信(单向交替传输); - 只能在父子进程或者兄弟进程中使用。 -

+![](pics/53cd9ade-b0a6-4399-b4de-7f1fbd06cdfb.png) ## 2. FIFO @@ -561,7 +535,7 @@ int mkfifoat(int fd, const char *path, mode_t mode); FIFO 常用于客户-服务器应用程序中,FIFO 用作汇聚点,在客户进程和服务器进程之间传递数据。 -

+![](pics/2ac50b81-d92a-4401-b9ec-f2113ecc3076.png) ## 3. 消息队列 @@ -586,10 +560,3 @@ FIFO 常用于客户-服务器应用程序中,FIFO 用作汇聚点,在客户 ## 6. 套接字 与其它通信机制不同的是,它可用于不同机器间的进程通信。 - - - - - - -
diff --git a/docs/notes/计算机操作系统 - 链接.md b/docs/notes/计算机操作系统 - 链接.md index 2f8f9fef..bdfc8ee6 100644 --- a/docs/notes/计算机操作系统 - 链接.md +++ b/docs/notes/计算机操作系统 - 链接.md @@ -1,10 +1,4 @@ - -* [编译系统](#编译系统) -* [静态链接](#静态链接) -* [目标文件](#目标文件) -* [动态链接](#动态链接) - - +[TOC] # 编译系统 @@ -29,7 +23,7 @@ gcc -o hello hello.c 这个过程大致如下: -

+ - 预处理阶段:处理以 # 开头的预处理命令; - 编译阶段:翻译成汇编文件; @@ -43,7 +37,7 @@ gcc -o hello hello.c - 符号解析:每个符号对应于一个函数、一个全局变量或一个静态变量,符号解析的目的是将每个符号引用与一个符号定义关联起来。 - 重定位:链接器通过把每个符号定义与一个内存位置关联起来,然后修改所有对这些符号的引用,使得它们指向这个内存位置。 -

+![](pics/47d98583-8bb0-45cc-812d-47eefa0a4a40.jpg) # 目标文件 @@ -63,11 +57,4 @@ gcc -o hello hello.c - 在给定的文件系统中一个库只有一个文件,所有引用该库的可执行目标文件都共享这个文件,它不会被复制到引用它的可执行文件中; - 在内存中,一个共享库的 .text 节(已编译程序的机器代码)的一个副本可以被不同的正在运行的进程共享。 -

- - - - - - -
+![](pics/76dc7769-1aac-4888-9bea-064f1caa8e77.jpg) diff --git a/docs/notes/计算机操作系统.md b/docs/notes/计算机操作系统.md index 1380db75..c7dcdb10 100644 --- a/docs/notes/计算机操作系统.md +++ b/docs/notes/计算机操作系统.md @@ -1,12 +1 @@ - - - - [计算机操作系统](https://github.com/CyC2018/CS-Notes/blob/master/notes/%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%20-%20%E7%9B%AE%E5%BD%95.md) - - - - - - -
diff --git a/docs/notes/计算机网络 - 传输层.md b/docs/notes/计算机网络 - 传输层.md index 6876871a..1febd298 100644 --- a/docs/notes/计算机网络 - 传输层.md +++ b/docs/notes/计算机网络 - 传输层.md @@ -1,17 +1,4 @@ - -* [UDP 和 TCP 的特点](#udp-和-tcp-的特点) -* [UDP 首部格式](#udp-首部格式) -* [TCP 首部格式](#tcp-首部格式) -* [TCP 的三次握手](#tcp-的三次握手) -* [TCP 的四次挥手](#tcp-的四次挥手) -* [TCP 可靠传输](#tcp-可靠传输) -* [TCP 滑动窗口](#tcp-滑动窗口) -* [TCP 流量控制](#tcp-流量控制) -* [TCP 拥塞控制](#tcp-拥塞控制) - * [1. 慢开始与拥塞避免](#1-慢开始与拥塞避免) - * [2. 快重传与快恢复](#2-快重传与快恢复) - - +[TOC] 网络层只把分组发送到目的主机,但是真正通信的并不是主机而是主机中的进程。传输层提供了进程间的逻辑通信,传输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个传输层实体之间有一条端到端的逻辑通信信道。 @@ -23,13 +10,13 @@ # UDP 首部格式 -

+ 首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的。 # TCP 首部格式 -

+ - **序号** :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。 @@ -47,7 +34,7 @@ # TCP 的三次握手 -

+ 假设 A 为客户端,B 为服务器端。 @@ -69,7 +56,7 @@ # TCP 的四次挥手 -

+ 以下描述不讨论序号和确认号,因为序号和确认号的规则比较简单。并且不讨论 ACK,因为 ACK 在连接建立之后都为 1。 @@ -102,13 +89,11 @@ TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文 一个报文段从发送再到接收到确认所经过的时间称为往返时间 RTT,加权平均往返时间 RTTs 计算如下:

- 其中,0 ≤ a < 1,RTTs 随着 a 的增加更容易受到 RTT 的影响。 超时时间 RTO 应该略大于 RTTs,TCP 使用的超时时间计算如下:

- 其中 RTTd 为偏差的加权平均值。 # TCP 滑动窗口 @@ -119,7 +104,7 @@ TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文 接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。 -

+ # TCP 流量控制 @@ -131,7 +116,7 @@ TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文 如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。 -

+ TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。 @@ -142,7 +127,7 @@ TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、 - 接收方有足够大的接收缓存,因此不会发生流量控制; - 虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。 -

+ ## 1. 慢开始与拥塞避免 @@ -162,11 +147,4 @@ TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、 慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。 -

- - - - - - -
+ diff --git a/docs/notes/计算机网络 - 应用层.md b/docs/notes/计算机网络 - 应用层.md index 1e28cbc2..8e5a638e 100644 --- a/docs/notes/计算机网络 - 应用层.md +++ b/docs/notes/计算机网络 - 应用层.md @@ -1,20 +1,4 @@ - -* [域名系统](#域名系统) -* [文件传送协议](#文件传送协议) -* [动态主机配置协议](#动态主机配置协议) -* [远程登录协议](#远程登录协议) -* [电子邮件协议](#电子邮件协议) - * [1. SMTP](#1-smtp) - * [2. POP3](#2-pop3) - * [3. IMAP](#3-imap) -* [常用端口](#常用端口) -* [Web 页面请求过程](#web-页面请求过程) - * [1. DHCP 配置主机信息](#1-dhcp-配置主机信息) - * [2. ARP 解析 MAC 地址](#2-arp-解析-mac-地址) - * [3. DNS 解析域名](#3-dns-解析域名) - * [4. HTTP 请求页面](#4-http-请求页面) - - +[TOC] # 域名系统 @@ -22,7 +6,7 @@ DNS 是一个分布式数据库,提供了主机名和 IP 地址之间相互转 域名具有层次结构,从上到下依次为:根域名、顶级域名、二级域名。 -

+![](pics/b54eeb16-0b0e-484c-be62-306f57c40d77.jpg) DNS 可以使用 UDP 或者 TCP 进行传输,使用的端口号都为 53。大多数情况下 DNS 使用 UDP 进行传输,这就要求域名解析器和域名服务器都必须自己处理超时和重传从而保证可靠性。在两种情况下会使用 TCP 进行传输: @@ -40,11 +24,11 @@ FTP 使用 TCP 进行连接,它需要两个连接来传送一个文件: - 主动模式:服务器端主动建立数据连接,其中服务器端的端口号为 20,客户端的端口号随机,但是必须大于 1024,因为 0\~1023 是熟知端口号。 -

+![](pics/03f47940-3843-4b51-9e42-5dcaff44858b.jpg) - 被动模式:客户端主动建立数据连接,其中客户端的端口号由客户端自己指定,服务器端的端口号随机。 -

+![](pics/be5c2c61-86d2-4dba-a289-b48ea23219de.jpg) 主动模式要求客户端开放端口号给服务器端,需要去配置客户端的防火墙。被动模式只需要服务器端开放端口号即可,无需客户端配置防火墙。但是被动模式会导致服务器端的安全性减弱,因为开放了过多的端口号。 @@ -61,7 +45,7 @@ DHCP 工作过程如下: 3. 如果客户端选择了某个 DHCP 服务器提供的信息,那么就发送 Request 报文给该 DHCP 服务器。 4. DHCP 服务器发送 Ack 报文,表示客户端此时可以使用提供给它的信息。 -

+![](pics/23219e4c-9fc0-4051-b33a-2bd95bf054ab.jpg) # 远程登录协议 @@ -75,13 +59,13 @@ TELNET 可以适应许多计算机和操作系统的差异,例如不同操作 邮件协议包含发送协议和读取协议,发送协议常用 SMTP,读取协议常用 POP3 和 IMAP。 -

+ ## 1. SMTP SMTP 只能发送 ASCII 码,而互联网邮件扩充 MIME 可以发送二进制文件。MIME 并没有改动或者取代 SMTP,而是增加邮件主体的结构,定义了非 ASCII 码的编码规则。 -

+ ## 2. POP3 @@ -164,10 +148,3 @@ IMAP 协议中客户端和服务器上的邮件保持同步,如果不手动删 - HTTP 服务器从 TCP 套接字读取 HTTP GET 报文,生成一个 HTTP 响应报文,将 Web 页面内容放入报文主体中,发回给主机。 - 浏览器收到 HTTP 响应报文后,抽取出 Web 页面内容,之后进行渲染,显示 Web 页面。 - - - - - - -
diff --git a/docs/notes/计算机网络 - 概述.md b/docs/notes/计算机网络 - 概述.md index 8634a766..1b6338a3 100644 --- a/docs/notes/计算机网络 - 概述.md +++ b/docs/notes/计算机网络 - 概述.md @@ -1,48 +1,30 @@ - -* [网络的网络](#网络的网络) -* [ISP](#isp) -* [主机之间的通信方式](#主机之间的通信方式) -* [电路交换与分组交换](#电路交换与分组交换) - * [1. 电路交换](#1-电路交换) - * [2. 分组交换](#2-分组交换) -* [时延](#时延) - * [1. 排队时延](#1-排队时延) - * [2. 处理时延](#2-处理时延) - * [3. 传输时延](#3-传输时延) - * [4. 传播时延](#4-传播时延) -* [计算机网络体系结构](#计算机网络体系结构) - * [1. 五层协议](#1-五层协议) - * [2. OSI](#2-osi) - * [3. TCP/IP](#3-tcpip) - * [4. 数据在各层之间的传递过程](#4-数据在各层之间的传递过程) - - +[TOC] # 网络的网络 网络把主机连接起来,而互联网是把多种不同的网络连接起来,因此互联网是网络的网络。 -

+ # ISP 互联网服务提供商 ISP 可以从互联网管理机构获得许多 IP 地址,同时拥有通信线路以及路由器等联网设备,个人或机构向 ISP 缴纳一定的费用就可以接入互联网。 -

+ 目前的互联网是一种多层次 ISP 结构,ISP 根据覆盖面积的大小分为第一层 ISP、区域 ISP 和接入 ISP。互联网交换点 IXP 允许两个 ISP 直接相连而不用经过第三个 ISP。 -

+ # 主机之间的通信方式 - 客户-服务器(C/S):客户是服务的请求方,服务器是服务的提供方。 -

+ - 对等(P2P):不区分客户和服务器。 -

+ # 电路交换与分组交换 @@ -60,7 +42,7 @@ 总时延 = 排队时延 + 处理时延 + 传输时延 + 传播时延 -

+ ## 1. 排队时延 @@ -76,7 +58,7 @@ -

+ 其中 l 表示数据帧的长度,v 表示传输速率。 @@ -87,13 +69,13 @@ -

+ 其中 l 表示信道长度,v 表示电磁波在信道上的传播速度。 # 计算机网络体系结构 -

+ ## 1. 五层协议 @@ -123,17 +105,10 @@ TCP/IP 体系结构不严格遵循 OSI 分层概念,应用层可能会直接使用 IP 层或者网络接口层。 -

+ ## 4. 数据在各层之间的传递过程 在向下的过程中,需要添加下层协议所需要的首部或者尾部,而在向上的过程中不断拆开首部和尾部。 路由器只有下面三层协议,因为路由器位于网络核心中,不需要为进程或者应用程序提供服务,因此也就不需要传输层和应用层。 - - - - - - -
diff --git a/docs/notes/计算机网络 - 物理层.md b/docs/notes/计算机网络 - 物理层.md index d312e310..c2bd4b90 100644 --- a/docs/notes/计算机网络 - 物理层.md +++ b/docs/notes/计算机网络 - 物理层.md @@ -1,8 +1,4 @@ - -* [通信方式](#通信方式) -* [带通调制](#带通调制) - - +[TOC] # 通信方式 @@ -16,12 +12,5 @@ 模拟信号是连续的信号,数字信号是离散的信号。带通调制把数字信号转换为模拟信号。 -

+ - - - - - - -
diff --git a/docs/notes/计算机网络 - 目录.md b/docs/notes/计算机网络 - 目录.md index a73176c2..ffb1f218 100644 --- a/docs/notes/计算机网络 - 目录.md +++ b/docs/notes/计算机网络 - 目录.md @@ -1,5 +1,3 @@ - - # 目录 - [概述](计算机网络%20-%20概述.md) @@ -26,10 +24,3 @@ - [Technology-Computer Networking[1]-Computer Networks and the Internet](http://www.linyibin.cn/2017/02/12/technology-ComputerNetworking-Internet/) - [P2P 网络概述.](http://slidesplayer.com/slide/11616167/) - [Circuit Switching (a) Circuit switching. (b) Packet switching.](http://slideplayer.com/slide/5115386/) - - - - - - -
diff --git a/docs/notes/计算机网络 - 目录1.md b/docs/notes/计算机网络 - 目录1.md index 9b2086f2..6bf3f786 100644 --- a/docs/notes/计算机网络 - 目录1.md +++ b/docs/notes/计算机网络 - 目录1.md @@ -1,5 +1,3 @@ - - # 目录 - [概述](notes/计算机网络%20-%20概述.md) @@ -27,10 +25,3 @@ - [P2P 网络概述.](http://slidesplayer.com/slide/11616167/) - [Circuit Switching (a) Circuit switching. (b) Packet switching.](http://slideplayer.com/slide/5115386/) - - - - - - -
diff --git a/docs/notes/计算机网络 - 网络层.md b/docs/notes/计算机网络 - 网络层.md index dd060bdd..a4d275fa 100644 --- a/docs/notes/计算机网络 - 网络层.md +++ b/docs/notes/计算机网络 - 网络层.md @@ -1,24 +1,4 @@ - -* [概述](#概述) -* [IP 数据报格式](#ip-数据报格式) -* [IP 地址编址方式](#ip-地址编址方式) - * [1. 分类](#1-分类) - * [2. 子网划分](#2-子网划分) - * [3. 无分类](#3-无分类) -* [地址解析协议 ARP](#地址解析协议-arp) -* [网际控制报文协议 ICMP](#网际控制报文协议-icmp) - * [1. Ping](#1-ping) - * [2. Traceroute](#2-traceroute) -* [虚拟专用网 VPN](#虚拟专用网-vpn) -* [网络地址转换 NAT](#网络地址转换-nat) -* [路由器的结构](#路由器的结构) -* [路由器分组转发流程](#路由器分组转发流程) -* [路由选择协议](#路由选择协议) - * [1. 内部网关协议 RIP](#1-内部网关协议-rip) - * [2. 内部网关协议 OSPF](#2-内部网关协议-ospf) - * [3. 外部网关协议 BGP](#3-外部网关协议-bgp) - - +[TOC] # 概述 @@ -26,7 +6,7 @@ 使用 IP 协议,可以把异构的物理网络连接起来,使得在网络层看起来好像是一个统一的网络。 -

+ 与 IP 协议配套使用的还有三个协议: @@ -36,7 +16,7 @@ # IP 数据报格式 -

+ - **版本** : 有 4(IPv4)和 6(IPv6)两个值; @@ -56,7 +36,7 @@ - **片偏移** : 和标识符一起,用于发生分片的情况。片偏移的单位为 8 字节。 -

+ # IP 地址编址方式 @@ -72,7 +52,7 @@ IP 地址的编址方式经历了三个历史阶段: IP 地址 ::= {< 网络号 >, < 主机号 >} -

+ ## 2. 子网划分 @@ -102,27 +82,27 @@ CIDR 的地址掩码可以继续称为子网掩码,子网掩码首 1 长度为 网络层实现主机之间的通信,而链路层实现具体每段链路之间的通信。因此在通信过程中,IP 数据报的源地址和目的地址始终不变,而 MAC 地址随着链路的改变而改变。 -

+ ARP 实现由 IP 地址得到 MAC 地址。 -

+ 每个主机都有一个 ARP 高速缓存,里面有本局域网上的各主机和路由器的 IP 地址到 MAC 地址的映射表。 如果主机 A 知道主机 B 的 IP 地址,但是 ARP 高速缓存中没有该 IP 地址到 MAC 地址的映射,此时主机 A 通过广播的方式发送 ARP 请求分组,主机 B 收到该请求后会发送 ARP 响应分组给主机 A 告知其 MAC 地址,随后主机 A 向其高速缓存中写入主机 B 的 IP 地址到 MAC 地址的映射。 -

+ # 网际控制报文协议 ICMP ICMP 是为了更有效地转发 IP 数据报和提高交付成功的机会。它封装在 IP 数据报中,但是不属于高层协议。 -

+ ICMP 报文分为差错报告报文和询问报文。 -

+ ## 1. Ping @@ -155,7 +135,7 @@ VPN 使用公用的互联网作为本机构各专用网之间的通信载体。 下图中,场所 A 和 B 的通信经过互联网,如果场所 A 的主机 X 要和另一个场所 B 的主机 Y 通信,IP 数据报的源地址是 10.1.0.1,目的地址是 10.2.0.3。数据报先发送到与互联网相连的路由器 R1,R1 对内部数据进行加密,然后重新加上数据报的首部,源地址是路由器 R1 的全球地址 125.1.2.3,目的地址是路由器 R2 的全球地址 194.4.5.6。路由器 R2 收到数据报后将数据部分进行解密,恢复原来的数据报,此时目的地址为 10.2.0.3,就交付给 Y。 -

+ # 网络地址转换 NAT @@ -163,7 +143,7 @@ VPN 使用公用的互联网作为本机构各专用网之间的通信载体。 在以前,NAT 将本地 IP 和全球 IP 一一对应,这种方式下拥有 n 个全球 IP 地址的专用网内最多只可以同时有 n 台主机接入互联网。为了更有效地利用全球 IP 地址,现在常用的 NAT 转换表把传输层的端口号也用上了,使得多个专用网内部的主机共用一个全球 IP 地址。使用端口号的 NAT 也叫做网络地址与端口转换 NAPT。 -

+ # 路由器的结构 @@ -171,7 +151,7 @@ VPN 使用公用的互联网作为本机构各专用网之间的通信载体。 分组转发结构由三个部分组成:交换结构、一组输入端口和一组输出端口。 -

+ # 路由器分组转发流程 @@ -182,7 +162,7 @@ VPN 使用公用的互联网作为本机构各专用网之间的通信载体。 - 若路由表中有一个默认路由,则把数据报传送给路由表中所指明的默认路由器; - 报告转发分组出错。 -

+ # 路由选择协议 @@ -239,11 +219,4 @@ BGP 只能寻找一条比较好的路由,而不是最佳路由。 每个 AS 都必须配置 BGP 发言人,通过在两个相邻 BGP 发言人之间建立 TCP 连接来交换路由信息。 -

- - - - - - -
+ diff --git a/docs/notes/计算机网络 - 链路层.md b/docs/notes/计算机网络 - 链路层.md index b47b2f83..2e76cdd9 100644 --- a/docs/notes/计算机网络 - 链路层.md +++ b/docs/notes/计算机网络 - 链路层.md @@ -1,26 +1,4 @@ - -* [基本问题](#基本问题) - * [1. 封装成帧](#1-封装成帧) - * [2. 透明传输](#2-透明传输) - * [3. 差错检测](#3-差错检测) -* [信道分类](#信道分类) - * [1. 广播信道](#1-广播信道) - * [2. 点对点信道](#2-点对点信道) -* [信道复用技术](#信道复用技术) - * [1. 频分复用](#1-频分复用) - * [2. 时分复用](#2-时分复用) - * [3. 统计时分复用](#3-统计时分复用) - * [4. 波分复用](#4-波分复用) - * [5. 码分复用](#5-码分复用) -* [CSMA/CD 协议](#csmacd-协议) -* [PPP 协议](#ppp-协议) -* [MAC 地址](#mac-地址) -* [局域网](#局域网) -* [以太网](#以太网) -* [交换机](#交换机) -* [虚拟局域网](#虚拟局域网) - - +[TOC] # 基本问题 @@ -28,7 +6,7 @@ 将网络层传下来的分组添加首部和尾部,用于标记帧的开始和结束。 -

+ ## 2. 透明传输 @@ -36,7 +14,7 @@ 帧使用首部和尾部进行定界,如果帧的数据部分含有和首部尾部相同的内容,那么帧的开始和结束位置就会被错误的判定。需要在数据部分出现首部尾部相同的内容前面插入转义字符。如果数据部分出现转义字符,那么就在转义字符前面再加个转义字符。在接收端进行处理之后可以还原出原始数据。这个过程透明传输的内容是转义字符,用户察觉不到转义字符的存在。 -

+ ## 3. 差错检测 @@ -64,13 +42,13 @@ 频分复用的所有主机在相同的时间占用不同的频率带宽资源。 -

+ ## 2. 时分复用 时分复用的所有主机在不同的时间占用相同的频率带宽资源。 -

+ 使用频分复用和时分复用进行通信,在通信的过程中主机会一直占用一部分信道资源。但是由于计算机数据的突发性质,通信过程没必要一直占用信道资源而不让出给其它用户使用,因此这两种方式对信道的利用率都不高。 @@ -78,7 +56,7 @@ 是对时分复用的一种改进,不固定每个用户在时分复用帧中的位置,只要有数据就集中起来组成统计时分复用帧然后发送。 -

+ ## 4. 波分复用 @@ -90,7 +68,7 @@ -

+ 为了讨论方便,取 m=8,设码片 为 00011011。在拥有该码片的用户发送比特 1 时就发送该码片,发送比特 0 时就发送该码片的反码 11100100。 @@ -100,9 +78,9 @@ -

+ -

+ 其中 的反码。 @@ -110,7 +88,7 @@ 码分复用需要发送的数据量为原先的 m 倍。 -

+ # CSMA/CD 协议 @@ -125,13 +103,13 @@ CSMA/CD 表示载波监听多点接入 / 碰撞检测。 当发生碰撞时,站点要停止发送,等待一段时间再发送。这个时间采用 **截断二进制指数退避算法** 来确定。从离散的整数集合 {0, 1, .., (2k-1)} 中随机取出一个数,记作 r,然后取 r 倍的争用期作为重传等待时间。 -

+ # PPP 协议 互联网用户通常需要连接到某个 ISP 之后才能接入到互联网,PPP 协议是用户计算机和 ISP 进行通信时所使用的数据链路层协议。 -

+ PPP 的帧格式: @@ -140,7 +118,7 @@ PPP 的帧格式: - FCS 字段是使用 CRC 的检验序列 - 信息部分的长度不超过 1500 -

+ # MAC 地址 @@ -156,7 +134,7 @@ MAC 地址是链路层地址,长度为 6 字节(48 位),用于唯一标 可以按照网络拓扑结构对局域网进行分类: -

+ # 以太网 @@ -172,7 +150,7 @@ MAC 地址是链路层地址,长度为 6 字节(48 位),用于唯一标 - **数据** :长度在 46-1500 之间,如果太小则需要填充; - **FCS** :帧检验序列,使用的是 CRC 检验方法; -

+ # 交换机 @@ -182,7 +160,7 @@ MAC 地址是链路层地址,长度为 6 字节(48 位),用于唯一标 下图中,交换机有 4 个接口,主机 A 向主机 B 发送数据帧时,交换机把主机 A 到接口 1 的映射写入交换表中。为了发送数据帧到 B,先查交换表,此时没有主机 B 的表项,那么主机 A 就发送广播帧,主机 C 和主机 D 会丢弃该帧,主机 B 回应该帧向主机 A 发送数据包时,交换机查找交换表得到主机 A 映射的接口为 1,就发送数据帧到接口 1,同时交换机添加主机 B 到接口 2 的映射。 -

+ # 虚拟局域网 @@ -192,12 +170,5 @@ MAC 地址是链路层地址,长度为 6 字节(48 位),用于唯一标 使用 VLAN 干线连接来建立虚拟局域网,每台交换机上的一个特殊接口被设置为干线接口,以互连 VLAN 交换机。IEEE 定义了一种扩展的以太网帧格式 802.1Q,它在标准以太网帧上加进了 4 字节首部 VLAN 标签,用于表示该帧属于哪一个虚拟局域网。 -

+ - - - - - - -
diff --git a/docs/notes/计算机网络.md b/docs/notes/计算机网络.md index 94dce4ec..c8befa04 100644 --- a/docs/notes/计算机网络.md +++ b/docs/notes/计算机网络.md @@ -1,12 +1 @@ - - - - [计算机网络.md](https://github.com/CyC2018/CS-Notes/blob/master/notes/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%20-%20%E7%9B%AE%E5%BD%95.md) - - - - - - -
diff --git a/docs/notes/设计模式.md b/docs/notes/设计模式.md index 26d00c6a..c90f78dd 100644 --- a/docs/notes/设计模式.md +++ b/docs/notes/设计模式.md @@ -1,36 +1,4 @@ - -* [一、概述](#一概述) -* [二、创建型](#二创建型) - * [1. 单例(Singleton)](#1-单例singleton) - * [2. 简单工厂(Simple Factory)](#2-简单工厂simple-factory) - * [3. 工厂方法(Factory Method)](#3-工厂方法factory-method) - * [4. 抽象工厂(Abstract Factory)](#4-抽象工厂abstract-factory) - * [5. 生成器(Builder)](#5-生成器builder) - * [6. 原型模式(Prototype)](#6-原型模式prototype) -* [三、行为型](#三行为型) - * [1. 责任链(Chain Of Responsibility)](#1-责任链chain-of-responsibility) - * [2. 命令(Command)](#2-命令command) - * [3. 解释器(Interpreter)](#3-解释器interpreter) - * [4. 迭代器(Iterator)](#4-迭代器iterator) - * [5. 中介者(Mediator)](#5-中介者mediator) - * [6. 备忘录(Memento)](#6-备忘录memento) - * [7. 观察者(Observer)](#7-观察者observer) - * [8. 状态(State)](#8-状态state) - * [9. 策略(Strategy)](#9-策略strategy) - * [10. 模板方法(Template Method)](#10-模板方法template-method) - * [11. 访问者(Visitor)](#11-访问者visitor) - * [12. 空对象(Null)](#12-空对象null) -* [四、结构型](#四结构型) - * [1. 适配器(Adapter)](#1-适配器adapter) - * [2. 桥接(Bridge)](#2-桥接bridge) - * [3. 组合(Composite)](#3-组合composite) - * [4. 装饰(Decorator)](#4-装饰decorator) - * [5. 外观(Facade)](#5-外观facade) - * [6. 享元(Flyweight)](#6-享元flyweight) - * [7. 代理(Proxy)](#7-代理proxy) -* [参考资料](#参考资料) - - +[TOC] # 一、概述 @@ -52,7 +20,7 @@ 私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。 -

+![](pics/eca1f422-8381-409b-ad04-98ef39ae38ba.png) ### Implementation @@ -253,7 +221,7 @@ secondName 这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。客户类往往有多个,如果不使用简单工厂,那么所有的客户类都要知道所有子类的细节。而且一旦子类发生改变,例如增加子类,那么所有的客户类都要进行修改。 -

+![](pics/40c0c17e-bba6-4493-9857-147c0044a018.png) ### Implementation @@ -336,7 +304,7 @@ public class Client { 下图中,Factory 有一个 doSomething() 方法,这个方法需要用到一个产品对象,这个产品对象由 factoryMethod() 方法创建。该方法是抽象的,需要由子类去实现。 -

+![](pics/f4d0afd0-8e78-4914-9e60-4366eaf065b5.png) ### Implementation @@ -400,7 +368,7 @@ public class ConcreteFactory2 extends Factory { 从高层次来看,抽象工厂使用了组合,即 Cilent 组合了 AbstractFactory,而工厂方法模式使用了继承。 -

+![](pics/e2190c36-8b27-4690-bde5-9911020a1294.png) ### Implementation @@ -490,7 +458,7 @@ public class Client { ### Class Diagram -

+![](pics/db5e376d-0b3e-490e-a43a-3231914b6668.png) ### Implementation @@ -580,7 +548,7 @@ abcdefghijklmnopqrstuvwxyz ### Class Diagram -

+![](pics/b8922f8c-95e6-4187-be85-572a509afb71.png) ### Implementation @@ -641,7 +609,7 @@ abc - Handler:定义处理请求的接口,并且实现后继链(successor) -

+![](pics/ca9f23bf-55a4-47b2-9534-a28e35397988.png) ### Implementation @@ -779,13 +747,13 @@ request2 is handle by ConcreteHandler2 - Invoker:通过它来调用命令 - Client:可以设置命令与命令的接收者 -

+![](pics/c44a0342-f405-4f17-b750-e27cf4aadde2.png) ### Implementation 设计一个遥控器,可以控制电灯开关。 -

+![](pics/e6bded8e-41a0-489a-88a6-638e88ab7666.jpg) ```java public interface Command { @@ -900,7 +868,7 @@ public class Client { - TerminalExpression:终结符表达式,每个终结符都需要一个 TerminalExpression。 - Context:上下文,包含解释器之外的一些全局信息。 -

+![](pics/2b125bcd-1b36-43be-9b78-d90b076be549.png) ### Implementation @@ -1025,7 +993,7 @@ false - Iterator 主要定义了 hasNext() 和 next() 方法。 - Client 组合了 Aggregate,为了迭代遍历 Aggregate,也需要组合 Iterator。 -

+![](pics/89292ae1-5f13-44dc-b508-3f035e80bf89.png) ### Implementation @@ -1114,17 +1082,17 @@ public class Client { - Mediator:中介者,定义一个接口用于与各同事(Colleague)对象通信。 - Colleague:同事,相关对象 -

+![](pics/30d6e95c-2e3c-4d32-bf4f-68128a70bc05.png) ### Implementation Alarm(闹钟)、CoffeePot(咖啡壶)、Calendar(日历)、Sprinkler(喷头)是一组相关的对象,在某个对象的事件产生时需要去操作其它对象,形成了下面这种依赖结构: -

+![](pics/82cfda3b-b53b-4c89-9fdb-26dd2db0cd02.jpg) 使用中介者模式可以将复杂的依赖结构变成星形结构: -

+![](pics/5359cbf5-5a79-4874-9b17-f23c53c2cb80.jpg) ```java public abstract class Colleague { @@ -1284,7 +1252,7 @@ doSprinkler() - Caretaker:负责保存好备忘录 - Menento:备忘录,存储原始对象的的状态。备忘录实际上有两个接口,一个是提供给 Caretaker 的窄接口:它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。 -

+![](pics/50678f34-694f-45a4-91c6-34d985c83fee.png) ### Implementation @@ -1457,7 +1425,7 @@ public class Client { 主题(Subject)是被观察的对象,而其所有依赖者(Observer)称为观察者。 -

+ ### Class Diagram @@ -1465,13 +1433,13 @@ public class Client { 观察者(Observer)的注册功能需要调用主题的 registerObserver() 方法。 -

+![](pics/a8c8f894-a712-447c-9906-5caef6a016e3.png) ### Implementation 天气数据布告板会在天气信息发生改变时更新其内容,布告板有多个,并且在将来会继续增加。 -

+![](pics/b1df9732-86ce-4d69-9f06-fba1db7b3b5a.jpg) ```java public interface Subject { @@ -1592,13 +1560,13 @@ StatisticsDisplay.update: 1.0 1.0 1.0 ### Class Diagram -

+![](pics/79df886f-fdc3-4020-a07f-c991bb58e0d8.png) ### Implementation 糖果销售机有多种状态,每种状态下销售机有不同的行为,状态可以发生转移,使得销售机的行为也发生改变。 -

+ ```java public interface State { @@ -1899,7 +1867,7 @@ No gumball dispensed - Strategy 接口定义了一个算法族,它们都实现了 behavior() 方法。 - Context 是使用到该算法族的类,其中的 doSomething() 方法会调用 behavior(),setStrategy(Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法。 -

+![](pics/cd1be8c2-755a-4a66-ad92-2e30f8f47922.png) ### 与状态模式的比较 @@ -1986,13 +1954,13 @@ quack! ### Class Diagram -

+![](pics/ac6a794b-68c0-486c-902f-8d988eee5766.png) ### Implementation 冲咖啡和冲茶都有类似的流程,但是某些步骤会有点不一样,要求复用那些相同步骤的代码。 -

+![](pics/11236498-1417-46ce-a1b0-e10054256955.png) ```java public abstract class CaffeineBeverage { @@ -2089,7 +2057,7 @@ Tea.addCondiments - ConcreteVisitor:具体访问者,存储遍历过程中的累计结果 - ObjectStructure:对象结构,可以是组合结构,或者是一个集合。 -

+![](pics/79c6f036-bde6-4393-85a3-ef36a0327bd2.png) ### Implementation @@ -2294,7 +2262,7 @@ Number of items: 6 ### Class Diagram -

+![](pics/22870bbe-898f-4c17-a31a-d7c5ee5d1c10.png) ### Implementation @@ -2346,11 +2314,11 @@ public class Client { 把一个类接口转换成另一个用户需要的接口。 -

+![](pics/3d5b828e-5c4d-48d8-a440-281e4a8e1c92.png) ### Class Diagram -

+![](pics/ff5152fc-4ff3-44c4-95d6-1061002c364a.png) ### Implementation @@ -2422,7 +2390,7 @@ public class Client { - Abstraction:定义抽象类的接口 - Implementor:定义实现类接口 -

+![](pics/2a1f8b0f-1dd7-4409-b177-a381c58066ad.png) ### Implementation @@ -2580,7 +2548,7 @@ public class Client { 组合对象拥有一个或者多个组件对象,因此组合对象的操作可以委托给组件对象去处理,而组件对象可以是另一个组合对象或者叶子对象。 -

+![](pics/2b8bfd57-b4d1-4a75-bfb0-bcf1fba4014a.png) ### Implementation @@ -2712,7 +2680,7 @@ Composite:root 装饰者(Decorator)和具体组件(ConcreteComponent)都继承自组件(Component),具体组件的方法实现不需要依赖于其它对象,而装饰者组合了一个组件,这样它可以装饰其它装饰者或者具体组件。所谓装饰,就是把这个装饰者套在被装饰者之上,从而动态扩展被装饰者的功能。装饰者的方法有一部分是自己的,这属于它的功能,然后调用被装饰者的方法实现,从而也保留了被装饰者的功能。可以看到,具体组件应当是装饰层次的最低层,因为只有具体组件的方法实现不需要依赖于其它对象。 -

+![](pics/6b833bc2-517a-4270-8a5e-0a5f6df8cd96.png) ### Implementation @@ -2720,7 +2688,7 @@ Composite:root 下图表示在 DarkRoast 饮料上新增新添加 Mocha 配料,之后又添加了 Whip 配料。DarkRoast 被 Mocha 包裹,Mocha 又被 Whip 包裹。它们都继承自相同父类,都有 cost() 方法,外层类的 cost() 方法调用了内层类的 cost() 方法。 -

+ ```java public interface Beverage { @@ -2818,7 +2786,7 @@ public class Client { ### Class Diagram -

+![](pics/f9978fa6-9f49-4a0f-8540-02d269ac448f.png) ### Implementation @@ -2877,7 +2845,7 @@ public class Client { - IntrinsicState:内部状态,享元对象共享内部状态 - ExtrinsicState:外部状态,每个享元对象的外部状态不同 -

+![](pics/5f5c22d5-9c0e-49e1-b5b0-6cc7032724d4.png) ### Implementation @@ -2966,7 +2934,7 @@ Java 利用缓存来加速大量小对象的访问时间。 - 保护代理(Protection Proxy):按权限控制对象的访问,它负责检查调用者是否具有实现一个请求所必须的访问权限。 - 智能代理(Smart Reference):取代了简单的指针,它在访问对象时执行一些附加操作:记录对象的引用次数;当第一次引用一个对象时,将它装入内存;在访问一个实际对象前,检查是否已经锁定了它,以确保其它对象不能改变它。 -

+![](pics/9b679ff5-94c6-48a7-b9b7-2ea868e828ed.png) ### Implementation @@ -3064,10 +3032,3 @@ public class ImageViewer { - [Design Patterns](http://www.oodesign.com/) - [Design patterns implemented in Java](http://java-design-patterns.com/) - [The breakdown of design patterns in JDK](http://www.programering.com/a/MTNxAzMwATY.html) - - - - - - -
diff --git a/docs/notes/集群.md b/docs/notes/集群.md index 640d825e..783d1666 100644 --- a/docs/notes/集群.md +++ b/docs/notes/集群.md @@ -1,13 +1,4 @@ - -* [一、负载均衡](#一负载均衡) - * [负载均衡算法](#负载均衡算法) - * [转发实现](#转发实现) -* [二、集群下的 Session 管理](#二集群下的-session-管理) - * [Sticky Session](#sticky-session) - * [Session Replication](#session-replication) - * [Session Server](#session-server) - - +[TOC] # 一、负载均衡 @@ -33,12 +24,12 @@ 下图中,一共有 6 个客户端产生了 6 个请求,这 6 个请求按 (1, 2, 3, 4, 5, 6) 的顺序发送。(1, 3, 5) 的请求会被发送到服务器 1,(2, 4, 6) 的请求会被发送到服务器 2。 -

+ 该算法比较适合每个服务器的性能差不多的场景,如果有性能存在差异的情况下,那么性能较差的服务器可能无法承担过大的负载(下图的 Server 2)。 -

+ ### 2. 加权轮询(Weighted Round Robbin) @@ -46,7 +37,7 @@ 例如下图中,服务器 1 被赋予的权值为 5,服务器 2 被赋予的权值为 1,那么 (1, 2, 3, 4, 5) 请求会被发送到服务器 1,(6) 请求会被发送到服务器 2。 -

+ ### 3. 最少连接(least Connections) @@ -54,13 +45,13 @@ 例如下图中,(1, 3, 5) 请求会被发送到服务器 1,但是 (1, 3) 很快就断开连接,此时只有 (5) 请求连接服务器 1;(2, 4, 6) 请求被发送到服务器 2,只有 (2) 的连接断开,此时 (6, 4) 请求连接服务器 2。该系统继续运行时,服务器 2 会承担过大的负载。 -

+ 最少连接算法就是将请求发送给当前最少连接数的服务器上。 例如下图中,服务器 1 当前连接数最小,那么新到来的请求 6 就会被发送到服务器 1 上。 -

+ ### 4. 加权最少连接(Weighted Least Connection) @@ -72,7 +63,7 @@ 和轮询算法类似,该算法比较适合服务器性能差不多的场景。 -

+ ### 6. 源地址哈希法 (IP Hash) @@ -80,7 +71,7 @@ 可以保证同一 IP 的客户端的请求会转发到同一台服务器上,用来实现会话粘滞(Sticky Session) -

+ ## 转发实现 @@ -95,7 +86,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 该负载均衡转发的缺点比较明显,实际场景中很少使用它。 -

+ ### 2. DNS 域名解析 @@ -111,7 +102,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 大型网站基本使用了 DNS 做为第一级负载均衡手段,然后在内部使用其它方式做第二级负载均衡。也就是说,域名解析的结果为内部的负载均衡服务器 IP 地址。 -

+ ### 3. 反向代理服务器 @@ -168,7 +159,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 - 当服务器宕机时,将丢失该服务器上的所有 Session。 -

+ ## Session Replication @@ -179,7 +170,7 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 - 占用过多内存; - 同步过程占用网络带宽以及服务器处理器时间。 -

+ ## Session Server @@ -193,16 +184,9 @@ HTTP 重定向负载均衡服务器使用某种负载均衡算法计算得到服 - 需要去实现存取 Session 的代码。 -

+ 参考: - [Session Management using Spring Session with JDBC DataStore](https://sivalabs.in/2018/02/session-management-using-spring-session-jdbc-datastore/) - - - - - - -
diff --git a/docs/notes/面向对象思想.md b/docs/notes/面向对象思想.md index 91c40e49..20287302 100644 --- a/docs/notes/面向对象思想.md +++ b/docs/notes/面向对象思想.md @@ -1,21 +1,4 @@ - -* [一、三大特性](#一三大特性) - * [封装](#封装) - * [继承](#继承) - * [多态](#多态) -* [二、类图](#二类图) - * [泛化关系 (Generalization)](#泛化关系-generalization) - * [实现关系 (Realization)](#实现关系-realization) - * [聚合关系 (Aggregation)](#聚合关系-aggregation) - * [组合关系 (Composition)](#组合关系-composition) - * [关联关系 (Association)](#关联关系-association) - * [依赖关系 (Dependency)](#依赖关系-dependency) -* [三、设计原则](#三设计原则) - * [S.O.L.I.D](#solid) - * [其他常见原则](#其他常见原则) -* [参考资料](#参考资料) - - +[TOC] # 一、三大特性 @@ -141,7 +124,7 @@ Percussion is playing... 用来描述继承关系,在 Java 中使用 extends 关键字。 -

+ ```text @startuml @@ -162,7 +145,7 @@ Vihical <|-- Trunck 用来实现一个接口,在 Java 中使用 implements 关键字。 -

+ ```text @startuml @@ -183,7 +166,7 @@ MoveBehavior <|.. Run 表示整体由部分组成,但是整体和部分不是强依赖的,整体不存在了部分还是会存在。 -

+ ```text @startuml @@ -206,7 +189,7 @@ Computer o-- Screen 和聚合不同,组合中整体和部分是强依赖的,整体不存在了部分也不存在了。比如公司和部门,公司没了部门就不存在了。但是公司和员工就属于聚合关系了,因为公司没了员工还在。 -

+ ```text @startuml @@ -227,7 +210,7 @@ Company *-- DepartmentB 表示不同类对象之间有关联,这是一种静态关系,与运行过程的状态无关,在最开始就可以确定。因此也可以用 1 对 1、多对 1、多对多这种关联关系来表示。比如学生和学校就是一种关联关系,一个学校可以有很多学生,但是一个学生只属于一个学校,因此这是一种多对一的关系,在运行开始之前就可以确定。 -

+ ```text @startuml @@ -250,7 +233,7 @@ School "1" - "n" Student - A 类是 B 类方法当中的一个参数; - A 类向 B 类发送消息,从而影响 B 类发生变化。 -

+ ```text @startuml @@ -368,10 +351,3 @@ Vihicle .. N - [看懂 UML 类图和时序图](http://design-patterns.readthedocs.io/zh_CN/latest/read_uml.html#generalization) - [UML 系列——时序图(顺序图)sequence diagram](http://www.cnblogs.com/wolf-sun/p/UML-Sequence-diagram.html) - [面向对象编程三大特性 ------ 封装、继承、多态](http://blog.csdn.net/jianyuerensheng/article/details/51602015) - - - - - - -
diff --git a/docs/pics/0038204c-4b8a-42a5-921d-080f6674f989.png b/docs/pics/0038204c-4b8a-42a5-921d-080f6674f989.png deleted file mode 100644 index 31a2d8d2..00000000 Binary files a/docs/pics/0038204c-4b8a-42a5-921d-080f6674f989.png and /dev/null differ diff --git a/docs/pics/005b481b-502b-4e3f-985d-d043c2b330aa.png b/docs/pics/005b481b-502b-4e3f-985d-d043c2b330aa.png deleted file mode 100644 index 0f8543c2..00000000 Binary files a/docs/pics/005b481b-502b-4e3f-985d-d043c2b330aa.png and /dev/null differ diff --git a/docs/pics/011f3ef6-d824-4d43-8b2c-36dab8eaaa72-1.png b/docs/pics/011f3ef6-d824-4d43-8b2c-36dab8eaaa72-1.png deleted file mode 100644 index c5fc2511..00000000 Binary files a/docs/pics/011f3ef6-d824-4d43-8b2c-36dab8eaaa72-1.png and /dev/null differ diff --git a/docs/pics/014fbc4d-d873-4a12-b160-867ddaed9807.jpg b/docs/pics/014fbc4d-d873-4a12-b160-867ddaed9807.jpg deleted file mode 100644 index 39c003ce..00000000 Binary files a/docs/pics/014fbc4d-d873-4a12-b160-867ddaed9807.jpg and /dev/null differ diff --git a/docs/pics/02943a90-7dd4-4e9a-9325-f8217d3cc54d.jpg b/docs/pics/02943a90-7dd4-4e9a-9325-f8217d3cc54d.jpg deleted file mode 100644 index 41d0a904..00000000 Binary files a/docs/pics/02943a90-7dd4-4e9a-9325-f8217d3cc54d.jpg and /dev/null differ diff --git a/docs/pics/02a1fbfd-7a9d-4114-95df-ca2445587a1f.jpg b/docs/pics/02a1fbfd-7a9d-4114-95df-ca2445587a1f.jpg deleted file mode 100644 index d345a178..00000000 Binary files a/docs/pics/02a1fbfd-7a9d-4114-95df-ca2445587a1f.jpg and /dev/null differ diff --git a/docs/pics/03f47940-3843-4b51-9e42-5dcaff44858b.jpg b/docs/pics/03f47940-3843-4b51-9e42-5dcaff44858b.jpg deleted file mode 100644 index 9a6f75c6..00000000 Binary files a/docs/pics/03f47940-3843-4b51-9e42-5dcaff44858b.jpg and /dev/null differ diff --git a/docs/pics/042cf928-3c8e-4815-ae9c-f2780202c68f.png b/docs/pics/042cf928-3c8e-4815-ae9c-f2780202c68f.png deleted file mode 100644 index 57d8c810..00000000 Binary files a/docs/pics/042cf928-3c8e-4815-ae9c-f2780202c68f.png and /dev/null differ diff --git a/docs/pics/047faac4-a368-4565-8331-2b66253080d3.jpg b/docs/pics/047faac4-a368-4565-8331-2b66253080d3.jpg deleted file mode 100644 index f6506214..00000000 Binary files a/docs/pics/047faac4-a368-4565-8331-2b66253080d3.jpg and /dev/null differ diff --git a/docs/pics/051e436c-0e46-4c59-8f67-52d89d656182.png b/docs/pics/051e436c-0e46-4c59-8f67-52d89d656182.png deleted file mode 100644 index 44e72008..00000000 Binary files a/docs/pics/051e436c-0e46-4c59-8f67-52d89d656182.png and /dev/null differ diff --git a/docs/pics/05a08f2e-9914-4a77-92ef-aebeaecf4f66.jpg b/docs/pics/05a08f2e-9914-4a77-92ef-aebeaecf4f66.jpg deleted file mode 100644 index 0e9bbc86..00000000 Binary files a/docs/pics/05a08f2e-9914-4a77-92ef-aebeaecf4f66.jpg and /dev/null differ diff --git a/docs/pics/067b310c-6877-40fe-9dcf-10654e737485.jpg b/docs/pics/067b310c-6877-40fe-9dcf-10654e737485.jpg deleted file mode 100644 index 09e496ef..00000000 Binary files a/docs/pics/067b310c-6877-40fe-9dcf-10654e737485.jpg and /dev/null differ diff --git a/docs/pics/075e1977-7846-4928-96c8-bb5b0268693c.jpg b/docs/pics/075e1977-7846-4928-96c8-bb5b0268693c.jpg deleted file mode 100644 index 80b1791d..00000000 Binary files a/docs/pics/075e1977-7846-4928-96c8-bb5b0268693c.jpg and /dev/null differ diff --git a/docs/pics/0889c0b4-07b4-45fc-873c-e0e16b97f67d.png b/docs/pics/0889c0b4-07b4-45fc-873c-e0e16b97f67d.png deleted file mode 100644 index c4dbe764..00000000 Binary files a/docs/pics/0889c0b4-07b4-45fc-873c-e0e16b97f67d.png and /dev/null differ diff --git a/docs/pics/08f32fd3-f736-4a67-81ca-295b2a7972f2.jpg b/docs/pics/08f32fd3-f736-4a67-81ca-295b2a7972f2.jpg deleted file mode 100644 index c87a6f86..00000000 Binary files a/docs/pics/08f32fd3-f736-4a67-81ca-295b2a7972f2.jpg and /dev/null differ diff --git a/docs/pics/093f9e57-429c-413a-83ee-c689ba596cef.png b/docs/pics/093f9e57-429c-413a-83ee-c689ba596cef.png deleted file mode 100644 index 7958531c..00000000 Binary files a/docs/pics/093f9e57-429c-413a-83ee-c689ba596cef.png and /dev/null differ diff --git a/docs/pics/094b279a-b2db-4be7-87a3-b2a039c7448e.jpg b/docs/pics/094b279a-b2db-4be7-87a3-b2a039c7448e.jpg deleted file mode 100644 index eb7437e6..00000000 Binary files a/docs/pics/094b279a-b2db-4be7-87a3-b2a039c7448e.jpg and /dev/null differ diff --git a/docs/pics/0972501d-f854-4d26-8fce-babb27c267f6.jpg b/docs/pics/0972501d-f854-4d26-8fce-babb27c267f6.jpg deleted file mode 100644 index d43cafc0..00000000 Binary files a/docs/pics/0972501d-f854-4d26-8fce-babb27c267f6.jpg and /dev/null differ diff --git a/docs/pics/0ad9f7ba-f408-4999-a77a-9b73562c9088.gif b/docs/pics/0ad9f7ba-f408-4999-a77a-9b73562c9088.gif deleted file mode 100644 index 81ebc9d2..00000000 Binary files a/docs/pics/0ad9f7ba-f408-4999-a77a-9b73562c9088.gif and /dev/null differ diff --git a/docs/pics/0b587744-c0a8-46f2-8d72-e8f070d67b4b.jpg b/docs/pics/0b587744-c0a8-46f2-8d72-e8f070d67b4b.jpg deleted file mode 100644 index 430719d0..00000000 Binary files a/docs/pics/0b587744-c0a8-46f2-8d72-e8f070d67b4b.jpg and /dev/null differ diff --git a/docs/pics/0c12221f-729e-4c22-b0ba-0dfc909f8adf.jpg b/docs/pics/0c12221f-729e-4c22-b0ba-0dfc909f8adf.jpg deleted file mode 100644 index 068f6dee..00000000 Binary files a/docs/pics/0c12221f-729e-4c22-b0ba-0dfc909f8adf.jpg and /dev/null differ diff --git a/docs/pics/0c6f9930-8704-4a54-af23-19f9ca3e48b0.jpg b/docs/pics/0c6f9930-8704-4a54-af23-19f9ca3e48b0.jpg deleted file mode 100644 index 8bb39d71..00000000 Binary files a/docs/pics/0c6f9930-8704-4a54-af23-19f9ca3e48b0.jpg and /dev/null differ diff --git a/docs/pics/0dae7e93-cfd1-4bd3-97e8-325b032b716f.gif b/docs/pics/0dae7e93-cfd1-4bd3-97e8-325b032b716f.gif deleted file mode 100644 index e1e41d2d..00000000 Binary files a/docs/pics/0dae7e93-cfd1-4bd3-97e8-325b032b716f.gif and /dev/null differ diff --git a/docs/pics/0dbc4f7d-05c9-4aae-8065-7b7ea7e9709e.gif b/docs/pics/0dbc4f7d-05c9-4aae-8065-7b7ea7e9709e.gif deleted file mode 100644 index c5051aeb..00000000 Binary files a/docs/pics/0dbc4f7d-05c9-4aae-8065-7b7ea7e9709e.gif and /dev/null differ diff --git a/docs/pics/0dd2d40a-5b2b-4d45-b176-e75a4cd4bdbf.png b/docs/pics/0dd2d40a-5b2b-4d45-b176-e75a4cd4bdbf.png deleted file mode 100644 index 1bb834c8..00000000 Binary files a/docs/pics/0dd2d40a-5b2b-4d45-b176-e75a4cd4bdbf.png and /dev/null differ diff --git a/docs/pics/0df5d84c-e7ca-4e3a-a688-bb8e68894467.png b/docs/pics/0df5d84c-e7ca-4e3a-a688-bb8e68894467.png deleted file mode 100644 index 9e35ec60..00000000 Binary files a/docs/pics/0df5d84c-e7ca-4e3a-a688-bb8e68894467.png and /dev/null differ diff --git a/docs/pics/0e8fdc96-83c1-4798-9abe-45fc91d70b9d.png b/docs/pics/0e8fdc96-83c1-4798-9abe-45fc91d70b9d.png deleted file mode 100644 index 4a1fcfa9..00000000 Binary files a/docs/pics/0e8fdc96-83c1-4798-9abe-45fc91d70b9d.png and /dev/null differ diff --git a/docs/pics/0ea37ee2-c224-4c79-b895-e131c6805c40.png b/docs/pics/0ea37ee2-c224-4c79-b895-e131c6805c40.png deleted file mode 100644 index 837088e8..00000000 Binary files a/docs/pics/0ea37ee2-c224-4c79-b895-e131c6805c40.png and /dev/null differ diff --git a/docs/pics/0f399a9f-1351-4b2d-b8a4-2ebe82b1a703.jpg b/docs/pics/0f399a9f-1351-4b2d-b8a4-2ebe82b1a703.jpg deleted file mode 100644 index e1bd6fe8..00000000 Binary files a/docs/pics/0f399a9f-1351-4b2d-b8a4-2ebe82b1a703.jpg and /dev/null differ diff --git a/docs/pics/0f754c1d-b5cb-48cd-90e0-4a86034290a1.png b/docs/pics/0f754c1d-b5cb-48cd-90e0-4a86034290a1.png deleted file mode 100644 index 778d7c90..00000000 Binary files a/docs/pics/0f754c1d-b5cb-48cd-90e0-4a86034290a1.png and /dev/null differ diff --git a/docs/pics/0f8d178b-52d8-491b-9dfd-41e05a952578.gif b/docs/pics/0f8d178b-52d8-491b-9dfd-41e05a952578.gif deleted file mode 100644 index b28b214e..00000000 Binary files a/docs/pics/0f8d178b-52d8-491b-9dfd-41e05a952578.gif and /dev/null differ diff --git a/docs/pics/0fa6c237-a909-4e2a-a771-2c5485cd8ce0.png b/docs/pics/0fa6c237-a909-4e2a-a771-2c5485cd8ce0.png deleted file mode 100644 index a4eead80..00000000 Binary files a/docs/pics/0fa6c237-a909-4e2a-a771-2c5485cd8ce0.png and /dev/null differ diff --git a/docs/pics/101550414151983.gif b/docs/pics/101550414151983.gif deleted file mode 100644 index f1c63cf7..00000000 Binary files a/docs/pics/101550414151983.gif and /dev/null differ diff --git a/docs/pics/1097658b-c0e6-4821-be9b-25304726a11c.jpg b/docs/pics/1097658b-c0e6-4821-be9b-25304726a11c.jpg deleted file mode 100644 index fb8aa672..00000000 Binary files a/docs/pics/1097658b-c0e6-4821-be9b-25304726a11c.jpg and /dev/null differ diff --git a/docs/pics/111521118015898.gif b/docs/pics/111521118015898.gif deleted file mode 100644 index ca576769..00000000 Binary files a/docs/pics/111521118015898.gif and /dev/null differ diff --git a/docs/pics/111521118445538.gif b/docs/pics/111521118445538.gif deleted file mode 100644 index a4f2fe4c..00000000 Binary files a/docs/pics/111521118445538.gif and /dev/null differ diff --git a/docs/pics/111521118483039.gif b/docs/pics/111521118483039.gif deleted file mode 100644 index 0f63c443..00000000 Binary files a/docs/pics/111521118483039.gif and /dev/null differ diff --git a/docs/pics/111521118640738.gif b/docs/pics/111521118640738.gif deleted file mode 100644 index cb6a9b29..00000000 Binary files a/docs/pics/111521118640738.gif and /dev/null differ diff --git a/docs/pics/111521119203347.gif b/docs/pics/111521119203347.gif deleted file mode 100644 index deb7c350..00000000 Binary files a/docs/pics/111521119203347.gif and /dev/null differ diff --git a/docs/pics/111521119368714.gif b/docs/pics/111521119368714.gif deleted file mode 100644 index 0793cfbd..00000000 Binary files a/docs/pics/111521119368714.gif and /dev/null differ diff --git a/docs/pics/111550414182638.gif b/docs/pics/111550414182638.gif deleted file mode 100644 index 96f5a518..00000000 Binary files a/docs/pics/111550414182638.gif and /dev/null differ diff --git a/docs/pics/11236498-1417-46ce-a1b0-e10054256955.png b/docs/pics/11236498-1417-46ce-a1b0-e10054256955.png deleted file mode 100644 index cc6726ff..00000000 Binary files a/docs/pics/11236498-1417-46ce-a1b0-e10054256955.png and /dev/null differ diff --git a/docs/pics/1176f9e1-3442-4808-a47a-76fbaea1b806.png b/docs/pics/1176f9e1-3442-4808-a47a-76fbaea1b806.png deleted file mode 100644 index 581673ff..00000000 Binary files a/docs/pics/1176f9e1-3442-4808-a47a-76fbaea1b806.png and /dev/null differ diff --git a/docs/pics/11b27de5-5a9d-45e4-95cc-417fa3ad1d38.jpg b/docs/pics/11b27de5-5a9d-45e4-95cc-417fa3ad1d38.jpg deleted file mode 100644 index 4bc7e502..00000000 Binary files a/docs/pics/11b27de5-5a9d-45e4-95cc-417fa3ad1d38.jpg and /dev/null differ diff --git a/docs/pics/1202b2d6-9469-4251-bd47-ca6034fb6116.png b/docs/pics/1202b2d6-9469-4251-bd47-ca6034fb6116.png deleted file mode 100644 index 0db77ec4..00000000 Binary files a/docs/pics/1202b2d6-9469-4251-bd47-ca6034fb6116.png and /dev/null differ diff --git a/docs/pics/12a65cc6-20e0-4706-9fe6-3ba49413d7f6.png b/docs/pics/12a65cc6-20e0-4706-9fe6-3ba49413d7f6.png deleted file mode 100644 index 69283617..00000000 Binary files a/docs/pics/12a65cc6-20e0-4706-9fe6-3ba49413d7f6.png and /dev/null differ diff --git a/docs/pics/13454fa1-23a8-4578-9663-2b13a6af564a.jpg b/docs/pics/13454fa1-23a8-4578-9663-2b13a6af564a.jpg deleted file mode 100644 index 5284457b..00000000 Binary files a/docs/pics/13454fa1-23a8-4578-9663-2b13a6af564a.jpg and /dev/null differ diff --git a/docs/pics/137c593d-0a9e-47b8-a9e6-b71f540b82dd.png b/docs/pics/137c593d-0a9e-47b8-a9e6-b71f540b82dd.png deleted file mode 100644 index 790e5c92..00000000 Binary files a/docs/pics/137c593d-0a9e-47b8-a9e6-b71f540b82dd.png and /dev/null differ diff --git a/docs/pics/13b0940e-d1d7-4b17-af4f-b70cb0a75e08.png b/docs/pics/13b0940e-d1d7-4b17-af4f-b70cb0a75e08.png deleted file mode 100644 index 5de1625e..00000000 Binary files a/docs/pics/13b0940e-d1d7-4b17-af4f-b70cb0a75e08.png and /dev/null differ diff --git a/docs/pics/14389ea4-8d96-4e96-9f76-564ca3324c1e.png b/docs/pics/14389ea4-8d96-4e96-9f76-564ca3324c1e.png deleted file mode 100644 index 71b87153..00000000 Binary files a/docs/pics/14389ea4-8d96-4e96-9f76-564ca3324c1e.png and /dev/null differ diff --git a/docs/pics/1492928105791_3.png b/docs/pics/1492928105791_3.png deleted file mode 100644 index 95684c61..00000000 Binary files a/docs/pics/1492928105791_3.png and /dev/null differ diff --git a/docs/pics/1492928416812_4.png b/docs/pics/1492928416812_4.png deleted file mode 100644 index 341d1da2..00000000 Binary files a/docs/pics/1492928416812_4.png and /dev/null differ diff --git a/docs/pics/1492929000361_5.png b/docs/pics/1492929000361_5.png deleted file mode 100644 index 449b97dd..00000000 Binary files a/docs/pics/1492929000361_5.png and /dev/null differ diff --git a/docs/pics/1492929444818_6.png b/docs/pics/1492929444818_6.png deleted file mode 100644 index 8c401099..00000000 Binary files a/docs/pics/1492929444818_6.png and /dev/null differ diff --git a/docs/pics/1492929553651_7.png b/docs/pics/1492929553651_7.png deleted file mode 100644 index 62363b36..00000000 Binary files a/docs/pics/1492929553651_7.png and /dev/null differ diff --git a/docs/pics/1492930243286_8.png b/docs/pics/1492930243286_8.png deleted file mode 100644 index 777a68cb..00000000 Binary files a/docs/pics/1492930243286_8.png and /dev/null differ diff --git a/docs/pics/14fe1e71-8518-458f-a220-116003061a83.png b/docs/pics/14fe1e71-8518-458f-a220-116003061a83.png deleted file mode 100644 index ece93663..00000000 Binary files a/docs/pics/14fe1e71-8518-458f-a220-116003061a83.png and /dev/null differ diff --git a/docs/pics/15313ed8-a520-4799-a300-2b6b36be314f.jpg b/docs/pics/15313ed8-a520-4799-a300-2b6b36be314f.jpg deleted file mode 100644 index 1d62bef3..00000000 Binary files a/docs/pics/15313ed8-a520-4799-a300-2b6b36be314f.jpg and /dev/null differ diff --git a/docs/pics/1556770b-8c01-4681-af10-46f1df69202c.jpg b/docs/pics/1556770b-8c01-4681-af10-46f1df69202c.jpg deleted file mode 100644 index 94d1adc2..00000000 Binary files a/docs/pics/1556770b-8c01-4681-af10-46f1df69202c.jpg and /dev/null differ diff --git a/docs/pics/15851555-5abc-497d-ad34-efed10f43a6b.png b/docs/pics/15851555-5abc-497d-ad34-efed10f43a6b.png deleted file mode 100644 index fc45f2ec..00000000 Binary files a/docs/pics/15851555-5abc-497d-ad34-efed10f43a6b.png and /dev/null differ diff --git a/docs/pics/1623f524-b011-40c8-b83f-eab38d538f76.png b/docs/pics/1623f524-b011-40c8-b83f-eab38d538f76.png deleted file mode 100644 index 90f74bd8..00000000 Binary files a/docs/pics/1623f524-b011-40c8-b83f-eab38d538f76.png and /dev/null differ diff --git a/docs/pics/164944d3-bbd2-4bb2-924b-e62199c51b90.png b/docs/pics/164944d3-bbd2-4bb2-924b-e62199c51b90.png deleted file mode 100644 index a81dbb83..00000000 Binary files a/docs/pics/164944d3-bbd2-4bb2-924b-e62199c51b90.png and /dev/null differ diff --git a/docs/pics/17e301df-52e8-4886-b593-841a16d13e44.png b/docs/pics/17e301df-52e8-4886-b593-841a16d13e44.png deleted file mode 100644 index b1ae4d1c..00000000 Binary files a/docs/pics/17e301df-52e8-4886-b593-841a16d13e44.png and /dev/null differ diff --git a/docs/pics/1818e141-8700-4026-99f7-900a545875f5.png b/docs/pics/1818e141-8700-4026-99f7-900a545875f5.png deleted file mode 100644 index 33bb2621..00000000 Binary files a/docs/pics/1818e141-8700-4026-99f7-900a545875f5.png and /dev/null differ diff --git a/docs/pics/195f8693-5ec4-4987-8560-f25e365879dd.png b/docs/pics/195f8693-5ec4-4987-8560-f25e365879dd.png deleted file mode 100644 index b2ea3f87..00000000 Binary files a/docs/pics/195f8693-5ec4-4987-8560-f25e365879dd.png and /dev/null differ diff --git a/docs/pics/19d423e9-74f7-4c2b-9b97-55890e0d5193.png b/docs/pics/19d423e9-74f7-4c2b-9b97-55890e0d5193.png deleted file mode 100644 index eeee8920..00000000 Binary files a/docs/pics/19d423e9-74f7-4c2b-9b97-55890e0d5193.png and /dev/null differ diff --git a/docs/pics/1a851e90-0d5c-4d4f-ac54-34c20ecfb903.jpg b/docs/pics/1a851e90-0d5c-4d4f-ac54-34c20ecfb903.jpg deleted file mode 100644 index dc927207..00000000 Binary files a/docs/pics/1a851e90-0d5c-4d4f-ac54-34c20ecfb903.jpg and /dev/null differ diff --git a/docs/pics/1a9977e4-2f5c-49a6-aec9-f3027c9f46a7.png b/docs/pics/1a9977e4-2f5c-49a6-aec9-f3027c9f46a7.png deleted file mode 100644 index 3457a74b..00000000 Binary files a/docs/pics/1a9977e4-2f5c-49a6-aec9-f3027c9f46a7.png and /dev/null differ diff --git a/docs/pics/1ab49e39-012b-4383-8284-26570987e3c4.jpg b/docs/pics/1ab49e39-012b-4383-8284-26570987e3c4.jpg deleted file mode 100644 index 48a91211..00000000 Binary files a/docs/pics/1ab49e39-012b-4383-8284-26570987e3c4.jpg and /dev/null differ diff --git a/docs/pics/1b80288d-1b35-4cd3-aa17-7e27ab9a2389.png b/docs/pics/1b80288d-1b35-4cd3-aa17-7e27ab9a2389.png deleted file mode 100644 index 44b12ccd..00000000 Binary files a/docs/pics/1b80288d-1b35-4cd3-aa17-7e27ab9a2389.png and /dev/null differ diff --git a/docs/pics/1bea398f-17a7-4f67-a90b-9e2d243eaa9a.png b/docs/pics/1bea398f-17a7-4f67-a90b-9e2d243eaa9a.png deleted file mode 100644 index f7b624cb..00000000 Binary files a/docs/pics/1bea398f-17a7-4f67-a90b-9e2d243eaa9a.png and /dev/null differ diff --git a/docs/pics/1d28ad05-39e5-49a2-a6a1-a6f496adba6a.png b/docs/pics/1d28ad05-39e5-49a2-a6a1-a6f496adba6a.png deleted file mode 100644 index 7c7cce6d..00000000 Binary files a/docs/pics/1d28ad05-39e5-49a2-a6a1-a6f496adba6a.png and /dev/null differ diff --git a/docs/pics/1daadd30-bd54-419e-a764-0dc95ac69653_200.png b/docs/pics/1daadd30-bd54-419e-a764-0dc95ac69653_200.png deleted file mode 100644 index 3e0cd649..00000000 Binary files a/docs/pics/1daadd30-bd54-419e-a764-0dc95ac69653_200.png and /dev/null differ diff --git a/docs/pics/1db1c7ea-0443-478b-8df9-7e33b1336cc4.png b/docs/pics/1db1c7ea-0443-478b-8df9-7e33b1336cc4.png deleted file mode 100644 index e3082177..00000000 Binary files a/docs/pics/1db1c7ea-0443-478b-8df9-7e33b1336cc4.png and /dev/null differ diff --git a/docs/pics/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png b/docs/pics/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png deleted file mode 100644 index ec214a8e..00000000 Binary files a/docs/pics/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png and /dev/null differ diff --git a/docs/pics/1e46fd03-0cda-4d60-9b1c-0c256edaf6b2.png b/docs/pics/1e46fd03-0cda-4d60-9b1c-0c256edaf6b2.png deleted file mode 100644 index 8c496033..00000000 Binary files a/docs/pics/1e46fd03-0cda-4d60-9b1c-0c256edaf6b2.png and /dev/null differ diff --git a/docs/pics/1e6affc4-18e5-4596-96ef-fb84c63bf88a.png b/docs/pics/1e6affc4-18e5-4596-96ef-fb84c63bf88a.png deleted file mode 100644 index e28387b0..00000000 Binary files a/docs/pics/1e6affc4-18e5-4596-96ef-fb84c63bf88a.png and /dev/null differ diff --git a/docs/pics/1fc969e4-0e7c-441b-b53c-01950d2f2be5.png b/docs/pics/1fc969e4-0e7c-441b-b53c-01950d2f2be5.png deleted file mode 100644 index 6b4c7781..00000000 Binary files a/docs/pics/1fc969e4-0e7c-441b-b53c-01950d2f2be5.png and /dev/null differ diff --git a/docs/pics/1fe2dc77-9a2d-4643-90b3-bbf50f649bac.png b/docs/pics/1fe2dc77-9a2d-4643-90b3-bbf50f649bac.png deleted file mode 100644 index 0c1ae3cd..00000000 Binary files a/docs/pics/1fe2dc77-9a2d-4643-90b3-bbf50f649bac.png and /dev/null differ diff --git a/docs/pics/2017-06-11-ca.png b/docs/pics/2017-06-11-ca.png deleted file mode 100644 index d3b7b209..00000000 Binary files a/docs/pics/2017-06-11-ca.png and /dev/null differ diff --git a/docs/pics/206f965e-53b2-4732-90cf-75910b80d7ac.png b/docs/pics/206f965e-53b2-4732-90cf-75910b80d7ac.png deleted file mode 100644 index 069b7e17..00000000 Binary files a/docs/pics/206f965e-53b2-4732-90cf-75910b80d7ac.png and /dev/null differ diff --git a/docs/pics/22870bbe-898f-4c17-a31a-d7c5ee5d1c10.png b/docs/pics/22870bbe-898f-4c17-a31a-d7c5ee5d1c10.png deleted file mode 100644 index 6cbae157..00000000 Binary files a/docs/pics/22870bbe-898f-4c17-a31a-d7c5ee5d1c10.png and /dev/null differ diff --git a/docs/pics/22de0538-7c6e-4365-bd3b-8ce3c5900216.png b/docs/pics/22de0538-7c6e-4365-bd3b-8ce3c5900216.png deleted file mode 100644 index 8d7dc098..00000000 Binary files a/docs/pics/22de0538-7c6e-4365-bd3b-8ce3c5900216.png and /dev/null differ diff --git a/docs/pics/22fda4ae-4dd5-489d-ab10-9ebfdad22ae0.jpg b/docs/pics/22fda4ae-4dd5-489d-ab10-9ebfdad22ae0.jpg deleted file mode 100644 index b45bb546..00000000 Binary files a/docs/pics/22fda4ae-4dd5-489d-ab10-9ebfdad22ae0.jpg and /dev/null differ diff --git a/docs/pics/23219e4c-9fc0-4051-b33a-2bd95bf054ab.jpg b/docs/pics/23219e4c-9fc0-4051-b33a-2bd95bf054ab.jpg deleted file mode 100644 index 61c39069..00000000 Binary files a/docs/pics/23219e4c-9fc0-4051-b33a-2bd95bf054ab.jpg and /dev/null differ diff --git a/docs/pics/233f8d89-31d7-413f-9c02-042f19c46ba1.png b/docs/pics/233f8d89-31d7-413f-9c02-042f19c46ba1.png deleted file mode 100644 index 05d4de2e..00000000 Binary files a/docs/pics/233f8d89-31d7-413f-9c02-042f19c46ba1.png and /dev/null differ diff --git a/docs/pics/23b9d625-ef28-42b5-bb22-d7aedd007e16.jpg b/docs/pics/23b9d625-ef28-42b5-bb22-d7aedd007e16.jpg deleted file mode 100644 index b2431955..00000000 Binary files a/docs/pics/23b9d625-ef28-42b5-bb22-d7aedd007e16.jpg and /dev/null differ diff --git a/docs/pics/23ba890e-e11c-45e2-a20c-64d217f83430.png b/docs/pics/23ba890e-e11c-45e2-a20c-64d217f83430.png deleted file mode 100644 index 5fccbd1c..00000000 Binary files a/docs/pics/23ba890e-e11c-45e2-a20c-64d217f83430.png and /dev/null differ diff --git a/docs/pics/23e4462b-263f-4d15-8805-529e0ca7a4d1.jpg b/docs/pics/23e4462b-263f-4d15-8805-529e0ca7a4d1.jpg deleted file mode 100644 index dad602bb..00000000 Binary files a/docs/pics/23e4462b-263f-4d15-8805-529e0ca7a4d1.jpg and /dev/null differ diff --git a/docs/pics/245fd2fb-209c-4ad5-bc5e-eb5664966a0e.jpg b/docs/pics/245fd2fb-209c-4ad5-bc5e-eb5664966a0e.jpg deleted file mode 100644 index 1e85dc95..00000000 Binary files a/docs/pics/245fd2fb-209c-4ad5-bc5e-eb5664966a0e.jpg and /dev/null differ diff --git a/docs/pics/265bab88-7be9-44c5-a33f-f93d9882c096.png b/docs/pics/265bab88-7be9-44c5-a33f-f93d9882c096.png deleted file mode 100644 index 97e6f8cf..00000000 Binary files a/docs/pics/265bab88-7be9-44c5-a33f-f93d9882c096.png and /dev/null differ diff --git a/docs/pics/2719067e-b299-4639-9065-bed6729dbf0b.png b/docs/pics/2719067e-b299-4639-9065-bed6729dbf0b.png deleted file mode 100644 index 95057e05..00000000 Binary files a/docs/pics/2719067e-b299-4639-9065-bed6729dbf0b.png and /dev/null differ diff --git a/docs/pics/271ce08f-c124-475f-b490-be44fedc6d2e.png b/docs/pics/271ce08f-c124-475f-b490-be44fedc6d2e.png deleted file mode 100644 index 8de6367b..00000000 Binary files a/docs/pics/271ce08f-c124-475f-b490-be44fedc6d2e.png and /dev/null differ diff --git a/docs/pics/278fe431-af88-4a95-a895-9c3b80117de3.jpg b/docs/pics/278fe431-af88-4a95-a895-9c3b80117de3.jpg deleted file mode 100644 index c2697572..00000000 Binary files a/docs/pics/278fe431-af88-4a95-a895-9c3b80117de3.jpg and /dev/null differ diff --git a/docs/pics/2797a609-68db-4d7b-8701-41ac9a34b14f.jpg b/docs/pics/2797a609-68db-4d7b-8701-41ac9a34b14f.jpg deleted file mode 100644 index f9e77863..00000000 Binary files a/docs/pics/2797a609-68db-4d7b-8701-41ac9a34b14f.jpg and /dev/null differ diff --git a/docs/pics/292b4a35-4507-4256-84ff-c218f108ee31.jpg b/docs/pics/292b4a35-4507-4256-84ff-c218f108ee31.jpg deleted file mode 100644 index 2cf77c68..00000000 Binary files a/docs/pics/292b4a35-4507-4256-84ff-c218f108ee31.jpg and /dev/null differ diff --git a/docs/pics/29a14735-e154-4f60-9a04-c9628e5d09f4.png b/docs/pics/29a14735-e154-4f60-9a04-c9628e5d09f4.png deleted file mode 100644 index b2655874..00000000 Binary files a/docs/pics/29a14735-e154-4f60-9a04-c9628e5d09f4.png and /dev/null differ diff --git a/docs/pics/2_14_microkernelArchitecture.jpg b/docs/pics/2_14_microkernelArchitecture.jpg deleted file mode 100644 index 21c2a58f..00000000 Binary files a/docs/pics/2_14_microkernelArchitecture.jpg and /dev/null differ diff --git a/docs/pics/2a1f8b0f-1dd7-4409-b177-a381c58066ad.png b/docs/pics/2a1f8b0f-1dd7-4409-b177-a381c58066ad.png deleted file mode 100644 index 7d765595..00000000 Binary files a/docs/pics/2a1f8b0f-1dd7-4409-b177-a381c58066ad.png and /dev/null differ diff --git a/docs/pics/2ac50b81-d92a-4401-b9ec-f2113ecc3076.png b/docs/pics/2ac50b81-d92a-4401-b9ec-f2113ecc3076.png deleted file mode 100644 index 173ce970..00000000 Binary files a/docs/pics/2ac50b81-d92a-4401-b9ec-f2113ecc3076.png and /dev/null differ diff --git a/docs/pics/2b125bcd-1b36-43be-9b78-d90b076be549.png b/docs/pics/2b125bcd-1b36-43be-9b78-d90b076be549.png deleted file mode 100644 index e07b1812..00000000 Binary files a/docs/pics/2b125bcd-1b36-43be-9b78-d90b076be549.png and /dev/null differ diff --git a/docs/pics/2b8bfd57-b4d1-4a75-bfb0-bcf1fba4014a.png b/docs/pics/2b8bfd57-b4d1-4a75-bfb0-bcf1fba4014a.png deleted file mode 100644 index a8b7184b..00000000 Binary files a/docs/pics/2b8bfd57-b4d1-4a75-bfb0-bcf1fba4014a.png and /dev/null differ diff --git a/docs/pics/2bab4127-3e7d-48cc-914e-436be859fb05.png b/docs/pics/2bab4127-3e7d-48cc-914e-436be859fb05.png deleted file mode 100644 index c65e1eaa..00000000 Binary files a/docs/pics/2bab4127-3e7d-48cc-914e-436be859fb05.png and /dev/null differ diff --git a/docs/pics/2bcc58ad-bf7f-485c-89b5-e7cafc211ce2.jpg b/docs/pics/2bcc58ad-bf7f-485c-89b5-e7cafc211ce2.jpg deleted file mode 100644 index d2dd5fc6..00000000 Binary files a/docs/pics/2bcc58ad-bf7f-485c-89b5-e7cafc211ce2.jpg and /dev/null differ diff --git a/docs/pics/2d09a847-b854-439c-9198-b29c65810944.png b/docs/pics/2d09a847-b854-439c-9198-b29c65810944.png deleted file mode 100644 index f3ab93e5..00000000 Binary files a/docs/pics/2d09a847-b854-439c-9198-b29c65810944.png and /dev/null differ diff --git a/docs/pics/2de794ca-aa7b-48f3-a556-a0e2708cb976.jpg b/docs/pics/2de794ca-aa7b-48f3-a556-a0e2708cb976.jpg deleted file mode 100644 index 403fbe44..00000000 Binary files a/docs/pics/2de794ca-aa7b-48f3-a556-a0e2708cb976.jpg and /dev/null differ diff --git a/docs/pics/2f683fe8-bee8-46a9-86a7-685c8981555856191616.png b/docs/pics/2f683fe8-bee8-46a9-86a7-685c8981555856191616.png deleted file mode 100644 index ba7b5b0c..00000000 Binary files a/docs/pics/2f683fe8-bee8-46a9-86a7-685c8981555856191616.png and /dev/null differ diff --git a/docs/pics/308a02e9-3346-4251-8c41-bd5536dab491.png b/docs/pics/308a02e9-3346-4251-8c41-bd5536dab491.png deleted file mode 100644 index 5ec4647d..00000000 Binary files a/docs/pics/308a02e9-3346-4251-8c41-bd5536dab491.png and /dev/null differ diff --git a/docs/pics/30d6e95c-2e3c-4d32-bf4f-68128a70bc05.png b/docs/pics/30d6e95c-2e3c-4d32-bf4f-68128a70bc05.png deleted file mode 100644 index e5397988..00000000 Binary files a/docs/pics/30d6e95c-2e3c-4d32-bf4f-68128a70bc05.png and /dev/null differ diff --git a/docs/pics/31b7e8de-ed11-4f69-b5fd-ba454120ac31.jpg b/docs/pics/31b7e8de-ed11-4f69-b5fd-ba454120ac31.jpg deleted file mode 100644 index 2f5fa186..00000000 Binary files a/docs/pics/31b7e8de-ed11-4f69-b5fd-ba454120ac31.jpg and /dev/null differ diff --git a/docs/pics/31d9adce-2af8-4754-8386-0aabb4e500b0.png b/docs/pics/31d9adce-2af8-4754-8386-0aabb4e500b0.png deleted file mode 100644 index 1248f60f..00000000 Binary files a/docs/pics/31d9adce-2af8-4754-8386-0aabb4e500b0.png and /dev/null differ diff --git a/docs/pics/32b05e81-41b3-414a-8656-736c9604e3d6.png b/docs/pics/32b05e81-41b3-414a-8656-736c9604e3d6.png deleted file mode 100644 index 38a07f6f..00000000 Binary files a/docs/pics/32b05e81-41b3-414a-8656-736c9604e3d6.png and /dev/null differ diff --git a/docs/pics/33576849-9275-47bb-ada7-8ded5f5e7c73.png b/docs/pics/33576849-9275-47bb-ada7-8ded5f5e7c73.png deleted file mode 100644 index 14f5b19d..00000000 Binary files a/docs/pics/33576849-9275-47bb-ada7-8ded5f5e7c73.png and /dev/null differ diff --git a/docs/pics/335fe19c-4a76-45ab-9320-88c90d6a0d7e.png b/docs/pics/335fe19c-4a76-45ab-9320-88c90d6a0d7e.png deleted file mode 100644 index 57fad732..00000000 Binary files a/docs/pics/335fe19c-4a76-45ab-9320-88c90d6a0d7e.png and /dev/null differ diff --git a/docs/pics/34751bd9-e8e4-4c20-94bc-f7217049fada.png b/docs/pics/34751bd9-e8e4-4c20-94bc-f7217049fada.png deleted file mode 100644 index 31e7cfc3..00000000 Binary files a/docs/pics/34751bd9-e8e4-4c20-94bc-f7217049fada.png and /dev/null differ diff --git a/docs/pics/35253fa4-f60a-4e3b-aaec-8fc835aabdac.gif b/docs/pics/35253fa4-f60a-4e3b-aaec-8fc835aabdac.gif deleted file mode 100644 index 133e5b40..00000000 Binary files a/docs/pics/35253fa4-f60a-4e3b-aaec-8fc835aabdac.gif and /dev/null differ diff --git a/docs/pics/379444c9-f1d1-45cd-b7aa-b0c18427d388.jpg b/docs/pics/379444c9-f1d1-45cd-b7aa-b0c18427d388.jpg deleted file mode 100644 index 18a14452..00000000 Binary files a/docs/pics/379444c9-f1d1-45cd-b7aa-b0c18427d388.jpg and /dev/null differ diff --git a/docs/pics/390c913b-5f31-444f-bbdb-2b88b688e7ce.jpg b/docs/pics/390c913b-5f31-444f-bbdb-2b88b688e7ce.jpg deleted file mode 100644 index 27699929..00000000 Binary files a/docs/pics/390c913b-5f31-444f-bbdb-2b88b688e7ce.jpg and /dev/null differ diff --git a/docs/pics/395a9e83-b1a1-4a1d-b170-d081e7bb5bab.png b/docs/pics/395a9e83-b1a1-4a1d-b170-d081e7bb5bab.png deleted file mode 100644 index 4f3d0ccd..00000000 Binary files a/docs/pics/395a9e83-b1a1-4a1d-b170-d081e7bb5bab.png and /dev/null differ diff --git a/docs/pics/396be981-3f2c-4fd9-8101-dbf9c841504b.jpg b/docs/pics/396be981-3f2c-4fd9-8101-dbf9c841504b.jpg deleted file mode 100644 index 79c5704a..00000000 Binary files a/docs/pics/396be981-3f2c-4fd9-8101-dbf9c841504b.jpg and /dev/null differ diff --git a/docs/pics/399b459d-db9e-4e77-b879-e6492c7d382b.gif b/docs/pics/399b459d-db9e-4e77-b879-e6492c7d382b.gif deleted file mode 100644 index 66d52391..00000000 Binary files a/docs/pics/399b459d-db9e-4e77-b879-e6492c7d382b.gif and /dev/null differ diff --git a/docs/pics/39ccb299-ee99-4dd1-b8b4-2f9ec9495cb4.png b/docs/pics/39ccb299-ee99-4dd1-b8b4-2f9ec9495cb4.png deleted file mode 100644 index 1240d1f5..00000000 Binary files a/docs/pics/39ccb299-ee99-4dd1-b8b4-2f9ec9495cb4.png and /dev/null differ diff --git a/docs/pics/3be42601-9d33-4d29-8358-a9d16453af93.png b/docs/pics/3be42601-9d33-4d29-8358-a9d16453af93.png deleted file mode 100644 index ca17dae9..00000000 Binary files a/docs/pics/3be42601-9d33-4d29-8358-a9d16453af93.png and /dev/null differ diff --git a/docs/pics/3cd630ea-017c-488d-ad1d-732b4efeddf5.png b/docs/pics/3cd630ea-017c-488d-ad1d-732b4efeddf5.png deleted file mode 100644 index 9dc77733..00000000 Binary files a/docs/pics/3cd630ea-017c-488d-ad1d-732b4efeddf5.png and /dev/null differ diff --git a/docs/pics/3d5b828e-5c4d-48d8-a440-281e4a8e1c92.png b/docs/pics/3d5b828e-5c4d-48d8-a440-281e4a8e1c92.png deleted file mode 100644 index 5d9504ee..00000000 Binary files a/docs/pics/3d5b828e-5c4d-48d8-a440-281e4a8e1c92.png and /dev/null differ diff --git a/docs/pics/3ea280b5-be7d-471b-ac76-ff020384357c.gif b/docs/pics/3ea280b5-be7d-471b-ac76-ff020384357c.gif deleted file mode 100644 index 4c8540a9..00000000 Binary files a/docs/pics/3ea280b5-be7d-471b-ac76-ff020384357c.gif and /dev/null differ diff --git a/docs/pics/3fb5b255-b791-45b6-8754-325c8741855a.png b/docs/pics/3fb5b255-b791-45b6-8754-325c8741855a.png deleted file mode 100644 index fac97232..00000000 Binary files a/docs/pics/3fb5b255-b791-45b6-8754-325c8741855a.png and /dev/null differ diff --git a/docs/pics/40121fa5-cb5c-4add-9945-e087220cd039_200.png b/docs/pics/40121fa5-cb5c-4add-9945-e087220cd039_200.png deleted file mode 100644 index 91d510e7..00000000 Binary files a/docs/pics/40121fa5-cb5c-4add-9945-e087220cd039_200.png and /dev/null differ diff --git a/docs/pics/40c0c17e-bba6-4493-9857-147c0044a018.png b/docs/pics/40c0c17e-bba6-4493-9857-147c0044a018.png deleted file mode 100644 index 9182292c..00000000 Binary files a/docs/pics/40c0c17e-bba6-4493-9857-147c0044a018.png and /dev/null differ diff --git a/docs/pics/40c6570d-c1d7-4c38-843e-ba991b2328c2.png b/docs/pics/40c6570d-c1d7-4c38-843e-ba991b2328c2.png deleted file mode 100644 index 7274bedd..00000000 Binary files a/docs/pics/40c6570d-c1d7-4c38-843e-ba991b2328c2.png and /dev/null differ diff --git a/docs/pics/417bc315-4409-48c6-83e0-59e8d405429e.jpg b/docs/pics/417bc315-4409-48c6-83e0-59e8d405429e.jpg deleted file mode 100644 index 38ab13b7..00000000 Binary files a/docs/pics/417bc315-4409-48c6-83e0-59e8d405429e.jpg and /dev/null differ diff --git a/docs/pics/423f2a40-bee1-488e-b460-8e76c48ee560.png b/docs/pics/423f2a40-bee1-488e-b460-8e76c48ee560.png deleted file mode 100644 index b366f810..00000000 Binary files a/docs/pics/423f2a40-bee1-488e-b460-8e76c48ee560.png and /dev/null differ diff --git a/docs/pics/4240a69f-4d51-4d16-b797-2dfe110f30bd.png b/docs/pics/4240a69f-4d51-4d16-b797-2dfe110f30bd.png deleted file mode 100644 index d889e516..00000000 Binary files a/docs/pics/4240a69f-4d51-4d16-b797-2dfe110f30bd.png and /dev/null differ diff --git a/docs/pics/42430e94-3137-48c0-bdb6-3cebaf9102e3.jpg b/docs/pics/42430e94-3137-48c0-bdb6-3cebaf9102e3.jpg deleted file mode 100644 index 4a949dd8..00000000 Binary files a/docs/pics/42430e94-3137-48c0-bdb6-3cebaf9102e3.jpg and /dev/null differ diff --git a/docs/pics/424f34ab-a9fd-49a6-9969-d76b42251365.png b/docs/pics/424f34ab-a9fd-49a6-9969-d76b42251365.png deleted file mode 100644 index d5c1a58d..00000000 Binary files a/docs/pics/424f34ab-a9fd-49a6-9969-d76b42251365.png and /dev/null differ diff --git a/docs/pics/42661013-750f-420b-b3c1-437e9a11fb65.png b/docs/pics/42661013-750f-420b-b3c1-437e9a11fb65.png deleted file mode 100644 index 964f97f8..00000000 Binary files a/docs/pics/42661013-750f-420b-b3c1-437e9a11fb65.png and /dev/null differ diff --git a/docs/pics/437cb54c-5970-4ba9-b2ef-2541f7d6c81e.gif b/docs/pics/437cb54c-5970-4ba9-b2ef-2541f7d6c81e.gif deleted file mode 100644 index 7a188a57..00000000 Binary files a/docs/pics/437cb54c-5970-4ba9-b2ef-2541f7d6c81e.gif and /dev/null differ diff --git a/docs/pics/43d323ac-9f07-4e4a-a315-4eaf8c38766c.jpg b/docs/pics/43d323ac-9f07-4e4a-a315-4eaf8c38766c.jpg deleted file mode 100644 index d5504802..00000000 Binary files a/docs/pics/43d323ac-9f07-4e4a-a315-4eaf8c38766c.jpg and /dev/null differ diff --git a/docs/pics/44d33643-1004-43a3-b99a-4d688a08d0a1.png b/docs/pics/44d33643-1004-43a3-b99a-4d688a08d0a1.png deleted file mode 100644 index fc180089..00000000 Binary files a/docs/pics/44d33643-1004-43a3-b99a-4d688a08d0a1.png and /dev/null differ diff --git a/docs/pics/45016e98-6879-4709-8569-262b2d6d60b9.png b/docs/pics/45016e98-6879-4709-8569-262b2d6d60b9.png deleted file mode 100644 index 57da9786..00000000 Binary files a/docs/pics/45016e98-6879-4709-8569-262b2d6d60b9.png and /dev/null differ diff --git a/docs/pics/45be9587-6069-4ab7-b9ac-840db1a53744.jpg b/docs/pics/45be9587-6069-4ab7-b9ac-840db1a53744.jpg deleted file mode 100644 index 336ee59b..00000000 Binary files a/docs/pics/45be9587-6069-4ab7-b9ac-840db1a53744.jpg and /dev/null differ diff --git a/docs/pics/476329d4-e2ef-4f7b-8ac9-a52a6f784600.png b/docs/pics/476329d4-e2ef-4f7b-8ac9-a52a6f784600.png deleted file mode 100644 index a53d1307..00000000 Binary files a/docs/pics/476329d4-e2ef-4f7b-8ac9-a52a6f784600.png and /dev/null differ diff --git a/docs/pics/47d98583-8bb0-45cc-812d-47eefa0a4a40.jpg b/docs/pics/47d98583-8bb0-45cc-812d-47eefa0a4a40.jpg deleted file mode 100644 index f6ddd2c2..00000000 Binary files a/docs/pics/47d98583-8bb0-45cc-812d-47eefa0a4a40.jpg and /dev/null differ diff --git a/docs/pics/48517227-324c-4664-bd26-a2d2cffe2bfe.png b/docs/pics/48517227-324c-4664-bd26-a2d2cffe2bfe.png deleted file mode 100644 index ca11ce32..00000000 Binary files a/docs/pics/48517227-324c-4664-bd26-a2d2cffe2bfe.png and /dev/null differ diff --git a/docs/pics/485fdf34-ccf8-4185-97c6-17374ee719a0.png b/docs/pics/485fdf34-ccf8-4185-97c6-17374ee719a0.png deleted file mode 100644 index 7f842458..00000000 Binary files a/docs/pics/485fdf34-ccf8-4185-97c6-17374ee719a0.png and /dev/null differ diff --git a/docs/pics/48a934ff-a29b-434c-8e1d-8c8ec20cb91d.png b/docs/pics/48a934ff-a29b-434c-8e1d-8c8ec20cb91d.png deleted file mode 100644 index d9ef579a..00000000 Binary files a/docs/pics/48a934ff-a29b-434c-8e1d-8c8ec20cb91d.png and /dev/null differ diff --git a/docs/pics/48b1d459-8832-4e92-938a-728aae730739.jpg b/docs/pics/48b1d459-8832-4e92-938a-728aae730739.jpg deleted file mode 100644 index 8adfea82..00000000 Binary files a/docs/pics/48b1d459-8832-4e92-938a-728aae730739.jpg and /dev/null differ diff --git a/docs/pics/48d79be8-085b-4862-8a9d-18402eb93b31.png b/docs/pics/48d79be8-085b-4862-8a9d-18402eb93b31.png deleted file mode 100644 index 9b585629..00000000 Binary files a/docs/pics/48d79be8-085b-4862-8a9d-18402eb93b31.png and /dev/null differ diff --git a/docs/pics/49d2adc1-b28a-44bf-babb-d44993f4a2e3.gif b/docs/pics/49d2adc1-b28a-44bf-babb-d44993f4a2e3.gif deleted file mode 100644 index e2af5f10..00000000 Binary files a/docs/pics/49d2adc1-b28a-44bf-babb-d44993f4a2e3.gif and /dev/null differ diff --git a/docs/pics/4aa5e057-bc57-4719-ab57-c6fbc861c505.png b/docs/pics/4aa5e057-bc57-4719-ab57-c6fbc861c505.png deleted file mode 100644 index cf18debb..00000000 Binary files a/docs/pics/4aa5e057-bc57-4719-ab57-c6fbc861c505.png and /dev/null differ diff --git a/docs/pics/4ab87717-e264-4232-825d-8aaf08f14e8b.jpg b/docs/pics/4ab87717-e264-4232-825d-8aaf08f14e8b.jpg deleted file mode 100644 index b5333a2b..00000000 Binary files a/docs/pics/4ab87717-e264-4232-825d-8aaf08f14e8b.jpg and /dev/null differ diff --git a/docs/pics/4b2ae78c-e254-44df-9e37-578e2f2bef52.jpg b/docs/pics/4b2ae78c-e254-44df-9e37-578e2f2bef52.jpg deleted file mode 100644 index 3669e15b..00000000 Binary files a/docs/pics/4b2ae78c-e254-44df-9e37-578e2f2bef52.jpg and /dev/null differ diff --git a/docs/pics/4bf5e3fb-a285-4138-b3b6-780956eb1df1.gif b/docs/pics/4bf5e3fb-a285-4138-b3b6-780956eb1df1.gif deleted file mode 100644 index e2b8d75e..00000000 Binary files a/docs/pics/4bf5e3fb-a285-4138-b3b6-780956eb1df1.gif and /dev/null differ diff --git a/docs/pics/4bf8d0ba-36f0-459e-83a0-f15278a5a157.png b/docs/pics/4bf8d0ba-36f0-459e-83a0-f15278a5a157.png deleted file mode 100644 index 4b485ecd..00000000 Binary files a/docs/pics/4bf8d0ba-36f0-459e-83a0-f15278a5a157.png and /dev/null differ diff --git a/docs/pics/4c457532-550b-4eca-b881-037b84b4934b.jpg b/docs/pics/4c457532-550b-4eca-b881-037b84b4934b.jpg deleted file mode 100644 index 0c03ab09..00000000 Binary files a/docs/pics/4c457532-550b-4eca-b881-037b84b4934b.jpg and /dev/null differ diff --git a/docs/pics/4cf711a8-7ab2-4152-b85c-d5c226733807.png b/docs/pics/4cf711a8-7ab2-4152-b85c-d5c226733807.png deleted file mode 100644 index 03d1e447..00000000 Binary files a/docs/pics/4cf711a8-7ab2-4152-b85c-d5c226733807.png and /dev/null differ diff --git a/docs/pics/4e2485e4-34bd-4967-9f02-0c093b797aaa.png b/docs/pics/4e2485e4-34bd-4967-9f02-0c093b797aaa.png deleted file mode 100644 index a5643118..00000000 Binary files a/docs/pics/4e2485e4-34bd-4967-9f02-0c093b797aaa.png and /dev/null differ diff --git a/docs/pics/4e93f7d4-2623-4129-a939-59051256561e.png b/docs/pics/4e93f7d4-2623-4129-a939-59051256561e.png deleted file mode 100644 index b48fb693..00000000 Binary files a/docs/pics/4e93f7d4-2623-4129-a939-59051256561e.png and /dev/null differ diff --git a/docs/pics/50678f34-694f-45a4-91c6-34d985c83fee.png b/docs/pics/50678f34-694f-45a4-91c6-34d985c83fee.png deleted file mode 100644 index 3af4acb0..00000000 Binary files a/docs/pics/50678f34-694f-45a4-91c6-34d985c83fee.png and /dev/null differ diff --git a/docs/pics/50831a6f-2777-46ea-a571-29f23c85cc21.jpg b/docs/pics/50831a6f-2777-46ea-a571-29f23c85cc21.jpg deleted file mode 100644 index 8bd241bc..00000000 Binary files a/docs/pics/50831a6f-2777-46ea-a571-29f23c85cc21.jpg and /dev/null differ diff --git a/docs/pics/508c6e52-9f93-44ed-b6b9-e69050e14807.jpg b/docs/pics/508c6e52-9f93-44ed-b6b9-e69050e14807.jpg deleted file mode 100644 index f7f3ca5b..00000000 Binary files a/docs/pics/508c6e52-9f93-44ed-b6b9-e69050e14807.jpg and /dev/null differ diff --git a/docs/pics/51e2ed95-65b8-4ae9-8af3-65602d452a25.jpg b/docs/pics/51e2ed95-65b8-4ae9-8af3-65602d452a25.jpg deleted file mode 100644 index 4627281d..00000000 Binary files a/docs/pics/51e2ed95-65b8-4ae9-8af3-65602d452a25.jpg and /dev/null differ diff --git a/docs/pics/52a7744f-5bce-4ff3-a6f0-8449334d9f3d.png b/docs/pics/52a7744f-5bce-4ff3-a6f0-8449334d9f3d.png deleted file mode 100644 index 5770e1be..00000000 Binary files a/docs/pics/52a7744f-5bce-4ff3-a6f0-8449334d9f3d.png and /dev/null differ diff --git a/docs/pics/530764d5-f67f-47a2-8df4-57e8646e1400.png b/docs/pics/530764d5-f67f-47a2-8df4-57e8646e1400.png deleted file mode 100644 index 656e6501..00000000 Binary files a/docs/pics/530764d5-f67f-47a2-8df4-57e8646e1400.png and /dev/null differ diff --git a/docs/pics/5359cbf5-5a79-4874-9b17-f23c53c2cb80.jpg b/docs/pics/5359cbf5-5a79-4874-9b17-f23c53c2cb80.jpg deleted file mode 100644 index d0f87699..00000000 Binary files a/docs/pics/5359cbf5-5a79-4874-9b17-f23c53c2cb80.jpg and /dev/null differ diff --git a/docs/pics/53cd9ade-b0a6-4399-b4de-7f1fbd06cdfb.png b/docs/pics/53cd9ade-b0a6-4399-b4de-7f1fbd06cdfb.png deleted file mode 100644 index 2666f9c2..00000000 Binary files a/docs/pics/53cd9ade-b0a6-4399-b4de-7f1fbd06cdfb.png and /dev/null differ diff --git a/docs/pics/55dc4e84-573d-4c13-a765-52ed1dd251f9.png b/docs/pics/55dc4e84-573d-4c13-a765-52ed1dd251f9.png deleted file mode 100644 index d5194f55..00000000 Binary files a/docs/pics/55dc4e84-573d-4c13-a765-52ed1dd251f9.png and /dev/null differ diff --git a/docs/pics/562f2844-d77c-40e0-887a-28a7128abd42.png b/docs/pics/562f2844-d77c-40e0-887a-28a7128abd42.png deleted file mode 100644 index 4fa7c1fd..00000000 Binary files a/docs/pics/562f2844-d77c-40e0-887a-28a7128abd42.png and /dev/null differ diff --git a/docs/pics/5778d113-8e13-4c53-b5bf-801e58080b97.png b/docs/pics/5778d113-8e13-4c53-b5bf-801e58080b97.png deleted file mode 100644 index b0f94a99..00000000 Binary files a/docs/pics/5778d113-8e13-4c53-b5bf-801e58080b97.png and /dev/null differ diff --git a/docs/pics/58b70113-3876-49af-85a9-68eb00a72d59.jpg b/docs/pics/58b70113-3876-49af-85a9-68eb00a72d59.jpg deleted file mode 100644 index 39713d40..00000000 Binary files a/docs/pics/58b70113-3876-49af-85a9-68eb00a72d59.jpg and /dev/null differ diff --git a/docs/pics/5942debd-fc00-477a-b390-7c5692cc8070.jpg b/docs/pics/5942debd-fc00-477a-b390-7c5692cc8070.jpg deleted file mode 100644 index 8f4dd78a..00000000 Binary files a/docs/pics/5942debd-fc00-477a-b390-7c5692cc8070.jpg and /dev/null differ diff --git a/docs/pics/5b718e86-7102-4bb6-8ca5-d1dd791530c5.png b/docs/pics/5b718e86-7102-4bb6-8ca5-d1dd791530c5.png deleted file mode 100644 index 6a611257..00000000 Binary files a/docs/pics/5b718e86-7102-4bb6-8ca5-d1dd791530c5.png and /dev/null differ diff --git a/docs/pics/5bb1b38a-527e-4802-a385-267dadbd30ba.png b/docs/pics/5bb1b38a-527e-4802-a385-267dadbd30ba.png deleted file mode 100644 index fb1a182c..00000000 Binary files a/docs/pics/5bb1b38a-527e-4802-a385-267dadbd30ba.png and /dev/null differ diff --git a/docs/pics/5c638d59-d4ae-4ba4-ad44-80bdc30f38dd.jpg b/docs/pics/5c638d59-d4ae-4ba4-ad44-80bdc30f38dd.jpg deleted file mode 100644 index 25fbc7e6..00000000 Binary files a/docs/pics/5c638d59-d4ae-4ba4-ad44-80bdc30f38dd.jpg and /dev/null differ diff --git a/docs/pics/5ea609cb-8ad4-4c4c-aee6-45a40a81794a.jpg b/docs/pics/5ea609cb-8ad4-4c4c-aee6-45a40a81794a.jpg deleted file mode 100644 index 331d33df..00000000 Binary files a/docs/pics/5ea609cb-8ad4-4c4c-aee6-45a40a81794a.jpg and /dev/null differ diff --git a/docs/pics/5f1cb999-cb9a-4f6c-a0af-d90377295ab8.png b/docs/pics/5f1cb999-cb9a-4f6c-a0af-d90377295ab8.png deleted file mode 100644 index a3fdc228..00000000 Binary files a/docs/pics/5f1cb999-cb9a-4f6c-a0af-d90377295ab8.png and /dev/null differ diff --git a/docs/pics/5f5c22d5-9c0e-49e1-b5b0-6cc7032724d4.png b/docs/pics/5f5c22d5-9c0e-49e1-b5b0-6cc7032724d4.png deleted file mode 100644 index 72722db4..00000000 Binary files a/docs/pics/5f5c22d5-9c0e-49e1-b5b0-6cc7032724d4.png and /dev/null differ diff --git a/docs/pics/5f5ef0b6-98ea-497c-a007-f6c55288eab1.png b/docs/pics/5f5ef0b6-98ea-497c-a007-f6c55288eab1.png deleted file mode 100644 index a3ea0a24..00000000 Binary files a/docs/pics/5f5ef0b6-98ea-497c-a007-f6c55288eab1.png and /dev/null differ diff --git a/docs/pics/600e9c75-5033-4dad-ae2b-930957db638e.png b/docs/pics/600e9c75-5033-4dad-ae2b-930957db638e.png deleted file mode 100644 index 38425801..00000000 Binary files a/docs/pics/600e9c75-5033-4dad-ae2b-930957db638e.png and /dev/null differ diff --git a/docs/pics/6019b2db-bc3e-4408-b6d8-96025f4481d6.png b/docs/pics/6019b2db-bc3e-4408-b6d8-96025f4481d6.png deleted file mode 100644 index 79388c09..00000000 Binary files a/docs/pics/6019b2db-bc3e-4408-b6d8-96025f4481d6.png and /dev/null differ diff --git a/docs/pics/603dbb49-dac5-4825-9694-5f1d65cefd44.png b/docs/pics/603dbb49-dac5-4825-9694-5f1d65cefd44.png deleted file mode 100644 index 61622713..00000000 Binary files a/docs/pics/603dbb49-dac5-4825-9694-5f1d65cefd44.png and /dev/null differ diff --git a/docs/pics/6234eb3d-ccf2-4987-a724-235aef6957b1.png b/docs/pics/6234eb3d-ccf2-4987-a724-235aef6957b1.png deleted file mode 100644 index f259d26e..00000000 Binary files a/docs/pics/6234eb3d-ccf2-4987-a724-235aef6957b1.png and /dev/null differ diff --git a/docs/pics/6270c216-7ec0-4db7-94de-0003bce37cd2.png b/docs/pics/6270c216-7ec0-4db7-94de-0003bce37cd2.png deleted file mode 100644 index eaa364e8..00000000 Binary files a/docs/pics/6270c216-7ec0-4db7-94de-0003bce37cd2.png and /dev/null differ diff --git a/docs/pics/6283be2a-814a-4a10-84bf-9592533fe6bc.png b/docs/pics/6283be2a-814a-4a10-84bf-9592533fe6bc.png deleted file mode 100644 index 07b89658..00000000 Binary files a/docs/pics/6283be2a-814a-4a10-84bf-9592533fe6bc.png and /dev/null differ diff --git a/docs/pics/62e0dd4f-44c3-43ee-bb6e-fedb9e068519.png b/docs/pics/62e0dd4f-44c3-43ee-bb6e-fedb9e068519.png deleted file mode 100644 index 3a41cdce..00000000 Binary files a/docs/pics/62e0dd4f-44c3-43ee-bb6e-fedb9e068519.png and /dev/null differ diff --git a/docs/pics/62e77997-6957-4b68-8d12-bfd609bb2c68.jpg b/docs/pics/62e77997-6957-4b68-8d12-bfd609bb2c68.jpg deleted file mode 100644 index 2c6a953e..00000000 Binary files a/docs/pics/62e77997-6957-4b68-8d12-bfd609bb2c68.jpg and /dev/null differ diff --git a/docs/pics/63c2909f-0c5f-496f-9fe5-ee9176b31aba.jpg b/docs/pics/63c2909f-0c5f-496f-9fe5-ee9176b31aba.jpg deleted file mode 100644 index 92d9f59b..00000000 Binary files a/docs/pics/63c2909f-0c5f-496f-9fe5-ee9176b31aba.jpg and /dev/null differ diff --git a/docs/pics/63c8ffea-a9f2-4ebe-97d1-d71be71246f9.jpg b/docs/pics/63c8ffea-a9f2-4ebe-97d1-d71be71246f9.jpg deleted file mode 100644 index 7aa6788c..00000000 Binary files a/docs/pics/63c8ffea-a9f2-4ebe-97d1-d71be71246f9.jpg and /dev/null differ diff --git a/docs/pics/658fc5e7-79c0-4247-9445-d69bf194c539.png b/docs/pics/658fc5e7-79c0-4247-9445-d69bf194c539.png deleted file mode 100644 index f1181b86..00000000 Binary files a/docs/pics/658fc5e7-79c0-4247-9445-d69bf194c539.png and /dev/null differ diff --git a/docs/pics/66192382-558b-4b05-a35d-ac4a2b1a9811.jpg b/docs/pics/66192382-558b-4b05-a35d-ac4a2b1a9811.jpg deleted file mode 100644 index eec226c5..00000000 Binary files a/docs/pics/66192382-558b-4b05-a35d-ac4a2b1a9811.jpg and /dev/null differ diff --git a/docs/pics/66402828-fb2b-418f-83f6-82153491bcfe.jpg b/docs/pics/66402828-fb2b-418f-83f6-82153491bcfe.jpg deleted file mode 100644 index be5ad357..00000000 Binary files a/docs/pics/66402828-fb2b-418f-83f6-82153491bcfe.jpg and /dev/null differ diff --git a/docs/pics/66a01953-5303-43b1-8646-0c77b825e980.png b/docs/pics/66a01953-5303-43b1-8646-0c77b825e980.png deleted file mode 100644 index 48a120be..00000000 Binary files a/docs/pics/66a01953-5303-43b1-8646-0c77b825e980.png and /dev/null differ diff --git a/docs/pics/66a6899d-c6b0-4a47-8569-9d08f0baf86c.png b/docs/pics/66a6899d-c6b0-4a47-8569-9d08f0baf86c.png deleted file mode 100644 index a8536c94..00000000 Binary files a/docs/pics/66a6899d-c6b0-4a47-8569-9d08f0baf86c.png and /dev/null differ diff --git a/docs/pics/66ae164c-ad47-4905-895e-51fe38ce797a.png b/docs/pics/66ae164c-ad47-4905-895e-51fe38ce797a.png deleted file mode 100644 index 17210ca8..00000000 Binary files a/docs/pics/66ae164c-ad47-4905-895e-51fe38ce797a.png and /dev/null differ diff --git a/docs/pics/66d00642-ce37-466c-8f7a-143d0bf84cd6.png b/docs/pics/66d00642-ce37-466c-8f7a-143d0bf84cd6.png deleted file mode 100644 index be928f70..00000000 Binary files a/docs/pics/66d00642-ce37-466c-8f7a-143d0bf84cd6.png and /dev/null differ diff --git a/docs/pics/6729baa0-57d7-4817-b3aa-518cbccf824c.jpg b/docs/pics/6729baa0-57d7-4817-b3aa-518cbccf824c.jpg deleted file mode 100644 index 0020b3d7..00000000 Binary files a/docs/pics/6729baa0-57d7-4817-b3aa-518cbccf824c.jpg and /dev/null differ diff --git a/docs/pics/67582ade-d44a-46a6-8757-3c1296cc1ef9.png b/docs/pics/67582ade-d44a-46a6-8757-3c1296cc1ef9.png deleted file mode 100644 index 2d42dcba..00000000 Binary files a/docs/pics/67582ade-d44a-46a6-8757-3c1296cc1ef9.png and /dev/null differ diff --git a/docs/pics/6782674c-1bfe-4879-af39-e9d722a95d39.png b/docs/pics/6782674c-1bfe-4879-af39-e9d722a95d39.png deleted file mode 100644 index ca2b35e8..00000000 Binary files a/docs/pics/6782674c-1bfe-4879-af39-e9d722a95d39.png and /dev/null differ diff --git a/docs/pics/67bf5487-c45d-49b6-b9c0-a058d8c68902.png b/docs/pics/67bf5487-c45d-49b6-b9c0-a058d8c68902.png deleted file mode 100644 index 5de38f69..00000000 Binary files a/docs/pics/67bf5487-c45d-49b6-b9c0-a058d8c68902.png and /dev/null differ diff --git a/docs/pics/68b110b9-76c6-4ee2-b541-4145e65adb3e.jpg b/docs/pics/68b110b9-76c6-4ee2-b541-4145e65adb3e.jpg deleted file mode 100644 index 324b7fec..00000000 Binary files a/docs/pics/68b110b9-76c6-4ee2-b541-4145e65adb3e.jpg and /dev/null differ diff --git a/docs/pics/691f11eb-31a7-46be-9de1-61f433c4b3c7.png b/docs/pics/691f11eb-31a7-46be-9de1-61f433c4b3c7.png deleted file mode 100644 index 59f47a8c..00000000 Binary files a/docs/pics/691f11eb-31a7-46be-9de1-61f433c4b3c7.png and /dev/null differ diff --git a/docs/pics/6980aef0-debe-4b4b-8da5-8b1befbc1408.gif b/docs/pics/6980aef0-debe-4b4b-8da5-8b1befbc1408.gif deleted file mode 100644 index 05704a44..00000000 Binary files a/docs/pics/6980aef0-debe-4b4b-8da5-8b1befbc1408.gif and /dev/null differ diff --git a/docs/pics/69d6c38d-1dec-4f72-ae60-60dbc10e9d15.png b/docs/pics/69d6c38d-1dec-4f72-ae60-60dbc10e9d15.png deleted file mode 100644 index 84611618..00000000 Binary files a/docs/pics/69d6c38d-1dec-4f72-ae60-60dbc10e9d15.png and /dev/null differ diff --git a/docs/pics/6a88a398-c494-41f5-bb62-9f7fb811df7c.jpg b/docs/pics/6a88a398-c494-41f5-bb62-9f7fb811df7c.jpg deleted file mode 100644 index 1b1c0bb3..00000000 Binary files a/docs/pics/6a88a398-c494-41f5-bb62-9f7fb811df7c.jpg and /dev/null differ diff --git a/docs/pics/6b504f1f-bf76-4aab-a146-a9c7a58c2029.png b/docs/pics/6b504f1f-bf76-4aab-a146-a9c7a58c2029.png deleted file mode 100644 index b613aa38..00000000 Binary files a/docs/pics/6b504f1f-bf76-4aab-a146-a9c7a58c2029.png and /dev/null differ diff --git a/docs/pics/6b833bc2-517a-4270-8a5e-0a5f6df8cd96.png b/docs/pics/6b833bc2-517a-4270-8a5e-0a5f6df8cd96.png deleted file mode 100644 index 05faa726..00000000 Binary files a/docs/pics/6b833bc2-517a-4270-8a5e-0a5f6df8cd96.png and /dev/null differ diff --git a/docs/pics/6cfdf7b0-ea9d-4371-893f-76e78f004223.png b/docs/pics/6cfdf7b0-ea9d-4371-893f-76e78f004223.png deleted file mode 100644 index adac7ef4..00000000 Binary files a/docs/pics/6cfdf7b0-ea9d-4371-893f-76e78f004223.png and /dev/null differ diff --git a/docs/pics/6fb7cf89-71b3-48c1-bc6a-5110e1f1fc15.gif b/docs/pics/6fb7cf89-71b3-48c1-bc6a-5110e1f1fc15.gif deleted file mode 100644 index b9f2cbdc..00000000 Binary files a/docs/pics/6fb7cf89-71b3-48c1-bc6a-5110e1f1fc15.gif and /dev/null differ diff --git a/docs/pics/6fda1dc7-5c74-49c1-bb79-237a77e43a43.png b/docs/pics/6fda1dc7-5c74-49c1-bb79-237a77e43a43.png deleted file mode 100644 index dec1bde8..00000000 Binary files a/docs/pics/6fda1dc7-5c74-49c1-bb79-237a77e43a43.png and /dev/null differ diff --git a/docs/pics/7002c01b-1ed5-475a-9e5f-5fc8a4cdbcc0.jpg b/docs/pics/7002c01b-1ed5-475a-9e5f-5fc8a4cdbcc0.jpg deleted file mode 100644 index 4b894134..00000000 Binary files a/docs/pics/7002c01b-1ed5-475a-9e5f-5fc8a4cdbcc0.jpg and /dev/null differ diff --git a/docs/pics/71550414107576.gif b/docs/pics/71550414107576.gif deleted file mode 100644 index 874dc8e3..00000000 Binary files a/docs/pics/71550414107576.gif and /dev/null differ diff --git a/docs/pics/71b97a50-a49f-4f1a-81d1-48c3364d61b3.png b/docs/pics/71b97a50-a49f-4f1a-81d1-48c3364d61b3.png deleted file mode 100644 index 5cd92145..00000000 Binary files a/docs/pics/71b97a50-a49f-4f1a-81d1-48c3364d61b3.png and /dev/null differ diff --git a/docs/pics/72a01242-e6b4-46c5-a285-24e754d63093.png b/docs/pics/72a01242-e6b4-46c5-a285-24e754d63093.png deleted file mode 100644 index 362910ac..00000000 Binary files a/docs/pics/72a01242-e6b4-46c5-a285-24e754d63093.png and /dev/null differ diff --git a/docs/pics/72aac98a-d5df-4bfa-a71a-4bb16a87474c.png b/docs/pics/72aac98a-d5df-4bfa-a71a-4bb16a87474c.png deleted file mode 100644 index 125a804c..00000000 Binary files a/docs/pics/72aac98a-d5df-4bfa-a71a-4bb16a87474c.png and /dev/null differ diff --git a/docs/pics/72be01cd-41ae-45f7-99b9-a8d284e44dd4.png b/docs/pics/72be01cd-41ae-45f7-99b9-a8d284e44dd4.png deleted file mode 100644 index ad0ae80d..00000000 Binary files a/docs/pics/72be01cd-41ae-45f7-99b9-a8d284e44dd4.png and /dev/null differ diff --git a/docs/pics/72ee7e9a-194d-42e9-b4d7-29c23417ca18.png b/docs/pics/72ee7e9a-194d-42e9-b4d7-29c23417ca18.png deleted file mode 100644 index 2ad89c0a..00000000 Binary files a/docs/pics/72ee7e9a-194d-42e9-b4d7-29c23417ca18.png and /dev/null differ diff --git a/docs/pics/73403d84-d921-49f1-93a9-d8fe050f3497.png b/docs/pics/73403d84-d921-49f1-93a9-d8fe050f3497.png deleted file mode 100644 index 09e4a751..00000000 Binary files a/docs/pics/73403d84-d921-49f1-93a9-d8fe050f3497.png and /dev/null differ diff --git a/docs/pics/74dc31eb-6baa-47ea-ab1c-d27a0ca35093.png b/docs/pics/74dc31eb-6baa-47ea-ab1c-d27a0ca35093.png deleted file mode 100644 index dae4c8f4..00000000 Binary files a/docs/pics/74dc31eb-6baa-47ea-ab1c-d27a0ca35093.png and /dev/null differ diff --git a/docs/pics/75184b58-c627-4edc-8dcf-605762ebb733.png b/docs/pics/75184b58-c627-4edc-8dcf-605762ebb733.png deleted file mode 100644 index ef2e7411..00000000 Binary files a/docs/pics/75184b58-c627-4edc-8dcf-605762ebb733.png and /dev/null differ diff --git a/docs/pics/759013d7-61d8-4509-897a-d75af598a236.png b/docs/pics/759013d7-61d8-4509-897a-d75af598a236.png deleted file mode 100644 index 7befb908..00000000 Binary files a/docs/pics/759013d7-61d8-4509-897a-d75af598a236.png and /dev/null differ diff --git a/docs/pics/76a49594323247f21c9b3a69945445ee.png b/docs/pics/76a49594323247f21c9b3a69945445ee.png deleted file mode 100644 index 00300dc3..00000000 Binary files a/docs/pics/76a49594323247f21c9b3a69945445ee.png and /dev/null differ diff --git a/docs/pics/76dc7769-1aac-4888-9bea-064f1caa8e77.jpg b/docs/pics/76dc7769-1aac-4888-9bea-064f1caa8e77.jpg deleted file mode 100644 index 642aba6b..00000000 Binary files a/docs/pics/76dc7769-1aac-4888-9bea-064f1caa8e77.jpg and /dev/null differ diff --git a/docs/pics/774d756b-902a-41a3-a3fd-81ca3ef688dc.png b/docs/pics/774d756b-902a-41a3-a3fd-81ca3ef688dc.png deleted file mode 100644 index 0ef06be5..00000000 Binary files a/docs/pics/774d756b-902a-41a3-a3fd-81ca3ef688dc.png and /dev/null differ diff --git a/docs/pics/77931a4b-72ba-4016-827d-84b9a6845a51.png b/docs/pics/77931a4b-72ba-4016-827d-84b9a6845a51.png deleted file mode 100644 index 8fb36a37..00000000 Binary files a/docs/pics/77931a4b-72ba-4016-827d-84b9a6845a51.png and /dev/null differ diff --git a/docs/pics/7818c574-97a8-48db-8e62-8bfb030b02ba.png b/docs/pics/7818c574-97a8-48db-8e62-8bfb030b02ba.png deleted file mode 100644 index 46c887bf..00000000 Binary files a/docs/pics/7818c574-97a8-48db-8e62-8bfb030b02ba.png and /dev/null differ diff --git a/docs/pics/794239e3-4baf-4aad-92df-f02f59b2a6fe.png b/docs/pics/794239e3-4baf-4aad-92df-f02f59b2a6fe.png deleted file mode 100644 index b6e54e26..00000000 Binary files a/docs/pics/794239e3-4baf-4aad-92df-f02f59b2a6fe.png and /dev/null differ diff --git a/docs/pics/79c6f036-bde6-4393-85a3-ef36a0327bd2.png b/docs/pics/79c6f036-bde6-4393-85a3-ef36a0327bd2.png deleted file mode 100644 index cd072555..00000000 Binary files a/docs/pics/79c6f036-bde6-4393-85a3-ef36a0327bd2.png and /dev/null differ diff --git a/docs/pics/79df886f-fdc3-4020-a07f-c991bb58e0d8.png b/docs/pics/79df886f-fdc3-4020-a07f-c991bb58e0d8.png deleted file mode 100644 index 2c8b681b..00000000 Binary files a/docs/pics/79df886f-fdc3-4020-a07f-c991bb58e0d8.png and /dev/null differ diff --git a/docs/pics/7a29acce-f243-4914-9f00-f2988c528412.jpg b/docs/pics/7a29acce-f243-4914-9f00-f2988c528412.jpg deleted file mode 100644 index bc671f24..00000000 Binary files a/docs/pics/7a29acce-f243-4914-9f00-f2988c528412.jpg and /dev/null differ diff --git a/docs/pics/7a3215ec-6fb7-4935-8b0d-cb408208f7cb.png b/docs/pics/7a3215ec-6fb7-4935-8b0d-cb408208f7cb.png deleted file mode 100644 index 6ddfe7ba..00000000 Binary files a/docs/pics/7a3215ec-6fb7-4935-8b0d-cb408208f7cb.png and /dev/null differ diff --git a/docs/pics/7a3c6a30-c735-4edb-8115-337288a4f0f2.jpg b/docs/pics/7a3c6a30-c735-4edb-8115-337288a4f0f2.jpg deleted file mode 100644 index 23f82178..00000000 Binary files a/docs/pics/7a3c6a30-c735-4edb-8115-337288a4f0f2.jpg and /dev/null differ diff --git a/docs/pics/7a85e285-e152-4116-b6dc-3fab27ba9437.jpg b/docs/pics/7a85e285-e152-4116-b6dc-3fab27ba9437.jpg deleted file mode 100644 index 6ad6d641..00000000 Binary files a/docs/pics/7a85e285-e152-4116-b6dc-3fab27ba9437.jpg and /dev/null differ diff --git a/docs/pics/7b281b1e-0595-402b-ae35-8c91084c33c1.png b/docs/pics/7b281b1e-0595-402b-ae35-8c91084c33c1.png deleted file mode 100644 index 9308ecb6..00000000 Binary files a/docs/pics/7b281b1e-0595-402b-ae35-8c91084c33c1.png and /dev/null differ diff --git a/docs/pics/7b3efa99-d306-4982-8cfb-e7153c33aab4.png b/docs/pics/7b3efa99-d306-4982-8cfb-e7153c33aab4.png deleted file mode 100644 index 21aafd0a..00000000 Binary files a/docs/pics/7b3efa99-d306-4982-8cfb-e7153c33aab4.png and /dev/null differ diff --git a/docs/pics/7bd202a7-93d4-4f3a-a878-af68ae25539a.png b/docs/pics/7bd202a7-93d4-4f3a-a878-af68ae25539a.png deleted file mode 100644 index d325c907..00000000 Binary files a/docs/pics/7bd202a7-93d4-4f3a-a878-af68ae25539a.png and /dev/null differ diff --git a/docs/pics/7c349b91-050b-4d72-a7f8-ec86320307ea.png b/docs/pics/7c349b91-050b-4d72-a7f8-ec86320307ea.png deleted file mode 100644 index d2f9705e..00000000 Binary files a/docs/pics/7c349b91-050b-4d72-a7f8-ec86320307ea.png and /dev/null differ diff --git a/docs/pics/7c54de21-e2ff-402e-bc42-4037de1c1592.png b/docs/pics/7c54de21-e2ff-402e-bc42-4037de1c1592.png deleted file mode 100644 index 5f493376..00000000 Binary files a/docs/pics/7c54de21-e2ff-402e-bc42-4037de1c1592.png and /dev/null differ diff --git a/docs/pics/7d97dde0-0695-4707-bb68-e6c13a2e1b45.png b/docs/pics/7d97dde0-0695-4707-bb68-e6c13a2e1b45.png deleted file mode 100644 index d1ac27c7..00000000 Binary files a/docs/pics/7d97dde0-0695-4707-bb68-e6c13a2e1b45.png and /dev/null differ diff --git a/docs/pics/7ec9d619-fa60-4a2b-95aa-bf1a62aad408.jpg b/docs/pics/7ec9d619-fa60-4a2b-95aa-bf1a62aad408.jpg deleted file mode 100644 index 5232e7dd..00000000 Binary files a/docs/pics/7ec9d619-fa60-4a2b-95aa-bf1a62aad408.jpg and /dev/null differ diff --git a/docs/pics/7fffa4b8-b36d-471f-ad0c-a88ee763bb76.png b/docs/pics/7fffa4b8-b36d-471f-ad0c-a88ee763bb76.png deleted file mode 100644 index d853302e..00000000 Binary files a/docs/pics/7fffa4b8-b36d-471f-ad0c-a88ee763bb76.png and /dev/null differ diff --git a/docs/pics/8006a450-6c2f-498c-a928-c927f758b1d0.png b/docs/pics/8006a450-6c2f-498c-a928-c927f758b1d0.png deleted file mode 100644 index ac453eeb..00000000 Binary files a/docs/pics/8006a450-6c2f-498c-a928-c927f758b1d0.png and /dev/null differ diff --git a/docs/pics/807f4258-dba8-4c54-9c3c-a707c7ccffa2.jpg b/docs/pics/807f4258-dba8-4c54-9c3c-a707c7ccffa2.jpg deleted file mode 100644 index 047f619d..00000000 Binary files a/docs/pics/807f4258-dba8-4c54-9c3c-a707c7ccffa2.jpg and /dev/null differ diff --git a/docs/pics/80804f52-8815-4096-b506-48eef3eed5c6.png b/docs/pics/80804f52-8815-4096-b506-48eef3eed5c6.png deleted file mode 100644 index 7e3234c4..00000000 Binary files a/docs/pics/80804f52-8815-4096-b506-48eef3eed5c6.png and /dev/null differ diff --git a/docs/pics/81538cd5-1bcf-4e31-86e5-e198df1e013b.jpg b/docs/pics/81538cd5-1bcf-4e31-86e5-e198df1e013b.jpg deleted file mode 100644 index ecf6a7d0..00000000 Binary files a/docs/pics/81538cd5-1bcf-4e31-86e5-e198df1e013b.jpg and /dev/null differ diff --git a/docs/pics/82cfda3b-b53b-4c89-9fdb-26dd2db0cd02.jpg b/docs/pics/82cfda3b-b53b-4c89-9fdb-26dd2db0cd02.jpg deleted file mode 100644 index 68829f1e..00000000 Binary files a/docs/pics/82cfda3b-b53b-4c89-9fdb-26dd2db0cd02.jpg and /dev/null differ diff --git a/docs/pics/83185315-793a-453a-a927-5e8d92b5c0ef.jpg b/docs/pics/83185315-793a-453a-a927-5e8d92b5c0ef.jpg deleted file mode 100644 index 48a52864..00000000 Binary files a/docs/pics/83185315-793a-453a-a927-5e8d92b5c0ef.jpg and /dev/null differ diff --git a/docs/pics/83acbb02-872a-4178-b22a-c89c3cb60263.jpg b/docs/pics/83acbb02-872a-4178-b22a-c89c3cb60263.jpg deleted file mode 100644 index af346a0f..00000000 Binary files a/docs/pics/83acbb02-872a-4178-b22a-c89c3cb60263.jpg and /dev/null differ diff --git a/docs/pics/83d466bd-946b-4430-854a-cf7b0696d4c8.jpg b/docs/pics/83d466bd-946b-4430-854a-cf7b0696d4c8.jpg deleted file mode 100644 index ece6156c..00000000 Binary files a/docs/pics/83d466bd-946b-4430-854a-cf7b0696d4c8.jpg and /dev/null differ diff --git a/docs/pics/83d909d2-3858-4fe1-8ff4-16471db0b180.png b/docs/pics/83d909d2-3858-4fe1-8ff4-16471db0b180.png deleted file mode 100644 index 5904529b..00000000 Binary files a/docs/pics/83d909d2-3858-4fe1-8ff4-16471db0b180.png and /dev/null differ diff --git a/docs/pics/8441b2c4-dca7-4d6b-8efb-f22efccaf331.png b/docs/pics/8441b2c4-dca7-4d6b-8efb-f22efccaf331.png deleted file mode 100644 index 376c348c..00000000 Binary files a/docs/pics/8441b2c4-dca7-4d6b-8efb-f22efccaf331.png and /dev/null differ diff --git a/docs/pics/8442519f-0b4d-48f4-8229-56f984363c69.png b/docs/pics/8442519f-0b4d-48f4-8229-56f984363c69.png deleted file mode 100644 index b8290f0b..00000000 Binary files a/docs/pics/8442519f-0b4d-48f4-8229-56f984363c69.png and /dev/null differ diff --git a/docs/pics/84a5b15a-86c5-4d8e-9439-d9fd5a4699a1.jpg b/docs/pics/84a5b15a-86c5-4d8e-9439-d9fd5a4699a1.jpg deleted file mode 100644 index 22bf89a3..00000000 Binary files a/docs/pics/84a5b15a-86c5-4d8e-9439-d9fd5a4699a1.jpg and /dev/null differ diff --git a/docs/pics/85c05fb1-5546-4c50-9221-21f231cdc8c5.jpg b/docs/pics/85c05fb1-5546-4c50-9221-21f231cdc8c5.jpg deleted file mode 100644 index 4b911193..00000000 Binary files a/docs/pics/85c05fb1-5546-4c50-9221-21f231cdc8c5.jpg and /dev/null differ diff --git a/docs/pics/8668a3e1-c9c7-4fcb-98b2-a96a5d841579.png b/docs/pics/8668a3e1-c9c7-4fcb-98b2-a96a5d841579.png deleted file mode 100644 index 02ead80d..00000000 Binary files a/docs/pics/8668a3e1-c9c7-4fcb-98b2-a96a5d841579.png and /dev/null differ diff --git a/docs/pics/867e93eb-3161-4f39-b2d2-c0cd3788e194.png b/docs/pics/867e93eb-3161-4f39-b2d2-c0cd3788e194.png deleted file mode 100644 index 4b19db6d..00000000 Binary files a/docs/pics/867e93eb-3161-4f39-b2d2-c0cd3788e194.png and /dev/null differ diff --git a/docs/pics/86e6a91d-a285-447a-9345-c5484b8d0c47.png b/docs/pics/86e6a91d-a285-447a-9345-c5484b8d0c47.png deleted file mode 100644 index d2f88403..00000000 Binary files a/docs/pics/86e6a91d-a285-447a-9345-c5484b8d0c47.png and /dev/null differ diff --git a/docs/pics/874b3ff7-7c5c-4e7a-b8ab-a82a3e038d20.png b/docs/pics/874b3ff7-7c5c-4e7a-b8ab-a82a3e038d20.png deleted file mode 100644 index f5f8f0f3..00000000 Binary files a/docs/pics/874b3ff7-7c5c-4e7a-b8ab-a82a3e038d20.png and /dev/null differ diff --git a/docs/pics/879814ee-48b5-4bcb-86f5-dcc400cb81ad.png b/docs/pics/879814ee-48b5-4bcb-86f5-dcc400cb81ad.png deleted file mode 100644 index 1f9f077c..00000000 Binary files a/docs/pics/879814ee-48b5-4bcb-86f5-dcc400cb81ad.png and /dev/null differ diff --git a/docs/pics/89292ae1-5f13-44dc-b508-3f035e80bf89.png b/docs/pics/89292ae1-5f13-44dc-b508-3f035e80bf89.png deleted file mode 100644 index bb186222..00000000 Binary files a/docs/pics/89292ae1-5f13-44dc-b508-3f035e80bf89.png and /dev/null differ diff --git a/docs/pics/8996a537-7c4a-4ec8-a3b7-7ef1798eae26.png b/docs/pics/8996a537-7c4a-4ec8-a3b7-7ef1798eae26.png deleted file mode 100644 index 25b7a7ae..00000000 Binary files a/docs/pics/8996a537-7c4a-4ec8-a3b7-7ef1798eae26.png and /dev/null differ diff --git a/docs/pics/8b798007-e0fb-420c-b981-ead215692417.jpg b/docs/pics/8b798007-e0fb-420c-b981-ead215692417.jpg deleted file mode 100644 index 8d52d766..00000000 Binary files a/docs/pics/8b798007-e0fb-420c-b981-ead215692417.jpg and /dev/null differ diff --git a/docs/pics/8b7ebbad-9604-4375-84e3-f412099d170c.png b/docs/pics/8b7ebbad-9604-4375-84e3-f412099d170c.png deleted file mode 100644 index 6b3dfeb4..00000000 Binary files a/docs/pics/8b7ebbad-9604-4375-84e3-f412099d170c.png and /dev/null differ diff --git a/docs/pics/8c662999-c16c-481c-9f40-1fdba5bc9167.png b/docs/pics/8c662999-c16c-481c-9f40-1fdba5bc9167.png deleted file mode 100644 index ff810e91..00000000 Binary files a/docs/pics/8c662999-c16c-481c-9f40-1fdba5bc9167.png and /dev/null differ diff --git a/docs/pics/8cb2be66-3d47-41ba-b55b-319fc68940d4.png b/docs/pics/8cb2be66-3d47-41ba-b55b-319fc68940d4.png deleted file mode 100644 index f701076c..00000000 Binary files a/docs/pics/8cb2be66-3d47-41ba-b55b-319fc68940d4.png and /dev/null differ diff --git a/docs/pics/8d779ab7-ffcc-47c6-90ec-ede8260b2368.png b/docs/pics/8d779ab7-ffcc-47c6-90ec-ede8260b2368.png deleted file mode 100644 index 20f171c8..00000000 Binary files a/docs/pics/8d779ab7-ffcc-47c6-90ec-ede8260b2368.png and /dev/null differ diff --git a/docs/pics/8edc5164-810b-4cc5-bda8-2a2c98556377.jpg b/docs/pics/8edc5164-810b-4cc5-bda8-2a2c98556377.jpg deleted file mode 100644 index 924bacf2..00000000 Binary files a/docs/pics/8edc5164-810b-4cc5-bda8-2a2c98556377.jpg and /dev/null differ diff --git a/docs/pics/8fdc577d-552d-4b43-b5e4-a8f98bc2cb51.png b/docs/pics/8fdc577d-552d-4b43-b5e4-a8f98bc2cb51.png deleted file mode 100644 index 3182c754..00000000 Binary files a/docs/pics/8fdc577d-552d-4b43-b5e4-a8f98bc2cb51.png and /dev/null differ diff --git a/docs/pics/910f613f-514f-4534-87dd-9b4699d59d31.png b/docs/pics/910f613f-514f-4534-87dd-9b4699d59d31.png deleted file mode 100644 index 2f552034..00000000 Binary files a/docs/pics/910f613f-514f-4534-87dd-9b4699d59d31.png and /dev/null differ diff --git a/docs/pics/9112288f-23f5-4e53-b222-a46fdbca1603.png b/docs/pics/9112288f-23f5-4e53-b222-a46fdbca1603.png deleted file mode 100644 index 457f9860..00000000 Binary files a/docs/pics/9112288f-23f5-4e53-b222-a46fdbca1603.png and /dev/null differ diff --git a/docs/pics/914894c2-0bc4-46b5-bef9-0316a69ef521.jpg b/docs/pics/914894c2-0bc4-46b5-bef9-0316a69ef521.jpg deleted file mode 100644 index 6993cf9e..00000000 Binary files a/docs/pics/914894c2-0bc4-46b5-bef9-0316a69ef521.jpg and /dev/null differ diff --git a/docs/pics/91550414131331.gif b/docs/pics/91550414131331.gif deleted file mode 100644 index 2626fdf8..00000000 Binary files a/docs/pics/91550414131331.gif and /dev/null differ diff --git a/docs/pics/924914c0-660c-4e4a-bbc0-1df1146e7516.jpg b/docs/pics/924914c0-660c-4e4a-bbc0-1df1146e7516.jpg deleted file mode 100644 index 900a0e19..00000000 Binary files a/docs/pics/924914c0-660c-4e4a-bbc0-1df1146e7516.jpg and /dev/null differ diff --git a/docs/pics/93fb1d38-83f9-464a-a733-67b2e6bfddda.png b/docs/pics/93fb1d38-83f9-464a-a733-67b2e6bfddda.png deleted file mode 100644 index c971b0e0..00000000 Binary files a/docs/pics/93fb1d38-83f9-464a-a733-67b2e6bfddda.png and /dev/null differ diff --git a/docs/pics/9420a703-1f9d-42ce-808e-bcb82b56483d.png b/docs/pics/9420a703-1f9d-42ce-808e-bcb82b56483d.png deleted file mode 100644 index 4141618f..00000000 Binary files a/docs/pics/9420a703-1f9d-42ce-808e-bcb82b56483d.png and /dev/null differ diff --git a/docs/pics/942ca0d2-9d5c-45a4-89cb-5fd89b61913f.png b/docs/pics/942ca0d2-9d5c-45a4-89cb-5fd89b61913f.png deleted file mode 100644 index 09de6b0b..00000000 Binary files a/docs/pics/942ca0d2-9d5c-45a4-89cb-5fd89b61913f.png and /dev/null differ diff --git a/docs/pics/942f33c9-8ad9-4987-836f-007de4c21de0.png b/docs/pics/942f33c9-8ad9-4987-836f-007de4c21de0.png deleted file mode 100644 index 0fd33f0f..00000000 Binary files a/docs/pics/942f33c9-8ad9-4987-836f-007de4c21de0.png and /dev/null differ diff --git a/docs/pics/94617147-0cbd-4a28-847d-81e52efb1b1e.png b/docs/pics/94617147-0cbd-4a28-847d-81e52efb1b1e.png deleted file mode 100644 index db834987..00000000 Binary files a/docs/pics/94617147-0cbd-4a28-847d-81e52efb1b1e.png and /dev/null differ diff --git a/docs/pics/95080fae-de40-463d-a76e-783a0c677fec.gif b/docs/pics/95080fae-de40-463d-a76e-783a0c677fec.gif deleted file mode 100644 index 9de55285..00000000 Binary files a/docs/pics/95080fae-de40-463d-a76e-783a0c677fec.gif and /dev/null differ diff --git a/docs/pics/952e06bd-5a65-4cab-82e4-dd1536462f38.png b/docs/pics/952e06bd-5a65-4cab-82e4-dd1536462f38.png deleted file mode 100644 index 10280868..00000000 Binary files a/docs/pics/952e06bd-5a65-4cab-82e4-dd1536462f38.png and /dev/null differ diff --git a/docs/pics/95903878-725b-4ed9-bded-bc4aae0792a9.jpg b/docs/pics/95903878-725b-4ed9-bded-bc4aae0792a9.jpg deleted file mode 100644 index 8a436997..00000000 Binary files a/docs/pics/95903878-725b-4ed9-bded-bc4aae0792a9.jpg and /dev/null differ diff --git a/docs/pics/9709694b-db05-4cce-8d2f-1c8b09f4d921.png b/docs/pics/9709694b-db05-4cce-8d2f-1c8b09f4d921.png deleted file mode 100644 index cc3e2517..00000000 Binary files a/docs/pics/9709694b-db05-4cce-8d2f-1c8b09f4d921.png and /dev/null differ diff --git a/docs/pics/9823768c-212b-4b1a-b69a-b3f59e07b977.jpg b/docs/pics/9823768c-212b-4b1a-b69a-b3f59e07b977.jpg deleted file mode 100644 index 0b89710a..00000000 Binary files a/docs/pics/9823768c-212b-4b1a-b69a-b3f59e07b977.jpg and /dev/null differ diff --git a/docs/pics/99b6060e-099d-4201-8e86-f8ab3768a7cf.png b/docs/pics/99b6060e-099d-4201-8e86-f8ab3768a7cf.png deleted file mode 100644 index 123575b8..00000000 Binary files a/docs/pics/99b6060e-099d-4201-8e86-f8ab3768a7cf.png and /dev/null differ diff --git a/docs/pics/99d5e84e-fc2a-49a3-8259-8de274617756.gif b/docs/pics/99d5e84e-fc2a-49a3-8259-8de274617756.gif deleted file mode 100644 index b5cf8e79..00000000 Binary files a/docs/pics/99d5e84e-fc2a-49a3-8259-8de274617756.gif and /dev/null differ diff --git a/docs/pics/9a519773-84b2-4c81-81cf-4e7dd739a97a.png b/docs/pics/9a519773-84b2-4c81-81cf-4e7dd739a97a.png deleted file mode 100644 index c90e62dc..00000000 Binary files a/docs/pics/9a519773-84b2-4c81-81cf-4e7dd739a97a.png and /dev/null differ diff --git a/docs/pics/9ae89f16-7905-4a6f-88a2-874b4cac91f4.jpg b/docs/pics/9ae89f16-7905-4a6f-88a2-874b4cac91f4.jpg deleted file mode 100644 index 654735d5..00000000 Binary files a/docs/pics/9ae89f16-7905-4a6f-88a2-874b4cac91f4.jpg and /dev/null differ diff --git a/docs/pics/9b679ff5-94c6-48a7-b9b7-2ea868e828ed.png b/docs/pics/9b679ff5-94c6-48a7-b9b7-2ea868e828ed.png deleted file mode 100644 index d361b7b3..00000000 Binary files a/docs/pics/9b679ff5-94c6-48a7-b9b7-2ea868e828ed.png and /dev/null differ diff --git a/docs/pics/9b838aee-0996-44a5-9b0f-3d1e3e2f5100.png b/docs/pics/9b838aee-0996-44a5-9b0f-3d1e3e2f5100.png deleted file mode 100644 index 01049930..00000000 Binary files a/docs/pics/9b838aee-0996-44a5-9b0f-3d1e3e2f5100.png and /dev/null differ diff --git a/docs/pics/9bbddeeb-e939-41f0-8e8e-2b1a0aa7e0a7.png b/docs/pics/9bbddeeb-e939-41f0-8e8e-2b1a0aa7e0a7.png deleted file mode 100644 index 02b1f35a..00000000 Binary files a/docs/pics/9bbddeeb-e939-41f0-8e8e-2b1a0aa7e0a7.png and /dev/null differ diff --git a/docs/pics/9c422923-1447-4a3b-a4e1-97e663738187.jpg b/docs/pics/9c422923-1447-4a3b-a4e1-97e663738187.jpg deleted file mode 100644 index ce066302..00000000 Binary files a/docs/pics/9c422923-1447-4a3b-a4e1-97e663738187.jpg and /dev/null differ diff --git a/docs/pics/9cd0ae20-4fb5-4017-a000-f7d3a0eb3529.png b/docs/pics/9cd0ae20-4fb5-4017-a000-f7d3a0eb3529.png deleted file mode 100644 index 49da824e..00000000 Binary files a/docs/pics/9cd0ae20-4fb5-4017-a000-f7d3a0eb3529.png and /dev/null differ diff --git a/docs/pics/9d1deeba-4ae1-41dc-98f4-47d85b9831bc.gif b/docs/pics/9d1deeba-4ae1-41dc-98f4-47d85b9831bc.gif deleted file mode 100644 index 41146c22..00000000 Binary files a/docs/pics/9d1deeba-4ae1-41dc-98f4-47d85b9831bc.gif and /dev/null differ diff --git a/docs/pics/9daa3616-00a4-48c4-9146-792dc8499be3.jpg b/docs/pics/9daa3616-00a4-48c4-9146-792dc8499be3.jpg deleted file mode 100644 index ab7ef4a5..00000000 Binary files a/docs/pics/9daa3616-00a4-48c4-9146-792dc8499be3.jpg and /dev/null differ diff --git a/docs/pics/9dae7475-934f-42e5-b3b3-12724337170a.png b/docs/pics/9dae7475-934f-42e5-b3b3-12724337170a.png deleted file mode 100644 index 7508fa08..00000000 Binary files a/docs/pics/9dae7475-934f-42e5-b3b3-12724337170a.png and /dev/null differ diff --git a/docs/pics/9ea86eb5-000a-4281-b948-7b567bd6f1d8.png b/docs/pics/9ea86eb5-000a-4281-b948-7b567bd6f1d8.png deleted file mode 100644 index 61717a26..00000000 Binary files a/docs/pics/9ea86eb5-000a-4281-b948-7b567bd6f1d8.png and /dev/null differ diff --git a/docs/pics/BSD_disk.png b/docs/pics/BSD_disk.png deleted file mode 100644 index b5ada5b3..00000000 Binary files a/docs/pics/BSD_disk.png and /dev/null differ diff --git a/docs/pics/GUID_Partition_Table_Scheme.svg.png b/docs/pics/GUID_Partition_Table_Scheme.svg.png deleted file mode 100644 index ddb9975f..00000000 Binary files a/docs/pics/GUID_Partition_Table_Scheme.svg.png and /dev/null differ diff --git a/docs/pics/HTTP1_x_Connections.png b/docs/pics/HTTP1_x_Connections.png deleted file mode 100644 index 68039d6b..00000000 Binary files a/docs/pics/HTTP1_x_Connections.png and /dev/null differ diff --git a/docs/pics/HTTP_RequestMessageExample.png b/docs/pics/HTTP_RequestMessageExample.png deleted file mode 100644 index e970928e..00000000 Binary files a/docs/pics/HTTP_RequestMessageExample.png and /dev/null differ diff --git a/docs/pics/HTTP_ResponseMessageExample.png b/docs/pics/HTTP_ResponseMessageExample.png deleted file mode 100644 index 4d050b3a..00000000 Binary files a/docs/pics/HTTP_ResponseMessageExample.png and /dev/null differ diff --git a/docs/pics/How-HTTPS-Works.png b/docs/pics/How-HTTPS-Works.png deleted file mode 100644 index 7c31acf2..00000000 Binary files a/docs/pics/How-HTTPS-Works.png and /dev/null differ diff --git a/docs/pics/PPjwP.png b/docs/pics/PPjwP.png deleted file mode 100644 index f5895f64..00000000 Binary files a/docs/pics/PPjwP.png and /dev/null differ diff --git a/docs/pics/ProcessState.png b/docs/pics/ProcessState.png deleted file mode 100644 index 39269579..00000000 Binary files a/docs/pics/ProcessState.png and /dev/null differ diff --git a/docs/pics/_u4E0B_u8F7D.png b/docs/pics/_u4E0B_u8F7D.png deleted file mode 100644 index f6903ee7..00000000 Binary files a/docs/pics/_u4E0B_u8F7D.png and /dev/null differ diff --git a/docs/pics/_u4E8C_u53C9_u6811_u7684_u4E0B_.gif b/docs/pics/_u4E8C_u53C9_u6811_u7684_u4E0B_.gif deleted file mode 100644 index f769ea68..00000000 Binary files a/docs/pics/_u4E8C_u53C9_u6811_u7684_u4E0B_.gif and /dev/null differ diff --git a/docs/pics/_u4E8C_u53C9_u6811_u7684_u4E0B_1548504426508.gif b/docs/pics/_u4E8C_u53C9_u6811_u7684_u4E0B_1548504426508.gif deleted file mode 100644 index 9941311f..00000000 Binary files a/docs/pics/_u4E8C_u53C9_u6811_u7684_u4E0B_1548504426508.gif and /dev/null differ diff --git a/docs/pics/_u4E8C_u7EF4_u6570_u7EC4_u4E2D_.gif b/docs/pics/_u4E8C_u7EF4_u6570_u7EC4_u4E2D_.gif deleted file mode 100644 index 763fc1a3..00000000 Binary files a/docs/pics/_u4E8C_u7EF4_u6570_u7EC4_u4E2D_.gif and /dev/null differ diff --git a/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548293972480.gif b/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548293972480.gif deleted file mode 100644 index 1587890c..00000000 Binary files a/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548293972480.gif and /dev/null differ diff --git a/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548295232667.gif b/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548295232667.gif deleted file mode 100644 index 312fea60..00000000 Binary files a/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548295232667.gif and /dev/null differ diff --git a/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548296249372.gif b/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548296249372.gif deleted file mode 100644 index 61c506c9..00000000 Binary files a/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548296249372.gif and /dev/null differ diff --git a/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548503461113.gif b/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548503461113.gif deleted file mode 100644 index 8c0ba8e3..00000000 Binary files a/docs/pics/_u4ECE_u5C3E_u5230_u5934_u6253_1548503461113.gif and /dev/null differ diff --git a/docs/pics/_u6590_u6CE2_u90A3_u5951_u6570_u5217.gif b/docs/pics/_u6590_u6CE2_u90A3_u5951_u6570_u5217.gif deleted file mode 100644 index ad4a1ff7..00000000 Binary files a/docs/pics/_u6590_u6CE2_u90A3_u5951_u6570_u5217.gif and /dev/null differ diff --git a/docs/pics/_u66FF_u6362_u7A7A_u683C.gif b/docs/pics/_u66FF_u6362_u7A7A_u683C.gif deleted file mode 100644 index fe6c5503..00000000 Binary files a/docs/pics/_u66FF_u6362_u7A7A_u683C.gif and /dev/null differ diff --git a/docs/pics/_u7528_u4E24_u4E2A_u6808_u5B9E_.gif b/docs/pics/_u7528_u4E24_u4E2A_u6808_u5B9E_.gif deleted file mode 100644 index dfeff15b..00000000 Binary files a/docs/pics/_u7528_u4E24_u4E2A_u6808_u5B9E_.gif and /dev/null differ diff --git a/docs/pics/_u91CD_u5EFA_u4E8C_u53C9_u6811-1.gif b/docs/pics/_u91CD_u5EFA_u4E8C_u53C9_u6811-1.gif deleted file mode 100644 index a6552b51..00000000 Binary files a/docs/pics/_u91CD_u5EFA_u4E8C_u53C9_u6811-1.gif and /dev/null differ diff --git a/docs/pics/_u91CD_u5EFA_u4E8C_u53C9_u6811-21548502782193.gif b/docs/pics/_u91CD_u5EFA_u4E8C_u53C9_u6811-21548502782193.gif deleted file mode 100644 index d5a4eec5..00000000 Binary files a/docs/pics/_u91CD_u5EFA_u4E8C_u53C9_u6811-21548502782193.gif and /dev/null differ diff --git a/docs/pics/a0ce43b7-afa8-4397-a96e-5c12a070f2ae.jpg b/docs/pics/a0ce43b7-afa8-4397-a96e-5c12a070f2ae.jpg deleted file mode 100644 index 5e469507..00000000 Binary files a/docs/pics/a0ce43b7-afa8-4397-a96e-5c12a070f2ae.jpg and /dev/null differ diff --git a/docs/pics/a14268b3-b937-4ffa-a34a-4cc53071686b.jpg b/docs/pics/a14268b3-b937-4ffa-a34a-4cc53071686b.jpg deleted file mode 100644 index 38996fa2..00000000 Binary files a/docs/pics/a14268b3-b937-4ffa-a34a-4cc53071686b.jpg and /dev/null differ diff --git a/docs/pics/a1616dac-0e12-40b2-827d-9e3f7f0b940d.png b/docs/pics/a1616dac-0e12-40b2-827d-9e3f7f0b940d.png deleted file mode 100644 index b6b5bc44..00000000 Binary files a/docs/pics/a1616dac-0e12-40b2-827d-9e3f7f0b940d.png and /dev/null differ diff --git a/docs/pics/a314bb79-5b18-4e63-a976-3448bffa6f1b.png b/docs/pics/a314bb79-5b18-4e63-a976-3448bffa6f1b.png deleted file mode 100644 index 2d650365..00000000 Binary files a/docs/pics/a314bb79-5b18-4e63-a976-3448bffa6f1b.png and /dev/null differ diff --git a/docs/pics/a3253deb-8d21-40a1-aae4-7d178e4aa319.jpg b/docs/pics/a3253deb-8d21-40a1-aae4-7d178e4aa319.jpg deleted file mode 100644 index 13574915..00000000 Binary files a/docs/pics/a3253deb-8d21-40a1-aae4-7d178e4aa319.jpg and /dev/null differ diff --git a/docs/pics/a3e4dc62-0da5-4d22-94f2-140078281812.jpg b/docs/pics/a3e4dc62-0da5-4d22-94f2-140078281812.jpg deleted file mode 100644 index 5fb9e5ca..00000000 Binary files a/docs/pics/a3e4dc62-0da5-4d22-94f2-140078281812.jpg and /dev/null differ diff --git a/docs/pics/a40661e4-1a71-46d2-a158-ff36f7fc3331.png b/docs/pics/a40661e4-1a71-46d2-a158-ff36f7fc3331.png deleted file mode 100644 index e602c1f3..00000000 Binary files a/docs/pics/a40661e4-1a71-46d2-a158-ff36f7fc3331.png and /dev/null differ diff --git a/docs/pics/a42ad3a7-3574-4c48-a783-ed3d08a0688a.jpg b/docs/pics/a42ad3a7-3574-4c48-a783-ed3d08a0688a.jpg deleted file mode 100644 index 4fe7b4b5..00000000 Binary files a/docs/pics/a42ad3a7-3574-4c48-a783-ed3d08a0688a.jpg and /dev/null differ diff --git a/docs/pics/a4444545-0d68-4015-9a3d-19209dc436b3.png b/docs/pics/a4444545-0d68-4015-9a3d-19209dc436b3.png deleted file mode 100644 index b35be3f5..00000000 Binary files a/docs/pics/a4444545-0d68-4015-9a3d-19209dc436b3.png and /dev/null differ diff --git a/docs/pics/a4a0a6e6-386b-4bfa-b899-ec33d3310f3e.png b/docs/pics/a4a0a6e6-386b-4bfa-b899-ec33d3310f3e.png deleted file mode 100644 index 7866d799..00000000 Binary files a/docs/pics/a4a0a6e6-386b-4bfa-b899-ec33d3310f3e.png and /dev/null differ diff --git a/docs/pics/a6ac2b08-3861-4e85-baa8-382287bfee9f.png b/docs/pics/a6ac2b08-3861-4e85-baa8-382287bfee9f.png deleted file mode 100644 index 26b0bd03..00000000 Binary files a/docs/pics/a6ac2b08-3861-4e85-baa8-382287bfee9f.png and /dev/null differ diff --git a/docs/pics/a6c20f60-5eba-427d-9413-352ada4b40fe.png b/docs/pics/a6c20f60-5eba-427d-9413-352ada4b40fe.png deleted file mode 100644 index d6c39eb4..00000000 Binary files a/docs/pics/a6c20f60-5eba-427d-9413-352ada4b40fe.png and /dev/null differ diff --git a/docs/pics/a7cb8423-895d-4975-8ef8-662a0029c772.png b/docs/pics/a7cb8423-895d-4975-8ef8-662a0029c772.png deleted file mode 100644 index 29f9d362..00000000 Binary files a/docs/pics/a7cb8423-895d-4975-8ef8-662a0029c772.png and /dev/null differ diff --git a/docs/pics/a8c8f894-a712-447c-9906-5caef6a016e3.png b/docs/pics/a8c8f894-a712-447c-9906-5caef6a016e3.png deleted file mode 100644 index bd757f81..00000000 Binary files a/docs/pics/a8c8f894-a712-447c-9906-5caef6a016e3.png and /dev/null differ diff --git a/docs/pics/a9077f06-7584-4f2b-8c20-3a8e46928820.jpg b/docs/pics/a9077f06-7584-4f2b-8c20-3a8e46928820.jpg deleted file mode 100644 index 67b2264d..00000000 Binary files a/docs/pics/a9077f06-7584-4f2b-8c20-3a8e46928820.jpg and /dev/null differ diff --git a/docs/pics/a9f18f8a-c1ea-422e-aa56-d91716b0f755.jpg b/docs/pics/a9f18f8a-c1ea-422e-aa56-d91716b0f755.jpg deleted file mode 100644 index 9579a564..00000000 Binary files a/docs/pics/a9f18f8a-c1ea-422e-aa56-d91716b0f755.jpg and /dev/null differ diff --git a/docs/pics/aa29cc88-7256-4399-8c7f-3cf4a6489559.png b/docs/pics/aa29cc88-7256-4399-8c7f-3cf4a6489559.png deleted file mode 100644 index 9b93237e..00000000 Binary files a/docs/pics/aa29cc88-7256-4399-8c7f-3cf4a6489559.png and /dev/null differ diff --git a/docs/pics/aaac1bbe-8e37-43d6-b645-cec16a092654_200.png b/docs/pics/aaac1bbe-8e37-43d6-b645-cec16a092654_200.png deleted file mode 100644 index f6d7d790..00000000 Binary files a/docs/pics/aaac1bbe-8e37-43d6-b645-cec16a092654_200.png and /dev/null differ diff --git a/docs/pics/abb3e0d1-c1bd-45d0-8190-73c74a9f6679.png b/docs/pics/abb3e0d1-c1bd-45d0-8190-73c74a9f6679.png deleted file mode 100644 index 45848b45..00000000 Binary files a/docs/pics/abb3e0d1-c1bd-45d0-8190-73c74a9f6679.png and /dev/null differ diff --git a/docs/pics/ac6a794b-68c0-486c-902f-8d988eee5766.png b/docs/pics/ac6a794b-68c0-486c-902f-8d988eee5766.png deleted file mode 100644 index 3c05e805..00000000 Binary files a/docs/pics/ac6a794b-68c0-486c-902f-8d988eee5766.png and /dev/null differ diff --git a/docs/pics/ac929ea3-daca-40ec-9e95-4b2fa6678243.png b/docs/pics/ac929ea3-daca-40ec-9e95-4b2fa6678243.png deleted file mode 100644 index a9361a1e..00000000 Binary files a/docs/pics/ac929ea3-daca-40ec-9e95-4b2fa6678243.png and /dev/null differ diff --git a/docs/pics/ace20410-f053-4c4a-aca4-2c603ff11bbe.png b/docs/pics/ace20410-f053-4c4a-aca4-2c603ff11bbe.png deleted file mode 100644 index 25f75527..00000000 Binary files a/docs/pics/ace20410-f053-4c4a-aca4-2c603ff11bbe.png and /dev/null differ diff --git a/docs/pics/adfb427d-3b21-40d7-a142-757f4ed73079.png b/docs/pics/adfb427d-3b21-40d7-a142-757f4ed73079.png deleted file mode 100644 index 9da3a137..00000000 Binary files a/docs/pics/adfb427d-3b21-40d7-a142-757f4ed73079.png and /dev/null differ diff --git a/docs/pics/ae1b27b8-bc13-42e7-ac12-a2242e125499.png b/docs/pics/ae1b27b8-bc13-42e7-ac12-a2242e125499.png deleted file mode 100644 index 5b5bfc47..00000000 Binary files a/docs/pics/ae1b27b8-bc13-42e7-ac12-a2242e125499.png and /dev/null differ diff --git a/docs/pics/aefa8042-15fa-4e8b-9f50-20b282a2c624.png b/docs/pics/aefa8042-15fa-4e8b-9f50-20b282a2c624.png deleted file mode 100644 index 9b7ce9df..00000000 Binary files a/docs/pics/aefa8042-15fa-4e8b-9f50-20b282a2c624.png and /dev/null differ diff --git a/docs/pics/af0e94d9-502d-4531-938f-d46dd29de52d.png b/docs/pics/af0e94d9-502d-4531-938f-d46dd29de52d.png deleted file mode 100644 index 7aab9bed..00000000 Binary files a/docs/pics/af0e94d9-502d-4531-938f-d46dd29de52d.png and /dev/null differ diff --git a/docs/pics/af198da1-2480-4043-b07f-a3b91a88b815.png b/docs/pics/af198da1-2480-4043-b07f-a3b91a88b815.png deleted file mode 100644 index 908d678a..00000000 Binary files a/docs/pics/af198da1-2480-4043-b07f-a3b91a88b815.png and /dev/null differ diff --git a/docs/pics/af1d1166-63af-47b6-9aa3-2bf2bd37bd03.jpg b/docs/pics/af1d1166-63af-47b6-9aa3-2bf2bd37bd03.jpg deleted file mode 100644 index 00ea4f6b..00000000 Binary files a/docs/pics/af1d1166-63af-47b6-9aa3-2bf2bd37bd03.jpg and /dev/null differ diff --git a/docs/pics/b0611f89-1e5f-4494-a795-3544bf65042a.gif b/docs/pics/b0611f89-1e5f-4494-a795-3544bf65042a.gif deleted file mode 100644 index 3e1fdb8b..00000000 Binary files a/docs/pics/b0611f89-1e5f-4494-a795-3544bf65042a.gif and /dev/null differ diff --git a/docs/pics/b0f0107a-e35b-4ace-b25e-cacb22b1556035029196.gif b/docs/pics/b0f0107a-e35b-4ace-b25e-cacb22b1556035029196.gif deleted file mode 100644 index 080f51aa..00000000 Binary files a/docs/pics/b0f0107a-e35b-4ace-b25e-cacb22b1556035029196.gif and /dev/null differ diff --git a/docs/pics/b0f61ac2-a4b6-4042-9cf0-ccf4238c1ff7.png b/docs/pics/b0f61ac2-a4b6-4042-9cf0-ccf4238c1ff7.png deleted file mode 100644 index 8561aad3..00000000 Binary files a/docs/pics/b0f61ac2-a4b6-4042-9cf0-ccf4238c1ff7.png and /dev/null differ diff --git a/docs/pics/b1df9732-86ce-4d69-9f06-fba1db7b3b5a.jpg b/docs/pics/b1df9732-86ce-4d69-9f06-fba1db7b3b5a.jpg deleted file mode 100644 index 0444210b..00000000 Binary files a/docs/pics/b1df9732-86ce-4d69-9f06-fba1db7b3b5a.jpg and /dev/null differ diff --git a/docs/pics/b1fa0453-a4b0-4eae-a352-48acca8fff74.png b/docs/pics/b1fa0453-a4b0-4eae-a352-48acca8fff74.png deleted file mode 100644 index 842b2f6c..00000000 Binary files a/docs/pics/b1fa0453-a4b0-4eae-a352-48acca8fff74.png and /dev/null differ diff --git a/docs/pics/b25e75a5-7aa4-42f8-b2f8-d5f81c4fb2fc.png b/docs/pics/b25e75a5-7aa4-42f8-b2f8-d5f81c4fb2fc.png deleted file mode 100644 index 7ed8a50b..00000000 Binary files a/docs/pics/b25e75a5-7aa4-42f8-b2f8-d5f81c4fb2fc.png and /dev/null differ diff --git a/docs/pics/b2b77b9e-958c-4016-8ae5-9c6edd83871e.png b/docs/pics/b2b77b9e-958c-4016-8ae5-9c6edd83871e.png deleted file mode 100644 index c376a027..00000000 Binary files a/docs/pics/b2b77b9e-958c-4016-8ae5-9c6edd83871e.png and /dev/null differ diff --git a/docs/pics/b396d726-b75f-4a32-89a2-03a7b6e19f6f.jpg b/docs/pics/b396d726-b75f-4a32-89a2-03a7b6e19f6f.jpg deleted file mode 100644 index a3e1a656..00000000 Binary files a/docs/pics/b396d726-b75f-4a32-89a2-03a7b6e19f6f.jpg and /dev/null differ diff --git a/docs/pics/b54eeb16-0b0e-484c-be62-306f57c40d77.jpg b/docs/pics/b54eeb16-0b0e-484c-be62-306f57c40d77.jpg deleted file mode 100644 index 692a0357..00000000 Binary files a/docs/pics/b54eeb16-0b0e-484c-be62-306f57c40d77.jpg and /dev/null differ diff --git a/docs/pics/b5bdcbe2-b958-4aef-9151-6ad963cb28b4.png b/docs/pics/b5bdcbe2-b958-4aef-9151-6ad963cb28b4.png deleted file mode 100644 index 8b44b871..00000000 Binary files a/docs/pics/b5bdcbe2-b958-4aef-9151-6ad963cb28b4.png and /dev/null differ diff --git a/docs/pics/b5e9fa4d-78d3-4176-8273-756d970742c7.png b/docs/pics/b5e9fa4d-78d3-4176-8273-756d970742c7.png deleted file mode 100644 index 59ec8ce1..00000000 Binary files a/docs/pics/b5e9fa4d-78d3-4176-8273-756d970742c7.png and /dev/null differ diff --git a/docs/pics/b8081c84-62c4-4019-b3ee-4bd0e443d647.jpg b/docs/pics/b8081c84-62c4-4019-b3ee-4bd0e443d647.jpg deleted file mode 100644 index e881294b..00000000 Binary files a/docs/pics/b8081c84-62c4-4019-b3ee-4bd0e443d647.jpg and /dev/null differ diff --git a/docs/pics/b8922f8c-95e6-4187-be85-572a509afb71.png b/docs/pics/b8922f8c-95e6-4187-be85-572a509afb71.png deleted file mode 100644 index c70d6970..00000000 Binary files a/docs/pics/b8922f8c-95e6-4187-be85-572a509afb71.png and /dev/null differ diff --git a/docs/pics/b8dd708d-f372-4b04-b828-1dd99021c244.png b/docs/pics/b8dd708d-f372-4b04-b828-1dd99021c244.png deleted file mode 100644 index ed37aeb0..00000000 Binary files a/docs/pics/b8dd708d-f372-4b04-b828-1dd99021c244.png and /dev/null differ diff --git a/docs/pics/b903fda8-07d0-46a7-91a7-e803892895cf.gif b/docs/pics/b903fda8-07d0-46a7-91a7-e803892895cf.gif deleted file mode 100644 index 873aac86..00000000 Binary files a/docs/pics/b903fda8-07d0-46a7-91a7-e803892895cf.gif and /dev/null differ diff --git a/docs/pics/b988877c-0f0a-4593-916d-de2081320628.jpg b/docs/pics/b988877c-0f0a-4593-916d-de2081320628.jpg deleted file mode 100644 index ba000138..00000000 Binary files a/docs/pics/b988877c-0f0a-4593-916d-de2081320628.jpg and /dev/null differ diff --git a/docs/pics/b9d79a5a-e7af-499b-b989-f10483e71b8b.jpg b/docs/pics/b9d79a5a-e7af-499b-b989-f10483e71b8b.jpg deleted file mode 100644 index b7502831..00000000 Binary files a/docs/pics/b9d79a5a-e7af-499b-b989-f10483e71b8b.jpg and /dev/null differ diff --git a/docs/pics/ba078291-791e-4378-b6d1-ece76c2f0b14.png b/docs/pics/ba078291-791e-4378-b6d1-ece76c2f0b14.png deleted file mode 100644 index c2a32e7d..00000000 Binary files a/docs/pics/ba078291-791e-4378-b6d1-ece76c2f0b14.png and /dev/null differ diff --git a/docs/pics/ba355101-4a93-4c71-94fb-1da83639727b.jpg b/docs/pics/ba355101-4a93-4c71-94fb-1da83639727b.jpg deleted file mode 100644 index b5625ae0..00000000 Binary files a/docs/pics/ba355101-4a93-4c71-94fb-1da83639727b.jpg and /dev/null differ diff --git a/docs/pics/baaa681f-7c52-4198-a5ae-303b9386cf47.png b/docs/pics/baaa681f-7c52-4198-a5ae-303b9386cf47.png deleted file mode 100644 index e0331808..00000000 Binary files a/docs/pics/baaa681f-7c52-4198-a5ae-303b9386cf47.png and /dev/null differ diff --git a/docs/pics/bb6a49be-00f2-4f27-a0ce-4ed764bc605c.png b/docs/pics/bb6a49be-00f2-4f27-a0ce-4ed764bc605c.png deleted file mode 100644 index 7845ba00..00000000 Binary files a/docs/pics/bb6a49be-00f2-4f27-a0ce-4ed764bc605c.png and /dev/null differ diff --git a/docs/pics/bb7fc182-98c2-4860-8ea3-630e27a5f29f.png b/docs/pics/bb7fc182-98c2-4860-8ea3-630e27a5f29f.png deleted file mode 100644 index 92dfa7f5..00000000 Binary files a/docs/pics/bb7fc182-98c2-4860-8ea3-630e27a5f29f.png and /dev/null differ diff --git a/docs/pics/bc6be2d0-ed5e-4def-89e5-3ada9afa811a.gif b/docs/pics/bc6be2d0-ed5e-4def-89e5-3ada9afa811a.gif deleted file mode 100644 index 23de8ec7..00000000 Binary files a/docs/pics/bc6be2d0-ed5e-4def-89e5-3ada9afa811a.gif and /dev/null differ diff --git a/docs/pics/be5c2c61-86d2-4dba-a289-b48ea23219de.jpg b/docs/pics/be5c2c61-86d2-4dba-a289-b48ea23219de.jpg deleted file mode 100644 index a2965a7d..00000000 Binary files a/docs/pics/be5c2c61-86d2-4dba-a289-b48ea23219de.jpg and /dev/null differ diff --git a/docs/pics/be608a77-7b7f-4f8e-87cc-f2237270bf69.png b/docs/pics/be608a77-7b7f-4f8e-87cc-f2237270bf69.png deleted file mode 100644 index 44696cc0..00000000 Binary files a/docs/pics/be608a77-7b7f-4f8e-87cc-f2237270bf69.png and /dev/null differ diff --git a/docs/pics/beba612e-dc5b-4fc2-869d-0b23408ac90a.png b/docs/pics/beba612e-dc5b-4fc2-869d-0b23408ac90a.png deleted file mode 100644 index 158015bc..00000000 Binary files a/docs/pics/beba612e-dc5b-4fc2-869d-0b23408ac90a.png and /dev/null differ diff --git a/docs/pics/bf16c541-0717-473b-b75d-4115864f4fbf.jpg b/docs/pics/bf16c541-0717-473b-b75d-4115864f4fbf.jpg deleted file mode 100644 index 71496f6a..00000000 Binary files a/docs/pics/bf16c541-0717-473b-b75d-4115864f4fbf.jpg and /dev/null differ diff --git a/docs/pics/bf667594-bb4b-4634-bf9b-0596a45415ba.jpg b/docs/pics/bf667594-bb4b-4634-bf9b-0596a45415ba.jpg deleted file mode 100644 index 399edf31..00000000 Binary files a/docs/pics/bf667594-bb4b-4634-bf9b-0596a45415ba.jpg and /dev/null differ diff --git a/docs/pics/bfea8772-d01b-4a51-8adc-edfd7d3dce84.jpg b/docs/pics/bfea8772-d01b-4a51-8adc-edfd7d3dce84.jpg deleted file mode 100644 index 597be53c..00000000 Binary files a/docs/pics/bfea8772-d01b-4a51-8adc-edfd7d3dce84.jpg and /dev/null differ diff --git a/docs/pics/c037c901-7eae-4e31-a1e4-9d41329e5c3e.png b/docs/pics/c037c901-7eae-4e31-a1e4-9d41329e5c3e.png deleted file mode 100644 index 9e2feb27..00000000 Binary files a/docs/pics/c037c901-7eae-4e31-a1e4-9d41329e5c3e.png and /dev/null differ diff --git a/docs/pics/c0874e0a-dba3-467e-9c86-dd9313e0843e.jpg b/docs/pics/c0874e0a-dba3-467e-9c86-dd9313e0843e.jpg deleted file mode 100644 index 8d95cb5d..00000000 Binary files a/docs/pics/c0874e0a-dba3-467e-9c86-dd9313e0843e.jpg and /dev/null differ diff --git a/docs/pics/c094d2bc-ec75-444b-af77-d369dfb6b3b4.png b/docs/pics/c094d2bc-ec75-444b-af77-d369dfb6b3b4.png deleted file mode 100644 index 9e8e93c9..00000000 Binary files a/docs/pics/c094d2bc-ec75-444b-af77-d369dfb6b3b4.png and /dev/null differ diff --git a/docs/pics/c0a9fa91-da2e-4892-8c9f-80206a6f7047.png b/docs/pics/c0a9fa91-da2e-4892-8c9f-80206a6f7047.png deleted file mode 100644 index 14c225b3..00000000 Binary files a/docs/pics/c0a9fa91-da2e-4892-8c9f-80206a6f7047.png and /dev/null differ diff --git a/docs/pics/c11528f6-fc71-4a2b-8d2f-51b8954c38f1.jpg b/docs/pics/c11528f6-fc71-4a2b-8d2f-51b8954c38f1.jpg deleted file mode 100644 index 3ae21c60..00000000 Binary files a/docs/pics/c11528f6-fc71-4a2b-8d2f-51b8954c38f1.jpg and /dev/null differ diff --git a/docs/pics/c13e2a3d-b01c-4a08-a69b-db2c4e821e09.png b/docs/pics/c13e2a3d-b01c-4a08-a69b-db2c4e821e09.png deleted file mode 100644 index 69fe1ba2..00000000 Binary files a/docs/pics/c13e2a3d-b01c-4a08-a69b-db2c4e821e09.png and /dev/null differ diff --git a/docs/pics/c269e362-1128-4212-9cf3-d4c12b363b2f.gif b/docs/pics/c269e362-1128-4212-9cf3-d4c12b363b2f.gif deleted file mode 100644 index e372dea1..00000000 Binary files a/docs/pics/c269e362-1128-4212-9cf3-d4c12b363b2f.gif and /dev/null differ diff --git a/docs/pics/c2ca8dd2-8d00-4a3e-bece-db7849ac9cfd.gif b/docs/pics/c2ca8dd2-8d00-4a3e-bece-db7849ac9cfd.gif deleted file mode 100644 index 99bb0743..00000000 Binary files a/docs/pics/c2ca8dd2-8d00-4a3e-bece-db7849ac9cfd.gif and /dev/null differ diff --git a/docs/pics/c2cbf5d2-82af-4c78-bd43-495da5adf55f.png b/docs/pics/c2cbf5d2-82af-4c78-bd43-495da5adf55f.png deleted file mode 100644 index 74acb7c2..00000000 Binary files a/docs/pics/c2cbf5d2-82af-4c78-bd43-495da5adf55f.png and /dev/null differ diff --git a/docs/pics/c2d343f7-604c-4856-9a3c-c71d6f67fecc.png b/docs/pics/c2d343f7-604c-4856-9a3c-c71d6f67fecc.png deleted file mode 100644 index d50c1da4..00000000 Binary files a/docs/pics/c2d343f7-604c-4856-9a3c-c71d6f67fecc.png and /dev/null differ diff --git a/docs/pics/c3369072-c740-43b0-b276-202bd1d3960d.jpg b/docs/pics/c3369072-c740-43b0-b276-202bd1d3960d.jpg deleted file mode 100644 index 17a2e9bf..00000000 Binary files a/docs/pics/c3369072-c740-43b0-b276-202bd1d3960d.jpg and /dev/null differ diff --git a/docs/pics/c34f4503-f62c-4043-9dc6-3e03288657df.jpg b/docs/pics/c34f4503-f62c-4043-9dc6-3e03288657df.jpg deleted file mode 100644 index f4ed4dce..00000000 Binary files a/docs/pics/c34f4503-f62c-4043-9dc6-3e03288657df.jpg and /dev/null differ diff --git a/docs/pics/c395a428-827c-405b-abd7-8a069316f583.jpg b/docs/pics/c395a428-827c-405b-abd7-8a069316f583.jpg deleted file mode 100644 index 8cee2ac8..00000000 Binary files a/docs/pics/c395a428-827c-405b-abd7-8a069316f583.jpg and /dev/null differ diff --git a/docs/pics/c3c1c0e8-3a78-4426-961f-b46dd0879dd8.png b/docs/pics/c3c1c0e8-3a78-4426-961f-b46dd0879dd8.png deleted file mode 100644 index adebfb11..00000000 Binary files a/docs/pics/c3c1c0e8-3a78-4426-961f-b46dd0879dd8.png and /dev/null differ diff --git a/docs/pics/c44a0342-f405-4f17-b750-e27cf4aadde2.png b/docs/pics/c44a0342-f405-4f17-b750-e27cf4aadde2.png deleted file mode 100644 index 200fa5d4..00000000 Binary files a/docs/pics/c44a0342-f405-4f17-b750-e27cf4aadde2.png and /dev/null differ diff --git a/docs/pics/c4859290-e27d-4f12-becf-e2a5c1f3a275.gif b/docs/pics/c4859290-e27d-4f12-becf-e2a5c1f3a275.gif deleted file mode 100644 index 9e8a50a2..00000000 Binary files a/docs/pics/c4859290-e27d-4f12-becf-e2a5c1f3a275.gif and /dev/null differ diff --git a/docs/pics/c5085437-54df-4304-b62d-44b961711ba7.png b/docs/pics/c5085437-54df-4304-b62d-44b961711ba7.png deleted file mode 100644 index 75adb584..00000000 Binary files a/docs/pics/c5085437-54df-4304-b62d-44b961711ba7.png and /dev/null differ diff --git a/docs/pics/c625baa0-dde6-449e-93df-c3a67f2f430f.jpg b/docs/pics/c625baa0-dde6-449e-93df-c3a67f2f430f.jpg deleted file mode 100644 index 4a6d5197..00000000 Binary files a/docs/pics/c625baa0-dde6-449e-93df-c3a67f2f430f.jpg and /dev/null differ diff --git a/docs/pics/c79da808-0f28-4a36-bc04-33ccc5b83c13.png b/docs/pics/c79da808-0f28-4a36-bc04-33ccc5b83c13.png deleted file mode 100644 index 6770675e..00000000 Binary files a/docs/pics/c79da808-0f28-4a36-bc04-33ccc5b83c13.png and /dev/null differ diff --git a/docs/pics/c8563120-cb00-4dd6-9213-9d9b337a7f7c.png b/docs/pics/c8563120-cb00-4dd6-9213-9d9b337a7f7c.png deleted file mode 100644 index 228e1d8a..00000000 Binary files a/docs/pics/c8563120-cb00-4dd6-9213-9d9b337a7f7c.png and /dev/null differ diff --git a/docs/pics/c9cfd600-bc91-4f3a-9f99-b42f88a5bb24.jpg b/docs/pics/c9cfd600-bc91-4f3a-9f99-b42f88a5bb24.jpg deleted file mode 100644 index 8faf0c50..00000000 Binary files a/docs/pics/c9cfd600-bc91-4f3a-9f99-b42f88a5bb24.jpg and /dev/null differ diff --git a/docs/pics/ca9f23bf-55a4-47b2-9534-a28e35397988.png b/docs/pics/ca9f23bf-55a4-47b2-9534-a28e35397988.png deleted file mode 100644 index 95969741..00000000 Binary files a/docs/pics/ca9f23bf-55a4-47b2-9534-a28e35397988.png and /dev/null differ diff --git a/docs/pics/cafbfeb8-7dfe-4c0a-a3c9-750eeb824068.png b/docs/pics/cafbfeb8-7dfe-4c0a-a3c9-750eeb824068.png deleted file mode 100644 index 8cd71a87..00000000 Binary files a/docs/pics/cafbfeb8-7dfe-4c0a-a3c9-750eeb824068.png and /dev/null differ diff --git a/docs/pics/cbbfe06c-f0cb-47c4-bf7b-2780aebd98b2.png b/docs/pics/cbbfe06c-f0cb-47c4-bf7b-2780aebd98b2.png deleted file mode 100644 index eef74b36..00000000 Binary files a/docs/pics/cbbfe06c-f0cb-47c4-bf7b-2780aebd98b2.png and /dev/null differ diff --git a/docs/pics/cbf50eb8-22b4-4528-a2e7-d187143d57f7.png b/docs/pics/cbf50eb8-22b4-4528-a2e7-d187143d57f7.png deleted file mode 100644 index 27f2b742..00000000 Binary files a/docs/pics/cbf50eb8-22b4-4528-a2e7-d187143d57f7.png and /dev/null differ diff --git a/docs/pics/ccd773a5-ad38-4022-895c-7ac318f31437.png b/docs/pics/ccd773a5-ad38-4022-895c-7ac318f31437.png deleted file mode 100644 index e4706e59..00000000 Binary files a/docs/pics/ccd773a5-ad38-4022-895c-7ac318f31437.png and /dev/null differ diff --git a/docs/pics/cd1be8c2-755a-4a66-ad92-2e30f8f47922.png b/docs/pics/cd1be8c2-755a-4a66-ad92-2e30f8f47922.png deleted file mode 100644 index 441597fb..00000000 Binary files a/docs/pics/cd1be8c2-755a-4a66-ad92-2e30f8f47922.png and /dev/null differ diff --git a/docs/pics/cd411a94-3786-4c94-9e08-f28320e010d5.png b/docs/pics/cd411a94-3786-4c94-9e08-f28320e010d5.png deleted file mode 100644 index d941a7cb..00000000 Binary files a/docs/pics/cd411a94-3786-4c94-9e08-f28320e010d5.png and /dev/null differ diff --git a/docs/pics/cd5fbcff-3f35-43a6-8ffa-082a93ce0f0e.png b/docs/pics/cd5fbcff-3f35-43a6-8ffa-082a93ce0f0e.png deleted file mode 100644 index b721cc0a..00000000 Binary files a/docs/pics/cd5fbcff-3f35-43a6-8ffa-082a93ce0f0e.png and /dev/null differ diff --git a/docs/pics/cf4386a1-58c9-4eca-a17f-e12b1e9770eb.png b/docs/pics/cf4386a1-58c9-4eca-a17f-e12b1e9770eb.png deleted file mode 100644 index 9b9f3838..00000000 Binary files a/docs/pics/cf4386a1-58c9-4eca-a17f-e12b1e9770eb.png and /dev/null differ diff --git a/docs/pics/d02f74dd-8e33-4f3c-bf29-53203a06695a.png b/docs/pics/d02f74dd-8e33-4f3c-bf29-53203a06695a.png deleted file mode 100644 index d76c0354..00000000 Binary files a/docs/pics/d02f74dd-8e33-4f3c-bf29-53203a06695a.png and /dev/null differ diff --git a/docs/pics/d03a2efa-ef19-4c96-97e8-ff61df8061d3.png b/docs/pics/d03a2efa-ef19-4c96-97e8-ff61df8061d3.png deleted file mode 100644 index 5a4fdbcf..00000000 Binary files a/docs/pics/d03a2efa-ef19-4c96-97e8-ff61df8061d3.png and /dev/null differ diff --git a/docs/pics/d0afdd23-c9a5-4d1c-9b3d-404bff3bd0d1.png b/docs/pics/d0afdd23-c9a5-4d1c-9b3d-404bff3bd0d1.png deleted file mode 100644 index 9f1fbb07..00000000 Binary files a/docs/pics/d0afdd23-c9a5-4d1c-9b3d-404bff3bd0d1.png and /dev/null differ diff --git a/docs/pics/d156bcda-ac8d-4324-95e0-0c8df41567c9.gif b/docs/pics/d156bcda-ac8d-4324-95e0-0c8df41567c9.gif deleted file mode 100644 index 66afd965..00000000 Binary files a/docs/pics/d156bcda-ac8d-4324-95e0-0c8df41567c9.gif and /dev/null differ diff --git a/docs/pics/d160ec2e-cfe2-4640-bda7-62f53e58b8c0.png b/docs/pics/d160ec2e-cfe2-4640-bda7-62f53e58b8c0.png deleted file mode 100644 index cc971351..00000000 Binary files a/docs/pics/d160ec2e-cfe2-4640-bda7-62f53e58b8c0.png and /dev/null differ diff --git a/docs/pics/d1ed87eb-da5a-4728-b0dc-e3705aa028ea.gif b/docs/pics/d1ed87eb-da5a-4728-b0dc-e3705aa028ea.gif deleted file mode 100644 index 9681e7e7..00000000 Binary files a/docs/pics/d1ed87eb-da5a-4728-b0dc-e3705aa028ea.gif and /dev/null differ diff --git a/docs/pics/d27c99f0-7881-4f2d-9675-c75cbdee3acd.jpg b/docs/pics/d27c99f0-7881-4f2d-9675-c75cbdee3acd.jpg deleted file mode 100644 index fe765547..00000000 Binary files a/docs/pics/d27c99f0-7881-4f2d-9675-c75cbdee3acd.jpg and /dev/null differ diff --git a/docs/pics/d2ae9932-e2b1-4191-8ee9-e573f36d3895.png b/docs/pics/d2ae9932-e2b1-4191-8ee9-e573f36d3895.png deleted file mode 100644 index f8223bd8..00000000 Binary files a/docs/pics/d2ae9932-e2b1-4191-8ee9-e573f36d3895.png and /dev/null differ diff --git a/docs/pics/d2c072cc-8b17-480c-813e-18cdb3b4b51f.jpg b/docs/pics/d2c072cc-8b17-480c-813e-18cdb3b4b51f.jpg deleted file mode 100644 index b58c676e..00000000 Binary files a/docs/pics/d2c072cc-8b17-480c-813e-18cdb3b4b51f.jpg and /dev/null differ diff --git a/docs/pics/d4c3a4a1-0846-46ec-9cc3-eaddfca71254.jpg b/docs/pics/d4c3a4a1-0846-46ec-9cc3-eaddfca71254.jpg deleted file mode 100644 index 6acf5626..00000000 Binary files a/docs/pics/d4c3a4a1-0846-46ec-9cc3-eaddfca71254.jpg and /dev/null differ diff --git a/docs/pics/d52270b4-9097-4667-9f18-f405fc661c99.png b/docs/pics/d52270b4-9097-4667-9f18-f405fc661c99.png deleted file mode 100644 index 16ff310e..00000000 Binary files a/docs/pics/d52270b4-9097-4667-9f18-f405fc661c99.png and /dev/null differ diff --git a/docs/pics/d5e838cf-d8a2-49af-90df-1b2a714ee676.jpg b/docs/pics/d5e838cf-d8a2-49af-90df-1b2a714ee676.jpg deleted file mode 100644 index dca06e46..00000000 Binary files a/docs/pics/d5e838cf-d8a2-49af-90df-1b2a714ee676.jpg and /dev/null differ diff --git a/docs/pics/d85870db-f28c-48c3-9d24-85a36fda5e51.png b/docs/pics/d85870db-f28c-48c3-9d24-85a36fda5e51.png deleted file mode 100644 index f0a85bef..00000000 Binary files a/docs/pics/d85870db-f28c-48c3-9d24-85a36fda5e51.png and /dev/null differ diff --git a/docs/pics/da1f96b9-fd4d-44ca-8925-fb14c5733388.png b/docs/pics/da1f96b9-fd4d-44ca-8925-fb14c5733388.png deleted file mode 100644 index 87da9b04..00000000 Binary files a/docs/pics/da1f96b9-fd4d-44ca-8925-fb14c5733388.png and /dev/null differ diff --git a/docs/pics/db5e376d-0b3e-490e-a43a-3231914b6668.png b/docs/pics/db5e376d-0b3e-490e-a43a-3231914b6668.png deleted file mode 100644 index 0cf8929b..00000000 Binary files a/docs/pics/db5e376d-0b3e-490e-a43a-3231914b6668.png and /dev/null differ diff --git a/docs/pics/db5f30a7-8bfa-4ecc-ab5d-747c77818964.gif b/docs/pics/db5f30a7-8bfa-4ecc-ab5d-747c77818964.gif deleted file mode 100644 index 9b78e709..00000000 Binary files a/docs/pics/db5f30a7-8bfa-4ecc-ab5d-747c77818964.gif and /dev/null differ diff --git a/docs/pics/db808eff-31d7-4229-a4ad-b8ae71870a3a.png b/docs/pics/db808eff-31d7-4229-a4ad-b8ae71870a3a.png deleted file mode 100644 index 1fc4f47e..00000000 Binary files a/docs/pics/db808eff-31d7-4229-a4ad-b8ae71870a3a.png and /dev/null differ diff --git a/docs/pics/db85a909-5e11-48b2-85d2-f003e7bb35c0.png b/docs/pics/db85a909-5e11-48b2-85d2-f003e7bb35c0.png deleted file mode 100644 index 2c87f48e..00000000 Binary files a/docs/pics/db85a909-5e11-48b2-85d2-f003e7bb35c0.png and /dev/null differ diff --git a/docs/pics/dc00f70e-c5c8-4d20-baf1-2d70014a97e3.jpg b/docs/pics/dc00f70e-c5c8-4d20-baf1-2d70014a97e3.jpg deleted file mode 100644 index aa4cdad8..00000000 Binary files a/docs/pics/dc00f70e-c5c8-4d20-baf1-2d70014a97e3.jpg and /dev/null differ diff --git a/docs/pics/dc82f0f3-c1d4-4ac8-90ac-d5b32a9bd75a.jpg b/docs/pics/dc82f0f3-c1d4-4ac8-90ac-d5b32a9bd75a.jpg deleted file mode 100644 index 6a5c3e4b..00000000 Binary files a/docs/pics/dc82f0f3-c1d4-4ac8-90ac-d5b32a9bd75a.jpg and /dev/null differ diff --git a/docs/pics/dc964b86-7a08-4bde-a3d9-e6ddceb29f98.png b/docs/pics/dc964b86-7a08-4bde-a3d9-e6ddceb29f98.png deleted file mode 100644 index a08e6be1..00000000 Binary files a/docs/pics/dc964b86-7a08-4bde-a3d9-e6ddceb29f98.png and /dev/null differ diff --git a/docs/pics/dcdbb96c-9077-4121-aeb8-743e54ac02a4.png b/docs/pics/dcdbb96c-9077-4121-aeb8-743e54ac02a4.png deleted file mode 100644 index f97a64bd..00000000 Binary files a/docs/pics/dcdbb96c-9077-4121-aeb8-743e54ac02a4.png and /dev/null differ diff --git a/docs/pics/dd3b289c-d90e-44a6-a44c-4880517eb1de.png b/docs/pics/dd3b289c-d90e-44a6-a44c-4880517eb1de.png deleted file mode 100644 index 53dd099d..00000000 Binary files a/docs/pics/dd3b289c-d90e-44a6-a44c-4880517eb1de.png and /dev/null differ diff --git a/docs/pics/dd563037-fcaa-4bd8-83b6-b39d93a12c77.jpg b/docs/pics/dd563037-fcaa-4bd8-83b6-b39d93a12c77.jpg deleted file mode 100644 index 91072441..00000000 Binary files a/docs/pics/dd563037-fcaa-4bd8-83b6-b39d93a12c77.jpg and /dev/null differ diff --git a/docs/pics/de9b9ea0-1327-4865-93e5-6f805c48bc9e.png b/docs/pics/de9b9ea0-1327-4865-93e5-6f805c48bc9e.png deleted file mode 100644 index d2e5e8fe..00000000 Binary files a/docs/pics/de9b9ea0-1327-4865-93e5-6f805c48bc9e.png and /dev/null differ diff --git a/docs/pics/dfd5d3f8-673c-486b-8ecf-d2082107b67b.png b/docs/pics/dfd5d3f8-673c-486b-8ecf-d2082107b67b.png deleted file mode 100644 index 11aaa325..00000000 Binary files a/docs/pics/dfd5d3f8-673c-486b-8ecf-d2082107b67b.png and /dev/null differ diff --git a/docs/pics/docker-filesystems-busyboxrw.png b/docs/pics/docker-filesystems-busyboxrw.png deleted file mode 100644 index 5f046cbc..00000000 Binary files a/docs/pics/docker-filesystems-busyboxrw.png and /dev/null differ diff --git a/docs/pics/e0870f80-b79e-4542-ae39-7420d4b0d8fe.png b/docs/pics/e0870f80-b79e-4542-ae39-7420d4b0d8fe.png deleted file mode 100644 index a6447ad1..00000000 Binary files a/docs/pics/e0870f80-b79e-4542-ae39-7420d4b0d8fe.png and /dev/null differ diff --git a/docs/pics/e0900bb2-220a-43b7-9aa9-1d5cd55ff56e.png b/docs/pics/e0900bb2-220a-43b7-9aa9-1d5cd55ff56e.png deleted file mode 100644 index b4c565fb..00000000 Binary files a/docs/pics/e0900bb2-220a-43b7-9aa9-1d5cd55ff56e.png and /dev/null differ diff --git a/docs/pics/e130e5b8-b19a-4f1e-b860-223040525cf6.jpg b/docs/pics/e130e5b8-b19a-4f1e-b860-223040525cf6.jpg deleted file mode 100644 index 17e92f78..00000000 Binary files a/docs/pics/e130e5b8-b19a-4f1e-b860-223040525cf6.jpg and /dev/null differ diff --git a/docs/pics/e151b5df-5390-4365-b66e-b130cd253c12.png b/docs/pics/e151b5df-5390-4365-b66e-b130cd253c12.png deleted file mode 100644 index d1ea8287..00000000 Binary files a/docs/pics/e151b5df-5390-4365-b66e-b130cd253c12.png and /dev/null differ diff --git a/docs/pics/e1ab9f28-cb15-4178-84b2-98aad87f9bc8.jpg b/docs/pics/e1ab9f28-cb15-4178-84b2-98aad87f9bc8.jpg deleted file mode 100644 index 150da804..00000000 Binary files a/docs/pics/e1ab9f28-cb15-4178-84b2-98aad87f9bc8.jpg and /dev/null differ diff --git a/docs/pics/e1eda3d5-5ec8-4708-8e25-1a04c5e11f48.png b/docs/pics/e1eda3d5-5ec8-4708-8e25-1a04c5e11f48.png deleted file mode 100644 index bffe7520..00000000 Binary files a/docs/pics/e1eda3d5-5ec8-4708-8e25-1a04c5e11f48.png and /dev/null differ diff --git a/docs/pics/e2190c36-8b27-4690-bde5-9911020a1294.png b/docs/pics/e2190c36-8b27-4690-bde5-9911020a1294.png deleted file mode 100644 index e0243d9c..00000000 Binary files a/docs/pics/e2190c36-8b27-4690-bde5-9911020a1294.png and /dev/null differ diff --git a/docs/pics/e3124763-f75e-46c3-ba82-341e6c98d862.jpg b/docs/pics/e3124763-f75e-46c3-ba82-341e6c98d862.jpg deleted file mode 100644 index 80643657..00000000 Binary files a/docs/pics/e3124763-f75e-46c3-ba82-341e6c98d862.jpg and /dev/null differ diff --git a/docs/pics/e325a903-f0b1-4fbd-82bf-88913dc2f290.png b/docs/pics/e325a903-f0b1-4fbd-82bf-88913dc2f290.png deleted file mode 100644 index 68f2e23f..00000000 Binary files a/docs/pics/e325a903-f0b1-4fbd-82bf-88913dc2f290.png and /dev/null differ diff --git a/docs/pics/e3f1657c-80fc-4dfa-9643-bf51abd201c6.png b/docs/pics/e3f1657c-80fc-4dfa-9643-bf51abd201c6.png deleted file mode 100644 index be72990c..00000000 Binary files a/docs/pics/e3f1657c-80fc-4dfa-9643-bf51abd201c6.png and /dev/null differ diff --git a/docs/pics/e41405a8-7c05-4f70-8092-e961e28d3112.jpg b/docs/pics/e41405a8-7c05-4f70-8092-e961e28d3112.jpg deleted file mode 100644 index f922db60..00000000 Binary files a/docs/pics/e41405a8-7c05-4f70-8092-e961e28d3112.jpg and /dev/null differ diff --git a/docs/pics/e42f188f-f4a9-4e6f-88fc-45f4682072fb.png b/docs/pics/e42f188f-f4a9-4e6f-88fc-45f4682072fb.png deleted file mode 100644 index 6f01f0b3..00000000 Binary files a/docs/pics/e42f188f-f4a9-4e6f-88fc-45f4682072fb.png and /dev/null differ diff --git a/docs/pics/e69537d2-a016-4676-b169-9ea17eeb9037.gif b/docs/pics/e69537d2-a016-4676-b169-9ea17eeb9037.gif deleted file mode 100644 index 4e90f7b1..00000000 Binary files a/docs/pics/e69537d2-a016-4676-b169-9ea17eeb9037.gif and /dev/null differ diff --git a/docs/pics/e6bded8e-41a0-489a-88a6-638e88ab7666.jpg b/docs/pics/e6bded8e-41a0-489a-88a6-638e88ab7666.jpg deleted file mode 100644 index 1daa964e..00000000 Binary files a/docs/pics/e6bded8e-41a0-489a-88a6-638e88ab7666.jpg and /dev/null differ diff --git a/docs/pics/e738a3d2-f42e-4755-ae13-ca23497e7a97.png b/docs/pics/e738a3d2-f42e-4755-ae13-ca23497e7a97.png deleted file mode 100644 index d61f5515..00000000 Binary files a/docs/pics/e738a3d2-f42e-4755-ae13-ca23497e7a97.png and /dev/null differ diff --git a/docs/pics/e92d0ebc-7d46-413b-aec1-34a39602f787.png b/docs/pics/e92d0ebc-7d46-413b-aec1-34a39602f787.png deleted file mode 100644 index 99f6c33d..00000000 Binary files a/docs/pics/e92d0ebc-7d46-413b-aec1-34a39602f787.png and /dev/null differ diff --git a/docs/pics/e98deb5a-d5d4-4294-aa9b-9220d4483403.jpg b/docs/pics/e98deb5a-d5d4-4294-aa9b-9220d4483403.jpg deleted file mode 100644 index d855ff8d..00000000 Binary files a/docs/pics/e98deb5a-d5d4-4294-aa9b-9220d4483403.jpg and /dev/null differ diff --git a/docs/pics/e98e9d20-206b-4533-bacf-3448d0096f38.png b/docs/pics/e98e9d20-206b-4533-bacf-3448d0096f38.png deleted file mode 100644 index 4b71bf11..00000000 Binary files a/docs/pics/e98e9d20-206b-4533-bacf-3448d0096f38.png and /dev/null differ diff --git a/docs/pics/eaa506b6-0747-4bee-81f8-3cda795d8154.png b/docs/pics/eaa506b6-0747-4bee-81f8-3cda795d8154.png deleted file mode 100644 index 2cf0d857..00000000 Binary files a/docs/pics/eaa506b6-0747-4bee-81f8-3cda795d8154.png and /dev/null differ diff --git a/docs/pics/eb859228-c0f2-4bce-910d-d9f76929352b.png b/docs/pics/eb859228-c0f2-4bce-910d-d9f76929352b.png deleted file mode 100644 index 7104f020..00000000 Binary files a/docs/pics/eb859228-c0f2-4bce-910d-d9f76929352b.png and /dev/null differ diff --git a/docs/pics/ec4d7464-7140-46d8-827e-d63634202e1e.png b/docs/pics/ec4d7464-7140-46d8-827e-d63634202e1e.png deleted file mode 100644 index aa7d4fa8..00000000 Binary files a/docs/pics/ec4d7464-7140-46d8-827e-d63634202e1e.png and /dev/null differ diff --git a/docs/pics/ec840967-d127-4da3-b6bb-186996c56746.png b/docs/pics/ec840967-d127-4da3-b6bb-186996c56746.png deleted file mode 100644 index 35599ebf..00000000 Binary files a/docs/pics/ec840967-d127-4da3-b6bb-186996c56746.png and /dev/null differ diff --git a/docs/pics/ec923dc7-864c-47b0-a411-1f2c48d084de.png b/docs/pics/ec923dc7-864c-47b0-a411-1f2c48d084de.png deleted file mode 100644 index 627fda37..00000000 Binary files a/docs/pics/ec923dc7-864c-47b0-a411-1f2c48d084de.png and /dev/null differ diff --git a/docs/pics/eca1f422-8381-409b-ad04-98ef39ae38ba.png b/docs/pics/eca1f422-8381-409b-ad04-98ef39ae38ba.png deleted file mode 100644 index ea25e3d8..00000000 Binary files a/docs/pics/eca1f422-8381-409b-ad04-98ef39ae38ba.png and /dev/null differ diff --git a/docs/pics/ecd89a22-c075-4716-8423-e0ba89230e9a.jpg b/docs/pics/ecd89a22-c075-4716-8423-e0ba89230e9a.jpg deleted file mode 100644 index 7de3770b..00000000 Binary files a/docs/pics/ecd89a22-c075-4716-8423-e0ba89230e9a.jpg and /dev/null differ diff --git a/docs/pics/ecf8ad5d-5403-48b9-b6e7-f2e20ff1552090620367.png b/docs/pics/ecf8ad5d-5403-48b9-b6e7-f2e20ff1552090620367.png deleted file mode 100644 index 25ed7497..00000000 Binary files a/docs/pics/ecf8ad5d-5403-48b9-b6e7-f2e20ff1552090620367.png and /dev/null differ diff --git a/docs/pics/ecf8ad5d-5403-48b9-b6e7-f2e20ffe8fca.png b/docs/pics/ecf8ad5d-5403-48b9-b6e7-f2e20ffe8fca.png deleted file mode 100644 index 25ed7497..00000000 Binary files a/docs/pics/ecf8ad5d-5403-48b9-b6e7-f2e20ffe8fca.png and /dev/null differ diff --git a/docs/pics/ed523051-608f-4c3f-b343-383e2d194470.png b/docs/pics/ed523051-608f-4c3f-b343-383e2d194470.png deleted file mode 100644 index 1f703e2f..00000000 Binary files a/docs/pics/ed523051-608f-4c3f-b343-383e2d194470.png and /dev/null differ diff --git a/docs/pics/ed5522bb-3a60-481c-8654-43e7195a48fe.png b/docs/pics/ed5522bb-3a60-481c-8654-43e7195a48fe.png deleted file mode 100644 index 1c153a8a..00000000 Binary files a/docs/pics/ed5522bb-3a60-481c-8654-43e7195a48fe.png and /dev/null differ diff --git a/docs/pics/ed77b0e6-38d9-4a34-844f-724f3ffa2c12.jpg b/docs/pics/ed77b0e6-38d9-4a34-844f-724f3ffa2c12.jpg deleted file mode 100644 index 9aac1677..00000000 Binary files a/docs/pics/ed77b0e6-38d9-4a34-844f-724f3ffa2c12.jpg and /dev/null differ diff --git a/docs/pics/ee994da4-0fc7-443d-ac56-c08caf00a204.jpg b/docs/pics/ee994da4-0fc7-443d-ac56-c08caf00a204.jpg deleted file mode 100644 index c390adc7..00000000 Binary files a/docs/pics/ee994da4-0fc7-443d-ac56-c08caf00a204.jpg and /dev/null differ diff --git a/docs/pics/ef25ff7c-0f63-420d-8b30-eafbeea35d11.gif b/docs/pics/ef25ff7c-0f63-420d-8b30-eafbeea35d11.gif deleted file mode 100644 index ee7c43a1..00000000 Binary files a/docs/pics/ef25ff7c-0f63-420d-8b30-eafbeea35d11.gif and /dev/null differ diff --git a/docs/pics/ef552ae3-ae0d-4217-88e6-99cbe8163f0c.jpg b/docs/pics/ef552ae3-ae0d-4217-88e6-99cbe8163f0c.jpg deleted file mode 100644 index 7205887b..00000000 Binary files a/docs/pics/ef552ae3-ae0d-4217-88e6-99cbe8163f0c.jpg and /dev/null differ diff --git a/docs/pics/f0574025-c514-49f5-a591-6d6a71f271f7.jpg b/docs/pics/f0574025-c514-49f5-a591-6d6a71f271f7.jpg deleted file mode 100644 index 9fe38a46..00000000 Binary files a/docs/pics/f0574025-c514-49f5-a591-6d6a71f271f7.jpg and /dev/null differ diff --git a/docs/pics/f1912ba6-6402-4321-9aa8-13d32fd121d1.jpg b/docs/pics/f1912ba6-6402-4321-9aa8-13d32fd121d1.jpg deleted file mode 100644 index dd8ac0b4..00000000 Binary files a/docs/pics/f1912ba6-6402-4321-9aa8-13d32fd121d1.jpg and /dev/null differ diff --git a/docs/pics/f3131e98-8d20-4ff9-b14b-d6803691555844133783.png b/docs/pics/f3131e98-8d20-4ff9-b14b-d6803691555844133783.png deleted file mode 100644 index 361f9dce..00000000 Binary files a/docs/pics/f3131e98-8d20-4ff9-b14b-d6803691555844133783.png and /dev/null differ diff --git a/docs/pics/f48883c8-9d8a-494e-99a4-317d8ddb8552.png b/docs/pics/f48883c8-9d8a-494e-99a4-317d8ddb8552.png deleted file mode 100644 index 3b612ba1..00000000 Binary files a/docs/pics/f48883c8-9d8a-494e-99a4-317d8ddb8552.png and /dev/null differ diff --git a/docs/pics/f4d0afd0-8e78-4914-9e60-4366eaf065b5.png b/docs/pics/f4d0afd0-8e78-4914-9e60-4366eaf065b5.png deleted file mode 100644 index a40e2616..00000000 Binary files a/docs/pics/f4d0afd0-8e78-4914-9e60-4366eaf065b5.png and /dev/null differ diff --git a/docs/pics/f4d534ab-0092-4a81-9e5b-ae889b9a72be.jpg b/docs/pics/f4d534ab-0092-4a81-9e5b-ae889b9a72be.jpg deleted file mode 100644 index 1d85456a..00000000 Binary files a/docs/pics/f4d534ab-0092-4a81-9e5b-ae889b9a72be.jpg and /dev/null differ diff --git a/docs/pics/f5792051-d9b2-4ca4-a234-a4a2de3d5a57.png b/docs/pics/f5792051-d9b2-4ca4-a234-a4a2de3d5a57.png deleted file mode 100644 index 95a55e94..00000000 Binary files a/docs/pics/f5792051-d9b2-4ca4-a234-a4a2de3d5a57.png and /dev/null differ diff --git a/docs/pics/f579cab0-3d49-4d00-8e14-e9e1669d0f9f.png b/docs/pics/f579cab0-3d49-4d00-8e14-e9e1669d0f9f.png deleted file mode 100644 index 403aaf17..00000000 Binary files a/docs/pics/f579cab0-3d49-4d00-8e14-e9e1669d0f9f.png and /dev/null differ diff --git a/docs/pics/f5cb6028-425d-4939-91eb-cca9dd6b6c6c.jpg b/docs/pics/f5cb6028-425d-4939-91eb-cca9dd6b6c6c.jpg deleted file mode 100644 index ae2be09e..00000000 Binary files a/docs/pics/f5cb6028-425d-4939-91eb-cca9dd6b6c6c.jpg and /dev/null differ diff --git a/docs/pics/f61b5419-c94a-4df1-8d4d-aed9ae8cc6d5.png b/docs/pics/f61b5419-c94a-4df1-8d4d-aed9ae8cc6d5.png deleted file mode 100644 index 10ca0879..00000000 Binary files a/docs/pics/f61b5419-c94a-4df1-8d4d-aed9ae8cc6d5.png and /dev/null differ diff --git a/docs/pics/f6e146f1-57ad-411b-beb3-770a142164ef.png b/docs/pics/f6e146f1-57ad-411b-beb3-770a142164ef.png deleted file mode 100644 index 8b25cf20..00000000 Binary files a/docs/pics/f6e146f1-57ad-411b-beb3-770a142164ef.png and /dev/null differ diff --git a/docs/pics/f71af66b-0d54-4399-a44b-f47b58321984.png b/docs/pics/f71af66b-0d54-4399-a44b-f47b58321984.png deleted file mode 100644 index ba64d5ea..00000000 Binary files a/docs/pics/f71af66b-0d54-4399-a44b-f47b58321984.png and /dev/null differ diff --git a/docs/pics/f74144be-857a-40cd-8ec7-87626ef4e20b.png b/docs/pics/f74144be-857a-40cd-8ec7-87626ef4e20b.png deleted file mode 100644 index 33349af1..00000000 Binary files a/docs/pics/f74144be-857a-40cd-8ec7-87626ef4e20b.png and /dev/null differ diff --git a/docs/pics/f7d170a3-e446-4a64-ac2d-cb95028f81a8.png b/docs/pics/f7d170a3-e446-4a64-ac2d-cb95028f81a8.png deleted file mode 100644 index ccc91793..00000000 Binary files a/docs/pics/f7d170a3-e446-4a64-ac2d-cb95028f81a8.png and /dev/null differ diff --git a/docs/pics/f87afe72-c2df-4c12-ac03-9b8d581a8af8.jpg b/docs/pics/f87afe72-c2df-4c12-ac03-9b8d581a8af8.jpg deleted file mode 100644 index 1a025366..00000000 Binary files a/docs/pics/f87afe72-c2df-4c12-ac03-9b8d581a8af8.jpg and /dev/null differ diff --git a/docs/pics/f8b3f73d-0fda-449f-b55b-fa36b7ac04cd.png b/docs/pics/f8b3f73d-0fda-449f-b55b-fa36b7ac04cd.png deleted file mode 100644 index c4dbe764..00000000 Binary files a/docs/pics/f8b3f73d-0fda-449f-b55b-fa36b7ac04cd.png and /dev/null differ diff --git a/docs/pics/f900f266-a323-42b2-bc43-218fdb8811a8.jpg b/docs/pics/f900f266-a323-42b2-bc43-218fdb8811a8.jpg deleted file mode 100644 index ca0c3096..00000000 Binary files a/docs/pics/f900f266-a323-42b2-bc43-218fdb8811a8.jpg and /dev/null differ diff --git a/docs/pics/f9240aa1-8d48-4959-b28a-7ca45c3e4d91.png b/docs/pics/f9240aa1-8d48-4959-b28a-7ca45c3e4d91.png deleted file mode 100644 index 839e8f4f..00000000 Binary files a/docs/pics/f9240aa1-8d48-4959-b28a-7ca45c3e4d91.png and /dev/null differ diff --git a/docs/pics/f9978fa6-9f49-4a0f-8540-02d269ac448f.png b/docs/pics/f9978fa6-9f49-4a0f-8540-02d269ac448f.png deleted file mode 100644 index a72845ef..00000000 Binary files a/docs/pics/f9978fa6-9f49-4a0f-8540-02d269ac448f.png and /dev/null differ diff --git a/docs/pics/f99ee771-c56f-47fb-9148-c0036695b5fe.jpg b/docs/pics/f99ee771-c56f-47fb-9148-c0036695b5fe.jpg deleted file mode 100644 index 96e22a72..00000000 Binary files a/docs/pics/f99ee771-c56f-47fb-9148-c0036695b5fe.jpg and /dev/null differ diff --git a/docs/pics/f9f2a16b-4843-44d1-9759-c745772e9bcf.jpg b/docs/pics/f9f2a16b-4843-44d1-9759-c745772e9bcf.jpg deleted file mode 100644 index b2265de9..00000000 Binary files a/docs/pics/f9f2a16b-4843-44d1-9759-c745772e9bcf.jpg and /dev/null differ diff --git a/docs/pics/fb327611-7e2b-4f2f-9f5b-38592d408f07.png b/docs/pics/fb327611-7e2b-4f2f-9f5b-38592d408f07.png deleted file mode 100644 index 774ecf10..00000000 Binary files a/docs/pics/fb327611-7e2b-4f2f-9f5b-38592d408f07.png and /dev/null differ diff --git a/docs/pics/fb3b8f7a-4293-4a38-aae1-62284db979a3.png b/docs/pics/fb3b8f7a-4293-4a38-aae1-62284db979a3.png deleted file mode 100644 index 6575dc98..00000000 Binary files a/docs/pics/fb3b8f7a-4293-4a38-aae1-62284db979a3.png and /dev/null differ diff --git a/docs/pics/fb44307f-8e98-4ff7-a918-31dacfa564b4.jpg b/docs/pics/fb44307f-8e98-4ff7-a918-31dacfa564b4.jpg deleted file mode 100644 index f4690971..00000000 Binary files a/docs/pics/fb44307f-8e98-4ff7-a918-31dacfa564b4.jpg and /dev/null differ diff --git a/docs/pics/fcc941ec-134b-4dcd-bc86-1702fd305300.gif b/docs/pics/fcc941ec-134b-4dcd-bc86-1702fd305300.gif deleted file mode 100644 index 8296aff5..00000000 Binary files a/docs/pics/fcc941ec-134b-4dcd-bc86-1702fd305300.gif and /dev/null differ diff --git a/docs/pics/fdc45a09-f838-4348-8959-d2c793727788.png b/docs/pics/fdc45a09-f838-4348-8959-d2c793727788.png deleted file mode 100644 index 7463b34f..00000000 Binary files a/docs/pics/fdc45a09-f838-4348-8959-d2c793727788.png and /dev/null differ diff --git a/docs/pics/fec3ba89-115a-4cf9-b165-756757644641.png b/docs/pics/fec3ba89-115a-4cf9-b165-756757644641.png deleted file mode 100644 index 1a313d2d..00000000 Binary files a/docs/pics/fec3ba89-115a-4cf9-b165-756757644641.png and /dev/null differ diff --git a/docs/pics/ff5152fc-4ff3-44c4-95d6-1061002c364a.png b/docs/pics/ff5152fc-4ff3-44c4-95d6-1061002c364a.png deleted file mode 100644 index 31831acc..00000000 Binary files a/docs/pics/ff5152fc-4ff3-44c4-95d6-1061002c364a.png and /dev/null differ diff --git a/docs/pics/ffd96b99-8009-487c-8e98-11c9d44ef14f.png b/docs/pics/ffd96b99-8009-487c-8e98-11c9d44ef14f.png deleted file mode 100644 index b01c1ca0..00000000 Binary files a/docs/pics/ffd96b99-8009-487c-8e98-11c9d44ef14f.png and /dev/null differ diff --git a/docs/pics/flow.png b/docs/pics/flow.png deleted file mode 100644 index e8399749..00000000 Binary files a/docs/pics/flow.png and /dev/null differ diff --git a/docs/pics/inode_with_signatures.jpg b/docs/pics/inode_with_signatures.jpg deleted file mode 100644 index ed6b0e30..00000000 Binary files a/docs/pics/inode_with_signatures.jpg and /dev/null differ diff --git a/docs/pics/linux-filesystem.png b/docs/pics/linux-filesystem.png deleted file mode 100644 index b56fe50b..00000000 Binary files a/docs/pics/linux-filesystem.png and /dev/null differ diff --git a/docs/pics/master-slave-proxy.png b/docs/pics/master-slave-proxy.png deleted file mode 100644 index 6f47b010..00000000 Binary files a/docs/pics/master-slave-proxy.png and /dev/null differ diff --git a/docs/pics/master-slave.png b/docs/pics/master-slave.png deleted file mode 100644 index fa4a1e17..00000000 Binary files a/docs/pics/master-slave.png and /dev/null differ diff --git a/docs/pics/network-of-networks.gif b/docs/pics/network-of-networks.gif deleted file mode 100644 index 7473f913..00000000 Binary files a/docs/pics/network-of-networks.gif and /dev/null differ diff --git a/docs/pics/ssl-offloading.jpg b/docs/pics/ssl-offloading.jpg deleted file mode 100644 index 8f01a418..00000000 Binary files a/docs/pics/ssl-offloading.jpg and /dev/null differ diff --git a/docs/pics/tGPV0.png b/docs/pics/tGPV0.png deleted file mode 100644 index 89fb7bfe..00000000 Binary files a/docs/pics/tGPV0.png and /dev/null differ diff --git a/notes/10.1 斐波那契数列.md b/notes/10.1 斐波那契数列.md new file mode 100644 index 00000000..50f2744f --- /dev/null +++ b/notes/10.1 斐波那契数列.md @@ -0,0 +1,74 @@ +# 10.1 斐波那契数列 + +[NowCoder](https://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3?tpId=13&tqId=11160&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +求斐波那契数列的第 n 项,n <= 39。 + + + +

+ +## 解题思路 + +如果使用递归求解,会重复计算一些子问题。例如,计算 f(4) 需要计算 f(3) 和 f(2),计算 f(3) 需要计算 f(2) 和 f(1),可以看到 f(2) 被重复计算了。 + +

+ +递归是将一个问题划分成多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,从而避免重复求解子问题。 + +```java +public int Fibonacci(int n) { + if (n <= 1) + return n; + int[] fib = new int[n + 1]; + fib[1] = 1; + for (int i = 2; i <= n; i++) + fib[i] = fib[i - 1] + fib[i - 2]; + return fib[n]; +} +``` + +考虑到第 i 项只与第 i-1 和第 i-2 项有关,因此只需要存储前两项的值就能求解第 i 项,从而将空间复杂度由 O(N) 降低为 O(1)。 + +```java +public int Fibonacci(int n) { + if (n <= 1) + return n; + int pre2 = 0, pre1 = 1; + int fib = 0; + for (int i = 2; i <= n; i++) { + fib = pre2 + pre1; + pre2 = pre1; + pre1 = fib; + } + return fib; +} +``` + +由于待求解的 n 小于 40,因此可以将前 40 项的结果先进行计算,之后就能以 O(1) 时间复杂度得到第 n 项的值。 + +```java +public class Solution { + + private int[] fib = new int[40]; + + public Solution() { + fib[1] = 1; + for (int i = 2; i < fib.length; i++) + fib[i] = fib[i - 1] + fib[i - 2]; + } + + public int Fibonacci(int n) { + return fib[n]; + } +} +``` + + + + + + +
diff --git a/notes/10.2 矩形覆盖.md b/notes/10.2 矩形覆盖.md new file mode 100644 index 00000000..a95e2b03 --- /dev/null +++ b/notes/10.2 矩形覆盖.md @@ -0,0 +1,47 @@ +# 10.2 矩形覆盖 + +[NowCoder](https://www.nowcoder.com/practice/72a5a919508a4251859fb2cfb987a0e6?tpId=13&tqId=11163&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +我们可以用 2\*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2\*1 的小矩形无重叠地覆盖一个 2\*n 的大矩形,总共有多少种方法? + +

+ +## 解题思路 + +当 n 为 1 时,只有一种覆盖方法: + +

+ +当 n 为 2 时,有两种覆盖方法: + +

+ +要覆盖 2\*n 的大矩形,可以先覆盖 2\*1 的矩形,再覆盖 2\*(n-1) 的矩形;或者先覆盖 2\*2 的矩形,再覆盖 2\*(n-2) 的矩形。而覆盖 2\*(n-1) 和 2\*(n-2) 的矩形可以看成子问题。该问题的递推公式如下: + + + +

+ +```java +public int RectCover(int n) { + if (n <= 2) + return n; + int pre2 = 1, pre1 = 2; + int result = 0; + for (int i = 3; i <= n; i++) { + result = pre2 + pre1; + pre2 = pre1; + pre1 = result; + } + return result; +} +``` + + + + + + +
diff --git a/notes/10.3 跳台阶.md b/notes/10.3 跳台阶.md new file mode 100644 index 00000000..32c79ea5 --- /dev/null +++ b/notes/10.3 跳台阶.md @@ -0,0 +1,45 @@ +# 10.3 跳台阶 + +[NowCoder](https://www.nowcoder.com/practice/8c82a5b80378478f9484d87d1c5f12a4?tpId=13&tqId=11161&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 + +

+ +## 解题思路 + +当 n = 1 时,只有一种跳法: + +

+ +当 n = 2 时,有两种跳法: + +

+ +跳 n 阶台阶,可以先跳 1 阶台阶,再跳 n-1 阶台阶;或者先跳 2 阶台阶,再跳 n-2 阶台阶。而 n-1 和 n-2 阶台阶的跳法可以看成子问题,该问题的递推公式为: + +

+ +```java +public int JumpFloor(int n) { + if (n <= 2) + return n; + int pre2 = 1, pre1 = 2; + int result = 0; + for (int i = 2; i < n; i++) { + result = pre2 + pre1; + pre2 = pre1; + pre1 = result; + } + return result; +} +``` + + + + + + +
diff --git a/notes/10.4 变态跳台阶.md b/notes/10.4 变态跳台阶.md new file mode 100644 index 00000000..8ea29fca --- /dev/null +++ b/notes/10.4 变态跳台阶.md @@ -0,0 +1,65 @@ +# 10.4 变态跳台阶 + +[NowCoder](https://www.nowcoder.com/practice/22243d016f6b47f2a6928b4313c85387?tpId=13&tqId=11162&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级... 它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 + +

+ +## 解题思路 + +### 动态规划 + +```java +public int JumpFloorII(int target) { + int[] dp = new int[target]; + Arrays.fill(dp, 1); + for (int i = 1; i < target; i++) + for (int j = 0; j < i; j++) + dp[i] += dp[j]; + return dp[target - 1]; +} +``` + +### 数学推导 + +跳上 n-1 级台阶,可以从 n-2 级跳 1 级上去,也可以从 n-3 级跳 2 级上去...,那么 + +``` +f(n-1) = f(n-2) + f(n-3) + ... + f(0) +``` + +同样,跳上 n 级台阶,可以从 n-1 级跳 1 级上去,也可以从 n-2 级跳 2 级上去... ,那么 + +``` +f(n) = f(n-1) + f(n-2) + ... + f(0) +``` + +综上可得 + +``` +f(n) - f(n-1) = f(n-1) +``` + +即 + +``` +f(n) = 2*f(n-1) +``` + +所以 f(n) 是一个等比数列 + +```source-java +public int JumpFloorII(int target) { + return (int) Math.pow(2, target - 1); +} +``` + + + + + + +
diff --git a/notes/11. 旋转数组的最小数字.md b/notes/11. 旋转数组的最小数字.md new file mode 100644 index 00000000..07baaf8a --- /dev/null +++ b/notes/11. 旋转数组的最小数字.md @@ -0,0 +1,72 @@ +# 11. 旋转数组的最小数字 + +[NowCoder](https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=13&tqId=11159&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 + +

+ +## 解题思路 + +将旋转数组对半分可以得到一个包含最小元素的新旋转数组,以及一个非递减排序的数组。新的旋转数组的数组元素是原数组的一半,从而将问题规模减少了一半,这种折半性质的算法的时间复杂度为 O(logN)(为了方便,这里将 log2N 写为 logN)。 + +

+ +此时问题的关键在于确定对半分得到的两个数组哪一个是旋转数组,哪一个是非递减数组。我们很容易知道非递减数组的第一个元素一定小于等于最后一个元素。 + +通过修改二分查找算法进行求解(l 代表 low,m 代表 mid,h 代表 high): + +- 当 nums[m] <= nums[h] 时,表示 [m, h] 区间内的数组是非递减数组,[l, m] 区间内的数组是旋转数组,此时令 h = m; +- 否则 [m + 1, h] 区间内的数组是旋转数组,令 l = m + 1。 + +```java +public int minNumberInRotateArray(int[] nums) { + if (nums.length == 0) + return 0; + int l = 0, h = nums.length - 1; + while (l < h) { + int m = l + (h - l) / 2; + if (nums[m] <= nums[h]) + h = m; + else + l = m + 1; + } + return nums[l]; +} +``` + +如果数组元素允许重复,会出现一个特殊的情况:nums[l] == nums[m] == nums[h],此时无法确定解在哪个区间,需要切换到顺序查找。例如对于数组 {1,1,1,0,1},l、m 和 h 指向的数都为 1,此时无法知道最小数字 0 在哪个区间。 + +```java +public int minNumberInRotateArray(int[] nums) { + if (nums.length == 0) + return 0; + int l = 0, h = nums.length - 1; + while (l < h) { + int m = l + (h - l) / 2; + if (nums[l] == nums[m] && nums[m] == nums[h]) + return minNumber(nums, l, h); + else if (nums[m] <= nums[h]) + h = m; + else + l = m + 1; + } + return nums[l]; +} + +private int minNumber(int[] nums, int l, int h) { + for (int i = l; i < h; i++) + if (nums[i] > nums[i + 1]) + return nums[i + 1]; + return nums[l]; +} +``` + + + + + + +
diff --git a/notes/12. 矩阵中的路径.md b/notes/12. 矩阵中的路径.md new file mode 100644 index 00000000..0e84fab5 --- /dev/null +++ b/notes/12. 矩阵中的路径.md @@ -0,0 +1,71 @@ +# 12. 矩阵中的路径 + +[NowCoder](https://www.nowcoder.com/practice/c61c6999eecb4b8f88a98f66b273a3cc?tpId=13&tqId=11218&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向上下左右移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 + +例如下面的矩阵包含了一条 bfce 路径。 + +

+ +## 解题思路 + +使用回溯法(backtracking)进行求解,它是一种暴力搜索方法,通过搜索所有可能的结果来求解问题。回溯法在一次搜索结束时需要进行回溯(回退),将这一次搜索过程中设置的状态进行清除,从而开始一次新的搜索过程。例如下图示例中,从 f 开始,下一步有 4 种搜索可能,如果先搜索 b,需要将 b 标记为已经使用,防止重复使用。在这一次搜索结束之后,需要将 b 的已经使用状态清除,并搜索 c。 + +

+ +本题的输入是数组而不是矩阵(二维数组),因此需要先将数组转换成矩阵。 + +```java +private final static int[][] next = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}}; +private int rows; +private int cols; + +public boolean hasPath(char[] array, int rows, int cols, char[] str) { + if (rows == 0 || cols == 0) return false; + this.rows = rows; + this.cols = cols; + boolean[][] marked = new boolean[rows][cols]; + char[][] matrix = buildMatrix(array); + for (int i = 0; i < rows; i++) + for (int j = 0; j < cols; j++) + if (backtracking(matrix, str, marked, 0, i, j)) + return true; + + return false; +} + +private boolean backtracking(char[][] matrix, char[] str, + boolean[][] marked, int pathLen, int r, int c) { + + if (pathLen == str.length) return true; + if (r < 0 || r >= rows || c < 0 || c >= cols + || matrix[r][c] != str[pathLen] || marked[r][c]) { + + return false; + } + marked[r][c] = true; + for (int[] n : next) + if (backtracking(matrix, str, marked, pathLen + 1, r + n[0], c + n[1])) + return true; + marked[r][c] = false; + return false; +} + +private char[][] buildMatrix(char[] array) { + char[][] matrix = new char[rows][cols]; + for (int r = 0, idx = 0; r < rows; r++) + for (int c = 0; c < cols; c++) + matrix[r][c] = array[idx++]; + return matrix; +} +``` + + + + + + +
diff --git a/notes/13. 机器人的运动范围.md b/notes/13. 机器人的运动范围.md new file mode 100644 index 00000000..0da8fed7 --- /dev/null +++ b/notes/13. 机器人的运动范围.md @@ -0,0 +1,65 @@ +# 13. 机器人的运动范围 + +[NowCoder](https://www.nowcoder.com/practice/6e5207314b5241fb83f2329e89fdecc8?tpId=13&tqId=11219&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +地上有一个 m 行和 n 列的方格。一个机器人从坐标 (0, 0) 的格子开始移动,每一次只能向左右上下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 k 的格子。 + +例如,当 k 为 18 时,机器人能够进入方格 (35,37),因为 3+5+3+7=18。但是,它不能进入方格 (35,38),因为 3+5+3+8=19。请问该机器人能够达到多少个格子? + +## 解题思路 + +使用深度优先搜索(Depth First Search,DFS)方法进行求解。回溯是深度优先搜索的一种特例,它在一次搜索过程中需要设置一些本次搜索过程的局部状态,并在本次搜索结束之后清除状态。而普通的深度优先搜索并不需要使用这些局部状态,虽然还是有可能设置一些全局状态。 + +```java +private static final int[][] next = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}}; +private int cnt = 0; +private int rows; +private int cols; +private int threshold; +private int[][] digitSum; + +public int movingCount(int threshold, int rows, int cols) { + this.rows = rows; + this.cols = cols; + this.threshold = threshold; + initDigitSum(); + boolean[][] marked = new boolean[rows][cols]; + dfs(marked, 0, 0); + return cnt; +} + +private void dfs(boolean[][] marked, int r, int c) { + if (r < 0 || r >= rows || c < 0 || c >= cols || marked[r][c]) + return; + marked[r][c] = true; + if (this.digitSum[r][c] > this.threshold) + return; + cnt++; + for (int[] n : next) + dfs(marked, r + n[0], c + n[1]); +} + +private void initDigitSum() { + int[] digitSumOne = new int[Math.max(rows, cols)]; + for (int i = 0; i < digitSumOne.length; i++) { + int n = i; + while (n > 0) { + digitSumOne[i] += n % 10; + n /= 10; + } + } + this.digitSum = new int[rows][cols]; + for (int i = 0; i < this.rows; i++) + for (int j = 0; j < this.cols; j++) + this.digitSum[i][j] = digitSumOne[i] + digitSumOne[j]; +} +``` + + + + + + +
diff --git a/notes/14. 剪绳子.md b/notes/14. 剪绳子.md new file mode 100644 index 00000000..1cac46d3 --- /dev/null +++ b/notes/14. 剪绳子.md @@ -0,0 +1,59 @@ +# 14. 剪绳子 + +[Leetcode](https://leetcode.com/problems/integer-break/description/) + +## 题目描述 + +把一根绳子剪成多段,并且使得每段的长度乘积最大。 + +```html +n = 2 +return 1 (2 = 1 + 1) + +n = 10 +return 36 (10 = 3 + 3 + 4) +``` + +## 解题思路 + +### 贪心 + +尽可能多剪长度为 3 的绳子,并且不允许有长度为 1 的绳子出现。如果出现了,就从已经切好长度为 3 的绳子中拿出一段与长度为 1 的绳子重新组合,把它们切成两段长度为 2 的绳子。 + +证明:当 n >= 5 时,3(n - 3) - n = 2n - 9 > 0,且 2(n - 2) - n = n - 4 > 0。因此在 n >= 5 的情况下,将绳子剪成一段为 2 或者 3,得到的乘积会更大。又因为 3(n - 3) - 2(n - 2) = n - 5 >= 0,所以剪成一段长度为 3 比长度为 2 得到的乘积更大。 + +```java +public int integerBreak(int n) { + if (n < 2) + return 0; + if (n == 2) + return 1; + if (n == 3) + return 2; + int timesOf3 = n / 3; + if (n - timesOf3 * 3 == 1) + timesOf3--; + int timesOf2 = (n - timesOf3 * 3) / 2; + return (int) (Math.pow(3, timesOf3)) * (int) (Math.pow(2, timesOf2)); +} +``` + +### 动态规划 + +```java +public int integerBreak(int n) { + int[] dp = new int[n + 1]; + dp[1] = 1; + for (int i = 2; i <= n; i++) + for (int j = 1; j < i; j++) + dp[i] = Math.max(dp[i], Math.max(j * (i - j), dp[j] * (i - j))); + return dp[n]; +} +``` + + + + + + +
diff --git a/notes/15. 二进制中 1 的个数.md b/notes/15. 二进制中 1 的个数.md new file mode 100644 index 00000000..455764d3 --- /dev/null +++ b/notes/15. 二进制中 1 的个数.md @@ -0,0 +1,47 @@ +# 15. 二进制中 1 的个数 + +[NowCoder](https://www.nowcoder.com/practice/8ee967e43c2c4ec193b040ea7fbb10b8?tpId=13&tqId=11164&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个整数,输出该数二进制表示中 1 的个数。 + +### n&(n-1) + +该位运算去除 n 的位级表示中最低的那一位。 + +``` +n : 10110100 +n-1 : 10110011 +n&(n-1) : 10110000 +``` + +时间复杂度:O(M),其中 M 表示 1 的个数。 + + +```java +public int NumberOf1(int n) { + int cnt = 0; + while (n != 0) { + cnt++; + n &= (n - 1); + } + return cnt; +} +``` + + +### Integer.bitCount() + +```java +public int NumberOf1(int n) { + return Integer.bitCount(n); +} +``` + + + + + + +
diff --git a/notes/16. 数值的整数次方.md b/notes/16. 数值的整数次方.md new file mode 100644 index 00000000..1246d8ba --- /dev/null +++ b/notes/16. 数值的整数次方.md @@ -0,0 +1,43 @@ +# 16. 数值的整数次方 + +[NowCoder](https://www.nowcoder.com/practice/1a834e5e3e1a4b7ba251417554e07c00?tpId=13&tqId=11165&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +给定一个 double 类型的浮点数 base 和 int 类型的整数 exponent,求 base 的 exponent 次方。 + +## 解题思路 + +下面的讨论中 x 代表 base,n 代表 exponent。 + + + +

+ + +因为 (x\*x)n/2 可以通过递归求解,并且每次递归 n 都减小一半,因此整个算法的时间复杂度为 O(logN)。 + +```java +public double Power(double base, int exponent) { + if (exponent == 0) + return 1; + if (exponent == 1) + return base; + boolean isNegative = false; + if (exponent < 0) { + exponent = -exponent; + isNegative = true; + } + double pow = Power(base * base, exponent / 2); + if (exponent % 2 != 0) + pow = pow * base; + return isNegative ? 1 / pow : pow; +} +``` + + + + + + +
diff --git a/notes/17. 打印从 1 到最大的 n 位数.md b/notes/17. 打印从 1 到最大的 n 位数.md new file mode 100644 index 00000000..27a6cd12 --- /dev/null +++ b/notes/17. 打印从 1 到最大的 n 位数.md @@ -0,0 +1,47 @@ +# 17. 打印从 1 到最大的 n 位数 + +## 题目描述 + +输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数即 999。 + +## 解题思路 + +由于 n 可能会非常大,因此不能直接用 int 表示数字,而是用 char 数组进行存储。 + +使用回溯法得到所有的数。 + +```java +public void print1ToMaxOfNDigits(int n) { + if (n <= 0) + return; + char[] number = new char[n]; + print1ToMaxOfNDigits(number, 0); +} + +private void print1ToMaxOfNDigits(char[] number, int digit) { + if (digit == number.length) { + printNumber(number); + return; + } + for (int i = 0; i < 10; i++) { + number[digit] = (char) (i + '0'); + print1ToMaxOfNDigits(number, digit + 1); + } +} + +private void printNumber(char[] number) { + int index = 0; + while (index < number.length && number[index] == '0') + index++; + while (index < number.length) + System.out.print(number[index++]); + System.out.println(); +} +``` + + + + + + +
diff --git a/notes/18.1 在 O(1) 时间内删除链表节点.md b/notes/18.1 在 O(1) 时间内删除链表节点.md new file mode 100644 index 00000000..f0b5fbe1 --- /dev/null +++ b/notes/18.1 在 O(1) 时间内删除链表节点.md @@ -0,0 +1,44 @@ +# 18.1 在 O(1) 时间内删除链表节点 + +## 解题思路 + +① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,然后令该节点指向下下个节点,再删除下一个节点,时间复杂度为 O(1)。 + +

+ +② 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向 null,时间复杂度为 O(N)。 + +

+ +综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个尾节点以 O(N) 的时间复杂度操作节点的总次数。(2N-1)/N \~ 2,因此该算法的平均时间复杂度为 O(1)。 + +```java +public ListNode deleteNode(ListNode head, ListNode tobeDelete) { + if (head == null || tobeDelete == null) + return null; + if (tobeDelete.next != null) { + // 要删除的节点不是尾节点 + ListNode next = tobeDelete.next; + tobeDelete.val = next.val; + tobeDelete.next = next.next; + } else { + if (head == tobeDelete) + // 只有一个节点 + head = null; + else { + ListNode cur = head; + while (cur.next != tobeDelete) + cur = cur.next; + cur.next = null; + } + } + return head; +} +``` + + + + + + +
diff --git a/notes/18.2 删除链表中重复的结点.md b/notes/18.2 删除链表中重复的结点.md new file mode 100644 index 00000000..d5a153fe --- /dev/null +++ b/notes/18.2 删除链表中重复的结点.md @@ -0,0 +1,32 @@ +# 18.2 删除链表中重复的结点 + +[NowCoder](https://www.nowcoder.com/practice/fc533c45b73a41b0b44ccba763f866ef?tpId=13&tqId=11209&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +

+ +## 解题描述 + +```java +public ListNode deleteDuplication(ListNode pHead) { + if (pHead == null || pHead.next == null) + return pHead; + ListNode next = pHead.next; + if (pHead.val == next.val) { + while (next != null && pHead.val == next.val) + next = next.next; + return deleteDuplication(next); + } else { + pHead.next = deleteDuplication(pHead.next); + return pHead; + } +} +``` + + + + + + +
diff --git a/notes/19. 正则表达式匹配.md b/notes/19. 正则表达式匹配.md new file mode 100644 index 00000000..162e2873 --- /dev/null +++ b/notes/19. 正则表达式匹配.md @@ -0,0 +1,47 @@ +# 19. 正则表达式匹配 + +[NowCoder](https://www.nowcoder.com/practice/45327ae22b7b413ea21df13ee7d6429c?tpId=13&tqId=11205&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +请实现一个函数用来匹配包括 '.' 和 '\*' 的正则表达式。模式中的字符 '.' 表示任意一个字符,而 '\*' 表示它前面的字符可以出现任意次(包含 0 次)。 + +在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串 "aaa" 与模式 "a.a" 和 "ab\*ac\*a" 匹配,但是与 "aa.a" 和 "ab\*a" 均不匹配。 + +## 解题思路 + +应该注意到,'.' 是用来当做一个任意字符,而 '\*' 是用来重复前面的字符。这两个的作用不同,不能把 '.' 的作用和 '\*' 进行类比,从而把它当成重复前面字符一次。 + +```java +public boolean match(char[] str, char[] pattern) { + + int m = str.length, n = pattern.length; + boolean[][] dp = new boolean[m + 1][n + 1]; + + dp[0][0] = true; + for (int i = 1; i <= n; i++) + if (pattern[i - 1] == '*') + dp[0][i] = dp[0][i - 2]; + + for (int i = 1; i <= m; i++) + for (int j = 1; j <= n; j++) + if (str[i - 1] == pattern[j - 1] || pattern[j - 1] == '.') + dp[i][j] = dp[i - 1][j - 1]; + else if (pattern[j - 1] == '*') + if (pattern[j - 2] == str[i - 1] || pattern[j - 2] == '.') { + dp[i][j] |= dp[i][j - 1]; // a* counts as single a + dp[i][j] |= dp[i - 1][j]; // a* counts as multiple a + dp[i][j] |= dp[i][j - 2]; // a* counts as empty + } else + dp[i][j] = dp[i][j - 2]; // a* only counts as empty + + return dp[m][n]; +} +``` + + + + + + +
diff --git a/notes/20. 表示数值的字符串.md b/notes/20. 表示数值的字符串.md new file mode 100644 index 00000000..eb158242 --- /dev/null +++ b/notes/20. 表示数值的字符串.md @@ -0,0 +1,56 @@ +# 20. 表示数值的字符串 + +[NowCoder](https://www.nowcoder.com/practice/6f8c901d091949a5837e24bb82a731f2?tpId=13&tqId=11206&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +``` +true + +"+100" +"5e2" +"-123" +"3.1416" +"-1E-16" +``` + +``` +false + +"12e" +"1a3.14" +"1.2.3" +"+-5" +"12e+4.3" +``` + + +## 解题思路 + +使用正则表达式进行匹配。 + +```html +[] : 字符集合 +() : 分组 +? : 重复 0 ~ 1 次 ++ : 重复 1 ~ n 次 +* : 重复 0 ~ n 次 +. : 任意字符 +\\. : 转义后的 . +\\d : 数字 +``` + +```java +public boolean isNumeric(char[] str) { + if (str == null || str.length == 0) + return false; + return new String(str).matches("[+-]?\\d*(\\.\\d+)?([eE][+-]?\\d+)?"); +} +``` + + + + + + +
diff --git a/notes/21. 调整数组顺序使奇数位于偶数前面.md b/notes/21. 调整数组顺序使奇数位于偶数前面.md new file mode 100644 index 00000000..e6904534 --- /dev/null +++ b/notes/21. 调整数组顺序使奇数位于偶数前面.md @@ -0,0 +1,67 @@ +# 21. 调整数组顺序使奇数位于偶数前面 + +[NowCoder](https://www.nowcoder.com/practice/beb5aa231adc45b2a5dcc5b62c93f593?tpId=13&tqId=11166&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +需要保证奇数和奇数,偶数和偶数之间的相对位置不变,这和书本不太一样。 + +

+ +## 解题思路 + +方法一:创建一个新数组,时间复杂度 O(N),空间复杂度 O(N)。 + +```java +public void reOrderArray(int[] nums) { + // 奇数个数 + int oddCnt = 0; + for (int x : nums) + if (!isEven(x)) + oddCnt++; + int[] copy = nums.clone(); + int i = 0, j = oddCnt; + for (int num : copy) { + if (num % 2 == 1) + nums[i++] = num; + else + nums[j++] = num; + } +} + +private boolean isEven(int x) { + return x % 2 == 0; +} +``` + +方法二:使用冒泡思想,每次都当前偶数上浮到当前最右边。时间复杂度 O(N2),空间复杂度 O(1),时间换空间。 + +```java +public void reOrderArray(int[] nums) { + int N = nums.length; + for (int i = N - 1; i > 0; i--) { + for (int j = 0; j < i; j++) { + if (isEven(nums[j]) && !isEven(nums[j + 1])) { + swap(nums, j, j + 1); + } + } + } +} + +private boolean isEven(int x) { + return x % 2 == 0; +} + +private void swap(int[] nums, int i, int j) { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; +} +``` + + + + + + +
diff --git a/notes/22. 链表中倒数第 K 个结点.md b/notes/22. 链表中倒数第 K 个结点.md new file mode 100644 index 00000000..4b2666ff --- /dev/null +++ b/notes/22. 链表中倒数第 K 个结点.md @@ -0,0 +1,34 @@ +# 22. 链表中倒数第 K 个结点 + +[NowCoder](https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&tqId=11167&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +设链表的长度为 N。设置两个指针 P1 和 P2,先让 P1 移动 K 个节点,则还有 N - K 个节点可以移动。此时让 P1 和 P2 同时移动,可以知道当 P1 移动到链表结尾时,P2 移动到第 N - K 个节点处,该位置就是倒数第 K 个节点。 + +

+ +```java +public ListNode FindKthToTail(ListNode head, int k) { + if (head == null) + return null; + ListNode P1 = head; + while (P1 != null && k-- > 0) + P1 = P1.next; + if (k > 0) + return null; + ListNode P2 = head; + while (P1 != null) { + P1 = P1.next; + P2 = P2.next; + } + return P2; +} +``` + + + + + + +
diff --git a/notes/23. 链表中环的入口结点.md b/notes/23. 链表中环的入口结点.md new file mode 100644 index 00000000..9ba6c95e --- /dev/null +++ b/notes/23. 链表中环的入口结点.md @@ -0,0 +1,40 @@ +# 23. 链表中环的入口结点 + +[NowCoder](https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4?tpId=13&tqId=11208&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +一个链表中包含环,请找出该链表的环的入口结点。要求不能使用额外的空间。 + +## 解题思路 + +使用双指针,一个指针 fast 每次移动两个节点,一个指针 slow 每次移动一个节点。因为存在环,所以两个指针必定相遇在环中的某个节点上。假设相遇点在下图的 z1 位置,此时 fast 移动的节点数为 x+2y+z,slow 为 x+y,由于 fast 速度比 slow 快一倍,因此 x+2y+z=2(x+y),得到 x=z。 + +在相遇点,slow 要到环的入口点还需要移动 z 个节点,如果让 fast 重新从头开始移动,并且速度变为每次移动一个节点,那么它到环入口点还需要移动 x 个节点。在上面已经推导出 x=z,因此 fast 和 slow 将在环入口点相遇。 + +

+ +```java +public ListNode EntryNodeOfLoop(ListNode pHead) { + if (pHead == null || pHead.next == null) + return null; + ListNode slow = pHead, fast = pHead; + do { + fast = fast.next.next; + slow = slow.next; + } while (slow != fast); + fast = pHead; + while (slow != fast) { + slow = slow.next; + fast = fast.next; + } + return slow; +} +``` + + + + + + +
diff --git a/notes/24. 反转链表.md b/notes/24. 反转链表.md new file mode 100644 index 00000000..4fa7a32e --- /dev/null +++ b/notes/24. 反转链表.md @@ -0,0 +1,43 @@ +# 24. 反转链表 + +[NowCoder](https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca?tpId=13&tqId=11168&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +### 递归 + +```java +public ListNode ReverseList(ListNode head) { + if (head == null || head.next == null) + return head; + ListNode next = head.next; + head.next = null; + ListNode newHead = ReverseList(next); + next.next = head; + return newHead; +} +``` + +### 迭代 + +使用头插法。 + +```java +public ListNode ReverseList(ListNode head) { + ListNode newList = new ListNode(-1); + while (head != null) { + ListNode next = head.next; + head.next = newList.next; + newList.next = head; + head = next; + } + return newList.next; +} +``` + + + + + + +
diff --git a/notes/25. 合并两个排序的链表.md b/notes/25. 合并两个排序的链表.md new file mode 100644 index 00000000..575d44fa --- /dev/null +++ b/notes/25. 合并两个排序的链表.md @@ -0,0 +1,58 @@ +# 25. 合并两个排序的链表 + +[NowCoder](https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337?tpId=13&tqId=11169&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +

+ +## 解题思路 + +### 递归 + +```java +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; + } else { + list2.next = Merge(list1, list2.next); + return list2; + } +} +``` + +### 迭代 + +```java +public ListNode Merge(ListNode list1, ListNode list2) { + ListNode head = new ListNode(-1); + ListNode cur = head; + while (list1 != null && list2 != null) { + if (list1.val <= list2.val) { + cur.next = list1; + list1 = list1.next; + } else { + cur.next = list2; + list2 = list2.next; + } + cur = cur.next; + } + if (list1 != null) + cur.next = list1; + if (list2 != null) + cur.next = list2; + return head.next; +} +``` + + + + + + +
diff --git a/notes/26. 树的子结构.md b/notes/26. 树的子结构.md new file mode 100644 index 00000000..e7cab9b6 --- /dev/null +++ b/notes/26. 树的子结构.md @@ -0,0 +1,34 @@ +# 26. 树的子结构 + +[NowCoder](https://www.nowcoder.com/practice/6e196c44c7004d15b1610b9afca8bd88?tpId=13&tqId=11170&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +

+ +## 解题思路 + +```java +public boolean HasSubtree(TreeNode root1, TreeNode root2) { + if (root1 == null || root2 == null) + return false; + return isSubtreeWithRoot(root1, root2) || HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2); +} + +private boolean isSubtreeWithRoot(TreeNode root1, TreeNode root2) { + if (root2 == null) + return true; + if (root1 == null) + return false; + if (root1.val != root2.val) + return false; + return isSubtreeWithRoot(root1.left, root2.left) && isSubtreeWithRoot(root1.right, root2.right); +} +``` + + + + + + +
diff --git a/notes/27. 二叉树的镜像.md b/notes/27. 二叉树的镜像.md new file mode 100644 index 00000000..811b31ce --- /dev/null +++ b/notes/27. 二叉树的镜像.md @@ -0,0 +1,32 @@ +# 27. 二叉树的镜像 + +[NowCoder](https://www.nowcoder.com/practice/564f4c26aa584921bc75623e48ca3011?tpId=13&tqId=11171&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +

+ +## 解题思路 + +```java +public void Mirror(TreeNode root) { + if (root == null) + return; + swap(root); + Mirror(root.left); + Mirror(root.right); +} + +private void swap(TreeNode root) { + TreeNode t = root.left; + root.left = root.right; + root.right = t; +} +``` + + + + + + +
diff --git a/notes/28. 对称的二叉树.md b/notes/28. 对称的二叉树.md new file mode 100644 index 00000000..13ec3b28 --- /dev/null +++ b/notes/28. 对称的二叉树.md @@ -0,0 +1,34 @@ +# 28. 对称的二叉树 + +[NowCoder](https://www.nowcoder.com/practice/ff05d44dfdb04e1d83bdbdab320efbcb?tpId=13&tqId=11211&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +

+ +## 解题思路 + +```java +boolean isSymmetrical(TreeNode pRoot) { + if (pRoot == null) + return true; + return isSymmetrical(pRoot.left, pRoot.right); +} + +boolean isSymmetrical(TreeNode t1, TreeNode t2) { + if (t1 == null && t2 == null) + return true; + if (t1 == null || t2 == null) + return false; + if (t1.val != t2.val) + return false; + return isSymmetrical(t1.left, t2.right) && isSymmetrical(t1.right, t2.left); +} +``` + + + + + + +
diff --git a/notes/29. 顺时针打印矩阵.md b/notes/29. 顺时针打印矩阵.md new file mode 100644 index 00000000..a9972761 --- /dev/null +++ b/notes/29. 顺时针打印矩阵.md @@ -0,0 +1,39 @@ +# 29. 顺时针打印矩阵 + +[NowCoder](https://www.nowcoder.com/practice/9b4c81a02cd34f76be2659fa0d54342a?tpId=13&tqId=11172&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +下图的矩阵顺时针打印结果为:1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10 + +

+ +## 解题思路 + +```java +public ArrayList printMatrix(int[][] matrix) { + ArrayList ret = new ArrayList<>(); + int r1 = 0, r2 = matrix.length - 1, c1 = 0, c2 = matrix[0].length - 1; + while (r1 <= r2 && c1 <= c2) { + for (int i = c1; i <= c2; i++) + ret.add(matrix[r1][i]); + for (int i = r1 + 1; i <= r2; i++) + ret.add(matrix[i][c2]); + if (r1 != r2) + for (int i = c2 - 1; i >= c1; i--) + ret.add(matrix[r2][i]); + if (c1 != c2) + for (int i = r2 - 1; i > r1; i--) + ret.add(matrix[i][c1]); + r1++; r2--; c1++; c2--; + } + return ret; +} +``` + + + + + + +
diff --git a/notes/3. 数组中重复的数字.md b/notes/3. 数组中重复的数字.md new file mode 100644 index 00000000..b1d21dac --- /dev/null +++ b/notes/3. 数组中重复的数字.md @@ -0,0 +1,56 @@ +# 3. 数组中重复的数字 + +[NowCoder](https://www.nowcoder.com/practice/623a5ac0ea5b4e5f95552655361ae0a8?tpId=13&tqId=11203&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 + +```html +Input: +{2, 3, 1, 0, 2, 5} + +Output: +2 +``` + +## 解题思路 + +要求时间复杂度 O(N),空间复杂度 O(1)。因此不能使用排序的方法,也不能使用额外的标记数组。 + +对于这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素调整到第 i 个位置上进行求解。 + +以 (2, 3, 1, 0, 2, 5) 为例,遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复: + +

+ + +```java +public boolean duplicate(int[] nums, int length, int[] duplication) { + if (nums == null || length <= 0) + return false; + for (int i = 0; i < length; i++) { + while (nums[i] != i) { + if (nums[i] == nums[nums[i]]) { + duplication[0] = nums[i]; + return true; + } + swap(nums, i, nums[i]); + } + } + return false; +} + +private void swap(int[] nums, int i, int j) { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; +} +``` + + + + + + +
diff --git a/notes/30. 包含 min 函数的栈.md b/notes/30. 包含 min 函数的栈.md new file mode 100644 index 00000000..041e5139 --- /dev/null +++ b/notes/30. 包含 min 函数的栈.md @@ -0,0 +1,39 @@ +# 30. 包含 min 函数的栈 + +[NowCoder](https://www.nowcoder.com/practice/4c776177d2c04c2494f2555c9fcc1e49?tpId=13&tqId=11173&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的 min 函数。 + +## 解题思路 + +```java +private Stack dataStack = new Stack<>(); +private Stack minStack = new Stack<>(); + +public void push(int node) { + dataStack.push(node); + minStack.push(minStack.isEmpty() ? node : Math.min(minStack.peek(), node)); +} + +public void pop() { + dataStack.pop(); + minStack.pop(); +} + +public int top() { + return dataStack.peek(); +} + +public int min() { + return minStack.peek(); +} +``` + + + + + + +
diff --git a/notes/31. 栈的压入、弹出序列.md b/notes/31. 栈的压入、弹出序列.md new file mode 100644 index 00000000..58ff69cc --- /dev/null +++ b/notes/31. 栈的压入、弹出序列.md @@ -0,0 +1,36 @@ +# 31. 栈的压入、弹出序列 + +[NowCoder](https://www.nowcoder.com/practice/d77d11405cc7470d82554cb392585106?tpId=13&tqId=11174&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。 + +例如序列 1,2,3,4,5 是某栈的压入顺序,序列 4,5,3,2,1 是该压栈序列对应的一个弹出序列,但 4,3,5,1,2 就不可能是该压栈序列的弹出序列。 + +## 解题思路 + +使用一个栈来模拟压入弹出操作。 + +```java +public boolean IsPopOrder(int[] pushSequence, int[] popSequence) { + int n = pushSequence.length; + Stack stack = new Stack<>(); + for (int pushIndex = 0, popIndex = 0; pushIndex < n; pushIndex++) { + stack.push(pushSequence[pushIndex]); + while (popIndex < n && !stack.isEmpty() + && stack.peek() == popSequence[popIndex]) { + stack.pop(); + popIndex++; + } + } + return stack.isEmpty(); +} +``` + + + + + + +
diff --git a/notes/32.1 从上往下打印二叉树.md b/notes/32.1 从上往下打印二叉树.md new file mode 100644 index 00000000..9fb54483 --- /dev/null +++ b/notes/32.1 从上往下打印二叉树.md @@ -0,0 +1,44 @@ +# 32.1 从上往下打印二叉树 + +[NowCoder](https://www.nowcoder.com/practice/7fe2212963db4790b57431d9ed259701?tpId=13&tqId=11175&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +从上往下打印出二叉树的每个节点,同层节点从左至右打印。 + +例如,以下二叉树层次遍历的结果为:1,2,3,4,5,6,7 + +

+ +## 解题思路 + +使用队列来进行层次遍历。 + +不需要使用两个队列分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。 + +```java +public ArrayList PrintFromTopToBottom(TreeNode root) { + Queue queue = new LinkedList<>(); + ArrayList ret = new ArrayList<>(); + queue.add(root); + while (!queue.isEmpty()) { + int cnt = queue.size(); + while (cnt-- > 0) { + TreeNode t = queue.poll(); + if (t == null) + continue; + ret.add(t.val); + queue.add(t.left); + queue.add(t.right); + } + } + return ret; +} +``` + + + + + + +
diff --git a/notes/32.2 把二叉树打印成多行.md b/notes/32.2 把二叉树打印成多行.md new file mode 100644 index 00000000..0de90b52 --- /dev/null +++ b/notes/32.2 把二叉树打印成多行.md @@ -0,0 +1,39 @@ +# 32.2 把二叉树打印成多行 + +[NowCoder](https://www.nowcoder.com/practice/445c44d982d04483b04a54f298796288?tpId=13&tqId=11213&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +和上题几乎一样。 + +## 解题思路 + +```java +ArrayList> Print(TreeNode pRoot) { + ArrayList> ret = new ArrayList<>(); + Queue queue = new LinkedList<>(); + queue.add(pRoot); + while (!queue.isEmpty()) { + ArrayList list = new ArrayList<>(); + int cnt = queue.size(); + while (cnt-- > 0) { + TreeNode node = queue.poll(); + if (node == null) + continue; + list.add(node.val); + queue.add(node.left); + queue.add(node.right); + } + if (list.size() != 0) + ret.add(list); + } + return ret; +} +``` + + + + + + +
diff --git a/notes/32.3 按之字形顺序打印二叉树.md b/notes/32.3 按之字形顺序打印二叉树.md new file mode 100644 index 00000000..0a283ae3 --- /dev/null +++ b/notes/32.3 按之字形顺序打印二叉树.md @@ -0,0 +1,43 @@ +# 32.3 按之字形顺序打印二叉树 + +[NowCoder](https://www.nowcoder.com/practice/91b69814117f4e8097390d107d2efbe0?tpId=13&tqId=11212&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。 + +## 解题思路 + +```java +public ArrayList> Print(TreeNode pRoot) { + ArrayList> ret = new ArrayList<>(); + Queue queue = new LinkedList<>(); + queue.add(pRoot); + boolean reverse = false; + while (!queue.isEmpty()) { + ArrayList list = new ArrayList<>(); + int cnt = queue.size(); + while (cnt-- > 0) { + TreeNode node = queue.poll(); + if (node == null) + continue; + list.add(node.val); + queue.add(node.left); + queue.add(node.right); + } + if (reverse) + Collections.reverse(list); + reverse = !reverse; + if (list.size() != 0) + ret.add(list); + } + return ret; +} +``` + + + + + + +
diff --git a/notes/33. 二叉搜索树的后序遍历序列.md b/notes/33. 二叉搜索树的后序遍历序列.md new file mode 100644 index 00000000..9c25f832 --- /dev/null +++ b/notes/33. 二叉搜索树的后序遍历序列.md @@ -0,0 +1,41 @@ +# 33. 二叉搜索树的后序遍历序列 + +[NowCoder](https://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd?tpId=13&tqId=11176&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。假设输入的数组的任意两个数字都互不相同。 + +例如,下图是后序遍历序列 1,3,2 所对应的二叉搜索树。 + +

+ +## 解题思路 + +```java +public boolean VerifySquenceOfBST(int[] sequence) { + if (sequence == null || sequence.length == 0) + return false; + return verify(sequence, 0, sequence.length - 1); +} + +private boolean verify(int[] sequence, int first, int last) { + if (last - first <= 1) + return true; + int rootVal = sequence[last]; + int cutIndex = first; + while (cutIndex < last && sequence[cutIndex] <= rootVal) + cutIndex++; + for (int i = cutIndex; i < last; i++) + if (sequence[i] < rootVal) + return false; + return verify(sequence, first, cutIndex - 1) && verify(sequence, cutIndex, last - 1); +} +``` + + + + + + +
diff --git a/notes/34. 二叉树中和为某一值的路径.md b/notes/34. 二叉树中和为某一值的路径.md new file mode 100644 index 00000000..8621a018 --- /dev/null +++ b/notes/34. 二叉树中和为某一值的路径.md @@ -0,0 +1,43 @@ +# 34. 二叉树中和为某一值的路径 + +[NowCoder](https://www.nowcoder.com/practice/b736e784e3e34731af99065031301bca?tpId=13&tqId=11177&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。 + +下图的二叉树有两条和为 22 的路径:10, 5, 7 和 10, 12 + +

+ +## 解题思路 + +```java +private ArrayList> ret = new ArrayList<>(); + +public ArrayList> FindPath(TreeNode root, int target) { + backtracking(root, target, new ArrayList<>()); + return ret; +} + +private void backtracking(TreeNode node, int target, ArrayList path) { + if (node == null) + return; + path.add(node.val); + target -= node.val; + if (target == 0 && node.left == null && node.right == null) { + ret.add(new ArrayList<>(path)); + } else { + backtracking(node.left, target, path); + backtracking(node.right, target, path); + } + path.remove(path.size() - 1); +} +``` + + + + + + +
diff --git a/notes/35. 复杂链表的复制.md b/notes/35. 复杂链表的复制.md new file mode 100644 index 00000000..c7ee727f --- /dev/null +++ b/notes/35. 复杂链表的复制.md @@ -0,0 +1,74 @@ +# 35. 复杂链表的复制 + +[NowCoder](https://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba?tpId=13&tqId=11178&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的 head。 + +```java +public class RandomListNode { + int label; + RandomListNode next = null; + RandomListNode random = null; + + RandomListNode(int label) { + this.label = label; + } +} +``` + +

+ +## 解题思路 + +第一步,在每个节点的后面插入复制的节点。 + +

+ +第二步,对复制节点的 random 链接进行赋值。 + +

+ +第三步,拆分。 + +

+ +```java +public RandomListNode Clone(RandomListNode pHead) { + if (pHead == null) + return null; + // 插入新节点 + RandomListNode cur = pHead; + while (cur != null) { + RandomListNode clone = new RandomListNode(cur.label); + clone.next = cur.next; + cur.next = clone; + cur = clone.next; + } + // 建立 random 链接 + cur = pHead; + while (cur != null) { + RandomListNode clone = cur.next; + if (cur.random != null) + clone.random = cur.random.next; + cur = clone.next; + } + // 拆分 + cur = pHead; + RandomListNode pCloneHead = pHead.next; + while (cur.next != null) { + RandomListNode next = cur.next; + cur.next = next.next; + cur = next; + } + return pCloneHead; +} +``` + + + + + + +
diff --git a/notes/36. 二叉搜索树与双向链表.md b/notes/36. 二叉搜索树与双向链表.md new file mode 100644 index 00000000..d70111a5 --- /dev/null +++ b/notes/36. 二叉搜索树与双向链表.md @@ -0,0 +1,41 @@ +# 36. 二叉搜索树与双向链表 + +[NowCoder](https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&tqId=11179&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 + +

+ +## 解题思路 + +```java +private TreeNode pre = null; +private TreeNode head = null; + +public TreeNode Convert(TreeNode root) { + inOrder(root); + return head; +} + +private void inOrder(TreeNode node) { + if (node == null) + return; + inOrder(node.left); + node.left = pre; + if (pre != null) + pre.right = node; + pre = node; + if (head == null) + head = node; + inOrder(node.right); +} +``` + + + + + + +
diff --git a/notes/37. 序列化二叉树.md b/notes/37. 序列化二叉树.md new file mode 100644 index 00000000..69086138 --- /dev/null +++ b/notes/37. 序列化二叉树.md @@ -0,0 +1,46 @@ +# 37. 序列化二叉树 + +[NowCoder](https://www.nowcoder.com/practice/cf7e25aa97c04cc1a68c8f040e71fb84?tpId=13&tqId=11214&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +请实现两个函数,分别用来序列化和反序列化二叉树。 + +## 解题思路 + +```java +private String deserializeStr; + +public String Serialize(TreeNode root) { + if (root == null) + return "#"; + return root.val + " " + Serialize(root.left) + " " + Serialize(root.right); +} + +public TreeNode Deserialize(String str) { + deserializeStr = str; + return Deserialize(); +} + +private TreeNode Deserialize() { + if (deserializeStr.length() == 0) + return null; + int index = deserializeStr.indexOf(" "); + String node = index == -1 ? deserializeStr : deserializeStr.substring(0, index); + deserializeStr = index == -1 ? "" : deserializeStr.substring(index + 1); + if (node.equals("#")) + return null; + int val = Integer.valueOf(node); + TreeNode t = new TreeNode(val); + t.left = Deserialize(); + t.right = Deserialize(); + return t; +} +``` + + + + + + +
diff --git a/notes/38. 字符串的排列.md b/notes/38. 字符串的排列.md new file mode 100644 index 00000000..8deb1fff --- /dev/null +++ b/notes/38. 字符串的排列.md @@ -0,0 +1,47 @@ +# 38. 字符串的排列 + +[NowCoder](https://www.nowcoder.com/practice/fe6b651b66ae47d7acce78ffdd9a96c7?tpId=13&tqId=11180&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串 abc,则打印出由字符 a, b, c 所能排列出来的所有字符串 abc, acb, bac, bca, cab 和 cba。 + +## 解题思路 + +```java +private ArrayList ret = new ArrayList<>(); + +public ArrayList Permutation(String str) { + if (str.length() == 0) + return ret; + char[] chars = str.toCharArray(); + Arrays.sort(chars); + backtracking(chars, new boolean[chars.length], new StringBuilder()); + return ret; +} + +private void backtracking(char[] chars, boolean[] hasUsed, StringBuilder s) { + if (s.length() == chars.length) { + ret.add(s.toString()); + return; + } + for (int i = 0; i < chars.length; i++) { + if (hasUsed[i]) + continue; + if (i != 0 && chars[i] == chars[i - 1] && !hasUsed[i - 1]) /* 保证不重复 */ + continue; + hasUsed[i] = true; + s.append(chars[i]); + backtracking(chars, hasUsed, s); + s.deleteCharAt(s.length() - 1); + hasUsed[i] = false; + } +} +``` + + + + + + +
diff --git a/notes/39. 数组中出现次数超过一半的数字.md b/notes/39. 数组中出现次数超过一半的数字.md new file mode 100644 index 00000000..4518f5a0 --- /dev/null +++ b/notes/39. 数组中出现次数超过一半的数字.md @@ -0,0 +1,34 @@ +# 39. 数组中出现次数超过一半的数字 + +[NowCoder](https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=13&tqId=11181&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +多数投票问题,可以利用 Boyer-Moore Majority Vote Algorithm 来解决这个问题,使得时间复杂度为 O(N)。 + +使用 cnt 来统计一个元素出现的次数,当遍历到的元素和统计元素相等时,令 cnt++,否则令 cnt--。如果前面查找了 i 个元素,且 cnt == 0,说明前 i 个元素没有 majority,或者有 majority,但是出现的次数少于 i / 2 ,因为如果多于 i / 2 的话 cnt 就一定不会为 0 。此时剩下的 n - i 个元素中,majority 的数目依然多于 (n - i) / 2,因此继续查找就能找出 majority。 + +```java +public int MoreThanHalfNum_Solution(int[] nums) { + int majority = nums[0]; + for (int i = 1, cnt = 1; i < nums.length; i++) { + cnt = nums[i] == majority ? cnt + 1 : cnt - 1; + if (cnt == 0) { + majority = nums[i]; + cnt = 1; + } + } + int cnt = 0; + for (int val : nums) + if (val == majority) + cnt++; + return cnt > nums.length / 2 ? majority : 0; +} +``` + + + + + + +
diff --git a/notes/4. 二维数组中的查找.md b/notes/4. 二维数组中的查找.md new file mode 100644 index 00000000..26c7a722 --- /dev/null +++ b/notes/4. 二维数组中的查找.md @@ -0,0 +1,54 @@ +# 4. 二维数组中的查找 + +[NowCoder](https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&tqId=11154&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序。给定一个数,判断这个数是否在该二维数组中。 + +```html +Consider the following matrix: +[ + [1, 4, 7, 11, 15], + [2, 5, 8, 12, 19], + [3, 6, 9, 16, 22], + [10, 13, 14, 17, 24], + [18, 21, 23, 26, 30] +] + +Given target = 5, return true. +Given target = 20, return false. +``` + +## 解题思路 + +要求时间复杂度 O(M + N),空间复杂度 O(1)。其中 M 为行数,N 为 列数。 + +该二维数组中的一个数,小于它的数一定在其左边,大于它的数一定在其下边。因此,从右上角开始查找,就可以根据 target 和当前元素的大小关系来缩小查找区间,当前元素的查找区间为左下角的所有元素。 + +

+ +```java +public boolean Find(int target, int[][] matrix) { + if (matrix == null || matrix.length == 0 || matrix[0].length == 0) + return false; + int rows = matrix.length, cols = matrix[0].length; + int r = 0, c = cols - 1; // 从右上角开始 + while (r <= rows - 1 && c >= 0) { + if (target == matrix[r][c]) + return true; + else if (target > matrix[r][c]) + r++; + else + c--; + } + return false; +} +``` + + + + + + +
diff --git a/notes/40. 最小的 K 个数.md b/notes/40. 最小的 K 个数.md new file mode 100644 index 00000000..5730eaee --- /dev/null +++ b/notes/40. 最小的 K 个数.md @@ -0,0 +1,88 @@ +# 40. 最小的 K 个数 + +[NowCoder](https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf?tpId=13&tqId=11182&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +### 快速选择 + +- 复杂度:O(N) + O(1) +- 只有当允许修改数组元素时才可以使用 + +快速排序的 partition() 方法,会返回一个整数 j 使得 a[l..j-1] 小于等于 a[j],且 a[j+1..h] 大于等于 a[j],此时 a[j] 就是数组的第 j 大元素。可以利用这个特性找出数组的第 K 个元素,这种找第 K 个元素的算法称为快速选择算法。 + +```java +public ArrayList GetLeastNumbers_Solution(int[] nums, int k) { + ArrayList ret = new ArrayList<>(); + if (k > nums.length || k <= 0) + return ret; + findKthSmallest(nums, k - 1); + /* findKthSmallest 会改变数组,使得前 k 个数都是最小的 k 个数 */ + for (int i = 0; i < k; i++) + ret.add(nums[i]); + return ret; +} + +public void findKthSmallest(int[] nums, int k) { + int l = 0, h = nums.length - 1; + while (l < h) { + int j = partition(nums, l, h); + if (j == k) + break; + if (j > k) + h = j - 1; + else + l = j + 1; + } +} + +private int partition(int[] nums, int l, int h) { + int p = nums[l]; /* 切分元素 */ + int i = l, j = h + 1; + while (true) { + while (i != h && nums[++i] < p) ; + while (j != l && nums[--j] > p) ; + if (i >= j) + break; + swap(nums, i, j); + } + swap(nums, l, j); + return j; +} + +private void swap(int[] nums, int i, int j) { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; +} +``` + +### 大小为 K 的最小堆 + +- 复杂度:O(NlogK) + O(K) +- 特别适合处理海量数据 + +应该使用大顶堆来维护最小堆,而不能直接创建一个小顶堆并设置一个大小,企图让小顶堆中的元素都是最小元素。 + +维护一个大小为 K 的最小堆过程如下:在添加一个元素之后,如果大顶堆的大小大于 K,那么需要将大顶堆的堆顶元素去除。 + +```java +public ArrayList GetLeastNumbers_Solution(int[] nums, int k) { + if (k > nums.length || k <= 0) + return new ArrayList<>(); + PriorityQueue maxHeap = new PriorityQueue<>((o1, o2) -> o2 - o1); + for (int num : nums) { + maxHeap.add(num); + if (maxHeap.size() > k) + maxHeap.poll(); + } + return new ArrayList<>(maxHeap); +} +``` + + + + + + +
diff --git a/notes/41.1 数据流中的中位数.md b/notes/41.1 数据流中的中位数.md new file mode 100644 index 00000000..bc94e3fa --- /dev/null +++ b/notes/41.1 数据流中的中位数.md @@ -0,0 +1,47 @@ +# 41.1 数据流中的中位数 + +[NowCoder](https://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1?tpId=13&tqId=11216&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。 + +## 解题思路 + +```java +/* 大顶堆,存储左半边元素 */ +private PriorityQueue left = new PriorityQueue<>((o1, o2) -> o2 - o1); +/* 小顶堆,存储右半边元素,并且右半边元素都大于左半边 */ +private PriorityQueue right = new PriorityQueue<>(); +/* 当前数据流读入的元素个数 */ +private int N = 0; + +public void Insert(Integer val) { + /* 插入要保证两个堆存于平衡状态 */ + if (N % 2 == 0) { + /* N 为偶数的情况下插入到右半边。 + * 因为右半边元素都要大于左半边,但是新插入的元素不一定比左半边元素来的大, + * 因此需要先将元素插入左半边,然后利用左半边为大顶堆的特点,取出堆顶元素即为最大元素,此时插入右半边 */ + left.add(val); + right.add(left.poll()); + } else { + right.add(val); + left.add(right.poll()); + } + N++; +} + +public Double GetMedian() { + if (N % 2 == 0) + return (left.peek() + right.peek()) / 2.0; + else + return (double) right.peek(); +} +``` + + + + + + +
diff --git a/notes/41.2 字符流中第一个不重复的字符.md b/notes/41.2 字符流中第一个不重复的字符.md new file mode 100644 index 00000000..d1910c8b --- /dev/null +++ b/notes/41.2 字符流中第一个不重复的字符.md @@ -0,0 +1,32 @@ +# 41.2 字符流中第一个不重复的字符 + +[NowCoder](https://www.nowcoder.com/practice/00de97733b8e4f97a3fb5c680ee10720?tpId=13&tqId=11207&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符 "go" 时,第一个只出现一次的字符是 "g"。当从该字符流中读出前六个字符“google" 时,第一个只出现一次的字符是 "l"。 + +## 解题思路 + +```java +private int[] cnts = new int[256]; +private Queue queue = new LinkedList<>(); + +public void Insert(char ch) { + cnts[ch]++; + queue.add(ch); + while (!queue.isEmpty() && cnts[queue.peek()] > 1) + queue.poll(); +} + +public char FirstAppearingOnce() { + return queue.isEmpty() ? '#' : queue.peek(); +} +``` + + + + + + +
diff --git a/notes/42. 连续子数组的最大和.md b/notes/42. 连续子数组的最大和.md new file mode 100644 index 00000000..22a46f3c --- /dev/null +++ b/notes/42. 连续子数组的最大和.md @@ -0,0 +1,31 @@ +# 42. 连续子数组的最大和 + +[NowCoder](https://www.nowcoder.com/practice/459bd355da1549fa8a49e350bf3df484?tpId=13&tqId=11183&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +{6, -3, -2, 7, -15, 1, 2, 2},连续子数组的最大和为 8(从第 0 个开始,到第 3 个为止)。 + +## 解题思路 + +```java +public int FindGreatestSumOfSubArray(int[] nums) { + if (nums == null || nums.length == 0) + return 0; + int greatestSum = Integer.MIN_VALUE; + int sum = 0; + for (int val : nums) { + sum = sum <= 0 ? val : sum + val; + greatestSum = Math.max(greatestSum, sum); + } + return greatestSum; +} +``` + + + + + + + +
diff --git a/notes/43. 从 1 到 n 整数中 1 出现的次数.md b/notes/43. 从 1 到 n 整数中 1 出现的次数.md new file mode 100644 index 00000000..a996676b --- /dev/null +++ b/notes/43. 从 1 到 n 整数中 1 出现的次数.md @@ -0,0 +1,25 @@ +# 43. 从 1 到 n 整数中 1 出现的次数 + +[NowCoder](https://www.nowcoder.com/practice/bd7f978302044eee894445e244c7eee6?tpId=13&tqId=11184&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +```java +public int NumberOf1Between1AndN_Solution(int n) { + int cnt = 0; + for (int m = 1; m <= n; m *= 10) { + int a = n / m, b = n % m; + cnt += (a + 8) / 10 * m + (a % 10 == 1 ? b + 1 : 0); + } + return cnt; +} +``` + +> [Leetcode : 233. Number of Digit One](https://leetcode.com/problems/number-of-digit-one/discuss/64381/4+-lines-O(log-n)-C++JavaPython) + + + + + + +
diff --git a/notes/44. 数字序列中的某一位数字.md b/notes/44. 数字序列中的某一位数字.md new file mode 100644 index 00000000..0344ee56 --- /dev/null +++ b/notes/44. 数字序列中的某一位数字.md @@ -0,0 +1,61 @@ +# 44. 数字序列中的某一位数字 + +## 题目描述 + +数字以 0123456789101112131415... 的格式序列化到一个字符串中,求这个字符串的第 index 位。 + +## 解题思路 + +```java +public int getDigitAtIndex(int index) { + if (index < 0) + return -1; + int place = 1; // 1 表示个位,2 表示 十位... + while (true) { + int amount = getAmountOfPlace(place); + int totalAmount = amount * place; + if (index < totalAmount) + return getDigitAtIndex(index, place); + index -= totalAmount; + place++; + } +} + +/** + * place 位数的数字组成的字符串长度 + * 10, 90, 900, ... + */ +private int getAmountOfPlace(int place) { + if (place == 1) + return 10; + return (int) Math.pow(10, place - 1) * 9; +} + +/** + * place 位数的起始数字 + * 0, 10, 100, ... + */ +private int getBeginNumberOfPlace(int place) { + if (place == 1) + return 0; + return (int) Math.pow(10, place - 1); +} + +/** + * 在 place 位数组成的字符串中,第 index 个数 + */ +private int getDigitAtIndex(int index, int place) { + int beginNumber = getBeginNumberOfPlace(place); + int shiftNumber = index / place; + String number = (beginNumber + shiftNumber) + ""; + int count = index % place; + return number.charAt(count) - '0'; +} +``` + + + + + + +
diff --git a/notes/45. 把数组排成最小的数.md b/notes/45. 把数组排成最小的数.md new file mode 100644 index 00000000..e65c4a4e --- /dev/null +++ b/notes/45. 把数组排成最小的数.md @@ -0,0 +1,34 @@ +# 45. 把数组排成最小的数 + +[NowCoder](https://www.nowcoder.com/practice/8fecd3f8ba334add803bf2a06af1b993?tpId=13&tqId=11185&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组 {3,32,321},则打印出这三个数字能排成的最小数字为 321323。 + +## 解题思路 + +可以看成是一个排序问题,在比较两个字符串 S1 和 S2 的大小时,应该比较的是 S1+S2 和 S2+S1 的大小,如果 S1+S2 < S2+S1,那么应该把 S1 排在前面,否则应该把 S2 排在前面。 + +```java +public String PrintMinNumber(int[] numbers) { + if (numbers == null || numbers.length == 0) + return ""; + int n = numbers.length; + String[] nums = new String[n]; + for (int i = 0; i < n; i++) + nums[i] = numbers[i] + ""; + Arrays.sort(nums, (s1, s2) -> (s1 + s2).compareTo(s2 + s1)); + String ret = ""; + for (String str : nums) + ret += str; + return ret; +} +``` + + + + + + +
diff --git a/notes/46. 把数字翻译成字符串.md b/notes/46. 把数字翻译成字符串.md new file mode 100644 index 00000000..bfe8ce42 --- /dev/null +++ b/notes/46. 把数字翻译成字符串.md @@ -0,0 +1,38 @@ +# 46. 把数字翻译成字符串 + +[Leetcode](https://leetcode.com/problems/decode-ways/description/) + +## 题目描述 + +给定一个数字,按照如下规则翻译成字符串:1 翻译成“a”,2 翻译成“b”... 26 翻译成“z”。一个数字有多种翻译可能,例如 12258 一共有 5 种,分别是 abbeh,lbeh,aveh,abyh,lyh。实现一个函数,用来计算一个数字有多少种不同的翻译方法。 + +## 解题思路 + +```java +public int numDecodings(String s) { + if (s == null || s.length() == 0) + return 0; + int n = s.length(); + int[] dp = new int[n + 1]; + dp[0] = 1; + dp[1] = s.charAt(0) == '0' ? 0 : 1; + for (int i = 2; i <= n; i++) { + int one = Integer.valueOf(s.substring(i - 1, i)); + if (one != 0) + dp[i] += dp[i - 1]; + if (s.charAt(i - 2) == '0') + continue; + int two = Integer.valueOf(s.substring(i - 2, i)); + if (two <= 26) + dp[i] += dp[i - 2]; + } + return dp[n]; +} +``` + + + + + + +
diff --git a/notes/47. 礼物的最大价值.md b/notes/47. 礼物的最大价值.md new file mode 100644 index 00000000..fe5463e9 --- /dev/null +++ b/notes/47. 礼物的最大价值.md @@ -0,0 +1,42 @@ +# 47. 礼物的最大价值 + +[NowCoder](https://www.nowcoder.com/questionTerminal/72a99e28381a407991f2c96d8cb238ab) + +## 题目描述 + +在一个 m\*n 的棋盘的每一个格都放有一个礼物,每个礼物都有一定价值(大于 0)。从左上角开始拿礼物,每次向右或向下移动一格,直到右下角结束。给定一个棋盘,求拿到礼物的最大价值。例如,对于如下棋盘 + +``` +1 10 3 8 +12 2 9 6 +5 7 4 11 +3 7 16 5 +``` + +礼物的最大价值为 1+12+5+7+7+16+5=53。 + +## 解题思路 + +应该用动态规划求解,而不是深度优先搜索,深度优先搜索过于复杂,不是最优解。 + +```java +public int getMost(int[][] values) { + if (values == null || values.length == 0 || values[0].length == 0) + return 0; + int n = values[0].length; + int[] dp = new int[n]; + for (int[] value : values) { + dp[0] += value[0]; + for (int i = 1; i < n; i++) + dp[i] = Math.max(dp[i], dp[i - 1]) + value[i]; + } + return dp[n - 1]; +} +``` + + + + + + +
diff --git a/notes/48. 最长不含重复字符的子字符串.md b/notes/48. 最长不含重复字符的子字符串.md new file mode 100644 index 00000000..2d9c885e --- /dev/null +++ b/notes/48. 最长不含重复字符的子字符串.md @@ -0,0 +1,36 @@ +# 48. 最长不含重复字符的子字符串 + +## 题目描述 + +输入一个字符串(只包含 a\~z 的字符),求其最长不含重复字符的子字符串的长度。例如对于 arabcacfr,最长不含重复字符的子字符串为 acfr,长度为 4。 + +## 解题思路 + +```java +public int longestSubStringWithoutDuplication(String str) { + int curLen = 0; + int maxLen = 0; + int[] preIndexs = new int[26]; + Arrays.fill(preIndexs, -1); + for (int curI = 0; curI < str.length(); curI++) { + int c = str.charAt(curI) - 'a'; + int preI = preIndexs[c]; + if (preI == -1 || curI - preI > curLen) { + curLen++; + } else { + maxLen = Math.max(maxLen, curLen); + curLen = curI - preI; + } + preIndexs[c] = curI; + } + maxLen = Math.max(maxLen, curLen); + return maxLen; +} +``` + + + + + + +
diff --git a/notes/49. 丑数.md b/notes/49. 丑数.md new file mode 100644 index 00000000..bfbc78ab --- /dev/null +++ b/notes/49. 丑数.md @@ -0,0 +1,37 @@ +# 49. 丑数 + +[NowCoder](https://www.nowcoder.com/practice/6aa9e04fc3794f68acf8778237ba065b?tpId=13&tqId=11186&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,但 14 不是,因为它包含因子 7。习惯上我们把 1 当做是第一个丑数。求按从小到大的顺序的第 N 个丑数。 + +## 解题思路 + +```java +public int GetUglyNumber_Solution(int N) { + if (N <= 6) + return N; + int i2 = 0, i3 = 0, i5 = 0; + int[] dp = new int[N]; + dp[0] = 1; + for (int i = 1; i < N; i++) { + int next2 = dp[i2] * 2, next3 = dp[i3] * 3, next5 = dp[i5] * 5; + dp[i] = Math.min(next2, Math.min(next3, next5)); + if (dp[i] == next2) + i2++; + if (dp[i] == next3) + i3++; + if (dp[i] == next5) + i5++; + } + return dp[N - 1]; +} +``` + + + + + + +
diff --git a/notes/5. 替换空格.md b/notes/5. 替换空格.md new file mode 100644 index 00000000..e0669ac0 --- /dev/null +++ b/notes/5. 替换空格.md @@ -0,0 +1,55 @@ +# 5. 替换空格 + +[NowCoder](https://www.nowcoder.com/practice/4060ac7e3e404ad1a894ef3e17650423?tpId=13&tqId=11155&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + + +将一个字符串中的空格替换成 "%20"。 + +```text +Input: +"A B" + +Output: +"A%20B" +``` + +## 解题思路 + +在字符串尾部填充任意字符,使得字符串的长度等于替换之后的长度。因为一个空格要替换成三个字符(%20),因此当遍历到一个空格时,需要在尾部填充两个任意字符。 + +令 P1 指向字符串原来的末尾位置,P2 指向字符串现在的末尾位置。P1 和 P2 从后向前遍历,当 P1 遍历到一个空格时,就需要令 P2 指向的位置依次填充 02%(注意是逆序的),否则就填充上 P1 指向字符的值。 + +从后向前遍是为了在改变 P2 所指向的内容时,不会影响到 P1 遍历原来字符串的内容。 + +

+ +```java +public String replaceSpace(StringBuffer str) { + int P1 = str.length() - 1; + for (int i = 0; i <= P1; i++) + if (str.charAt(i) == ' ') + str.append(" "); + + int P2 = str.length() - 1; + while (P1 >= 0 && P2 > P1) { + char c = str.charAt(P1--); + if (c == ' ') { + str.setCharAt(P2--, '0'); + str.setCharAt(P2--, '2'); + str.setCharAt(P2--, '%'); + } else { + str.setCharAt(P2--, c); + } + } + return str.toString(); +} +``` + + + + + + +
diff --git a/notes/50. 第一个只出现一次的字符位置.md b/notes/50. 第一个只出现一次的字符位置.md new file mode 100644 index 00000000..e433a214 --- /dev/null +++ b/notes/50. 第一个只出现一次的字符位置.md @@ -0,0 +1,56 @@ +# 50. 第一个只出现一次的字符位置 + +[NowCoder](https://www.nowcoder.com/practice/1c82e8cf713b4bbeb2a5b31cf5b0417c?tpId=13&tqId=11187&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +在一个字符串中找到第一个只出现一次的字符,并返回它的位置。 + +``` +Input: abacc +Output: b +``` + +## 解题思路 + +最直观的解法是使用 HashMap 对出现次数进行统计,但是考虑到要统计的字符范围有限,因此可以使用整型数组代替 HashMap,从而将空间复杂度由 O(N) 降低为 O(1)。 + +```java +public int FirstNotRepeatingChar(String str) { + int[] cnts = new int[256]; + for (int i = 0; i < str.length(); i++) + cnts[str.charAt(i)]++; + for (int i = 0; i < str.length(); i++) + if (cnts[str.charAt(i)] == 1) + return i; + return -1; +} +``` + +以上实现的空间复杂度还不是最优的。考虑到只需要找到只出现一次的字符,那么需要统计的次数信息只有 0,1,更大,使用两个比特位就能存储这些信息。 + +```java +public int FirstNotRepeatingChar2(String str) { + BitSet bs1 = new BitSet(256); + BitSet bs2 = new BitSet(256); + for (char c : str.toCharArray()) { + if (!bs1.get(c) && !bs2.get(c)) + bs1.set(c); // 0 0 -> 0 1 + else if (bs1.get(c) && !bs2.get(c)) + bs2.set(c); // 0 1 -> 1 1 + } + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (bs1.get(c) && !bs2.get(c)) // 0 1 + return i; + } + return -1; +} +``` + + + + + + +
diff --git a/notes/51. 数组中的逆序对.md b/notes/51. 数组中的逆序对.md new file mode 100644 index 00000000..ee439664 --- /dev/null +++ b/notes/51. 数组中的逆序对.md @@ -0,0 +1,55 @@ +# 51. 数组中的逆序对 + +[NowCoder](https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。 + +## 解题思路 + +```java +private long cnt = 0; +private int[] tmp; // 在这里声明辅助数组,而不是在 merge() 递归函数中声明 + +public int InversePairs(int[] nums) { + tmp = new int[nums.length]; + mergeSort(nums, 0, nums.length - 1); + return (int) (cnt % 1000000007); +} + +private void mergeSort(int[] nums, int l, int h) { + if (h - l < 1) + return; + int m = l + (h - l) / 2; + mergeSort(nums, l, m); + mergeSort(nums, m + 1, h); + merge(nums, l, m, h); +} + +private void merge(int[] nums, int l, int m, int h) { + int i = l, j = m + 1, k = l; + while (i <= m || j <= h) { + if (i > m) + tmp[k] = nums[j++]; + else if (j > h) + tmp[k] = nums[i++]; + else if (nums[i] <= nums[j]) + tmp[k] = nums[i++]; + else { + tmp[k] = nums[j++]; + this.cnt += m - i + 1; // nums[i] > nums[j],说明 nums[i...mid] 都大于 nums[j] + } + k++; + } + for (k = l; k <= h; k++) + nums[k] = tmp[k]; +} +``` + + + + + + +
diff --git a/notes/52. 两个链表的第一个公共结点.md b/notes/52. 两个链表的第一个公共结点.md new file mode 100644 index 00000000..2cde1b81 --- /dev/null +++ b/notes/52. 两个链表的第一个公共结点.md @@ -0,0 +1,31 @@ +# 52. 两个链表的第一个公共结点 + +[NowCoder](https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tpId=13&tqId=11189&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +

+ +## 解题思路 + +设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a。 + +当访问链表 A 的指针访问到链表尾部时,令它从链表 B 的头部重新开始访问链表 B;同样地,当访问链表 B 的指针访问到链表尾部时,令它从链表 A 的头部重新开始访问链表 A。这样就能控制访问 A 和 B 两个链表的指针能同时访问到交点。 + +```java +public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { + ListNode l1 = pHead1, l2 = pHead2; + while (l1 != l2) { + l1 = (l1 == null) ? pHead2 : l1.next; + l2 = (l2 == null) ? pHead1 : l2.next; + } + return l1; +} +``` + + + + + + +
diff --git a/notes/53. 数字在排序数组中出现的次数.md b/notes/53. 数字在排序数组中出现的次数.md new file mode 100644 index 00000000..0adf759e --- /dev/null +++ b/notes/53. 数字在排序数组中出现的次数.md @@ -0,0 +1,43 @@ +# 53. 数字在排序数组中出现的次数 + +[NowCoder](https://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2?tpId=13&tqId=11190&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +```html +Input: +nums = 1, 2, 3, 3, 3, 3, 4, 6 +K = 3 + +Output: +4 +``` + +## 解题思路 + +```java +public int GetNumberOfK(int[] nums, int K) { + int first = binarySearch(nums, K); + int last = binarySearch(nums, K + 1); + return (first == nums.length || nums[first] != K) ? 0 : last - first; +} + +private int binarySearch(int[] nums, int K) { + int l = 0, h = nums.length; + while (l < h) { + int m = l + (h - l) / 2; + if (nums[m] >= K) + h = m; + else + l = m + 1; + } + return l; +} +``` + + + + + + +
diff --git a/notes/54. 二叉查找树的第 K 个结点.md b/notes/54. 二叉查找树的第 K 个结点.md new file mode 100644 index 00000000..3e581e0c --- /dev/null +++ b/notes/54. 二叉查找树的第 K 个结点.md @@ -0,0 +1,34 @@ +# 54. 二叉查找树的第 K 个结点 + +[NowCoder](https://www.nowcoder.com/practice/ef068f602dde4d28aab2b210e859150a?tpId=13&tqId=11215&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 解题思路 + +利用二叉查找树中序遍历有序的特点。 + +```java +private TreeNode ret; +private int cnt = 0; + +public TreeNode KthNode(TreeNode pRoot, int k) { + inOrder(pRoot, k); + return ret; +} + +private void inOrder(TreeNode root, int k) { + if (root == null || cnt >= k) + return; + inOrder(root.left, k); + cnt++; + if (cnt == k) + ret = root; + inOrder(root.right, k); +} +``` + + + + + + +
diff --git a/notes/55.1 二叉树的深度.md b/notes/55.1 二叉树的深度.md new file mode 100644 index 00000000..5d98b48d --- /dev/null +++ b/notes/55.1 二叉树的深度.md @@ -0,0 +1,24 @@ +# 55.1 二叉树的深度 + +[NowCoder](https://www.nowcoder.com/practice/435fb86331474282a3499955f0a41e8b?tpId=13&tqId=11191&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 + +

+ +## 解题思路 + +```java +public int TreeDepth(TreeNode root) { + return root == null ? 0 : 1 + Math.max(TreeDepth(root.left), TreeDepth(root.right)); +} +``` + + + + + + +
diff --git a/notes/55.2 平衡二叉树.md b/notes/55.2 平衡二叉树.md new file mode 100644 index 00000000..1d4aa52c --- /dev/null +++ b/notes/55.2 平衡二叉树.md @@ -0,0 +1,37 @@ +# 55.2 平衡二叉树 + +[NowCoder](https://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId=13&tqId=11192&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +平衡二叉树左右子树高度差不超过 1。 + +

+ +## 解题思路 + +```java +private boolean isBalanced = true; + +public boolean IsBalanced_Solution(TreeNode root) { + height(root); + return isBalanced; +} + +private int height(TreeNode root) { + if (root == null || !isBalanced) + return 0; + int left = height(root.left); + int right = height(root.right); + if (Math.abs(left - right) > 1) + isBalanced = false; + return 1 + Math.max(left, right); +} +``` + + + + + + +
diff --git a/notes/56. 数组中只出现一次的数字.md b/notes/56. 数组中只出现一次的数字.md new file mode 100644 index 00000000..5cbac703 --- /dev/null +++ b/notes/56. 数组中只出现一次的数字.md @@ -0,0 +1,35 @@ +# 56. 数组中只出现一次的数字 + +[NowCoder](https://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?tpId=13&tqId=11193&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +一个整型数组里除了两个数字之外,其他的数字都出现了两次,找出这两个数。 + +## 解题思路 + +两个不相等的元素在位级表示上必定会有一位存在不同,将数组的所有元素异或得到的结果为不存在重复的两个元素异或的结果。 + +diff &= -diff 得到出 diff 最右侧不为 0 的位,也就是不存在重复的两个元素在位级表示上最右侧不同的那一位,利用这一位就可以将两个元素区分开来。 + +```java +public void FindNumsAppearOnce(int[] nums, int num1[], int num2[]) { + int diff = 0; + for (int num : nums) + diff ^= num; + diff &= -diff; + for (int num : nums) { + if ((num & diff) == 0) + num1[0] ^= num; + else + num2[0] ^= num; + } +} +``` + + + + + + +
diff --git a/notes/57.1 和为 S 的两个数字.md b/notes/57.1 和为 S 的两个数字.md new file mode 100644 index 00000000..a9d9f6bb --- /dev/null +++ b/notes/57.1 和为 S 的两个数字.md @@ -0,0 +1,38 @@ +# 57.1 和为 S 的两个数字 + +[NowCoder](https://www.nowcoder.com/practice/390da4f7a00f44bea7c2f3d19491311b?tpId=13&tqId=11195&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输入一个递增排序的数组和一个数字 S,在数组中查找两个数,使得他们的和正好是 S。如果有多对数字的和等于 S,输出两个数的乘积最小的。 + +## 解题思路 + +使用双指针,一个指针指向元素较小的值,一个指针指向元素较大的值。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。 + +- 如果两个指针指向元素的和 sum == target,那么得到要求的结果; +- 如果 sum > target,移动较大的元素,使 sum 变小一些; +- 如果 sum < target,移动较小的元素,使 sum 变大一些。 + +```java +public ArrayList FindNumbersWithSum(int[] array, int sum) { + int i = 0, j = array.length - 1; + while (i < j) { + int cur = array[i] + array[j]; + if (cur == sum) + return new ArrayList<>(Arrays.asList(array[i], array[j])); + if (cur < sum) + i++; + else + j--; + } + return new ArrayList<>(); +} +``` + + + + + + +
diff --git a/notes/57.2 和为 S 的连续正数序列.md b/notes/57.2 和为 S 的连续正数序列.md new file mode 100644 index 00000000..012db7b6 --- /dev/null +++ b/notes/57.2 和为 S 的连续正数序列.md @@ -0,0 +1,50 @@ +# 57.2 和为 S 的连续正数序列 + +[NowCoder](https://www.nowcoder.com/practice/c451a3fd84b64cb19485dad758a55ebe?tpId=13&tqId=11194&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +输出所有和为 S 的连续正数序列。 + +例如和为 100 的连续序列有: + +``` +[9, 10, 11, 12, 13, 14, 15, 16] +[18, 19, 20, 21, 22]。 +``` + +## 解题思路 + +```java +public ArrayList> FindContinuousSequence(int sum) { + ArrayList> ret = new ArrayList<>(); + int start = 1, end = 2; + int curSum = 3; + while (end < sum) { + if (curSum > sum) { + curSum -= start; + start++; + } else if (curSum < sum) { + end++; + curSum += end; + } else { + ArrayList list = new ArrayList<>(); + for (int i = start; i <= end; i++) + list.add(i); + ret.add(list); + curSum -= start; + start++; + end++; + curSum += end; + } + } + return ret; +} +``` + + + + + + +
diff --git a/notes/58.1 翻转单词顺序列.md b/notes/58.1 翻转单词顺序列.md new file mode 100644 index 00000000..2d3f0437 --- /dev/null +++ b/notes/58.1 翻转单词顺序列.md @@ -0,0 +1,54 @@ +# 58.1 翻转单词顺序列 + +[NowCoder](https://www.nowcoder.com/practice/3194a4f4cf814f63919d0790578d51f3?tpId=13&tqId=11197&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +```html +Input: +"I am a student." + +Output: +"student. a am I" +``` + +## 解题思路 + +题目应该有一个隐含条件,就是不能用额外的空间。虽然 Java 的题目输入参数为 String 类型,需要先创建一个字符数组使得空间复杂度为 O(N),但是正确的参数类型应该和原书一样,为字符数组,并且只能使用该字符数组的空间。任何使用了额外空间的解法在面试时都会大打折扣,包括递归解法。 + +正确的解法应该是和书上一样,先旋转每个单词,再旋转整个字符串。 + +```java +public String ReverseSentence(String str) { + int n = str.length(); + char[] chars = str.toCharArray(); + int i = 0, j = 0; + while (j <= n) { + if (j == n || chars[j] == ' ') { + reverse(chars, i, j - 1); + i = j + 1; + } + j++; + } + reverse(chars, 0, n - 1); + return new String(chars); +} + +private void reverse(char[] c, int i, int j) { + while (i < j) + swap(c, i++, j--); +} + +private void swap(char[] c, int i, int j) { + char t = c[i]; + c[i] = c[j]; + c[j] = t; +} +``` + + + + + + +
diff --git a/notes/58.2 左旋转字符串.md b/notes/58.2 左旋转字符串.md new file mode 100644 index 00000000..d71486f9 --- /dev/null +++ b/notes/58.2 左旋转字符串.md @@ -0,0 +1,48 @@ +# 58.2 左旋转字符串 + +[NowCoder](https://www.nowcoder.com/practice/12d959b108cb42b1ab72cef4d36af5ec?tpId=13&tqId=11196&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +```html +Input: +S="abcXYZdef" +K=3 + +Output: +"XYZdefabc" +``` + +## 解题思路 + +先将 "abc" 和 "XYZdef" 分别翻转,得到 "cbafedZYX",然后再把整个字符串翻转得到 "XYZdefabc"。 + +```java +public String LeftRotateString(String str, int n) { + if (n >= str.length()) + return str; + char[] chars = str.toCharArray(); + reverse(chars, 0, n - 1); + reverse(chars, n, chars.length - 1); + reverse(chars, 0, chars.length - 1); + return new String(chars); +} + +private void reverse(char[] chars, int i, int j) { + while (i < j) + swap(chars, i++, j--); +} + +private void swap(char[] chars, int i, int j) { + char t = chars[i]; + chars[i] = chars[j]; + chars[j] = t; +} +``` + + + + + + +
diff --git a/notes/59. 滑动窗口的最大值.md b/notes/59. 滑动窗口的最大值.md new file mode 100644 index 00000000..dda1258f --- /dev/null +++ b/notes/59. 滑动窗口的最大值.md @@ -0,0 +1,36 @@ +# 59. 滑动窗口的最大值 + +[NowCoder](https://www.nowcoder.com/practice/1624bc35a45c42c0bc17d17fa0cba788?tpId=13&tqId=11217&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。 + +例如,如果输入数组 {2, 3, 4, 2, 6, 2, 5, 1} 及滑动窗口的大小 3,那么一共存在 6 个滑动窗口,他们的最大值分别为 {4, 4, 6, 6, 6, 5}。 + +## 解题思路 + +```java +public ArrayList maxInWindows(int[] num, int size) { + ArrayList ret = new ArrayList<>(); + if (size > num.length || size < 1) + return ret; + PriorityQueue heap = new PriorityQueue<>((o1, o2) -> o2 - o1); /* 大顶堆 */ + for (int i = 0; i < size; i++) + heap.add(num[i]); + ret.add(heap.peek()); + for (int i = 0, j = i + size; j < num.length; i++, j++) { /* 维护一个大小为 size 的大顶堆 */ + heap.remove(num[i]); + heap.add(num[j]); + ret.add(heap.peek()); + } + return ret; +} +``` + + + + + + +
diff --git a/notes/6. 从尾到头打印链表.md b/notes/6. 从尾到头打印链表.md new file mode 100644 index 00000000..15ffe84e --- /dev/null +++ b/notes/6. 从尾到头打印链表.md @@ -0,0 +1,85 @@ +# 6. 从尾到头打印链表 + +[NowCoder](https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId=13&tqId=11156&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +从尾到头反过来打印出每个结点的值。 + +

+ +## 解题思路 + +### 使用递归 + +要逆序打印链表 1->2->3(3,2,1),可以先逆序打印链表 2->3(3,2),最后再打印第一个节点 1。而链表 2->3 可以看成一个新的链表,要逆序打印该链表可以继续使用求解函数,也就是在求解函数中调用自己,这就是递归函数。 + +```java +public ArrayList printListFromTailToHead(ListNode listNode) { + ArrayList ret = new ArrayList<>(); + if (listNode != null) { + ret.addAll(printListFromTailToHead(listNode.next)); + ret.add(listNode.val); + } + return ret; +} +``` + +### 使用头插法 + +使用头插法可以得到一个逆序的链表。 + +头结点和第一个节点的区别: + +- 头结点是在头插法中使用的一个额外节点,这个节点不存储值; +- 第一个节点就是链表的第一个真正存储值的节点。 + +

+ +```java +public ArrayList printListFromTailToHead(ListNode listNode) { + // 头插法构建逆序链表 + ListNode head = new ListNode(-1); + while (listNode != null) { + ListNode memo = listNode.next; + listNode.next = head.next; + head.next = listNode; + listNode = memo; + } + // 构建 ArrayList + ArrayList ret = new ArrayList<>(); + head = head.next; + while (head != null) { + ret.add(head.val); + head = head.next; + } + return ret; +} +``` + +### 使用栈 + +栈具有后进先出的特点,在遍历链表时将值按顺序放入栈中,最后出栈的顺序即为逆序。 + +

+ +```java +public ArrayList printListFromTailToHead(ListNode listNode) { + Stack stack = new Stack<>(); + while (listNode != null) { + stack.add(listNode.val); + listNode = listNode.next; + } + ArrayList ret = new ArrayList<>(); + while (!stack.isEmpty()) + ret.add(stack.pop()); + return ret; +} +``` + + + + + + +
diff --git a/notes/60. n 个骰子的点数.md b/notes/60. n 个骰子的点数.md new file mode 100644 index 00000000..c981a002 --- /dev/null +++ b/notes/60. n 个骰子的点数.md @@ -0,0 +1,79 @@ +# 60. n 个骰子的点数 + +[Lintcode](https://www.lintcode.com/en/problem/dices-sum/) + +## 题目描述 + +把 n 个骰子扔在地上,求点数和为 s 的概率。 + +

+ +## 解题思路 + +### 动态规划 + +使用一个二维数组 dp 存储点数出现的次数,其中 dp[i][j] 表示前 i 个骰子产生点数 j 的次数。 + +空间复杂度:O(N2) + +```java +public List> dicesSum(int n) { + final int face = 6; + final int pointNum = face * n; + long[][] dp = new long[n + 1][pointNum + 1]; + + for (int i = 1; i <= face; i++) + dp[1][i] = 1; + + for (int i = 2; i <= n; i++) + for (int j = i; j <= pointNum; j++) /* 使用 i 个骰子最小点数为 i */ + for (int k = 1; k <= face && k <= j; k++) + dp[i][j] += dp[i - 1][j - k]; + + final double totalNum = Math.pow(6, n); + List> ret = new ArrayList<>(); + for (int i = n; i <= pointNum; i++) + ret.add(new AbstractMap.SimpleEntry<>(i, dp[n][i] / totalNum)); + + return ret; +} +``` + +### 动态规划 + 旋转数组 + +空间复杂度:O(N) + +```java +public List> dicesSum(int n) { + final int face = 6; + final int pointNum = face * n; + long[][] dp = new long[2][pointNum + 1]; + + for (int i = 1; i <= face; i++) + dp[0][i] = 1; + + int flag = 1; /* 旋转标记 */ + for (int i = 2; i <= n; i++, flag = 1 - flag) { + for (int j = 0; j <= pointNum; j++) + dp[flag][j] = 0; /* 旋转数组清零 */ + + for (int j = i; j <= pointNum; j++) + for (int k = 1; k <= face && k <= j; k++) + dp[flag][j] += dp[1 - flag][j - k]; + } + + final double totalNum = Math.pow(6, n); + List> ret = new ArrayList<>(); + for (int i = n; i <= pointNum; i++) + ret.add(new AbstractMap.SimpleEntry<>(i, dp[1 - flag][i] / totalNum)); + + return ret; +} +``` + + + + + + +
diff --git a/notes/61. 扑克牌顺子.md b/notes/61. 扑克牌顺子.md new file mode 100644 index 00000000..771b7472 --- /dev/null +++ b/notes/61. 扑克牌顺子.md @@ -0,0 +1,44 @@ +# 61. 扑克牌顺子 + +[NowCoder](https://www.nowcoder.com/practice/762836f4d43d43ca9deb273b3de8e1f4?tpId=13&tqId=11198&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +五张牌,其中大小鬼为癞子,牌面为 0。判断这五张牌是否能组成顺子。 + +

+ + +## 解题思路 + +```java +public boolean isContinuous(int[] nums) { + + if (nums.length < 5) + return false; + + Arrays.sort(nums); + + // 统计癞子数量 + int cnt = 0; + for (int num : nums) + if (num == 0) + cnt++; + + // 使用癞子去补全不连续的顺子 + for (int i = cnt; i < nums.length - 1; i++) { + if (nums[i + 1] == nums[i]) + return false; + cnt -= nums[i + 1] - nums[i] - 1; + } + + return cnt >= 0; +} +``` + + + + + + +
diff --git a/notes/62. 圆圈中最后剩下的数.md b/notes/62. 圆圈中最后剩下的数.md new file mode 100644 index 00000000..41813cc5 --- /dev/null +++ b/notes/62. 圆圈中最后剩下的数.md @@ -0,0 +1,28 @@ +# 62. 圆圈中最后剩下的数 + +[NowCoder](https://www.nowcoder.com/practice/f78a359491e64a50bce2d89cff857eb6?tpId=13&tqId=11199&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +让小朋友们围成一个大圈。然后,随机指定一个数 m,让编号为 0 的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续 0...m-1 报数 .... 这样下去 .... 直到剩下最后一个小朋友,可以不用表演。 + +## 解题思路 + +约瑟夫环,圆圈长度为 n 的解可以看成长度为 n-1 的解再加上报数的长度 m。因为是圆圈,所以最后需要对 n 取余。 + +```java +public int LastRemaining_Solution(int n, int m) { + if (n == 0) /* 特殊输入的处理 */ + return -1; + if (n == 1) /* 递归返回条件 */ + return 0; + return (LastRemaining_Solution(n - 1, m) + m) % n; +} +``` + + + + + + +
diff --git a/notes/63. 股票的最大利润.md b/notes/63. 股票的最大利润.md new file mode 100644 index 00000000..a91cf0fb --- /dev/null +++ b/notes/63. 股票的最大利润.md @@ -0,0 +1,34 @@ +# 63. 股票的最大利润 + +[Leetcode](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/) + +## 题目描述 + +可以有一次买入和一次卖出,买入必须在前。求最大收益。 + +

+ +## 解题思路 + +使用贪心策略,假设第 i 轮进行卖出操作,买入操作价格应该在 i 之前并且价格最低。 + +```java +public int maxProfit(int[] prices) { + if (prices == null || prices.length == 0) + return 0; + int soFarMin = prices[0]; + int maxProfit = 0; + for (int i = 1; i < prices.length; i++) { + soFarMin = Math.min(soFarMin, prices[i]); + maxProfit = Math.max(maxProfit, prices[i] - soFarMin); + } + return maxProfit; +} +``` + + + + + + +
diff --git a/notes/64. 求 1+2+3+...+n.md b/notes/64. 求 1+2+3+...+n.md new file mode 100644 index 00000000..c7ffc571 --- /dev/null +++ b/notes/64. 求 1+2+3+...+n.md @@ -0,0 +1,30 @@ +# 64. 求 1+2+3+...+n + +[NowCoder](https://www.nowcoder.com/practice/7a0da8fc483247ff8800059e12d7caf1?tpId=13&tqId=11200&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +要求不能使用乘除法、for、while、if、else、switch、case 等关键字及条件判断语句 A ? B : C。 + +## 解题思路 + +使用递归解法最重要的是指定返回条件,但是本题无法直接使用 if 语句来指定返回条件。 + +条件与 && 具有短路原则,即在第一个条件语句为 false 的情况下不会去执行第二个条件语句。利用这一特性,将递归的返回条件取非然后作为 && 的第一个条件语句,递归的主体转换为第二个条件语句,那么当递归的返回条件为 true 的情况下就不会执行递归的主体部分,递归返回。 + +本题的递归返回条件为 n <= 0,取非后就是 n > 0;递归的主体部分为 sum += Sum_Solution(n - 1),转换为条件语句后就是 (sum += Sum_Solution(n - 1)) > 0。 + +```java +public int Sum_Solution(int n) { + int sum = n; + boolean b = (n > 0) && ((sum += Sum_Solution(n - 1)) > 0); + return sum; +} +``` + + + + + + +
diff --git a/notes/65. 不用加减乘除做加法.md b/notes/65. 不用加减乘除做加法.md new file mode 100644 index 00000000..004442d5 --- /dev/null +++ b/notes/65. 不用加减乘除做加法.md @@ -0,0 +1,26 @@ +# 65. 不用加减乘除做加法 + +[NowCoder](https://www.nowcoder.com/practice/59ac416b4b944300b617d4f7f111b215?tpId=13&tqId=11201&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +写一个函数,求两个整数之和,要求不得使用 +、-、\*、/ 四则运算符号。 + +## 解题思路 + +a ^ b 表示没有考虑进位的情况下两数的和,(a & b) << 1 就是进位。 + +递归会终止的原因是 (a & b) << 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。 + +```java +public int Add(int a, int b) { + return b == 0 ? a : Add(a ^ b, (a & b) << 1); +} +``` + + + + + + +
diff --git a/notes/66. 构建乘积数组.md b/notes/66. 构建乘积数组.md new file mode 100644 index 00000000..52d73f87 --- /dev/null +++ b/notes/66. 构建乘积数组.md @@ -0,0 +1,31 @@ +# 66. 构建乘积数组 + +[NowCoder](https://www.nowcoder.com/practice/94a4d381a68b47b7a8bed86f2975db46?tpId=13&tqId=11204&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +给定一个数组 A[0, 1,..., n-1],请构建一个数组 B[0, 1,..., n-1],其中 B 中的元素 B[i]=A[0]\*A[1]\*...\*A[i-1]\*A[i+1]\*...\*A[n-1]。要求不能使用除法。 + +

+ + +## 解题思路 + +```java +public int[] multiply(int[] A) { + int n = A.length; + int[] B = new int[n]; + for (int i = 0, product = 1; i < n; product *= A[i], i++) /* 从左往右累乘 */ + B[i] = product; + for (int i = n - 1, product = 1; i >= 0; product *= A[i], i--) /* 从右往左累乘 */ + B[i] *= product; + return B; +} +``` + + + + + + +
diff --git a/notes/67. 把字符串转换成整数.md b/notes/67. 把字符串转换成整数.md new file mode 100644 index 00000000..8ecdccf1 --- /dev/null +++ b/notes/67. 把字符串转换成整数.md @@ -0,0 +1,44 @@ +# 67. 把字符串转换成整数 + +[NowCoder](https://www.nowcoder.com/practice/1277c681251b4372bdef344468e4f26e?tpId=13&tqId=11202&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +将一个字符串转换成一个整数,字符串不是一个合法的数值则返回 0,要求不能使用字符串转换整数的库函数。 + +```html +Iuput: ++2147483647 +1a33 + +Output: +2147483647 +0 +``` + +## 解题思路 + +```java +public int StrToInt(String str) { + if (str == null || str.length() == 0) + return 0; + boolean isNegative = str.charAt(0) == '-'; + int ret = 0; + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + if (i == 0 && (c == '+' || c == '-')) /* 符号判定 */ + continue; + if (c < '0' || c > '9') /* 非法输入 */ + return 0; + ret = ret * 10 + (c - '0'); + } + return isNegative ? -ret : ret; +} +``` + + + + + + +
diff --git a/notes/68. 树中两个节点的最低公共祖先.md b/notes/68. 树中两个节点的最低公共祖先.md new file mode 100644 index 00000000..bce290e5 --- /dev/null +++ b/notes/68. 树中两个节点的最低公共祖先.md @@ -0,0 +1,48 @@ +# 68. 树中两个节点的最低公共祖先 + +## 解题思路 + +### 二叉查找树 + +[Leetcode : 235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description/) + +二叉查找树中,两个节点 p, q 的公共祖先 root 满足 root.val >= p.val && root.val <= q.val。 + +

+ +```java +public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null) + return root; + if (root.val > p.val && root.val > q.val) + return lowestCommonAncestor(root.left, p, q); + if (root.val < p.val && root.val < q.val) + return lowestCommonAncestor(root.right, p, q); + return root; +} +``` + +### 普通二叉树 + +[Leetcode : 236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/) + +在左右子树中查找是否存在 p 或者 q,如果 p 和 q 分别在两个子树中,那么就说明根节点就是最低公共祖先。 + +

+ +```java +public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { + if (root == null || root == p || root == q) + return root; + TreeNode left = lowestCommonAncestor(root.left, p, q); + TreeNode right = lowestCommonAncestor(root.right, p, q); + return left == null ? right : right == null ? left : root; +} +``` + + + + + + +
diff --git a/notes/7. 重建二叉树.md b/notes/7. 重建二叉树.md new file mode 100644 index 00000000..4fee604f --- /dev/null +++ b/notes/7. 重建二叉树.md @@ -0,0 +1,45 @@ +# 7. 重建二叉树 + +[NowCoder](https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 + + +

+ +## 解题思路 + +前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两部分,左部分为树的左子树中序遍历结果,右部分为树的右子树中序遍历的结果。 + +

+ +```java +// 缓存中序遍历数组每个值对应的索引 +private Map indexForInOrders = new HashMap<>(); + +public TreeNode reConstructBinaryTree(int[] pre, int[] in) { + for (int i = 0; i < in.length; i++) + indexForInOrders.put(in[i], i); + return reConstructBinaryTree(pre, 0, pre.length - 1, 0); +} + +private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int inL) { + if (preL > preR) + return null; + TreeNode root = new TreeNode(pre[preL]); + int inIndex = indexForInOrders.get(root.val); + int leftTreeSize = inIndex - inL; + root.left = reConstructBinaryTree(pre, preL + 1, preL + leftTreeSize, inL); + root.right = reConstructBinaryTree(pre, preL + leftTreeSize + 1, preR, inL + leftTreeSize + 1); + return root; +} +``` + + + + + + +
diff --git a/notes/8. 二叉树的下一个结点.md b/notes/8. 二叉树的下一个结点.md new file mode 100644 index 00000000..84fdaaa1 --- /dev/null +++ b/notes/8. 二叉树的下一个结点.md @@ -0,0 +1,57 @@ +# 8. 二叉树的下一个结点 + +[NowCoder](https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 + +```java +public class TreeLinkNode { + + int val; + TreeLinkNode left = null; + TreeLinkNode right = null; + TreeLinkNode next = null; + + TreeLinkNode(int val) { + this.val = val; + } +} +``` + +## 解题思路 + +① 如果一个节点的右子树不为空,那么该节点的下一个节点是右子树的最左节点; + +

+ +② 否则,向上找第一个左链接指向的树包含该节点的祖先节点。 + +

+ +```java +public TreeLinkNode GetNext(TreeLinkNode pNode) { + if (pNode.right != null) { + TreeLinkNode node = pNode.right; + while (node.left != null) + node = node.left; + return node; + } else { + while (pNode.next != null) { + TreeLinkNode parent = pNode.next; + if (parent.left == pNode) + return parent; + pNode = pNode.next; + } + } + return null; +} +``` + + + + + + +
diff --git a/notes/9. 用两个栈实现队列.md b/notes/9. 用两个栈实现队列.md new file mode 100644 index 00000000..2f0cee5b --- /dev/null +++ b/notes/9. 用两个栈实现队列.md @@ -0,0 +1,40 @@ +# 9. 用两个栈实现队列 + +[NowCoder](https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) + +## 题目描述 + +用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。 + +## 解题思路 + +in 栈用来处理入栈(push)操作,out 栈用来处理出栈(pop)操作。一个元素进入 in 栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入 out 栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,先进入的元素先退出,这就是队列的顺序。 + +

+ +```java +Stack in = new Stack(); +Stack out = new Stack(); + +public void push(int node) { + in.push(node); +} + +public int pop() throws Exception { + if (out.isEmpty()) + while (!in.isEmpty()) + out.push(in.pop()); + + if (out.isEmpty()) + throw new Exception("queue is empty"); + + return out.pop(); +} +``` + + + + + + +
diff --git a/notes/HTTP.md b/notes/HTTP.md index 5a7fc636..a7e14f90 100644 --- a/notes/HTTP.md +++ b/notes/HTTP.md @@ -76,7 +76,7 @@ URI 包含 URL 和 URN。 # 二、HTTP 方法 -客户端发送的 **请求报文** 第一行为请求行,包含了方法字段。 +客户端发送的 **请求报文** 第一行为请求行,包含了方法字段。 ## GET @@ -173,7 +173,7 @@ CONNECT www.example.com:443 HTTP/1.1 # 三、HTTP 状态码 -服务器返回的 **响应报文** 中第一行为状态行,包含了状态码以及原因短语,用来告知客户端请求的结果。 +服务器返回的 **响应报文** 中第一行为状态行,包含了状态码以及原因短语,用来告知客户端请求的结果。 | 状态码 | 类别 | 含义 | | :---: | :---: | :---: | @@ -185,45 +185,45 @@ CONNECT www.example.com:443 HTTP/1.1 ## 1XX 信息 -- **100 Continue** :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。 +- **100 Continue** :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。 ## 2XX 成功 -- **200 OK** +- **200 OK** -- **204 No Content** :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。 +- **204 No Content** :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。 -- **206 Partial Content** :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。 +- **206 Partial Content** :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。 ## 3XX 重定向 -- **301 Moved Permanently** :永久性重定向 +- **301 Moved Permanently** :永久性重定向 -- **302 Found** :临时性重定向 +- **302 Found** :临时性重定向 -- **303 See Other** :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。 +- **303 See Other** :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。 - 注:虽然 HTTP 协议规定 301、302 状态下重定向时不允许把 POST 方法改成 GET 方法,但是大多数浏览器都会在 301、302 和 303 状态下的重定向把 POST 方法改成 GET 方法。 -- **304 Not Modified** :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回 304 状态码。 +- **304 Not Modified** :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回 304 状态码。 -- **307 Temporary Redirect** :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的 POST 方法改成 GET 方法。 +- **307 Temporary Redirect** :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的 POST 方法改成 GET 方法。 ## 4XX 客户端错误 -- **400 Bad Request** :请求报文中存在语法错误。 +- **400 Bad Request** :请求报文中存在语法错误。 -- **401 Unauthorized** :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进行过一次请求,则表示用户认证失败。 +- **401 Unauthorized** :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进行过一次请求,则表示用户认证失败。 -- **403 Forbidden** :请求被拒绝。 +- **403 Forbidden** :请求被拒绝。 -- **404 Not Found** +- **404 Not Found** ## 5XX 服务器错误 -- **500 Internal Server Error** :服务器正在执行请求时发生错误。 +- **500 Internal Server Error** :服务器正在执行请求时发生错误。 -- **503 Service Unavailable** :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。 +- **503 Service Unavailable** :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。 # 四、HTTP 首部 @@ -436,7 +436,7 @@ Session 可以存储在服务器上的文件、数据库或者内存中。也可 HTTP/1.1 通过 Cache-Control 首部字段来控制缓存。 -**3.1 禁止进行缓存** +**3.1 禁止进行缓存** no-store 指令规定不能对请求或响应的任何一部分进行缓存。 @@ -444,7 +444,7 @@ no-store 指令规定不能对请求或响应的任何一部分进行缓存。 Cache-Control: no-store ``` -**3.2 强制确认缓存** +**3.2 强制确认缓存** no-cache 指令规定缓存服务器需要先向源服务器验证缓存资源的有效性,只有当缓存资源有效时才能使用该缓存对客户端的请求进行响应。 @@ -452,7 +452,7 @@ no-cache 指令规定缓存服务器需要先向源服务器验证缓存资源 Cache-Control: no-cache ``` -**3.3 私有缓存和公共缓存** +**3.3 私有缓存和公共缓存** private 指令规定了将资源作为私有缓存,只能被单独用户使用,一般存储在用户浏览器中。 @@ -466,7 +466,7 @@ public 指令规定了将资源作为公共缓存,可以被多个用户使用 Cache-Control: public ``` -**3.4 缓存过期机制** +**3.4 缓存过期机制** max-age 指令出现在请求报文,并且缓存资源的缓存时间小于该指令指定的时间,那么就能接受该缓存。 @@ -515,7 +515,7 @@ If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT ### 1. 类型 -**1.1 服务端驱动型** +**1.1 服务端驱动型** 客户端设置特定的 HTTP 首部字段,例如 Accept、Accept-Charset、Accept-Encoding、Accept-Language,服务器根据这些字段返回特定的资源。 @@ -525,7 +525,7 @@ If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT - 客户端提供的信息相当冗长(HTTP/2 协议的首部压缩机制缓解了这个问题),并且存在隐私风险(HTTP 指纹识别技术); - 给定的资源需要返回不同的展现形式,共享缓存的效率会降低,而服务器端的实现会越来越复杂。 -**1.2 代理驱动型** +**1.2 代理驱动型** 服务器返回 300 Multiple Choices 或者 406 Not Acceptable,客户端从中选出最合适的那个资源。 @@ -691,7 +691,7 @@ HTTPS 采用混合的加密机制,使用非对称密钥加密用于传输对 ## 认证 -通过使用 **证书** 来对通信方进行认证。 +通过使用 **证书** 来对通信方进行认证。 数字证书认证机构(CA,Certificate Authority)是客户端与服务器双方都可信赖的第三方机构。 diff --git a/notes/Java 基础.md b/notes/Java 基础.md index 73191381..3d6b339e 100644 --- a/notes/Java 基础.md +++ b/notes/Java 基础.md @@ -185,21 +185,21 @@ value 数组被声明为 final,这意味着 value 数组初始化之后就不 ## 不可变的好处 -**1. 可以缓存 hash 值** +**1. 可以缓存 hash 值** 因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,因此只需要进行一次计算。 -**2. String Pool 的需要** +**2. String Pool 的需要** 如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。

-**3. 安全性** +**3. 安全性** String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 对象的那一方以为现在连接的是其它主机,而实际情况却不一定是。 -**4. 线程安全** +**4. 线程安全** String 不可变性天生具备线程安全,可以在多个线程中安全地使用。 @@ -207,12 +207,12 @@ String 不可变性天生具备线程安全,可以在多个线程中安全地 ## String, StringBuffer and StringBuilder -**1. 可变性** +**1. 可变性** - String 不可变 - StringBuffer 和 StringBuilder 可变 -**2. 线程安全** +**2. 线程安全** - String 不可变,因此是线程安全的 - StringBuilder 不是线程安全的 @@ -509,7 +509,7 @@ public class AccessWithInnerClassExample { ## 抽象类与接口 -**1. 抽象类** +**1. 抽象类** 抽象类和抽象方法都使用 abstract 关键字进行声明。如果一个类中包含抽象方法,那么这个类必须声明为抽象类。 @@ -544,7 +544,7 @@ AbstractClassExample ac2 = new AbstractExtendClassExample(); ac2.func1(); ``` -**2. 接口** +**2. 接口** 接口是抽象类的延伸,在 Java 8 之前,它可以看成是一个完全抽象的类,也就是说它不能有任何的方法实现。 @@ -588,14 +588,14 @@ ie2.func1(); System.out.println(InterfaceExample.x); ``` -**3. 比较** +**3. 比较** - 从设计层面上看,抽象类提供了一种 IS-A 关系,那么就必须满足里式替换原则,即子类对象必须能够替换掉所有父类对象。而接口更像是一种 LIKE-A 关系,它只是提供一种方法实现契约,并不要求接口和实现接口的类具有 IS-A 关系。 - 从使用上来看,一个类可以实现多个接口,但是不能继承多个抽象类。 - 接口的字段只能是 static 和 final 类型的,而抽象类的字段没有这种限制。 - 接口的成员只能是 public 的,而抽象类的成员可以有多种访问权限。 -**4. 使用选择** +**4. 使用选择** 使用接口: @@ -669,7 +669,7 @@ SuperExtendExample.func() ## 重写与重载 -**1. 重写(Override)** +**1. 重写(Override)** 存在于继承体系中,指子类实现了一个与父类在方法声明上完全相同的一个方法。 @@ -773,7 +773,7 @@ public static void main(String[] args) { } ``` -**2. 重载(Overload)** +**2. 重载(Overload)** 存在于同一个类中,指一个方法与已经存在的方法名称上相同,但是参数类型、个数、顺序至少有一个不同。 @@ -810,7 +810,7 @@ public final void wait() throws InterruptedException ## equals() -**1. 等价关系** +**1. 等价关系** Ⅰ 自反性 @@ -847,7 +847,7 @@ x.equals(y) == x.equals(y); // true x.equals(null); // false; ``` -**2. 等价与相等** +**2. 等价与相等** - 对于基本类型,== 判断两个值是否相等,基本类型没有 equals() 方法。 - 对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价。 @@ -859,7 +859,7 @@ System.out.println(x.equals(y)); // true System.out.println(x == y); // false ``` -**3. 实现** +**3. 实现** - 检查是否为同一个对象的引用,如果是直接返回 true; - 检查是否是同一个类型,如果不是,直接返回 false; @@ -952,7 +952,7 @@ ToStringExample@4554617c ## clone() -**1. cloneable** +**1. cloneable** clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写 clone(),其它类就不能直接去调用该类实例的 clone() 方法。 @@ -1011,7 +1011,7 @@ public class CloneExample implements Cloneable { } ``` -**2. 浅拷贝** +**2. 浅拷贝** 拷贝对象和原始对象的引用类型引用同一个对象。 @@ -1054,7 +1054,7 @@ e1.set(2, 222); System.out.println(e2.get(2)); // 222 ``` -**3. 深拷贝** +**3. 深拷贝** 拷贝对象和原始对象的引用类型引用不同对象。 @@ -1102,7 +1102,7 @@ e1.set(2, 222); System.out.println(e2.get(2)); // 2 ``` -**4. clone() 的替代方案** +**4. clone() 的替代方案** 使用 clone() 方法来拷贝一个对象即复杂又有风险,它会抛出异常,并且还需要类型转换。Effective Java 书上讲到,最好不要去使用 clone(),可以使用拷贝构造函数或者拷贝工厂来拷贝一个对象。 @@ -1146,7 +1146,7 @@ System.out.println(e2.get(2)); // 2 ## final -**1. 数据** +**1. 数据** 声明数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量。 @@ -1160,19 +1160,19 @@ final A y = new A(); y.a = 1; ``` -**2. 方法** +**2. 方法** 声明方法不能被子类重写。 private 方法隐式地被指定为 final,如果在子类中定义的方法和基类中的一个 private 方法签名相同,此时子类的方法不是重写基类方法,而是在子类中定义了一个新的方法。 -**3. 类** +**3. 类** 声明类不允许被继承。 ## static -**1. 静态变量** +**1. 静态变量** - 静态变量:又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来访问它。静态变量在内存中只存在一份。 - 实例变量:每创建一个实例就会产生一个实例变量,它与该实例同生共死。 @@ -1192,7 +1192,7 @@ public class A { } ``` -**2. 静态方法** +**2. 静态方法** 静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法。 @@ -1220,7 +1220,7 @@ public class A { } ``` -**3. 静态语句块** +**3. 静态语句块** 静态语句块在类初始化时运行一次。 @@ -1241,7 +1241,7 @@ public class A { 123 ``` -**4. 静态内部类** +**4. 静态内部类** 非静态内部类依赖于外部类的实例,而静态内部类不需要。 @@ -1265,7 +1265,7 @@ public class OuterClass { 静态内部类不能访问外部类的非静态的变量和方法。 -**5. 静态导包** +**5. 静态导包** 在使用静态变量和方法时不用再指明 ClassName,从而简化代码,但可读性大大降低。 @@ -1273,7 +1273,7 @@ public class OuterClass { import static com.xxx.ClassName.* ``` -**6. 初始化顺序** +**6. 初始化顺序** 静态变量和静态语句块优先于实例变量和普通语句块,静态变量和静态语句块的初始化顺序取决于它们在代码中的顺序。 @@ -1317,7 +1317,7 @@ public InitialOrderTest() { # 七、反射 -每个类都有一个 **Class** 对象,包含了与类有关的信息。当编译一个新类时,会产生一个同名的 .class 文件,该文件内容保存着 Class 对象。 +每个类都有一个 **Class** 对象,包含了与类有关的信息。当编译一个新类时,会产生一个同名的 .class 文件,该文件内容保存着 Class 对象。 类加载相当于 Class 对象的加载,类在第一次使用时才动态加载到 JVM 中。也可以使用 `Class.forName("com.mysql.jdbc.Driver")` 这种方式来控制类的加载,该方法会返回一个 Class 对象。 @@ -1325,25 +1325,25 @@ public InitialOrderTest() { Class 和 java.lang.reflect 一起对反射提供了支持,java.lang.reflect 类库主要包含了以下三个类: -- **Field** :可以使用 get() 和 set() 方法读取和修改 Field 对象关联的字段; -- **Method** :可以使用 invoke() 方法调用与 Method 对象关联的方法; -- **Constructor** :可以用 Constructor 的 newInstance() 创建新的对象。 +- **Field** :可以使用 get() 和 set() 方法读取和修改 Field 对象关联的字段; +- **Method** :可以使用 invoke() 方法调用与 Method 对象关联的方法; +- **Constructor** :可以用 Constructor 的 newInstance() 创建新的对象。 -**反射的优点:** +**反射的优点:** -* **可扩展性** :应用程序可以利用全限定名创建可扩展对象的实例,来使用来自外部的用户自定义类。 -* **类浏览器和可视化开发环境** :一个类浏览器需要可以枚举类的成员。可视化开发环境(如 IDE)可以从利用反射中可用的类型信息中受益,以帮助程序员编写正确的代码。 -* **调试器和测试工具** : 调试器需要能够检查一个类里的私有成员。测试工具可以利用反射来自动地调用类里定义的可被发现的 API 定义,以确保一组测试中有较高的代码覆盖率。 +* **可扩展性** :应用程序可以利用全限定名创建可扩展对象的实例,来使用来自外部的用户自定义类。 +* **类浏览器和可视化开发环境** :一个类浏览器需要可以枚举类的成员。可视化开发环境(如 IDE)可以从利用反射中可用的类型信息中受益,以帮助程序员编写正确的代码。 +* **调试器和测试工具** : 调试器需要能够检查一个类里的私有成员。测试工具可以利用反射来自动地调用类里定义的可被发现的 API 定义,以确保一组测试中有较高的代码覆盖率。 -**反射的缺点:** +**反射的缺点:** 尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。在我们使用反射技术时,下面几条内容应该牢记于心。 -* **性能开销** :反射涉及了动态类型的解析,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。 +* **性能开销** :反射涉及了动态类型的解析,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。 -* **安全限制** :使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如 Applet,那么这就是个问题了。 +* **安全限制** :使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如 Applet,那么这就是个问题了。 -* **内部暴露** :由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用,这可能导致代码功能失调并破坏可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。 +* **内部暴露** :由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用,这可能导致代码功能失调并破坏可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。 - [Trail: The Reflection API](https://docs.oracle.com/javase/tutorial/reflect/index.html) @@ -1351,10 +1351,10 @@ Class 和 java.lang.reflect 一起对反射提供了支持,java.lang.reflect # 八、异常 -Throwable 可以用来表示任何可以作为异常抛出的类,分为两种: **Error** 和 **Exception**。其中 Error 用来表示 JVM 无法处理的错误,Exception 分为两种: +Throwable 可以用来表示任何可以作为异常抛出的类,分为两种: **Error** 和 **Exception**。其中 Error 用来表示 JVM 无法处理的错误,Exception 分为两种: -- **受检异常** :需要用 try...catch... 语句捕获并进行处理,并且可以从异常中恢复; -- **非受检异常** :是程序运行时错误,例如除 0 会引发 Arithmetic Exception,此时程序崩溃并且无法恢复。 +- **受检异常** :需要用 try...catch... 语句捕获并进行处理,并且可以从异常中恢复; +- **非受检异常** :是程序运行时错误,例如除 0 会引发 Arithmetic Exception,此时程序崩溃并且无法恢复。

@@ -1385,7 +1385,7 @@ Java 注解是附加在代码中的一些元信息,用于一些工具在编译 ## Java 各版本的新特性 -**New highlights in Java SE 8** +**New highlights in Java SE 8** 1. Lambda Expressions 2. Pipelines and Streams @@ -1397,7 +1397,7 @@ Java 注解是附加在代码中的一些元信息,用于一些工具在编译 8. Parallel operations 9. PermGen Error Removed -**New highlights in Java SE 7** +**New highlights in Java SE 7** 1. Strings in Switch Statement 2. Type Inference for Generic Instance Creation diff --git a/notes/Java 容器.md b/notes/Java 容器.md index 34f4045f..24a85b62 100644 --- a/notes/Java 容器.md +++ b/notes/Java 容器.md @@ -618,7 +618,7 @@ int hash = hash(key); int i = indexFor(hash, table.length); ``` -**4.1 计算 hash 值** +**4.1 计算 hash 值** ```java final int hash(Object k) { @@ -643,7 +643,7 @@ public final int hashCode() { } ``` -**4.2 取模** +**4.2 取模** 令 x = 1<<4,即 x 为 2 的 4 次方,它具有以下性质: diff --git a/notes/Java 并发.md b/notes/Java 并发.md index b32a5378..a2f91391 100644 --- a/notes/Java 并发.md +++ b/notes/Java 并发.md @@ -384,7 +384,7 @@ Java 提供了两种锁机制来控制多个线程对共享资源的互斥访问 ## synchronized -**1. 同步一个代码块** +**1. 同步一个代码块** ```java public void func() { @@ -441,7 +441,7 @@ public static void main(String[] args) { ``` -**2. 同步一个方法** +**2. 同步一个方法** ```java public synchronized void func () { @@ -451,7 +451,7 @@ public synchronized void func () { 它和同步代码块一样,作用于同一个对象。 -**3. 同步一个类** +**3. 同步一个类** ```java public void func() { @@ -490,7 +490,7 @@ public static void main(String[] args) { 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 ``` -**4. 同步一个静态方法** +**4. 同步一个静态方法** ```java public synchronized static void fun() { @@ -538,27 +538,27 @@ public static void main(String[] args) { ## 比较 -**1. 锁的实现** +**1. 锁的实现** synchronized 是 JVM 实现的,而 ReentrantLock 是 JDK 实现的。 -**2. 性能** +**2. 性能** 新版本 Java 对 synchronized 进行了很多优化,例如自旋锁等,synchronized 与 ReentrantLock 大致相同。 -**3. 等待可中断** +**3. 等待可中断** 当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。 ReentrantLock 可中断,而 synchronized 不行。 -**4. 公平锁** +**4. 公平锁** 公平锁是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁。 synchronized 中的锁是非公平的,ReentrantLock 默认情况下也是非公平的,但是也可以是公平的。 -**5. 锁绑定多个条件** +**5. 锁绑定多个条件** 一个 ReentrantLock 可以同时绑定多个 Condition 对象。 @@ -669,7 +669,7 @@ before after ``` -**wait() 和 sleep() 的区别** +**wait() 和 sleep() 的区别** - wait() 是 Object 的方法,而 sleep() 是 Thread 的静态方法; - wait() 会释放锁,sleep() 不会。 @@ -907,12 +907,12 @@ other task is running... java.util.concurrent.BlockingQueue 接口有以下阻塞队列的实现: -- **FIFO 队列** :LinkedBlockingQueue、ArrayBlockingQueue(固定长度) -- **优先级队列** :PriorityBlockingQueue +- **FIFO 队列** :LinkedBlockingQueue、ArrayBlockingQueue(固定长度) +- **优先级队列** :PriorityBlockingQueue 提供了阻塞的 take() 和 put() 方法:如果队列为空 take() 将阻塞,直到队列中有内容;如果队列为满 put() 将阻塞,直到队列有空闲位置。 -**使用 BlockingQueue 实现生产者消费者问题** +**使用 BlockingQueue 实现生产者消费者问题** ```java public class ProducerConsumer { diff --git a/notes/Java 虚拟机.md b/notes/Java 虚拟机.md index 69e02e32..aa431b9e 100644 --- a/notes/Java 虚拟机.md +++ b/notes/Java 虚拟机.md @@ -28,7 +28,7 @@ -本文大部分内容参考 **周志明《深入理解 Java 虚拟机》** ,想要深入学习的话请看原书。 +本文大部分内容参考 **周志明《深入理解 Java 虚拟机》** ,想要深入学习的话请看原书。 # 一、运行时数据区域 @@ -462,11 +462,11 @@ G1 把堆划分成多个大小相等的独立区域(Region),新生代和 包括以下 7 个阶段: -- **加载(Loading)** -- **验证(Verification)** -- **准备(Preparation)** -- **解析(Resolution)** -- **初始化(Initialization)** +- **加载(Loading)** +- **验证(Verification)** +- **准备(Preparation)** +- **解析(Resolution)** +- **初始化(Initialization)** - 使用(Using) - 卸载(Unloading) @@ -521,11 +521,9 @@ public static final int value = 123; 其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。
- ### 5. 初始化
- 初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段是虚拟机执行类构造器 <clinit>() 方法的过程。在准备阶段,类变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划去初始化类变量和其它资源。 <clinit>() 是由编译器自动收集类中所有类变量的赋值动作和静态语句块中的语句合并产生的,编译器收集的顺序由语句在源文件中出现的顺序决定。特别注意的是,静态语句块只能访问到定义在它之前的类变量,定义在它之后的类变量只能赋值,不能访问。例如以下代码: @@ -624,7 +622,6 @@ System.out.println(ConstClass.HELLOWORLD); - 应用程序类加载器(Application ClassLoader)这个类加载器是由 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。由于这个类加载器是 ClassLoader 中的 getSystemClassLoader() 方法的返回值,因此一般称为系统类加载器。它负责加载用户类路径(ClassPath)上所指定的类库,开发者可以直接使用这个类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。
- ## 双亲委派模型 应用程序是由三种类加载器互相配合从而实现类加载,除此之外还可以加入自己定义的类加载器。 diff --git a/notes/Leetcode 题解 - 二分查找.md b/notes/Leetcode 题解 - 二分查找.md index 1a7c44be..ff9624e7 100644 --- a/notes/Leetcode 题解 - 二分查找.md +++ b/notes/Leetcode 题解 - 二分查找.md @@ -8,7 +8,7 @@ -**正常实现** +正常实现** ```text Input : [1,2,3,4,5] @@ -33,11 +33,11 @@ public int binarySearch(int[] nums, int key) { } ``` -**时间复杂度** +**时间复杂度** 二分查找也称为折半查找,每次都能将查找区间减半,这种折半特性的算法时间复杂度为 O(logN)。 -**m 计算** +**m 计算** 有两种计算中值 m 的方式: @@ -46,14 +46,14 @@ public int binarySearch(int[] nums, int key) { l + h 可能出现加法溢出,也就是说加法的结果大于整型能够表示的范围。但是 l 和 h 都为正数,因此 h - l 不会出现加法溢出问题。所以,最好使用第二种计算法方法。 -**未成功查找的返回值** +**未成功查找的返回值** 循环退出时如果仍然没有查找到 key,那么表示查找失败。可以有两种返回值: - -1:以一个错误码表示没有查找到 key - l:将 key 插入到 nums 中的正确位置 -**变种** +**变种** 二分查找可以有很多变种,变种实现要注意边界值的判断。例如在一个有重复元素的数组中查找 key 的最左位置的实现如下: diff --git a/notes/Leetcode 题解 - 位运算.md b/notes/Leetcode 题解 - 位运算.md index a9fd6121..d89047bc 100644 --- a/notes/Leetcode 题解 - 位运算.md +++ b/notes/Leetcode 题解 - 位运算.md @@ -15,7 +15,7 @@ -**基本原理** +**基本原理** 0s 表示一串 0,1s 表示一串 1。 @@ -41,7 +41,7 @@ x ^ x = 0 x & x = x x | x = x - \>\>\> n 为无符号右移,左边会补上 0。 - << n 为算术左移,相当于乘以 2n。 -** mask 计算** +** mask 计算** 要获取 111111111,将 0 取反即可,\~0。 @@ -51,7 +51,7 @@ x ^ x = 0 x & x = x x | x = x 要得到 1 到 i 位为 0 的 mask,只需将 1 到 i 位为 1 的 mask 取反,即 \~((1<<i)-1)。 -**Java 中的位操作** +**Java 中的位操作** ```html static int Integer.bitCount(); // 统计 1 的数量 diff --git a/notes/Leetcode 题解 - 动态规划.md b/notes/Leetcode 题解 - 动态规划.md index 2f225146..baef722f 100644 --- a/notes/Leetcode 题解 - 动态规划.md +++ b/notes/Leetcode 题解 - 动态规划.md @@ -40,6 +40,8 @@ + + 递归和动态规划都是将原问题拆成多个子问题然后求解,他们之间最本质的区别是,动态规划保存了子问题的解,避免重复计算。 # 斐波那契数列 @@ -430,9 +432,9 @@ public int numDecodings(String s) { # 最长递增子序列 -已知一个序列 {S1, S2,...,Sn},取出若干数组成新的序列 {Si1, Si2,..., Sim},其中 i1、i2 ... im 保持递增,即新序列中各个数仍然保持原数列中的先后顺序,称新序列为原序列的一个 **子序列** 。 +已知一个序列 {S1, S2,...,Sn},取出若干数组成新的序列 {Si1, Si2,..., Sim},其中 i1、i2 ... im 保持递增,即新序列中各个数仍然保持原数列中的先后顺序,称新序列为原序列的一个 **子序列** 。 -如果在子序列中,当下标 ix > iy 时,Six > Siy,称子序列为原序列的一个 **递增子序列** 。 +如果在子序列中,当下标 ix > iy 时,Six > Siy,称子序列为原序列的一个 **递增子序列** 。 定义一个数组 dp 存储最长递增子序列的长度,dp[n] 表示以 Sn 结尾的序列的最长递增子序列长度。对于一个递增子序列 {Si1, Si2,...,Sim},如果 im < n 并且 Sim < Sn,此时 {Si1, Si2,..., Sim, Sn} 为一个递增子序列,递增子序列的长度增加 1。满足上述条件的递增子序列中,长度最长的那个递增子序列就是要找的,在长度最长的递增子序列上加上 Sn 就构成了以 Sn 为结尾的最长递增子序列。因此 dp[n] = max{ dp[i]+1 | Si < Sn && i < n} 。 @@ -676,7 +678,7 @@ public int knapsack(int W, int N, int[] weights, int[] values) { } ``` -**空间优化** +**空间优化** 在程序实现时可以对 0-1 背包做优化。观察状态转移方程可以知道,前 i 件物品的状态仅与前 i-1 件物品的状态有关,因此可以将 dp 定义为一维数组,其中 dp[j] 既可以表示 dp[i-1][j] 也可以表示 dp[i][j]。此时, @@ -701,7 +703,7 @@ public int knapsack(int W, int N, int[] weights, int[] values) { } ``` -**无法使用贪心算法的解释** +**无法使用贪心算法的解释** 0-1 背包问题无法使用贪心算法来求解,也就是说不能按照先添加性价比最高的物品来达到最优,这是因为这种方式可能造成背包空间的浪费,从而无法达到最优。考虑下面的物品和一个容量为 5 的背包,如果先添加物品 0 再添加物品 1,那么只能存放的价值为 16,浪费了大小为 2 的空间。最优的方式是存放物品 1 和物品 2,价值为 22. @@ -711,7 +713,7 @@ public int knapsack(int W, int N, int[] weights, int[] values) { | 1 | 2 | 10 | 5 | | 2 | 3 | 12 | 4 | -**变种** +**变种** - 完全背包:物品数量为无限个 diff --git a/notes/Leetcode 题解 - 哈希表.md b/notes/Leetcode 题解 - 哈希表.md index 34ed2004..c9512df6 100644 --- a/notes/Leetcode 题解 - 哈希表.md +++ b/notes/Leetcode 题解 - 哈希表.md @@ -8,9 +8,9 @@ 哈希表使用 O(N) 空间复杂度存储数据,并且以 O(1) 时间复杂度求解问题。 -- Java 中的 **HashSet** 用于存储一个集合,可以查找元素是否在集合中。如果元素有穷,并且范围不大,那么可以用一个布尔数组来存储一个元素是否存在。例如对于只有小写字符的元素,就可以用一个长度为 26 的布尔数组来存储一个字符集合,使得空间复杂度降低为 O(1)。 +- Java 中的 **HashSet** 用于存储一个集合,可以查找元素是否在集合中。如果元素有穷,并且范围不大,那么可以用一个布尔数组来存储一个元素是否存在。例如对于只有小写字符的元素,就可以用一个长度为 26 的布尔数组来存储一个字符集合,使得空间复杂度降低为 O(1)。 - Java 中的 **HashMap** 主要用于映射关系,从而把两个元素联系起来。HashMap 也可以用来对元素进行计数统计,此时键为元素,值为计数。和 HashSet 类似,如果元素有穷并且范围不大,可以用整型数组来进行统计。在对一个内容进行压缩或者其它转换时,利用 HashMap 可以把原始内容和转换后的内容联系起来。例如在一个简化 url 的系统中 [Leetcdoe : 535. Encode and Decode TinyURL (Medium) + Java 中的 **HashMap** 主要用于映射关系,从而把两个元素联系起来。HashMap 也可以用来对元素进行计数统计,此时键为元素,值为计数。和 HashSet 类似,如果元素有穷并且范围不大,可以用整型数组来进行统计。在对一个内容进行压缩或者其它转换时,利用 HashMap 可以把原始内容和转换后的内容联系起来。例如在一个简化 url 的系统中 [Leetcdoe : 535. Encode and Decode TinyURL (Medium) [Leetcode](https://leetcode.com/problems/encode-and-decode-tinyurl/description/),利用 HashMap 就可以存储精简后的 url 到原始 url 的映射,使得不仅可以显示简化的 url,也可以根据简化的 url 得到原始 url 从而定位到正确的资源�) / [力扣](https://leetcode-cn.com/problems/encode-and-decode-tinyurl/description/),利用 HashMap 就可以存储精简后的 url 到原始 url 的映射,使得不仅可以显示简化的 url,也可以根据简化的 url 得到原始 url 从而定位到正确的资源�) diff --git a/notes/Leetcode 题解 - 排序.md b/notes/Leetcode 题解 - 排序.md index 7fdd6c2a..bdb256d8 100644 --- a/notes/Leetcode 题解 - 排序.md +++ b/notes/Leetcode 题解 - 排序.md @@ -12,13 +12,13 @@ # 快速选择 -用于求解 **Kth Element** 问题,也就是第 K 个元素的问题。 +用于求解 **Kth Element** 问题,也就是第 K 个元素的问题。 可以使用快速排序的 partition() 进行实现。需要先打乱数组,否则最坏情况下时间复杂度为 O(N2)。 # 堆 -用于求解 **TopK Elements** 问题,也就是 K 个最小元素的问题。可以维护一个大小为 K 的最小堆,最小堆中的元素就是最小元素。最小堆需要使用大顶堆来实现,大顶堆表示堆顶元素是堆中最大元素。这是因为我们要得到 k 个最小的元素,因此当遍历到一个新的元素时,需要知道这个新元素是否比堆中最大的元素更小,更小的话就把堆中最大元素去除,并将新元素添加到堆中。所以我们需要很容易得到最大元素并移除最大元素,大顶堆就能很好满足这个要求。 +用于求解 **TopK Elements** 问题,也就是 K 个最小元素的问题。可以维护一个大小为 K 的最小堆,最小堆中的元素就是最小元素。最小堆需要使用大顶堆来实现,大顶堆表示堆顶元素是堆中最大元素。这是因为我们要得到 k 个最小的元素,因此当遍历到一个新的元素时,需要知道这个新元素是否比堆中最大的元素更小,更小的话就把堆中最大元素去除,并将新元素添加到堆中。所以我们需要很容易得到最大元素并移除最大元素,大顶堆就能很好满足这个要求。 堆也可以用于求解 Kth Element 问题,得到了大小为 k 的最小堆之后,因为使用了大顶堆来实现,因此堆顶元素就是第 k 大的元素。 @@ -39,7 +39,7 @@ Output: 5 题目描述:找到倒数第 k 个的元素。 -**排序** :时间复杂度 O(NlogN),空间复杂度 O(1) +**排序** :时间复杂度 O(NlogN),空间复杂度 O(1) ```java public int findKthLargest(int[] nums, int k) { @@ -48,7 +48,7 @@ public int findKthLargest(int[] nums, int k) { } ``` -**堆** :时间复杂度 O(NlogK),空间复杂度 O(K)。 +**堆** :时间复杂度 O(NlogK),空间复杂度 O(K)。 ```java public int findKthLargest(int[] nums, int k) { @@ -62,7 +62,7 @@ public int findKthLargest(int[] nums, int k) { } ``` -**快速选择** :时间复杂度 O(N),空间复杂度 O(1) +**快速选择** :时间复杂度 O(N),空间复杂度 O(1) ```java public int findKthLargest(int[] nums, int k) { diff --git a/notes/Leetcode 题解 - 搜索.md b/notes/Leetcode 题解 - 搜索.md index 73d75074..3c7179b0 100644 --- a/notes/Leetcode 题解 - 搜索.md +++ b/notes/Leetcode 题解 - 搜索.md @@ -52,7 +52,7 @@ - 4 -> {} - 3 -> {} -每一层遍历的节点都与根节点距离相同。设 di 表示第 i 个节点与根节点的距离,推导出一个结论:对于先遍历的节点 i 与后遍历的节点 j,有 di <= dj。利用这个结论,可以求解最短路径等 **最优解** 问题:第一次遍历到目的节点,其所经过的路径为最短路径。应该注意的是,使用 BFS 只能求解无权图的最短路径,无权图是指从一个节点到另一个节点的代价都记为 1。 +每一层遍历的节点都与根节点距离相同。设 di 表示第 i 个节点与根节点的距离,推导出一个结论:对于先遍历的节点 i 与后遍历的节点 j,有 di <= dj。利用这个结论,可以求解最短路径等 **最优解** 问题:第一次遍历到目的节点,其所经过的路径为最短路径。应该注意的是,使用 BFS 只能求解无权图的最短路径,无权图是指从一个节点到另一个节点的代价都记为 1。 在程序实现 BFS 时需要考虑以下问题: @@ -275,7 +275,7 @@ private int getShortestPath(List[] graphic, int start, int end) { 而深度优先搜索在得到一个新节点时立即对新节点进行遍历:从节点 0 出发开始遍历,得到到新节点 6 时,立马对新节点 6 进行遍历,得到新节点 4;如此反复以这种方式遍历新节点,直到没有新节点了,此时返回。返回到根节点 0 的情况是,继续对根节点 0 进行遍历,得到新节点 2,然后继续以上步骤。 -从一个节点出发,使用 DFS 对一个图进行遍历时,能够遍历到的节点都是从初始节点可达的,DFS 常用来求解这种 **可达性** 问题。 +从一个节点出发,使用 DFS 对一个图进行遍历时,能够遍历到的节点都是从初始节点可达的,DFS 常用来求解这种 **可达性** 问题。 在程序实现 DFS 时需要考虑以下问题: @@ -577,8 +577,8 @@ private void dfs(int r, int c, boolean[][] canReach) { Backtracking(回溯)属于 DFS。 -- 普通 DFS 主要用在 **可达性问题** ,这种问题只需要执行到特点的位置然后返回即可。 -- 而 Backtracking 主要用于求解 **排列组合** 问题,例如有 { 'a','b','c' } 三个字符,求解所有由这三个字符排列得到的字符串,这种问题在执行到特定的位置返回之后还会继续执行求解过程。 +- 普通 DFS 主要用在 **可达性问题** ,这种问题只需要执行到特点的位置然后返回即可。 +- 而 Backtracking 主要用于求解 **排列组合** 问题,例如有 { 'a','b','c' } 三个字符,求解所有由这三个字符排列得到的字符串,这种问题在执行到特定的位置返回之后还会继续执行求解过程。 因为 Backtracking 不是立即返回,而要继续求解,因此在程序实现时,需要注意对元素的标记问题: diff --git a/notes/Leetcode 题解 - 数学.md b/notes/Leetcode 题解 - 数学.md index 00524e9c..7845a636 100644 --- a/notes/Leetcode 题解 - 数学.md +++ b/notes/Leetcode 题解 - 数学.md @@ -321,7 +321,7 @@ Only two moves are needed (remember each move increments or decrements one eleme 设数组长度为 N,则可以找到 N/2 对 a 和 b 的组合,使它们都移动到 m 的位置。 -**解法 1** +**解法 1** 先排序,时间复杂度:O(NlogN) @@ -339,7 +339,7 @@ public int minMoves2(int[] nums) { } ``` -**解法 2** +**解法 2** 使用快速选择找到中位数,时间复杂度 O(N) diff --git a/notes/Leetcode 题解 - 目录.md b/notes/Leetcode 题解 - 目录.md index 2458e510..1e38c714 100644 --- a/notes/Leetcode 题解 - 目录.md +++ b/notes/Leetcode 题解 - 目录.md @@ -1,5 +1,3 @@ - - 本文从 Leetcode 中精选大概 200 左右的题目,去除了某些繁杂但是没有多少算法思想的题目,同时保留了面试中经常被问到的经典题目。 # 算法思想 diff --git a/notes/Leetcode 题解 - 目录1.md b/notes/Leetcode 题解 - 目录1.md index 40c1cee2..9df8bab3 100644 --- a/notes/Leetcode 题解 - 目录1.md +++ b/notes/Leetcode 题解 - 目录1.md @@ -1,5 +1,3 @@ - - 本文从 Leetcode 中精选大概 200 左右的题目,去除了某些繁杂但是没有多少算法思想的题目,同时保留了面试中经常被问到的经典题目。 # 算法思想 diff --git a/notes/Leetcode 题解 - 贪心思想.md b/notes/Leetcode 题解 - 贪心思想.md index eb6844c2..e7a11cb5 100644 --- a/notes/Leetcode 题解 - 贪心思想.md +++ b/notes/Leetcode 题解 - 贪心思想.md @@ -301,7 +301,7 @@ Explanation: You could modify the first 4 to 1 to get a non-decreasing array. 题目描述:判断一个数组是否能只修改一个数就成为非递减数组。 -在出现 nums[i] < nums[i - 1] 时,需要考虑的是应该修改数组的哪个数,使得本次修改能使 i 之前的数组成为非递减数组,并且 **不影响后续的操作** 。优先考虑令 nums[i - 1] = nums[i],因为如果修改 nums[i] = nums[i - 1] 的话,那么 nums[i] 这个数会变大,就有可能比 nums[i + 1] 大,从而影响了后续操作。还有一个比较特别的情况就是 nums[i] < nums[i - 2],修改 nums[i - 1] = nums[i] 不能使数组成为非递减数组,只能修改 nums[i] = nums[i - 1]。 +在出现 nums[i] < nums[i - 1] 时,需要考虑的是应该修改数组的哪个数,使得本次修改能使 i 之前的数组成为非递减数组,并且 **不影响后续的操作** 。优先考虑令 nums[i - 1] = nums[i],因为如果修改 nums[i] = nums[i - 1] 的话,那么 nums[i] 这个数会变大,就有可能比 nums[i + 1] 大,从而影响了后续操作。还有一个比较特别的情况就是 nums[i] < nums[i - 2],修改 nums[i - 1] = nums[i] 不能使数组成为非递减数组,只能修改 nums[i] = nums[i - 1]。 ```java public boolean checkPossibility(int[] nums) { diff --git a/notes/Leetcode 题解.md b/notes/Leetcode 题解.md index a29a0f11..099ae848 100644 --- a/notes/Leetcode 题解.md +++ b/notes/Leetcode 题解.md @@ -1,7 +1,3 @@ - - - - [Leetcode 题解](https://github.com/CyC2018/CS-Notes/blob/master/notes/Leetcode%20%E9%A2%98%E8%A7%A3%20-%20%E7%9B%AE%E5%BD%95.md) diff --git a/notes/Linux.md b/notes/Linux.md index 5bb4b258..2dc28c80 100644 --- a/notes/Linux.md +++ b/notes/Linux.md @@ -641,7 +641,7 @@ locate 使用 /var/lib/mlocate/ 这个数据库来进行搜索,它存储在内 example: find . -name "shadow*" ``` -**① 与时间有关的选项** +**① 与时间有关的选项** ```html -mtime n :列出在 n 天前的那一天修改过内容的文件 @@ -654,7 +654,7 @@ example: find . -name "shadow*"

-**② 与文件拥有者和所属群组有关的选项** +**② 与文件拥有者和所属群组有关的选项** ```html -uid n @@ -665,7 +665,7 @@ example: find . -name "shadow*" -nogroup:搜索所属群组不存在于 /etc/group 的文件 ``` -**③ 与文件权限和名称有关的选项** +**③ 与文件权限和名称有关的选项** ```html -name filename @@ -892,7 +892,7 @@ $ export | cut -c 12- ## 排序指令 -**sort** 用于排序。 +**sort** 用于排序。 ```html $ sort [-fbMnrtuk] [file or stdin] @@ -916,7 +916,7 @@ alex:x:1001:1002::/home/alex:/bin/bash arod:x:1002:1003::/home/arod:/bin/bash ``` -**uniq** 可以将重复的数据只取一个。 +**uniq** 可以将重复的数据只取一个。 ```html $ uniq [-ic] @@ -938,7 +938,7 @@ $ last | cut -d ' ' -f 1 | sort | uniq -c ## 双向输出重定向 -输出重定向会将输出内容重定向到文件中,而 **tee** 不仅能够完成这个功能,还能保留屏幕上的输出。也就是说,使用 tee 指令,一个输出会同时传送到文件和屏幕上。 +输出重定向会将输出内容重定向到文件中,而 **tee** 不仅能够完成这个功能,还能保留屏幕上的输出。也就是说,使用 tee 指令,一个输出会同时传送到文件和屏幕上。 ```html $ tee [-a] file @@ -946,7 +946,7 @@ $ tee [-a] file ## 字符转换指令 -**tr** 用来删除一行中的字符,或者对字符进行替换。 +**tr** 用来删除一行中的字符,或者对字符进行替换。 ```html $ tr [-ds] SET1 ... @@ -959,21 +959,21 @@ $ tr [-ds] SET1 ... $ last | tr '[a-z]' '[A-Z]' ``` - **col** 将 tab 字符转为空格字符。 + **col** 将 tab 字符转为空格字符。 ```html $ col [-xb] -x : 将 tab 键转换成对等的空格键 ``` -**expand** 将 tab 转换一定数量的空格,默认是 8 个。 +**expand** 将 tab 转换一定数量的空格,默认是 8 个。 ```html $ expand [-t] file -t :tab 转为空格的数量 ``` -**join** 将有相同数据的那一行合并在一起。 +**join** 将有相同数据的那一行合并在一起。 ```html $ join [-ti12] file1 file2 @@ -983,7 +983,7 @@ $ join [-ti12] file1 file2 -2 :第二个文件所用的比较字段 ``` -**paste** 直接将两行粘贴在一起。 +**paste** 直接将两行粘贴在一起。 ```html $ paste [-d] file1 file2 @@ -992,7 +992,7 @@ $ paste [-d] file1 file2 ## 分区指令 -**split** 将一个文件划分成多个文件。 +**split** 将一个文件划分成多个文件。 ```html $ split [-bl] file PREFIX diff --git a/notes/MySQL.md b/notes/MySQL.md index 649c17a6..1af77024 100644 --- a/notes/MySQL.md +++ b/notes/MySQL.md @@ -388,9 +388,9 @@ MySQL 提供了 FROM_UNIXTIME() 函数把 UNIX 时间戳转换为日期,并提 主要涉及三个线程:binlog 线程、I/O 线程和 SQL 线程。 -- **binlog 线程** :负责将主服务器上的数据更改写入二进制日志(Binary log)中。 -- **I/O 线程** :负责从主服务器上读取二进制日志,并写入从服务器的中继日志(Relay log)。 -- **SQL 线程** :负责读取中继日志,解析出主服务器已经执行的数据更改并在从服务器中重放(Replay)。 +- **binlog 线程** :负责将主服务器上的数据更改写入二进制日志(Binary log)中。 +- **I/O 线程** :负责从主服务器上读取二进制日志,并写入从服务器的中继日志(Relay log)。 +- **SQL 线程** :负责读取中继日志,解析出主服务器已经执行的数据更改并在从服务器中重放(Replay)。

diff --git a/notes/SQL.md b/notes/SQL.md index 067d975b..42b25c50 100644 --- a/notes/SQL.md +++ b/notes/SQL.md @@ -130,7 +130,7 @@ DELETE FROM mytable WHERE id = 1; ``` -**TRUNCATE TABLE** 可以清空表,也就是删除所有行。 +**TRUNCATE TABLE** 可以清空表,也就是删除所有行。 ```sql TRUNCATE TABLE mytable; @@ -177,8 +177,8 @@ LIMIT 2, 3; # 八、排序 -- **ASC** :升序(默认) -- **DESC** :降序 +- **ASC** :升序(默认) +- **DESC** :降序 可以按多个列进行排序,并且为每个列指定不同的排序方式: @@ -213,21 +213,21 @@ WHERE col IS NULL; 应该注意到,NULL 与 0、空字符串都不同。 -**AND 和 OR** 用于连接多个过滤条件。优先处理 AND,当一个过滤表达式涉及到多个 AND 和 OR 时,可以使用 () 来决定优先级,使得优先级关系更清晰。 +**AND 和 OR** 用于连接多个过滤条件。优先处理 AND,当一个过滤表达式涉及到多个 AND 和 OR 时,可以使用 () 来决定优先级,使得优先级关系更清晰。 -**IN** 操作符用于匹配一组值,其后也可以接一个 SELECT 子句,从而匹配子查询得到的一组值。 +**IN** 操作符用于匹配一组值,其后也可以接一个 SELECT 子句,从而匹配子查询得到的一组值。 -**NOT** 操作符用于否定一个条件。 +**NOT** 操作符用于否定一个条件。 # 十、通配符 通配符也是用在过滤语句中,但它只能用于文本字段。 -- **%** 匹配 >=0 个任意字符; +- **%** 匹配 >=0 个任意字符; -- **\_** 匹配 ==1 个任意字符; +- **\_** 匹配 ==1 个任意字符; -- **[ ]** 可以匹配集合内的字符,例如 [ab] 将匹配字符 a 或者 b。用脱字符 ^ 可以对其进行否定,也就是不匹配集合内的字符。 +- **[ ]** 可以匹配集合内的字符,例如 [ab] 将匹配字符 a 或者 b。用脱字符 ^ 可以对其进行否定,也就是不匹配集合内的字符。 使用 Like 来进行通配符匹配。 @@ -243,14 +243,14 @@ WHERE col LIKE '[^AB]%'; -- 不以 A 和 B 开头的任意文本 在数据库服务器上完成数据的转换和格式化的工作往往比客户端上快得多,并且转换和格式化后的数据量更少的话可以减少网络通信量。 -计算字段通常需要使用 **AS** 来取别名,否则输出的时候字段名为计算表达式。 +计算字段通常需要使用 **AS** 来取别名,否则输出的时候字段名为计算表达式。 ```sql SELECT col1 * col2 AS alias FROM mytable; ``` -**CONCAT()** 用于连接两个字段。许多数据库会使用空格把一个值填充为列宽,因此连接的结果会出现一些不必要的空格,使用 **TRIM()** 可以去除首尾空格。 +**CONCAT()** 用于连接两个字段。许多数据库会使用空格把一个值填充为列宽,因此连接的结果会出现一些不必要的空格,使用 **TRIM()** 可以去除首尾空格。 ```sql SELECT CONCAT(TRIM(col1), '(', TRIM(col2), ')') AS concat_col @@ -293,7 +293,7 @@ FROM mytable; | LENGTH() | 长度 | | SOUNDEX() | 转换为语音值 | -其中, **SOUNDEX()** 可以将一个字符串转换为描述其语音表示的字母数字模式。 +其中, **SOUNDEX()** 可以将一个字符串转换为描述其语音表示的字母数字模式。 ```sql SELECT * @@ -517,7 +517,7 @@ orders 表: # 十六、组合查询 -使用 **UNION** 来组合两个查询,如果第一个查询返回 M 行,第二个查询返回 N 行,那么组合查询的结果一般为 M+N 行。 +使用 **UNION** 来组合两个查询,如果第一个查询返回 M 行,第二个查询返回 N 行,那么组合查询的结果一般为 M+N 行。 每个查询必须包含相同的列、表达式和聚集函数。 @@ -710,7 +710,7 @@ USE mysql; SELECT user FROM user; ``` -**创建账户** +**创建账户** 新创建的账户没有任何权限。 @@ -718,25 +718,25 @@ SELECT user FROM user; CREATE USER myuser IDENTIFIED BY 'mypassword'; ``` -**修改账户名** +**修改账户名** ```sql RENAME USER myuser TO newuser; ``` -**删除账户** +**删除账户** ```sql DROP USER myuser; ``` -**查看权限** +**查看权限** ```sql SHOW GRANTS FOR myuser; ``` -**授予权限** +**授予权限** 账户用 username@host 的形式定义,username@% 使用的是默认主机名。 @@ -744,7 +744,7 @@ SHOW GRANTS FOR myuser; GRANT SELECT, INSERT ON mydatabase.* TO myuser; ``` -**删除权限** +**删除权限** GRANT 和 REVOKE 可在几个层次上控制访问权限: @@ -758,7 +758,7 @@ GRANT 和 REVOKE 可在几个层次上控制访问权限: REVOKE SELECT, INSERT ON mydatabase.* FROM myuser; ``` -**更改密码** +**更改密码** 必须使用 Password() 函数进行加密。 diff --git a/notes/pics/image-20191102011523992.png b/notes/pics/image-20191102011523992.png new file mode 100644 index 00000000..7a41f199 Binary files /dev/null and b/notes/pics/image-20191102011523992.png differ diff --git a/notes/pics/image-20191102011531465.png b/notes/pics/image-20191102011531465.png new file mode 100644 index 00000000..5091e0d6 Binary files /dev/null and b/notes/pics/image-20191102011531465.png differ diff --git a/notes/代码可读性.md b/notes/代码可读性.md index 6d5e2ff4..2107be44 100644 --- a/notes/代码可读性.md +++ b/notes/代码可读性.md @@ -160,7 +160,7 @@ if (!(a || b)) { # 九、变量与可读性 -**去除控制流变量** 。在循环中通过使用 break 或者 return 可以减少控制流变量的使用。 +**去除控制流变量** 。在循环中通过使用 break 或者 return 可以减少控制流变量的使用。 ```java boolean done = false; @@ -182,7 +182,7 @@ while(/* condition */) { } ``` -**减小变量作用域** 。作用域越小,越容易定位到变量所有使用的地方。 +**减小变量作用域** 。作用域越小,越容易定位到变量所有使用的地方。 JavaScript 可以用闭包减小作用域。以下代码中 submit_form 是函数变量,submitted 变量控制函数不会被提交两次。第一个实现中 submitted 是全局变量,第二个实现把 submitted 放到匿名函数中,从而限制了起作用域范围。 @@ -212,7 +212,7 @@ JavaScript 中没有用 var 声明的变量都是全局变量,而全局变量 变量定义的位置应当离它使用的位置最近。 -**实例解析** +**实例解析** 在一个网页中有以下文本输入字段: diff --git a/notes/代码风格规范.md b/notes/代码风格规范.md index a2e6ea80..eb9f7d44 100644 --- a/notes/代码风格规范.md +++ b/notes/代码风格规范.md @@ -1,7 +1,3 @@ - - - - - [Twitter Java Style Guide](https://github.com/twitter/commons/blob/master/src/java/com/twitter/common/styleguide.md) - [Google Java Style Guide](http://google.github.io/styleguide/javaguide.html) - [阿里巴巴Java开发手册](https://github.com/alibaba/p3c) diff --git a/notes/剑指 Offer 题解 - 40~49.md b/notes/剑指 Offer 题解 - 40~49.md index 8bf7eaba..d2f5df09 100644 --- a/notes/剑指 Offer 题解 - 40~49.md +++ b/notes/剑指 Offer 题解 - 40~49.md @@ -1,18 +1,3 @@ - -* [40. 最小的 K 个数](#40-最小的-k-个数) -* [41.1 数据流中的中位数](#411-数据流中的中位数) -* [41.2 字符流中第一个不重复的字符](#412-字符流中第一个不重复的字符) -* [42. 连续子数组的最大和](#42-连续子数组的最大和) -* [43. 从 1 到 n 整数中 1 出现的次数](#43-从-1-到-n-整数中-1-出现的次数) -* [44. 数字序列中的某一位数字](#44-数字序列中的某一位数字) -* [45. 把数组排成最小的数](#45-把数组排成最小的数) -* [46. 把数字翻译成字符串](#46-把数字翻译成字符串) -* [47. 礼物的最大价值](#47-礼物的最大价值) -* [48. 最长不含重复字符的子字符串](#48-最长不含重复字符的子字符串) -* [49. 丑数](#49-丑数) - - - # 40. 最小的 K 个数 [NowCoder](https://www.nowcoder.com/practice/6a296eb82cf844ca8539b57c23e6e9bf?tpId=13&tqId=11182&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) diff --git a/notes/剑指 Offer 题解 - 目录.md b/notes/剑指 Offer 题解 - 目录.md index b4492ec2..40c1aacc 100644 --- a/notes/剑指 Offer 题解 - 目录.md +++ b/notes/剑指 Offer 题解 - 目录.md @@ -1,14 +1,82 @@ - - # 目录 -- [3\~9](剑指%20Offer%20题解%20-%203\~9.md) -- [10\~19](剑指%20Offer%20题解%20-%2010\~19.md) -- [20\~29](剑指%20Offer%20题解%20-%2020\~29.md) -- [30\~39](剑指%20Offer%20题解%20-%2030\~39.md) -- [40\~49](剑指%20Offer%20题解%20-%2040\~49.md) -- [50\~59](剑指%20Offer%20题解%20-%2050\~59.md) -- [60\~68](剑指%20Offer%20题解%20-%2060\~68.md) + +- [3. 数组中重复的数字.md](3.%20数组中重复的数字.md) +- [4. 二维数组中的查找.md](4.%20二维数组中的查找.md) +- [5. 替换空格.md](5.%20替换空格.md) +- [6. 从尾到头打印链表.md](6.%20从尾到头打印链表.md) +- [7. 重建二叉树.md](7.%20重建二叉树.md) +- [8. 二叉树的下一个结点.md](8.%20二叉树的下一个结点.md) +- [9. 用两个栈实现队列.md](9.%20用两个栈实现队列.md) +- [10.1 斐波那契数列.md](10.1%20斐波那契数列.md) +- [10.2 矩形覆盖.md](10.2%20矩形覆盖.md) +- [10.3 跳台阶.md](10.3%20跳台阶.md) +- [10.4 变态跳台阶.md](10.4%20变态跳台阶.md) +- [11. 旋转数组的最小数字.md](11.%20旋转数组的最小数字.md) +- [12. 矩阵中的路径.md](12.%20矩阵中的路径.md) +- [13. 机器人的运动范围.md](13.%20机器人的运动范围.md) +- [14. 剪绳子.md](14.%20剪绳子.md) +- [15. 二进制中 1 的个数.md](15.%20二进制中%201%20的个数.md) +- [16. 数值的整数次方.md](16.%20数值的整数次方.md) +- [17. 打印从 1 到最大的 n 位数.md](17.%20打印从%201%20到最大的%20n%20位数.md) +- [18.1 在 O(1) 时间内删除链表节点.md](18.1%20在%20O(1)%20时间内删除链表节点.md) +- [18.2 删除链表中重复的结点.md](18.2%20删除链表中重复的结点.md) +- [19. 正则表达式匹配.md](19.%20正则表达式匹配.md) +- [20. 表示数值的字符串.md](20.%20表示数值的字符串.md) +- [21. 调整数组顺序使奇数位于偶数前面.md](21.%20调整数组顺序使奇数位于偶数前面.md) +- [22. 链表中倒数第 K 个结点.md](22.%20链表中倒数第%20K%20个结点.md) +- [23. 链表中环的入口结点.md](23.%20链表中环的入口结点.md) +- [24. 反转链表.md](24.%20反转链表.md) +- [25. 合并两个排序的链表.md](25.%20合并两个排序的链表.md) +- [26. 树的子结构.md](26.%20树的子结构.md) +- [27. 二叉树的镜像.md](27.%20二叉树的镜像.md) +- [28. 对称的二叉树.md](28.%20对称的二叉树.md) +- [29. 顺时针打印矩阵.md](29.%20顺时针打印矩阵.md) +- [30. 包含 min 函数的栈.md](30.%20包含%20min%20函数的栈.md) +- [31. 栈的压入、弹出序列.md](31.%20栈的压入、弹出序列.md) +- [32.1 从上往下打印二叉树.md](32.1%20从上往下打印二叉树.md) +- [32.2 把二叉树打印成多行.md](32.2%20把二叉树打印成多行.md) +- [32.3 按之字形顺序打印二叉树.md](32.3%20按之字形顺序打印二叉树.md) +- [33. 二叉搜索树的后序遍历序列.md](33.%20二叉搜索树的后序遍历序列.md) +- [34. 二叉树中和为某一值的路径.md](34.%20二叉树中和为某一值的路径.md) +- [35. 复杂链表的复制.md](35.%20复杂链表的复制.md) +- [36. 二叉搜索树与双向链表.md](36.%20二叉搜索树与双向链表.md) +- [37. 序列化二叉树.md](37.%20序列化二叉树.md) +- [38. 字符串的排列.md](38.%20字符串的排列.md) +- [39. 数组中出现次数超过一半的数字.md](39.%20数组中出现次数超过一半的数字.md) +- [40. 最小的 K 个数.md](40.%20最小的%20K%20个数.md) +- [41.1 数据流中的中位数.md](41.1%20数据流中的中位数.md) +- [41.2 字符流中第一个不重复的字符.md](41.2%20字符流中第一个不重复的字符.md) +- [42. 连续子数组的最大和.md](42.%20连续子数组的最大和.md) +- [43. 从 1 到 n 整数中 1 出现的次数.md](43.%20从%201%20到%20n%20整数中%201%20出现的次数.md) +- [44. 数字序列中的某一位数字.md](44.%20数字序列中的某一位数字.md) +- [45. 把数组排成最小的数.md](45.%20把数组排成最小的数.md) +- [46. 把数字翻译成字符串.md](46.%20把数字翻译成字符串.md) +- [47. 礼物的最大价值.md](47.%20礼物的最大价值.md) +- [48. 最长不含重复字符的子字符串.md](48.%20最长不含重复字符的子字符串.md) +- [49. 丑数.md](49.%20丑数.md) +- [50. 第一个只出现一次的字符位置.md](50.%20第一个只出现一次的字符位置.md) +- [51. 数组中的逆序对.md](51.%20数组中的逆序对.md) +- [52. 两个链表的第一个公共结点.md](52.%20两个链表的第一个公共结点.md) +- [53. 数字在排序数组中出现的次数.md](53.%20数字在排序数组中出现的次数.md) +- [54. 二叉查找树的第 K 个结点.md](54.%20二叉查找树的第%20K%20个结点.md) +- [55.1 二叉树的深度.md](55.1%20二叉树的深度.md) +- [55.2 平衡二叉树.md](55.2%20平衡二叉树.md) +- [56. 数组中只出现一次的数字.md](56.%20数组中只出现一次的数字.md) +- [57.1 和为 S 的两个数字.md](57.1%20和为%20S%20的两个数字.md) +- [57.2 和为 S 的连续正数序列.md](57.2%20和为%20S%20的连续正数序列.md) +- [58.1 翻转单词顺序列.md](58.1%20翻转单词顺序列.md) +- [58.2 左旋转字符串.md](58.2%20左旋转字符串.md) +- [59. 滑动窗口的最大值.md](59.%20滑动窗口的最大值.md) +- [60. n 个骰子的点数.md](60.%20n%20个骰子的点数.md) +- [61. 扑克牌顺子.md](61.%20扑克牌顺子.md) +- [62. 圆圈中最后剩下的数.md](62.%20圆圈中最后剩下的数.md) +- [63. 股票的最大利润.md](63.%20股票的最大利润.md) +- [64. 求 1+2+3+...+n.md](64.%20求%201+2+3+...+n.md) +- [65. 不用加减乘除做加法.md](65.%20不用加减乘除做加法.md) +- [66. 构建乘积数组.md](66.%20构建乘积数组.md) +- [67. 把字符串转换成整数.md](67.%20把字符串转换成整数.md) +- [68. 树中两个节点的最低公共祖先.md](68.%20树中两个节点的最低公共祖先.md) # 参考文献 diff --git a/notes/剑指 Offer 题解 - 目录1.md b/notes/剑指 Offer 题解 - 目录1.md index 25dbddd6..cdd614a7 100644 --- a/notes/剑指 Offer 题解 - 目录1.md +++ b/notes/剑指 Offer 题解 - 目录1.md @@ -1,14 +1,82 @@ - - # 目录 -- [3\~9](notes/剑指%20Offer%20题解%20-%203\~9.md) -- [10\~19](notes/剑指%20Offer%20题解%20-%2010\~19.md) -- [20\~29](notes/剑指%20Offer%20题解%20-%2020\~29.md) -- [30\~39](notes/剑指%20Offer%20题解%20-%2030\~39.md) -- [40\~49](notes/剑指%20Offer%20题解%20-%2040\~49.md) -- [50\~59](notes/剑指%20Offer%20题解%20-%2050\~59.md) -- [60\~68](notes/剑指%20Offer%20题解%20-%2060\~68.md) +- [3. 数组中重复的数字.md](notes/3.%20数组中重复的数字.md) +- [4. 二维数组中的查找.md](notes/4.%20二维数组中的查找.md) +- [5. 替换空格.md](notes/5.%20替换空格.md) +- [6. 从尾到头打印链表.md](notes/6.%20从尾到头打印链表.md) +- [7. 重建二叉树.md](notes/7.%20重建二叉树.md) +- [8. 二叉树的下一个结点.md](notes/8.%20二叉树的下一个结点.md) +- [9. 用两个栈实现队列.md](notes/9.%20用两个栈实现队列.md) +- [10.1 斐波那契数列.md](notes/10.1%20斐波那契数列.md) +- [10.2 矩形覆盖.md](notes/10.2%20矩形覆盖.md) +- [10.3 跳台阶.md](notes/10.3%20跳台阶.md) +- [10.4 变态跳台阶.md](notes/10.4%20变态跳台阶.md) +- [11. 旋转数组的最小数字.md](notes/11.%20旋转数组的最小数字.md) +- [12. 矩阵中的路径.md](notes/12.%20矩阵中的路径.md) +- [13. 机器人的运动范围.md](notes/13.%20机器人的运动范围.md) +- [14. 剪绳子.md](notes/14.%20剪绳子.md) +- [15. 二进制中 1 的个数.md](notes/15.%20二进制中%201%20的个数.md) +- [16. 数值的整数次方.md](notes/16.%20数值的整数次方.md) +- [17. 打印从 1 到最大的 n 位数.md](notes/17.%20打印从%201%20到最大的%20n%20位数.md) +- [18.1 在 O(1) 时间内删除链表节点.md](notes/18.1%20在%20O(1)%20时间内删除链表节点.md) +- [18.2 删除链表中重复的结点.md](notes/18.2%20删除链表中重复的结点.md) +- [19. 正则表达式匹配.md](notes/19.%20正则表达式匹配.md) +- [20. 表示数值的字符串.md](notes/20.%20表示数值的字符串.md) +- [21. 调整数组顺序使奇数位于偶数前面.md](notes/21.%20调整数组顺序使奇数位于偶数前面.md) +- [22. 链表中倒数第 K 个结点.md](notes/22.%20链表中倒数第%20K%20个结点.md) +- [23. 链表中环的入口结点.md](notes/23.%20链表中环的入口结点.md) +- [24. 反转链表.md](notes/24.%20反转链表.md) +- [25. 合并两个排序的链表.md](notes/25.%20合并两个排序的链表.md) +- [26. 树的子结构.md](notes/26.%20树的子结构.md) +- [27. 二叉树的镜像.md](notes/27.%20二叉树的镜像.md) +- [28. 对称的二叉树.md](notes/28.%20对称的二叉树.md) +- [29. 顺时针打印矩阵.md](notes/29.%20顺时针打印矩阵.md) +- [30. 包含 min 函数的栈.md](notes/30.%20包含%20min%20函数的栈.md) +- [31. 栈的压入、弹出序列.md](notes/31.%20栈的压入、弹出序列.md) +- [32.1 从上往下打印二叉树.md](notes/32.1%20从上往下打印二叉树.md) +- [32.2 把二叉树打印成多行.md](notes/32.2%20把二叉树打印成多行.md) +- [32.3 按之字形顺序打印二叉树.md](notes/32.3%20按之字形顺序打印二叉树.md) +- [33. 二叉搜索树的后序遍历序列.md](notes/33.%20二叉搜索树的后序遍历序列.md) +- [34. 二叉树中和为某一值的路径.md](notes/34.%20二叉树中和为某一值的路径.md) +- [35. 复杂链表的复制.md](notes/35.%20复杂链表的复制.md) +- [36. 二叉搜索树与双向链表.md](notes/36.%20二叉搜索树与双向链表.md) +- [37. 序列化二叉树.md](notes/37.%20序列化二叉树.md) +- [38. 字符串的排列.md](notes/38.%20字符串的排列.md) +- [39. 数组中出现次数超过一半的数字.md](notes/39.%20数组中出现次数超过一半的数字.md) +- [40. 最小的 K 个数.md](notes/40.%20最小的%20K%20个数.md) +- [41.1 数据流中的中位数.md](notes/41.1%20数据流中的中位数.md) +- [41.2 字符流中第一个不重复的字符.md](notes/41.2%20字符流中第一个不重复的字符.md) +- [42. 连续子数组的最大和.md](notes/42.%20连续子数组的最大和.md) +- [43. 从 1 到 n 整数中 1 出现的次数.md](notes/43.%20从%201%20到%20n%20整数中%201%20出现的次数.md) +- [44. 数字序列中的某一位数字.md](notes/44.%20数字序列中的某一位数字.md) +- [45. 把数组排成最小的数.md](notes/45.%20把数组排成最小的数.md) +- [46. 把数字翻译成字符串.md](notes/46.%20把数字翻译成字符串.md) +- [47. 礼物的最大价值.md](notes/47.%20礼物的最大价值.md) +- [48. 最长不含重复字符的子字符串.md](notes/48.%20最长不含重复字符的子字符串.md) +- [49. 丑数.md](notes/49.%20丑数.md) +- [50. 第一个只出现一次的字符位置.md](notes/50.%20第一个只出现一次的字符位置.md) +- [51. 数组中的逆序对.md](notes/51.%20数组中的逆序对.md) +- [52. 两个链表的第一个公共结点.md](notes/52.%20两个链表的第一个公共结点.md) +- [53. 数字在排序数组中出现的次数.md](notes/53.%20数字在排序数组中出现的次数.md) +- [54. 二叉查找树的第 K 个结点.md](notes/54.%20二叉查找树的第%20K%20个结点.md) +- [55.1 二叉树的深度.md](notes/55.1%20二叉树的深度.md) +- [55.2 平衡二叉树.md](notes/55.2%20平衡二叉树.md) +- [56. 数组中只出现一次的数字.md](notes/56.%20数组中只出现一次的数字.md) +- [57.1 和为 S 的两个数字.md](notes/57.1%20和为%20S%20的两个数字.md) +- [57.2 和为 S 的连续正数序列.md](notes/57.2%20和为%20S%20的连续正数序列.md) +- [58.1 翻转单词顺序列.md](notes/58.1%20翻转单词顺序列.md) +- [58.2 左旋转字符串.md](notes/58.2%20左旋转字符串.md) +- [59. 滑动窗口的最大值.md](notes/59.%20滑动窗口的最大值.md) +- [60. n 个骰子的点数.md](notes/60.%20n%20个骰子的点数.md) +- [61. 扑克牌顺子.md](notes/61.%20扑克牌顺子.md) +- [62. 圆圈中最后剩下的数.md](notes/62.%20圆圈中最后剩下的数.md) +- [63. 股票的最大利润.md](notes/63.%20股票的最大利润.md) +- [64. 求 1+2+3+...+n.md](notes/64.%20求%201+2+3+...+n.md) +- [65. 不用加减乘除做加法.md](notes/65.%20不用加减乘除做加法.md) +- [66. 构建乘积数组.md](notes/66.%20构建乘积数组.md) +- [67. 把字符串转换成整数.md](notes/67.%20把字符串转换成整数.md) +- [68. 树中两个节点的最低公共祖先.md](notes/68.%20树中两个节点的最低公共祖先.md) + # 参考文献 diff --git a/notes/剑指 offer 题解.md b/notes/剑指 offer 题解.md index d04ad9bc..7ee9a8c6 100644 --- a/notes/剑指 offer 题解.md +++ b/notes/剑指 offer 题解.md @@ -1,7 +1,3 @@ - - - - [剑指 Offer 题解](https://github.com/CyC2018/CS-Notes/blob/master/notes/%E5%89%91%E6%8C%87%20Offer%20%E9%A2%98%E8%A7%A3%20-%20%E7%9B%AE%E5%BD%95.md) diff --git a/notes/数据库系统原理.md b/notes/数据库系统原理.md index 36d5177a..ca64f413 100644 --- a/notes/数据库系统原理.md +++ b/notes/数据库系统原理.md @@ -147,8 +147,8 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。 | - | X | S | | :--: | :--: | :--: | -| **X** |×|×| -| **S** |×|√| +| **X** |×|×| +| **S** |×|√| ### 2. 意向锁 @@ -167,10 +167,10 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。 | - | X | IX | S | IS | | :--: | :--: | :--: | :--: | :--: | -| **X** |× |× |× | ×| -| **IX** |× |√ |× | √| -| **S** |× |× |√ | √| -| **IS** |× |√ |√ | √| +| **X** |× |× |× | ×| +| **IX** |× |√ |× | √| +| **S** |× |× |√ | √| +| **IS** |× |√ |√ | √| 解释如下: @@ -181,7 +181,7 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。 ### 1. 三级封锁协议 -**一级封锁协议** +**一级封锁协议** 事务 T 要修改数据 A 时必须加 X 锁,直到 T 结束才释放锁。 @@ -202,7 +202,7 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。 | | commit | | | unlock-x(A)| -**二级封锁协议** +**二级封锁协议** 在一级的基础上,要求读取数据 A 时必须加 S 锁,读取完马上释放 S 锁。 @@ -223,7 +223,7 @@ MySQL 中提供了两种封锁粒度:行级锁以及表级锁。 | | unlock-s(A)| | | commit | -**三级封锁协议** +**三级封锁协议** 在二级的基础上,要求读取数据 A 时必须加 S 锁,直到事务结束了才能释放 S 锁。 @@ -448,7 +448,7 @@ SELECT c FROM t WHERE c BETWEEN 10 and 20 FOR UPDATE; 可以通过分解来满足。 - **分解前**
+ **分解前**
| Sno | Sname | Sdept | Mname | Cname | Grade | | :---: | :---: | :---: | :---: | :---: |:---:| @@ -467,7 +467,7 @@ Grade 完全函数依赖于键码,它没有任何冗余数据,每个学生 Sname, Sdept 和 Mname 都部分依赖于键码,当一个学生选修了多门课时,这些数据就会出现多次,造成大量冗余数据。 - **分解后**
+ **分解后**
关系-1 diff --git a/notes/正则表达式.md b/notes/正则表达式.md index 7971869b..769e10a8 100644 --- a/notes/正则表达式.md +++ b/notes/正则表达式.md @@ -23,45 +23,45 @@ # 二、匹配单个字符 -**.** 可以用来匹配任何的单个字符,但是在绝大多数实现里面,不能匹配换行符; +**.** 可以用来匹配任何的单个字符,但是在绝大多数实现里面,不能匹配换行符; -**.** 是元字符,表示它有特殊的含义,而不是字符本身的含义。如果需要匹配 . ,那么要用 \ 进行转义,即在 . 前面加上 \ 。 +**.** 是元字符,表示它有特殊的含义,而不是字符本身的含义。如果需要匹配 . ,那么要用 \ 进行转义,即在 . 前面加上 \ 。 正则表达式一般是区分大小写的,但也有些实现不区分。 -**正则表达式** +**正则表达式** ``` C.C2018 ``` -**匹配结果** +**匹配结果** -My name is **CyC2018** . +My name is **CyC2018** . # 三、匹配一组字符 -**[ ]** 定义一个字符集合; +**[ ]** 定义一个字符集合; 0-9、a-z 定义了一个字符区间,区间使用 ASCII 码来确定,字符区间在 [ ] 中使用。 -**-** 只有在 [ ] 之间才是元字符,在 [ ] 之外就是一个普通字符; +**-** 只有在 [ ] 之间才是元字符,在 [ ] 之外就是一个普通字符; -**^** 在 [ ] 中是取非操作。 +**^** 在 [ ] 中是取非操作。 -**应用** +**应用** 匹配以 abc 为开头,并且最后一个字母不为数字的字符串: -**正则表达式** +**正则表达式** ``` abc[^0-9] ``` -**匹配结果** +**匹配结果** -1. **abcd** +1. **abcd** 2. abc1 3. abc2 @@ -109,15 +109,15 @@ abc[^0-9] # 五、重复匹配 -- **\+** 匹配 1 个或者多个字符 -- **\** * 匹配 0 个或者多个字符 -- **?** 匹配 0 个或者 1 个字符 +- **\+** 匹配 1 个或者多个字符 +- **\** * 匹配 0 个或者多个字符 +- **?** 匹配 0 个或者 1 个字符 -**应用** +**应用** 匹配邮箱地址。 -**正则表达式** +**正则表达式** ``` [\w.]+@\w+\.\w+ @@ -125,25 +125,25 @@ abc[^0-9] [\w.] 匹配的是字母数字或者 . ,在其后面加上 + ,表示匹配多次。在字符集合 [ ] 里,. 不是元字符; -**匹配结果** +**匹配结果** -**abc.def@qq.com** +**abc.def@qq.com** -- **{n}** 匹配 n 个字符 -- **{m,n}** 匹配 m\~n 个字符 -- **{m,}** 至少匹配 m 个字符 +- **{n}** 匹配 n 个字符 +- **{m,n}** 匹配 m\~n 个字符 +- **{m,}** 至少匹配 m 个字符 \* 和 + 都是贪婪型元字符,会匹配尽可能多的内容。在后面加 ? 可以转换为懒惰型元字符,例如 \*?、+? 和 {m,n}? 。 -**正则表达式** +**正则表达式** ``` a.+c ``` -**匹配结果** +**匹配结果** -**abcabcabc** +**abcabcabc** 由于 + 是贪婪型的,因此 .+ 会匹配更可能多的内容,所以会把整个 abcabcabc 文本都匹配,而不是只匹配前面的 abc 文本。用懒惰型可以实现匹配前面的。 @@ -151,23 +151,23 @@ a.+c ## 单词边界 -**\b** 可以匹配一个单词的边界,边界是指位于 \w 和 \W 之间的位置;**\B** 匹配一个不是单词边界的位置。 +**\b** 可以匹配一个单词的边界,边界是指位于 \w 和 \W 之间的位置;**\B** 匹配一个不是单词边界的位置。 \b 只匹配位置,不匹配字符,因此 \babc\b 匹配出来的结果为 3 个字符。 ## 字符串边界 -**^** 匹配整个字符串的开头,**$** 匹配结尾。 +**^** 匹配整个字符串的开头,**$** 匹配结尾。 ^ 元字符在字符集合中用作求非,在字符集合外用作匹配字符串的开头。 分行匹配模式(multiline)下,换行被当做字符串的边界。 -**应用** +**应用** 匹配代码中以 // 开始的注释行 -**正则表达式** +**正则表达式** ``` ^\s*\/\/.*$ @@ -175,47 +175,47 @@ a.+c

-**匹配结果** +**匹配结果** 1. public void fun() { -2.      **// 注释 1** +2.      **// 注释 1** 3.      int a = 1; 4.      int b = 2; -5.      **// 注释 2** +5.      **// 注释 2** 6.      int c = a + b; 7. } # 七、使用子表达式 -使用 **( )** 定义一个子表达式。子表达式的内容可以当成一个独立元素,即可以将它看成一个字符,并且使用 * 等元字符。 +使用 **( )** 定义一个子表达式。子表达式的内容可以当成一个独立元素,即可以将它看成一个字符,并且使用 * 等元字符。 子表达式可以嵌套,但是嵌套层次过深会变得很难理解。 -**正则表达式** +**正则表达式** ``` (ab){2,} ``` -**匹配结果** +**匹配结果** -**ababab** +**ababab** -**|** 是或元字符,它把左边和右边所有的部分都看成单独的两个部分,两个部分只要有一个匹配就行。 +**|** 是或元字符,它把左边和右边所有的部分都看成单独的两个部分,两个部分只要有一个匹配就行。 -**正则表达式** +**正则表达式** ``` (19|20)\d{2} ``` -**匹配结果** +**匹配结果** -1. **1900** -2. **2010** +1. **1900** +2. **2010** 3. 1020 -**应用** +**应用** 匹配 IP 地址。 @@ -227,27 +227,27 @@ IP 地址中每部分都是 0-255 的数字,用正则表达式匹配时以下 - 2 开头,第 2 位是 0-4 的三位数 - 25 开头,第 3 位是 0-5 的三位数 -**正则表达式** +**正则表达式** ``` ((25[0-5]|(2[0-4]\d)|(1\d{2})|([1-9]\d)|(\d))\.){3}(25[0-5]|(2[0-4]\d)|(1\d{2})|([1-9]\d)|(\d)) ``` -**匹配结果** +**匹配结果** -1. **192.168.0.1** +1. **192.168.0.1** 2. 00.00.00.00 3. 555.555.555.555 # 八、回溯引用 -回溯引用使用 **\n** 来引用某个子表达式,其中 n 代表的是子表达式的序号,从 1 开始。它和子表达式匹配的内容一致,比如子表达式匹配到 abc,那么回溯引用部分也需要匹配 abc 。 +回溯引用使用 **\n** 来引用某个子表达式,其中 n 代表的是子表达式的序号,从 1 开始。它和子表达式匹配的内容一致,比如子表达式匹配到 abc,那么回溯引用部分也需要匹配 abc 。 -**应用** +**应用** 匹配 HTML 中合法的标题元素。 -**正则表达式** +**正则表达式** \1 将回溯引用子表达式 (h[1-6]) 匹配的内容,也就是说必须和子表达式匹配的内容一致。 @@ -255,31 +255,31 @@ IP 地址中每部分都是 0-255 的数字,用正则表达式匹配时以下 <(h[1-6])>\w*?<\/\1> ``` -**匹配结果** +**匹配结果** -1. **<h1>x</h1>** -2. **<h2>x</h2>** +1. **<h1>x</h1>** +2. **<h2>x</h2>** 3. <h3>x</h1> ## 替换 需要用到两个正则表达式。 -**应用** +**应用** 修改电话号码格式。 -**文本** +**文本** 313-555-1234 -**查找正则表达式** +**查找正则表达式** ``` (\d{3})(-)(\d{3})(-)(\d{4}) ``` -**替换正则表达式** +**替换正则表达式** 在第一个子表达式查找的结果加上 () ,然后加一个空格,在第三个和第五个字表达式查找的结果中间加上 - 进行分隔。 @@ -287,7 +287,7 @@ IP 地址中每部分都是 0-255 的数字,用正则表达式匹配时以下 ($1) $3-$5 ``` -**结果** +**结果** (313) 555-1234 @@ -301,27 +301,27 @@ IP 地址中每部分都是 0-255 的数字,用正则表达式匹配时以下 | \U | 把\U 和\E 之间的字符全部转换为大写 | | \E | 结束\L 或者\U | -**应用** +**应用** 把文本的第二个和第三个字符转换为大写。 -**文本** +**文本** abcd -**查找** +**查找** ``` (\w)(\w{2})(\w) ``` -**替换** +**替换** ``` $1\U$2\E$3 ``` -**结果** +**结果** aBCd @@ -329,21 +329,21 @@ aBCd 前后查找规定了匹配的内容首尾应该匹配的内容,但是又不包含首尾匹配的内容。 -向前查找使用 **?=** 定义,它规定了尾部匹配的内容,这个匹配的内容在 ?= 之后定义。所谓向前查找,就是规定了一个匹配的内容,然后以这个内容为尾部向前面查找需要匹配的内容。向后匹配用 ?<= 定义(注: JavaScript 不支持向后匹配,Java 对其支持也不完善)。 +向前查找使用 **?=** 定义,它规定了尾部匹配的内容,这个匹配的内容在 ?= 之后定义。所谓向前查找,就是规定了一个匹配的内容,然后以这个内容为尾部向前面查找需要匹配的内容。向后匹配用 ?<= 定义(注: JavaScript 不支持向后匹配,Java 对其支持也不完善)。 -**应用** +**应用** 查找出邮件地址 @ 字符前面的部分。 -**正则表达式** +**正则表达式** ``` \w+(?=@) ``` -**结果** +**结果** -**abc** @qq.com +**abc** @qq.com 对向前和向后查找取非,只要把 = 替换成 ! 即可,比如 (?=) 替换成 (?!) 。取非操作使得匹配那些首尾不符合要求的内容。 @@ -353,7 +353,7 @@ aBCd 条件为某个子表达式是否匹配,如果匹配则需要继续匹配条件表达式后面的内容。 -**正则表达式** +**正则表达式** 子表达式 (\\() 匹配一个左括号,其后的 ? 表示匹配 0 个或者 1 个。 ?(1) 为条件,当子表达式 1 匹配时条件成立,需要执行 \) 匹配,也就是匹配右括号。 @@ -361,17 +361,17 @@ aBCd (\()?abc(?(1)\)) ``` -**结果** +**结果** -1. **(abc)** -2. **abc** +1. **(abc)** +2. **abc** 3. (abc ## 前后查找条件 条件为定义的首尾是否匹配,如果匹配,则继续执行后面的匹配。注意,首尾不包含在匹配的内容中。 -**正则表达式** +**正则表达式** ?(?=-) 为前向查找条件,只有在以 - 为前向查找的结尾能匹配 \d{5} ,才继续匹配 -\d{4} 。 @@ -379,11 +379,11 @@ aBCd \d{5}(?(?=-)-\d{4}) ``` -**结果** +**结果** -1. **11111** +1. **11111** 2. 22222- -3. **33333-4444** +3. **33333-4444** # 参考资料 diff --git a/notes/算法 - 其它.md b/notes/算法 - 其它.md index befe3fe0..01e2a4fa 100644 --- a/notes/算法 - 其它.md +++ b/notes/算法 - 其它.md @@ -1,9 +1,3 @@ - -* [汉诺塔](#汉诺塔) -* [哈夫曼编码](#哈夫曼编码) - - - # 汉诺塔

diff --git a/notes/算法 - 排序.md b/notes/算法 - 排序.md index c8e58e9b..a71e8f10 100644 --- a/notes/算法 - 排序.md +++ b/notes/算法 - 排序.md @@ -1,32 +1,3 @@ - -* [约定](#约定) -* [选择排序](#选择排序) -* [冒泡排序](#冒泡排序) -* [插入排序](#插入排序) -* [希尔排序](#希尔排序) -* [归并排序](#归并排序) - * [1. 归并方法](#1-归并方法) - * [2. 自顶向下归并排序](#2-自顶向下归并排序) - * [3. 自底向上归并排序](#3-自底向上归并排序) -* [快速排序](#快速排序) - * [1. 基本算法](#1-基本算法) - * [2. 切分](#2-切分) - * [3. 性能分析](#3-性能分析) - * [4. 算法改进](#4-算法改进) - * [5. 基于切分的快速选择算法](#5-基于切分的快速选择算法) -* [堆排序](#堆排序) - * [1. 堆](#1-堆) - * [2. 上浮和下沉](#2-上浮和下沉) - * [3. 插入元素](#3-插入元素) - * [4. 删除最大元素](#4-删除最大元素) - * [5. 堆排序](#5-堆排序) - * [6. 分析](#6-分析) -* [小结](#小结) - * [1. 排序算法的比较](#1-排序算法的比较) - * [2. Java 的排序算法实现](#2-java-的排序算法实现) - - - # 约定 待排序的元素需要实现 Java 的 Comparable 接口,该接口有 compareTo() 方法,可以用它来判断两个元素的大小关系。 diff --git a/notes/算法 - 目录.md b/notes/算法 - 目录.md index 9605ed05..d0768ba5 100644 --- a/notes/算法 - 目录.md +++ b/notes/算法 - 目录.md @@ -1,5 +1,3 @@ - - # 目录 - [算法分析](算法%20-%20算法分析.md) diff --git a/notes/算法 - 目录1.md b/notes/算法 - 目录1.md index 4d590961..12613393 100644 --- a/notes/算法 - 目录1.md +++ b/notes/算法 - 目录1.md @@ -1,5 +1,3 @@ - - # 目录 - [算法分析](notes/算法%20-%20算法分析.md) diff --git a/notes/算法 - 符号表.md b/notes/算法 - 符号表.md index 6255c3d3..ed22353a 100644 --- a/notes/算法 - 符号表.md +++ b/notes/算法 - 符号表.md @@ -243,11 +243,11 @@ public class BinarySearchOrderedST, Value> implement # 二叉查找树 -**二叉树** 是一个空链接,或者是一个有左右两个链接的节点,每个链接都指向一颗子二叉树。 +**二叉树** 是一个空链接,或者是一个有左右两个链接的节点,每个链接都指向一颗子二叉树。

-**二叉查找树** (BST)是一颗二叉树,并且每个节点的值都大于等于其左子树中的所有节点的值而小于等于右子树的所有节点的值。 +**二叉查找树** (BST)是一颗二叉树,并且每个节点的值都大于等于其左子树中的所有节点的值而小于等于右子树的所有节点的值。 BST 有一个重要性质,就是它的中序遍历结果递增排序。 diff --git a/notes/算法.md b/notes/算法.md index 72023263..2597009f 100644 --- a/notes/算法.md +++ b/notes/算法.md @@ -1,7 +1,3 @@ - - - - [算法](https://github.com/CyC2018/CS-Notes/blob/master/notes/%E7%AE%97%E6%B3%95%20-%20%E7%9B%AE%E5%BD%95.md) diff --git a/notes/计算机操作系统 - 内存管理.md b/notes/计算机操作系统 - 内存管理.md index bb7eee32..d4599d4e 100644 --- a/notes/计算机操作系统 - 内存管理.md +++ b/notes/计算机操作系统 - 内存管理.md @@ -73,7 +73,6 @@ ```

- ## 3. 最近未使用 > NRU, Not Recently Used diff --git a/notes/计算机操作系统 - 目录.md b/notes/计算机操作系统 - 目录.md index 57f42022..db5f29d7 100644 --- a/notes/计算机操作系统 - 目录.md +++ b/notes/计算机操作系统 - 目录.md @@ -1,5 +1,3 @@ - - # 目录 - [概述](计算机操作系统%20-%20概述.md) diff --git a/notes/计算机操作系统 - 目录1.md b/notes/计算机操作系统 - 目录1.md index 492b4d63..616f34e0 100644 --- a/notes/计算机操作系统 - 目录1.md +++ b/notes/计算机操作系统 - 目录1.md @@ -1,5 +1,3 @@ - - # 目录 - [概述](notes/计算机操作系统%20-%20概述.md) diff --git a/notes/计算机操作系统 - 进程管理.md b/notes/计算机操作系统 - 进程管理.md index 692f22d8..32fdee61 100644 --- a/notes/计算机操作系统 - 进程管理.md +++ b/notes/计算机操作系统 - 进程管理.md @@ -87,19 +87,19 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H 批处理系统没有太多的用户操作,在该系统中,调度算法目标是保证吞吐量和周转时间(从提交到终止的时间)。 -**1.1 先来先服务 first-come first-serverd(FCFS)** +**1.1 先来先服务 first-come first-serverd(FCFS)** 非抢占式的调度算法,按照请求的顺序进行调度。 有利于长作业,但不利于短作业,因为短作业必须一直等待前面的长作业执行完毕才能执行,而长作业又需要执行很长时间,造成了短作业等待时间过长。 -**1.2 短作业优先 shortest job first(SJF)** +**1.2 短作业优先 shortest job first(SJF)** 非抢占式的调度算法,按估计运行时间最短的顺序进行调度。 长作业有可能会饿死,处于一直等待短作业执行完毕的状态。因为如果一直有短作业到来,那么长作业永远得不到调度。 -**1.3 最短剩余时间优先 shortest remaining time next(SRTN)** +**1.3 最短剩余时间优先 shortest remaining time next(SRTN)** 最短作业优先的抢占式版本,按剩余运行时间的顺序进行调度。 当一个新的作业到达时,其整个运行时间与当前进程的剩余时间作比较。如果新的进程需要的时间更少,则挂起当前进程,运行新的进程。否则新的进程等待。 @@ -107,7 +107,7 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H 交互式系统有大量的用户交互操作,在该系统中调度算法的目标是快速地进行响应。 -**2.1 时间片轮转** +**2.1 时间片轮转** 将所有就绪进程按 FCFS 的原则排成一个队列,每次调度时,把 CPU 时间分配给队首进程,该进程可以执行一个时间片。当时间片用完时,由计时器发出时钟中断,调度程序便停止该进程的执行,并将它送往就绪队列的末尾,同时继续把 CPU 时间分配给队首的进程。 @@ -118,13 +118,13 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H

-**2.2 优先级调度** +**2.2 优先级调度** 为每个进程分配一个优先级,按优先级进行调度。 为了防止低优先级的进程永远等不到调度,可以随着时间的推移增加等待进程的优先级。 -**2.3 多级反馈队列** +**2.3 多级反馈队列** 一个进程需要执行 100 个时间片,如果采用时间片轮转调度算法,那么需要交换 100 次。 @@ -165,12 +165,12 @@ QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 H 信号量(Semaphore)是一个整型变量,可以对其执行 down 和 up 操作,也就是常见的 P 和 V 操作。 -- **down** : 如果信号量大于 0 ,执行 -1 操作;如果信号量等于 0,进程睡眠,等待信号量大于 0; -- **up** :对信号量执行 +1 操作,唤醒睡眠的进程让其完成 down 操作。 +- **down** : 如果信号量大于 0 ,执行 -1 操作;如果信号量等于 0,进程睡眠,等待信号量大于 0; +- **up** :对信号量执行 +1 操作,唤醒睡眠的进程让其完成 down 操作。 down 和 up 操作需要被设计成原语,不可分割,通常的做法是在执行这些操作的时候屏蔽中断。 -如果信号量的取值只能为 0 或者 1,那么就成为了 **互斥量(Mutex)** ,0 表示临界区已经加锁,1 表示临界区解锁。 +如果信号量的取值只能为 0 或者 1,那么就成为了 **互斥量(Mutex)** ,0 表示临界区已经加锁,1 表示临界区解锁。 ```c typedef int semaphore; @@ -188,7 +188,7 @@ void P2() { } ``` - **使用信号量实现生产者-消费者问题**
+ **使用信号量实现生产者-消费者问题**
问题描述:使用一个缓冲区来保存物品,只有缓冲区没有满,生产者才可以放入物品;只有缓冲区不为空,消费者才可以拿走物品。 @@ -253,9 +253,9 @@ end monitor; 管程有一个重要特性:在一个时刻只能有一个进程使用管程。进程在无法继续执行的时候不能一直占用管程,否则其它进程永远不能使用管程。 -管程引入了 **条件变量** 以及相关的操作:**wait()** 和 **signal()** 来实现同步操作。对条件变量执行 wait() 操作会导致调用进程阻塞,把管程让出来给另一个进程持有。signal() 操作用于唤醒被阻塞的进程。 +管程引入了 **条件变量** 以及相关的操作:**wait()** 和 **signal()** 来实现同步操作。对条件变量执行 wait() 操作会导致调用进程阻塞,把管程让出来给另一个进程持有。signal() 操作用于唤醒被阻塞的进程。 - **使用管程实现生产者-消费者问题**
+ **使用管程实现生产者-消费者问题**
```pascal // 管程 diff --git a/notes/计算机操作系统.md b/notes/计算机操作系统.md index 1380db75..84d12598 100644 --- a/notes/计算机操作系统.md +++ b/notes/计算机操作系统.md @@ -1,7 +1,3 @@ - - - - [计算机操作系统](https://github.com/CyC2018/CS-Notes/blob/master/notes/%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%20-%20%E7%9B%AE%E5%BD%95.md) diff --git a/notes/计算机网络 - 传输层.md b/notes/计算机网络 - 传输层.md index bc2b6859..12d5a481 100644 --- a/notes/计算机网络 - 传输层.md +++ b/notes/计算机网络 - 传输层.md @@ -31,19 +31,19 @@

-- **序号** :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。 +- **序号** :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。 -- **确认号** :期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。 +- **确认号** :期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。 -- **数据偏移** :指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。 +- **数据偏移** :指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。 -- **确认 ACK** :当 ACK=1 时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1。 +- **确认 ACK** :当 ACK=1 时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1。 -- **同步 SYN** :在连接建立时用来同步序号。当 SYN=1,ACK=0 时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中 SYN=1,ACK=1。 +- **同步 SYN** :在连接建立时用来同步序号。当 SYN=1,ACK=0 时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中 SYN=1,ACK=1。 -- **终止 FIN** :用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,并要求释放连接。 +- **终止 FIN** :用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,并要求释放连接。 -- **窗口** :窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。 +- **窗口** :窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。 # TCP 的三次握手 @@ -61,7 +61,7 @@ - B 收到 A 的确认后,连接建立。 -**三次握手的原因** +**三次握手的原因** 第三次握手是为了防止失效的连接请求到达服务器,让服务器错误打开连接。 @@ -83,11 +83,11 @@ - B 收到 A 的确认后释放连接。 -**四次挥手的原因** +**四次挥手的原因** 客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。 -**TIME_WAIT** +**TIME_WAIT** 客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由: @@ -102,13 +102,11 @@ TCP 使用超时重传来实现可靠传输:如果一个已经发送的报文 一个报文段从发送再到接收到确认所经过的时间称为往返时间 RTT,加权平均往返时间 RTTs 计算如下:

- 其中,0 ≤ a < 1,RTTs 随着 a 的增加更容易受到 RTT 的影响。 超时时间 RTO 应该略大于 RTTs,TCP 使用的超时时间计算如下:

- 其中 RTTd 为偏差的加权平均值。 # TCP 滑动窗口 diff --git a/notes/计算机网络 - 概述.md b/notes/计算机网络 - 概述.md index 8b8b38d9..35b58744 100644 --- a/notes/计算机网络 - 概述.md +++ b/notes/计算机网络 - 概述.md @@ -97,23 +97,23 @@ ## 1. 五层协议 -- **应用层** :为特定应用程序提供数据传输服务,例如 HTTP、DNS 等协议。数据单位为报文。 +- **应用层** :为特定应用程序提供数据传输服务,例如 HTTP、DNS 等协议。数据单位为报文。 -- **传输层** :为进程提供通用数据传输服务。由于应用层协议很多,定义通用的传输层协议就可以支持不断增多的应用层协议。运输层包括两种协议:传输控制协议 TCP,提供面向连接、可靠的数据传输服务,数据单位为报文段;用户数据报协议 UDP,提供无连接、尽最大努力的数据传输服务,数据单位为用户数据报。TCP 主要提供完整性服务,UDP 主要提供及时性服务。 +- **传输层** :为进程提供通用数据传输服务。由于应用层协议很多,定义通用的传输层协议就可以支持不断增多的应用层协议。运输层包括两种协议:传输控制协议 TCP,提供面向连接、可靠的数据传输服务,数据单位为报文段;用户数据报协议 UDP,提供无连接、尽最大努力的数据传输服务,数据单位为用户数据报。TCP 主要提供完整性服务,UDP 主要提供及时性服务。 -- **网络层** :为主机提供数据传输服务。而传输层协议是为主机中的进程提供数据传输服务。网络层把传输层传递下来的报文段或者用户数据报封装成分组。 +- **网络层** :为主机提供数据传输服务。而传输层协议是为主机中的进程提供数据传输服务。网络层把传输层传递下来的报文段或者用户数据报封装成分组。 -- **数据链路层** :网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。 +- **数据链路层** :网络层针对的还是主机之间的数据传输服务,而主机之间可以有很多链路,链路层协议就是为同一链路的主机提供数据传输服务。数据链路层把网络层传下来的分组封装成帧。 -- **物理层** :考虑的是怎样在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。 +- **物理层** :考虑的是怎样在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。 ## 2. OSI 其中表示层和会话层用途如下: -- **表示层** :数据压缩、加密以及数据描述,这使得应用程序不必关心在各台主机中数据内部格式不同的问题。 +- **表示层** :数据压缩、加密以及数据描述,这使得应用程序不必关心在各台主机中数据内部格式不同的问题。 -- **会话层** :建立及管理会话。 +- **会话层** :建立及管理会话。 五层协议没有表示层和会话层,而是将这些功能留给应用程序开发者处理。 diff --git a/notes/计算机网络 - 目录.md b/notes/计算机网络 - 目录.md index a73176c2..7d7b0def 100644 --- a/notes/计算机网络 - 目录.md +++ b/notes/计算机网络 - 目录.md @@ -1,5 +1,3 @@ - - # 目录 - [概述](计算机网络%20-%20概述.md) diff --git a/notes/计算机网络 - 目录1.md b/notes/计算机网络 - 目录1.md index 9b2086f2..28a9aa1e 100644 --- a/notes/计算机网络 - 目录1.md +++ b/notes/计算机网络 - 目录1.md @@ -1,5 +1,3 @@ - - # 目录 - [概述](notes/计算机网络%20-%20概述.md) diff --git a/notes/计算机网络 - 网络层.md b/notes/计算机网络 - 网络层.md index 39031443..78ecfa9f 100644 --- a/notes/计算机网络 - 网络层.md +++ b/notes/计算机网络 - 网络层.md @@ -38,23 +38,23 @@

-- **版本** : 有 4(IPv4)和 6(IPv6)两个值; +- **版本** : 有 4(IPv4)和 6(IPv6)两个值; -- **首部长度** : 占 4 位,因此最大值为 15。值为 1 表示的是 1 个 32 位字的长度,也就是 4 字节。因为固定部分长度为 20 字节,因此该值最小为 5。如果可选字段的长度不是 4 字节的整数倍,就用尾部的填充部分来填充。 +- **首部长度** : 占 4 位,因此最大值为 15。值为 1 表示的是 1 个 32 位字的长度,也就是 4 字节。因为固定部分长度为 20 字节,因此该值最小为 5。如果可选字段的长度不是 4 字节的整数倍,就用尾部的填充部分来填充。 -- **区分服务** : 用来获得更好的服务,一般情况下不使用。 +- **区分服务** : 用来获得更好的服务,一般情况下不使用。 -- **总长度** : 包括首部长度和数据部分长度。 +- **总长度** : 包括首部长度和数据部分长度。 -- **生存时间** :TTL,它的存在是为了防止无法交付的数据报在互联网中不断兜圈子。以路由器跳数为单位,当 TTL 为 0 时就丢弃数据报。 +- **生存时间** :TTL,它的存在是为了防止无法交付的数据报在互联网中不断兜圈子。以路由器跳数为单位,当 TTL 为 0 时就丢弃数据报。 -- **协议** :指出携带的数据应该上交给哪个协议进行处理,例如 ICMP、TCP、UDP 等。 +- **协议** :指出携带的数据应该上交给哪个协议进行处理,例如 ICMP、TCP、UDP 等。 -- **首部检验和** :因为数据报每经过一个路由器,都要重新计算检验和,因此检验和不包含数据部分可以减少计算的工作量。 +- **首部检验和** :因为数据报每经过一个路由器,都要重新计算检验和,因此检验和不包含数据部分可以减少计算的工作量。 -- **标识** : 在数据报长度过长从而发生分片的情况下,相同数据报的不同分片具有相同的标识符。 +- **标识** : 在数据报长度过长从而发生分片的情况下,相同数据报的不同分片具有相同的标识符。 -- **片偏移** : 和标识符一起,用于发生分片的情况。片偏移的单位为 8 字节。 +- **片偏移** : 和标识符一起,用于发生分片的情况。片偏移的单位为 8 字节。

@@ -94,7 +94,7 @@ CIDR 的记法上采用在 IP 地址后面加上网络前缀长度的方法, CIDR 的地址掩码可以继续称为子网掩码,子网掩码首 1 长度为网络前缀的长度。 -一个 CIDR 地址块中有很多地址,一个 CIDR 表示的网络就可以表示原来的很多个网络,并且在路由表中只需要一个路由就可以代替原来的多个路由,减少了路由表项的数量。把这种通过使用网络前缀来减少路由表项的方式称为路由聚合,也称为 **构成超网** 。 +一个 CIDR 地址块中有很多地址,一个 CIDR 表示的网络就可以表示原来的很多个网络,并且在路由表中只需要一个路由就可以代替原来的多个路由,减少了路由表项的数量。把这种通过使用网络前缀来减少路由表项的方式称为路由聚合,也称为 **构成超网** 。 在路由表中的项目由“网络前缀”和“下一跳地址”组成,在查找时可能会得到不止一个匹配结果,应当采用最长前缀匹配来确定应该匹配哪一个。 diff --git a/notes/计算机网络 - 链路层.md b/notes/计算机网络 - 链路层.md index 0b2ec040..c1a69edc 100644 --- a/notes/计算机网络 - 链路层.md +++ b/notes/计算机网络 - 链路层.md @@ -117,13 +117,13 @@ CSMA/CD 表示载波监听多点接入 / 碰撞检测。 -- **多点接入** :说明这是总线型网络,许多主机以多点的方式连接到总线上。 -- **载波监听** :每个主机都必须不停地监听信道。在发送前,如果监听到信道正在使用,就必须等待。 -- **碰撞检测** :在发送中,如果监听到信道已有其它主机正在发送数据,就表示发生了碰撞。虽然每个主机在发送数据之前都已经监听到信道为空闲,但是由于电磁波的传播时延的存在,还是有可能会发生碰撞。 +- **多点接入** :说明这是总线型网络,许多主机以多点的方式连接到总线上。 +- **载波监听** :每个主机都必须不停地监听信道。在发送前,如果监听到信道正在使用,就必须等待。 +- **碰撞检测** :在发送中,如果监听到信道已有其它主机正在发送数据,就表示发生了碰撞。虽然每个主机在发送数据之前都已经监听到信道为空闲,但是由于电磁波的传播时延的存在,还是有可能会发生碰撞。 -记端到端的传播时延为 τ,最先发送的站点最多经过 2τ 就可以知道是否发生了碰撞,称 2τ 为 **争用期** 。只有经过争用期之后还没有检测到碰撞,才能肯定这次发送不会发生碰撞。 +记端到端的传播时延为 τ,最先发送的站点最多经过 2τ 就可以知道是否发生了碰撞,称 2τ 为 **争用期** 。只有经过争用期之后还没有检测到碰撞,才能肯定这次发送不会发生碰撞。 -当发生碰撞时,站点要停止发送,等待一段时间再发送。这个时间采用 **截断二进制指数退避算法** 来确定。从离散的整数集合 {0, 1, .., (2k-1)} 中随机取出一个数,记作 r,然后取 r 倍的争用期作为重传等待时间。 +当发生碰撞时,站点要停止发送,等待一段时间再发送。这个时间采用 **截断二进制指数退避算法** 来确定。从离散的整数集合 {0, 1, .., (2k-1)} 中随机取出一个数,记作 r,然后取 r 倍的争用期作为重传等待时间。

@@ -168,9 +168,9 @@ MAC 地址是链路层地址,长度为 6 字节(48 位),用于唯一标 以太网帧格式: -- **类型** :标记上层使用的协议; -- **数据** :长度在 46-1500 之间,如果太小则需要填充; -- **FCS** :帧检验序列,使用的是 CRC 检验方法; +- **类型** :标记上层使用的协议; +- **数据** :长度在 46-1500 之间,如果太小则需要填充; +- **FCS** :帧检验序列,使用的是 CRC 检验方法;

diff --git a/notes/计算机网络.md b/notes/计算机网络.md index 94dce4ec..d3d1b1d7 100644 --- a/notes/计算机网络.md +++ b/notes/计算机网络.md @@ -1,7 +1,3 @@ - - - - [计算机网络.md](https://github.com/CyC2018/CS-Notes/blob/master/notes/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%20-%20%E7%9B%AE%E5%BD%95.md) diff --git a/notes/设计模式.md b/notes/设计模式.md index 2dc4510b..872cf272 100644 --- a/notes/设计模式.md +++ b/notes/设计模式.md @@ -388,7 +388,7 @@ public class ConcreteFactory2 extends Factory { ### Intent -提供一个接口,用于创建 **相关的对象家族** 。 +提供一个接口,用于创建 **相关的对象家族** 。 ### Class Diagram diff --git a/notes/面向对象思想.md b/notes/面向对象思想.md index a41b19e1..e67bf484 100644 --- a/notes/面向对象思想.md +++ b/notes/面向对象思想.md @@ -62,11 +62,11 @@ public class Person { ## 继承 -继承实现了 **IS-A** 关系,例如 Cat 和 Animal 就是一种 IS-A 关系,因此 Cat 可以继承自 Animal,从而获得 Animal 非 private 的属性和方法。 +继承实现了 **IS-A** 关系,例如 Cat 和 Animal 就是一种 IS-A 关系,因此 Cat 可以继承自 Animal,从而获得 Animal 非 private 的属性和方法。 继承应该遵循里氏替换原则,子类对象必须能够替换掉所有父类对象。 -Cat 可以当做 Animal 来使用,也就是说可以使用 Animal 引用 Cat 对象。父类引用指向子类对象称为 **向上转型** 。 +Cat 可以当做 Animal 来使用,也就是说可以使用 Animal 引用 Cat 对象。父类引用指向子类对象称为 **向上转型** 。 ```java Animal animal = new Cat();