【日拱一卒】連結串列——迴文判斷
阿新 • • 發佈:2020-07-13
需求
判斷一個連結串列是否是迴文連結串列
迴文的形式大家應該都知道,類似
abcba 或者 abccba
這種對稱的方式都是迴文。
難點
如果將連結串列形式換成陣列,是不是就簡單很多了。針對一個長度為n的陣列,我們可以一一比對節點0和節點n-1,節點1和節點n-2,直到收尾索引相等。
但是這裡說的是連結串列,顯然遍歷完整個連結串列,找到尾結點,然後再回溯進行比較顯得有些不切實際,況且這裡並不是雙向連結串列。
所以這裡就要換個思路,重點是從迴文的對稱性著手。
思路
關鍵字:快慢指標、連結串列反轉
1、初始化兩個指標快指標和慢指標,慢指標每次走一步,快指標每次走兩步
2、依次遍歷整個連結串列,直到快指標遍歷完連結串列
此時fast指標已經率先到達連結串列的尾結點,停止遍歷。因為該連結串列包含奇數個元素,所以slow節點需要再移動一步。指向節點2。
3、此時藉助慢指標將後半部分連結串列反轉
反轉後連結串列頭指標為pre
4、依次遍歷比較原來連結串列和反轉後的連結串列pre的值是否相等,直到pre遍歷到尾結點。
有了如上思路,寫出對應程式碼就是順理成章的事了。
程式碼實現
func isPalindrome(head *ListNode) bool { if head == nil || head.Next == nil { return true } fast := head slow := head // 快慢指標,快指標每次移動兩步,慢指標每次移動一步 for fast != nil && fast.Next != nil { slow = slow.Next fast = fast.Next.Next } //如果是奇數,則慢指標再移動一步,到達中心點 if fast != nil { slow = slow.Next } // 慢指標反轉 var pre *ListNode = nil for slow != nil { pre, slow, slow.Next =slow, slow.Next, pre } cur := head for cur != nil && pre != nil { if cur.Val == pre.Val { cur = cur.Next pre = pre.Next } else { return false } } return true }
不忘初心
老王:你不好好種地,你以後長大能幹什麼
小王:學演算法
老王:學演算法?!你陣列、連結串列、棧、佇列、堆、排序、查詢都整不明白,你學什麼演算法
小王:我只學連結串列迴文判斷
老王:。。。
如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!如果您想持續關注我的文章,請掃描二維碼,關注JackieZheng的微信公眾號,我會將我的文章推送給您,並和您一起分享我日常閱讀過的優質文章。