题意整理
- 给定一个大小为n的字符串数组。
- 找出字符串数组中原根的个数。
- 给定一个字符串,其他任何字符串都不是它的前缀,则称为原根。
方法一(暴力法)
1.解题思路
直接遍历整个字符串数组,然后将当前字符串,与所有其他字符串进行比较,只要其他字符串中有一个是它的前缀,就不是原根,原根标记置为false。每次都判断原根标记是否为true,如果为true,则计数加一。
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @param s string字符串一维数组
* @return int整型
*/
public int solve (int n, String[] s) {
//初始化计数变量
int cnt=0;
for(int i=0;i<n;i++){
//判断是否是原根
boolean originRoot=true;
for(int j=0;j!=i&&j<n;j++){
//如果某个字符串能在s[i]第一个位置找到,说明是s[i]的前缀
if(s[i].indexOf(s[j])==0){
originRoot=false;
}
}
//如果所有其他字符串都是s[i]的前缀,则s[i]是原根
if(originRoot){
cnt++;
}
}
return cnt;
}
}3.复杂度分析
- 时间复杂度:假设每个字符串的长度是m,indexOf()的时间复杂度是
,总共需要判断
次,所以最终的时间复杂度是
,其中
是所有字符串的长度之和。
- 空间复杂度:需要额外常数级别的内存空间,所以空间复杂度是
。
方法二(字典树)
1.解题思路
首先将所有字符串插入字典树,通过字典树存储每个节点访问次数。然后检查每个字符串,如果字符串对应路径上所有节点访问次数等于1,或者字符串对应路径上所有节点访问次数大于1,则这个字符串是原根。
动图展示:
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param n int整型
* @param s string字符串一维数组
* @return int整型
*/
public int solve (int n, String[] s) {
//初始化字典树
Trie trie=new Trie();
for(int i=0;i<n;i++){
//往字典树中插入字符串
trie.insert(s[i]);
}
int res=0;
for(int i=0;i<n;i++){
//判断某个字符串是否是原根
if(trie.originRoot1(s[i])||trie.originRoot2(s[i])){
res++;
}
}
return res;
}
}
class Trie{
//子节点数组
Trie[] child;
//子节点访问次数
int cnt;
Trie(){
this.child=new Trie[26];
this.cnt=0;
}
public void insert(String s){
//从根节点开始遍历
Trie node=this;
for(char c:s.toCharArray()){
//如果为空,就新建节点
if(node.child[c-'a']==null){
node.child[c-'a']=new Trie();
}
//往子节点方向遍历
node=node.child[c-'a'];
//访问次数加一
node.cnt++;
}
}
//字符串所有节点访问次数大于1(比如["a","ab","ba"]中的"a")
public boolean originRoot1(String s){
Trie node=this;
for(char c:s.toCharArray()){
node=node.child[c-'a'];
if(node.cnt!=1){
return false;
}
}
return true;
}
//字符串所有节点访问次数等于1(比如["a","ab","ba"]中的"ba")
public boolean originRoot2(String s){
Trie node=this;
for(char c:s.toCharArray()){
node=node.child[c-'a'];
if(node.cnt==1){
return false;
}
}
return true;
}
} 3.复杂度分析
- 时间复杂度:假设
是所有字符串的长度之和,字典树中插入的节点个数最多为
,每次插入和检查的时间复杂度都是对应字符串的长度,所以时间复杂度是
。
- 空间复杂度:需要额外大小为
的空间存储节点,而每个节点还自带一个child数组(数组大小为26),所以空间复杂度是
。

京公网安备 11010502036488号