LeetCode解题(5)Java无重复字符的最长子串

题目

无重复字符的最长子串

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

示例 1:

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

示例 2:

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

示例 3:

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

错误过程

勿用,效率极差

 public int lengthOfLongestSubstring(String s) {
        int num=0;
        int len=0;

        List list=new ArrayList();
        char[] str =s.toCharArray();

        for(int i=0;i<str.length;i++){
            if (list.contains(str[i])){
                int k=list.size();
                if(len<k)
                    len=k;
                num=list.indexOf(str[i]);
                int x=num;
                for(int j=0;j<=x;){
                    list.remove(j);
                    x--;
                }
            }
            list.add(str[i]);
            if(i==str.length-1){
                if(len<list.size()){
                    len=list.size();
                }
            }
        }
        if (len == 0) {
            len=list.size();
        }
        return len;
    }

最初想:设置一个ArrayList,将String s转换成char[]数组,然后一个个加入,在加入数组的过程中比较数组前面的元素,存在相同的就去掉前面的子串(0到第一个相同元素)

在实现过程中出了各种各样的错误
remove方法每次删除都会把序号向前移,导致需要设置一个信号x

				num=list.indexOf(str[i]);
                int x=num;
                for(int j=0;j<=x;){
                    list.remove(j);
                    x--;
                }

没有重复,也就不进入去子串过程,需要多一句判断

        if (len == 0) {
            len=list.size();
        }

如果“aab”这种字符串,去子串后的子串最长,又需要判断

			if(i==str.length-1){
                if(len<list.size()){
                    len=list.size();
                }
            }

在这里插入图片描述

效率极差,还花了这么多时间考虑,当然,比暴力解法要好一些
这就是刚碰LeetCode狼狈的样子,还需学习
后面看了官方的方法,原来我这个本质上也是滑动窗口法,只是不够系统

官方的方法 - 滑动窗口

public class Solution {
    public 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;
    }
}


作者:LeetCode
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/wu-zhong-fu-zi-fu-de-zui-chang-zi-chuan-by-leetcod/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

在这里插入图片描述
设置一个Map,Map的key放字符,value放该字符所在数组下标

如果下一个字符在[i,j]找到重复的,将{i,map.get(s.charAt(j))}中大的那个替代i,也就是窗口滑动

 if (map.containsKey(s.charAt(j))) {
     i = Math.max(map.get(s.charAt(j)), i);
 }

ans表示数组的大小,也就是无重复字符的最长子串

  ans = Math.max(ans, j - i + 1);
发布了95 篇原创文章 · 获赞 25 · 访问量 4210

猜你喜欢

转载自blog.csdn.net/key_768/article/details/104413276