【LeetCode】不含重复字符的最长子字符串Java题解

149 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第36天,点击查看活动详情

题目描述

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

示例 1:

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

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

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

来源:力扣(LeetCode) 链接:leetcode.cn/problems/wt… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析

  • 今天的算法题目是字符串处理题目,题目要求 找出其中不含有重复字符的 最长连续子字符串 的长度。
  • 首先,不含有重复字符,我们可以使用 hashSet 数据结构来进行排重。容易想到的解法是,对字符串进行双重遍历,分别枚举子字符串进行求解。
  • 在使用普通解法求解题目的时候,发现在遍历的过程中对子字符串有重复计算法的部分。根据重复计算,我们可以进行优化,采用滑动窗口的思想,动态更新不重复的子字符串。我们两个指针变量,分别指向滑动窗口的左右区间。首先固定左区间位置,然后使用 hashset 判断是否包含重复的字符,更新右区间的位置。遇到重复字符,就更新左区间的位置。实现代码如下,供参考。

通过代码

  • 普通解法

    class Solution {
        public int lengthOfLongestSubstring(String s) {
            int ans = 0;
            if (s == "") {
                return ans;
            }
            int n = s.length();
            int[] dp = new int[n];
            for (int i = 0; i < n; i++) {
                dp[i] = 1;
                int j = i + 1;
                Set<Character> set = new HashSet<>();
                set.add(s.charAt(i));
                while (j < n && !set.contains(s.charAt(j))) {
                    set.add(s.charAt(j));
                    dp[i] = (j - i + 1);
                    j++;
                }
                ans = Math.max(ans, dp[i]);
            }
    
            return ans;
        }
    }
    
  • 滑动窗口解法

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int ans = 0;
        if (s == "") {
            return ans;
        }

        Set<Character> set = new HashSet<>();
        int n = s.length();
        int rk = -1;
        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++;
            }
            ans = Math.max(ans, rk - i + 1);
        }

        return ans;
    }
}

总结

  • 普通算法的时间复杂度是O(n * n),空间复杂度是O(n)。
  • 滑动窗口解法的时间复杂度是O(n),空间复杂度是O(1)。
  • 坚持算法每日一题,加油!