Merge remote-tracking branch 'origin/master'

This commit is contained in:
Wen 2022-08-30 22:54:39 +08:00
commit 520c01374e
3 changed files with 174 additions and 0 deletions

View File

@ -140,3 +140,11 @@ eg: [1,3,4,2,5]<br />
2的小数:1<br />
5的小数:1,3,4,2<br />
小数和为:1+1+3+1+1+3+4+2
### 前缀树
1单个字符串中字符从前到后的加到一棵多叉树上 <br />
2字符放在边上节点上有专属的数据项常见的是pass和end值<br />
3样本添加方式每个字符串都从根节点开始加如果没有路就新建如果有路就复用<br />
4添加时沿途节点的pass值加1每个字符串结束时来到的节点end值加1<br />
end值可查某个字符串出现几次,pass值可查以某个字符串为前缀的字符串出现过几次

View File

@ -0,0 +1,57 @@
package algorithm;
/**
* 荷兰国旗问题的划分
* arr[L....R] 以arr[R]作为划分值
* <arr[R]的在左侧 =arr[R]的在中间 >arr[R]的在右侧
*
* @author Wen
* @date 2022/8/8 22:05
*/
public class NetherlandsFlag {
//返回划分过后=arr[R]的数的左边界和右边界
public int[] cal(int[] arr, int L, int R) {
if (L > R) {
return new int[]{-1, -1};
}
if (L == R) {
return new int[]{L, R};
}
int index = 0;
int less = 0;
int large = R;
int num = arr[R];
while (index <= large) {
if (arr[index] == num) {
index++;
continue;
}
if (arr[index] < num) {
int temp = arr[less];
arr[less] = arr[index];
arr[index] = temp;
less++;
index++;
continue;
}
if (arr[index] > num) {
int temp = arr[large];
arr[large] = arr[index];
arr[index] = temp;
large--;
}
}
return new int[]{less , large};
}
public static void main(String[] args) {
NetherlandsFlag netherlandsFlag = new NetherlandsFlag();
int[] source = new int[]{1, 3, 5, 6, 3, 4, 3, 4, 8, 3};
netherlandsFlag.cal(source, 0, 9);
for (int i : source) {
System.out.println(i);
}
}
}

109
src/ds/tree/PrefixTree.java Normal file
View File

@ -0,0 +1,109 @@
package ds.tree;
/**
* @author Wen
* @date 2022/8/22 22:26
*/
public class PrefixTree {
private Node head;
public PrefixTree() {
head = new Node();
}
//将字符串插入前缀树中
public void insert(String str) {
if (str == null) {
return;
}
Node node = head;
node.pass++;
char[] chars = str.toCharArray();
for (char aChar : chars) {
int index = aChar - 'a';//在哪个节点上
if (node.next[index] == null) {
node.next[index] = new Node();
}
node.next[index].pass++;
node = node.next[index];
}
node.end++;
}
//str出现过几次
public Integer search(String str) {
if (str == null) {
return 0;
}
Node node = head;
char[] chars = str.toCharArray();
for (char aChar : chars) {
int index = aChar - 'a';//在哪个节点上
if (node.next[index] == null) {
return 0;
}
node = node.next[index];
}
return node.end;
}
public void delete(String str) {
if (search(str) > 0) {
Node node = head;
node.pass--;
char[] chars = str.toCharArray();
for (char aChar : chars) {
int index = aChar - 'a';//在哪个节点上
if (--node.next[index].pass == 0) {//pass为0后后面节点直接丢弃
node.next[index] = null;
return;
}
node = node.next[index];
}
node.end--;
}
}
//以prefix为前缀的字符串个数
public Integer prefixNumber(String prefix) {
if (prefix == null) {
return 0;
}
Node node = head;
char[] chars = prefix.toCharArray();
for (char aChar : chars) {
int index = aChar - 'a';//在哪个节点上
if (node.next[index] == null) {
return 0;
}
node = node.next[index];
}
return node.pass;
}
class Node {
int pass;
int end;
Node[] next;
public Node() {
this.pass = 0;
this.end = 0;
next = new Node[26];//假设字符串都是26个小写字母
}
}
public static void main(String[] args) {
PrefixTree prefixTree = new PrefixTree();
prefixTree.insert("abc");
prefixTree.insert("abc");
prefixTree.insert("eewd");
prefixTree.insert("adb");
prefixTree.insert("eewd");
prefixTree.insert("abs");
prefixTree.insert("eewd");
System.out.println(prefixTree.search("abc"));
System.out.println(prefixTree.search("eewd"));
System.out.println(prefixTree.prefixNumber("ab"));
}
}