栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

leecode刷题3.无重复字符的最长子串【Java】

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

leecode刷题3.无重复字符的最长子串【Java】

一、题目

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

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

输入: s = ""
输出: 0

提示:

0 <= s.length <= 5 * 104s 由英文字母、数字、符号和空格组成 二、方法一:暴力求解

逐个生成子字符串

看它是否含有重复的字符

public int lengthOfLongestSubString(String s){
    int n = s.length();
    if(n<=1)return n;
    int maxLen = 1;
    
    for(int i=0;i set = new HashSet<>();
    for(int i=start;i<=end;i++){
        if(set.contains(s.charAt(i))){		//如果区间中存在重复的元素则返回false
            return false;
        }
        set.add(s.charAt(i));
    }
    return true;	//返回true没有重复的元素
}

时间复杂度为O(n3)

空间复杂度为O(n)

会超时

三、方法二:滑动窗口

暴力求解存在重复计算,同一个子串会进行多次判断是否存在重复字符

优化:只需要判断s[i,j)中判断是否存在s[j]即可,如果存在s[j]则说明存在重复元素

核心思路:需要不断移动右边界,因为窗口越大越好,如果移动到某一个元素在当前窗口中已经存在,则需要移动左边界来缩小窗口,从而剔除掉重复的元素

    定义两个边界left和right,第一个不存在重复元素,将右边界right往右边移动

    右移后,此时窗口(子串)最大长度为2,更新maxLength

    继续右移,此时right所指字符在之前窗口中已经存在,此时应该缩小窗口从而将重复字符剔除窗口,就需要移动左边界left

    左边界移动后,窗口中依旧存在重复字符w,继续右移left

    这时left和right指向同一个元素,窗口中没有重复字符,就需要右移right扩大窗口

    右移right后,判断在窗口中没有重复字符,计算长度为2,和maxLenght相等,不用替换,继续右移右边界right

    此时窗口中不存在重复元素e,此时窗口长度为3,大于之前的maxLength2,则需要更新maxLength,此时right继续右移

    右移后,在窗口中已经存在相同元素w,则需要移动左边界left来缩小窗口剔除重复元素

    这时left所指为k,在窗口中不存在重复元素,继续右移right

    right移除字符串,结束循环

时间复杂度为O(n),每个字符最多遍历两遍

空间复杂度为O(n),需要将字符放在某种数据结构中,这种数据结构需要快速判断一个字符是否存在于这个窗口中,就需要一个HashSet来存储字符

public int lengthOfLongestSubString(String s){
    int n = s.length();
    if(n<=1)return n;
    int maxLen = 1;
    
    int left = 0,right = 0;	//左边界和右边界
    Set window = new HashSet<>();	//利用hashSet存储字符
    while(right 

优化:

以上当在窗口中存在重复字符,是一个一个字符的缩小窗口(一步一步的移动左边界left,效率较慢)

可以通过记住每个字符在字符串中的索引,当遇到重复字符的时候,就可以直接跳到重复字符的后面

可以使用HashMap存放遍历过的每个字符,来记录其位置

遍历字符串记录每个字符出现的位置,如果存在重复的元素,则将左边界left直接跳到重复元素的后面

此时w的索引位置变为最后一次的3,继续右移right

没有重复的元素则记录其索引,当移动到最后一位w,有重复元素,则拿到之前记录的w后一个元素的位置为4,将其赋给left,则可以快速剔除掉重复元素

public int lengthOfLongestSubString(String s){
    int n = s.length();
    if(n<=1)return n;
    int maxLen = 1;
    
    int left = 0,right = 0;	//左边界和右边界
    //利用hashMap存储字符的索引位置
    Map window = new HashMap<>();	
    //处理窗口
    while(right 

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/709129.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号