词典中最长的单词
思路: dfs+前缀树,在前缀树上做dfs,出口是某节点的end值为0,沿途节点的end值都大于0
class Solution {
public String ans="";// 这个居然不能声明成static类型!!!
public class TrieNode{
public int pass;
public int end;
public TrieNode[] nexts;
public TrieNode(int p,int e){
pass=p;
end=e;
}
public TrieNode(){
nexts=new TrieNode[26];
}
}
public class Trie{//前缀树
public TrieNode root;
public Trie(){
root=new TrieNode();
}
public void add(String s){
if(s==""||s==null)return;
TrieNode cur=root;
cur.pass++;
for(int i=0;i<s.length();++i){
if(cur.nexts[s.charAt(i)-'a']==null){
cur.nexts[s.charAt(i)-'a']=new TrieNode();
}
cur.nexts[s.charAt(i)-'a'].pass++;
cur=cur.nexts[s.charAt(i)-'a'];
}
cur.end++;
}
}
public void dfs(TrieNode root,TrieNode x,String path){
//System.out.println(path);
if(ans.equals(""))ans=path;
else if(ans.length()<path.length()){
ans=path;
}
else if(ans.length()==path.length()){
ans=(ans.compareTo(path)<=0?ans:path);
}
for(int i=0;i<26;++i){
if(x.nexts[i]!=null&&x.nexts[i].end>0){
dfs(root,x.nexts[i],path+(char)('a'+i));
}
}
}
public String longestWord(String[] words) {
Trie trie=new Trie();
for(String s:words){
trie.add(s);
}
dfs(trie.root,trie.root,"");
return ans;
}
}
前缀树结构实现
import java.util.*;
public class Solution {
/**
*
* @param operators string字符串二维数组 the ops
* @return string字符串一维数组
*/
public static class TrieNode{
public int p;
public int e;
public HashMap<Character,TrieNode>nextNodes;
public TrieNode() {
p=0;
e=0;
nextNodes=new HashMap<>();
}
}
public static class TrieTree{//前缀树结构
public TrieNode root;
//添加字符串,可重复添加
public TrieTree() {
root=new TrieNode();
}
public void insert(String word) {
if(word==null) {
root.p++;
return;
}
TrieNode cur=root;
cur.p++;
char[] chs=word.toCharArray();
for(int i=0;i<chs.length;++i) {
if(!cur.nextNodes.containsKey(chs[i])) {
cur.nextNodes.put(chs[i], new TrieNode());
}
cur=cur.nextNodes.get(chs[i]);
cur.p++;
}
cur.e++;
}
//查询word在字典树中出现过几次(完整的出现过,前缀式不算)
public int search(String word) {
if(word==null) {
return root.p;
}
TrieNode cur=root;
char[] chs=word.toCharArray();
for(int i=0;i<chs.length;++i) {
if(!cur.nextNodes.containsKey(chs[i])) {
return 0;
}
cur=cur.nextNodes.get(chs[i]);
}
return cur.e;
}
//返回以字符串pre作为前缀的单词数量
public int prefixNumber(String pre) {
if(pre==null)return root.p;
TrieNode cur=root;
char[] chs=pre.toCharArray();
for(int i=0;i<chs.length;++i) {
if(!cur.nextNodes.containsKey(chs[i])) {
return 0;
}
cur=cur.nextNodes.get(chs[i]);
}
return cur.p;
}
//删除word,如果word添加过多次,仅删除一次
public void delete(String word) {
if(search(word)==0) {
return;
}
TrieNode cur=root;
char[] chs=word.toCharArray();
for(int i=0;i<chs.length;++i) {
if(cur.nextNodes.get(chs[i]).p==0) {
cur.nextNodes.put(chs[i], null);
}
cur.p--;
cur=cur.nextNodes.get(chs[i]);
}
cur.e--;
}
}
public String[] trieU (String[][] operators) {
ArrayList<String>list=new ArrayList<>();
TrieTree root=new TrieTree();
for(int i=0;i<operators.length;++i){
switch(operators[i][0]){
case "1":{
root.insert(operators[i][1]);
break;
}
case "2":{
root.delete(operators[i][1]);
break;
}
case "3":{
if(root.search(operators[i][1])!=0)list.add("YES");
else list.add("NO");
break;
}
case "4":{
list.add(root.prefixNumber(operators[i][1])+"");
break;
}
}
}
String[] ans=new String[list.size()];
int k=0;
for(String s:list){
ans[k++]=s;
}
return ans;
}
}
最大子数组异或和
import java.util.Scanner;
public class Main {
public static class Node{
public Node[] nexts;
public Node() {
nexts=new Node[2];
}
}
public static class PreTree{//前缀树结构
public Node head=new Node();
public int maxEor(int[] arr) {
int max=Integer.MIN_VALUE;
int res=0;
add(0);
for(int i=0;i<arr.length;++i) {
res^=arr[i];//res: 0~i异或和
//[k..i]=[0..i]^[0..k-1]
max=Math.max(max, getMaxSubArray(res));
// System.out.println(getMaxSubArray(res));
add(res);
}
return max;
}
public void add(int x) {
Node cur=head;
for(int move=31;move>=0;--move) {
int path=(x>>move)&1;
if(cur.nexts[path]==null) {
cur.nexts[path]=new Node();
}
cur=cur.nexts[path];
}
}
public int getMaxSubArray(int res) {
Node cur=head;
int ans=0;
for(int move=31;move>=0;--move) {
int path=(res>>move)&1;
int best=(move==31?path:(path^1));
best=(cur.nexts[best]==null?(best^1):best);
ans|=((best^path)<<move);
cur=cur.nexts[best];
}
return ans;
}
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int[] arr=new int[n];
for(int i=0;i<n;++i) {
arr[i]=scan.nextInt();
}
PreTree pt=new PreTree();
System.out.println(pt.maxEor(arr));
}
}