Open azl397985856 opened 2 years ago
思路: 哈希表 + 双指针(滑动窗口) 思路用一个左指针指窗口的最左端,遍历右端 一旦发现哈希表中曾经出现过当前遍历的值,则for循环收缩窗口,直到当前值的哈希映射为0 则继续右移扩展窗口。 每次需要判断是否超过最长字符串,若超过则更新。
func lengthOfLongestSubstring(s string) int {
hash := map[byte]int{}
l := 0
out := 0
for r := range s{
for hash[s[r]] > 0{
hash[s[l]]--
l++
}
hash[s[r]]++
if r-l+1 > out{
out = r-l+1
}
}
return out
}
时间复杂度O(N) 空间复杂度O(N)
同向双指针滑窗+charArray记录出现次数: class Solution { public int lengthOfLongestSubstring(String s) { int start = 0; int end = 0; int result = 0; int[] charList = new int[128]; Arrays.fill(charList, -1); while (end < s.length()) { char letter = s.charAt(end); if (charList[letter] != -1 && charList[letter] >= start && charList[letter] < end) { start = charList[letter] + 1; } result = Math.max(result, end - start + 1); charList[letter] = end; end++; } return result; } }
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) return 0;
HashMap<Character, Integer> window = new HashMap<>();
int left = 0; int right = 0; int maxLen = 0;
while(right < s.length()){
char s1 = s.charAt(right);
right ++;
window.put(s1, window.getOrDefault(s1, 0) + 1);
while (window.get(s1) > 1){
char s2 = s.charAt(left);
left ++;
window.put(s2, window.getOrDefault(s2,0) - 1);
}
maxLen = Math.max(maxLen, right - left);
}
return maxLen;
}
}
//Time O(n), Space O(n)
滑动窗口
var lengthOfLongestSubstring = function(s) {
const hash = new Set()
let res = 0, right = -1 //右指针从左指针左边开始
for(let left = 0; left < s.length; left++){
if(left != 0){
hash.delete(s.charAt(left-1))
}
while(right+1 < s.length && !hash.has(s.charAt(right+1))){
hash.add(s.charAt(right+1))
right++
}
res = Math.max(res, right - left + 1)
}
return res
};
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function (s) {
if (!s.length) return 0;
let max = 0;
let left = 0;
let str = ''
for (let i = 0; i < s.length; i++) {
if (str.includes(s[i])) {
left += s.slice(left, i).indexOf(s[i]) + 1
continue;
}
str = s.slice(left, i + 1);
max = Math.max(max, str.length);
}
return max;
};
复杂度分析不是很会,不一定对,如果有错,请指正。
Sliding win
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# win:set. new char is not in it, append win; else, shink win until no dupli.
# why could not use set??
# hash
win = {}
left, right = 0, 0
longest = 0
for right in range(len(s)):
if s[right] in win:
# print(win, s[right], left, right)
left = max(left, win[s[right]] + 1)
win[ s[right] ] = right
longest = max(longest, right - left + 1)
return longest
Time:O(n) Space:O(n)?
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
ans = 0
left, right = 0, 0
seen = {}
while right < len(s):
cur = s[right]
right = right + 1
seen[cur] = seen.get(cur,0) + 1
#print(seen)
while seen.get(cur) > 1:
seen[s[left]] = seen[s[left]] - 1
left = left + 1
#print(left, right)
ans = max(ans, right - left)
滑动窗口
class Solution {
public int lengthOfLongestSubstring(String s) {
HashMap<Integer,Integer>d= new HashMap<>();
int left=0;
int right=0;
int m=s.length();
int ans=0;
while (right<m)
{
int x=s.charAt(right)-'a';
while(d.getOrDefault(x,0)>0 && left<right)
{
int y=s.charAt(left)-'a';
d.put(y,d.getOrDefault(y,0)-1);
left+=1;
}
d.put(x,d.getOrDefault(x,0)+1);
right+=1;
if (right-left>ans)
{
ans=right-left;
}
}
return ans;
}
}
双指针。用两个指针夹住一段子串。用一个集合记录见到过的字符。
如果右指针指向的字符,集合里没有,就向右扩展区间。并且计算最大长度。
如果右指针指向的字符,集合里已经有了,就收缩左指针,并移除左指针指向的字符,直到右指针指向的字符在集合中已经没有重复。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
n = len(s)
if not n: return 0
seen = set()
left, right, ans = 0, 0, 0
while right < n:
if s[right] not in seen:
seen.add(s[right])
right += 1
ans = max(ans, right - left)
else:
while s[right] in seen:
seen.remove(s[left])
left += 1
return ans
时间复杂度 O(n)
空间复杂度 O(n)
class Solution {
public:
int lengthOfLongestSubstring(string s) {
if(s.empty())return 0;
if(s.length()==1)return 1;
int max_length = 1,current_length=1;
int start_pos = 0;
int end_pos = 1;
while(end_pos!=s.length()){
const char c=s[end_pos];
int pos = s.find(c,start_pos);
if(pos==string::npos||start_pos>pos||pos==end_pos){
end_pos++;
current_length++;
max_length=max(max_length,current_length);
}else{
current_length = end_pos-pos;
start_pos =pos+1;
end_pos++;
}
}
return max_length;
}
};
from collections import defaultdict
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# sliding wid
l = 0
pool = defaultdict(int)
#
ans = 0
for r in range(len(s)):
if s[r] in pool:
# find duplicate
# move the l to make sure pool[s[r]] == 0
while pool[s[r]] != 0:
# -1 then move l
pool[s[l]] -= 1
# if == 0, remove the key
if pool[s[l]] == 0:
del pool[s[l]]
l += 1
# after remove the dupliate
pool[s[r]] += 1
ans = max(ans, r-l+1)
return ans
time O(N) space O(N)
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if (not s or len(s) == 0): return 0
# stores last seen index of a character
seen = {}
res = left = 0
for right, char in enumerate(s):
if char in seen and left <= seen[char]:
left = seen[char] + 1
else:
res = max(res, right - left + 1)
seen[char] = right
return res
思路: sliding window + hash map
class Solution {
public:
int lengthOfLongestSubstring(string s) {
//sliding window algorithm
int size = s.length();
if(size < 2)
{
return size;
}
int left{0}, right{0}, ans{1}; //indicator
unordered_map<char, int> memo;
for(auto c: s) //initialize memo
{
memo[c] = 0;
}
for(;right < size; right++)
{
char cur = s[right];
memo[cur]++;
for(; memo[cur] > 1; left++)
{
memo[s[left]]--;
}
ans = max(ans, right-left+1);
}
return ans;
}
};
time: o(n) space : o(n)
双指针+hashmap,通过hashmap来计算字符的frequency。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s:
return 0
m = defaultdict(int)
ans = 0
start = 0
for i,e in enumerate(s):
m[e]+=1
if m[e]>1:
ans = max(ans,i-start)
while start<i:
cur = s[start]
m[cur]-=1
start+=1
if cur == e:
break
else:
ans = max(ans, i-start+1)
return ans
复杂度分析
思路
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
seen = []
max_len, cur_len = 0, 0
left = 0
for i in range(len(s)):
cur_len += 1
while s[i] in seen:
seen.remove(s[left])
left += 1
cur_len -= 1
max_len = max(max_len, cur_len)
seen.append(s[i])
return max_len
复杂度分析
class Solution: def lengthOfLongestSubstring(self, s: str) -> int:
dic = defaultdict(int)
ans = 0
for i in range(len(s)):
c = 0
lis = []
for j in range(i,len(s)):
if s[j] not in lis:
lis.append(s[j])
c+=1
#print(lis)
else:
break
ans = max(ans,c)
#print(ans)
return ans
class Solution(object): def lengthOfLongestSubstring(self, s): """ :type s: str :rtype: int """ res = 0 helper = collections.defaultdict(int)
if not s:
return 0
l = 0
r = 0
while r <= len(s) - 1:
if helper[s[r]] == 0:
res = max(res, r - l + 1)
helper[s[r]] += 1
r += 1
else:
helper[s[l]] -= 1
l += 1
return res
滑动窗口
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s:return 0
left = 0
lookup = set()
n = len(s)
max_len = 0
cur_len = 0
for i in range(n):
cur_len += 1
while s[i] in lookup:
lookup.remove(s[left])
left += 1
cur_len -= 1
if cur_len > max_len:max_len = cur_len
lookup.add(s[i])
return max_len
时间复杂度: O(n)
空间复杂度: O(s)
最高端的滑动窗口往往是看不到快慢指针的
def lengthOfLongestSubstring(self, s: str) -> int:
if (l:=len(s))<=1:
return l
pos={}
cur=0
res=0
for index,i in enumerate(s):
if i in pos:
for j in range(index-cur,last:=pos[i]):
del pos[s[j]]
cur=index-last
pos[i]=index
else:
pos[i]=index
cur+=1
if cur>res:
res=cur
return res
class Solution:
# 哈希:naive想法,每次遇到重复的字符,从重复字符的起点开始重置字典重新统计,
# 这样worst case复杂度就是O(n^2)
def lengthOfLongestSubstring1(self, s: str) -> int:
d = defaultdict(lambda: [0, -1])
i, n = 0, len(s)
ans = 0
while i < n:
ch = s[i]
if d[ch][0] >= 1:
ans = max(ans, len(d.keys()))
i = d[ch][1] + 1
d = defaultdict(lambda: [0, -1])
continue
d[ch][0] += 1
d[ch][1] = i
i += 1
if len(d.keys()):
ans = max(ans, len(d.keys()))
return ans
# 哈希+滑动窗口:上面方法的改进,不需要重置字典,因为除了那个重复的字符以外其它的字符都是没重复的,
# 所以可以应用滑动窗口,当右指针扫到和set重复的情况,左指针向右滑直到找到这个重复的字符,
# 滑动的同时从set中删掉。复杂度O(n)
def lengthOfLongestSubstring(self, s: str) -> int:
chars = set()
ans = 0
i = 0
for ch in s:
if ch not in chars:
chars.add(ch)
else:
if len(chars) > ans:
ans = len(chars)
while s[i] != ch:
chars.remove(s[i])
i += 1
i += 1
return ans if ans > len(chars) else len(chars)
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
hashmap = {}
max_len = 0
start = 0
for idx in range(len(s)):
letter = s[idx]
if letter not in hashmap or hashmap[letter] < start:
hashmap[letter] = idx
max_len = max(max_len, idx + 1 - start)
else:
start = hashmap[letter] + 1
hashmap[letter] = idx
return max_len
time complexity: O(N) space complexity : O(K), K stands for the number of ASCII characters
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
charMap = dict()
i, maxLen = 0, 0
for j in range(len(s)):
c = s[j]
if c in charMap.keys():
i = max(i, charMap[c] + 1)
charMap[c] = j
maxLen = max(maxLen, j - i + 1)
return maxLen
Time Complexity: O(n), Space Complexity: O(n)
滑动窗口
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length(), res = 0;
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (int start = 0, end = 0; end < n; end++){
char ch = s.charAt(end);
if(map.containsKey(ch)) {
start = Math.max(map.get(ch),start); // 进行滑动,start缩到该ch上一次出现的下一个位置
}
res = Math.max(res, end - start + 1);
map.put(s.charAt(end), end + 1);
}
return res;
}
}
复杂度分析
C++ Code:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> record(256,0);
int left =0;
int right =0;
int ret =0;
while(right < s.size())
{
record[s[right]]++;
while(record[s[right]]>1)
{
record[s[left]]--;
left++;
}
ret = max(ret, right - left +1);
right++;
}
return ret;
}
};
class Solution {
public:
int lengthOfLongestSubstring(string s) {
vector<int> record(256,-1);
int left =0;
int ret =0;
for(int i=0; i< s.size(); i++)
{
if(record[s[i]]!=-1)
{
ret = max(ret, i - left);
left = max(left, record[s[i]]+1);
}
record[s[i]] = i;
}
ret = max(ret, int(s.size()) - left);
return ret;
}
};
Could use brute force, n characters, so O(n^2) substring in total. Each substring takes O(n) to check with a HashTable/array, so O(n^3)
Try HashMap and Sliding Window:
Move the right pointer to scan through the string , and update the HashMap;
If the character is already in the HashMap, then move the left pointer to the right of the same character previously found;
The two pointers can only move forward; The HashMap stores the last indices of every characters.
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length() == 0) return 0;
HashMap<Character, Integer> map = new HashMap<>();
int maxLength = 0;
for(int i = 0, j = 0; i < s.length(); i++){
if(map.containsKey(s.charAt(i))){
j = Math.max(map.get(s.charAt(i)) + 1, j);
}
map.put(s.charAt(i),i);
maxLength = Math.max(maxLength, i-j+1);
}
return maxLength;
}
}
Time: O(N)
Space: O(128) only 128 unique characters
思路: 滑动窗口(双指针)法:
复杂度分析:
代码(C++):
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int n = s.length();
if (n <= 1) return n;
// key: character, value: index in string
map<char, int> mp;
int l = 0;
int res = 0;
for (int i = 0; i < n; ++i) { // i = right boarder, l = left boarder
if (mp.count(s[i]) && l <= mp[s[i]])
l = mp[s[i]] + 1;
res = max(res, i - l + 1);
mp[s[i]] = i;
}
return res;
}
};
Java Code:
class Solution {
public int lengthOfLongestSubstring(String s) {
HashMap<Character,Integer> hs = new HashMap<>();
char[] arr = s.toCharArray();
int left = 0;
int max = 0;
for (int i = 0; i < arr.length; i++) {
if (hs.containsKey(arr[i])) {
left = Math.max(left, hs.get(arr[i]) + 1);
}
hs.put(arr[i], i);
max = Math.max(max, i - left + 1);
}
return max;
}
}
Thoughts
Code
public int lengthOfLongestSubstring(String s) {
if (s.length() == 0 || s == null) {
return 0;
}
int left = 0, max = 0;
Map<Character, Integer> map = new HashMap<>();
for (int right = 0; right < s.length(); right++) {
if (map.containsKey(s.charAt(right))) {
left = Math.max(left, map.get(s.charAt(right)) + 1);
}
map.put(s.charAt(right), right);
max = Math.max(max, right - left + 1);
}
return max;
}
Complexity
Hash Set
class Solution {
public int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet<>();
int maxLen = 0;
int left = 0;
for(int i = 0; i < s.length(); i++){
while(set.contains(s.charAt(i))){
set.remove(s.charAt(left));
left++;
}
set.add(s.charAt(i));
maxLen = Math.max(maxLen, i - left + 1);
}
return maxLen;
}
}
复杂度分析
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
dic = {}
result, last = 0, 0
for i in range(len(s)):
j = dic.get(s[i], -1)
dic[s[i]] = i
last = last + 1 if temp < i - j else i - j
result = max(result, last)
return result
Sliding windows + Hash Table. The sliding window's right boundary is always updates one by one. Every time when we meet a char has been seen before, we find out the last time we saw it. Compare its position with current sliding window's left boundary. If the left boundary if smaller than that position, we update the left boundary to the one position next to it. No matter whether we update the left boundary or not, we always update the answer to the longest subsequence without the repeat chars
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s:
return 0
ans = 1
i, j = 0, 0
lastSeen = {}
while j < len(s):
if s[j] in lastSeen and i < lastSeen[s[j]]:
i = lastSeen[s[j]]
lastSeen[s[j]] = j + 1
ans = max(ans, j -i + 1)
j += 1
return ans
Time: O(N) Space: O(N)
O(N) O(N). 哈希记录每一个字符出现的最后的位置,如果出现过了,就将左指针跳到最后出现位置的前一位,遍历中不断计算最大的左右指针差距
class Solution {
public int lengthOfLongestSubstring(String s) {
int[] cache = new int[128];
int res = 0;
for(int i = 0, j = 0; i < s.length(); i++){
if(cache[s.charAt(i)] > 0) j = Math.max(j, cache[s.charAt(i)]); //将左指针跳到当前无重复值的最大index。
cache[s.charAt(i)] = i + 1; //更新最后出现的位置
res = Math.max(i - j + 1, res);
}
return res;
}
}
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
ans = 0
i = 0
hashmap = defaultdict(int)
for j in range(len(s)):
hashmap[s[j]] += 1
if hashmap[s[j]] == 1:
ans = max(ans, j - i + 1)
else:
while hashmap[s[j]] > 1:
hashmap[s[i]] -= 1
i += 1
return ans
TC: O(N) SC:O(128)
O(n^2)
O(n)
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
if s == '':
return 0
maxlen=1
flag=0 #重复元素的下标
for i in range(1,len(s)):
leng=1
j=i
while j > flag:
if s[i]!=s[j-1]:
leng=leng+1 #未出现重复元素,长度加一
j=j-1
else:
flag=j #出现重复的,下一次就从重复元素的下一个开始比较
break
maxlen=max(maxlen,leng)
return maxlen
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s == null || s.length() == 0) return 0;
int left = 0;
int ans = 0;
HashMap<Character, Integer> map = new HashMap<>(); // map:<character, index>
for (int i = 0; i < s.length(); i ++) {
char c = s.charAt(i);
if (map.containsKey(c)) {
if (map.get(c) >= left) {
left = map.get(c) + 1;
}
}
ans = Math.max(ans, i - left + 1);
map.put(c, i);
}
return ans;
}
}
import collections
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
# hashmap: {key: char, value: frequency}
hashmap = collections.defaultdict(int)
ans = 0
l = 0
for r in range(len(s)):
# 用while不是if
while hashmap.get(s[r], 0) != 0:
hashmap[s[l]] = hashmap.get(s[l], 0) - 1
l += 1
hashmap[s[r]] = hashmap.get(s[r], 0) + 1
ans = max(ans, r-l+1)
return ans
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
hashmap = defaultdict(int)
i = 0
ans = 0
for j in range(len(s)):
hashmap[s[j]] += 1
while hashmap[s[j]] > 1:
hashmap[s[i]] -= 1
i += 1
ans = max(ans, j - i + 1)
return ans
Time complexity O(n) Space complexity <=O(128)
def lengthOfLongestSubstring(self, s):
start_pos = 0
current_pos = -1
max_length = 0
char_pos = {}
for current_pos in range(len(s)):
if s[current_pos] in char_pos and char_pos[s[current_pos]] >= start_pos :
max_length = max(max_length, current_pos - start_pos)
start_pos = char_pos[s[current_pos]] + 1
char_pos[s[current_pos]] = current_pos
return max(max_length, current_pos - start_pos + 1)
//s6
//s6
class Solution {
public int lengthOfLongestSubstring(String s) {
int res = 0, left = 0;
HashSet<Character> set = new HashSet<>();
for(int i = 0;i < s.length();i++) {
char cur = s.charAt(i);
while(set.contains(cur)){
char leftChar = s.charAt(left);
set.remove(leftChar);
left++;
}
set.add(cur);
res = Math.max(res, set.size());
}
return res;
}
}
time: O(N) space: O(N)
import collections
import heapq
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
hashmap = collections.Counter(nums)
heap = []
for num, frequency in hashmap.items():
heapq.heappush(heap, (frequency, num))
if len(heap) > k:
heapq.heappop(heap)
ans = []
while heap:
num = heapq.heappop(heap)[1]
ans.append(num)
return ans
// 1-2
class Solution {
public:
// 滑动窗口
int lengthOfLongestSubstring(string s) {
if (s.size() == 0) return 0;
unordered_set<char> uset;
int length = 0;
int left = 0;
for (int i = 0; i < s.size(); i++) {
while (uset.find(s[i]) != uset.end()) {
uset.erase(s[left]);
left++;
}
uset.insert(s[i]);
length = max(length, i - left + 1);
}
return length;
}
};
思路: 滑动窗口加哈希表。首先设定好左右窗口位置,其次,让右边一直往前走,直到遇到了哈希表有值的情况就停下来,让左边往前走并删除响应哈希表。用右边减左边 + 1计算窗口大小。
func lengthOfLongestSubstring(s string) int {
cur := map[byte]int{}
rk,ans := -1,0
for i := 0;i < len(s);i ++ {
if i != 0{
delete(cur,s[i - 1])
}
for rk + 1 < len(s) && cur[s[rk + 1]] == 0{
cur[s[rk + 1]] = 1
rk ++
}
ans = max(ans,rk + 1 - i )
}
return ans
}
func max(a int, b int) int {
if a > b{
return a
}else {
return b
}
}
空间复杂度:字符集大小 时间复杂度:N
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
n = len(s)
if n <= 1:
return n
l = 0
ans = 0
hashmap = {}
for r in range(0,n):
if not hashmap.__contains__(s[r]):
hashmap[s[r]] = True
else:
hashmap[s[r]] = not hashmap[s[r]]
while(hashmap[s[r]]== False):
hashmap[s[l]] = not hashmap[s[l]]
l += 1
ans = max(ans,r-l+1)
return ans
使用hash来充当一个滑动窗口
class Solution { public int lengthOfLongestSubstring(String s) { int res = 0; int left = 0,right = 0; HashSet<Character> set = new HashSet<>(); while(right<s.length()){ char temp = s.charAt(right++); if(!set.contains(temp)){ set.add(temp); }else{ while(set.contains(temp)){ set.remove(s.charAt(left++)); } set.add(temp); } res = Math.max(res,set.size()); } return res; } }
时间复杂度:O(n)
空间复杂度:O(n)
用hashmap存储字符串字符出现个数,定义一个双指针,left负责削减头部,right用于判断该字符数量是否超过1,超过1就停下,没超过就继续,最终找到最长无重复字符的子串
func lengthOfLongestSubstring(s string) int {
m := make(map[byte]int,0)
n := len(s)
right,ans :=-1,0
for left :=0; left <n; left++{
if left !=0{
delete(m, s[left-1])
}
for right+1 <n &&m[s[right+1]] == 0{
m[s[right+1]]++
right++
}
ans = max(ans, right-left+1)
}
return ans
}
func max(x, y int) int {
if x<y{
return y
}
return x
}
时间:O(n) 空间:O(n)
使用双指针形成一个滑动窗口,并用hash表统计窗口内字符数,一旦窗口内某个字符数重复次数超过1了,就移动左边界使该字符重复次数回到1
class Solution {
public int lengthOfLongestSubstring(String s) {
int[] hash=new int[128];
int left=0;
int res=0;
for(int right=0; right<s.length(); right++){
while(hash[s.charAt(right)]==1){
hash[s.charAt(left)]--;
left++;
}
hash[s.charAt(right)]++;
res=Math.max(res, right-left+1);
}
return res;
}
}
时间复杂度:O(n) 空间复杂度:O(1)
滑动窗口
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
const len = s.length;
const set = new Set();
let left = 0, right = -1, maxLen = 0;
while (left < len) {
if (left !== 0) {
// 移除字符
set.delete(s[left - 1]);
}
while (right + 1 < len && !set.has(s[right + 1])) {
// 添加字符
set.add(s[right + 1]);
// 右指针移动
right++;
}
// 更新答案
maxLen = Math.max(maxLen, right - left + 1);
// 左指针移动
left++;
}
return maxLen;
};
时间:O(N) 空间:O(N)
滑动窗口+哈希表
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.equals("")) return 0;
char[] input = s.toCharArray();
int i = 0, j = 0, result = 0, temp=0;
Map<Character, Integer> records = new HashMap<>();
while(i<input.length && j<input.length) {
if(records.get(input[j]) == null || records.get(input[j]) < i) {
records.put(input[j],j);
j++;
temp++;
} else {
result = Math.max(temp,result);
i = records.get(input[j]) + 1;
records.put(input[j],j);
j++;
temp = j - i;
}
}
result = Math.max(temp,result);
return result;
}
}
时间复杂度 O(N) 空间复杂度 O(N)
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
双指针+滑动窗口+hashset,遍历字符串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
unordered_set<char> cnt;
int n = s.size();
int ptr = -1, ans = 0;
for (int i = 0; i < n; ++i) {
if (i != 0) {
cnt.erase(s[i - 1]);
}
while (ptr + 1 < n && !cnt.count(s[ptr + 1])) {
cnt.insert(s[ptr + 1]);
++ptr;
}
ans = max(ans, ptr - i + 1);
}
return ans;
}
};
复杂度分析
# 题解
# 双指针+哈希表
# 遍历字符串,若当前元素在之前出现过,更新左指针
# 当之前出现的元素在左右指针中间,左指针更新为之前元素下标,若不在中间,左指针不变
# 当前元素加入哈希表
# 复杂度分析
# O(N)
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
dic, res, i = {}, 0, -1 #左指针
for j in range(len(s)): #右指针
if s[j] in dic: #当前元素在之前出现过,更新左指针
#之前出现过的元素在左右指针中间,左指针更新为之前元素下标,若不在左右指针中间,左指针不变
i = max(i, dic[s[j]])
dic[s[j]] = j #将当前元素加入哈希表中
res = max(res, j - i)
return res
3. 无重复字符的最长子串
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
前置知识
题目描述
示例 1:
输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 示例 3:
输入: "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。