Given a string, find the length of the longest substring without repeating characters.
Example 1:
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc"
, with the length of 3.
Example 2:
Input: "bbbbb"
Output: 1
Explanation: The answer is "b"
, with the length of 1.
Example 3:
Input: "pwwkew" Output: 3 Explanation: The answer is"wke"
, with the length of 3. Note that the answer must be a substring,"pwke"
is a subsequence and not a substring.
第一种方法使用哈希表(map实现),key是字符值,value是字符在字符串中的索引,对字符串s进行扫描,如果当前位置的字符没有在前面的扫描过程中出现过,则把该字符放入集合中,如果当前位置的字符曾经在前面扫描过程中出现过
(如果出现多次我们只保存最近出现的那个),则把上一个出现的字符删除,再把当前字符放入集合中,判断字符是否出现过使用哈希表。扫描过程中出现的最大集合的元素个数为答案。
1 class Solution { 2 public int lengthOfLongestSubstring(String s) { 3 if (s.length() == 0) return 0; 4 char []s1 = s.toCharArray(); 5 int ans = 1; 6 Map<String, Integer> map = new HashMap<>(); 7 int num = 0; 8 for (int i = 0; i < s.length(); ++i) { 9 String tc = String.valueOf(s1[i]); 10 if (map.containsKey(tc)) { 11 int temp = i - map.get(tc); 12 if (temp <= num) { 13 num = temp; 14 } else { 15 num++; 16 } 17 18 } else { 19 num++; 20 } 21 map.put(tc, i); 22 23 24 if (num > ans) { 25 ans = num; 26 } 27 } 28 return ans; 29 } 30 }
第二种办法是用set来判断字符是否出现重复,其他与第一种相同
1 class Solution { 2 public int lengthOfLongestSubstring(String s) { 3 Set<Character> set = new HashSet<>(); 4 int i = 0, j = 0; 5 int n= s.length(); 6 int ans = 0; 7 while (i < n && j < n) { 8 if (set.contains(s.charAt(j))) { 9 10 set.remove(s.charAt(i++)); 11 } else { 12 set.add(s.charAt(j++)); 13 ans = Math.max(ans, j - i); 14 } 15 } 16 17 18 return ans; 19 } 20 }
第三种方法,设f[i] = j为开始索引为i的最大无重复字符子串的结束索引为j,我们的目标是求出f[i] (i €[0, n - 1], n为字符串的长), 对字符串进行扫描,若当前位置字符没有在前面的扫描过程出现过
i的值不变,j的值往后走一位,如果当前位置字符曾经在前面的扫描过程出现过(如果出现多次我们只保存最近出现的那个),设最近出现的那个索引为k, 更新i = max(i + 1, k + 1),扫描过程中出现的最大集合为所求。
1 class Solution { 2 public int lengthOfLongestSubstring(String s) { 3 Map<Character, Integer> map = new HashMap<>(); 4 int ans = 0; 5 int n = s.length(); 6 for (int i = 0, j = 0; j < n; ++j) { 7 if (map.containsKey(s.charAt(j))) { 8 i = Math.max(i, map.get(s.charAt(j)) + 1); 9 10 } 11 ans = Math.max(j - i + 1, ans); 12 map.put(s.charAt(j), j); 13 } 14 15 16 return ans; 17 } 18 }
第四种方法用一维数组实现哈希表,长度为128,因为ascii码的长度为7bit, 2 ^ 7 = 128
1 class Solution { 2 public int lengthOfLongestSubstring(String s) { 3 int []map = new int[128]; 4 int ans = 0; 5 int n = s.length(); 6 for (int i = 1, j = 0; j < n; ++j) { 7 8 i = Math.max(i, map[s.charAt(j)] + 1); 9 10 11 ans = Math.max(j + 1 - i + 1, ans); 12 map[s.charAt(j)] = j + 1; 13 } 14 15 16 return ans; 17 } 18 }