3-无重复字符的最长子串

题目:

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

示例 1:

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters

解答:

方法一:

首先想到的是用两个迭代器iter iter2,看iter2所指向的字符是否存在于[iter,iter2]substring中,使用的是string的find_first_of

时间复杂度:O(n²)

int lengthOfLongestSubstring(string s)
{
    if (s.length() == 0 || s.length()==1)
    {
        return s.length();
    }
    int maxLen = -1;
    int len = 0;
    auto iter = s.begin();
    auto iter2 = s.begin();
    for (; iter != s.end(); iter++)
    {
        iter2 = iter + 1;
        while (iter2 != s.end())
        {
            string subStr = s.substr(iter-s.begin(), iter2 - iter);
            auto pos = subStr.find_first_of(*iter2);
            if (pos == string::npos)//iter2已经存在在之前的subStrle,则continue
            {
                len = iter2 - iter+1;
                if (len > maxLen)
                {
                    maxLen = iter2 - iter + 1;
                }
                iter2++;
                //cout << "maxLen:" << maxLen << endl;
            }
            else
            {
                len = iter2 - iter;//找到了,则iter++
                if (len > maxLen)
                {
                    maxLen = len;
                }
                //cout << "maxLen2:" << maxLen << endl;
                break;
            }
        };
    }

    return maxLen;
}

提交后,所占内存、运行时间都只超过5%,暴力遍历效果较差。

方法二:

  • 使用类似于hashmap的方式,
  • string可以通过s[i]访问第i个字符
  • 上面的查找用的find_first_of,太慢了

  string每个字符是一个char,而char的范围为0-127,因此创建一个char[128] map来存储所有出现的字符,以s[i]作为key,如果存在则map[s[i]]++,如果map[s[j]]的值>1则表示出现了多次,即存在重复的字符。

  使用两个索引滑动窗口,满足条件的不重复长度为:j-i+1

代码如下:

int lengthOfLongestSubstring3(string s)
{
    if (s.size() < 2)
    {
        return s.size();
    }

    int maxLen = 0;
    char map[130] = { 0 };
    int i = 0, j = 0;
    for (; j < s.length(); j++)
    {
        map[s[j]]++;    //将第j个字符放到数组中;
        while (map[s[j]] > 1)
        {
            map[s[i]]--;    //i向右移动
            i++;
        }
        if (j - i + 1 > maxLen)
        {
            //cout << "maxLen:" << maxLen << endl;
            //cout << "i j :" << j - 1 + i << endl;
            maxLen = j - i + 1;
        }
    }
    return maxLen;
}

提交结果:

总结:

  1.感觉leetcode提交后,运行时间的排名不准,同样的代码提交几次,排名差别有百分几的浮动。

  2.同样的问题,不同的代码的运行效率及内存占用差别还是很巨大的;

  3.现在工作时,只注意完成功能,从来没有考虑到代码效率问题,而且没有代码审核环境,提高很慢;

  4.闲着也是闲着,还是坚持刷题吧 ;

 

posted @ 2020-09-28 15:20  adfas  阅读(147)  评论(0编辑  收藏  举报