[面试题] 查找最长不含相同字符的连续子串

题意:由26个小写字母组成的字符串str,在str中查找最长但不含相同字符的连续子串。

1, 由于字符串只由小写字母组成,那么这个连续的字符串最长不会超过26。

2, 由于是连续的子串,那么很容易想到用一个滑动窗口来调整子串的长度,一旦出现重复的字母,那么需要缩小串口,没有出现重复那么可以继续放大。直到重复为止。

3, 现在重要的问题是怎么判定窗口字母是否重复,有两个办法:

       a, 每新进一个字符,就返回去找窗口内的其他字符,看是否重合,如果重合,那么这时候计算窗口的大小,然后把窗口的左侧移动到重复字符的右边。

       b, 利用一个计数器来记录窗口内的各个字符出现的次数,这样只要O(1)的时间就能知道当前这个字符是否出现过,如果出现了,那么字需要记录当前窗口大小,然后移动左边窗口,并把移出窗口的字符对应的计数器减1,直到当前字符不重复了。

总体来看,这整个算法的重点就在怎么判断一个字母在窗口中是否重复出现,而上面提供的两个算法在性能上差异不是太大,当然b方法要略微好于a方法,但是他们在算法复杂度上实际上都是O(N)的,只是系数有些差异。

下面代码实现了方法b

#include<stdio.h>                                                                                            
#include<string.h>
#include<memory.h>


int main( int argc, char **argv)
{
    char s[1024];
    int char_counter[26];
    scanf("%s", s );
    
    int max_length = 0;
    int left = 0;
    int right = 0;

    memset(char_counter, 0, sizeof(char_counter));
    while ( s[right] != 0)
    {
        if( char_counter[s[right] - 'a'] == 1 ) //出现重复的字母了
        {
            if ( max_length < right - left) //记录当前窗口大小
            {
                max_length = right - left;
            }
            while ( char_counter[s[right] - 'a'] == 1 ) //滑动串口左侧,直到字符没有重复
            {
                char_counter[s[left++] - 'a'] --;
            }
        }
        char_counter[s[right++] - 'a'] ++;
    }
    if ( max_length < right - left)
    {
        max_length = right - left;
    }
    printf( "max length = %d\n", max_length );
    return 0;
}                


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值