您的位置:首页 > 职场人生

LeetCode 003 Longest Substring Without Repeating Characters

2014-02-20 10:49 465 查看
题目

找到最长的字串,满足条件,这个字串中没有重复的字符。输出这个字符串的长度。

思路

1 一开始还是要理解题目的意思。我一开始以为统计字符串中所有不相同的字符。ok,那么一个hashmap就能够解决问题。

2 输出wrong后,重新理解了题目。第一个想到的是暴力破解,把每个字串都检查,是否有重复的,然后找到没有重复的最大字串。需要时间O(n^3)

3 重新思考,自己随便写了字符串,自己会怎么找。wlrbbmqmqbhc 从头开始,看到之前没重复的字符就继续,碰到有重复的,就记下之前这个字符串的长度。然后从重复的一样的那个字符后一位重新开始找。这样一来,就把代码的基本逻辑给说清楚了。

4 上面的代码在最下面,空间上用hashmap来记录每次新查找字符串是否出现过,没有出现,就记录字符和相应的下标。如果出现过,把下标+1设为新的开始。这样的算法,最好情况O(n),最差情况O(n2),平均来看也不是线性的。

5 观察到,其实两个重复字符之间我们会重复检查,所以想办法缩减这部分。这样每次,碰到重复的字符,我们不要回去,而是知道在这之前没有重复的字符串长度为多少,继续检查。另外,可以用一个数组代替hashmap。虽然固定256,但是查找起来更加方便。

代码

public class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length()==0){
return 0;
}
int n = s.length();
HashMap<Character,Integer> record = new HashMap<Character,Integer>();
int max=0;
int start =0;
while(start+max<n){
int cur = start;
while(cur<n&&!record.containsKey(s.charAt(cur))){
record.put(s.charAt(cur),cur);
cur++;
}
int tempmax = record.size();
if(tempmax>max){
max= tempmax;
}
if(cur==n){
max=record.size();
break;
}
start = record.get(s.charAt(cur))+1;
record.clear();
}

return max;
}
}


代码更新15.3.15

public class Solution {
public int lengthOfLongestSubstring(String s) {
if(s==null || s.length() ==0){
return 0;
}
int n =s.length();
HashMap<Character,Integer> record = new HashMap<Character,Integer>();
int start = 0;
int maxlength = 0;
for(int i=0;i<n;i++){
char cur = s.charAt(i);
if(!record.containsKey(cur)){
record.put(cur,i);
}
else{
if(record.get(cur)<start){
record.put(cur,i);
}
else{
maxlength = (i-start)>maxlength ? (i-start) : maxlength;
start = record.get(cur)+1;
record.put(cur,i);
}
}
}
return (n-start)>maxlength? (n-start):maxlength;
}
}


根据自己新的思路重新来了一遍,依然用hashMap 来记录字符-坐标。碰到出现过的字符,如果这个字符的坐标小于计算起始点,那么说明这个字符在目前的计算中无用,更新一下就好;如果大于等于计算起始点,说明碰到重复了,那么更新maxlength,同时计算起始点更新为重复的那个点原始坐标后一位,然后把重复的点的目前的坐标记录更新。

这个算法要当心一个细节,循环出去后,有可能没有更新maxlength
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode 面试笔试