【字节专场】leetcode3. 无重复字符的最长子串

mac2022-06-30  23

3. 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 示例 3: 输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。

方法一:滑动窗口

首先明确是求最长子串而不是最长子序列,子串是必须得连续的,这里稍微模拟一下,以“pwwkew”为例, 查看p是否已经在集合中,否,更新ans, 查看w是否已经在集合中,否,更新ans, 查看w是否已经在集合中,是,那么w重复了,所以需要更新左边界,从左开始移除元素,直到w不在集合中,再插入,然后更新ans…

public int lengthOfLongestSubstring(String s) { int len = s.length(); int i = 0, j = 0; //窗口为[i, j),也就是初始化为空 int ans = 0; Set<Character> set = new HashSet<>(); while (i<len && j<len){ if (!set.contains(s.charAt(j))){ set.add(s.charAt(j)); ans = Math.max(ans, j-i+1); j++; } else { set.remove(s.charAt(i)); i++; } } return ans; }

方法二:优化的滑动窗口

使用一个Map<Character, Integer>,key存字符,value存key在字符串中的下标+1,这样当扩展窗口碰到key已经存在时,就可以快速更新左边界为max(i, map.get(s.charAt(j))),虽然这里可能map内存的元素多余当前窗口的大小,但并不不会影响。

public int lengthOfLongestSubstring(String s) { int n = s.length(), ans = 0; Map<Character, Integer> map = new HashMap<>(); for (int j = 0, i = 0;j<s.length();j++){ if (map.containsKey(s.charAt(j))){ i = Math.max(i, map.get(s.charAt(j))); } ans = Math.max(j-i+1, ans); map.put(s.charAt(j), j+1); } return ans; }
最新回复(0)