leetCode题目:
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, 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.
需要注意边缘测试用例如"C",以及超长测试用例,还需要注意子串和子序列的区别
解法1:遍历字符串的每个字符,计算出以该字符为开始的最长子串,假设该字符串长度为N,则算法时间复杂度最大为N的平方
golang Code:func lengthOfLongestSubstring(s string) int { var buf bytes.Buffer maxLength := 0 currentLength := 0 for index := 0; index < len(s); index++ { //fmt.Println("currentIndex : " + strconv.Itoa(index)) //以index为开始计算最长子串的长度 for i := index; i < len(s); i++ { //fmt.Println("currentI : " + strconv.Itoa(i)) if !bytes.Contains(buf.Bytes(), []byte(string(s[i]))) { buf.WriteByte(s[i]) currentLength++ } else { if currentLength > maxLength { maxLength = currentLength } buf.Reset() currentLength = 0 break } } if currentLength > maxLength { maxLength = currentLength } buf.Reset() currentLength = 0 } return maxLength }
解法2:
来源EditorialSolution
以sliding windows的方式对字符串进行检查,维护下标I,J以及一个hashTable,I,J之间构成窗口。
以以下方式对I,J进行自增操作。
假如下标J的字符不在hashTable的Key中,则添加到hashTable中并将J作为Value,然后对J进行自增;
假如下标J的字符已经存在在hashTable的Key中,则hashTable中必定记录着这个字符前一次出现的下标J',直接将下标I更新为J’+1再继续运行算法。
此算法为优化版本,原来版本使用set保存出现过的字符,并且当出现存在字符时对I进行自增操作并从Set去掉下标为I的字符,可以想象此操作会一直进行下标J的字符被移出set,所以可以直接将I更新为下标为J的字符前一个出现的位置+1的位置。
此方法没有内嵌循环,时间复杂度为O(n)
JavaCode:public class Solution { public int lengthOfLongestSubstring(String s) { int n = s.length(), ans = 0; Map<Character, Integer> map = new HashMap<>(); // current index of character // try to extend the range [i, j] for (int j = 0, i = 0; j < n; j++) { if (map.containsKey(s.charAt(j))) { i = Math.max(map.get(s.charAt(j)), i); } ans = Math.max(ans, j - i + 1); map.put(s.charAt(j), j + 1); } return ans; } }
来源:https://www.cnblogs.com/RingLu/p/5625852.html