LeetCode 234. 迴文鏈表(golang實現)

經典的鏈表問題

判斷一個鏈表是否爲迴文鏈表。golang

  • 示例 1:
輸入: 1->2
輸出: false
複製代碼
  • 示例 2:
輸入: 1->2->2->1
輸出: true
複製代碼

這裏使用golang耍一遍,原理是同樣,語言只是其次。bash

使用快慢指針解決

  1. 慢指針 指向頭部
  2. 快指針 指向第二個節點
  3. 循環遍歷鏈表,快指針每次走兩個節點,慢指針每次走一個節點,當快指針遍歷完鏈表,慢指針挺下的位置就是中心點,由於快指針從第二個節點開始走,因此不須要考慮奇偶的狀況。
  4. 當找到中心點後,把慢指針走過的節點從頭到中心點截斷,爲待比較的第一部分鏈表
  5. 將從中心點到鏈表結尾的部分全部節點進行倒序操做,也就是鏈表的倒序。做爲待比較的第二部分鏈表
  6. 比較兩個鏈表每一個節點是否相等,若是相等則爲迴文
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */
func isPalindrome(head *ListNode) bool {
    if head == nil || head.Next == nil {
		return true
	}
	lat := head.Next // 快指針,爲何從第二個開始,是爲了解決奇偶問題
	pre := head      // 慢指針
	for lat != nil && lat.Next != nil {
		lat = lat.Next.Next
		pre = pre.Next
	}

	cur := pre.Next // 保留後面尚未遍歷的鏈表
	pre.Next = nil  // 將整個列表進行截斷,保存爲 第一個鏈表

	p := reverseLink(cur) // 將後面的鏈表倒序
    
    // 比較兩個鏈表
	for p != nil && head != nil {
		if p.Val != head.Val {
			return false
		}
		p = p.Next
		head = head.Next
	}

	return true
}


// reverseLink 將鏈表倒序
func reverseLink(listHead *ListNode) *ListNode {
	if listHead == nil && listHead.Next == nil {
		return listHead
	}

	p := listHead     // 遍歷鏈表的指針
	var rst *ListNode // 保存最後結果鏈表的指針
	var q *ListNode   // 保存下一個節點的臨時指針
    
    // 這裏不清楚的拿紙和筆畫一下就明白了
	for p != nil {
		q = p.Next
		p.Next = rst
		rst = p
		p = q
	}

	return rst
}
複製代碼

徹底使用鏈表操做就能夠將空間複雜度降到O(1)。spa

相關文章
相關標籤/搜索