演算法學習03 棧和佇列

2021-09-11 14:36:20 字數 3141 閱讀 7826

巨集觀劃分問題

最優解來自於資料狀況或問法

鍊錶問題:筆試與面試要求不同

佇列結構的實現: 迴圈佇列

最小棧的pop(),push(),getmin()操作的時間複雜度都是o(1)

解法:儲存兩個棧,data棧和min棧,data棧儲存壓入的資料,min棧儲存當前棧中最小值

當向data壓入乙個數時,與min棧棧頂比較,若被壓入的數比min棧頂小,則向min棧壓入新數,否則向min棧重複壓入min棧頂.

用佇列實現棧: 前邊所有數都入佇列,留著最後乙個數給使用者返回.

用棧實現佇列: 建立兩個棧:push棧和pop棧,進佇列時進push棧,出佇列時從pop棧往外拿. 中間可能要把資料從乙個棧倒入另乙個棧,每次倒資料的時候要直接倒完.

對於一些問題,其問題需要不斷的考慮邊界問題,比較難想,這樣我們就遵循先巨集觀再微觀的思路.

先提取出巨集觀思路來把問題劃分成微觀步驟,然後通過函式考慮區域性的具體實現.

將遍歷一圈提取成printcircle()函式,然後從左上角和右下角開始,每列印一圈兩個角向裡側移動一位,直到兩個角相遇.

printcircle()要考慮邊界情況: 左上角和右下角位於同一行或同一列.

將遍歷一圈提取成rotatecircle()函式,然後從左上角和右下角開始,每列印一圈兩個角向裡側移動一位,直到兩個角相遇.

rotatecircle()要考慮邊界情況: 左上角和右下角相遇,實際只有乙個元素,不用旋轉.

將列印一條斜線提取成writeline()函式,接收斜線的兩個頂點和列印方向. 初始斜線的頂點應該為矩陣左下角,每列印一行,頂點向右下移動一位,且方向轉變一次.

從右上角開始找,令指標指向右上角的節點,

注意指標不越界邊界條件:((cury < rownum) && (curx >=0)),一邊是等於,一邊是不等於.另外對二維陣列進行索引時先索引y,後索引x,matrix[y][x]現將陣列排序,設定兩個指標p1p2,分別指向陣列的第乙個元素和最後乙個元素.

計算兩個元素的和p1+p2若其和大於目標aim,則p2向前移動一位.

若其和小於目標aim,則p1向後移動一位.

若其和等於目標aim,則找到解,返回兩個指標.

p1p2相遇,則返回未找到,否則繼續步驟2.

鍊錶的題目時間複雜度難以優化,關鍵優化的點在於空間複雜度.

因此筆試鍊錶,優先考慮如何過掉這道題.

面試鍊錶,要注意考慮用更少空間複雜度.

快慢指標:

快指標指向末尾,慢指標走向中點.然後把右半部分逆序.

之後從兩頭開始向中間走,比較是否相等

最後在把右半部分逆序回來.

注意:鍊錶長度為偶數或者奇數會對兩個指標產生影響.

反轉鍊錶函式中要注意最後把煉表頭結點的next置空.

準備成陣列.然後再穿起來.

但是荷蘭國旗問題不保證穩定性,且要o(n)空間

設定三個指標節點:equal,more,less

遍歷一遍陣列,把相應的節點掛在三個指標後邊.

注意扣邊界: 有個區域沒節點.

遍歷兩次鍊錶,第一趟複製表的next結構,第二趟複製表的random指標.

具體實現有兩種方式:

使用map,較簡單

在原鍊錶每個節點後面複製出新節點.

注意:

1. 複製之後再遍歷鍊錶的話需要指標每次轉移跳兩格,要注意是否產生空指標錯誤,要將cur.next = cur.next.next;改為cur.next = (cur.next != null) ? cur.next.next : null;

2. 注意有一些節點的random指標指向空,這種複製的時候要格外小心,別發生空指標錯誤.cur.next.random = (cur.random != null) ? cur.random.next : null;

問題:判斷兩個鍊錶是否相交,若相交,返回首個交點. 其中兩個鍊錶都可能有環或者無環.

轉化: 該問題可以轉化為三個小問題:

判斷鍊錶是否有環,若有環返回入環節點,(快慢指標方法:快指標每次走兩步,慢指標每次走一步,直到相交. 然後新建兩個指標,分別指向交點指向頭結點,兩個指標同步後移直到他們相遇,相遇點為入環節點)leetcode 142

判斷兩個無環鏈表的首個交點(先遍歷兩個鍊錶,得出長度差值,根據差值對齊鍊錶,然後兩個頭指標同步後移直到相遇)leetcode 160

判斷兩個可能有環鏈表的首個交點

解法先找到兩個列表是否有環,並返回入環點.

若兩列表都無環,則轉化為無環鏈表求交點問題.

若乙個鍊錶有環,乙個鍊錶無環,則它們不可能相交.(反證:若相交,則無環鏈表最終將進環)

若兩鍊錶都有環,則先比較兩入環點是否相同

若兩入環點相同,則說明入環以前兩鍊錶已經相交,所以對於入環前節點可以簡化為無環鏈表求交點問題.

若兩入環點不同,則比較兩入環點是否相連:

1. 若兩入環點不相連,說明兩煉表無交點(乙個鍊錶不可能有兩個環)

2. 若兩入環點相連,則他們都是最早交點(這種情況下無非是哪個離兩煉表較近的問題了,無所謂首個交點)

前端演算法學習(二) 棧和佇列

特性 後進先出,就好比在乙個只有乙個口的箱子裡放東西,前面先放進去的東西只能後面再拿出來 function stack this.pop function var stack new stack stack.push 1 stack.push 2 stack.push 3 console.log s...

演算法03 棧 佇列

棧 後進先出 想象乙個彈夾 或者桶,後放進去的元素,先被取出來 push pop 佇列 先進先出 排隊,先來先服務 add poll 底層可以用乙個雙向鍊錶實現棧和佇列。也可以用陣列實現 為了簡單,可以只考慮容量固定的情況 可以用乙個陣列實現棧 limit,index 可以用陣列,通過迴圈使用來實現...

棧和佇列的基礎演算法學習(EPI)

今天學習的時間雖然挺多的,但是總覺效率不高。其實今天沒有按照計畫進行epi題目的瀏覽,白天去看了其他的書籍。準備找工作可能需要的狀態是一定量經典的書,偶爾溫習才可。書是看不完的,知識點也是固定的。所以從把手頭的幾本書在瀏覽完畢之後就要著手複習之前的知識啦。c 的知識,leetcode的題目,作業系統...