题目描述
请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法1:滑动窗口
1、利用滑动窗口,如果当前遍历的字母不在已遍历的字符串中,则右指针加1,判断当前最大窗口和当前窗口的最大值为最终结果
2、如果窗口中存在该元素,则将 head 指针右移,直到窗口中不包含该元素;
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s.length()==0) return 0;
else if (s.length()==1) return 1;
int res=1;
int left=0;
for(int i=1;i<s.length();) {
if (!isNot(s, left, i-1, s.charAt(i))) {
//如果没有在字串中,则加入
i++;
res=Math.max(res, i-left);
}else {
//如果在字串中
left++;
}
}
return res;
}
public boolean isNot(String s,int left,int right,char ch) {
for(int i=left;i<=right;i++) {
if (s.charAt(i)==ch) return true;
}
return false;
}
}
解法2:利用hashmap实现滑动窗口
1、如果hashmap中没有当前的字符,将key,value加入
2、如果有的话,则计算长度,如果长度比刚才的结果大,则改变最大长度
3、将最左边的指针移到hashmap中重复字符的右边一位
4、第三步需要注意的是,如果左指针加1没有刚才的左指针大,则不进行移动,例如测试用例tmm2nx
import java.util.HashMap;
class Solution {
public int lengthOfLongestSubstring(String s) {
int res=0;
int head=0;
HashMap<Character, Integer> resmap = new HashMap<Character, Integer>();
int i=0;
for(i=0;i<s.length();i++) {
if(!resmap.containsKey(s.charAt(i))) {
//如果没有在就添加进去
resmap.put(s.charAt(i), i);
res=Math.max(i-head, res);
}else {
//更新hash表
res=Math.max(i-head, res);
if (resmap.get(s.charAt(i))+1>head) {//测试用例tmm2nxt
head=resmap.get(s.charAt(i))+1;
}
resmap.remove(s.charAt(i));
resmap.put(s.charAt(i), i);
}
}
return Math.max(i-head, res);
}
}
解法3、动态规划
参考:https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/solution/pythonti-jie-shuang-100-dp-hua-dong-chuang-kou-shu/