题目
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
解答
第一种
//1、穷举,从第一个字符开始,一次向后遍历,如果有相同字符,记录长度。
//2、继续从第二个字符,重复1步骤,比较长度,留下最长的
//3、重复2,返回最长result
public static int lengthOfLongestSubstring(String s) {
int length = s.length();
int result = 0;
for (int i = 0; i < length; i++) {
for (int j = i + 1; j <= length; j++) {
//
if (unique(s,i,j)) {
result = Math.max(result, j - i);
}
}
}
return result;
}
public static boolean unique(String s,int i, int j){
HashSet<Character> strings = new HashSet<>();
for (int k = i; k < j; k++) {
char c = s.charAt(k);
if (strings.contains(c)){
return false;
}else{
strings.add(c);
}
}
return true;
}
第二种(滑动窗口)
public static int lengthOfLongestSubstring2(String s) {
int length = s.length();
HashSet<Character> characters = new HashSet<>();
int result = 0, i = 0, j = 0;
while (i < length && j <length){
if (!characters.contains(s.charAt(j))){
characters.add(s.charAt(j));
j++;
result = Math.max(result,j-i);
}else{
characters.remove(s.charAt(i));
i++;
}
}
return result;
}
分析
1、 第一种方式,时间复杂度 n3,这种方式在实际情况下是不可取的。
2、时间复杂度:O(2n) = O(n)O(2n)=O(n),在最糟糕的情况下,每个字符将被 ii 和 jj 访问两次。空间复杂度:O(min(m, n))O(min(m,n)),与之前的方法相同。滑动窗口法需要 O(k)O(k) 的空间,其中 kk 表示 Set 的大小。而 Set 的大小取决于字符串 nn 的大小以及字符集 / 字母 mm 的大小。
网友评论