【滑动窗口】Leetcode 无重复字符的最长子串

本文介绍了两种求解字符串中最长无重复字符子串的算法,分别是暴力枚举和滑动窗口方法,通过哈希表统计字符频次来判断子串是否有重复,最终返回最长子串的长度。
摘要由CSDN通过智能技术生成

题目解析

3. 无重复字符的最长子串在这里插入图片描述


算法讲解

算法1: 暴力枚举

枚举「从每⼀个位置」开始往后,无重复字符的子串可以到达什么位置。找出其中长度最大的即
可。
在往后寻找无重复子串能到达的位置时,可以利用「哈希表」统计出字符出现的频次,来判断什么
时候子串出现了重复元素

class Solution {
public:
 int lengthOfLongestSubstring(string s) {
 int ret = 0; // 记录结果
 int n = s.length();
 // 1. 枚举从不同位置开始的最⻓重复⼦串
 // 枚举起始位置
 for (int i = 0; i < n; i++)
 {
 	// 创建⼀个哈希表,统计频次
 	int hash[128] = { 0 }; 
 	// 寻找结束为⽌
 	for (int j = i; j < n; j++)
 	{
 		hash[s[j]]++; // 统计字符出现的频次
 		if (hash[s[j]] > 1) // 如果出现重复的
 		break;
 		// 如果没有重复,就更新 ret
 		ret = max(ret, j - i + 1);
 	}
 }
 // 2. 返回结果
 return ret;
 }
};

算法2: 滑动窗口

让滑动窗⼝满⾜:窗⼝内所有元素都是不重复的。
做法:右端元素 ch 进⼊窗⼝的时候,哈希表统计这个字符的频次:
▪ 如果这个字符出现的频次超过 1 ,说明窗⼝内有重复元素,那么就从左侧开始划出窗⼝,
直到 ch 这个元素的频次变为 1 ,然后再更新结果。
▪ 如果没有超过 1 ,说明当前窗⼝没有重复元素,可以直接更新结果

注意:这里左侧为什么需要划出窗口:1. 这个操作是滑动窗口的固定操作 2. 根据这道题来说,左侧的窗口值(Hash表里面的val)需要进行清零(划出)

class Solution {
public:
    int lengthOfLongestSubstring(string str) {
        //使用滑动窗口 辅助Hash
        int left= 0;
        int right = 0;
        char Hash[128] = {0};
        int len = INT_MIN;
        //窗口枚举以left为起始的滑动
        while(left < str.size())
        {
            //进窗口
            while(right < str.size() && Hash[str[right]] < 1)
            {
                Hash[str[right++]]++;
            } 
            //走到这里就是已将出现重复元素  出窗口  重复元素使当前的right 但是此时的Hash里面已经不是 无重复的了
            len = max(len, right - left);
            while(str[left] != str[right])
            {
                Hash[str[left++]] = 0;
            }
            Hash[str[left++]] = 0;
        }
        if(len == INT_MIN)return 0;
        return len;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值