leetCode-3: 无重复字符的最长子串

题目描述

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

示例

示例 1:
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

示例 2:
输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。

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

解题思路

方法一:双指针法(滑动窗口)

步骤
(1)设置变量 i 和 left 来控制滑动窗口的大小,left 控制左边界,i 控制右边界,result 作为最终返回的最长子字符串的大小;
(2)开辟 O(n) 的空间使用 HashMap 来临时存放子串,子串的范围便是 [left, num];
(3)使用控制右边界的变量 i 去遍历整个字符串;
(4)如果 map 中没有下标 i 所对应的字符,则将该字符作为 map 的 key,下标 i 作为 map 的 value 存放到 map 中;
(5)如果 map 中有当前下标 i 所对应的字符,则更新 map 中该 key 对应的 value 值为 i,并将 left 移动至 i 处,表示滑动窗口左边界移动;
(6)每次循环之后给 result 重新赋值,取 (i - left + 1) 与当前 result 的最大值,赋值给 result,最后返回 result 即为最终结果。
说明:若存在字符串"tmmzuxt",则有以下处理过程:
初始值:left = 0,result = 0,map 为空
第一步:left = 0,i = 0,map 中无 't' 元素,则存储,result = 1,此时滑动窗口的边界为 [0,0];
第二步:left = 0,i = 1,map 中无 'm' 元素,则存储,result = 2,此时滑动窗口的边界为 [0,1];
第三步:left = 0,i = 2,map 中有 'm' 元素,value 为 1,更新其 value 为 2,并使 left = i = 2,此时滑动窗口的边界为 [2,2];
第三步:left = 2,i = 3,map 中无 'z' 元素,则存储,result = 2,此时滑动窗口的边界为 [2,3];
第四步:left = 2,i = 4,map 中无 'u' 元素,则存储,result = 3,此时滑动窗口的边界为 [2,4];
第五步:left = 2,i = 5,map 中无 'x' 元素,则存储,result = 5,此时滑动窗口的边界为 [2,5];
第六步:left = 2,i = 6,map 中无 't' 元素,则存储,result = 5,此时滑动窗口的边界为 [2,6];
最终返回 result = 6,此时最长子串为 "mzuxt"。
时间复杂度

只需要遍历一次字符串,故时间复杂度为 O(n),但是因使用了空间换时间的方法,所以空间复杂度为 O(n).

代码展示
package com.jx.leetcode.medium;

import java.util.HashMap;
import java.util.Map;

/**
 * LeetCode第三题:无重复字符的最长子串
 * @author jiaoxian
 */
public class LengthOfLongestSubstring {

    public static int lengthOfLongestSubstring(String s) {
        if (s.length() == 0) {
            return 0;
        }
        int result = 0;
        int left = 0;
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            if (map.containsKey(s.charAt(i))) {
                left = Math.max(map.get(s.charAt(i)) + 1, left);
                map.put(s.charAt(i), i);
            } else {
                map.put(s.charAt(i), i);
            }
            result = Math.max(i - left + 1, result);
        }
        return result;
    }

    public static void main(String[] args) {
        String s = "pwweke";
        Long startTime = System.currentTimeMillis();
        int result = lengthOfLongestSubstring(s);
        Long endTime = System.currentTimeMillis();
        System.out.println("result = " + result);
        System.out.println("耗时:" + (endTime - startTime) + "ms");
    }

}

你可能感兴趣的:(#,LeetCode之中等题库,LeetCode,无重复字符的最长字串)