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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/abc15766228491/article/details/82316331

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

示例 1:

输入: “abcabcbb”
输出: 3
解释: 无重复字符的最长子串是 “abc”,其长度为 3。

示例 2:

输入: “bbbbb”
输出: 1
解释: 无重复字符的最长子串是 “b”,其长度为 1。

示例 3:

输入: “pwwkew”
输出: 3
解释: 无重复字符的最长子串是 “wke”,其长度为 3。
请注意,答案必须是一个子串,”pwke” 是一个子序列 而不是子串。

这道题算是入门的算法题了。。。。这道题都看了这么久,多谢 大神博客 提点,哎,菜是原罪。。。

下面说下大概思路

本题就是采取划窗机制,首先要一个map(或者其他的方法)保存每个字符出现过的位置,然后,设置一个头指针,就是左边界位置,然后向后遍历这个字符串,如果这个字符串中的字符没出现过,就保持这个左边界的位置不变,然后继续向后遍历,如果这个字符出现过,就把这个字符的位置拿出来看下,如果位置是在左边界的左边,则不用管,如果是在左边界的右边,就说明这个字符在左边界的后边出现过,现在又出现了一次,那就把左边界移动到上一次出现这个字符的位置,每次都更新这个长度(i-left+1)最后的结果就是最长的长度了。

coding 1:利用map

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        string str(s);
        map<char, int> m_c_i;
    for (int i = 0; i < str.length(); ++i) {
        //初始化这个map
        m_c_i[str[i]] = 0;
    }
    int left=0, result=0;
    for (int i = 0; i < str.length(); ++i) {
        if(m_c_i[str[i]]==0 || m_c_i[str[i]]<left){
            //如果没出现过这个字符(值为0),或者上次出现的位置在left左侧,那么就计数
            result = max(result, i-left+1);
        }else{
            //出现在left的右侧,则,更新left
            left = m_c_i[str[i]];
        }
        //更新这个字符出现的位置
        m_c_i[str[i]] = i+1;
    }
        return result;
    }
};

coding 2: 利用长度为256的数组保存,因为ascii最多表示256个字符,这种方法比上面的方法快一点点

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        string str(s);
        int point[256]={0}, result=0, left=0;
    for (int i = 0; i < str.length(); ++i) {
        if(point[str[i]]==0 || point[str[i]]<left){
            result = max(result, i-left+1);
        }else{
            left = point[str[i]];
        }
        point[str[i]]=i+1;
    }
        return result;
    }
};

coding 3:因为看到上面每次都在赋值,就想,干脆在变left的时候在赋值吧,可是事实是速度变慢了。。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        string str(s);
        int point[256]={0}, result=0, left=0, exam=0;
    for (int i = 0; i < str.length(); ++i) {
        if(point[str[i]]==0 || point[str[i]]<left){
            exam++;
        }else{
            result = max(result, exam);
             //这个地方一定要注意,exam是暂时存放这轮的长度的参数,不能每次都设为1,要从截断的地方计数,
            //比如:dvdf在检测到第二个d时,这里如果exam初始化为1,那么结果就是2了,因为v的长度没有算
            //所以更新的时候要用i-point[str[i]]+1就是用d的位置减去上一个d的位置,再检测f即可
            exam=i-point[str[i]]+1;
            left = point[str[i]];
        }
        point[str[i]]=i+1;
    }
    result = max(result, exam);
        return result;
    }
};

猜你喜欢

转载自blog.csdn.net/abc15766228491/article/details/82316331