[英]why is this algorithm so slow?
Given a string, find the first non-repeating character in it and return it's index. 给定一个字符串,找到它中的第一个非重复字符并返回它的索引。 If it doesn't exist, return -1. 如果它不存在,则返回-1。
s = "leetcode" return 0. s =“leetcode”返回0。
s = "loveleetcode", return 2 s =“loveleetcode”,返回2
This is my solution, simple and easy to understand. 这是我的解决方案,简单易懂。 However, on LeetCode it reports as "Time exceeds limit", which means it is too slow. 但是,在LeetCode上,它报告为“时间超出限制”,这意味着它太慢了。 This is a O(n^2) solution. 这是一个O(n ^ 2)解决方案。
public int firstUniqChar(String s) {
if(s==null || s.isEmpty() ){
return -1;
}
if(s.length()==1){
return 0;
}
char[] ss = s.toCharArray();
int size = s.length();
HashSet<Character> repeats = new HashSet<Character>();
for(int i=0; i<size; i++){
for(int j=i+1; j<size; j++){
if(repeats.contains(ss[i])){
continue;
}
if(ss[i]==ss[j]){
repeats.add(ss[i]);
break;
}
}
if(!repeats.contains(ss[i])){
return i;
}
}
return -1;
}
However, another version seems to be even slower, not judged as "time exceeds limit", as below: 然而,另一个版本似乎更慢,不被判断为“时间超过限制”,如下所示:
static int firstUniqChar(String s) {
if(s==null || s.isEmpty() ){
return -1;
}
if(s.length()==1){
return 0;
}
char[] ss = s.toCharArray();
int size = s.length();
for(int i=0; i<size; i++){
boolean unique = true;
for(int j=i+1; j<size; j++){
if(ss[i]==ss[j]){
unique = false;
break;
}
}
if(unique){
for(int j=0; j<i; j++){
if(ss[i]==ss[j]){
unique = false;
break;
}
}
}
if(unique){
return i;
}
}
return -1;
}
Don't do an inner loop. 不要做内循环。 Trade space for time and keep track of which characters are unique or not as you traverse the string one time . 交易时间空间,并在您遍历字符串一次时跟踪哪些字符是唯一的。
public static int firstUniqChar(String s) {
if(s==null || s.isEmpty() ){
return -1;
}
if(s.length()==1){
return 0;
}
Map<Character, Integer> uniqueCharacterMap = new LinkedHashMap<Character, Integer>();
Set<Character> nonuniqueCharacterSet = new HashSet<Character>();
for ( int i=0; i<s.length();i++) {
Character c = s.charAt(i);
if ( nonuniqueCharacterSet.contains(c) ) {
// character has already been determined to repeat
} else if ( uniqueCharacterMap.containsKey(c) ) {
uniqueCharacterMap.remove(c); // It's not unique
nonuniqueCharacterSet.add(c);
} else {
// so far, it is unique.
uniqueCharacterMap.put(c, i);
}
}
System.out.println(uniqueCharacterMap.toString());
Iterator<Map.Entry<Character, Integer>> i = uniqueCharacterMap.entrySet().iterator();
if ( i.hasNext() ) {
Map.Entry<Character, Integer> e = i.next();
return e.getValue();
}
return -1;
}
public static void main(String[] args) {
System.out.println("firstUniqChar(leetcode) = " + firstUniqChar("leetcode"));
System.out.println("firstUniqChar(loveleetcode) = " + firstUniqChar("loveleetcode"));
System.out.println("firstUniqChar(aaabbbccc) = " + firstUniqChar("aaabbbccc"));
}
A simple two-pass order(n) pseudo-code algorithm (for strings consisting just the character range 'a' to 'z') might be something like 一个简单的两遍(n)伪代码算法(对于只包含字符范围'a'到'z'的字符串)可能类似于
CharFrequency = array [a..z] of integer
for c in InputString do
inc(CharFrequency[c])
i = 0
while (i < Length(InputString)) and (CharFrequency[InputString[i]] <> 1) do
inc(i)
if (i < Length(InputString))
print(i)
else
print(-1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.