LeetCode刷题记录6-查找字符串的最长串

题目

Given a string, find the length of the longest substring without repeating characters.

Examples:

Given “abcabcbb”, the answer is “abc”, which the length is 3.

Given “bbbbb”, the answer is “b”, with the length of 1.

Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.

滑动窗口法

滑动窗口是数组/字符串问题中常用的抽象概念。窗口是数组/字符串中通常由开始和结束索引定义的一系列元素,即[i,j)。滑动窗口是将其两个边界“滑”到某个方向的窗口。例如,如果我们滑动[i,j)区间1个元素,然后它成为[i + 1,j + 1)(左闭,右开),只需要根据一定条件移动这个元素即可。

int lengthOfLongestSubstring(string s)
{
    int len = s.size();
    list<char> tempString;
    int res = 0, i = 0, j = 0;
    while (i < len && j < len)
    {
        if (std::find(tempString.begin(), tempString.end(), s.at(j)) == tempString.end())
        {
            tempString.push_back(s.at(j));
            j++;    //j为快速移动
            res = std::max(res, j - i);
        }
        else
        {
            tempString.pop_front();
            i++;
        }
    }
    return res;
}

最坏的情况下每个元素都将被访问2次。

优化滑动窗口法

其实我们没有任何必要让i来每次进行递增操作,我们只需要移动j即可。
我们可以用一个容器来记录每个值的最大index。这样我们在移动的时候每当在容器发现重复的值记录其index即可。

int lengthOfLongestSubstring_(string s)
{
    int len = s.size(), res = 0;
    unordered_map<char, int> map; // value => max index
    for(int j = 0, i = 0; j < len; ++j)
    {
        if(map.find(s.at(j)) != map.end())
        {
            i = std::max(map[s.at(j)], i);  //i => max index
        }
        res = std::max(res, j - i + 1);
        //tip : error
        //map.insert(std::make_pair(s.at(j), j + 1));
        map[s.at(j)] = j + 1;
    }
    return res;
}

同样的道理使用桶算法也可以实现该效果,桶算法原理基本和map的使用是一个道理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值