力扣第3题详解(多方法)

力扣真题

力扣第3题详解(多方法)
题目链接:3. 无重复字符的最长子串


题目描述

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


题目分析:

①可以直接使用暴力破解的方法,使用哈希进行遍历当出现次数大于1的时候结束循环
②使用滑动窗口算法破解
③使用滑动窗口&哈希 共同破解


解决方案:

【暴力破解】(超时)

int check(char *s, int start, int len) {
    char hash[128] = {0};//使用哈希遍历
    for (int i = start; i < start + len; ++i) {
        ++hash[s[i]];
        if (hash[s[i]] > 1) {//出现次数大于一次结束循环
            return 0;//hash遍历数组 如果出现重复的就返回0结束
        }
    }
    return 1;
}

//lengthOfLongestSubstring1 暴力解法
int lengthOfLongestSubstring1(char *s) {
    int n = strlen(s);
    //先假设全部都是不重复的,然后len--循环找到重复的消去
    for (int len = n; len >= 1; --len) {//外层循环决定要循环的子串长度,从最长开始
        int end = n - len;
        for (int start = 0; start <= end; ++start) {//内存循环决定每次循环的起始位置和结束位置,从最短开始
            if (check(s, start, len)) {//检测符合条件的长度
                return len;
            }
        }
    }
    return 0;
}

【滑动窗口】解法1

int lengthOfLongestSubstring2(char *s) {
    int left = 0;
    int right = 0;
    int max = 0;
    while (s[right] != '\0') {//从右 滑动开始
        int flag = -1;//标志位,left到right中有无重复字符
        for (int i = left; i < right; ++i) {//i从左到右遍历
            if (s[i] == s[right]) {//若存在相同字符
                flag = i + 1;   //标志位+1 跳出循环
                break;
            }
        }
        if (flag != -1) {//在窗口内存在相同字符
            left = flag;//移动left到相同字符的下一位,左滑动
        }
        ++right;//右滑动
        max = max < right - left ? right - left : max;
    }
    return max;
}

【滑动窗口】解法2

int lengthOfLongestSubstring3(char *s) {
    int left = 0;
    int right = 0;
    int max = 0;
    while (s[right] != '\0') {//从右 滑动开始
        //标志位使用strchr返回首次出现位置.(str:地址类型 指针)
        int pos = strchr(s + left, s[right]) - s;
        if (pos != right) {//首次出现位置与当前位置不同说明第二次出现
            left = pos + 1;
        }
        ++right;//右滑动
        max = max < right - left ? right - left : max;
    }
    return max;
}

【滑动窗口&哈希】

int lengthOfLongestSubstring4(const char *s) {
    int left = 0;
    int right = 0;
    int max = 0;
    int hash[128];
    memset(hash, -1, sizeof(hash));
    while (s[right] != '\0') {//从右 滑动开始
        if(left<=hash[s[right]]){
            left=hash[s[right]]+1;
        }
        hash[s[right]]=right;//给首次出现的字符赋值,当第二次出现时同下标的值已有且>=0
        ++right;//右滑动
        max = max < right - left ? right - left : max;
    }
    return max;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值