算法-无重复字符的最长子串

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

示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3。

给定 "bbbbb" ,最长的子串就是 "b" ,长度是1。

给定 "pwwkew" ,最长子串是 "wke" ,长度是3。请注意答案必须是一个子串,"pwke" 是 子序列 而不是子串。

思路:

  1. 从字符串第一个元素起,从左到右获取子串。
  2. 每前进一个字符(下标为j),就在当前子串中查找是否存在与当前字符重复的字符,如果存在(重复字符的下标为i),那么能确定一个包含不重复字符的子串,其长度为j - i 对比已存储的最大长度并把两者的最大值存储。
  3. 现在下一个子串的起点为当前重复的字符下标j.重复执行2、3操作,直到最后一个字符。

其实这是滑动窗口的思路。左闭右开。

int lengthOfLongestSubstring(char* s) {
    int len = strlen(s);
    //长度为0 的情况的处理
    if(len == 0) return 0;
    int max = 1;
    int statrIndex = 0;
    for (int i = 1; i < len; i ++) {
        char subStr = s[i];
        for(int j = statrIndex; j <i; j ++)
        {
            char ssubStr = s[j];
            //如果找到重复字符串
            if (subStr == ssubStr ) {
                if (max < i  - statrIndex) {
                    max = i  - statrIndex;
                }
                statrIndex = j + 1;
                break;
            }
        }
        //长度没添加一位,更新最大值
        if (max < i + 1 - statrIndex) {
            max = i + 1 - statrIndex;
        }
    }
    return max;
}
复制代码

其他解法:

//每个字符都有唯一字符串ASCII的作为唯一标识,这是个技巧性问题。最多256个
int lengthOfLongestSubstring(char* s) {
    //算法:用book标记出现过的字符的index,用max标记最大长度,用start标记当前不重复开始的index,用num表示当前不重复的个数
    //遍历数组,若book[]大于start,说明遇到相同元素,则从其相同处重新计算长度和起始位置
    if(NULL == s)
        return NULL;
    int len=strlen(s);
    int book[255]={0};
    //memset(book,0xff,255*sizeof(int));//将book初始化为-1
    if (0==len)
        return 0;
    int start=0,max=0;//max_start=0;
    int num=0;
    for (int i=0;i<len;i++)
    {
        if(book[s[i]]==0 || book[s[i]]<start+1)
        {
            num++;
            if(num>max)
            {
                //max_start=start;
                max=num;
            }
            book[s[i]]=i+1;
        }
        else
        {
            start=book[s[i]];
            num=i-start+1;
            book[s[i]]=i+1;
        }
    }
    return max;
}
复制代码
//写得好屌啊
int lengthOfLongestSubstring(char* s) {
    int len=0;
    char *end=s,*temp;
    char* addressTable[128]={NULL};
    while(*end){
        temp = addressTable[*end];
        addressTable[*end]=end;
        if(temp>=s){
        len=end-s>len?end-s:len;
        s = temp+1;
        }end++;
    }
    len=end-s>len?end-s:len;
    return len;
}
复制代码

小结:这里又存在查找问题,可以考虑使用哈希Map提高效率。

待完善....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值