Bootstrap

Leetcode JAVA刷刷站(3)无重复字符的最长子串

 一、题目概述

二、思路方向

       为了找出给定字符串中不含有重复字符的最长子串的长度,我们可以使用滑动窗口的方法。这种方法通过维护一个窗口(或称为子串),并动态地调整窗口的左右边界来找到最长的无重复字符子串。

三、代码实现 

public class Solution {  
    public int lengthOfLongestSubstring(String s) {  
        int n = s.length();  
        if (n == 0) return 0;  
  
        // 使用HashMap来存储字符及其最近出现的位置  
        Map<Character, Integer> map = new HashMap<>();  
        int maxLength = 0; // 最长无重复字符子串的长度  
        int left = 0; // 窗口左边界  
  
        for (int right = 0; right < n; right++) {  
            char c = s.charAt(right);  
            // 如果字符c已经在map中,并且其位置在窗口内(即大于等于left),则移动左边界  
            if (map.containsKey(c) && map.get(c) >= left) {  
                left = map.get(c) + 1;  
            }  
            // 更新字符c的最新位置  
            map.put(c, right);  
            // 更新最长无重复字符子串的长度  
            maxLength = Math.max(maxLength, right - left + 1);  
        }  
  
        return maxLength;  
    }  
  
    public static void main(String[] args) {  
        Solution solution = new Solution();  
        String s = "abcabcbb";  
        System.out.println("Length of longest substring without repeating characters: " + solution.lengthOfLongestSubstring(s));  
    }  
}

解释

  1. 初始化:我们初始化一个HashMap来存储每个字符最近一次出现的位置,以及一个变量maxLength来记录最长无重复字符子串的长度。我们还设置两个指针leftright来定义当前考虑的子串的边界。

  2. 遍历字符串:我们使用right指针遍历字符串的每个字符。对于每个字符,我们检查它是否已经在HashMap中,并且其位置是否在当前的窗口内(即大于等于left)。如果是,我们需要移动left指针到该字符上一次出现位置的下一个位置,以确保窗口内没有重复字符。

  3. 更新HashMap和maxLength:然后,我们更新HashMap中当前字符的位置为right,并检查是否需要更新maxLength

  4. 返回结果:遍历完成后,maxLength将包含最长无重复字符子串的长度,我们将其返回。

执行结果: 

四、小结

       这种方法的时间复杂度是O(n),因为我们只遍历了字符串两次(一次是right指针,一次是可能的left指针移动),而HashMap的插入和查找操作都是O(1)的。空间复杂度也是O(min(m, n)),其中m是字符集的大小(对于ASCII字符集,m=128),n是字符串的长度。在最坏的情况下,我们需要存储字符串中的所有不同字符。然而,由于字符集通常远小于字符串长度,因此可以认为空间复杂度是O(min(m, n)),但在实际应用中,它通常接近O(m)。

 结语

勇气不是没有恐惧,而是即便恐惧也依然前行

信心不是没有疑虑,而是即便疑虑也依然坚持

!!!

;