学渣带你刷Leetcode-0003.无重复字符的最长子串

引言


今天想写的太多了,废话的开场白不说了。
(1)字符串的输入 gets 和 scanf() 的区别需要注意
(2)两种方法吧
第一种运行复杂数据会超时的暴力方法,最起码可以解决问题,看着让自己还不算是那么没用,思路也算清晰
第二种是滑动窗口算法,看了网上好多大神的教学视频,怎奈天资愚钝,百思不得其解。多亏看了看视频(侵删)

题目描述

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

示例 1:

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

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


白话题目:


一串字符串,找出最长的子串(必须连着的,不是字序列)
 


算法:


字符指针表示字符串首地址,传进来都得获得长度
暴力解法:
(1)长度1,就返回一呗
(2)从i=0头开始,循环往下找到每一个子串,看看这段长度里面是否有重复的
(3)字符串查重方法,借用了一个128位的字符数组存ASCII码

滑动窗口算法:
1. 需要输出或比较的结果在原数据结构中是连续排列的(字符串中的连续不重复子串,数组中的连续元素最大和)
2. 每次窗口滑动时,只需观察窗口两端元素的变化,无论窗口多长,每次只操作两个头尾元素,当用到的窗口比较长时,可以显著减少操作次数

3.L,R指定滑动窗口,R不停的扩大,即将进来的元素是否满足无重复最长子串的条件,不满足的话需要挪动L,之后再挪动R,知道R走完。
打字说明有些捉急,感兴趣的可以参阅代码注释部分或者网上搜索爱学习的小鹏友的视频讲解,希望能有些意思。

视频详解地址:B站 爱学习的小鹏友【学渣带你刷Leetcode】https://www.bilibili.com/video/BV1C7411y7gB?p=3

C语言完成代码

略长,考虑以后往github上放一放吧。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 1000

/*
超时示例
ASCII码字符可以使用一个字节来表示,
有效取值范围为0~127,总共128个字符。
解题思路为:
定义一个128字节大小char型数组,数组初始化为0。
*/
int allUnique(char *s, int i,int j)
{
    char flag[128];
    int ret = 0;
    memset(flag, 0, sizeof(flag)); //复制为0;
    for(; i<=j; i++)
    {
        if (flag[*(s+i)])
        {
            ret = 1; //有重复
            break;
        }
        else
        {
            flag[*(s+i)] = 1;
        }
    }

    return ret;
}

//最笨方法没有之一
int lengthOfLongestSubstring1(char * s)
{
    int length=0;
    int n=strlen(s);  //原始有多长
    //printf("%d\n",n);
    int i,j;
    //遍历所有的子字符串,记录没有重复字母的子字符串的最大的长度
    //获取子字符串时,使用两个标签,分别代表子字符串的开头和结尾

    if(n==1)
    {
        length=1;
        return length;
    }

    for(i=0; i<n; i++)
    {
        length=(length>(1)?length:(1));
        for(j=i+1; j<n; j++)
        {
            //当子字符串没有重复字母时,ans记录最大的长度
            if(!allUnique(s,i,j))
            {
                length=(length>(j-i+1)?length:(j-i+1));
                //  printf("%d  %d----------  %d\n",i,j,length);
            }
        }

    }
    return length;

}

/*1. 需要输出或比较的结果在原数据结构中是连续排列的(字符串中的连续不重复子串,数组中的连续元素最大和)
2. 每次窗口滑动时,只需观察窗口两端元素的变化,无论窗口多长,每次只操作两个头尾元素,当用到的窗口比较长时,可以显著减少操作次数
*/
int lengthOfLongestSubstring2(char * s)
{
    int L = 0, R = 0,k;
    int maxlen = 0;
    int curlen = 0;
    int n = strlen(s);
    if (n == 0)
        return 0;
       // for (; R < n &&(maxlen+L)<n; R++) //这个一开始想不到也很正常吧?算是优化?L+现在最大的都大于n了还用你算啥啊
    for (; R < n ; R++)  //别光想着小姐姐雇佣雇佣的,目标是啥,是得循环完吧,
    {
        curlen++;  //右移一下,长度就+1,一开始就由一个长度了,求最长的,那总得看看啥是常吧,就把L--R之间算是长度吧
        for ( k = L; k <= R; k++)  //从左边开始比较,这里面有没有和要进来的相等的
        {
           // printf("%d %d\n",L,R);
            if (s[k] == s[R + 1])  //脑袋往不往前伸,不等的时候脑袋就往前走,R++;每加完就得看看腿动不动
            {
              //  printf("%c\n",s[R+1]);
                if (curlen > maxlen)  //看看当前快要动弹的位置是否大于最大长度呗
                {
                    maxlen = curlen;
                }
                L = k + 1;  //腿往前一移动
                curlen = R - L + 1;//就把L--R之间算是长度吧
                break;      //这个for就算完成了,脑袋正常往前把S[R+1]带进来就行了。
            }
        }
    }

    //这地方也别费劲想了,就是这些当前的长度和定义的最大长度,谁最长输出谁吧
    if (curlen > maxlen)
        return curlen;
    else
        return maxlen;
}

int main()
{
    //char s1[MAXSIZE];
    //scanf("%s\n",s1);  //scanf遇到空格会断开!!!,这个位置不要加\n,画蛇添足
    //printf("%s %c\n",s1,s1[2]);  //

    //char st[3];
    //printf("input string:\n");
    //scanf("%s",st);
    //printf("输出测试%s\n",st);
    printf("可以输入的测试数据 abcabcbb    bbbbbb  pwwkew");
    char  *s;
    s=(char *)malloc(sizeof(char));
    //scanf("%s",s);  //处理不了空格
    gets(s);
    printf("%s\n",s);

    printf("最容易理解的直白做法:%d\n",lengthOfLongestSubstring1(s));//pointer,p

    printf("滑动窗口(小姐姐):%d:\n",lengthOfLongestSubstring2(s));//pointer,p
    return 0;
}
发布了15 篇原创文章 · 获赞 1 · 访问量 1251

猜你喜欢

转载自blog.csdn.net/qq_39729096/article/details/105154998