[leetcode]3. longest substring without repeating characters

知识点:

  • But look up in hash table should be amortized O(1)O(1) time as long as the hash function was chosen carefully.
  • hashmap相交map set hashset,查找速度是最快的
  • 滑动窗口 :第一次接触到这个名词是tcp协议那里。就是i,j一头一尾,使j能尽量向右滑动,不满足,则j不动,i删去最左边一个,j继续向右
  • 接口的多态:“一个接口,多个类” set=new hashset() set=new treeset就是这个意思。

我这个弱鸡,第一反应总是暴力解法,然后超时gg了

class Solution {
    public int lengthOfLongestSubstring(String str) {
       
        char[] longsub=new char[str.length()];
        char[] s=str.toCharArray() ;
            
        int k=0,count=0,longcount=0;
        
        for(int m=0;m<str.length()&&(str.length()-m)>=longcount;m++){
            char[] sub=new char[str.length()];
            sub[0]=s[m];
            k=0;
            count=1;
            for(int i=m+1;i<str.length();i++){
                int flag=0;
                for(int j=0;j<=k;j++){
                    if(s[i]==sub[j]){
                        
                        flag=1;
                        break;
                    }
                     
                }
                
                if(flag==0){
                    sub[++k]=s[i];
                    count++;
                    System.out.println(count);
                    System.out.println(s[i]);
                }
                else{
                    
                    break;
                }
            }
            if(count>=longcount){
                longcount=count;
                longsub=sub; 
                        for(int q=0;q<sub.length;q++)
                         System.out.println("***"+sub[q]);
            }
            
            
        }
        
        return longcount;
    }
}

然后换hash表,确实快了,然后testcase又tle gg了

class Solution {
    public int lengthOfLongestSubstring(String str) {
       
        char[] longsub=new char[str.length()];
        char[] s=str.toCharArray() ;
            
        int k=0,count=0,longcount=0;
        
        for(int m=0;m<str.length()&&(str.length()-m)>=longcount;m++){
           // char[] sub=new char[str.length()];
           HashMap<String,Integer> sub=new HashMap();
            
            //sub[0]=s[m];
            sub.put(String.valueOf(s[m]),0);
            k=0;
            count=1;
            for(int i=m+1;i<str.length();i++){
                int flag=0;
                
                    if(sub.containsKey(String.valueOf(s[i]))){
                        
                        flag=1;
                        break;
                    }
                     
                
                
                if(flag==0){
                   // sub[++k]=s[i];
                    sub.put(String.valueOf(s[i]),++k);
                    count++;
                    System.out.println(count);
                    System.out.println(s[i]);
                }
                else{
                    
                    break;
                }
            }
            if(count>=longcount){
                longcount=count;
               // longsub=sub; 
                   //     for(int q=0;q<sub.length;q++)
                     //    System.out.println("***"+sub[q]);
            }
            
            
        }
        
        return longcount;
    }
}

然后我开始看答案了,思路完全是一样的啊,都是两个for循环

hashmap的查找比hashset的还更快,为啥我的还更慢一些呢?

答案1(O(N3)):

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length();
        int ans = 0;
        for (int i = 0; i < n; i++)
            for (int j = i + 1; j <= n; j++)
                if (allUnique(s, i, j)) ans = Math.max(ans, j - i);
        return ans;
    }

    public boolean allUnique(String s, int start, int end) {
        Set<Character> set = new HashSet<>();
        for (int i = start; i < end; i++) {
            Character ch = s.charAt(i);
            if (set.contains(ch)) return false;
            set.add(ch);
        }
        return true;
    }
}

看完答案,想了很久,发现自己代码太冗余了,忘记了character这个数据类型,然后删掉了一些打印的和无意义的代码,答案一跑55ms,我下面这一版只要6ms,开心死了(尽管还是暴力解法,但是我动脑子了啊)

自己的改进暴力解法(时间复杂度为O(N2))如下:

class Solution {
    public int lengthOfLongestSubstring(String str) {
        char[] longsub=new char[str.length()];
        char[] s=str.toCharArray() ;
        int k=0,count=0,longcount=0;
        
        for(int m=0;m<str.length()&&(str.length()-m)>=longcount;m++){
            HashMap<Character,Integer> sub=new HashMap();
            sub.put(s[m],0);
            k=0;
            count=1;
            
            for(int i=m+1;i<str.length();i++){
                int flag=0;
                    if(sub.containsKey(s[i])){
                        flag=1;
                        break;
                    }
                
                if(flag==0){
                    sub.put(s[i],++k);
                    count++;
                }
                else{
                    break;
                }
            }
            if(count>=longcount){
                longcount=count;
            }
            
        }
        
        return longcount;
    }
}

再看了答案二(滑动窗口+set),才发现,自己的方法实际上就类似滑动窗口,但是我是用了一个外循环来表示起点,用set更快。如下:

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int i=0,j=0,count=0;
        Set<Character> set=new HashSet<Character>() ;
        
        while(i<s.length()&&j<s.length()){
            if(!set.contains(s.charAt(j))){
                set.add(s.charAt(j));
                count=Math.max(j-i+1,count);
                j++;
            }
            else{
                set.remove(s.charAt(i));
                i++;
            }
        }
        return count;
    }
}

答案三(优化了的滑动窗口)
虽然我的代码没有标准答案简洁,但是思路更加符合自己的。

public class Solution {
    public int lengthOfLongestSubstring(String s) {
        int i=0,j=0,count=0;
        Map<Character,Integer> map=new HashMap<>() ;
        
        while(i<s.length()&&j<s.length()){
            if(!map.containsKey(s.charAt(j))){
                map.put(s.charAt(j),j);
                
            }else{
                i=Math.max(map.get(s.charAt(j))+1,i);
                map.put(s.charAt(j),j);
            }
            
            count=Math.max(j-i+1,count);
            j++;

        }
        return count;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_36869329/article/details/83722194