给定一个字符串,找出不含有重复字符的最长子串的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 无重复字符的最长子串是 "abc",其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 无重复字符的最长子串是 "b",其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 无重复字符的最长子串是 "wke",其长度为 3。
请注意,答案必须是一个子串,"pwke" 是一个子序列 而不是子串。
思路:给定一个队列,添加计数,检测是否有重复的key,重复则出列,直到key出列,然后key进队列计算count=size
若无重复则count++
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s.equals("")) {
return 0;
}
int count = 1;
int max=1;
Queue<Character> list = new LinkedList<Character>();
list.offer(s.charAt(0));
for (int i = 1; i < s.length(); i++) {
if (list.contains(s.charAt(i))) {
do {
list.poll();
} while (list.contains(s.charAt(i)));
list.offer(s.charAt(i));
count = list.size();
} else {
++count;
list.offer(s.charAt(i));
}
if (max < count) {
max = count;
}
}
return max;
}}
其中队列可以替换为为hashset,同理.,两个指针,一个表示当前,一个表示删除指针,删除一直进行到不包含当前char为止
class Solution {
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Set<Character> set = new HashSet<>();
int ans = 0, i = 0, j = 0;
while (i < n && j < n) {
// try to extend the range [i, j]
if (!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
ans = Math.max(ans, j - i);
}
else {
set.remove(s.charAt(i++));
}
}
return ans;
}}
还可以继续优化,这里时间复杂度为2n
可以继续优化为n,使用map,key为char,value记录当前char的下标,当发现重复的时候 j 直接跳到
Max(重复的地方+1 ,j)//防止abcba 出现 j变小的现象 ,j只会线性增加
class Solution {
public int lengthOfLongestSubstring(String s) {
HashMap<Character,Integer> map = new HashMap<>();
int j=0,ans=0;
for(int i=0;i<s.length();i++){
if(map.containsKey(s.charAt(i))){
j =Math.max(map.get(s.charAt(i))+1,j) ;
}
ans = Math.max(ans,i-j+1);
map.put(s.charAt(i),i);
}
return ans;
}}
这里map可以还可以优化为数组 int[] a = new int[];
int [26]
用于字母 ‘a’ - ‘z’或 ‘A’ - ‘Z’int [128]
用于ASCII码int [256]
用于扩展ASCII码- index[s.charAt(i)] = i;