1 问题描述
判断字符串中某个最长子串的长度,这个子串中不含有重复字符。
2 错误解法
class Solution { public int lengthOfLongestSubstring(String s) { char[] stringArr = s.toCharArray(); Map<Character, Integer> hashMap = new HashMap<>(); int maxLen = 0, t = 0; if (stringArr.length == 0) { return maxLen; }else { hashMap.put(stringArr[0], 0); maxLen = 1; t = maxLen; } for (int i = 1; i < stringArr.length; i++){ if (!hashMap.containsKey(stringArr[i])) { hashMap.put(stringArr[i], i); maxLen++; if (maxLen > t) { t = maxLen; } }else { if (maxLen > t) { t = maxLen; } maxLen = 0; hashMap.clear(); hashMap.put(stringArr[i], i); maxLen++; } } return t; } }
错误原因:没有考虑多种情况。
3 错误解法二
class Solution { public int lengthOfLongestSubstring(String s) { // 暴力解法,求出s的所有子串,再逐一判断是否满足要求 int maxLen = 0, t = 0; String subString; char[] subStringArr; for (int i = 0; i < s.length(); i++) { for (int j = i + 1; j <= s.length(); j++) { // 双重循环,获取每一个可能的子串 subString = s.substring(i, j); subStringArr = subString.toCharArray(); // 判断该子串是否包含重复字符(方法一) maxLen = subStringArr.length; for (char c : subStringArr) { if (subString.indexOf(c) != subString.lastIndexOf(c)) { maxLen = 0; break; } } // 判断该子串是否包含重复子串(方法二 HashSet) // Set<Character> hashSet = new HashSet<>(); // for (char c : subStringArr) { // hashSet.add(c); // } // if (hashSet.size() == subStringArr.length) { // maxLen = subStringArr.length; // }else { // continue; // } // 如果该子串不包含重复字符,则比较该子串与当前最长子串,哪个更长 if (maxLen > t) { t = maxLen; } } } return t; } }
暴力解法的思路可行,但实际运行不一定可行。最后一个测试用例3W+字符,超出了时间限制。
4 正确解法:平滑窗口
class Solution { public int lengthOfLongestSubstring(String s) { // 滑动窗口 int rk = -1, ans = 0; int n = s.length(); Set<Character> hashSet = new HashSet<>(); for (int i = 0; i < n; ++i) { if (i != 0) { hashSet.remove(s.charAt(i - 1)); // 每次遍历去掉集合中第一个元素 } while (rk + 1 < n && !hashSet.contains(s.charAt(rk + 1))) { hashSet.add(s.charAt(rk + 1)); ++rk; } ans = Math.max(ans, rk - i + 1); } return ans; } }