LeetCode HOT 100 —— 3.无重复字符的最长子串

题目

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度
在这里插入图片描述
提示:

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

思路

首先要注意的是:

  • 子串要求连续
  • 子序列可以不连续

本题的主要思路是:滑动窗口

滑动窗口:其实就是一个队列,比如例子中的abcabcbb,进入这个队列为abc时满足题意,当再进入a,窗口中变成了abca,不满足要求所以要移动这个队列,只需要将队列左边的元素移出就行了,直到满足题意为止

一直维持这样的队列,找出队列出现的最长长度的时候,即为解

简单来说就是,滑动窗口里面是符合要求的部分,然后扩大右边界,如果不符合要求了,就缩小左边界,直到窗口内的内容又满足题意了,然后接着扩大右边界

时间复杂度0(n)

java代码如下:

class Solution {
	public int lengthOfLongestSubstring(String s){
		//维护当前最长不重复字符子串
		Set<Character> set  = new HashSet<>();
		int left = 0;//滑动窗口的左边界,用于移除左边元素,动态变化
		int right = 0;//滑动窗口的右边界,用于找后面的元素,表示目前滑动到的元素位置,动态变化
		int max = 0;//滑动窗口最大长度
		while(right < s.length()){
			if(!set.contains(s.charAt(right))){
				//如果没有查到重复元素,就加到set中,right右移
				set.add(s.charAt(right));
				right++;
			} else {//如果遇到了重复元素
				//right查到重复元素先不动,将left右移,set删除left经过的字符,直到删除掉右边这个重复的字符(即right的值),如abcb->bcb->cb停
				set.remove(s.charAt(left));
				left++;
			}
			//每一次循环计算当前set子串里的长度
			max = Math.max(max,set.size());
		}
		return max;
	}
}

滑动窗口相关题目:
76. 最小覆盖子串
30. 串联所有单词的子串
209. 长度最小的子数组
239. 滑动窗口最大值
567. 字符串的排列

最后补充一些东西:很多人把 双指针滑动窗口 混为一谈,但从狭义的角度来说

  • 滑动窗口是一类问题,同向移动

滑动窗口的概念始于TCP,滑动窗口应当是左指针始终向右移动,右指针不停变化,也就是窗口长度不停变化但整体是向一个方向移动的。也就是说需要使用适合的数据结构来解决(或者说维护这个窗口),例如单调队列、平衡树等等。

  • 而双指针是一种解决方法,可以同向或双向移动

双指针又分成左右指针和快慢指针

(1)快慢指针:主要解决链表中的问题,一般为同向移动,比如判定链表中是否包含环

(2)左右指针:主要解决数组(或者字符串)问题,可以是双向移动(同向或者反向),一般为固定一个边界并改变另一个边界来不断逼近约束要求,比如二分搜索

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HDU-五七小卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值