最近在使用LeetCode:https://leetcode.com/
顺道练习golang。
今天下午完成了一个题目,原题如下:
Longest Substring Without Repeating Characters:字符串最长的无重复字符的子字符串
题目连接:https://leetcode.com/problems/longest-substring-without-repeating-characters/?tab=Description
花了点时间熟悉了一下golang的字符串和slice的操作,
主要用到了append方法,
话说golang的数组和slice没有indexOf方法真是不方便。
初步实现的算法是这样的:
func lengthOfLongestSubstring(s string) int {
var length int = len(s)
temp := make([]byte, 0, length)
var curMax []byte
var curStartIndex int
for i := 0; i < length; i++ {
if len(temp) == 0 { //temp length == 0
curStartIndex = i
temp = append(temp, s[i])
} else if indexOf(temp, s[i]) == -1 { //temp not contains s[i]
temp = append(temp, s[i])
} else { //temp contains s[i]
if len(temp) > len(curMax) {
curMax = temp
fmt.Println("record:", string(temp))
}
i = curStartIndex
for len(temp) != 0 {
temp = temp[:0]
}
}
}
if curMax == nil || len(curMax) < len(temp) {
curMax = temp
}
return len(curMax)
}
func indexOf(a []byte, b byte) int {
var length = len(a)
for i := 0; i < length; i++ {
if a[i] == b {
return i
}
}
return -1
}


提交代码,耗时159ms,被81.58%的人打败了!!
这尼玛我能忍?!!
当前实现的算法是:
记录当前子字符串的开始索引,
拼接到无法拼接之后对比当前最大长度字符串的长度,
然后从当前字符串的开始索引+1处又开始遍历。
最差的情况下循环的次数为:
len = 当前字符串长度
次数 = len +(len-1)+...+1
大概这么多次。
于是仔细的想了想,有些啥可以优化的地方。
其实在检测当前字符是否在当前字串中存在,
如果重复了的话,
可以得到当前字符在当前字串中的索引,
那么,就不用重新从当前子字符串索引+1处开始循环,
这里其实是多余的,
只需要更新当前子串,更新子串开始索引即可。
基本上循环len次就可以得出最长子串了。
优化后代码如下:
func lengthOfLongestSubstring(s string) int {
var length int = len(s)
temp := make([]byte, 0, length)
var curMax []byte
var curStartIndex int
for i := 0; i < length; i++ {
if len(temp) == 0 { //temp length == 0
curStartIndex = i
temp = append(temp, s[i])
} else if indexOf(temp, s[i]) == -1 { //temp not contains s[i]
temp = append(temp, s[i])
} else { //temp contains s[i]
if len(temp) > len(curMax) {
curMax = temp
}
var index = indexOf(temp, s[i])
curStartIndex = curStartIndex + index + 1
temp = temp[index+1:]
temp = append(temp, s[i])
}
}
if curMax == nil || len(curMax) < len(temp) {
curMax = temp
}
return len(curMax)
}
func indexOf(a []byte, b byte) int {
var length = len(a)
for i := 0; i < length; i++ {
if a[i] == b {
return i
}
}
return -1
}
优化后打败了91.45%的人,耗时9ms。

嗯, 可以接受。