引言:用Js攻略leetcode中的算法这揣,將會(huì)介紹自己的思路和注意點(diǎn)涝开,一邊學(xué)習(xí)一邊愉快刷題呀穗酥。
問題:
給定一個(gè)字符串护赊,找出不含有重復(fù)字符的最長子串的長度惠遏。
示例 1:
輸入: "abcabcbb"
輸出: 3
解釋: 無重復(fù)字符的最長子串是 "abc",其長度為 3骏啰。
示例 2:
輸入: "bbbbb"
輸出: 1
解釋: 無重復(fù)字符的最長子串是 "b"节吮,其長度為 1。
示例 3:
輸入: "pwwkew"
輸出: 3
解釋: 無重復(fù)字符的最長子串是 "wke"判耕,其長度為 3透绩。
請(qǐng)注意,答案必須是一個(gè)子串壁熄,"pwke" 是一個(gè)子序列 而不是子串帚豪。
思考:
采用動(dòng)態(tài)的劃窗來查找無重復(fù)子串,用noRepeatHead指示當(dāng)前劃窗的起始位置草丧,noRepeatEnd指示當(dāng)前劃窗的下一個(gè)需要驗(yàn)證的元素,當(dāng)前不重復(fù)的字符組成的劃窗子串為initialString狸臣。
初始時(shí):
查找noRepeatEnd對(duì)應(yīng)的元素是否在initialString中存在,若不存在昌执,劃窗自動(dòng)加上這個(gè)元素烛亦,然后變成下面的狀態(tài):
若元素已經(jīng)存在,直接截取從重復(fù)元素到當(dāng)前元素的字符串懂拾,保持整個(gè)字符串中字符不重復(fù)煤禽。
(因?yàn)橹蟮淖址赡芨L,比如‘a(chǎn)bcbedg’, 原先的initialString為abc, 第四個(gè)字符‘b’在initialString中岖赋,直接截取‘cb’檬果,再往后判斷,因?yàn)橥罂赡苡凶哟饶壳暗淖畲箝L度3還要大贾节,例如‘cbedg’的長度5)
因?yàn)榻厝『箝L度肯定不大于之前noRepeatHead和noRepeatEnd之間的長度汁汗,所以直接不判斷temp(當(dāng)前initialString的長度)和返回值(nowMaxLength)的大小
直到noRepeatHead到達(dá)字符串末尾結(jié)束(下圖 noRepeatEnd == s.length 了):
或者從noRepeatHead到字符串末尾的長度已經(jīng)不能超過當(dāng)前的最大長度(nowMaxLength)了,自然就不關(guān)心是否要繼續(xù)判斷:
代碼:
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
var result = 0;
if(s.length <= 1) {
return s.length;
}
var nowMaxLength = 1, noRepeatHead = 0, noRepeatEnd = 1;
var initialString = s[0]; var temp = 1, index = -1;
do {
index = initialString.indexOf(s[noRepeatEnd]);
if(index == -1) {
temp++;
if(temp>nowMaxLength){
nowMaxLength = temp;
}
initialString += s[noRepeatEnd];
noRepeatEnd ++;
} else {
noRepeatHead = noRepeatHead+ index + 1;//重復(fù)的話就把頭移到重復(fù)元素的下一個(gè)元素上知牌;
noRepeatEnd ++;
initialString = s.substring(noRepeatHead, noRepeatEnd);
temp = initialString.length;
}
}while(noRepeatHead < (s.length - nowMaxLength) && (noRepeatEnd < s.length));
return nowMaxLength;
};