3. Longest Substring Without Repeating Characters
一、题目
1、审题:
2、分析:
求最长非重复字符子串的长度
二、解答
1、分析:
方法一、
① 非重复字符的子串长度。用 Map的Key来存放字符,Value 来存放下标。
② maxLen 记录所求最长子串长度,初始为0;low 指针指向所考虑子串的最左边字符所在下标,high 指针指向最右边的下标,low与 high 初始为0;
③ a、遍历所给字符串中字符,若未在 Map 出现,则放入 Map,切 high++;
b、若该字符作为Key出现在 Map,则看其 Value 是否在所考虑子字符串内,若不在子串内,则同 a 处理,覆盖其value;
c、若该字符在子串内,则 low 指向该子串中该字符的下一个字符;
d、 a、b两步每次判断 maxLen 是否为已经出现的最长子串长度;
class Solution { public int lengthOfLongestSubstring(String s) { int maxLen = 1, low = 0, high = 0; int len = s.length(); if(len == 0) return 0; Map<Character, Integer> map = new HashMap<Character, Integer>(); while(high < len) { if(map.containsKey(s.charAt(high))) { //pwwkew if(map.get(s.charAt(high)) >= low) // 保证所查找范围为 low 与 high 之间 low = map.get(s.charAt(high))+1; // 当前遍历字符在之前出现的后一个元素下标 else if(maxLen < high - low + 1) // 若不在当前查找的子串当中 maxLen = high - low + 1; } else if(maxLen < high - low + 1) { maxLen = high - low + 1; } map.put(s.charAt(high), high); //abcabcbb pwwkew "tmmzuxt" high++; } return maxLen; } }
方法二、
利用 StringBuffer,添加、删除字符,并统计每一次的长度。
public class Solution { public int lengthOfLongestSubstring(String s) { StringBuffer sb = new StringBuffer(); int max = 0, temp = 0; for(int i = 0; i < s.length(); i++) { if(sb.toString().contains(s.charAt(i) + "")) { int index = sb.indexOf(s.charAt(i) + ""); sb.delete(0, index + 1); // 删除前串 temp = sb.toString().length(); } sb.append(s.charAt(i)); temp++; if( temp > max) max = temp; } return max; } }
方法三、采用 Map<Character, Integer> 存储字符、下标。变量 start 存储到此字符为止前边不重复的最开始的字符下标。
public int lengthOfLongestSubstring(String s) { HashMap<Character, Integer> map = new HashMap<>(); int start = 0, max = 0; for(int i = 0; i < s.length(); i++) { char c = s.charAt(i); if(map.containsKey(c)) { max = Math.max(max, i - start); start = Math.max(start, map.get(c) + 1); map.put(c, i); } else { map.put(c, i); } } max = Math.max(s.length() - start, max); return max; }