• leetcode每日刷题计划--day57


    Num 3 无重复的最长子串

    最简单做法:暴力二重循环,tle

    优化:只走一次,每次两个标记左右,如果出现重复的,把left调整到第一个不重复的位置,每次得出的子串和最长的比较

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            if(!s.length()) return 0;
            int left=0;
            int ans=1;
            for(int i=1;i<s.length();i++)
            {
                int j=i-1;
                while(j>=left && s[j]!=s[i])
                    j--;
                left=j+1;
                ans=max(ans,i-left+1);
            }
            return ans;
        }
    };
    View Code

    这样的优化本质上还是二重循环,仅仅比原来的暴力二重循环省略了一部分过程。

    偶然发现自己很久之前写过一个、方法差不多,用的ascii对应bool直接判断有无重复,时间更短内存近似

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            int len=s.length();
            int first,end;
            int ans=0;
            int now=0;
            first=0;
            int i,j;
            end=0;
            bool pd[300];
            memset(pd,0,sizeof(pd));
            for(i=0;i<len;i++)
            {
                if(pd[s[i]]==false)
                {
                    now++;
                    end++;
                    pd[s[i]]=true;
                    //cout<<"do1"<<s[i]<<" "<<first<<" "<<end<<endl;
                }
                else
                {
                    if(now>ans)
                        ans=now;
                    while(s[first]!=s[i])
                    {
                        pd[s[first++]]=false;
                        now--;
                    }
                    first++;
                    now--;
                    now++;
                    end++;
                    pd[s[i]]=true;
                     //cout<<"do2"<<s[i]<<" "<<first<<" "<<end<<endl;
                }
            }
            if(now>ans)
                ans=now;
            return ans;
        }
    };
    View Code

     注意空字符串的处理过程

    最上面的代码是用的滑窗法,但是寻找重复的过程还是要找一遍,用map也是一样的。

    在很久以前写的这个里面,用bool省略了一部分查询过程,只需要在发现重复的时候回去找。

    为了更快,可以直接用int数组标记出现位置,节省查询时间。

    map更适合范围更大的东西,如果范围明确用数组更合适。这里面限制了都是数组,开够ascill对应的字符就ok。数组是o(1),map是o(logN),向上面的直接查询是o(n)

    总结

    基础优化<很久前写的bool标记有无<map标记位置<数组标记位置

    class Solution {
    public:
        int lengthOfLongestSubstring(string s) {
            int a[200];
            if(!s.length())
                return 0;
            int ans=1;
            int left=0;
            memset(a,-1,sizeof(a));
            for(int i=0;i<=s.length()-1;i++)
            {
                if(a[s[i]]==-1)
                {
                    a[s[i]]=i;
                }
                else
                {
                    ans=max(ans,i-left);
                    for(int j=left;j<a[s[i]];j++)
                        a[s[j]]=-1;
                    left=a[s[i]]+1;
                    a[s[i]]=i;
                }
            }
            int temp=s.length()-1-left+1;
            ans=max(ans,temp);
            return ans;
        }
    };
    View Code

    最终优化版

    时间才能证明一切,选好了就尽力去做吧!
  • 相关阅读:
    ADO.NET的记忆碎片(四)
    ADO.NET的记忆碎片(八)
    卡特兰数 应用
    hdu 1249 三角形
    hdu 1143
    nyist 93 汉诺塔(三)
    hdu 1123 Train Problem II
    hdu 1133 Buy the Ticket
    hdu 1022 Train Problem I
    nyist 610 定长覆盖
  • 原文地址:https://www.cnblogs.com/tingxilin/p/11911435.html
Copyright © 2020-2023  润新知