leetcode3 无重复字符的最长子串

解法1:暴力法

解题步骤:

①找出字符串中的所有子串:两层循环实现

②判断子串中是否有重复字符:set实现

遍历子串,如果set中有该字符,则返回false,否则返回true

#include<iostream>
#include<set>
#include<string>
using namespace std;
class Solution{
public:
    int lengthOfLongestSubstring(string s){
        int n = s.length();
        int count=0;
        for(int i=0;i<n;++i){
            for(int j=i+1;j<=n;++j){
                if(allUnique(s,i,j)){
                    if(count<j-i)
                        count = j-i;
                }
            }
        }
        return count;
    }
    bool allUnique(string s, int start, int end){
        set<char> set;
        for(int i=start; i<end; ++i){
            if(set.count(s[i]) != 0){
                return false;
            }
            set.insert(s[i]);
        }
        return true;
    }
};

int main(){
    Solution solution;
    string s;
    cin>>s;
    int num;
    num = solution.lengthOfLongestSubstring(s);
    cout<<num<<endl;
    return 0;
}

 解法2:滑动窗口法

在本题中窗口表示不含重复字符的子串,用res表示最大不重复子串的长度。

为了计算滑动窗口的长度,我们用left表示窗口的左边界,窗口的右边界就是当前遍历到的字符。

如何判断字符重复出现?我们需要记录字符和它出现位置的映射。我们用一个256位大小的数组来代替哈希表表示字符最后出现的位置。该数组初始化全为0,表示所有字符都还没出现过。然后不断滑动窗口右边界,观察右边界对应的字符是否出现过,也即判断left是否需要更新。若数组中该字符对应的位置为0,则表示该字符从未出现过,left不变。若数组中该字符对应的位置不为0,说明该字符之前出现过,但是这个重复字符有可能在滑动窗口内部也有可能在滑动窗口左边。则接下来判断该字符是否在滑动窗口内部,若该字符的位置大于left,则表示该字符在滑动窗口内部,则移动left至重复字符处。若该字符的位置小于left,则表示该字符不在滑动窗口内部,无需更新left。

滑动窗口每次向右滑动一个字符,对应的数组中字符位置更新为i+1,然后比较res和滑动窗口的大小决定是否更新res。

class Solution{
public:
    int lengthOfLongestSubstring(string s){
        int m[256] = {0}, res = 0, left = 0;
        for(int i=0;i<s.size();++i){
//            if(m[s[i]] == 0 || m[s[i]] < left){
//                res = max(res, i-left+1);
//            }
//            else{
//                left = m[s[i]];
//            }
//            m[s[i]] = i+1;
////精简写法
            left = max(left, m[s[i]]);
            m[s[i]] = i+1;
            res = max(res, i-left+1); 
        }
        return res;
    }
}; 

解法2.2: 滑动窗口法
使用了HashMap建立字符和其最后出现位置之间的映射,其他操作同上

class Solution{
public:
    int lengthOfLongestSubstring(string s){
        int res=0, left=0;
        unordered_map<char, int> m;
        for(int i=0;i<s.size();++i){
            left = max(left, m[s[i]]);
            m[s[i]] = i+1;
            res = max(res, i-left+1);
        } 
        return res;
    }
}; 

 

posted @ 2019-06-04 14:10  松花酿酒春水煎茶  阅读(192)  评论(0编辑  收藏  举报