leetcode3--Longest Substring Without Repeating Characters(无重复字符的最长子串)【滑动窗口】

原题链接

文章目录


题目描述

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

示例 1:

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

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

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

提示:
0 <= s.length <= 5 * 104
 由英文字母、数字、符号和空格组成

一、模板介绍

正如标题所述,该题会用到滑动窗口的思想,那么什么是滑动窗口以及什么时候使用呢?

顾名思义,滑动窗口就是可滑动的窗口,这里的窗口即代表所包含的子串,滑动代表所包含的子串可以依次滑动(一般都是从左到右滑动),我们只需要创建两个指针(广义指针,并非术语指针)来表示窗口的左右边框,就可以表示该滑动窗口。

那创建完窗口后怎么操作捏?让右指针先右移1,判断现在的子串是否符合题目要求。如果符合右指针就继续右移;如果不符合左指针右移1,并判断现在是否符合,不符合则继续移动。

//以下是该模板伪代码
初始化left,right,ans             //left表示左指针,right表示右指针,ans是最终结果
while(right<字符长度)
{
    while(当前窗口内子串不符合要求)
    {
        left++;
        continue;
    }
    //接下来的操作代表该子串符合要求,则更新ans,并扩大右指针
    更新ans;
    right++;
}

 非常通俗的讲,就是两个指针,一般是右指针移动,不符合条件就左指针移。

那么什么时候使用呢?在题目要求最长最短子串时可以考虑这么做。

tips:该模板有一个潜在要求就是如果当前子串不符合要求,那右指针再扩大后的子串也一定不符合要求,所以才将左指针移动。像求最长回文子串就不符合这个模板。(如leetcode5--原题链接


二、解题碎碎念

1.首先要明白子串和子序列的区别,子串必须是连续的,而子序列可以从串中随意抽取字符,即子序列不要求连续。

2.在了解滑动窗口之后,我们可以尝试解题。对于模板,所要做的是怎么判断当前字符是否符合要求,即无重复字符。对于初学者来说,可以构造一个判断函数,在右指针扩大1后,判断右指针指向的字符与之前字符串之间是否有相同字符。

//一个简单的判断函数
#include<stirng>
bool NotExist(string a, char b,int start,int end)
{
	for (int i = start; i < end ; i++)
	{
		if (b == a[i])
			return false;
	}
	return true;
}

更新ans是做一个简单的if判断或一个三目运算

if (ans < (end - start + 1))
		ans = end - start + 1;

3.放到力扣上跑的话,会发现这样做的时间比较高,所以可以尝试用标准模板库中的模板,如unordered_set, (对于该模板的使用,笔者不再赘述,大家可以自行查找)。

//以下是使用unordered_set的核心函数,记得包含<unordered_set>头文件
int lengthOfLongestSubstring(string s) {
    int start = 0, end = 0, ans = 0;
unordered_set<char> win;
int len = s.length();
while (end < len)        //滑动窗口
{
	while (win.count(s[end]))      //不符合要求,扩大左指针,缩小子串
	{
		win.erase(s[start]);
		start++;
		continue;
	}
	win.insert(s[end]);
	if (ans < end - start + 1)      //更新ans
		ans = end - start + 1;
	end++;                  //扩大右指针
}
return ans;

总结

以上就是今天分享的内容,其实把上面的代码放到力扣上跑会发现时间也没有很快,因为更高效的方法我也没有学习啦,嘎嘎(  ̄з(〃´▽`〃)ε ̄ )

  • 18
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值