记一次算法优化的过程

最近在使用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。

  

 

嗯, 可以接受。

posted @ 2017-02-20 16:29  Ado_On  阅读(240)  评论(0编辑  收藏  举报