題目:請從字串中找出乙個最長的不包含重複字元的子字串,計算該最長子字串的長度。
示例:
示例 1:
輸入: 「abcabcbb」示例 2:輸出: 3 【解釋: 因為無重複字元的最長子串是 「abc」,所以其長度為 3。】
輸入: 「bbbbb」示例 3:輸出: 1 【解釋: 因為無重複字元的最長子串是 「b」,所以其長度為 1。】
輸入: 「pwwkew」求最長子串,是乙個最優解問題,那麼首先應該想到動態規劃,借助輔助陣列空間得到結果。我想到了動態規劃,但陣列中儲存的元素我想錯了,我拿陣列每次儲存字元了,然後寫出來就是暴力法了?。這個帶有一點動態規劃的暴力法思想是這樣的:利用輔助陣列得到了所有子串,儲存最大子串的長度,最後返回即可。輸出: 3 【解釋: 因為無重複字元的最長子串是 「wke」,所以其長度為 3。請注意,你的答案必須是子串的長度,「pwke」 是乙個子串行,不是子串。】
那我們那舉個例子,畫圖理解過程,輸入: 「pwwkew」 輸出: 3
是否重複和重複的兩種結果,我們通過index的值來表示,當不重複,那麼index的值不變,直接index++,即可儲存下乙個元素;如果重複,不是最後乙個元素,j為重複元素的下標,刪除0~j,index需要變化,index-=(j+1),指向刪除後陣列的最後乙個元素,再index++,儲存元素;如果是最後乙個,那麼index=-1,表示陣列沒有元素,然後index++,把元素儲存到0號下標。
我們給出**:
int
lengthoflongestsubstring
(string s)
else
//存在重複,如果重複的數值是陣列最後一位,那麼陣列從頭開始存,否則刪除重複下標前的資料即可,陣列繼續從後儲存
else
//不是最後一位
index-
=(j+1)
;}break;}
} index++
;//陣列下標++
dp[index]
=s[i];}
max=
(index+1)
>max?
(index+1)
:max;
//需要判斷最後一次的子串是否是最長的
return max;
}
這個方法,需要三次迴圈,一次遍歷陣列,一次找重複,一次刪除重複元素之前的數,時間複雜度為o(n^3)極高。
那正確的動態規劃應該是用陣列儲存當前的最長字元長度,而不是字元,即dp[i]表示從0~i位置的最長字元長度,那我們來看一下,如何分析它的初始狀態,轉移方程,返回值。
我們還是用示例:輸入: 「pwwkew」 輸出: 3 來理解過程:
那我們給出**:
//dp陣列儲存i位置最長子串的數字,
intlengthoflongestsubstring
(string s)
else
//雖然重複,但沒有在最長子串中
break;}
}//沒有重複,則直接+1即可
if(flag)
}return max;
}
這個思路,乙個for進行遍歷,乙個for查詢重複,開闢了o(n)的空間。
我們發現這個題目就是不斷地根據 i 和 j 來確定所有子串的長度,每次i-j為子串長度,max儲存最長的。兩個變數,乙個向前遍歷,乙個找重複的。有沒有想到雙指標呢,確實,這個題目也可以拿雙指標解答,它可以節省空間,我們來看一下思路吧:
那我們還是用示例:輸入: 「pwwkew」 輸出: 3 來理解過程:
那我們給出**:
int
lengthoflongestsubstring
(string s)}if
(flag)
//沒有重複元素,視窗擴大
}return max;
}
還是迴圈了兩邊,那有沒有什麼解決辦法,一次性就找到重複元素的位置,那我們會想到陣列,雜湊表,即陣列下標表示元素,陣列儲存出現位置,那我們下面看看。
我們可以利用雜湊表,因為它可以儲存鍵值和數值,我們可以省去迴圈找重複這乙個迴圈,那麼思路是什麼呢,其實主要思想沒變,就是少了迴圈的:
那我們還是用示例:輸入: 「pwwkew」 輸出: 3 來理解過程:
那我們給出**:
//4.引入雜湊表,上面雙指標我們的時間複雜度,第一次for是遍歷,第二次是判斷重複,那麼我們可以引入雜湊,直接得到重複陣列的下標,對滑動視窗的值,進行改變
intlengthoflongestsubstring
(string s)
hash[s[right]
]=right;
//更新資料最後一次出現的位置
res=
max(right-left+
1,res)
;//1-0為1,包含0,1兩個元素
}return res;
}
因為是字串,那麼我們也可以用陣列進行儲存,思路更簡單,雙指標原理不變,就容器變了:
這個過程和上面一樣,那就直接看一下**吧:
int
lengthoflongestsubstring
(string s)
a[s[right]
]=right;
res=
max(right-left+
1,res);}
return res;
}int
main()
加油哦!?。 面試題48 最長不含重複字元的子字串
請從字串中找出乙個最長的不包含重複字元的子字串,計算該最長子字串的長度。假設字串中只包含a z的字元。例如,在字串 arabcacfr 中,最長的不含重複字元的子字串是 acfr 長度為4。我們定義函式f i 表示以第i個字元為結尾的,不包含重複字元的子字串的最長長度。我們從左到右逐一掃瞄字串中的每...
面試題48 最長不含重複字元的子字串
題目描述 請從字串中找出乙個最長的不包含重複字元的子字串,計算該最長子字串的長度。示例 1 輸入 abcabcbb 輸出 3 解釋 因為無重複字元的最長子串是 abc 所以其長度為 3。示例 2 輸入 bbbbb 輸出 1 解釋 因為無重複字元的最長子串是 b 所以其長度為 1。示例 3 輸入 pw...
面試題48 最長不含重複字元的子字串(C )
請從字串中找出乙個最長的不包含重複字元的子字串,計算該最長子字串的長度。示例 1 輸入 abcabcbb 輸出 3 解釋 因為無重複字元的最長子串是 abc 所以其長度為 3。示例 2 輸入 bbbbb 輸出 1 解釋 因為無重複字元的最長子串是 b 所以其長度為 1。示例 3 輸入 pwwkew ...