给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。注意 "bca" 和 "cab" 也是正确答案。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
如何判断下一个元素和当前子串没有重复元素呢?
我们可以使用一个数组,这个数组一共有125个位置,freq[k]存储的anscal为k相应的字符他在子串中出现的评率,如果为0就是没有重复,为1就是重复了
字母对应的数字如下
int a = 'a'; // 97
int z = 'z'; // 122
int A = 'A'; // 65
int Z = 'Z'; // 90
写法一:使用数组记录窗口
public class Test02_3_2 { public static void main(String[] args) { test01(); } private static void test01() { int ret = lengthOfLongestSubstring("abcdddd"); System.out.println(ret); } public static int lengthOfLongestSubstring(String s) { if (s == null || s.equals("")) { return 0; } int left = 0; int right = 0; int maxLen = 1; int[] window = new int[128]; window[s.charAt(0)] = 1; while (left < s.length()) { maxLen = Math.max(maxLen, right - left + 1); if (right + 1 < s.length() && window[s.charAt(right + 1)] == 0) { window[s.charAt(right + 1)] = 1; right++; } else { window[s.charAt(left)] = 0; left++; } } return maxLen; } }写法二:使用set记录窗口中不重复的元素,效率会低一些
public class Test02_0001 { public static void main(String[] args) { int ret = lengthOfLongestSubstring("bbbbb"); System.out.println(ret); } public static int lengthOfLongestSubstring(String s) { // 边界条件判断 if (s == null || s.length() == 0) { return 0; } // 初始化指针 int left = 0; int right = 0; int maxSubArrLength = 1; // 窗口 Set<Character> window = new HashSet<>(); window.add(s.charAt(0)); while (left < s.length()) { maxSubArrLength = Math.max(maxSubArrLength, window.size()); if (right + 1 < s.length() && !window.contains(s.charAt(right + 1))) { // 窗口右移 window.add(s.charAt(right + 1)); right++; } else { // 遇到重复元素,窗口左移 // 右边指针无法再移动,窗口左移 window.remove(s.charAt(left)); left++; } } return maxSubArrLength; } }