前言
本文已收錄 GitHub https://github.com/ponkans/F2E(有怪怪整理的大前端知識技能樹),歡迎 Star,持續更新?
說實話,第一次寫演算法的怪怪,有點緊張,畢竟是一個數學怎麼也及不了格的小菜。
大一上期末全班倒數第4,噗呲,學渣實錘~
寫之前有在想,怎麼把演算法寫的比較有意思,就像大學高數課,說實話,老師講的是真心無聊。。
如果不是被所謂的學業規則所限制,真的很難聽下去。
設 M(x0,y0,z0) 為平面上的已知點,n=(A,B,C) 為法向量,M(x,y,z) 為平面上的任一點,則平面的點法式方程為 xxxx,聽著聽著就睡著了。。。(老師,我扛不住了!!)
所以,怪怪會盡量寫得有趣一點,讓你看完差不多可以記住這個演算法思想。
今天的題目是這樣的,給定一個字串,請你找出其中不含有重複字元的 最長子串 的長度。
簡單解釋一下。
比如給定字串“丙丙接水怪接”
第一步,找出字串中不含有重複字元的子串
- 丙
- 丙接
- 丙接水
- 丙接水怪
- 水怪接
第二步,計算出各個子串的長度,並取最大值。
- 在這裡最大值顯然就是 4,所以答案就是 4
ok,做完例題,其實很容易可以發現,核心就是第一步,找出不含有重複字元的子串。
那究竟要怎麼找呢,為了便於第一次看這個演算法的小夥伴好理解,我畫了幾張圖,大家看完還不懂,加微信罵我渣男好了!
找兩把槍,起始的時候都指向第一個字元。
我們順利的找到了第一個不重複的子串,“丙”。
接著保持紅槍不動,綠槍向後移動一位。
此時發現兩槍之間,字元重複了,找到跟綠槍重複的位置,並且將紅槍移動到重複位置的後一位,那麼此時變成了下面這個樣子。
於是我們找到了,第二個不重複的子串,跟第一個一樣,也是“丙”。
不慌,我們接著移動綠槍。
由於,在移動過程中,紅綠槍之間一直沒有重複,我們找到了不重複子串“丙接”、“丙接水”、“丙接水怪”
不急不急,還沒完,接著移動綠槍(綠槍已到最後一位,結束)
可以發現,當我們移動完綠槍到 “接”,此時紅綠之間的子串出現了重複的 “接”,於是我們還是按之前重複的思路:
- 找到重複字元 “接” 的位置
- 將紅槍移動到位置的後一位,即 “水”
- 得到紅綠之間不重複子串 “水怪接”
由此可見,當我們的綠槍移動到最後一位的時候,我們的找尋也就結束了,所有不重複的子串我們也都找到了。
其實上面的紅槍,綠槍,換一種說法就是左右指標,移動紅綠槍,就是移動左右指標,兩指標之間的視窗就是我們要的結果。
很像我們剪視訊的時候,拖動的那個擷取視訊進度的東東。。
這種解題的思想,就是大家常說的滑動視窗。
理解了思想,寫程式碼其實就比較簡單了。
直接上 LeetCode 原題跟程式碼,一些邊界情況我寫在註釋裡面了(仔細看註釋哦,邊界沒寫對會有問題哦)。去除註釋 10 行程式碼左右,建議第一次做的小夥伴動手寫一下,相信我,一定能寫出來。
說不定開啟了你的 LeetCode 演算法之旅哦?~
小結
滑動視窗的題,其實就是要搞清楚左右滑的界限是啥[吃瓜],比如上面這個題左視窗啥時候收縮就是關鍵。
開了一個演算法系列的專欄,後續會寫一些演算法相關的,近期演算法應該都會圍繞滑動視窗相關的展開去講。
上一篇國慶小結提到了一些技術,近期大概率是這個節奏發文章
- redux 原始碼、設計思想
- promise、generator、async await 原始碼(畢竟工作中高頻使用,需要看看)
- 常用 hooks 原始碼分析(新公司技術棧就是 React 這一套)
- 演算法
我是接水怪,一個普普通通的程式設計師。感謝各位的關注與3連??
聯絡我 / 公眾號
微信搜尋【接水怪】回覆”加群“,我會拉你進技術交流群。講真的,在這個群,哪怕您不說話,光看聊天記錄也是一種成長。(阿里技術專家、敖丙作者、Java3y、蘑菇街資深前端、螞蟻金服安全專家、各路大牛都在)。
接水怪也會定期原創,定期跟小夥伴進行經驗交流或幫忙看簡歷。加關注,不迷路,有機會一起跑個步? ↓↓↓