題目:無重複字符的最長子串java
描述:給定一個字符串,請你找出其中不含有重複字符的最長子串的長度。算法
示例:數組
有了題目001的經驗,咱們應該不會再使用暴力搜索方式來解此題。若使用暴力搜索,要獲得全部的子字符串,須要雙重for循環,時間複雜度爲O(n<sup>2</sup>),獲得的每一個字符串還須要判斷它是否包含重複字符,這一操做也須要O(n)的耗時,從而使得總時間複雜度達到O(n<sup>3</sup>)。這是沒法接受的,因此咱們應該尋求更好的解題方式。學習
此題有一個特定條件:無重複字符。若是使用哈希表來存儲每一個字符,咱們就能夠在構建子串時得知它是否包含重複字符。下面,咱們以示例中的輸入"abcabcbb"爲例,來講明哈希表是如何在此問題中發揮做用的。3d
首先,咱們建一個空的哈希表,key值是每一個字符,value是字符的下標。每當遇到一個哈希表中不存在的字符,咱們就把它存入表中,因此咱們能夠依次存入'a'->'b'->'c'三個字符,哈希表中的數據以下圖:code
當咱們要存入第四個字符時,哈希表中已經存在了該字符 'a',也就是說"abca"這個子串中包含了重複字符。如今,咱們能夠肯定,以第一個字符 'a' 爲起點的最長無重複字符子串就是"abc",且它的長度是 ( 字符 'b' 的下標 - 字符 'a' 的下標 + 1),這個值和哈希表的value正好對應。可是以第二個字符 'b' 爲起點的子串有可能比"bca"更長,咱們還須要看下一個字符是否重複,爲了保證哈希表中的value值和子串中字符的下標值一致,咱們須要把 'a' 的value更新成 3,也就是後一個 'a' 的下標。以下所示:blog
下一個字符是 'b',和上一步狀況一致,咱們確認了以第二個字符 'b' 爲起點的最長無重複字符子串是"bca",且它的長度是 ( 字符 'a' 的下標 - 字符 'b' 的下標 + 1),可是以第三個字符 'c' 爲起點的子串有可能比"cab"更長。重複這個過程,咱們就能夠找到以每一個字符爲起點的最長無重複字符子串。圖片
除了示例的狀況,咱們還要考慮第二種狀況,好比把輸入換成"abcbcad",一開始的結構是一致的,依然是依次存入'a'->'b'->'c'三個字符。當咱們要存入第四個字符時,哈希表中已經存在了該字符'b',可是 'b' 倒是處於中間的字符,這樣一來以第一個字符 'a' 爲起點的最長無重複字符子串是"abc",以第二個字符 'b' 爲起點的最長無重複字符子串是"bc"。而以第三個字符 'c' 爲起點的子串,在當前只包含 'c' 和 'b' 兩個字符,也就是說字符 'a' 是多餘的,以下所示:資源
能夠考慮把 'a' 從表中刪除,但更優雅的方式是使用標記,由於無用字符必定在當前被當作起點的字符以前,因此只要標記好這個字符的位置,就能夠忽略無用字符的存在,以下所示:字符串
之因此不選擇刪除字符,是由於沒法肯定後續是否還會再次出現這個字符,例如本例中字符 'a' 就會在第6位再次出現,這樣咱們以前的刪除操做就毫無心義了。
上述過程,咱們只須要對字符串進行一次遍歷就能獲得結果,時間複雜度僅爲O(n),這比暴力搜索好得多。參考代碼以下:
public int lengthOfLongestSubstring(String s){ Map<Character,Integer> map = new HashMap<>(); int maxLen = 0; int startIndex = 0; int tempMaxLen = 0; for (int i = 0, len = s.length(); i < len; i++) { if (map.containsKey(s.charAt(i)) && map.get(s.charAt(i)) >= startIndex) { startIndex = map.get(s.charAt(i)) + 1; } map.put(s.charAt(i), i); tempMaxLen = i - startIndex + 1; maxLen = maxLen < tempMaxLen ? tempMaxLen : maxLen; } return maxLen; }
以上思路也被稱做滑動窗口法,這個比喻還挺形象,但願你們能記住這個思路,當遇到此類問題時可以多往這方面想想,極大可能想到比暴力搜索好得多的算法。
題目:尋找兩個有序數組的中位數
描述:給定兩個大小爲 m 和 n 的有序數組 nums1 和 nums2。請你找出這兩個有序數組的中位數,而且要求算法的時間複雜度爲 O(log(m + n))。你能夠假設 nums1 和 nums2 不會同時爲空。
示例 1:
示例 2:
相關源碼請加QQ獲取。
【感謝您能看完,若是可以幫到您,麻煩點個贊~】
更多經驗技術歡迎前來共同窗習交流: 一點課堂-爲夢想而奮鬥的在線學習平臺 http://www.yidiankt.com/
![關注公衆號,回覆「1」免費領取-【java核心知識點】]
QQ討論羣:616683098
QQ:3184402434
想要深刻學習的同窗們能夠加我QQ一塊兒學習討論~還有全套資源分享,經驗探討,等你哦!