C++双指针滑动和利用Vector实现无重复字符的最长子串—力扣算法

题目:

力扣原题链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

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

示例 1:

输入: "abcabcbb"

输出: 3 

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

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

输入: "pwwkew"

输出: 3

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



 解题:

方法一:利用vector容器
执行用时 :20 ms, 在所有 cpp 提交中击败了66.62%的用户
内存消耗 :9.6 MB, 在所有 cpp 提交中击败了85.78%的用户
方法二:双指针滑动
执行用时 :4 ms, 在所有 cpp 提交中击败了99.47%的用户
内存消耗 :9 MB, 在所有 cpp 提交中击败了95.92%的用户

方法一:
对每一个传入字符串的字符与vector中的所有内容进行比较,无重复则将字符存入vector末尾,有重复则先更新不重复字符串最大值mlen,再将vector中的重复字符即其之前的内容删掉,返回mlen。

vector的erase函数删除向量中[first,last)中元素:iterator erase(iterator first,iterator last)。注意参数是iterator类型,不能用数值。应使用vector的一个函数:iterator begin()。返回向量头指针,指向第一个元素。

vector的相关内容可参考:https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int n=s.length();
        vector<char>str;
        int mlen=0;
        //扫描string s
        for(int i=0;i<n;i++){
            char c = s[i];
            //扫描vector str
            for(int m=str.size()-1;m>=0;m--){
                if(c==str[m]){
                    //更新mlen
                    if(mlen<str.size())
                        mlen = str.
                    //删除重复字符及其之前的字符。用vector的begin()函数控制删除区间
                    str.erase(str.begin(),str.begin()+m+1);
                    break;
                }
            }
            str.push_back(c);
        }
        if(mlen<str.size())
            mlen=str.size();
        return mlen;
    }
};

方法二:
在s的字符数量大于等于2个的时候,用头指针、尾指针指针分别指向s的开头和其开头+1,扫描两指针之间的字符并与尾指针进行对比,根据对比情况移动指针。
这期间只有两种情况,1:范围[头,尾)之间有跟尾字符重复的字符;2:没有。
遇到情况1时,更新最大长度mlen,头指针指向重复字符的后一位置,尾指针后移一位,继续扫描对比。
遇到情况2时,头指针不动,尾指针后移,继续。

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int length=s.length();
        //字符串长度为0、1时直接返回数字,双指针没有地方指。
        if(!length)
            return 0;
        if(length==1)
            return 1;
        //头指针p,最大长度mlen至少为1。
        int p=0,mlen=1;
        //尾指针end
        for(int end=1;end<length;end++){
            for(int aim=p;aim<end;aim++){
                //情况1
                if(s[aim]==s[end]){
                    //更新头指针p
                    p=aim+1;
                    //更新最大长度mlen
                    if(mlen<(end-aim))
                        mlen=end-aim;
                    break;
                }
            }
            //情况2。要算上尾指针所以+1。
            if(mlen<end-p+1)
                mlen=end-p+1;
        }
        return mlen;
    }
};

猜你喜欢

转载自www.cnblogs.com/foxer-z/p/11687281.html