前缀树
1. 前缀树
java
public static class Node1 {
public int pass ; // 经过这个节点就+1
public int end ; // 当这个字符结束时才+1
public Node1[] nexts;
public Node1() {
pass = 0;
end = 0;
nexts = new Node1[26];
}
}java
public void insert(String word) {
if (word == null) {
return;
}
char[] chs = word.toCharArray();
Node1 node = root;
node.pass++;
int index = 0;
for (int i = 0; i < chs.length; i++) { // 从左往右遍历字符
index = chs[i] - 'a'; // 由字符,对应成走向哪条路
if (node.nexts[index] == null) {
node.nexts[index] = new Node1();
}
node = node.nexts[index];
node.pass++;
}
node.end++;
}java
public void delete(String word) {
if (search(word) != 0) {
char[] chs = word.toCharArray();
Node1 node = root;
node.pass--;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (--node.nexts[index].pass == 0) {
node.nexts[index] = null;
return;
}
node = node.nexts[index];
}
node.end--;
}
}java
public int search(String word) {
if (word == null) {
return 0;
}
char[] chs = word.toCharArray();
Node1 node = root;
int index = 0;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (node.nexts[index] == null) {
return 0;
}
node = node.nexts[index];
}
return node.end;
}2. 基数排序
- 借助几个桶按个位 十位 百位排序
- 初始数组[021 , 010 , 111 , 022 , 011 , 012]
- 统计个位上出现的数字有几个 [ 1 , 3 ,2 , 0,0,0,0,0,0,0]
- 处理为前缀和的形式 [1 , 3 , 5 , 6 , 6 ,6 ,6 ,6 ,6 ,6]
- 从右往左进行处理,第一个数各位是2 ,此时<=2的数有5个,那么范围是【0,4】,所以012应该放在 4 这个位置上 , 然后-1,变为 [1 , 3 , 4 , 6 , 6 ,6 ,6 ,6 ,6 ,6]
- 个位排序后,最后结果是[010 , 021 , 111 , 011 ,022 , 012]
java
public static void radixSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
radixSort(arr, 0, arr.length - 1, maxbits(arr));
}
public static int maxbits(int[] arr) { //计算数字有多少位
int max = Integer.MIN_VALUE;
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, arr[i]);
}
int res = 0;
while (max != 0) {
res++;
max /= 10;
}
return res;
}
// arr[L..R]排序 , 最大值的十进制位数digit
public static void radixSort(int[] arr, int L, int R, int digit) {
final int radix = 10;
int i = 0, j = 0;
// 有多少个数准备多少个辅助空间
int[] help = new int[R - L + 1];
for (int d = 1; d <= digit; d++) { // 有多少位就进出几次
// 10个空间
// count[0] 当前位(d位)是0的数字有多少个
// count[1] 当前位(d位)是(0和1)的数字有多少个
// count[2] 当前位(d位)是(0、1和2)的数字有多少个
// count[i] 当前位(d位)是(0~i)的数字有多少个
int[] count = new int[radix]; // count[0..9]
for (i = L; i <= R; i++) { // 计算当前位0-9有多少个数
// 103 1 3
// 209 1 9
j = getDigit(arr[i], d);
count[j]++;
}
for (i = 1; i < radix; i++) { //计算前缀和
count[i] = count[i] + count[i - 1];
}
for (i = R; i >= L; i--) { //
j = getDigit(arr[i], d);
help[count[j] - 1] = arr[i];
count[j]--;
}
for (i = L, j = 0; i <= R; i++, j++) {
arr[i] = help[j];
}
}
}
public static int getDigit(int x, int d) {
return ((x / ((int) Math.pow(10, d - 1))) % 10);
}
阿源的知识库