LeetCode.M3
题目:
题目大意:
给定一个字符串S,找出S中最长的无重复字符的字串(不是子序列),返回子串长度。
数据范围:
如图所示,注意:字符串中不止有字母,也有各种符号。
思路:
双指针。
-
遍历字符串s中的每一个元素s[r], 对于每一个r,找到j使得双指针[l, r]维护的是以s[r]结尾的连续不重复子序列,其长度为r - l + 1, 与res比较并更新res。
-
对于每一个r,如何确定l的位置:由于[l, r - 1]是前一步得到的最长连续不重复子序列,所以如果[l, r]中有重复元素,一定是s[r],因此右移l直到s[r]不重复为止(由于[l, r - 1]已经是前一步的最优解,此时l只可能右移以剔除重复元素s[l],不可能左移增加元素,因此,l具有“单调性”)。
-
用HashMap记录子序列s[l, r]中各元素出现次数,遍历过程中对于每一个r,如果[l, r - 1]中含有重复的s[r], 则不断右移l,使得[l, r]中不含有重复的元素(s[r]),然后更新res。进行下一步循环。
代码:
import java.util.HashMap;
import java.util.Scanner;
class Solution {
public int lengthOfLongestSubstring(String s) {
HashMap<Character, Integer> hashMap = new HashMap<>();
int l = 0, res = 0;
for (int r = 0; r < s.length(); r ++ ){
char c = s.charAt(r);
hashMap.put(c, hashMap.getOrDefault(c, 0) + 1);
while (hashMap.get(c) > 1){
char c1 = s.charAt(l);
hashMap.put(c1, hashMap.get(c1) - 1);
l ++ ;
}
res = Math.max(res, r - l + 1);
}
return res;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
Solution solution = new Solution();
System.out.println(solution.lengthOfLongestSubstring(s));
}
}
时空复杂度分析等:
-
时间复杂度 : O(n)
-
空间复杂度 : O(n)