C++编程-leetcode-无重复字符的最长字串

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

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

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

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

提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成

思路:
这道题首先讲一下暴力破解,也就是最冗余的方式,以所有位置的字符分别作起点,遍历一遍,每一次选定一个起点,都向后遍历,遍历到每一个字符,都判断当前长度的字符串是不是重复字符串,如果不是则继续增加,如果是则返回。
而这种情况在数据量特别大的时候当然不可能使用,复杂度有点高。外层遍历是O(n^2) ,遍历一个字符又有一个判断是否重复,那就是O(n),整体就是O(n^3) .

那么我们可以怎么去优化呢?
我们可以借鉴寻找最长字串的方法,也就是动态规划,记录下当前相应的状态,依次遍历数组,每遍历一个都修改相应的状态,以供下次遍历的参考。具体做法如下:
1.
我们使用map结构,使用char和int的对应关系。我们需要使用below(char,int),记录下某个字符的下标,再有has(char,bool),记录下某个字符是否已经遍历。
2.
我们依次遍历数组,遍历到一个字符时,判断是否遍历过,如果没有,那就修改遍历过,并且修改below的该字符下标为1,判断当前长度是否超过最大长度,超过则修改最大长度的记录。

代码如下:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s=="")
        {
            return 0;
        }
        int length=s.size();
        int start=0;
        int max=0;
        int final_max=max;
        map<char,int> below;
        map<char,bool> has;
        for(int i=0;i<128;i++)
        {
            char a=i;
            below.insert(pair<char,int>(a,-1));
            has.insert(pair<char,bool>(a,false));
        }
        for(int i=0;i<length;i++)
        {
            if(has[s[i]]==false)
            {
                below[s[i]]=i;
                has[s[i]]=true;
                max++;
                if(max>final_max)
                {
                    final_max=max;
                }
            }
            else
            {
                int t=below[s[i]];
                below[s[i]]=i;
                for(int j=start;j<t;j++)
                {
                    has[s[j]]=false;
                    below[s[j]]=-1;
                    max--;
                }
                start=t+1;

            }
        }
        return final_max;
       
    }

};

你可能感兴趣的:(C++编程,C++编程-leetcode)