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标记位置<数组标记位置

猜你喜欢

转载自www.cnblogs.com/tingxilin/p/11911435.html