LeetCode Hot100-03

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

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

解题思路:

假设字符串为:abcdefghijk
1、最简单的,用暴力搜索法:遍历整个字符串,列举出所有的组合[ab、abc、abcd、...abcdefghijk]、
[bc、bcd、...bcdefghijk],遍历列举所有的组合,时间复杂度是O(N^2)。
再判断每个组合,不含重复字符的最长子串的长度,需要遍历该组合,时间复杂度是O(N)。
所以,暴力搜索法的总时间复杂度是O(N^3),差不多是会被面试官直接打死的效率。

2、利用动态规划的思路来处理:
我们记f(k)是已求解出的第k个字符,不含有重复字符的最长长度。
那么取出第k+1个字符,计算该字符上次出现的位置与当前位置的距离差,记为d。
a:如果字符从未出现过或d>f(k),则表示该字符没有出现在f(k)中,那么第f(k+1)=f(k)+1。
b:如果d<=f(k),那么k+1字符,出现在f(k)中,则此时f(k+1)=d。

举例来说就是:
a:对于字符串abcgeg,第一个字符g对应的f(g)=4,接下来取出字符e,字符e之前没有出现过,所以f(e)=f(g)+1=5。
b:接着取出第二个字符g:因为g之前出现过了,那么计算2个字符g的距离差d=2,所以第二个f(g)=2。

源码:

int lengthOfLongestSubstring(string s) {
        int curLength = 0;
        int maxLength = 0;
        int *prePos = new int[128];    // 记录128个字符,上次出现在字符串中的idx;
        for(int i=0;i<128;++i)
        {
            prePos[i] = -1;
        }

        // 遍历字符串;
        for(int j=0;j<s.length();++j)
        {
            int preIdx = prePos[s[j]-' '];  // 该字符上次出现的位置;
            if(preIdx<0 || j-preIdx>curLength){
                ++curLength;    // 没有出现在当前最长的字符串f(i-1)中
            }else{
                maxLength = curLength>maxLength?curLength:maxLength;
                curLength = j - preIdx;
            }

            prePos[s[j]-' '] = j;
        }
        maxLength = curLength>maxLength?curLength:maxLength;
        delete[] prePos;
        return maxLength;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值