给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
解题思路:
1. 子串: 串中任意个连续的字符组成的子序列称为该串的子串。
2. 关键是在找子串的起始点,需要考虑当前字符已经存在于构建的字典时,需要重置起点,但实际上正在遍历的淅川不包含当前的字符,所以需要考虑起始点移动时不能后退。
第一种:采用map
代码:
public static int lengthOfLongestSubstring(String s){
int fs = 0;//用于存取最后要返回的长度
//1.创建一个map,key:字符,value: 字符下标 `
Map<Character,Integer> map = new HashMap<>();
//2.遍历字符串,并将字符串存入map中
for (int start = 0,end = 0; end < s.length(); end++) {
char ch = s.charAt(end);
if (map.containsKey(ch)){ //若已经存在于map中,则将其对应的value拿出来
start = Math.max(map.get(ch),start);
}
// 取较大值
fs = Math.max(fs,end - start +1);
//存入map中
map.put(ch,end + 1);
}
return fs;
}
第二种:
1.创建辅助数组,长度为128,并将传入的字符串的每个字符作为辅助数组的下标,然后分别赋上1 2 3 …
即: abcabcbb ,a对应的ASCII是 97,则map[97] = 1
public static int lengthOfLongestSubstring_2(String s ){
int fa = 0;
int n = s.length();
int [] map = new int[128];
char [] ch = s.toCharArray();
for (int j = 0, i = 0; j < n; j++) {
//取较大值并赋值给 i,找到对应map数组下标对应的值,和 i 值比较
i = Math.max(map[ch[j]],i);
//字符串的长度等于最后一个字符的下标 - 最前面一个字符的下标
fa = Math.max(fa,j-i+1);
map[ch[j]] = j + 1; //以字符作为map数组的下标,并给对应的下标赋值
}
return fa;
}