auto commit

This commit is contained in:
CyC2018 2020-05-27 00:44:06 +08:00
parent 15324cf9e7
commit afcfca0a9d
19 changed files with 150 additions and 321 deletions

View File

@ -1141,7 +1141,7 @@ System.out.println(InterfaceExample.x);
使用接口
- 需要让不相关的类都实现一个方法例如不相关的类都可以实现 Compareable 接口中的 compareTo() 方法
- 需要让不相关的类都实现一个方法例如不相关的类都可以实现 Comparable 接口中的 compareTo() 方法
- 需要使用多重继承
使用抽象类

View File

@ -521,7 +521,7 @@ public static final int value = 123;
其中解析过程在某些情况下可以在初始化阶段之后再开始这是为了支持 Java 的动态绑定
<div data="补充为什么可以支持动态绑定 --> <--"></div>
### 5. 初始化
### 5. 初始化
<div data="modify -->"></div>
初始化阶段才真正开始执行类中定义的 Java 程序代码初始化阶段是虚拟机执行类构造器 &lt;clinit>() 方法的过程在准备阶段类变量已经赋过一次系统要求的初始值而在初始化阶段根据程序员通过程序制定的主观计划去初始化类变量和其它资源

View File

@ -1,5 +1,4 @@
<!-- GFM-TOC -->
* [0. 原理](#0-原理)
* [1. 统计两个数的二进制表示有多少位不同](#1-统计两个数的二进制表示有多少位不同)
* [2. 数组中唯一一个不重复的元素](#2-数组中唯一一个不重复的元素)
* [3. 找出数组中缺失的那个数](#3-找出数组中缺失的那个数)
@ -16,9 +15,7 @@
<!-- GFM-TOC -->
# 0. 原理
**基本原理**
**基本原理**
0s 表示一串 01s 表示一串 1
@ -28,79 +25,23 @@ x ^ 1s = ~x x & 1s = x x | 1s = 1s
x ^ x = 0 x & x = x x | x = x
```
利用 x ^ 1s = \~x 的特点可以将一个数的位级表示翻转利用 x ^ x = 0 的特点可以将三个数中重复的两个数去除只留下另一个数
- 利用 x ^ 1s = \~x 的特点可以将位级表示翻转利用 x ^ x = 0 的特点可以将三个数中重复的两个数去除只留下另一个数
- 利用 x & 0s = 0 x & 1s = x 的特点可以实现掩码操作一个数 num mask00111100 进行位与操作只保留 num 中与 mask 1 部分相对应的位
- 利用 x | 0s = x x | 1s = 1s 的特点可以实现设值操作一个数 num mask00111100 进行位或操作 num 中与 mask 1 部分相对应的位都设置为 1
```
1^1^2 = 2
```
位与运算技巧
利用 x & 0s = 0 x & 1s = x 的特点可以实现掩码操作一个数 num mask00111100 进行位与操作只保留 num 中与 mask 1 部分相对应的位
- n&(n-1) 去除 n 的位级表示中最低的那一位例如对于二进制表示 10110100减去 1 得到 10110011这两个数相与得到 10110000
- n&(-n) 得到 n 的位级表示中最低的那一位-n 得到 n 的反码加 1对于二进制表示 10110100-n 得到 01001100相与得到 00000100
- n-n&(\~n+1) 去除 n 的位级表示中最高的那一位
```
01011011 &
00111100
--------
00011000
```
移位运算
利用 x | 0s = x x | 1s = 1s 的特点可以实现设值操作一个数 num mask00111100 进行位或操作 num 中与 mask 1 部分相对应的位都设置为 1
- \>\> n 为算术右移相当于除以 2<sup>n</sup>
- \>\>\> n 为无符号右移左边会补上 0
- &lt;&lt; n 为算术左移相当于乘以 2<sup>n</sup>
```
01011011 |
00111100
--------
01111111
```
**位与运算技巧**
n&(n-1) 去除 n 的位级表示中最低的那一位 1例如对于二进制表示 01011011减去 1 得到 01011010这两个数相与得到 01011010
```
01011011 &
01011010
--------
01011010
```
n&(-n) 得到 n 的位级表示中最低的那一位 1-n 得到 n 的反码加 1也就是 -n=\~n+1例如对于二进制表示 10110100-n 得到 01001100相与得到 00000100
```
10110100 &
01001100
--------
00000100
```
n-(n&(-n)) 则可以去除 n 的位级表示中最低的那一位 1 n&(n-1) 效果一样
**移位运算**
\>\> n 为算术右移相当于除以 2<sup>n</sup>例如 -7 >> 2 = -2
```
11111111111111111111111111111001 >> 2
--------
11111111111111111111111111111110
```
\>\>\> n 为无符号右移左边会补上 0例如 -7 >>> 2 = 1073741822
```
11111111111111111111111111111001 >>> 2
--------
00111111111111111111111111111111
```
&lt;&lt; n 为算术左移相当于乘以 2<sup>n</sup>-7 << 2 = -28
```
11111111111111111111111111111001 << 2
--------
11111111111111111111111111100100
```
**mask 计算**
** mask 计算**
要获取 111111111 0 取反即可\~0

View File

@ -34,7 +34,7 @@
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/95903878-725b-4ed9-bded-bc4aae0792a9.jpg"/> </div><br>
广度优先搜索一层一层地进行遍历每层遍历都以上一层遍历的结果作为起点遍历一个距离能访问到的所有节点需要注意的是遍历过的节点不能再次被遍历
广度优先搜索一层一层地进行遍历每层遍历都以上一层遍历的结果作为起点遍历一个距离能访问到的所有节点需要注意的是遍历过的节点不能再次被遍历
第一层
@ -75,39 +75,33 @@
题目描述0 表示可以经过某个位置求解从左上角到右下角的最短路径长度
```java
public int shortestPathBinaryMatrix(int[][] grids) {
if (grids == null || grids.length == 0 || grids[0].length == 0) {
return -1;
}
int[][] direction = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}};
int m = grids.length, n = grids[0].length;
Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
queue.add(new Pair<>(0, 0));
int pathLength = 0;
while (!queue.isEmpty()) {
int size = queue.size();
pathLength++;
while (size-- > 0) {
Pair<Integer, Integer> cur = queue.poll();
int cr = cur.getKey(), cc = cur.getValue();
if (grids[cr][cc] == 1) {
public int shortestPathBinaryMatrix(int[][] grids) {
int[][] direction = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}};
int m = grids.length, n = grids[0].length;
Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
queue.add(new Pair<>(0, 0));
int pathLength = 0;
while (!queue.isEmpty()) {
int size = queue.size();
pathLength++;
while (size-- > 0) {
Pair<Integer, Integer> cur = queue.poll();
int cr = cur.getKey(), cc = cur.getValue();
grids[cr][cc] = 1; // 标记
for (int[] d : direction) {
int nr = cr + d[0], nc = cc + d[1];
if (nr < 0 || nr >= m || nc < 0 || nc >= n || grids[nr][nc] == 1) {
continue;
}
if (cr == m - 1 && cc == n - 1) {
return pathLength;
}
grids[cr][cc] = 1; // 标记
for (int[] d : direction) {
int nr = cr + d[0], nc = cc + d[1];
if (nr < 0 || nr >= m || nc < 0 || nc >= n) {
continue;
}
queue.add(new Pair<>(nr, nc));
if (nr == m - 1 && nc == n - 1) {
return pathLength + 1;
}
queue.add(new Pair<>(nr, nc));
}
}
return -1;
}
return -1;
}
```
## 2. 组成整数的最小平方数数量

View File

@ -827,7 +827,7 @@ https://leetcode.com/problems/rank-scores/description/
| 2 | 4.2 | 2 | 2 |
| 3 | 4.3 | 1 | 1 |
使用连接操作找到某个 score 对应的大于等于其值的记录
使用连接操作找到某个 score 对应的大于其值的记录
```sql
SELECT
@ -890,7 +890,7 @@ ORDER BY
| score | Rank |
| :---: | :--: |
| 4.2 | 1 |
| 4.2 | 1 |
| 4.2 | 2 |
| 4.1 | 2 |
连接情况如下

View File

@ -1021,7 +1021,7 @@ g/re/pglobally search a regular expression and print),使用正则表示式
```html
$ grep [-acinv] [--color=auto] 搜寻字符串 filename
-c 统计匹配到行的个数
-c 统计个数
-i 忽略大小写
-n 输出行号
-v 反向选择也就是显示出没有 搜寻字符串 内容的那一行
@ -1039,7 +1039,7 @@ $ grep -n 'the' regular_express.txt
18:google is the best tools for search keyword
```
示例正则表达式 a{m,n} 用来匹配字符 a m\~n 这里需要将 { } 进行转因为它们在 shell 是有特殊意义的
示例正则表达式 a{m,n} 用来匹配字符 a m\~n 这里需要将 { } 进行转因为它们在 shell 是有特殊意义的
```html
$ grep -n 'a\{2,5\}' regular_express.txt

View File

@ -1,10 +1,3 @@
# 前言
题目来自何海涛. 剑指 Offer[M]. 电子工业出版社, 2012.刷题网站推荐
- [牛客网](https://www.nowcoder.com/ta/coding-interviews?from=cyc_github)
- [Leetcode](https://leetcode-cn.com/problemset/lcof/)
# 目录
@ -85,6 +78,10 @@
- [67. 把字符串转换成整数](67.%20把字符串转换成整数.md)
- [68. 树中两个节点的最低公共祖先](68.%20树中两个节点的最低公共祖先.md)
# 参考文献
何海涛. 剑指 Offer[M]. 电子工业出版社, 2012.

View File

@ -73,7 +73,6 @@
```
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/eb859228-c0f2-4bce-910d-d9f76929352b.png"/> </div><br>
## 3. 最近未使用
> NRU, Not Recently Used
@ -89,7 +88,7 @@
NRU 优先换出已经被修改的脏页面R=0M=1而不是被频繁使用的干净页面R=1M=0
## 4. 先进先出
## 4. 先进先出
> FIFO, First In First Out

View File

@ -22,53 +22,20 @@ Output:
```java
public int StrToInt(String str) {
if (str == null)
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;
int result = 0;
boolean negative = false;//是否负数
int i = 0, len = str.length();
/**
* limit 默认初始化为*负的*最大正整数 假如字符串表示的是正数
* 由于int的范围为-2147483648~2147483647
* 那么result(在返回之前一直是负数形式)就必须和这个最大正数的负数来比较来判断是否溢出
*/
int limit = - Integer.MAX_VALUE;
int multmin;
int digit;
if (len > 0) {
char firstChar = str.charAt(0);//首先看第一位
if (firstChar < '0') { // 有可能是 "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;//在负号的情况下判断溢出的值就变成了 整数的 最小负数了
} else if (firstChar != '+')//第一位不是数字和-只能是+
return 0;
if (len == 1) // Cannot have lone "+" or "-"
return 0;
i++;
}
multmin = limit / 10;
while (i < len) {
digit = str.charAt(i++)-'0';
if (digit < 0 || digit > 9)
return 0;
//判断溢出
if (result < multmin) {
return 0;
}
result *= 10;
if (result < limit + digit) {
return 0;
}
result -= digit;
}
} else {
return 0;
}
//如果是正数就返回-resultresult一直是负数
return negative ? result : -result;
ret = ret * 10 + (c - '0');
}
return isNegative ? -ret : ret;
}
```

View File

@ -1141,7 +1141,7 @@ System.out.println(InterfaceExample.x);
使用接口
- 需要让不相关的类都实现一个方法例如不相关的类都可以实现 Compareable 接口中的 compareTo() 方法
- 需要让不相关的类都实现一个方法例如不相关的类都可以实现 Comparable 接口中的 compareTo() 方法
- 需要使用多重继承
使用抽象类
@ -1432,9 +1432,8 @@ Java 注解是附加在代码中的一些元信息,用于一些工具在编译
## JRE or JDK
- JREJava Runtime Environmentjava运行环境的简称为java的运行提供了所需的环境主要包括了JVM的标准实现和一些java基本类库
- JDKJava Development Kitjava开发工具包提供了java的开发及运行环境JDK是java开发的核心集成了JRE以及一些其他的工具比如编译 java 源码的编译器 javac等
- 因此可以这样认为JDK>JRE>JVMJRE支持了java程序的运行而JDK则同时支持了java程序的开发
- JRE is the JVM program, Java application need to run on JRE.
- JDK is a superset of JRE, JRE + tools for developing java programs. e.g, it provides the compiler "javac"
# 参考资料

View File

@ -521,7 +521,7 @@ public static final int value = 123;
其中解析过程在某些情况下可以在初始化阶段之后再开始这是为了支持 Java 的动态绑定
<div data="补充为什么可以支持动态绑定 --> <--"></div>
### 5. 初始化
### 5. 初始化
<div data="modify -->"></div>
初始化阶段才真正开始执行类中定义的 Java 程序代码初始化阶段是虚拟机执行类构造器 &lt;clinit>() 方法的过程在准备阶段类变量已经赋过一次系统要求的初始值而在初始化阶段根据程序员通过程序制定的主观计划去初始化类变量和其它资源

View File

@ -1,5 +1,4 @@
<!-- GFM-TOC -->
* [0. 原理](#0-原理)
* [1. 统计两个数的二进制表示有多少位不同](#1-统计两个数的二进制表示有多少位不同)
* [2. 数组中唯一一个不重复的元素](#2-数组中唯一一个不重复的元素)
* [3. 找出数组中缺失的那个数](#3-找出数组中缺失的那个数)
@ -16,9 +15,7 @@
<!-- GFM-TOC -->
# 0. 原理
**基本原理**
**基本原理**
0s 表示一串 01s 表示一串 1
@ -28,79 +25,23 @@ x ^ 1s = ~x x & 1s = x x | 1s = 1s
x ^ x = 0 x & x = x x | x = x
```
利用 x ^ 1s = \~x 的特点可以将一个数的位级表示翻转利用 x ^ x = 0 的特点可以将三个数中重复的两个数去除只留下另一个数
- 利用 x ^ 1s = \~x 的特点可以将位级表示翻转利用 x ^ x = 0 的特点可以将三个数中重复的两个数去除只留下另一个数
- 利用 x & 0s = 0 x & 1s = x 的特点可以实现掩码操作一个数 num mask00111100 进行位与操作只保留 num 中与 mask 1 部分相对应的位
- 利用 x | 0s = x x | 1s = 1s 的特点可以实现设值操作一个数 num mask00111100 进行位或操作 num 中与 mask 1 部分相对应的位都设置为 1
```
1^1^2 = 2
```
位与运算技巧
利用 x & 0s = 0 x & 1s = x 的特点可以实现掩码操作一个数 num mask00111100 进行位与操作只保留 num 中与 mask 1 部分相对应的位
- n&(n-1) 去除 n 的位级表示中最低的那一位例如对于二进制表示 10110100减去 1 得到 10110011这两个数相与得到 10110000
- n&(-n) 得到 n 的位级表示中最低的那一位-n 得到 n 的反码加 1对于二进制表示 10110100-n 得到 01001100相与得到 00000100
- n-n&(\~n+1) 去除 n 的位级表示中最高的那一位
```
01011011 &
00111100
--------
00011000
```
移位运算
利用 x | 0s = x x | 1s = 1s 的特点可以实现设值操作一个数 num mask00111100 进行位或操作 num 中与 mask 1 部分相对应的位都设置为 1
- \>\> n 为算术右移相当于除以 2<sup>n</sup>
- \>\>\> n 为无符号右移左边会补上 0
- &lt;&lt; n 为算术左移相当于乘以 2<sup>n</sup>
```
01011011 |
00111100
--------
01111111
```
**位与运算技巧**
n&(n-1) 去除 n 的位级表示中最低的那一位 1例如对于二进制表示 01011011减去 1 得到 01011010这两个数相与得到 01011010
```
01011011 &
01011010
--------
01011010
```
n&(-n) 得到 n 的位级表示中最低的那一位 1-n 得到 n 的反码加 1也就是 -n=\~n+1例如对于二进制表示 10110100-n 得到 01001100相与得到 00000100
```
10110100 &
01001100
--------
00000100
```
n-(n&(-n)) 则可以去除 n 的位级表示中最低的那一位 1 n&(n-1) 效果一样
**移位运算**
\>\> n 为算术右移相当于除以 2<sup>n</sup>例如 -7 >> 2 = -2
```
11111111111111111111111111111001 >> 2
--------
11111111111111111111111111111110
```
\>\>\> n 为无符号右移左边会补上 0例如 -7 >>> 2 = 1073741822
```
11111111111111111111111111111001 >>> 2
--------
00111111111111111111111111111111
```
&lt;&lt; n 为算术左移相当于乘以 2<sup>n</sup>-7 << 2 = -28
```
11111111111111111111111111111001 << 2
--------
11111111111111111111111111100100
```
**mask 计算**
** mask 计算**
要获取 111111111 0 取反即可\~0

View File

@ -139,7 +139,7 @@ private int rob(int[] nums, int first, int last) {
## 4. 信件错排
题目描述 N 信封它们被打乱求错误装信方式的数量所有信封都没有装各自的信
题目描述 N 信封它们被打乱求错误装信方式的数量
定义一个数组 dp 存储错误方式数量dp[i] 表示前 i 个信和信封的错误方式数量假设第 i 个信装到第 j 个信封里面而第 j 个信装到第 k 个信封里面根据 i k 是否相等有两种情况
@ -1055,10 +1055,7 @@ public int combinationSum4(int[] nums, int target) {
题目描述交易之后需要有一天的冷却时间
该题为马尔可夫过程分为A观望B持股C冷却三个状态
状态转移图A-(观望)->A, A-(买入-price)->B, B-(观望)->B, B-(卖出|+price)->C, C-(冷却)->A
可用维特比算法求解
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ffd96b99-8009-487c-8e98-11c9d44ef14f.png" width="300px"> </div><br>
```java
public int maxProfit(int[] prices) {
@ -1066,17 +1063,19 @@ public int maxProfit(int[] prices) {
return 0;
}
int N = prices.length;
int[] A = new int[N];
int[] B = new int[N];
int[] C = new int[N];
A[0] = 0;
B[0] = C[0] = -prices[0];
int[] buy = new int[N];
int[] s1 = new int[N];
int[] sell = new int[N];
int[] s2 = new int[N];
s1[0] = buy[0] = -prices[0];
sell[0] = s2[0] = 0;
for (int i = 1; i < N; i++) {
A[i] = Math.max(A[i - 1], C[i - 1]);
B[i] = Math.max(B[i - 1], A[i - 1] - prices[i]);
C[i] = B[i - 1] + prices[i];
buy[i] = s2[i - 1] - prices[i];
s1[i] = Math.max(buy[i - 1], s1[i - 1]);
sell[i] = Math.max(buy[i - 1], s1[i - 1]) + prices[i];
s2[i] = Math.max(s2[i - 1], sell[i - 1]);
}
return Math.max(A[N - 1], C[N - 1]);
return Math.max(sell[N - 1], s2[N - 1]);
}
```
@ -1099,22 +1098,24 @@ The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
题目描述每交易一次都要支付一定的费用
分为A观望B持股两个状态
状态转移图A-(观望)->A, A-(买入|-price)->B, B-(观望)->B, B-(卖出|+price|-fee)->A
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png" width="300px"> </div><br>
```java
public int maxProfit(int[] prices, int fee) {
int N = prices.length;
int[] A = new int[N];
int[] B = new int[N];
A[0] = 0;
B[0] = -prices[0];
int[] buy = new int[N];
int[] s1 = new int[N];
int[] sell = new int[N];
int[] s2 = new int[N];
s1[0] = buy[0] = -prices[0];
sell[0] = s2[0] = 0;
for (int i = 1; i < N; i++) {
A[i] = Math.max(A[i - 1], B[i - 1] + prices[i] -fee);
B[i] = Math.max(A[i - 1] - prices[i], B[i - 1]);
buy[i] = Math.max(sell[i - 1], s2[i - 1]) - prices[i];
s1[i] = Math.max(buy[i - 1], s1[i - 1]);
sell[i] = Math.max(buy[i - 1], s1[i - 1]) - fee + prices[i];
s2[i] = Math.max(s2[i - 1], sell[i - 1]);
}
return A[N - 1];
return Math.max(sell[N - 1], s2[N - 1]);
}
```

View File

@ -34,7 +34,7 @@
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/95903878-725b-4ed9-bded-bc4aae0792a9.jpg"/> </div><br>
广度优先搜索一层一层地进行遍历每层遍历都以上一层遍历的结果作为起点遍历一个距离能访问到的所有节点需要注意的是遍历过的节点不能再次被遍历
广度优先搜索一层一层地进行遍历每层遍历都以上一层遍历的结果作为起点遍历一个距离能访问到的所有节点需要注意的是遍历过的节点不能再次被遍历
第一层
@ -75,39 +75,33 @@
题目描述0 表示可以经过某个位置求解从左上角到右下角的最短路径长度
```java
public int shortestPathBinaryMatrix(int[][] grids) {
if (grids == null || grids.length == 0 || grids[0].length == 0) {
return -1;
}
int[][] direction = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}};
int m = grids.length, n = grids[0].length;
Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
queue.add(new Pair<>(0, 0));
int pathLength = 0;
while (!queue.isEmpty()) {
int size = queue.size();
pathLength++;
while (size-- > 0) {
Pair<Integer, Integer> cur = queue.poll();
int cr = cur.getKey(), cc = cur.getValue();
if (grids[cr][cc] == 1) {
public int shortestPathBinaryMatrix(int[][] grids) {
int[][] direction = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}};
int m = grids.length, n = grids[0].length;
Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
queue.add(new Pair<>(0, 0));
int pathLength = 0;
while (!queue.isEmpty()) {
int size = queue.size();
pathLength++;
while (size-- > 0) {
Pair<Integer, Integer> cur = queue.poll();
int cr = cur.getKey(), cc = cur.getValue();
grids[cr][cc] = 1; // 标记
for (int[] d : direction) {
int nr = cr + d[0], nc = cc + d[1];
if (nr < 0 || nr >= m || nc < 0 || nc >= n || grids[nr][nc] == 1) {
continue;
}
if (cr == m - 1 && cc == n - 1) {
return pathLength;
}
grids[cr][cc] = 1; // 标记
for (int[] d : direction) {
int nr = cr + d[0], nc = cc + d[1];
if (nr < 0 || nr >= m || nc < 0 || nc >= n) {
continue;
}
queue.add(new Pair<>(nr, nc));
if (nr == m - 1 && nc == n - 1) {
return pathLength + 1;
}
queue.add(new Pair<>(nr, nc));
}
}
return -1;
}
return -1;
}
```
## 2. 组成整数的最小平方数数量

View File

@ -827,7 +827,7 @@ https://leetcode.com/problems/rank-scores/description/
| 2 | 4.2 | 2 | 2 |
| 3 | 4.3 | 1 | 1 |
使用连接操作找到某个 score 对应的大于等于其值的记录
使用连接操作找到某个 score 对应的大于其值的记录
```sql
SELECT
@ -890,7 +890,7 @@ ORDER BY
| score | Rank |
| :---: | :--: |
| 4.2 | 1 |
| 4.2 | 1 |
| 4.2 | 2 |
| 4.1 | 2 |
连接情况如下

View File

@ -1021,7 +1021,7 @@ g/re/pglobally search a regular expression and print),使用正则表示式
```html
$ grep [-acinv] [--color=auto] 搜寻字符串 filename
-c 统计匹配到行的个数
-c 统计个数
-i 忽略大小写
-n 输出行号
-v 反向选择也就是显示出没有 搜寻字符串 内容的那一行
@ -1039,7 +1039,7 @@ $ grep -n 'the' regular_express.txt
18:google is the best tools for search keyword
```
示例正则表达式 a{m,n} 用来匹配字符 a m\~n 这里需要将 { } 进行转因为它们在 shell 是有特殊意义的
示例正则表达式 a{m,n} 用来匹配字符 a m\~n 这里需要将 { } 进行转因为它们在 shell 是有特殊意义的
```html
$ grep -n 'a\{2,5\}' regular_express.txt

View File

@ -1,10 +1,3 @@
# 前言
题目来自何海涛. 剑指 Offer[M]. 电子工业出版社, 2012.刷题网站推荐
- [牛客网](https://www.nowcoder.com/ta/coding-interviews?from=cyc_github)
- [Leetcode](https://leetcode-cn.com/problemset/lcof/)
# 目录
@ -85,6 +78,10 @@
- [67. 把字符串转换成整数](67.%20把字符串转换成整数.md)
- [68. 树中两个节点的最低公共祖先](68.%20树中两个节点的最低公共祖先.md)
# 参考文献
何海涛. 剑指 Offer[M]. 电子工业出版社, 2012.

View File

@ -245,13 +245,13 @@ public class BinarySearchOrderedST<Key extends Comparable<Key>, Value> implement
**二叉树** 是一个空链接或者是一个有左右两个链接的节点每个链接都指向一颗子二叉树
<div align="center"> <img src="pics/c11528f6-fc71-4a2b-8d2f-51b8954c38f1.jpg" width="180"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c11528f6-fc71-4a2b-8d2f-51b8954c38f1.jpg" width="180"/> </div><br>
**二叉查找树** BST是一颗二叉树并且每个节点的值都大于等于其左子树中的所有节点的值而小于等于右子树的所有节点的值
BST 有一个重要性质就是它的中序遍历结果递增排序
<div align="center"> <img src="pics/ef552ae3-ae0d-4217-88e6-99cbe8163f0c.jpg" width="200"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ef552ae3-ae0d-4217-88e6-99cbe8163f0c.jpg" width="200"/> </div><br>
基本数据结构
@ -325,7 +325,7 @@ private Value get(Node x, Key key) {
当插入的键不存在于树中需要创建一个新节点并且更新上层节点的链接指向该节点使得该节点正确地链接到树中
<div align="center"> <img src="pics/58b70113-3876-49af-85a9-68eb00a72d59.jpg" width="200"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/58b70113-3876-49af-85a9-68eb00a72d59.jpg" width="200"/> </div><br>
```java
@Override
@ -354,11 +354,11 @@ private Node put(Node x, Key key, Value value) {
最好的情况下树是完全平衡的每条空链接和根节点的距离都为 logN
<div align="center"> <img src="pics/c395a428-827c-405b-abd7-8a069316f583.jpg" width="200"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/c395a428-827c-405b-abd7-8a069316f583.jpg" width="200"/> </div><br>
在最坏的情况下树的高度为 N
<div align="center"> <img src="pics/5ea609cb-8ad4-4c4c-aee6-45a40a81794a.jpg" width="200"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/5ea609cb-8ad4-4c4c-aee6-45a40a81794a.jpg" width="200"/> </div><br>
## 4. floor()
@ -436,7 +436,7 @@ private Node min(Node x) {
令指向最小节点的链接指向最小节点的右子树
<div align="center"> <img src="pics/31b7e8de-ed11-4f69-b5fd-ba454120ac31.jpg" width="450"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/31b7e8de-ed11-4f69-b5fd-ba454120ac31.jpg" width="450"/> </div><br>
```java
public void deleteMin() {
@ -457,7 +457,7 @@ public Node deleteMin(Node x) {
- 如果待删除的节点只有一个子树 那么只需要让指向待删除节点的链接指向唯一的子树即可
- 否则让右子树的最小节点替换该节点
<div align="center"> <img src="pics/23b9d625-ef28-42b5-bb22-d7aedd007e16.jpg" width="400"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/23b9d625-ef28-42b5-bb22-d7aedd007e16.jpg" width="400"/> </div><br>
```java
public void delete(Key key) {
@ -520,7 +520,7 @@ private List<Key> keys(Node x, Key l, Key h) {
2-3 查找树引入了 2- 节点和 3- 节点目的是为了让树平衡一颗完美平衡的 2-3 查找树的所有空链接到根节点的距离应该是相同的
<div align="center"> <img src="pics/1097658b-c0e6-4821-be9b-25304726a11c.jpg" width="160px"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1097658b-c0e6-4821-be9b-25304726a11c.jpg" width="160px"/> </div><br>
## 1. 插入操作
@ -530,11 +530,11 @@ private List<Key> keys(Node x, Key l, Key h) {
- 如果插入到 2- 节点上那么直接将新节点和原来的节点组成 3- 节点即可
<div align="center"> <img src="pics/0c6f9930-8704-4a54-af23-19f9ca3e48b0.jpg" width="350"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/0c6f9930-8704-4a54-af23-19f9ca3e48b0.jpg" width="350"/> </div><br>
- 如果是插入到 3- 节点上就会产生一个临时 4- 节点时需要将 4- 节点分裂成 3 2- 节点并将中间的 2- 节点移到上层节点中如果上移操作继续产生临时 4- 节点则一直进行分裂上移直到不存在临时 4- 节点
<div align="center"> <img src="pics/7002c01b-1ed5-475a-9e5f-5fc8a4cdbcc0.jpg" width="460"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/7002c01b-1ed5-475a-9e5f-5fc8a4cdbcc0.jpg" width="460"/> </div><br>
## 2. 性质
@ -546,7 +546,7 @@ private List<Key> keys(Node x, Key l, Key h) {
红黑树是 2-3 查找树但它不需要分别定义 2- 节点和 3- 节点而是在普通的二叉查找树之上为节点添加颜色指向一个节点的链接颜色如果为红色那么这个节点和上层节点表示的是一个 3- 节点而黑色则是普通链接
<div align="center"> <img src="pics/f1912ba6-6402-4321-9aa8-13d32fd121d1.jpg" width="240"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f1912ba6-6402-4321-9aa8-13d32fd121d1.jpg" width="240"/> </div><br>
红黑树具有以下性质
@ -555,7 +555,7 @@ private List<Key> keys(Node x, Key l, Key h) {
画红黑树时可以将红链接画平
<div align="center"> <img src="pics/f5cb6028-425d-4939-91eb-cca9dd6b6c6c.jpg" width="220"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f5cb6028-425d-4939-91eb-cca9dd6b6c6c.jpg" width="220"/> </div><br>
```java
public class RedBlackBST<Key extends Comparable<Key>, Value> extends BST<Key, Value> {
@ -575,7 +575,7 @@ public class RedBlackBST<Key extends Comparable<Key>, Value> extends BST<Key, Va
因为合法的红链接都为左链接如果出现右链接为红链接那么就需要进行左旋转操作
<div align="center"> <img src="pics/f4d534ab-0092-4a81-9e5b-ae889b9a72be.jpg" width="480"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/f4d534ab-0092-4a81-9e5b-ae889b9a72be.jpg" width="480"/> </div><br>
```java
public Node rotateLeft(Node h) {
@ -594,7 +594,7 @@ public Node rotateLeft(Node h) {
进行右旋转是为了转换两个连续的左红链接这会在之后的插入过程中探讨
<div align="center"> <img src="pics/63c8ffea-a9f2-4ebe-97d1-d71be71246f9.jpg" width="480"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/63c8ffea-a9f2-4ebe-97d1-d71be71246f9.jpg" width="480"/> </div><br>
```java
public Node rotateRight(Node h) {
@ -613,7 +613,7 @@ public Node rotateRight(Node h) {
一个 4- 节点在红黑树中表现为一个节点的左右子节点都是红色的分裂 4- 节点除了需要将子节点的颜色由红变黑之外同时需要将父节点的颜色由黑变红 2-3 树的角度看就是将中间节点移到上层节点
<div align="center"> <img src="pics/094b279a-b2db-4be7-87a3-b2a039c7448e.jpg" width="270"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/094b279a-b2db-4be7-87a3-b2a039c7448e.jpg" width="270"/> </div><br>
```java
void flipColors(Node h) {
@ -631,7 +631,7 @@ void flipColors(Node h) {
- 如果左子节点是红色的而且左子节点的左子节点也是红色的进行右旋转
- 如果左右子节点均为红色的进行颜色转换
<div align="center"> <img src="pics/4c457532-550b-4eca-b881-037b84b4934b.jpg" width="430"/> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/4c457532-550b-4eca-b881-037b84b4934b.jpg" width="430"/> </div><br>
```java
@Override
@ -756,7 +756,7 @@ public class Transaction {
对于 N 个键M 条链表 (N>M)如果哈希函数能够满足均匀性的条件每条链表的大小趋向于 N/M因此未命中的查找和插入操作所需要的比较次数为 \~N/M
<div align="center"> <img src="pics/cbbfe06c-f0cb-47c4-bf7b-2780aebd98b2.png" width="330px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/cbbfe06c-f0cb-47c4-bf7b-2780aebd98b2.png" width="330px"> </div><br>
## 3. 线性探测法
@ -765,7 +765,7 @@ public class Transaction {
使用线性探测法数组的大小 M 应当大于键的个数 NM>N)
<div align="center"> <img src="pics/0dbc4f7d-05c9-4aae-8065-7b7ea7e9709e.gif" width="350px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/0dbc4f7d-05c9-4aae-8065-7b7ea7e9709e.gif" width="350px"> </div><br>
```java
public class LinearProbingHashST<Key, Value> implements UnorderedST<Key, Value> {
@ -867,7 +867,7 @@ public void delete(Key key) {
线性探测法的成本取决于连续条目的长度连续条目也叫聚簇当聚簇很长时在查找和插入时也需要进行很多次探测例如下图中 2\~4 位置就是一个聚簇
<div align="center"> <img src="pics/ace20410-f053-4c4a-aca4-2c603ff11bbe.png" width="340px"> </div><br>
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ace20410-f053-4c4a-aca4-2c603ff11bbe.png" width="340px"> </div><br>
α = N/M α 称为使用率理论证明 α 小于 1/2 时探测的预计次数只在 1.5 2.5 之间为了保证散列表的性能应当调整数组的大小使得 α [1/4, 1/2] 之间

View File

@ -73,7 +73,6 @@
```
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/eb859228-c0f2-4bce-910d-d9f76929352b.png"/> </div><br>
## 3. 最近未使用
> NRU, Not Recently Used
@ -89,7 +88,7 @@
NRU 优先换出已经被修改的脏页面R=0M=1而不是被频繁使用的干净页面R=1M=0
## 4. 先进先出
## 4. 先进先出
> FIFO, First In First Out