LeetCode-无重复字符的最长子串

无重复字符的最长子串

首先:写了2小时写出来的垃圾算法

	
     public static int lengthOfLongestSubstring(String s) {      
        char t[] = s.toCharArray();
        int count = 0;
        int max =0;
        
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        Map<Integer, Integer> map2 = new HashMap<Integer, Integer>();  //核心
        for(int i =0;i<s.length();i++) {
        	if(map.get(t[i]-'a')==null) {
        		map.put(t[i]-'a',i);
        		map2.put(i,t[i]-'a');
        		count++;
        		
        		if(count>max) {
        			max = count;
        		}

        		
        	}else {
        		
        		count = i-map.get(t[i]-'a');  //核心
        		System.out.println(map.get(t[i]-'a'));
        		int k = map.get(t[i]-'a');											
        		int temp = -1;   //核心清理
        		for(int j =0; j<=k ;j++) {
        			if(map2.get(j)!=null) {
        				temp = map2.get(j);
            			map.remove(temp);
            			map2.remove(j);
            			map.put(t[i]-'a',i);
            			map2.put(i,t[i]-'a');
            			
        			}
        			temp = -1;
        		}
        	}
        	System.out.println(count+"---"+i+"--"+t[i]);
        }
    	System.out.println("--------------");
        return max;
    }



看了大神的解析,发现这就是一个滑动窗口问题:

什么是滑动窗口?

其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!

如何移动?

我们只要把队列的左边的元素移出就行了,直到满足题目要求!

一直维持这样的队列,找出队列出现最长的长度时候,求出解!

还有一个最坑的地方 hashmap :

如果重复添加的话,hashmap会自动覆盖key一样的数据,保证一个key对应一个value

public static int lengthOfLongestSubstring3(String s) {      
    int n = s.length(), ans = 0;
    Map<Character, Integer> map = new HashMap<>();
    for (int end = 0, start = 0; end < n; end++) {
        char alpha = s.charAt(end);
        if(map.get(alpha)!=null) {
            start = Math.max(map.get(alpha), start);  		
        }

        map.put(s.charAt(end),end+1);
        ans = Math.max(ans, end+1-start);
    }
    return ans;
}

自己修改自己的代码:

class Solution {
    public int lengthOfLongestSubstring(String s) {
          char t[] = s.toCharArray();
        int count = 0;
        int max =0;
        
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();

        for(int i =0;i<s.length();i++) {
        	if(map.get(t[i]-'a')==null) {
        		count++;
        		if(count>max) {
        			max = count;
        		}
        	}else {	
        		if(map.get(t[i]-'a')<i-count) {  //滑动窗口最前端以前的不用管了
        			count++;
        			if(count>max) {
            			max = count;
            		}
        		}else {
        			count = i-map.get(t[i]-'a');  //核心  滑动		
        		}							
        	}
    		map.put(t[i]-'a',i);
        }
        return max;
    }
}

总结:

  1. 没有把问题抽象为滑动窗口问题;
  2. 没有意识到hashmap可以这样覆盖。
posted @ 2019-12-28 01:00  逆风微笑的魔法师  阅读(90)  评论(0)    收藏  举报