题目
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.
标签:Hash Table、Two Pointers、String
相关链接: (H) Longest Substring with At Most Two Distinct Characters
题意
给定一个字符串,找出字符串中包含不重复元素的最长子串。
结题思路
自己的思路很快就想到了,即首先设置一个字典存储每一次访问的字符串中的字母,新建一个空字符串用来存储当前子串。遍历字符串,如果字典中不包含当前字符,则说明没有重复,当前子串+=当前字符。
若有重复则从当前子串中删除重复字符前所有的元素。比如:若输入的字符串是abcbacbb
则当当前字符遍历到a、b、c时当前子串为abc
。遍历到下一个字符b
时,则删除ab
当前子串为cb
。并且要更新字典。
这样的实现代码是可以通过的,但是很慢,优化方式是使用两个指针。一个指针指向子串头,一个指针指向子串尾。当当前字符不在字典中时,尾指针增加,当重复时,头指针后移到重复元素之后的字符。子串长度为j-i
代码
一刷:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class Solution {
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0 || s == "") {
return 0;
}
char[] arr = s.toCharArray();
Map<String,Integer> map = new HashMap<>();
int max = 0;
String result = "";
for (int i = 0;i< arr.length;i++) {
if (map.containsKey(arr[i]+"")) {
if (max < result.length()) {
max = result.length();
}
int index = result.indexOf(arr[i] + "");
result += arr[i];
String newS = result.substring(index + 1);
map.remove(0, index);
map.put(arr[i]+"", 0);
result = newS;
} else {
map.put(arr[i]+"", 0);
result += arr[i];
}
}
if (max < result.length()) {
max = result.length();
}
return max;
}
}
二刷:
import java.util.HashMap;
import java.util.Map;
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Map<String,Integer> map = new HashMap<>();
int max = 0, i = 0, j = 0;
while (j < n) {
if (map.containsKey(s.charAt(j) +"")) {
if (max < j - i) {
max = j - i;
}
while (s.charAt(i) != s.charAt(j)) {
map.remove(s.charAt(i)+ "");
i++;
}
map.put(s.charAt(j) + "", 0);
i++;
j++;
} else {
map.put(s.charAt(j)+"", 0);
j ++;
}
}
if (max < j-i) {
max = j-i;
}
return max;
}
}