【leetcode】3. 无重复字符的最长子串

3. 无重复字符的最长子串

整体思路: 用一个unorder_map来保存字符串中每个字符所对应的最近一次出现位置,用字符串本身作为map的key

设一个k和i,k用来表示最长子串的起始位置,i用来表示顺序遍历的当前位置,max_len用来保存当前最长子串长度

遍历字符串

如果当前字符没有出现过(map[key] == 0),则置map的value为当前位置i

如果当前字符已经出现过(map[key] != 0),则首先更新max_len,在将k到上一次出现当前重复字符的位置(map[s1[i]])之间的所有字符对应的value值置为0,表示这些字符在新的子串中没有出现过。

注意: 由于第一个节点的位置i==0,无论访问过还是没有访问过,map中第一个字符所对应的value值一直是0,这会产生误解,到底是这个字符没有遍历过所以为0,还是被遍历过设置成了0。为了解决这个问题,在字符串开头设置一个“#”,这是一个除了开头,不会再出现的字符,避免了重复出现无法判断的问题

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int i, k = 1;
        int max_len = 0;
        if(s.length() == 0 || s.length() == 1)
            return s.length();
        string s1 = "#" + s;
        unordered_map<int, int> map;
        
        for(i = 0; i < s1.length(); i++){
            if(map[s1[i]] != 0){
                max_len = max(max_len, i - k);
                for(k; k < map[s1[i]]; k++)
                    map[s1[k]] = 0;
                k = map[s1[k]] + 1;
            }   
            map[s1[i]] = i;
        }
        return max(max_len, i - k); 
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值