auto commit
This commit is contained in:
parent
15324cf9e7
commit
afcfca0a9d
|
@ -1141,7 +1141,7 @@ System.out.println(InterfaceExample.x);
|
||||||
|
|
||||||
使用接口:
|
使用接口:
|
||||||
|
|
||||||
- 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Compareable 接口中的 compareTo() 方法;
|
- 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Comparable 接口中的 compareTo() 方法;
|
||||||
- 需要使用多重继承。
|
- 需要使用多重继承。
|
||||||
|
|
||||||
使用抽象类:
|
使用抽象类:
|
||||||
|
|
|
@ -521,7 +521,7 @@ public static final int value = 123;
|
||||||
其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。
|
其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。
|
||||||
|
|
||||||
<div data="补充为什么可以支持动态绑定 --> <--"></div>
|
<div data="补充为什么可以支持动态绑定 --> <--"></div>
|
||||||
### 5. 初始化
|
### 5. 初始化
|
||||||
|
|
||||||
<div data="modify -->"></div>
|
<div data="modify -->"></div>
|
||||||
初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段是虚拟机执行类构造器 <clinit>() 方法的过程。在准备阶段,类变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划去初始化类变量和其它资源。
|
初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段是虚拟机执行类构造器 <clinit>() 方法的过程。在准备阶段,类变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划去初始化类变量和其它资源。
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<!-- GFM-TOC -->
|
<!-- GFM-TOC -->
|
||||||
* [0. 原理](#0-原理)
|
|
||||||
* [1. 统计两个数的二进制表示有多少位不同](#1-统计两个数的二进制表示有多少位不同)
|
* [1. 统计两个数的二进制表示有多少位不同](#1-统计两个数的二进制表示有多少位不同)
|
||||||
* [2. 数组中唯一一个不重复的元素](#2-数组中唯一一个不重复的元素)
|
* [2. 数组中唯一一个不重复的元素](#2-数组中唯一一个不重复的元素)
|
||||||
* [3. 找出数组中缺失的那个数](#3-找出数组中缺失的那个数)
|
* [3. 找出数组中缺失的那个数](#3-找出数组中缺失的那个数)
|
||||||
|
@ -16,9 +15,7 @@
|
||||||
<!-- GFM-TOC -->
|
<!-- GFM-TOC -->
|
||||||
|
|
||||||
|
|
||||||
# 0. 原理
|
**基本原理**
|
||||||
|
|
||||||
**基本原理**
|
|
||||||
|
|
||||||
0s 表示一串 0,1s 表示一串 1。
|
0s 表示一串 0,1s 表示一串 1。
|
||||||
|
|
||||||
|
@ -28,79 +25,23 @@ x ^ 1s = ~x x & 1s = x x | 1s = 1s
|
||||||
x ^ x = 0 x & x = x x | x = x
|
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 与 mask:00111100 进行位与操作,只保留 num 中与 mask 的 1 部分相对应的位。
|
||||||
|
- 利用 x | 0s = x 和 x | 1s = 1s 的特点,可以实现设值操作。一个数 num 与 mask:00111100 进行位或操作,将 num 中与 mask 的 1 部分相对应的位都设置为 1。
|
||||||
|
|
||||||
```
|
位与运算技巧:
|
||||||
1^1^2 = 2
|
|
||||||
```
|
|
||||||
|
|
||||||
利用 x & 0s = 0 和 x & 1s = x 的特点,可以实现掩码操作。一个数 num 与 mask:00111100 进行位与操作,只保留 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 与 mask:00111100 进行位或操作,将 num 中与 mask 的 1 部分相对应的位都设置为 1。
|
- \>\> n 为算术右移,相当于除以 2<sup>n</sup>;
|
||||||
|
- \>\>\> n 为无符号右移,左边会补上 0。
|
||||||
|
- << n 为算术左移,相当于乘以 2<sup>n</sup>。
|
||||||
|
|
||||||
```
|
** mask 计算**
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
<< n 为算术左移,相当于乘以 2<sup>n</sup>。-7 << 2 = -28。
|
|
||||||
|
|
||||||
```
|
|
||||||
11111111111111111111111111111001 << 2
|
|
||||||
--------
|
|
||||||
11111111111111111111111111100100
|
|
||||||
```
|
|
||||||
|
|
||||||
**mask 计算**
|
|
||||||
|
|
||||||
要获取 111111111,将 0 取反即可,\~0。
|
要获取 111111111,将 0 取反即可,\~0。
|
||||||
|
|
||||||
|
|
|
@ -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>
|
<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 表示可以经过某个位置,求解从左上角到右下角的最短路径长度。
|
题目描述:0 表示可以经过某个位置,求解从左上角到右下角的最短路径长度。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int shortestPathBinaryMatrix(int[][] grids) {
|
public int shortestPathBinaryMatrix(int[][] grids) {
|
||||||
if (grids == null || grids.length == 0 || grids[0].length == 0) {
|
int[][] direction = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}};
|
||||||
return -1;
|
int m = grids.length, n = grids[0].length;
|
||||||
}
|
Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
|
||||||
int[][] direction = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}};
|
queue.add(new Pair<>(0, 0));
|
||||||
int m = grids.length, n = grids[0].length;
|
int pathLength = 0;
|
||||||
Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
|
while (!queue.isEmpty()) {
|
||||||
queue.add(new Pair<>(0, 0));
|
int size = queue.size();
|
||||||
int pathLength = 0;
|
pathLength++;
|
||||||
while (!queue.isEmpty()) {
|
while (size-- > 0) {
|
||||||
int size = queue.size();
|
Pair<Integer, Integer> cur = queue.poll();
|
||||||
pathLength++;
|
int cr = cur.getKey(), cc = cur.getValue();
|
||||||
while (size-- > 0) {
|
grids[cr][cc] = 1; // 标记
|
||||||
Pair<Integer, Integer> cur = queue.poll();
|
for (int[] d : direction) {
|
||||||
int cr = cur.getKey(), cc = cur.getValue();
|
int nr = cr + d[0], nc = cc + d[1];
|
||||||
if (grids[cr][cc] == 1) {
|
if (nr < 0 || nr >= m || nc < 0 || nc >= n || grids[nr][nc] == 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cr == m - 1 && cc == n - 1) {
|
if (nr == m - 1 && nc == n - 1) {
|
||||||
return pathLength;
|
return pathLength + 1;
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
queue.add(new Pair<>(nr, nc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. 组成整数的最小平方数数量
|
## 2. 组成整数的最小平方数数量
|
||||||
|
|
|
@ -827,7 +827,7 @@ https://leetcode.com/problems/rank-scores/description/
|
||||||
| 2 | 4.2 | 2 | 2 |
|
| 2 | 4.2 | 2 | 2 |
|
||||||
| 3 | 4.3 | 1 | 1 |
|
| 3 | 4.3 | 1 | 1 |
|
||||||
|
|
||||||
使用连接操作找到某个 score 对应的大于等于其值的记录:
|
使用连接操作找到某个 score 对应的大于其值的记录:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -890,7 +890,7 @@ ORDER BY
|
||||||
| score | Rank |
|
| score | Rank |
|
||||||
| :---: | :--: |
|
| :---: | :--: |
|
||||||
| 4.2 | 1 |
|
| 4.2 | 1 |
|
||||||
| 4.2 | 1 |
|
| 4.2 | 2 |
|
||||||
| 4.1 | 2 |
|
| 4.1 | 2 |
|
||||||
|
|
||||||
连接情况如下:
|
连接情况如下:
|
||||||
|
|
|
@ -1021,7 +1021,7 @@ g/re/p(globally search a regular expression and print),使用正则表示式
|
||||||
|
|
||||||
```html
|
```html
|
||||||
$ grep [-acinv] [--color=auto] 搜寻字符串 filename
|
$ grep [-acinv] [--color=auto] 搜寻字符串 filename
|
||||||
-c : 统计匹配到行的个数
|
-c : 统计个数
|
||||||
-i : 忽略大小写
|
-i : 忽略大小写
|
||||||
-n : 输出行号
|
-n : 输出行号
|
||||||
-v : 反向选择,也就是显示出没有 搜寻字符串 内容的那一行
|
-v : 反向选择,也就是显示出没有 搜寻字符串 内容的那一行
|
||||||
|
@ -1039,7 +1039,7 @@ $ grep -n 'the' regular_express.txt
|
||||||
18:google is the best tools for search keyword
|
18:google is the best tools for search keyword
|
||||||
```
|
```
|
||||||
|
|
||||||
示例:正则表达式 a{m,n} 用来匹配字符 a m\~n 次,这里需要将 { 和 } 进行转义,因为它们在 shell 是有特殊意义的。
|
示例:正则表达式 a{m,n} 用来匹配字符 a m\~n 次,这里需要将 { 和 } 进行转移,因为它们在 shell 是有特殊意义的。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
$ grep -n 'a\{2,5\}' regular_express.txt
|
$ grep -n 'a\{2,5\}' regular_express.txt
|
||||||
|
|
|
@ -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)
|
- [67. 把字符串转换成整数](67.%20把字符串转换成整数.md)
|
||||||
- [68. 树中两个节点的最低公共祖先](68.%20树中两个节点的最低公共祖先.md)
|
- [68. 树中两个节点的最低公共祖先](68.%20树中两个节点的最低公共祖先.md)
|
||||||
|
|
||||||
|
# 参考文献
|
||||||
|
|
||||||
|
何海涛. 剑指 Offer[M]. 电子工业出版社, 2012.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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>
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/eb859228-c0f2-4bce-910d-d9f76929352b.png"/> </div><br>
|
||||||
|
|
||||||
## 3. 最近未使用
|
## 3. 最近未使用
|
||||||
|
|
||||||
> NRU, Not Recently Used
|
> NRU, Not Recently Used
|
||||||
|
@ -89,7 +88,7 @@
|
||||||
|
|
||||||
NRU 优先换出已经被修改的脏页面(R=0,M=1),而不是被频繁使用的干净页面(R=1,M=0)。
|
NRU 优先换出已经被修改的脏页面(R=0,M=1),而不是被频繁使用的干净页面(R=1,M=0)。
|
||||||
|
|
||||||
## 4. 先进先出
|
## 4. 先进先出
|
||||||
|
|
||||||
> FIFO, First In First Out
|
> FIFO, First In First Out
|
||||||
|
|
||||||
|
|
|
@ -22,53 +22,20 @@ Output:
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int StrToInt(String str) {
|
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;
|
return 0;
|
||||||
int result = 0;
|
ret = ret * 10 + (c - '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;
|
|
||||||
}
|
|
||||||
//如果是正数就返回-result(result一直是负数)
|
|
||||||
return negative ? result : -result;
|
|
||||||
}
|
}
|
||||||
|
return isNegative ? -ret : ret;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1141,7 +1141,7 @@ System.out.println(InterfaceExample.x);
|
||||||
|
|
||||||
使用接口:
|
使用接口:
|
||||||
|
|
||||||
- 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Compareable 接口中的 compareTo() 方法;
|
- 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Comparable 接口中的 compareTo() 方法;
|
||||||
- 需要使用多重继承。
|
- 需要使用多重继承。
|
||||||
|
|
||||||
使用抽象类:
|
使用抽象类:
|
||||||
|
@ -1432,9 +1432,8 @@ Java 注解是附加在代码中的一些元信息,用于一些工具在编译
|
||||||
|
|
||||||
## JRE or JDK
|
## JRE or JDK
|
||||||
|
|
||||||
- JRE:Java Runtime Environment,java运行环境的简称,为java的运行提供了所需的环境。主要包括了JVM的标准实现和一些java基本类库。
|
- JRE is the JVM program, Java application need to run on JRE.
|
||||||
- JDK:Java Development Kit,java开发工具包,提供了java的开发及运行环境。JDK是java开发的核心,集成了JRE以及一些其他的工具,比如编译 java 源码的编译器 javac等。
|
- JDK is a superset of JRE, JRE + tools for developing java programs. e.g, it provides the compiler "javac"
|
||||||
- 因此可以这样认为:JDK>JRE>JVM,JRE支持了java程序的运行,而JDK则同时支持了java程序的开发。
|
|
||||||
|
|
||||||
# 参考资料
|
# 参考资料
|
||||||
|
|
||||||
|
|
|
@ -521,7 +521,7 @@ public static final int value = 123;
|
||||||
其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。
|
其中解析过程在某些情况下可以在初始化阶段之后再开始,这是为了支持 Java 的动态绑定。
|
||||||
|
|
||||||
<div data="补充为什么可以支持动态绑定 --> <--"></div>
|
<div data="补充为什么可以支持动态绑定 --> <--"></div>
|
||||||
### 5. 初始化
|
### 5. 初始化
|
||||||
|
|
||||||
<div data="modify -->"></div>
|
<div data="modify -->"></div>
|
||||||
初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段是虚拟机执行类构造器 <clinit>() 方法的过程。在准备阶段,类变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划去初始化类变量和其它资源。
|
初始化阶段才真正开始执行类中定义的 Java 程序代码。初始化阶段是虚拟机执行类构造器 <clinit>() 方法的过程。在准备阶段,类变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划去初始化类变量和其它资源。
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<!-- GFM-TOC -->
|
<!-- GFM-TOC -->
|
||||||
* [0. 原理](#0-原理)
|
|
||||||
* [1. 统计两个数的二进制表示有多少位不同](#1-统计两个数的二进制表示有多少位不同)
|
* [1. 统计两个数的二进制表示有多少位不同](#1-统计两个数的二进制表示有多少位不同)
|
||||||
* [2. 数组中唯一一个不重复的元素](#2-数组中唯一一个不重复的元素)
|
* [2. 数组中唯一一个不重复的元素](#2-数组中唯一一个不重复的元素)
|
||||||
* [3. 找出数组中缺失的那个数](#3-找出数组中缺失的那个数)
|
* [3. 找出数组中缺失的那个数](#3-找出数组中缺失的那个数)
|
||||||
|
@ -16,9 +15,7 @@
|
||||||
<!-- GFM-TOC -->
|
<!-- GFM-TOC -->
|
||||||
|
|
||||||
|
|
||||||
# 0. 原理
|
**基本原理**
|
||||||
|
|
||||||
**基本原理**
|
|
||||||
|
|
||||||
0s 表示一串 0,1s 表示一串 1。
|
0s 表示一串 0,1s 表示一串 1。
|
||||||
|
|
||||||
|
@ -28,79 +25,23 @@ x ^ 1s = ~x x & 1s = x x | 1s = 1s
|
||||||
x ^ x = 0 x & x = x x | x = x
|
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 与 mask:00111100 进行位与操作,只保留 num 中与 mask 的 1 部分相对应的位。
|
||||||
|
- 利用 x | 0s = x 和 x | 1s = 1s 的特点,可以实现设值操作。一个数 num 与 mask:00111100 进行位或操作,将 num 中与 mask 的 1 部分相对应的位都设置为 1。
|
||||||
|
|
||||||
```
|
位与运算技巧:
|
||||||
1^1^2 = 2
|
|
||||||
```
|
|
||||||
|
|
||||||
利用 x & 0s = 0 和 x & 1s = x 的特点,可以实现掩码操作。一个数 num 与 mask:00111100 进行位与操作,只保留 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 与 mask:00111100 进行位或操作,将 num 中与 mask 的 1 部分相对应的位都设置为 1。
|
- \>\> n 为算术右移,相当于除以 2<sup>n</sup>;
|
||||||
|
- \>\>\> n 为无符号右移,左边会补上 0。
|
||||||
|
- << n 为算术左移,相当于乘以 2<sup>n</sup>。
|
||||||
|
|
||||||
```
|
** mask 计算**
|
||||||
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
|
|
||||||
```
|
|
||||||
|
|
||||||
<< n 为算术左移,相当于乘以 2<sup>n</sup>。-7 << 2 = -28。
|
|
||||||
|
|
||||||
```
|
|
||||||
11111111111111111111111111111001 << 2
|
|
||||||
--------
|
|
||||||
11111111111111111111111111100100
|
|
||||||
```
|
|
||||||
|
|
||||||
**mask 计算**
|
|
||||||
|
|
||||||
要获取 111111111,将 0 取反即可,\~0。
|
要获取 111111111,将 0 取反即可,\~0。
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ private int rob(int[] nums, int first, int last) {
|
||||||
|
|
||||||
## 4. 信件错排
|
## 4. 信件错排
|
||||||
|
|
||||||
题目描述:有 N 个 信 和 信封,它们被打乱,求错误装信方式的数量(所有信封都没有装各自的信)。
|
题目描述:有 N 个 信 和 信封,它们被打乱,求错误装信方式的数量。
|
||||||
|
|
||||||
定义一个数组 dp 存储错误方式数量,dp[i] 表示前 i 个信和信封的错误方式数量。假设第 i 个信装到第 j 个信封里面,而第 j 个信装到第 k 个信封里面。根据 i 和 k 是否相等,有两种情况:
|
定义一个数组 dp 存储错误方式数量,dp[i] 表示前 i 个信和信封的错误方式数量。假设第 i 个信装到第 j 个信封里面,而第 j 个信装到第 k 个信封里面。根据 i 和 k 是否相等,有两种情况:
|
||||||
|
|
||||||
|
@ -1055,10 +1055,7 @@ public int combinationSum4(int[] nums, int target) {
|
||||||
|
|
||||||
题目描述:交易之后需要有一天的冷却时间。
|
题目描述:交易之后需要有一天的冷却时间。
|
||||||
|
|
||||||
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ffd96b99-8009-487c-8e98-11c9d44ef14f.png" width="300px"> </div><br>
|
||||||
该题为马尔可夫过程,分为A观望,B持股,C冷却三个状态
|
|
||||||
状态转移图:A-(观望)->A, A-(买入|-price)->B, B-(观望)->B, B-(卖出|+price)->C, C-(冷却)->A
|
|
||||||
可用维特比算法求解
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int maxProfit(int[] prices) {
|
public int maxProfit(int[] prices) {
|
||||||
|
@ -1066,17 +1063,19 @@ public int maxProfit(int[] prices) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int N = prices.length;
|
int N = prices.length;
|
||||||
int[] A = new int[N];
|
int[] buy = new int[N];
|
||||||
int[] B = new int[N];
|
int[] s1 = new int[N];
|
||||||
int[] C = new int[N];
|
int[] sell = new int[N];
|
||||||
A[0] = 0;
|
int[] s2 = new int[N];
|
||||||
B[0] = C[0] = -prices[0];
|
s1[0] = buy[0] = -prices[0];
|
||||||
|
sell[0] = s2[0] = 0;
|
||||||
for (int i = 1; i < N; i++) {
|
for (int i = 1; i < N; i++) {
|
||||||
A[i] = Math.max(A[i - 1], C[i - 1]);
|
buy[i] = s2[i - 1] - prices[i];
|
||||||
B[i] = Math.max(B[i - 1], A[i - 1] - prices[i]);
|
s1[i] = Math.max(buy[i - 1], s1[i - 1]);
|
||||||
C[i] = B[i - 1] + prices[i];
|
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.
|
||||||
|
|
||||||
题目描述:每交易一次,都要支付一定的费用。
|
题目描述:每交易一次,都要支付一定的费用。
|
||||||
|
|
||||||
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png" width="300px"> </div><br>
|
||||||
分为A观望,B持股,两个状态
|
|
||||||
状态转移图:A-(观望)->A, A-(买入|-price)->B, B-(观望)->B, B-(卖出|+price|-fee)->A
|
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int maxProfit(int[] prices, int fee) {
|
public int maxProfit(int[] prices, int fee) {
|
||||||
int N = prices.length;
|
int N = prices.length;
|
||||||
int[] A = new int[N];
|
int[] buy = new int[N];
|
||||||
int[] B = new int[N];
|
int[] s1 = new int[N];
|
||||||
A[0] = 0;
|
int[] sell = new int[N];
|
||||||
B[0] = -prices[0];
|
int[] s2 = new int[N];
|
||||||
|
s1[0] = buy[0] = -prices[0];
|
||||||
|
sell[0] = s2[0] = 0;
|
||||||
for (int i = 1; i < N; i++) {
|
for (int i = 1; i < N; i++) {
|
||||||
A[i] = Math.max(A[i - 1], B[i - 1] + prices[i] -fee);
|
buy[i] = Math.max(sell[i - 1], s2[i - 1]) - prices[i];
|
||||||
B[i] = Math.max(A[i - 1] - prices[i], B[i - 1]);
|
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]);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -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>
|
<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 表示可以经过某个位置,求解从左上角到右下角的最短路径长度。
|
题目描述:0 表示可以经过某个位置,求解从左上角到右下角的最短路径长度。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
public int shortestPathBinaryMatrix(int[][] grids) {
|
public int shortestPathBinaryMatrix(int[][] grids) {
|
||||||
if (grids == null || grids.length == 0 || grids[0].length == 0) {
|
int[][] direction = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}};
|
||||||
return -1;
|
int m = grids.length, n = grids[0].length;
|
||||||
}
|
Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
|
||||||
int[][] direction = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}};
|
queue.add(new Pair<>(0, 0));
|
||||||
int m = grids.length, n = grids[0].length;
|
int pathLength = 0;
|
||||||
Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
|
while (!queue.isEmpty()) {
|
||||||
queue.add(new Pair<>(0, 0));
|
int size = queue.size();
|
||||||
int pathLength = 0;
|
pathLength++;
|
||||||
while (!queue.isEmpty()) {
|
while (size-- > 0) {
|
||||||
int size = queue.size();
|
Pair<Integer, Integer> cur = queue.poll();
|
||||||
pathLength++;
|
int cr = cur.getKey(), cc = cur.getValue();
|
||||||
while (size-- > 0) {
|
grids[cr][cc] = 1; // 标记
|
||||||
Pair<Integer, Integer> cur = queue.poll();
|
for (int[] d : direction) {
|
||||||
int cr = cur.getKey(), cc = cur.getValue();
|
int nr = cr + d[0], nc = cc + d[1];
|
||||||
if (grids[cr][cc] == 1) {
|
if (nr < 0 || nr >= m || nc < 0 || nc >= n || grids[nr][nc] == 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cr == m - 1 && cc == n - 1) {
|
if (nr == m - 1 && nc == n - 1) {
|
||||||
return pathLength;
|
return pathLength + 1;
|
||||||
}
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
queue.add(new Pair<>(nr, nc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. 组成整数的最小平方数数量
|
## 2. 组成整数的最小平方数数量
|
||||||
|
|
|
@ -827,7 +827,7 @@ https://leetcode.com/problems/rank-scores/description/
|
||||||
| 2 | 4.2 | 2 | 2 |
|
| 2 | 4.2 | 2 | 2 |
|
||||||
| 3 | 4.3 | 1 | 1 |
|
| 3 | 4.3 | 1 | 1 |
|
||||||
|
|
||||||
使用连接操作找到某个 score 对应的大于等于其值的记录:
|
使用连接操作找到某个 score 对应的大于其值的记录:
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -890,7 +890,7 @@ ORDER BY
|
||||||
| score | Rank |
|
| score | Rank |
|
||||||
| :---: | :--: |
|
| :---: | :--: |
|
||||||
| 4.2 | 1 |
|
| 4.2 | 1 |
|
||||||
| 4.2 | 1 |
|
| 4.2 | 2 |
|
||||||
| 4.1 | 2 |
|
| 4.1 | 2 |
|
||||||
|
|
||||||
连接情况如下:
|
连接情况如下:
|
||||||
|
|
|
@ -1021,7 +1021,7 @@ g/re/p(globally search a regular expression and print),使用正则表示式
|
||||||
|
|
||||||
```html
|
```html
|
||||||
$ grep [-acinv] [--color=auto] 搜寻字符串 filename
|
$ grep [-acinv] [--color=auto] 搜寻字符串 filename
|
||||||
-c : 统计匹配到行的个数
|
-c : 统计个数
|
||||||
-i : 忽略大小写
|
-i : 忽略大小写
|
||||||
-n : 输出行号
|
-n : 输出行号
|
||||||
-v : 反向选择,也就是显示出没有 搜寻字符串 内容的那一行
|
-v : 反向选择,也就是显示出没有 搜寻字符串 内容的那一行
|
||||||
|
@ -1039,7 +1039,7 @@ $ grep -n 'the' regular_express.txt
|
||||||
18:google is the best tools for search keyword
|
18:google is the best tools for search keyword
|
||||||
```
|
```
|
||||||
|
|
||||||
示例:正则表达式 a{m,n} 用来匹配字符 a m\~n 次,这里需要将 { 和 } 进行转义,因为它们在 shell 是有特殊意义的。
|
示例:正则表达式 a{m,n} 用来匹配字符 a m\~n 次,这里需要将 { 和 } 进行转移,因为它们在 shell 是有特殊意义的。
|
||||||
|
|
||||||
```html
|
```html
|
||||||
$ grep -n 'a\{2,5\}' regular_express.txt
|
$ grep -n 'a\{2,5\}' regular_express.txt
|
||||||
|
|
|
@ -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)
|
- [67. 把字符串转换成整数](67.%20把字符串转换成整数.md)
|
||||||
- [68. 树中两个节点的最低公共祖先](68.%20树中两个节点的最低公共祖先.md)
|
- [68. 树中两个节点的最低公共祖先](68.%20树中两个节点的最低公共祖先.md)
|
||||||
|
|
||||||
|
# 参考文献
|
||||||
|
|
||||||
|
何海涛. 剑指 Offer[M]. 电子工业出版社, 2012.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)是一颗二叉树,并且每个节点的值都大于等于其左子树中的所有节点的值而小于等于右子树的所有节点的值。
|
||||||
|
|
||||||
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
|
```java
|
||||||
@Override
|
@Override
|
||||||
|
@ -354,11 +354,11 @@ private Node put(Node x, Key key, Value value) {
|
||||||
|
|
||||||
最好的情况下树是完全平衡的,每条空链接和根节点的距离都为 logN。
|
最好的情况下树是完全平衡的,每条空链接和根节点的距离都为 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。
|
在最坏的情况下,树的高度为 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()
|
## 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
|
```java
|
||||||
public void deleteMin() {
|
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
|
```java
|
||||||
public void delete(Key key) {
|
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 查找树的所有空链接到根节点的距离应该是相同的。
|
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. 插入操作
|
## 1. 插入操作
|
||||||
|
|
||||||
|
@ -530,11 +530,11 @@ private List<Key> keys(Node x, Key l, Key h) {
|
||||||
|
|
||||||
- 如果插入到 2- 节点上,那么直接将新节点和原来的节点组成 3- 节点即可。
|
- 如果插入到 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- 节点。
|
- 如果是插入到 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. 性质
|
## 2. 性质
|
||||||
|
|
||||||
|
@ -546,7 +546,7 @@ private List<Key> keys(Node x, Key l, Key h) {
|
||||||
|
|
||||||
红黑树是 2-3 查找树,但它不需要分别定义 2- 节点和 3- 节点,而是在普通的二叉查找树之上,为节点添加颜色。指向一个节点的链接颜色如果为红色,那么这个节点和上层节点表示的是一个 3- 节点,而黑色则是普通链接。
|
红黑树是 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
|
```java
|
||||||
public class RedBlackBST<Key extends Comparable<Key>, Value> extends BST<Key, Value> {
|
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
|
```java
|
||||||
public Node rotateLeft(Node h) {
|
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
|
```java
|
||||||
public Node rotateRight(Node h) {
|
public Node rotateRight(Node h) {
|
||||||
|
@ -613,7 +613,7 @@ public Node rotateRight(Node h) {
|
||||||
|
|
||||||
一个 4- 节点在红黑树中表现为一个节点的左右子节点都是红色的。分裂 4- 节点除了需要将子节点的颜色由红变黑之外,同时需要将父节点的颜色由黑变红,从 2-3 树的角度看就是将中间节点移到上层节点。
|
一个 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
|
```java
|
||||||
void flipColors(Node h) {
|
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
|
```java
|
||||||
@Override
|
@Override
|
||||||
|
@ -756,7 +756,7 @@ public class Transaction {
|
||||||
|
|
||||||
对于 N 个键,M 条链表 (N>M),如果哈希函数能够满足均匀性的条件,每条链表的大小趋向于 N/M,因此未命中的查找和插入操作所需要的比较次数为 \~N/M。
|
对于 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. 线性探测法
|
## 3. 线性探测法
|
||||||
|
|
||||||
|
@ -765,7 +765,7 @@ public class Transaction {
|
||||||
使用线性探测法,数组的大小 M 应当大于键的个数 N(M>N)。
|
使用线性探测法,数组的大小 M 应当大于键的个数 N(M>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
|
```java
|
||||||
public class LinearProbingHashST<Key, Value> implements UnorderedST<Key, Value> {
|
public class LinearProbingHashST<Key, Value> implements UnorderedST<Key, Value> {
|
||||||
|
@ -867,7 +867,7 @@ public void delete(Key key) {
|
||||||
线性探测法的成本取决于连续条目的长度,连续条目也叫聚簇。当聚簇很长时,在查找和插入时也需要进行很多次探测。例如下图中 2\~4 位置就是一个聚簇。
|
线性探测法的成本取决于连续条目的长度,连续条目也叫聚簇。当聚簇很长时,在查找和插入时也需要进行很多次探测。例如下图中 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] 之间。
|
α = N/M,把 α 称为使用率。理论证明,当 α 小于 1/2 时探测的预计次数只在 1.5 到 2.5 之间。为了保证散列表的性能,应当调整数组的大小,使得 α 在 [1/4, 1/2] 之间。
|
||||||
|
|
||||||
|
|
|
@ -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>
|
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/eb859228-c0f2-4bce-910d-d9f76929352b.png"/> </div><br>
|
||||||
|
|
||||||
## 3. 最近未使用
|
## 3. 最近未使用
|
||||||
|
|
||||||
> NRU, Not Recently Used
|
> NRU, Not Recently Used
|
||||||
|
@ -89,7 +88,7 @@
|
||||||
|
|
||||||
NRU 优先换出已经被修改的脏页面(R=0,M=1),而不是被频繁使用的干净页面(R=1,M=0)。
|
NRU 优先换出已经被修改的脏页面(R=0,M=1),而不是被频繁使用的干净页面(R=1,M=0)。
|
||||||
|
|
||||||
## 4. 先进先出
|
## 4. 先进先出
|
||||||
|
|
||||||
> FIFO, First In First Out
|
> FIFO, First In First Out
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user