leetcode算法:3.无重复字符的最长子串

无重复字符的最长子串

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

示例 1:

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

示例 2:

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

示例 3:

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

思考

考虑空间复杂度

  1. 要求空间复杂度O(1)
  2. 允许空间复杂度O(n)

解答

  • 对于要求空间复杂度O(1)的这种情况,需要双层循环暴力搜索。
  • 对于允许空间复杂度O(n)的这种情况,空间换时间,可以达到时间复杂度O(n)。思路是用一个指针指示不重复字符串的开始位置,利用这个指针计算当前字符串长度,然后从第一个字符串开始搜索,每搜索一个字符串时查看是否有重复,没有重复继续下一个并更新不重复字符长度,有则将指针移动前面那个重复字符的下一字符处。

举个例子: 对于abcabc,首先指针p指向index为0的a,然后循环遍历字符串,遍历到index为1的b时,指针p指向a(index为0),此时未出现重复字符串,当前子串最大长度为index(b) - p = 1-0+1=2,然后继续遍历移动字符c,同理,此时index为2(字符c),指针p指向a(index为0),当前子串最大长度为index(b) - p = 1-0+1=2,继续遍历到字符a,此时a重复,从map中查询到前面a的index为0,则为保持不重复字符串的特性,需将指针p移到到a的下一位,因此p=index(a)+1。每次都计算最长子串长度,直到遍历结束。

package algo

func lengthOfLongestSubstring(s string) int {
	if len(s) < 1 {
		return 0
	}
	if len(s) == 1 {
		return 1
	}

	var (
		charMap               = make(map[int32]int)
		maxLength             = 0
		uniqueCharStringStart = 0
	)

	for index, each := range s {
		// 判断字符是否重复
		if at, ok := charMap[each]; ok {
			// 重复则将不重复字符串首字符位置指示符移动到重复字符后
			if at >= uniqueCharStringStart {
				uniqueCharStringStart = at + 1
			}
		}

		if index-uniqueCharStringStart+1 > maxLength {
			maxLength = index - uniqueCharStringStart + 1
		}

		charMap[each] = index
	}

	return maxLength
}

  

单元测试

package algo

import (
	"testing"
)

func TestLengthOfLongestSubstring(t *testing.T) {
	s1 := "abcdabcd"
	s2 := "abcabc"
	s3 := "aaaaaa"
	s4 := "abcddcba"
	s5 := "abcdefg"
	s6 := ""
	s7 := " "
	s8 := "  "
	s9 := "dvdf"

	if lengthOfLongestSubstring(s1) != 4 {
		t.Fatal()
	}
	if lengthOfLongestSubstring(s2) != 3 {
		t.Fatal()
	}
	if lengthOfLongestSubstring(s3) != 1 {
		t.Fatal()
	}
	if lengthOfLongestSubstring(s4) != 4 {
		t.Fatal()
	}
	if lengthOfLongestSubstring(s5) != 7 {
		t.Fatal()
	}
	if lengthOfLongestSubstring(s6) != 0 {
		t.Fatal()
	}
	if lengthOfLongestSubstring(s7) != 1 {
		t.Fatal()
	}
	if lengthOfLongestSubstring(s8) != 1 {
		t.Fatal()
	}
	if lengthOfLongestSubstring(s9) != 3 {
		t.Fatal()
	}
}

  

posted @ 2020-07-22 23:04  impluse  阅读(184)  评论(0编辑  收藏  举报