LeetCode 熱題 HOT 100(02,無重複字符的最長子串)

2021-02-16 玩世不恭的Coder
LeetCode 熱題 HOT 100(02,無重複字符的最長子串)

不夠優秀,發量尚多,千錘百鍊,方可成佛。

算法的重要性不言而喻,無論你是研究者,還是最近比較火熱的IT 打工人,都理應需要一定的算法能力,這也是面試的必備環節,算法功底的展示往往能讓面試官眼前一亮,這也是在大多數競爭者中脫穎而出的重要影響因素。

然而往往大多數人比較注重自身的實操能力,著重於對功能的實現,卻忽視了對算法能力的提高。有的時候採用不同的算法來解決同一個問題,運行效率相差還是挺大的,畢竟我們最終還是需要站在客戶的角度思考問題嘛,能給用戶帶來更加極致的體驗當然再好不過了。

萬法皆空,因果不空。Taoye之前也不怎麼情願花費太多的時間放在算法上,算法功底也是相當的薄弱。這不,進入到了一個新的學習階段,面對導師的各種「嚴刑拷打」和與身邊人的對比,才開始意識到自己「菜」的事實。

講到這,我的眼角又溼了!!!

這次的題目是LeeTCode 熱題 HOT 100的第三題,難度屬於中等,感覺比第二題稍微簡單點。

下面,我們就來看看這道題吧。

題目:無重複字符的最長子串

給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。

題目Url:https://leetcode.com/problems/longest-substring-without-repeating-characters/

示例

輸入: "abcabcbb"
輸出: 3
解釋: 因為無重複字符的最長子串是 "abc",所以其長度為 3。

輸入: "bbbbb"
輸出: 1
解釋: 因為無重複字符的最長子串是 "b",所以其長度為 1。

輸入: "pwwkew"
輸出: 3
解釋: 因為無重複字符的最長子串是 "wke",所以其長度為 3。請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。

思路

根據題目的要求,我們需要輸出無重複字符的最長子串長度,我們不妨用result來代替。

由於需要記錄輸入字符串的每個字符在之前遍歷的子串中是否重複,所以我們需要一個容器對已經遍歷過的字符進行臨時存儲。

進過分析,我們可以發現,臨時容器存儲的數據主要有兩個,一個是字符值,還有一個就是字符在輸入字符串中的索引值,且這兩個屬性有個一一映射關係。所以我們不難得到,可以通過創建一個HashTable來代替該容器,在Python中,則可以使用dict字典來表示。(與HOT 100第一題意思類似)我們不妨將該臨時字典容器用temp_dict來表示。

此外,在對輸入字符串進行遍歷的過程中,還需要用到一個臨時索引,主要用來記錄與遍歷當前字符值相同的上一個字符的索引,比如:示例1中輸入字符串為「abcabcbb」,當我們遍歷到索引為3的時候,此時字符為a,而上一個字符a的索引為0。所以,當我們遍歷到的字符在temp_dict中出現過時,則需要更改與該字符相同的上一個字符的索引,也就是由初始值-1更改為0。我們不妨將這個臨時索引用temp_index來表示

至此,我們得到的完整算法如下(推敲算法流程和下面代碼的實現):

初始化三個變量:result, temp_dict, temp_index = 0, dict(), -1,目標返回值result和temp_dict初始為0和dict()不用解釋,而temp_index之所以初始為-1,主要是因為我們返回新的result的時候,需要與之前的result和遍歷至此時候的最大長度進行比較,取二者的最大值。

對輸入的字符串進行遍歷,判斷如果當前遍歷字符在temp_dict中,且該字符上次出現的索引大於當前更新前的temp_index臨時索引,則需要更新臨時索引temp_index和臨時字典temp_dict。否則將首次出現的字符添加到臨時字典temp_index中,並更新result的值。

遍歷完輸入的字符串之後,返回result

該算法的Python實現:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        result, temp_dict, temp_index = 0, dict(), -1   # 定義初始變量
        for index, value in enumerate(s):               # 對輸入字符串s進行循環遍歷
            if value in temp_dict and temp_dict[value] > temp_index:    # 判斷temp_dict是更新還是添加
                temp_index, temp_dict[value] = temp_dict[value], index  # 更新temp_dcit和temp_index
            # 添加temp_dict,並修改result
            else: temp_dict[value], result = index, max(result, index - temp_index) 
        return result       # 遍歷完成返回目標結果

該算法的C++實現(實現思想同Python):

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int result = 0, temp_index = -1;
        unordered_map<char, int> temp_dict;
        for (int index = 0; index < s.size(); index++) {
            if (temp_dict.count(s[index]) != 0) {
                if (temp_dict[s[index]] > temp_index) {
                    temp_index = temp_dict[s[index]];
                    temp_dict[s[index]] = index;
                }
            }else {
                temp_dict[s[index]] = index;
                result = result > (index - temp_index) ? result : (index - temp_index);
            }
        }
        return result;
    }
};

另外,官方給出了一種滑動窗口的方式實現,主要是找出從每一個字符開始,不包含重複字符的最長子串。

滑動窗口的主要核心思想可以參考官方,或者下面三篇講解的思路,感覺講的很不錯:

《LeetCode第三題:解題思路》: https://blog.csdn.net/boling_cavalry/article/details/86563586

《LeetCode第三題:編碼實現》:https://blog.csdn.net/boling_cavalry/article/details/86654969

《LeetCode第三題:兩次優化》:https://blog.csdn.net/boling_cavalry/article/details/86655675

推薦閱讀:

LeetCode 熱題 HOT 100(00,兩數之和)
LeetCode 熱題 HOT 100(01,兩數相加)
Taoye滲透到一家黑平臺總部,背後的真相細思極恐
《大話資料庫》-SQL語句執行時,底層究竟做了什麼小動作?
那些年,我們玩過的Git,真香
基於Ubuntu+Python+Tensorflow+Jupyter notebook搭建深度學習環境
網絡爬蟲之頁面花式解析
手握手帶你了解Docker容器技術
一文詳解Hexo+Github小白建站
打開ElasticSearch、kibana、logstash的正確方式

相關焦點

  • LeetCode刷題筆記 - 3. 無重複字符的最長子串
    ,各個標籤的題目都有,可以整體練習,本公眾號後續會帶大家做一做上面的算法題。/給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。示例輸入: s = "abcabcbb"輸出: 3 解釋: 因為無重複字符的最長子串是 "abc",所以其長度為 3。
  • 無重複字符的最長子串 | Leetcode題解
    示例 1:輸入: "abcabcbb"輸出: 3解釋: 因為無重複字符的最長子串是 "abc",所以其長度為 3。示例 2:輸入: "bbbbb"輸出: 1解釋: 因為無重複字符的最長子串是 "b",所以其長度為 1。
  • 圖解LeetCode第 3 號問題:無重複字符的最長子串
    題目描述 給定一個字符串,找出不含有重複字符的最長子串的長度。示例 1:  輸入: "abcabcbb"   輸出: 3   解釋: 無重複字符的最長子串是 "abc",其長度為 3。示例 2:  輸入: "bbbbb"  輸出: 1.     解釋: 無重複字符的最長子串是 "b",其長度為 1。
  • 算法連載之求解不含有重複字符的最長子串長度
    問題給定一個字符串,找出其中不含有重複字符的最長子串長度。示例 1:輸入:"abcabcbb"輸出:3解釋:因為無重複字符的最長子串是 "abc",所以其長度為 3。示例 2:輸入:"bbbbb"輸出:1解釋:因為無重複字符的最長子串是 "b",所以其長度為 1。
  • 每日一道算法題,讓你的頭腦更活躍(沒有重複字符的最長子串)
    沒有重複字符的最長子串給定一個字符串,查找不重複字符的最長子字符串的長度。解題思路看到題目,我們可以了解到,我們需要的是沒有重複字符的字符串,由此我想到了HashSet集合,我們可以利用它的特性來處理這道題目。
  • LeetCode 熱題 HOT 100(03,尋找兩個正序數組的中位數)
    LeetCode 熱題 HOT 100(03,尋找兩個正序數組的中位數)不夠優秀,發量尚多,千錘百鍊,方可成佛。算法的重要性不言而喻,無論你是研究者,還是最近比較火熱的IT 打工人,都理應需要一定的算法能力,這也是面試的必備環節,算法功底的展示往往能讓面試官眼前一亮,這也是在大多數競爭者中脫穎而出的重要影響因素。
  • 經典leetcode算法題分享(字符串)
    你可以假設數組中的所有字符都是 ASCII 碼錶中的可列印字符。解題思路:一看到這道題,直呼是送分題,這反轉字符串不就是JavaAPI就有了嗎,於是乎直接大膽的,兩行代碼搞定,好傢夥!387.字符串中的第一個唯一字符題目:給定一個字符串,找到它的第一個不重複的字符,並返回它的索引。如果不存在,則返回 -1。
  • leetcode之字符串相加
    序本文主要記錄一下leetcode之字符串相加題目給定兩個字符串形式的非負整數 num1 和num2 ,計算它們的和。
  • LeetCode刷題實戰3:最長不重複子串
    https://leetcode.com/problems/longest-substring-without-repeating-characters/翻譯題目只有一句話:給定一個字符串,要求返回不包含重複字符的最長子串的長度。
  • [LeetCode] 943. Find the Shortest Superstring 找到最短的超級字符串
    Example 2:Input: ["catg","ctaagt","gcta","ttca","atgcatc"]Output: "gctaagttcatgcatc"Note:1<=A.length<=121<=A[i].length<=20這道題給了一個字符串數組
  • LeetCode-87.擾亂字符串(Scramble String)
    擾亂字符串給定一個字符串 s1,我們可以把它遞歸地分割成兩個非空子字符串,從而將其表示為二叉樹。下圖是字符串 s1 = "great" 的一種可能的表示形式。例如,如果我們挑選非葉節點 "gr" ,交換它的兩個子節點,將會產生擾亂字符串 "rgeat" 。
  • 一文帶你AC十道題【滑動窗口】
    無重複字符的最長子串)[1]【Python】滑動窗口(438. 找到字符串中所有字母異位詞)[4]【930. 和相同的二元子數組】(Java,Python)[6]【992. K 個不同整數的子數組】滑動窗口(Python)[7]【1004. 最大連續 1 的個數 III】滑動窗口(Python3)[8]【1234.
  • 另一道滑動窗口算法題【最長無重複子串】
    一 前言        昨天寫了一個算法題,引出一個求解方法——滑動窗口。很多人只是掃了一眼,沒細看文中代碼,就很不以為意。
  • 一招解決4道leetcode hard題,動態規劃在字符串匹配問題中的應用
    在做leetcode的時候,遇到hard題大家往往都覺得頭疼,但其實,掌握方法,舉一反三,hard題有時候我們也能想到好的思路,順利攻破,今天我們就介紹一下動態規劃在字符串匹配中的應用,相同類型的題目在前120道題中居然出現了4次!有必要好好總結一下!這四道題分別是:10.
  • 整數反轉 | Leetcode題解
    難度:支持語言:JavaScript、Java、Python相關標籤相關企業思路 1:使用字符串在反轉並不是最好的選擇,因為還需要處理負號和0的情況,用數字運算方式反轉比較適合。思路 2:本題如果不考慮溢出問題,是非常簡單的。解決溢出問題有兩個思路,第一個思路是通過字符串轉換加try catch的方式來解決,第二個思路就是通過數學計算來解決。由於字符串轉換的效率較低且使用較多庫函數,所以解題方案不考慮該方法,而是通過數學計算來解決。通過循環將數字x的每一位拆開,在計算新值時每一步都判斷是否溢出。
  • 上升下降字符串 | LeetCode
    「好久沒刷 LeetCode 了,剛打開頁面,啪,每日一題就顯示出來了,很快啊。
  • Leetcode題解 WordBreak
    題意題目:單詞斷開  給定一個非空的字符串s和一個字典wordDict,字典中包含許多非空的單詞,確定字符串s是否可以分割成通過字典中的一個或多個單詞組成的空格隔開的序列.假定字典中不包含重複的單詞.  由於本題每個組成成分都是單詞,也就是每次在原有字符串的返回true的基礎上增加一個字典中的單詞來組成新的能夠返回true的字符串.發現這是一種全局同一限制性的求解問題,限制條件是每次字符串增加的都是一個存在於字典中的單詞.舉個例子說明一下:  比如字符串是"leetcodeisnice
  • 【程式設計師面試金典】【字符串】面試題 10.02 - 變位詞組
    一 目錄 不折騰的前端,和鹹魚有什麼區別目錄一 目錄二 題目三 解題思路四 統計分析五 解題套路二 題目 編寫一種方法,對字符串數組進行排序,將所有變位詞組合在一起。變位詞是指字母相同,但排列不同的字符串。
  • 我說你在 LeetCode 練死勁不好用,他說你這也沒用,我說我這個有用.
    他們說,有一個說我在 LeetCode 刷題,都快刷吐了,你能不能教教我混元功法?幫助提高一下我的刷題姿勢。我說小朋友你要按照戰術來刷題,我說你在 LeetCode 練死勁不好用,他不服氣,他說你這也沒用,我說我這個有用。
  • 第五題:最長回文子串【leetcode】
    給定一個字符串 s,找到 s 中最長的回文子串。你可以假設 s 的最大長度為 1000。