剑指 Offer 48. 最长不含重复字符的子字符串

20 篇文章 2 订阅

剑指 Offer 48. 最长不含重复字符的子字符串

请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。

 示例 1:
输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

思路: 利用双指针,并开辟一个数组,对每个字符的出现进行统计,当字符出现次数大于1时,重新开始统计,直到遍历完字符串

前指针prev,后指针cur,prev不动,cur向后走,边走边统计字符个数,统计方法:arr[*cur]++。当发现某个字符个数大于1时,计算该段子串长度: cur-prev。随后prev要指向该段子串中与 *cur相同的字符的后面一个位置,再继续进行统计

以字符串"pwwkew"为例(图中手误arr多弄了个’w’的统计):

第一步:先将’p’统计为1,cur指向’w’,prev指向第一个字符’p’,将’w’的数量加1,‘p’ != ‘w’,cur向后走

image-20210818113619379

image-20210818113816103

第二步:cur指向’w’,判断’w’的个数已经>1了,计算该段字符串长度为cur - prev = 2,prev指向"pw"字符串的’w’的后面那个位置

image-20210818114012839

prev改变位置,将’p’, 'w’的个数置0,再把cur指向的元素置1,从该位置开始统计,cur向后走

image-20210818114233304

第三步:cur指向’k’,将 'k’的个数加1,cur向后走

image-20210818114857222

第四步:cur指向’e’,将’e’的个数加1,cur向后走

image-20210818114936286

第五步:

cur指向’w’,将’w’的个数加1,'w’的个数已经超过1了,计算长度:cur - prev = 3,更新最大长度为3,prev跳到"wke"中’w’的后面,cur向后走,重新进行统计

image-20210818115028519

此时cur已经遍历完字符串了,再统计一次长度cur - prev = 3,不用更新,所以最大长度就为3

记得开辟一个128大小的arr来统计字符,因为远不止小写字母需要统计👀:

image-20210818115426545

代码:

int lengthOfLongestSubstring(char* s){
    if (*s == '\0')//空字符串
    return 0;
    
    int *judge = (int*)calloc(127, sizeof(int));//并不只有小写字母,所有字符都可能出现
    judge[*s] = 1;//先统计首字符
    int maxlength = 1;//最小长度为1,所以先把最大长度置为1
    char*prev = s;
    char*cur = s + 1;//sur直接指向第二个字符

    while (*cur != '\0')
    {

        judge[*cur]++;//统计该字符
        if (judge[*cur] > 1)//有重复的字母
        {
            if (maxlength < (cur - prev))//更新最大长度
            {
                maxlength = cur - prev;
            }
            while (*prev != *cur)//找到中间这串中与*cur相同的那个字符的位置
            {
                //把该位置之前的字符统计置为0
                judge[*prev] = 0;
                prev++;
            }
            //找到之后再++,跳过这个位置
            prev++;

            judge[*cur] = 1;//并把当前元素重新统计为1,重新向后计算
        }

        cur++;
    }

    if (maxlength < (cur - prev))//当cur指向'\0'时,也要再进行最后的统计
        {
            maxlength = cur - prev;
        }

    return maxlength;
}
  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WoLannnnn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值