1. 程式人生 > >leetcode演算法題——golang——題(3)

leetcode演算法題——golang——題(3)

給定一個字串,找出不含有重複字元的最長子串的長度。

示例 1:

輸入: "abcabcbb"
輸出: 3
解釋: 無重複字元的最長子串是 "abc",其長度為 3。
示例 2:

輸入: "bbbbb"
輸出: 1
解釋: 無重複字元的最長子串是 "b",其長度為 1。
示例 3:

輸入: "pwwkew"
輸出: 3
解釋: 無重複字元的最長子串是 "wke",其長度為 3。
     請注意,答案必須是一個子串,"pwke" 是一個子序列 而不是子串。

方法一

//abcabcbb
//判斷子串是否合法
//內嵌一個迴圈判斷是否有重複子串
//如果有個重複子串,則start和end的位置增加
//如果不重複則,繼續增加子串的數量
func lengthOfLongestSubstring(s string) int {
	if s == ""{
		return 0
	}
	var strLen = len(s)
	var start,end=0,1
	var s2 string
	for end <= strLen{
		var s1 string = string(s[start:end])
		//計算重複
		var repeatCount int = 1
		var s1Len int = len(s1)
		for i:=0;i < s1Len;i++{
			var temp string = string(s1[i])
			repeatCount = strings.Count(s1,temp)
			//說明有重複的了
			if repeatCount >1{
				start++
				end =start+len(s1)
				break
			}
		}
		if repeatCount ==1{
			//增加
			s2 = s1 //儲存之前的值
			end++
		}
	}
	return len(s2)
}

方法二

//n*n*n  找出該串的所有子串,不重複,且最大即可
func lengthOfLongestSubstring(s string)int{
	var counts int = 0
	for i:=0;i<len(s);i++{
		//找出他所有的子串
		for j:=i+1;j<=len(s);j++{
			if allUnique(s,i,j){
				temp := math.Max(float64(counts),float64(j-i))
				counts = int(temp)
			}
		}
	}
	return counts
}

//找出子串不重複的
func allUnique(s string,start,end int)(bool){
	//會擷取start -> end-1位置的下標
	s = s[start:end]
	for i:=0;i<len(s);i++{
		//返回該子串在主串中的重複數量
		repeatCount := strings.Count(s,string(s[i]))
		if repeatCount !=1 {
			return false
		}
	}
	return true
}

方法三

//利用滑動視窗和容器
func lengthOfLongestSubstring(s string)int{
	//藉助一個容器,來判斷,子串中是否有重複 妙
	m := make(map[byte]byte)
	sLen := len(s)
	start,end := 0,0
	var repeatCount int = 0
	//start 和 end 雙條件判斷,只有end一個也可以,可能這樣更嚴謹一些吧
	for  start <sLen && end <sLen{
		temp := s[end]
		if _,ok := m[temp];!ok{
			//不存在說明該key是唯一的
			m[s[end]] = s[end]
			end++ //移動滑動視窗
			repeatCount = int(math.Max(float64(repeatCount),float64(end-start)))
		}else{
			//說明了有重複的,滑動視窗移動,則start+1,
			delete(m,s[start])
			start++
		}
	}
	return repeatCount

}

方法四

//優化滑動視窗
// abcabcbb
// abc
// bca
// cab
// abc
// cb
// b
func lengthOfLongestSubstring4(s string)int{
	var n,ans = len(s),0
	m := make(map[string]int) //存放字元出現的位置
	for j,i :=0,0; j<n;j++{
		if _,ok := m[string(s[j])];ok{
			//發現重複的,則重新選擇一個i,這個i停留在出現重複的前一位置
			i = int(math.Max(float64(m[string(s[j])]),float64(i))) //這裡的i則為下標
		}
		//每次計算j-i+1的記錄,j為字串的下標,i為下標,重複,i則從重複位置前一位開始
		ans = int(math.Max(float64(ans),float64(j-i+1)))
		m[string(s[j])] = j+1
	}
	return ans
}

推薦是  方法三、方法四