Leetcode刷题——无重复字符的最长子串


给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
题目链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

  • 示例1
输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
  • 示例2
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
  • 示例3
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。


思路:首先判断极限值,如果数组长度为0,就直接返回。定义一个最大长度num,创建一个HashSet存储无重复的元素,从每一个位置开始遍历,调用test()函数。test()函数中,首先要确定递归的出口,然后分为两种情况,如果set中有i位置的元素,就直接返回结果,因为无法继续构成连续的子串。如果set中没有i位置的元素,就尝试将i位置的元素添加到set中,进行下一层的递归调用,直到输出结果。

class Solution {
        public int lengthOfLongestSubstring(String s) {
            if(s.length() == 0) {
                return 0;           //如果数组长度为0,直接返回结果
            }
            int num = 0;      //定义无重复字符的最大长度
            Set answer = new HashSet<>();    //利用set存储无重复的元素
            for(int i =0; i < s.length() && s.length() - i >num ; i++) {    //遍历每一个元素
                int mes = test(s, i, 0, answer);    //调用方法,获得该位置开始无重复的最大长度
                if(num < mes) {     //如果大于,就更新最大长度
                    num = mes;
                }
                answer.clear();     //清空set,以便重新开始
            }
            return num;     //返回结果
        }
        private int test(String s, int i, int count, Set answer) {
            if(i >= s.length()) {       //如果已经遍历了所有,就返回结果
                return count;
            }
            char temp = s.charAt(i);    //获取i位置上的值
            if(answer.contains(temp)) {     //查看set中是否有temp
                return count;       //如果有,就结束调用,直接返回
            }
            answer.add(temp);   //如果set中不存在temp,就尝试把temp加入到集合中
            int msg=test(s, i+1, count+1, answer);  //递归调用下一层
            return msg; //返回结果
        }
    }


思路:这里采用的是滑动窗口的方法。同样创建一个set来存放没有重复的元素,并且设置左指针i=0,右指针j=0。进入while循环,判断set中是否含有j位置元素的指针,如果不含有,则将j位置的元素添加到set中,并且j右移一位,同时更新最大长度。如果含有,则表示从i位置开始的最大长度子串已经确定,那么就从set中删除i位置上的元素,同时i右移一位。

class Solution {
        public int lengthOfLongestSubstring(String s) {
            if(s.length() == 0) {
                return 0;           //如果字符串长度为0就直接返回
            }
            int i = 0, j = 0;       //设置左指针i和右指针j
            int num = 0;            //最大长度
            Set answer = new HashSet<>();    //创建一个set来存放没有重复的元素
            while(i < s.length() && j < s.length()) {   //限定边界条件
                if(!answer.contains(s.charAt(j))) {     //如果set中不含有j位置的元素
                    answer.add(s.charAt(j++));          //将j位置元素添加到set中,并且j+1
                    num = Math.max(num, j - i);         //更新最大长度
                }else {                                 //如果set中含有j位置的元素
                    answer.remove(s.charAt(i++));       //删除i位置上的元素,i+1
                }
            }
            return num;     //返回结果
        }
    }

你可能感兴趣的:(Leetcode刷题——无重复字符的最长子串)