给定一个字符串,请你找出其中不含有重复字符的最长子串 的长度。
示例 1:
输入: “abcabcbb”输出: 3解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”输出: 1解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”输出: 3解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。答案必须是子串 的长度,”pwke” 是一个子序列,不是子串。
题解 可采用滑动窗口法,将窗口内的字符保存到集合中,窗口的左边界向右移动时,弹出已不在窗口内的元素;窗口的右边界向右移动时判断字符是否已在集合中,若不在则加入,若已有则终止循环,记录当前最长长度。
Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import java.util.HashSet;public class Solution { public int lengthOfLongestSubstring (String s) { HashSet<Character> charSet = new HashSet <>(); int length = s.length(); int rk = -1 , ans = 0 ; for (int i = 0 ; i < length; i++) { if (i != 0 ) { charSet.remove(s.charAt(i - 1 )); } while (rk + 1 < length && !charSet.contains(s.charAt(rk + 1 ))) { charSet.add(s.charAt(rk + 1 )); rk++; } ans = Math.max(ans, rk - i + 1 ); } return ans; } public static void main (String[] args) { String s = "abcabcbb" ; Solution solution = new Solution (); System.out.println(solution.lengthOfLongestSubstring(s)); } }
Python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution : def lengthOfLongestSubstring (self, s: str ) -> int : char_set = set () rk, ans = -1 , 0 length = len (s) for i in range (length): if i != 0 : char_set.remove(s[i - 1 ]) while rk + 1 < length and s[rk + 1 ] not in char_set: char_set.add(s[rk + 1 ]) rk += 1 ans = max (ans, rk - i + 1 ) return ans
Go Golang 中没有集合,使用 map 实现过于繁琐,可采用 int 数组来模拟集合操作。
将每个字符的 ASCII
值作为数组的索引,数组内存储的为该字符的出现与否(1 或 0)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package mainimport ( "fmt" "math" ) func lengthOfLongestSubstring (s string ) int { var window [128 ]int length := len (s) rk, ans := -1 , 0 for i, _ := range s { if i != 0 { window[s[i-1 ]] = 0 } for rk+1 < length && window[s[rk+1 ]] == 0 { window[s[rk+1 ]] = 1 rk++ } ans = int (math.Max(float64 (ans), float64 (rk-i+1 ))) } return ans }