0
点赞
收藏
分享

微信扫一扫

力扣:无重复字符的最长字串 charAt()

题目:给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。
输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

Math.max()的源码

public static int max(int a, int b) { 
         return (a >= b) ? a : b;
     }

思路:
1、定义一个 map 数据结构存储 (k, v),其中 key 值为字符,存储有效字母,value 值为字符位置 +1,加 1 表示从字符位置后一个才开始不重复。
2、我们定义不重复子串的开始位置为 start,结束位置为 end
3、随着 end 不断遍历向后,会遇到与 [start, end] 区间内字符相同的情况,此时将字符作为 key 值,获取其 value 值,并更新 start,此时 [start, end] 区间内不存在重复字符
4、无论是否更新 start,都会更新其 map 数据结构和结果 ans。
5、时间复杂度:O(n)

图解:方便理解,复习
1、
在这里插入图片描述

  • 第一轮循环

在这里插入图片描述

  • 第二轮循环

在这里插入图片描述

  • 第三轮

在这里插入图片描述

  • 第四轮
    在这里插入图片描述
  • 第五轮
    在这里插入图片描述
  • 第六轮
    在这里插入图片描述
public int lengthOfLongestSubstring(String s) {
    int ans = 0;
    HashMap<Character,Integer> map = new HashMap<>();
    //存储起始点结束点。 结束条件。 必定自增的end
    for (int start = 0,end = 0; end < s.length(); end++) {
        char k = s.charAt(end);  //获取当前数组下标的key值
        if (map.containsKey(k)){
            start = Math.max(map.get(k),start);//集合中如果有的话,则把start更新到重复key值所对应的下标位置
        }
        ans = Math.max(ans,end-start+1);// 比较最长字符串,和新串的长度,返回最长,因为start/end都为0 所以加1
        map.put(s.charAt(end),end+1);
    }
    return ans;
}

在这里插入图片描述
但不是最优解,所以我看了一下评论区的大神,下面这个大神的执行用时相对较少,膜拜太猛了,最优解的网址:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/javati-jie-3wu-zhong-fu-zi-fu-de-zui-chang-zi-chua/
如果懒得点进去看的话,我把最优解的代码图解和代码放在下面
在这里插入图片描述

class Solution {
	public int lengthOfLongestSubstring(String s) {
		int i = 0;
		int flag = 0;
		int length = 0;
		int result = 0;
		while (i < s.length()) {
			int pos = s.indexOf(s.charAt(i),flag);
			if (pos < i) {
				if (length > result) {
					result = length;
				}
				if (result >= s.length() - pos - 1) {
					return result;
				}
				length = i - pos - 1;
				flag = pos + 1;
			}
			length++;
			i++;
		}
		return length;
	}
}
举报

相关推荐

0 条评论