力扣(LeetCode) -- 算法第三题-- 无重复字符的最长子串

题目:

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

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

输入: s = “”
输出: 0

思路:

假设我们选择字符串中第k个字符作为起始位置,并且获得了不包含重复最长子串的结束位置rk。当选择k+1作为起始位置,k+1到rk肯定是不包含重复字符的子串,那么我们增加rk的值变为rk+1。直到右侧出现重复字符,然后比较两个子串的长度。

  • 使用两个指针表示左右边界,左指针代表枚举子串的起始位置,右指针为rk。
  • 右指针不断向右移动一个字符,直到出现重复字符串为止,期间的子串代表着以左指针开始的,不包含重复字符的最长子串
  • 比较每一个子串的长度。

代码实现:

class Solution {
    
    
    //给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
    public int lengthOfLongestSubstring(String s) {
    
    
        Set<Character> set = new HashSet<Character>();
        int n = s.length();
        //右指针
        int rk = -1, count = 0;
        for (int i = 0; i < n; ++i) {
    
    
            if (i != 0) {
    
    
                //左指针往右移动一位,移除一个字符
                set.remove(s.charAt(i - 1));
            }
            while (rk + 1 < n && !set.contains(s.charAt(rk + 1))) {
    
    
                //右指针不断右移,直到出现重复
                set.add(s.charAt(rk + 1));
                ++rk;
            }


            //计算rk到i的数字个数
            count = Math.max(count, rk - i + 1);
        }

        return count;
    }
}

结果:

在这里插入图片描述

感谢你的阅读,不足之处欢迎指正!

猜你喜欢

转载自blog.csdn.net/weixin_51749554/article/details/115424139