LeetCode-T3-无重复字符的最长子串

问题描述

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

例子

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

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

输入: s = ""
输出: 0

思路1:

 

这道题用到的主要思路就是 滑动窗口

那什么是滑动窗口呢?

其实就是一个队列,比如例题中的abcabcbb,进入这个队列(窗口)为abc满足题目要求,当再进入a,队列就变成了abca,这时候就不满足要求,所以,我们要移动这个队列。

如何移动?

我们只需要把队列的左边的元素移出就可以了,知道满足题目要求!一直维持这样的队列,找出队列出现最长的长度的时候,求出解!

时间复杂度:O(n)

思路2:

其实和思路1差不多。思路也是滑动窗口

  1. 定义一个map集合的数据结构存储<K, V>,其中key值为字符,value值为该字符位置+1,加1表示从字符位置后一个才开始不重复。(散列表)
  2. 定义不重复子串的开始位置为start(队头),结束位置为end(队尾)。
  3. 随着end不断遍历向后,会遇到与[start, end]区间内字符相同的情况,此时将字符作为key值,获取其value值,并更新start,此时[start,end区间内不存在重复字符]
  4. 无聊是否更新start,都会更新其map数据结构和结果result。

代码实现

package HOT100;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class T3 {

    public static void main(String[] args) {
        String s = "bbbbbb";
        int len = lengthOfLongestSubstring(s);
        System.out.println(len);
    }

    public static int lengthOfLongestSubstring(String s) {

        // 定义一个HashMap集合,可以看做一个散列表,key用来存储字符 value用来存储下标+1
        Map<Character, Integer> hashMap = new HashMap<>();
        // 定义一个子串最大长度
        int maxLen = 0;
        // 首先得到字符串的长度
        int strLen = s.length();

        // 遍历字符串
        for (int start = 0, end = 0; end < strLen; end++) {
            // 首先获得当前的字符
            char currentChar = s.charAt(end);
            // 判断当前字符是否在hashMap中
            if (hashMap.containsKey(currentChar)) {
                // 找到相同的字符  start需要更新
                start = Math.max(start, hashMap.get(currentChar));
            }
            // 更新当前的 子串 长度
            maxLen = Math.max(end - start + 1, maxLen);
            // 存储到集合中   注意:这里是end+1
            hashMap.put(currentChar, end + 1);
        }

        return maxLen;

    }
}

图解

1.

2.

3.

4.

5.

6.

7.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值