题目描述

原题链接

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

  1. 输入: s = "abcabcbb"
  2. 输出: 3
  3. 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3

示例 2:

  1. 输入: s = "bbbbb"
  2. 输出: 1
  3. 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1

示例 3:

  1. 输入: s = "pwwkew"
  2. 输出: 3
  3. 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3
  4. 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

示例 4:

  1. 输入: s = ""
  2. 输出: 0

提示:

  1. 0 <= s.length <= 5 * 104
  2. s 由英文字母、数字、符号和空格组成

个人解法

JavaScript

  1. /**
  2. * @param {string} s
  3. * @return {number}
  4. */
  5. var lengthOfLongestSubstring = function(s) {
  6. var arr = [], max = 0
  7. for(var i = 0; i < s.length; i++) {
  8. var index = arr.indexOf(s[i])
  9. if(index !== -1) {
  10. arr.splice(0, index+1);
  11. }
  12. arr.push(s.charAt(i))
  13. max = Math.max(arr.length, max)
  14. }
  15. return max;
  16. };

Java

更优解法

Java

标签:滑动窗口
定义一个map数据结构存储(k,v),其中key值为字符,value值为字符位置+1,+1表示从字符位置后一个开始不重复(保证两个重复元素不在一个区间)。
定义不重复字串开始位置为start,结束位置为end。随着end不断遍历向后,会遇到与[start,end]区间内字符相同的情况,此时将字符作为key值,获取其value值,并更新start,此时[start,end]区间内不存在重复字符。无论是否 更新start,map数据结构和结果ans都会更新。

  1. class Solution {
  2. public int lengthOfLongestSubstring(String s) {
  3. int n = s.length(), ans = 0;
  4. Map<Character,Integer> map=new HashMap<>();
  5. for(int start=0,end=0;end<n;end++){
  6. char a=s.charAt(end);
  7. if(map.containsKey(a))
  8. start=Math.max(start,map.get(a));
  9. ans=Math.max(ans,end-start+1);
  10. map.put(a,end+1);
  11. }
  12. return ans;
  13. }
  14. }

画解:

1.
3.无重复字符的最长子串 - 图1
2.
3.无重复字符的最长子串 - 图2
3.3.无重复字符的最长子串 - 图3
4.3.无重复字符的最长子串 - 图4
5.

3.无重复字符的最长子串 - 图5
6.3.无重复字符的最长子串 - 图6
7.3.无重复字符的最长子串 - 图7

JavaScript

  1. var lengthOfLongestSubstring = function(s) {
  2. // 哈希集合,记录每个字符是否出现过
  3. const occ = new Set();
  4. const n = s.length;
  5. // 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
  6. let rk = -1, ans = 0;
  7. for (let i = 0; i < n; ++i) {
  8. if (i != 0) {
  9. // 左指针向右移动一格,移除一个字符
  10. occ.delete(s.charAt(i - 1));
  11. }
  12. while (rk + 1 < n && !occ.has(s.charAt(rk + 1))) {
  13. // 不断地移动右指针
  14. occ.add(s.charAt(rk + 1));
  15. ++rk;
  16. }
  17. // 第 i 到 rk 个字符是一个极长的无重复字符子串
  18. ans = Math.max(ans, rk - i + 1);
  19. }
  20. return ans;
  21. };