LEETCODE(力扣) 3. 无重复字符的最长子串(c语言实现)

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

示例 1:

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

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

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

int lengthOfLongestSubstring(char* s) {
    char *start,*end,*p;
    int length=1,max=1;
    start=s;
    end=s;
    p=s;
    if(*s=='\0')return 0;
    while(*(end+1)!='\0'&&*(start+1)!='\0')
    {
        if(start==end)
        {
            if(*(end+1)!=*start&&*(end+1)!='\0')
            {
                end++;
                length++;
            }
            else if(*(start+1)!='\0')
            {
                start++;
                end++;
                p=start;
            }
        }
        else
        {
            p=start;
            while(p<=end&&start!=end)
            {
                if(*(end+1)!=*p&&*(end+1)!='\0')
                {
                    p++;
                    
                }
                else
                {
                    if(*(p+1)!='\0')start=p+1;
                    end=start;
                    length=1;
                }
                
            }
            if(start!=end)
            {
                length++;
                if(*(end+1)!='\0')end++;
            }
           
           
        }
        if(length>max)max=length;
    }

    return max;
}

结果一塌糊涂

现思路:
使用两个指针划定已验证区域,选择区域右方第一个字符,并对区域内字符遍历比较,非重复字符则区域扩大一个,继续选择右方字符进行遍历,且记录最大区域值。
遇到重复字符时,区域左区间、右区间移到p右方一个字符处,重新进行遍历。
如此重复,直到遍历完整个字符组。
该思路差在每次更新区间,原区间在p之后已遍历的字符都得重新进行遍历。

标准解答:
采用哈希表记录每一次字符的出现
参考标准答案后的解答:

int lengthOfLongestSubstring(char* s) {
    char *start;
    int length=0,max=0;
    bool check[128]={0};
    start=s;
    while(*s!='\0')
    {
    	if(check[*s]!=1)
    	{
    		check[*s]=1;
    		length++;
		}
		else
		{
          check[*start]=0;
			if(*start==*s)start++;//窗口内与窗口外的重复字符相邻
			while(check[*s]==1&&start<s)
			{
				start++;
				check[*start]=0;
				length--;
			}
			if(*start==*s&&start!=s)start++;//窗口右边又连续的字符与窗口内字符重复
			check[*s]=1;
		}
		if(length>max)max=length;
		s++;
	    
	}

    return max;
}


时间上效果不错,但还是不如标准解答简洁。

posted @ 2025-03-03 17:07  Osen  阅读(55)  评论(0)    收藏  举报