⚡考研面试⚡leetcode每天练——无重复字符的最长子串

114 阅读1分钟

这是我参与 8 月更文挑战的第 4 天,活动详情查看: 8月更文挑战

题目:无重复字符的最长子串

要求:
给定一个字符串 `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 * 104
s 由英文字母、数字、符号和空格组成
通过次数1,129,207提交次数2,998,621

一点点思路

大家看到这道题第一感觉是什么?,是不是和我一样想从头开始一个一个遍历不同就下一个相同就从第二个开始在开始接着重复第一次的操作,然后找到每次最长的那个对每一次结果进行比较,最后得出结果。能想出这个方法我已经觉得自己很🆗了我是 在这里插入图片描述

改进算法

确实不得不承认我刚开始的想法的时间和空间复杂度都很高,在我仔细思索中我想起来了计算机网络中的“滑动窗口”的概念。而且我也做过类似的题。接下来我们就用滑动窗口做一下试试。不了解计算机网络的同学也没事,后面我会出关于这方面的知识的。请大家多多关注就可以了。不懂的可以先看一下这个链接链接

开战

将字符串分割开来

刚才我们说了关于做题的思路在具体实施过程中,我们还要解决一个问题比如“asd”这个字符串我们怎么得到a啊。下面我们就来介绍一下有关函数 charAt(int index)。关于他的介绍我们可以在你的Java软件里面按住ctrl点击鼠标左键会弹出他的原文档。

关于该函数
 public char charAt(int index) {
        if (isLatin1()) {
            return StringLatin1.charAt(value, index);
        } else {
            return StringUTF16.charAt(value, index);
        }
    }
    
介绍:

/**
     * Returns the {@code char} value at the
     * specified index. An index ranges from {@code 0} to
     * {@code length() - 1}. The first {@code char} value of the sequence
     * is at index {@code 0}, the next at index {@code 1},
     * and so on, as for array indexing.
     *
     * <p>If the {@code char} value specified by the index is a
     * <a href="Character.html#unicode">surrogate</a>, the surrogate
     * value is returned.
     *
     * @param      index   the index of the {@code char} value.
     * @return     the {@code char} value at the specified index of this string.
     *             The first {@code char} value is at index {@code 0}.
     * @throws     IndexOutOfBoundsException  if the {@code index}
     *             argument is negative or not less than the length of this
     *             string.
     */

大家要培养看原文档的能力这在我下面要推荐的javaWeb里面有强调。我们下面看一个例子

package leetcode;

public class test {
	public static void main(String[] args) {
		String a="feixue";
		for(int i=0;i<a.length();i++) {
			char b=a.charAt(i);
			System.out.println(b);
		}
		
	}

}
结果:
f
e
i
x
u
e

源码和详解:

所谓滑动窗口,我们提到了窗口肯定就要有框了,没有框怎么叫窗口呢类似下面 在这里插入图片描述 我们定义两个指针leftright他们相当于窗口的左右框,大致思路是right指针先向右移判断现在指向的字符是否在窗口里面,在的话就移动left不在的话就移动right知道结束。 下面给出实现步骤:

public int lengthOfLongestSubstring2(String s) {
    int n = s.length();
    if (n <= 1) return n;
    int maxLen = 1;

    int left = 0, right = 0;
    Set<Character> feixue = new HashSet<>();//为了实现快速的一 一对应的关系我们使用了hashSet方法
    while (right < n) {
        char rightChar = s.charAt(right);
        while (feixue.contains(rightChar)) {
            window.remove(s.charAt(left));
            left++;
        }
        maxLen = Math.max(maxLen, right - left + 1);
        feixue.add(rightChar);
        right++;
    }

    return maxLen;
}

有什么不对的欢迎指正,谢谢大家的指点了先,嘻嘻嘻。