3. Longest Substring Without Repeating Characters
Given a string s, find the length of the longest substring without repeating characters.
Example 1:
Input: s = "abcabcbb" Output: 3 Explanation: The answer is "abc", with the length of 3.
Example 2:
Input: s = "bbbbb" Output: 1 Explanation: The answer is "b", with the length of 1.
Example 3:
Input: s = "pwwkew" Output: 3 Explanation: The answer is "wke", with the length of 3. Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
Example 4:
Input: s = "" Output: 0
Constraints:
0 <= s.length <= 5 * 104
s
consists of English letters, digits, symbols and spaces.
暴力
class Solution {
public int lengthOfLongestSubstring(String s) {
int max = 0;
Map<Character, Integer> hashtable = new HashMap<Character, Integer>();
char[] charArray = s.toCharArray();
for (int i = 0; i < charArray.length; i++) {
int num = 0;
for (int j = i; j < charArray.length; j++) {
if (hashtable.containsKey(charArray[j])) {
hashtable.clear();
break;
} else {
num += 1;
hashtable.put(charArray[j], j);
}
if (max < num) max = num;
}
}
return max;
}
}
时间复杂度: O ( N 2 ) O(N^2) O(N2)
空间复杂度: O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣)
官方-滑动窗口
class Solution {
public int lengthOfLongestSubstring(String s) {
// 哈希集合,记录每个字符是否出现过
Set<Character> occ = new HashSet<Character>();
int n = s.length();
// 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
int rk = -1, ans = 0;
for (int i = 0; i < n; ++i) {
if (i != 0) {
// 左指针向右移动一格,移除一个字符
occ.remove(s.charAt(i - 1));
}
while (rk + 1 < n && !occ.contains(s.charAt(rk + 1))) {
// 不断地移动右指针
occ.add(s.charAt(rk + 1));
++rk;
}
// 第 i 到 rk 个字符是一个极长的无重复字符子串
ans = Math.max(ans, rk - i + 1);
}
return ans;
}
}
时间复杂度: O ( N ) O(N) O(N),其中 N N N 是字符串的长度。左指针和右指针分别会遍历整个字符串一次。
空间复杂度: O ( ∣ Σ ∣ ) O(|\Sigma|) O(∣Σ∣),其中 Σ \Sigma Σ 表示字符集(即字符串中可以出现的字符), ∣ Σ ∣ |\Sigma| ∣Σ∣ 表示字符集的大小。在本题中没有明确说明字符。