给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
1.暴力法
遍历所有子字符串并判断是否有重复,记录下他们的长度 最后输出最长的子字符串长度
代码:
package test;
import java.util.HashSet;
import java.util.Set;
public class test23 {
public static void main(String[] args) {
test23 t = new test23();
String s = "pwwkew";
t.lengthOfLongestSubstring(s);
}
public int lengthOfLongestSubstring(String s) {
int n = s.length();
int ans = 0;
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);
}
}
}
System.out.println(ans);
return ans;
}
public boolean allUnique(String s, int start, int end) {
Set<Character> set = new HashSet<>();
for(int i = start; i < end; i++) {
Character ch = s.charAt(i);
if(set.contains(ch)) {
return false;
}
set.add(ch);
}
return true;
}
}
输出:
2.滑动窗口
以 i
为起始点, j
为结束点将含括的子字符串插入到set
数组中,若插入的字符s.charAt(j)
在set
数组中不重复则记录一次当前子字符串长度 ans
。若插入字符在数组中存在重复则不插入,并移除数组中最开始索引处 i
的字符,索引 i++
,知道整个字符串循环完 得到最后最长的子字符串长度 ans
。
代码:
package test;
import java.util.HashSet;
import java.util.Set;
public class test24 {
public static void main(String[] args) {
test24 t = new test24();
String s = "pwwkew";
t.lengthOfLongestSubstring(s);
}
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) {
if(!set.contains(s.charAt(j))) {
set.add(s.charAt(j));
j++;
ans = Math.max(ans, j-i);
} else {
set.remove(s.charAt(i));
i++;
}
}
System.out.println(ans);
return ans;
}
}
输出:
3.优化的滑动窗口
创建一个HashMap
用来存放每一个字符,i
为左边界 j
为右边界。
当遍历到重复的字符,将左边界i
移动到此重复字符前一次出现map.containsKey(s.charAt(j))
的地方或不动(i = Math.max(map.get(s.charAt(j)), i)
),并记录最长子串长度ans
.
代码:
package test;
import java.util.HashMap;
import java.util.Map;
public class test25 {
public static void main(String[] args) {
test25 t = new test25();
String s = "pwwkew";
t.lengthOfLongestSubstring(s);
}
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
Map<Character, Integer> map = new HashMap<>();
for(int i = 0, j = 0; j < n; j++) {
if(map.containsKey(s.charAt(j))) {
i = Math.max(i, map.get(s.charAt(j)));
}
ans = Math.max(ans, j - i + 1);
map.put(s.charAt(j), j+1);
}
System.out.println(ans);
return ans;
}
}
输出: