leetcode题解系列-002 无重复最长子串长度

首先,老原则,先直接上代码。

//
// Created by tannzh on 2020/6/11.
//
/*

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
 */

#include <iostream>
#include <string>
#include <unordered_map>
#include <algorithm>

using namespace std;

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        size_t region = 0, start = 0;
        unordered_map<char, size_t> trace;
        for(size_t i = 0; i < s.size(); ++i){
            auto found = trace.find(s[i]);
            if(found != trace.end() && found->second >= start) {
                region = std::max(region, i - start);
                start = found->second + 1;
            }

            trace[s[i]] = i;
        }

        return std::max(region, s.size() - start);
    }
};

int main(int argc, char **argv)
{
    Solution s;
    std::string testStr1 = "abcabcbb";
    std::string testStr2 = "bbbbb";
    std::string testStr3 = "pwwkew";

    std::cout << testStr1 << ", lengthOfLongestSubstring: " << s.lengthOfLongestSubstring(testStr1) << std::endl;
    std::cout << testStr2 << ", lengthOfLongestSubstring: " << s.lengthOfLongestSubstring(testStr2) << std::endl;
    std::cout << testStr3 << ", lengthOfLongestSubstring: " << s.lengthOfLongestSubstring(testStr3) << std::endl;

    return 0;
}

解题思路

leetcode题解系列-002 无重复最长子串长度

 

首先,求的只是长度,那么一定有一个 trace 来边记录边比较(max)。

其次,没有重复字符几乎是唯一条件,那么检查重复显然用 k-v mapping.

最后,要考虑一次迭代过程中,如何度量这个长度。

设 substr 的起点为 start(s), 终点为 last(l). 每一次迭代,记录一张索引表。

leetcode题解系列-002 无重复最长子串长度

 

上图所示,last 指向 `a`, 查询当前表可知,`a` 的位置记录在案,且 `pos >= start`. 故此刻诞生一个 substr. 长度为 `last - start`. s 更新位置为 `pos + 1`.
有:

auto found = cache.find(s[last]);
if (found != cache.end() && found->second >= start) {
    region = max(region, last - start);
    start = found->second + 1;
}
cache[s[last]] = last;

注意最终还需要比较一次,返回 max(ret, s.size() - start)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值