3.无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
一、暴力法
使用了集合来存储子字符串
hashset.add(E e):返回boolean型,如果此 set 中尚未包含指定元素,则添加指定元素;如果此 set 已包含该元素,则该调用不更改 set 并返回 false
时间复杂度
class Solution { public int lengthOfLongestSubstring(String s) { if(s.length() == 0) return 0; int max = 1; for(int i = 0; i < s.length()-1;i++){ Set<Character> set = new HashSet<>(); set.add(s.charAt(i)); int j = i+1; for(; j < s.length(); j++){ if(set.add(s.charAt(j))) max = Math.max(set.size(),max); //若j指的是最后一个字符,则不用再进行下一次循环 else if(j == s.length()-1) return max; else break; if(j == s.length()) return max; } } return max; } }
二、滑动窗口
滑动窗口是数组/字符串问题中常用的抽象概念。 窗口通常是在数组/字符串中由开始和结束索引定义的一系列元素的集合.
class Solution { public int lengthOfLongestSubstring(String s) { int n = s.length(); int ans,i,j; i = j = ans = 0; Set<Character>set = new HashSet<>(); while(i < n && j < n){ if(!set.contains(s.charAt(j))){ set.add(s.charAt(j++)); ans = Math.max(ans,j-i); } else set.remove(s.charAt(i++)); } return ans; } }
三、优化的滑动窗口(重点是start更新的位置)
分三种情况:
①当前字符不在map中:start不变,更新ans,更新map
②当前字符在map中(且在当前滑动窗口中):更新start到map中重复字符的下一位,ans不变,更新map
③当前字符在map中(不在当前滑动窗口中):start不变,更新ans,更新map
将三种情况综合,使代码简洁明了。
class Solution { public int lengthOfLongestSubstring(String s) { Map<Character,Integer>map = new HashMap<>(); int ans = 0; for(int start=0,end=0; end < s.length(); end++){ if(map.containsKey(s.charAt(end))){ start = Math.max(start,map.get(s.charAt(end))); } ans = Math.max(ans,end-start+1); map.put(s.charAt(end),end+1); } return ans; } }

浙公网安备 33010602011771号