最长无重复子串

第一种

设置一个滑动窗口,左下标记 l, 右下标记r
r 向右移动,记录每个字符的最后一次出现的位置 m
如果当前字符在 m 中存在,并且重复字符出现的位置在l右侧,让l移动到重复字符的下一个位置,跳过重复的字符
r每次移动时,计算r与l的距离,记录最大值

func lengthOfLongestSubstring(s string) int {
	c := []rune(s)
	size := len(c)
	if size <= 1 {
		return size
	}
	l, r, maxLen, k := 0, 0, 0, 0
	ok := false

	m := make(map[rune]int, size)
	for ; r < size; r++ {

		if k, ok = m[c[r]]; ok && k >= l {
			l = k + 1
		}
		if r-l+1 > maxLen {
			maxLen = r - l + 1
		}
		m[c[r]] = r
	}
	return maxLen
}

第二种

速度与第一种差不多,但内存占用少

func lengthOfLongestSubstring(s string) int {
	c := []rune(s)
	size := len(c)
	if size <= 1 {
		return size
	}
	l, r, maxLen := 0, 0, 0

	// 标记字符最后一次出现的位置,不可以使用默认0值,因为下标是从0开始的
	m := [128]int{}
	for i := 0; i < 128; i++ {
		m[i] = -1
	}
	for ; r < size; r++ {

		// 当出现重复字符时,左标记跳到该字符的下一个位置
		l = max(l, m[c[r]]+1)
		// 记录窗口最大长度
		maxLen = max(maxLen, r-l+1)
		// 记录字符出现的位置
		m[c[r]] = r
	}
	return maxLen
}

func max(a int, b int) int {
	if a > b {
		return a
	}
	return b
}