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

给定一个字符串,请找出其中无重复字符的最长子字符串。

样例

例如,在"abcabcbb"中,其无重复字符的最长子字符串是"abc",其长度为 3

对于,"bbbbb",其无重复字符的最长子字符串为"b",长度为1



public class Solution {
     
/** 遍历该字符串,每遍历一个字母时,利用map去找该字母最近一次出现是什么时候
* 中间这一段便是无重复字符的字符串。
* 算法思想:两次循环得到所有的子串,用hash判断是否重复。


代码
代码中需要注意的地方:
1.以字符对应的ASCII码作为hash值,visit[str[i]]=0,说明str[i]这个字符还没有出现过,=1说明有重复。
2.在每次内层循环重新开始的时候,都要将visit初始化为0,每次内层循环求的是str[i...j]之间的最长子串,要判断他们之间是否有重复,所以要确保i...j这个范围内的visit都没初始化为0了,否则出现i...j之间的字符和这个范围之外的字符重复就会导致结果出错。




用一个256个元素的整形数组表示一个字符串中是否含有某个字符。
a~b分别映射到数组元素0~25。
用两个指针分别指向字符串的第一个和第二个元素,用第二个指针从左往右扫描字符串。
每扫描一个字符,根据数组中对应的值来判断这个字符是否已经出现。
如果没出现,则继续扫描,同时更新已知不相同子串的最大长度。
如果出现过,那么向右移动第一个指针,直到刚才重复的那个字符不再重复,然后继续上面的工作。
http://www.cnblogs.com/haozhengfei/p/d0906ebc98f7b6eaecb3ecd738dc78ac.html
     */
    public int lengthOfLongestSubstring(String A){
        
    }
    public int lengthOfLongestSubstring(String A) {
        if(A == null || A.length() == 0)return 0;
        //map 统计A中每种字符之前出现的位置
        Map<Character, Integer> map = new HashMap<Character, Integer>();
        //len代表以s[i-1]结尾的情况下,最长无重复子串的长度
        int[] len = new int[A.length()];
        char[] charArr = A.toCharArray();
        //从头到尾遍历charArr,统计出以每个字符为当前位置的向前最长无重复子串的长度
        for(int i=0; i<A.length(); i++){
            Integer lastPosOfChar = map.get(charArr[i]);//获取键对应的值,即下标
            if(lastPosOfChar == null){//说明当前字符第一次出现
                //更新最长无重复子串的长度
                len[i] =  i == 0 ? 1 : len[i-1] + 1;
                //map记录当前字符出现的位置,即存入
                map.put(charArr[i], i);
            }
            else{//当前字符不是第一次出现(既然不是第一次出现,那也不是在第一个位置),也就是之前出现过该字符
                //获取前一个字符最长无重复子串的长度
                int aPos = lastPosOfChar + 1;
                int unRepeatLen = len[i-1];
                int bPos = i - unRepeatLen;
                if(aPos >= bPos){
                    //当前位置的最长无重复子串长度
                    len[i] = i - aPos + 1;
                }
                else{
                    //当前位置的最长无重复子串长度
                    len[i] = i - bPos + 1;
                }
                //跟新当前字符出现的位置
                map.put(charArr[i], i);
            }
        }
        //遍历len,最大值即为所求
        int max = len[0];
        for(int i: len) if(i > max) max = i;
        return max;
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值