題目: 無重復字符的最長子串
描述:
給定一個字符串 s ,請你找出其中不含有重復字符的 最長子串 的長度。
示例 1:
輸入: s = “abcabcbb”
輸出: 3
解釋: 因為無重復字符的最長子串是 “abc”,所以其長度為 3。
leetcode鏈接
方法一:滑動窗口(雙指針)
設定兩個指針left和right指向最長子串的頭部和尾部的下一個元素,left和right初始分別為0和1,對于right指向的每一個元素我們都在前面left和right區間內尋找是否出現過,若未出現過,則把它加入子串中,,right指針右移,若出現過,left指針移動到出現的元素后一個位置,right指針移動到出現的元素后兩個位置,最后再更新最長子串的長度
時間復雜度:o(n2) 需要遍歷一遍字符串的時間復雜度為o(n),對于每一個新加入的元素都需要進行查找操作,時間復雜度為o(n),因此總時間復雜度為o(n2)
空間復雜度:o(1) 都在原字符串上進行操作,無需占用新的內存空間
int lengthOfLongestSubstring(string s) {int n = s.size();if(n==1){//字符串只有一個元素,那么最長無重復子串長度也為1return 1;}int left = 0,right = 1;int maxLen = 0;while(right<n){int i = left;//在子串中查找相同的元素while(s[right]!=s[i]&&i<right){i++;}if(i==right){//沒有相同的元素則加入子串中right++;}else{left = i+1;right = i+2;}//更新最大的子串長度maxLen = max(maxLen,right-left);}return maxLen;
}
方法二:滑動窗口+哈希表判斷重重復元素
對于方法一中我們判斷重復元素需要遍歷一遍子數組,時間復雜度為o(n),因此我們考慮用哈希表來優化查找重復元素的時間,我們把子數組的每一個元素存儲到哈希表中,哈希表查找的時間復雜度為o(1),同樣的我們定義兩個指針left和right,left
指向子數組的起始位置,right指向待加入的元素,然后我們利用count()判斷right指向的元素是否在子數組中存在,如果不存在,那么加入哈希表中,如果存在刪除哈希表中鍵為s[left]的元素,然后left右移動,循環此操作直到right指向的元素在子數組中不出現為止,最后維護最大的子數組長度。
時間復雜度:o(n)left,right指針均只會向右移動,遍歷一遍字符串,時間復雜度為o(n)
空間復雜度:o(n)哈希表的空間為o(n)
int lengthOfLongestSubstring(string s) {int n = s.size();int left = 0,right = 0;int maxLen = 0;unordered_map<char,int> map;while(right<n){while(left<right&&map.count(s[right])){//刪除有重復字符的子串直至不出現重復的字符map.erase(s[left++]);}//把right指向的元素當成關鍵字插入mapmap[s[right++]] = 0;maxLen = max(maxLen,right-left);}return maxLen;}