重温算法之无重复字符的最长子串

133 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一.题目介绍

1.题目来源

链接:LeetCode

2.题目

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

示例1:

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

示例2:

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

示例3:

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

请注意,你的答案必须是子串的长度,"pwke"是一个子序列,不是子串。

二.具体实现

1.实现思路

题目的要求是取出所有无重复子串。如示例1,abc有重复,则结果是abc的字符串长度,而如示例2中只有一个b元素,则其长度为1,依次类推,我们只要通过两次遍历获取,找到重复字符串中最长的那个即可。

2.实现代码

1)自己的实现方式

public int lengthOfLongestSubstring(String s) {
    //开始位置
    int startAt = 0;
    //结束文章
    int endAt = 0;
    //两层循环遍历,依次比较元素,
    for (int i = 0; i < s.length(); i++) {
        int j = i+1;
        如果元素不相同则跳出循环,证明其不存在重复
        for (; j < s.length(); j++) {
            if (s.substring(i, j).indexOf(s.charAt(j)) != -1) { break; }
        }
        int currentMax = j - i;
        int max = endAt - startAt;
        //存在则记录其开始和结束的位置,即重复子串
        if (currentMax > max) { endAt = j; startAt = i; }
    }
    //重复子串的长度
    return s.substring(startAt, endAt);
}

2)题友的实现方式

使用HashSet的特点(不能存储重复元素),定义两个左右指针,然后在左指针向右移动的时候,我们从哈希集合中移除一个字符,在右指针向右移动的时候,我们往哈希集合中添加一个字符。

实现代码: image.png

3.运行结果

image.png

image.png

三.题后思考

做这类的题目可能最先想到的都是暴力法,直接双层循环,依次比较,但是时间复杂度就高了,如官方题解里借助Hashset的特点去存储元素的话其实更加的简洁明了一些,还是得多看看题解,多学习学习这种思路。