leetcode演算法題——golang——題(3)
阿新 • • 發佈:2018-12-19
給定一個字串,找出不含有重複字元的最長子串的長度。 示例 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
}
推薦是 方法三、方法四