我试图解决这个问题: https://leetcode.com / problems / longest-substring-without-repeating-characters /


以下代码在44毫秒内通过了所有测试。

 
 for(int i = 0; i< s.length(); i ++){
 if(!mp.containsKey(s.charAt(i))){
 mp.put(s.charAt(i),i);
 // max = Math.max(max,i-first + 1);
 }
别的{
 if(mp.get(s.charAt(i))+ 1> = first){
 first = mp.get(s.charAt(i))+ 1;
 }
 mp.put(s.charAt(i),i);
 // max = Math.max(max,i-first + 1);
 }
 max = Math.max(max,i-first + 1);
 }



 但以下代码仅在20毫秒内通过了所有测试。


 for(int i = 0; i< s.length(); i ++){
 if(!mp.containsKey(s.charAt(i))){
 mp.put(s.charAt(i),i);
 max = Math.max(max,i-first + 1);
 }
别的{
 if(mp.get(s.charAt(i))+ 1> = first){
 first = mp.get(s.charAt(i))+ 1;
 }
 mp.put(s.charAt(i),i);
 max = Math.max(max,i-first + 1);
 }
 }



 为什么会有这么大的差异?两个样本中的最大值只更改一次,但在if-else语句中更改它的效率远远高于在for循环结束时更改它的效率。这是一个例外,还是我们应该在编码时遵循这个标准?

答案 0 :(得分:1)
简化(不是早期优化,请参见最大!),得到
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
Integer n = mp.get(ch):
if (n != null) {
first = Math.max(first, n + 1);
}
mp.put(ch, i);
max = Math.max(max, i - first + 1);
}
备注原始版本中值i的双重放置。 如果第一个Math.max被替换为if,则代码可能会更快。
很难发表声明w.r.t.为了加速这两个原始版本,也许热点编译器看到了冗余。或者其他什么。
使用mp.putIfAbsent
或类似版本查看java 8版本会很不错,但这可能会让它变慢。