3.Longest Substring Without Repeating Characters

来源:互联网 发布:淘宝网不显示图片 编辑:程序博客网 时间:2024/06/06 13:12

题目描述:

Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.

思路

要求最长的没有重复元素的连续子字符串,最简单的是方法是使用双重循环,遍历所有的子字符串,并一一判断是否有重复元素,没有重复元素,再更新子字符串的最大值。这种暴力破解法时间复杂度太高,超时。

for (int i = 0; i < n; i++)    for (int j = i + 1; j <= n; j++)        //判断子字符串是否有重复元素        if (allUnique(s, i, j))             ans = Math.max(ans, j - i);

上面这种暴力法,有一个可以改进的地方,就是当我们要判断sij是否有重复元素时,我们在此之前已经判断了sij1是否有重复元素了,无需重复判断,我们只需要检查sj是否在子串sij1中就可以了。可以借助HashSet实现。通过使用HashSet作为一个滑动窗口,检查当前的字符是否在一个字符串中,时间复杂度只有O(1)。Set是不含重复元素的集合。
滑动窗口是一个通常用于数组或字符串问题的抽象概念。一个窗口是数组或字符串中的一系列元素,这些元素通常由开始和结束索引定义,例如[i,j)(左闭,右开)。滑动窗口是一个窗口“滑动”它的两个边界到特定的方向。例如,如果我们滑动[i,j)到右边1个元素,那么它就变成[i+1,j+1)(左闭,右开)。
回到我们的问题。我们使用HashSet来存储当前窗口中的字符[i,j)(初始时j=i)。然后我们将指数j右移。如果不是在HashSet中,我们会进一步滑动j。一直到sj已经在HashSet中了。我们发现没有重复字符的最大子字符串从索引i开始。遍历索引i,就得到了答案。

代码:

public class Solution {    public int lengthOfLongestSubstring(String s) {        int n = s.length();        Set<Character> set = new HashSet<>();        int ans = 0, i = 0, j = 0;        while (i < n && j < n) {            // try to extend the range [i, j]            if (!set.contains(s.charAt(j))){                set.add(s.charAt(j++));                ans = Math.max(ans, j - i);            }            else {                set.remove(s.charAt(i++));            }        }        return ans;    }}
阅读全文
0 0
原创粉丝点击