LeetCode:3. Longest Substring Without Repeating Characters

3. Longest Substring Without Repeating Characters

Medium

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3. 
             Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

解法一:暴力破解

    //Brute Force
    public static int lengthOfLongestSubstring(String s) {
        int max = 0 ;
        Set<Character> set = new HashSet<>() ;
        
        for(int i=0; i<s.length(); i++) {
            for(int j=i; j<s.length(); j++) {
                char ch = s.charAt(j) ;
                if(set.contains(ch)) {
                    max = Math.max(max, set.size()) ;
                    set.clear();
                    break ;
                } else {
                    set.add(ch) ;
                }
                
            }
            
        }
        
        
        return Math.max(max, set.size()) ;
    }

解法二:滑动窗口

1. 分别设置两个快慢指针i和j,起始位置均在0位;i为慢指针,j为快指针

2. 依次遍历字符串s中的每个字符ch,并设置集合Set用于缓存当前快慢指针之间的子字符串

  1)如果ch不在set中,说明当前子字符串还未出现在快慢指针之间的字符串中,所以该子字符串还有进一步扩大的可能;所以快指针j++;i保持不动;且与当前保持的最大值max做比较,记录最大值;

  2)如果ch在set中,说明当前字符已在快慢指针之间的字符串中出现过了,所以当前子字符串遍历结束,(如果继续遍历则会在子字符串中出现重复字符);此时需要慢指针i右移一位+1,开始重新计算子串,但需要将移动之前的所指字符从set中删除掉;且快指针j不动。

  3)重复步骤1)2)直到i或者j到达字符串末尾为止

  4)max记为最长子字符串长度

    //Sliding Window
    public static 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;
    }

解法三:滑动窗口(优化版)

    // Sliding Window Optimized
    public static int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0;
        Map<Character, Integer> map = new HashMap<>(); // current index of character
        // try to extend the range [i, j]
        for (int j = 0, i = 0; j < n; j++) {
            if (map.containsKey(s.charAt(j))) {
                i = Math.max(map.get(s.charAt(j)), i);
            }
            ans = Math.max(ans, j - i + 1);
            map.put(s.charAt(j), j + 1);
        }
        return ans;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yexianyi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值