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

Posted aaaaaaaWoLan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 48. 最长不含重复字符的子字符串相关的知识,希望对你有一定的参考价值。

剑指 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向后走

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

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

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

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

第五步:

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

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

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

代码:

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;
}

以上是关于剑指 Offer 48. 最长不含重复字符的子字符串的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

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

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