• 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.闲着也是闲着,还是坚持刷题吧 ;

  • 相关阅读:
    Delphi 与 DirectX 之 DelphiX(10): TPictureCollectionItem.StretchDraw 绘制到指定矩形
    Delphi 与 DirectX 之 DelphiX(11): TPictureCollectionItem.DrawAdd、DrawSub
    Delphi 与 DirectX 之 DelphiX(13): TPictureCollectionItem.DrawRotate
    Delphi 与 DirectX 之 DelphiX(8): 第一个简单动画
    上周热点回顾(10.2210.28)
    如果云计算
    网站已恢复正常,让大家久等了
    上周热点回顾(10.1510.21)
    10.24,今天是程序员节,祝大家节日快乐
    园豆兑换阿里云代金券 体验阿里云云服务器
  • 原文地址:https://www.cnblogs.com/zyk1113/p/13744896.html
Copyright © 2020-2023  润新知