问题:
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.
分析:
1.对于这个问题最简单的解决方法是暴力遍历,在这种方法中会出现重复检查子字符串中是否有重复的问题,有出现超时的问题。
for(inti=0;i<n;i++)
for(intj=i+1;j<=n;j++)
……
2.使用滑动窗口的方法,滑动窗口是解决数组/字符串问题的常用方法。
如果已经确定在i至j-1的范围内没有重复字符,那么只需检验第j位字符是否已经存在于[i,j-1]范围的子字符串中,如果不存在重复,那么将滑动窗口变为[i,j],如果存在重复,将滑动窗口的下界向右滑动,直到没有重复。
代码实现1:
class Solution {
public int lengthOfLongestSubstring(String s) {
int longlen = 1;//表示目前最长子字符串的长度
int loc = 0;//某个字符在子字符串中的位置
int start = 0;//滑动窗口下界
String sub = "";//存放临时的一个子字符串
String longsub = "";//存放目前最长的子字符串
if(s == null)
return 0;
if(s.equals(""))
return 0;
sub = s.substring(0,1);
for(int i = 1; i<s.length();i++)
{
if(sub.contains(s.substring(i,i+1)))
{
loc = sub.indexOf(s.substring(i,i+1));
start = i - (sub.length()-1 -loc);//
if(sub.length() >= longsub.length())
{
longsub = sub;
longlen = longsub.length();
}
}
sub = s.substring(start,i+1);
}
return (sub.length() >= longsub.length())?sub.length():longlen;
}
}
代码实现2:
对于每次获得子字符串,我们可以选择不同的数据结构来存储,下面代码中使用了Set:
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++));//i++实现了滑动窗口的下界向右滑动
}
}
return ans;
}
}
代码实现3:
使用HashMap来记录滑动窗口的滑动位置。
public class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
Map<Character, Integer> map = new HashMap<>(); // current index of character
// try to extend the range [i, j]
for (int j = 0, i = 0; j < n; j++) {
if (map.containsKey(s.charAt(j))) {
i = Math.max(map.get(s.charAt(j)), i);
}
ans = Math.max(ans, j - i + 1);
map.put(s.charAt(j), j + 1);
}
return ans;
}
}