LeetCode 003 Longest Substring Without Repeating Characters

题目


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


思路


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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值