Java 最长的子字符串,超过了时间限制
给定一个字符串,查找最长子字符串的长度,不重复字符。例如,“abcabcbb”不重复字母的最长子字符串是“abc”,其长度为3。对于“bbb”,最长的子字符串是“b”,长度为1Java 最长的子字符串,超过了时间限制,java,string,algorithm,Java,String,Algorithm,给定一个字符串,查找最长子字符串的长度,不重复字符。例如,“abcabcbb”不重复字母的最长子字符串是“abc”,其长度为3。对于“bbb”,最长的子字符串是“b”,长度为1 public static int lengthOfLongestSubstring(String s) { if (s.length()==0) return 0; int maxlen = 1; HashMap<Character, ArrayList<Integ
public static int lengthOfLongestSubstring(String s) {
if (s.length()==0)
return 0;
int maxlen = 1;
HashMap<Character, ArrayList<Integer>> check = new HashMap<Character,ArrayList<Integer>>();
for (int i = 0; i < s.length(); i++) {
for (int j = i; j < s.length(); j++) {
if (!check.containsKey(s.charAt(j))) {
ArrayList<Integer> value= new ArrayList<>();
value.add(j);
check.put(s.charAt(j), value);
}
else {
maxlen = Math.max(j - i, maxlen);
ArrayList<Integer> temp = check.get(s.charAt(j));
i=temp.get(temp.size()-1);
// get the last index(biggest index) of the key value
check.clear();
break;
}
if(j==s.length()-1) {
maxlen = Math.max(j - i + 1, maxlen);
}
}
}
return maxlen;
}
}
public static int lengthOfLongestSubstring(字符串s){
如果(s.length()==0)
返回0;
int maxlen=1;
HashMap check=新建HashMap();
对于(int i=0;i
对于长可重复字符串的最后一次测试,超出了时间限制。不知道如何优化。寻求改进,谢谢这个问题可以用O(N)来解决,其中N是字符串的长度 算法: 1) 迭代字符串中的字符。跟踪每个字符的最后一次出现。在每个信件商店,前一个相同的字符离我们有多远。 例如:使用字符串“abccdae”,我们将得到列表[1,2,3,1,5,5,7]。请注意,如果字符在我们将其设置为单词开头的长度之前没有出现 2) 让我们调用我们得到的列表V(在示例V=[1,2,3,1,5,5,7]) 3) 定义函数f(x),它计算不重复以索引x结尾的字符的最长单词 它认为: f(0)=0 f(x)=min(f(x-1)+1,V[x]),x>0 4) 迭代word并在每个索引处计算f 5) 求f的最大值 每一步都是O(N),但如果你到处玩,你可以同时完成所有的步骤,甚至可以不断提高
希望这有帮助。在下面找到一个优化的版本。与初始版本相比的增强功能:
- 它不会创建其他对象
- 它不复制任何字符,它处理字符串数据本身
- 它减少了比较步骤的数量
编辑如Boris所述,仍有可能进行优化。在这里,我将不遵循Donald E.Knuth的观点:“过早优化是万恶之源。”;-) 这里有一个相当简单的解决方案,它应该比您的解决方案更快:
public static int longestNonRepeating(final String s) {
final Set<Character> unique = new HashSet<>();
int max = 0;
for (int i = 0; i < s.length(); ++i) {
final char c = s.charAt(i);
if (!unique.add(c)) {
for (int j = i - unique.size(); j < i; ++j) {
if (s.charAt(j) != c) {
unique.remove(s.charAt(j));
} else {
break;
}
}
}
max = Math.max(max, unique.size());
}
return max;
}
在我们独特的集合中有a
a b c a b c
0 1 2 3 4 5
^
|
i
a b c a b c
0 1 2 3 4 5
^
|
i
a b c a b c
0 1 2 3 4 5
^ ^
| |
j i
在我们独特的集合中有a、b
a b c a b c
0 1 2 3 4 5
^
|
i
a b c a b c
0 1 2 3 4 5
^
|
i
a b c a b c
0 1 2 3 4 5
^ ^
| |
j i
在我们独特的集合中有a、b、c
a b c a b c
0 1 2 3 4 5
^
|
i
a b c a b c
0 1 2 3 4 5
^
|
i
a b c a b c
0 1 2 3 4 5
^ ^
| |
j i
我们尝试将
添加到唯一的
集合
,它是重复的。从唯一子字符串的开头,尝试查找a
。幸运的是,这是在0
,我们不需要从unique中删除任何内容
a b c a b c
0 1 2 3 4 5
^ ^
| |
j i
a b c a b c
0 1 2 3 4 5
^ ^
| |
j i
我们尝试将添加到唯一的集合,它是重复的。从唯一子字符串的开头,尝试查找b
。幸运的是,这是在1
,我们不需要从unique中删除任何内容
a b c a b c
0 1 2 3 4 5
^ ^
| |
j i
a b c a b c
0 1 2 3 4 5
^ ^
| |
j i
我们试图将添加到唯一的集合,它是重复的。从唯一子字符串的开头,尝试查找c
。幸运的是,这是在1
,我们不需要从unique中删除任何内容
a b c a b c
0 1 2 3 4 5
^ ^
| |
j i
a b c a b c
0 1 2 3 4 5
^ ^
| |
j i
我们完成了。最长的唯一子串是
3
这里是一个具有时间复杂性的解决方案O(n)
。由于两个原因,它可能比其他解决方案更快
字符串
末尾时,将不同连续字符链的长度与当前最大值进行比较字符串
有许多不同的字符,它会占用大量内存
public static int subStringLength(final String s) {
final Map<Character, Integer> indices = new HashMap<>();
int max = 0;
int start = 0;
final int length = s.length();
for (int i = 0; i < length; i++) {
Integer k = indices.put(s.charAt(i), i);
if (k != null && k >= start) {
max = Math.max(max, i - start);
start = k + 1;
}
}
return Math.max(max, length - start);
}
public static int subStringLength(最终字符串s){
最终映射索引=新的HashMap();
int max=0;
int start=0;
最终整数长度=s.长度();
for(int i=0;i=start){
max=Math.max(max,i-start);
开始=k+1;
}
}
返回Math.max(max,length-start);
}
你到底想计算什么?您代码中的一些注释可能会有所帮助,并且标题有误。如果您不对代码进行注释或描述输入和输出,您希望我们如何确定此代码应该做什么。我想我们可能会猜到,但这远远不够。为什么最长的不可重复
字符串是3
?这里的逻辑是什么?还不清楚。最大的不可重复字符串始终是完整字符串。但这一切与超出时间限制有什么关系?时间限制是多少?你可以修改hasNoDupeChars的代码,一旦发现重复的代码,就返回。你也应该重用集合
@boristesspider,在fail fast
旁边,我在建议的解决方案中没有做任何其他更改。当人们滥用Knuth引用时,这是我最讨厌的事情之一。这不是Knuth的意思。懒惰的编码从来没有借口。至少在再次使用它之前阅读。@Boristeider